diff --git a/src/lib/components/account/sendVerificationEmailModal.svelte b/src/lib/components/account/sendVerificationEmailModal.svelte
index bbe676142..1ad53ed1b 100644
--- a/src/lib/components/account/sendVerificationEmailModal.svelte
+++ b/src/lib/components/account/sendVerificationEmailModal.svelte
@@ -1,79 +1,194 @@
-
-
-
-
- To continue using Appwrite Cloud, please verify your email address. An email will be
- sent to {get(user)?.email}
-
-
-
+
+
+
+
+
+ To continue using Appwrite Cloud, please verify your email address. An email
+ will be sent to {email || get(user)?.email}
+
-
-
-
-
+ logout()}>Switch account
+
+ {#if emailSent && resendTimer > 0}
+
+
+ Didn't get the email? Try again in {resendTimer}s
+
+
+ {/if}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/components/alerts/emailVerificationBanner.svelte b/src/lib/components/alerts/emailVerificationBanner.svelte
deleted file mode 100644
index 72e2bd016..000000000
--- a/src/lib/components/alerts/emailVerificationBanner.svelte
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-{#if shouldShowEmailBanner}
-
-
- To avoid losing access to your projects, make sure {$user.email} is valid and up to date. Email
- verification will be required soon.
-
-
-
-
-
-
-{/if}
diff --git a/src/lib/components/index.ts b/src/lib/components/index.ts
index 47afdf41a..b9d6e57ed 100644
--- a/src/lib/components/index.ts
+++ b/src/lib/components/index.ts
@@ -85,5 +85,5 @@ export { default as ViewToggle } from './viewToggle.svelte';
export { default as RegionEndpoint } from './regionEndpoint.svelte';
export { default as ExpirationInput } from './expirationInput.svelte';
export { default as EstimatedCard } from './estimatedCard.svelte';
-export { default as EmailVerificationBanner } from './alerts/emailVerificationBanner.svelte';
export { default as SortButton, type SortDirection } from './sortButton.svelte';
+export { default as SendVerificationEmailModal } from './account/sendVerificationEmailModal.svelte';
diff --git a/src/routes/(console)/+layout.svelte b/src/routes/(console)/+layout.svelte
index a8e6e30c7..d3a77a8c4 100644
--- a/src/routes/(console)/+layout.svelte
+++ b/src/routes/(console)/+layout.svelte
@@ -45,7 +45,7 @@
import { headerAlert } from '$lib/stores/headerAlert';
import { UsageRates } from '$lib/components/billing';
import { canSeeProjects } from '$lib/stores/roles';
- import { BottomModalAlert, EmailVerificationBanner } from '$lib/components';
+ import { BottomModalAlert } from '$lib/components';
import {
IconAnnotation,
IconBookOpen,
@@ -346,8 +346,6 @@
-
-
{#if $wizard.show && $wizard.component}
{:else if $wizard.cover}
diff --git a/src/routes/(console)/verify-email/+page.svelte b/src/routes/(console)/verify-email/+page.svelte
new file mode 100644
index 000000000..c70b0e2d3
--- /dev/null
+++ b/src/routes/(console)/verify-email/+page.svelte
@@ -0,0 +1,93 @@
+
+
+
+ Verify Email - Appwrite
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/routes/(console)/verify-email/+page.ts b/src/routes/(console)/verify-email/+page.ts
new file mode 100644
index 000000000..15ad453bc
--- /dev/null
+++ b/src/routes/(console)/verify-email/+page.ts
@@ -0,0 +1,45 @@
+import { resolve } from '$app/paths';
+import { redirect } from '@sveltejs/kit';
+import type { PageLoad } from './$types';
+import { Dependencies } from '$lib/constants';
+import { sdk } from '$lib/stores/sdk';
+import { addNotification } from '$lib/stores/notifications';
+import { VARS } from '$lib/system';
+
+export const load: PageLoad = async ({ parent, depends, url }) => {
+ if (!VARS.EMAIL_VERIFICATION) {
+ redirect(303, resolve('/'));
+ }
+
+ const { account } = await parent();
+ depends(Dependencies.ACCOUNT);
+
+ const user = url.searchParams.get('userId') ?? null;
+ const secret = url.searchParams.get('secret') ?? null;
+
+ if (account && account.emailVerification === true) {
+ redirect(303, resolve('/'));
+ } else if (user && secret) {
+ try {
+ await sdk.forConsole.account.updateVerification({
+ userId: user,
+ secret
+ });
+
+ addNotification({
+ type: 'success',
+ message: 'Email has been verified',
+ timeout: 10000 // 10 seconds max, because if succeeded, loads takes some time!
+ });
+ } catch (error) {
+ addNotification({
+ type: 'error',
+ message: error.message
+ });
+ } finally {
+ redirect(303, resolve('/'));
+ }
+ } else {
+ redirect(303, resolve('/'));
+ }
+};
diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts
index 46b84cc98..5ee94b650 100644
--- a/src/routes/+layout.ts
+++ b/src/routes/+layout.ts
@@ -6,10 +6,10 @@ import { redirect } from '@sveltejs/kit';
import { Dependencies } from '$lib/constants';
import type { LayoutLoad } from './$types';
import { redirectTo } from './store';
-import { base } from '$app/paths';
+import { base, resolve } from '$app/paths';
import type { Account } from '$lib/stores/user';
import type { AppwriteException } from '@appwrite.io/console';
-import { isCloud } from '$lib/system';
+import { isCloud, VARS } from '$lib/system';
import { checkPricingRefAndRedirect } from '$lib/helpers/pricingRedirect';
export const ssr = false;
@@ -29,6 +29,15 @@ export const load: LayoutLoad = async ({ depends, url, route }) => {
}
if (account) {
+ if (isCloud && !account.emailVerification && VARS.EMAIL_VERIFICATION) {
+ const isConsoleRoute = route.id?.startsWith('/(console)');
+ const isVerifyEmailPage = url.pathname === resolve('/verify-email');
+
+ if (isConsoleRoute && !isVerifyEmailPage) {
+ redirect(303, resolve('/verify-email'));
+ }
+ }
+
return {
account: account,
organizations: !isCloud