Refresh page after email verified

This commit is contained in:
MartinBraquet
2026-02-13 13:10:44 +01:00
parent b6598f917c
commit af95174929
4 changed files with 59 additions and 12 deletions

View File

@@ -0,0 +1,28 @@
import {User} from 'firebase/auth'
import {Button} from 'web/components/buttons/button'
import {sendVerificationEmail} from 'web/lib/firebase/email-verification'
import {useT} from 'web/lib/locale'
import {Col} from "web/components/layout/col"
export function EmailVerificationButton(props: {
user: User
}) {
const {user} = props
const t = useT()
const isEmailVerified = user.emailVerified
return (
<Col>
<Button
color={'gray-outline'}
onClick={() => sendVerificationEmail(user, t)}
disabled={isEmailVerified}
>
{isEmailVerified
? t('settings.email.verified', 'Email Verified ✔️')
: t('settings.email.send_verification', 'Send verification email')}
</Button>
</Col>
)
}

View File

@@ -1,7 +1,6 @@
import {Button} from 'web/components/buttons/button'
import {Col} from 'web/components/layout/col'
import {sendVerificationEmail} from 'web/lib/firebase/email-verification'
import clsx from 'clsx'
import {EmailVerificationButton} from "web/components/email-verification-button";
interface EmailVerificationPromptProps {
firebaseUser: any
@@ -18,9 +17,7 @@ export function EmailVerificationPrompt(
return (
<Col className={clsx('gap-4 max-w-xl', className)}>
<h3>{t('messaging.email_verification_required', "You must verify your email to message people.")}</h3>
<Button color={'gray-outline'} onClick={() => sendVerificationEmail(firebaseUser!, t)} disabled={false}>
{t('settings.email.send_verification', 'Send verification email')}
</Button>
<EmailVerificationButton user={firebaseUser}/>
</Col>
)
}

View File

@@ -1,5 +1,6 @@
import toast from "react-hot-toast";
import {sendEmailVerification, User} from "firebase/auth";
import {auth} from "web/lib/firebase/users";
export const sendVerificationEmail = async (
@@ -26,4 +27,30 @@ export const sendVerificationEmail = async (
toast.error(t('settings.email.too_many_requests', "You can't request more than one email per minute. Please wait before sending another request."))
}
})
async function waitForEmailVerification(intervalMs = 2000, timeoutMs = 5 * 60 * 1000) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const user = auth.currentUser;
if (!user) return false;
// Refresh user record from Firebase
await user.reload();
if (user.emailVerified) {
// IMPORTANT: force a new ID token with updated claims
await user.getIdToken(true);
toast.success(t('settings.email.verified', 'Email Verified ✔️'))
return true;
}
await new Promise(r => setTimeout(r, intervalMs));
}
return false;
}
waitForEmailVerification()
}

View File

@@ -22,7 +22,7 @@ import {AboutSettings} from "web/components/about-settings";
import {LanguagePicker} from "web/components/language/language-picker";
import {useT} from "web/lib/locale";
import HiddenProfilesModal from 'web/components/settings/hidden-profiles-modal'
import {sendVerificationEmail} from "web/lib/firebase/email-verification";
import {EmailVerificationButton} from "web/components/email-verification-button";
export default function NotificationsPage() {
const t = useT()
@@ -108,8 +108,6 @@ const LoadedGeneralSettings = (props: {
changeUserEmail(data.newEmail)
}
const isEmailVerified = user.emailVerified
return <>
<div className="flex flex-col gap-2 max-w-fit">
<h3>{t('settings.general.theme', 'Theme')}</h3>
@@ -127,10 +125,7 @@ const LoadedGeneralSettings = (props: {
<h3>{t('settings.general.account', 'Account')}</h3>
<h5>{t('settings.general.email', 'Email')}</h5>
<Button color={'gray-outline'} onClick={() => sendVerificationEmail(user, t)}
disabled={!privateUser?.email || isEmailVerified}>
{isEmailVerified ? t('settings.email.verified', 'Email Verified ✔️') : t('settings.email.send_verification', 'Send verification email')}
</Button>
<EmailVerificationButton user={user}/>
{!isChangingEmail ? (
<Button color={'gray-outline'} onClick={() => setIsChangingEmail(true)}>