From efed2cc324e6399963479d1853ccf9faa75b8f9e Mon Sep 17 00:00:00 2001 From: Harsh Mahajan <127186841+HarshMN2345@users.noreply.github.com> Date: Sun, 28 Sep 2025 22:36:19 +0530 Subject: [PATCH] feat: Implement email OTP authentication --- .../(public)/(guest)/login/+page.svelte | 38 +++++- .../(guest)/login/email-otp/+page.svelte | 118 ++++++++++++++++++ .../(public)/(guest)/login/email-otp/+page.ts | 39 ++++++ 3 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 src/routes/(public)/(guest)/login/email-otp/+page.svelte create mode 100644 src/routes/(public)/(guest)/login/email-otp/+page.ts diff --git a/src/routes/(public)/(guest)/login/+page.svelte b/src/routes/(public)/(guest)/login/+page.svelte index e9f8f25b4..1efc26447 100644 --- a/src/routes/(public)/(guest)/login/+page.svelte +++ b/src/routes/(public)/(guest)/login/+page.svelte @@ -15,9 +15,33 @@ import { Layout } from '@appwrite.io/pink-svelte'; let mail: string, pass: string, disabled: boolean; + let showPasswordLogin: boolean = false; export let data; + $: showPasswordLogin = pass && pass.length > 0; + + async function sendSignInCode() { + try { + disabled = true; + // use createEmailToken for sign in with code + const sessionToken = await sdk.forConsole.account.createEmailToken({ + userId: 'unique', + email: mail + }); + + await goto( + `${base}/login/email-otp?email=${encodeURIComponent(mail)}&userId=${sessionToken.userId}` + ); + } catch (error) { + disabled = false; + addNotification({ + type: 'error', + message: error.message + }); + } + } + async function login() { try { disabled = true; @@ -52,7 +76,6 @@ return; } - // no specific redirect, so redirect will happen through invalidating the account await invalidate(Dependencies.ACCOUNT); } catch (error) { disabled = false; @@ -92,22 +115,27 @@ Sign in -
+ - + + {#if showPasswordLogin} + + {:else} + + {/if} + {#if isCloud} or + +
+ + + Didn't get it? + Resend code + + +
+
diff --git a/src/routes/(public)/(guest)/login/email-otp/+page.ts b/src/routes/(public)/(guest)/login/email-otp/+page.ts new file mode 100644 index 000000000..974a7a003 --- /dev/null +++ b/src/routes/(public)/(guest)/login/email-otp/+page.ts @@ -0,0 +1,39 @@ +import { base } from '$app/paths'; +import type { Campaign } from '$lib/stores/campaigns'; +import { sdk } from '$lib/stores/sdk'; +import { redirect } from '@sveltejs/kit'; +import type { PageLoad } from './$types'; + +export const load: PageLoad = async ({ url }) => { + if (!url.searchParams.has('email')) { + redirect(303, `${base}/login`); + } + + if (url.searchParams.has('code')) { + const code = url.searchParams.get('code'); + let campaign: Campaign; + try { + const couponData = await sdk.forConsole.billing.getCoupon(code); + if (couponData.campaign) { + campaign = await sdk.forConsole.billing.getCampaign(couponData.campaign); + return { + couponData, + campaign + }; + } else redirect(303, `${base}/login`); + } catch (e) { + redirect(303, `${base}/login`); + } + } + if (url.searchParams.has('campaign')) { + const campaignId = url.searchParams.get('campaign'); + let campaign: Campaign; + try { + campaign = await sdk.forConsole.billing.getCampaign(campaignId); + return { campaign }; + } catch (e) { + redirect(303, `${base}/login`); + } + } + return; +};