-
Notifications
You must be signed in to change notification settings - Fork 186
feat: implement blocking email verification modal #2379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
ConsoleProject ID: Sites (2)
Note Appwrite has a Discord community with over 16 000 members. |
Walkthrough
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib/components/account/sendVerificationEmailModal.svelte (1)
116-139
: Scrub verification secrets from the URL after successful verification.Leaving
userId
andsecret
in the address bar is a security/privacy risk (leaks via history, screenshots, support logs). Replace the URL withcleanUrl
on success.Apply this diff inside the success branch:
try { await sdk.forConsole.account.updateVerification({ userId, secret }); addNotification({ message: 'Email verified successfully', type: 'success' }); await Promise.all([ invalidate(Dependencies.ACCOUNT), invalidate(Dependencies.FACTORS) ]); + // Remove sensitive query params from the URL without a navigation + if (browser) { + history.replaceState({}, '', cleanUrl); + } } catch (error) {
🧹 Nitpick comments (5)
src/lib/components/account/sendVerificationEmailModal.svelte (4)
195-209
: Add a z-index to ensure the scrim truly blocks the console.Without an explicit z-index, fixed/sticky elements with higher stacking contexts can sit above the scrim.
.email-verification-scrim { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: hsl(240 5% 8% / 0.6); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; + z-index: 1000; /* ensure it overlays console chrome */ }
168-174
: Prefer reactive$user
overget(user)
in markup.Using
get()
makes the email non-reactive and adds an unnecessary import.- style="display: inline;">{get(user)?.email}</Typography.Text> + style="display: inline;">{$user?.email}</Typography.Text>Also remove the unused import:
- import { get } from 'svelte/store';
60-60
: Specify radix for parseInt.Be explicit with base-10 to avoid surprises.
- const timerEndTime = parseInt(savedTimerEnd); + const timerEndTime = parseInt(savedTimerEnd, 10);
176-177
: Ensure “Switch account” is keyboard-accessible.If
Link
requireshref
for focusability, switch to a button-styled control or providehref
and prevent default in the handler.Example:
-<Link variant="default" on:click={() => logout(false)}>Switch account</Link> +<Button variant="link" on:click={() => logout(false)}>Switch account</Button>src/routes/(console)/+layout.svelte (1)
367-368
: Modal placement LGTM; consider gating at callsite (optional).The component self-gates on
isCloud
and other conditions, but you could also wrap it here for tiny render savings.Example:
{#if isCloud} <SendVerificationEmailModal /> {/if}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/lib/components/account/sendVerificationEmailModal.svelte
(2 hunks)src/lib/components/alerts/emailVerificationBanner.svelte
(0 hunks)src/lib/components/index.ts
(0 hunks)src/routes/(console)/+layout.svelte
(2 hunks)
💤 Files with no reviewable changes (2)
- src/lib/components/alerts/emailVerificationBanner.svelte
- src/lib/components/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: e2e
- GitHub Check: build
🔇 Additional comments (3)
src/lib/components/account/sendVerificationEmailModal.svelte (2)
158-166
: Double overlay check.The custom scrim plus Modal may result in two overlays/backdrops. If
Modal
already renders its own overlay, consider disabling it or reusing it (and applying the blur there) to avoid stacking/scroll issues.
40-51
: Timer/persistence flow looks solid.Good use of a saved end time and a countdown with rehydration.
src/routes/(console)/+layout.svelte (1)
48-50
: Imports look correct and consistent with the new flow.
onDestroy(() => { | ||
if (timerInterval) { | ||
clearInterval(timerInterval); | ||
} | ||
// round up localstorage when component is destroyed | ||
if (browser) { | ||
localStorage.removeItem(TIMER_END_KEY); | ||
localStorage.removeItem(EMAIL_SENT_KEY); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't clear localStorage on destroy; it defeats persistence of the resend timer.
Clearing TIMER_END_KEY
/EMAIL_SENT_KEY
in onDestroy
breaks the “persist across reloads” goal and allows immediate resends after a refresh/navigation.
Apply this diff:
onDestroy(() => {
if (timerInterval) {
clearInterval(timerInterval);
}
- // round up localstorage when component is destroyed
- if (browser) {
- localStorage.removeItem(TIMER_END_KEY);
- localStorage.removeItem(EMAIL_SENT_KEY);
- }
});
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
onDestroy(() => { | |
if (timerInterval) { | |
clearInterval(timerInterval); | |
} | |
// round up localstorage when component is destroyed | |
if (browser) { | |
localStorage.removeItem(TIMER_END_KEY); | |
localStorage.removeItem(EMAIL_SENT_KEY); | |
} | |
}); | |
onDestroy(() => { | |
if (timerInterval) { | |
clearInterval(timerInterval); | |
} | |
}); |
🤖 Prompt for AI Agents
In src/lib/components/account/sendVerificationEmailModal.svelte around lines 146
to 155, the onDestroy handler currently clears TIMER_END_KEY and EMAIL_SENT_KEY
from localStorage which breaks persistence across navigations; remove the
localStorage.removeItem calls from onDestroy so the resend timer state is
preserved across reloads and navigations, leaving only the
clearInterval(timerInterval) logic; ensure any clearing of those keys happens
only when the timer naturally expires or when an explicit cancel/reset action
occurs (not on component destroy).
<Button on:click={sendVerificationEmail} disabled={creating || resendTimer > 0}> | ||
{emailSent ? 'Resend email' : 'Send email'} | ||
</Button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not button submit and use the onSubmit
?
What does this PR do?
Test Plan
Related PRs and Issues
(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)
Have you read the Contributing Guidelines on issues?
yes
Summary by CodeRabbit
New Features
UX Improvements
Removed