diff --git a/.env.example b/.env.example index 30973b2c1e..14f47df658 100644 --- a/.env.example +++ b/.env.example @@ -4,5 +4,4 @@ PUBLIC_APPWRITE_MULTI_REGION=false PUBLIC_APPWRITE_ENDPOINT=http://localhost/v1 PUBLIC_STRIPE_KEY= PUBLIC_GROWTH_ENDPOINT= -PUBLIC_CONSOLE_EMAIL_VERIFICATION=false PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS=true \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2a19d6fbee..45f34e1420 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -41,7 +41,6 @@ jobs: "PUBLIC_CONSOLE_MODE=cloud" "PUBLIC_CONSOLE_FEATURE_FLAGS=" "PUBLIC_APPWRITE_MULTI_REGION=true" - "PUBLIC_CONSOLE_EMAIL_VERIFICATION=true" "PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS=false" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY }}" @@ -83,7 +82,6 @@ jobs: "PUBLIC_CONSOLE_MODE=cloud" "PUBLIC_CONSOLE_FEATURE_FLAGS=" "PUBLIC_APPWRITE_MULTI_REGION=true" - "PUBLIC_CONSOLE_EMAIL_VERIFICATION=true" "PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS=false" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}" @@ -122,7 +120,6 @@ jobs: build-args: | "PUBLIC_CONSOLE_MODE=self-hosted" "PUBLIC_APPWRITE_MULTI_REGION=false" - "PUBLIC_CONSOLE_EMAIL_VERIFICATION=false" "PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS=true" "PUBLIC_CONSOLE_FEATURE_FLAGS=" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" @@ -162,7 +159,6 @@ jobs: build-args: | "PUBLIC_CONSOLE_MODE=cloud" "PUBLIC_APPWRITE_MULTI_REGION=false" - "PUBLIC_CONSOLE_EMAIL_VERIFICATION=true" "PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS=false" "PUBLIC_CONSOLE_FEATURE_FLAGS=" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}" diff --git a/Dockerfile b/Dockerfile index 5da6ccbf2a..ec562d53a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,6 @@ ADD ./static /app/static ARG PUBLIC_CONSOLE_MODE ARG PUBLIC_CONSOLE_FEATURE_FLAGS ARG PUBLIC_APPWRITE_MULTI_REGION -ARG PUBLIC_CONSOLE_EMAIL_VERIFICATION ARG PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS ARG PUBLIC_APPWRITE_ENDPOINT ARG PUBLIC_GROWTH_ENDPOINT @@ -36,7 +35,6 @@ ENV PUBLIC_GROWTH_ENDPOINT=$PUBLIC_GROWTH_ENDPOINT ENV PUBLIC_CONSOLE_MODE=$PUBLIC_CONSOLE_MODE ENV PUBLIC_CONSOLE_FEATURE_FLAGS=$PUBLIC_CONSOLE_FEATURE_FLAGS ENV PUBLIC_APPWRITE_MULTI_REGION=$PUBLIC_APPWRITE_MULTI_REGION -ENV PUBLIC_CONSOLE_EMAIL_VERIFICATION=$PUBLIC_CONSOLE_EMAIL_VERIFICATION ENV PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS=$PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS ENV PUBLIC_STRIPE_KEY=$PUBLIC_STRIPE_KEY ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN diff --git a/build.js b/build.js index df5933adc8..a9cedede20 100644 --- a/build.js +++ b/build.js @@ -28,7 +28,6 @@ async function main() { logEnv('MULTI REGION', env?.PUBLIC_APPWRITE_MULTI_REGION); logEnv('APPWRITE ENDPOINT', env?.PUBLIC_APPWRITE_ENDPOINT, 'relative'); logEnv('GROWTH ENDPOINT', env?.PUBLIC_GROWTH_ENDPOINT); - logEnv('CONSOLE EMAIL VERIFICATION', env?.PUBLIC_CONSOLE_EMAIL_VERIFICATION); logEnv('CONSOLE MOCK AI SUGGESTIONS', env?.PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS); log(); logDelimiter(); diff --git a/package.json b/package.json index 8d1a0d1ba2..4fc791832e 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e", + "@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2751", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@50b60cc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 463bb83f37..ee3a3e2eb5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e - version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e + specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2751 + version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2751 '@appwrite.io/pink-icons': specifier: 0.25.0 version: 0.25.0 @@ -260,8 +260,8 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e': - resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e} + '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2751': + resolution: {tarball: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2751} version: 1.10.0 '@appwrite.io/pink-icons-svelte@2.0.0-RC.1': @@ -3703,7 +3703,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@fe3277e': {} + '@appwrite.io/console@https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@2751': {} '@appwrite.io/pink-icons-svelte@2.0.0-RC.1(svelte@5.25.3)': dependencies: diff --git a/src/lib/system.ts b/src/lib/system.ts index 4532609925..0c9a44b76e 100644 --- a/src/lib/system.ts +++ b/src/lib/system.ts @@ -11,7 +11,6 @@ export const VARS = { APPWRITE_ENDPOINT: env.PUBLIC_APPWRITE_ENDPOINT ?? undefined, GROWTH_ENDPOINT: env.PUBLIC_GROWTH_ENDPOINT ?? undefined, PUBLIC_STRIPE_KEY: env.PUBLIC_STRIPE_KEY ?? undefined, - EMAIL_VERIFICATION: env.PUBLIC_CONSOLE_EMAIL_VERIFICATION === 'true', MOCK_AI_SUGGESTIONS: (env.PUBLIC_CONSOLE_MOCK_AI_SUGGESTIONS ?? 'true') === 'true' }; diff --git a/src/routes/(console)/+layout.ts b/src/routes/(console)/+layout.ts index 3cf1478a3a..0fe20e22d8 100644 --- a/src/routes/(console)/+layout.ts +++ b/src/routes/(console)/+layout.ts @@ -7,20 +7,20 @@ import type { Plan, PlanList } from '$lib/sdk/billing'; import { Query } from '@appwrite.io/console'; export const load: LayoutLoad = async ({ depends, parent }) => { - const { organizations } = await parent(); + const { organizations, consoleVariables } = await parent(); depends(Dependencies.RUNTIMES); depends(Dependencies.CONSOLE_VARIABLES); depends(Dependencies.ORGANIZATION); const { endpoint, project } = sdk.forConsole.client.config; - const [preferences, plansArray, versionData, consoleVariables] = await Promise.all([ + const [preferences, plansArray, versionData, variables] = await Promise.all([ sdk.forConsole.account.getPrefs(), isCloud ? sdk.forConsole.billing.getPlansInfo() : null, fetch(`${endpoint}/health/version`, { headers: { 'X-Appwrite-Project': project } }).then((response) => response.json() as { version?: string }), - sdk.forConsole.console.variables() + consoleVariables ? consoleVariables : sdk.forConsole.console.variables() ]); const plansInfo = toPlanMap(plansArray); @@ -50,7 +50,7 @@ export const load: LayoutLoad = async ({ depends, parent }) => { preferences, currentOrgId, organizations, - consoleVariables, + consoleVariables: variables, version: versionData?.version ?? null, allProjectsCount: projectsCount }; diff --git a/src/routes/(console)/account/updateMfa.svelte b/src/routes/(console)/account/updateMfa.svelte index 29127d730e..5715885c88 100644 --- a/src/routes/(console)/account/updateMfa.svelte +++ b/src/routes/(console)/account/updateMfa.svelte @@ -60,7 +60,7 @@ if (userId && secret) { history.replaceState(null, '', cleanUrl); try { - await sdk.forConsole.account.updateVerification({ userId, secret }); + await sdk.forConsole.account.updateEmailVerification({ userId, secret }); // Don't show notification here - the modal will handle it await Promise.all([ invalidate(Dependencies.ACCOUNT), diff --git a/src/routes/(console)/verify-email/+page.ts b/src/routes/(console)/verify-email/+page.ts index d97e736667..f9c1d9b45c 100644 --- a/src/routes/(console)/verify-email/+page.ts +++ b/src/routes/(console)/verify-email/+page.ts @@ -4,14 +4,14 @@ 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) { + const { account, consoleVariables } = await parent(); + + if (!consoleVariables._APP_REQUIRE_CONSOLE_VERIFICATION) { redirect(303, resolve('/')); } - const { account } = await parent(); depends(Dependencies.ACCOUNT); const user = url.searchParams.get('userId') ?? null; @@ -21,7 +21,7 @@ export const load: PageLoad = async ({ parent, depends, url }) => { redirect(303, resolve('/')); } else if (user && secret) { try { - await sdk.forConsole.account.updateVerification({ + await sdk.forConsole.account.updateEmailVerification({ userId: user, secret }); diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 5ee94b6502..d3219424e1 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -5,12 +5,13 @@ import { sdk } from '$lib/stores/sdk'; import { redirect } from '@sveltejs/kit'; import { Dependencies } from '$lib/constants'; import type { LayoutLoad } from './$types'; -import { redirectTo } from './store'; +import { isEmailVerificationRequired, redirectTo } from './store'; import { base, resolve } from '$app/paths'; import type { Account } from '$lib/stores/user'; -import type { AppwriteException } from '@appwrite.io/console'; -import { isCloud, VARS } from '$lib/system'; +import type { AppwriteException, Models } from '@appwrite.io/console'; +import { isCloud } from '$lib/system'; import { checkPricingRefAndRedirect } from '$lib/helpers/pricingRedirect'; +import { get } from 'svelte/store'; export const ssr = false; @@ -23,13 +24,30 @@ export const load: LayoutLoad = async ({ depends, url, route }) => { .then((response) => [response, null]) .catch((error) => [null, error])) as [Account, AppwriteException]; + let isVerificationNeeded = false; + let consoleVariables: Models.ConsoleVariables | null = null; + + // cached so we don't always load the variables! + const writableStoreValue = get(isEmailVerificationRequired); + if (writableStoreValue === null) { + try { + consoleVariables = await sdk.forConsole.console.variables(); + isVerificationNeeded = consoleVariables._APP_REQUIRE_CONSOLE_VERIFICATION; + isEmailVerificationRequired.set(isVerificationNeeded); + } catch (error) { + // ignore + } + } else { + isVerificationNeeded = writableStoreValue; + } + if (url.searchParams.has('forceRedirect')) { redirectTo.set(url.searchParams.get('forceRedirect') || null); url.searchParams.delete('forceRedirect'); } if (account) { - if (isCloud && !account.emailVerification && VARS.EMAIL_VERIFICATION) { + if (isCloud && !account.emailVerification && isVerificationNeeded) { const isConsoleRoute = route.id?.startsWith('/(console)'); const isVerifyEmailPage = url.pathname === resolve('/verify-email'); @@ -40,6 +58,7 @@ export const load: LayoutLoad = async ({ depends, url, route }) => { return { account: account, + consoleVariables, organizations: !isCloud ? await sdk.forConsole.teams.list() : await sdk.forConsole.billing.listOrganization() diff --git a/src/routes/store.ts b/src/routes/store.ts index cd67fc8d90..3363ab149f 100644 --- a/src/routes/store.ts +++ b/src/routes/store.ts @@ -1,9 +1,11 @@ import { browser } from '$app/environment'; import { writable } from 'svelte/store'; -export const requestedMigration = writable | null>(null); -export const redirectTo = writable(null); export const loading = writable(true); +export const redirectTo = writable(null); +export const requestedMigration = writable | null>(null); + +export const isEmailVerificationRequired = writable(null); loading.subscribe((value) => { if (browser) globalThis.document.body.dataset.loading = value ? 'true' : 'false';