fix email verification flow

This commit is contained in:
Ben Senescu 2026-06-19 19:38:55 -04:00 committed by GitHub
parent 17c6c8f60b
commit b2931a6542
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -47,16 +47,14 @@ function getVerificationErrorMessage(error: string | undefined) {
function getVerifyEmailPageCopy({ function getVerifyEmailPageCopy({
isHostedMode, isHostedMode,
errorMessage, errorMessage,
isWaiting,
isPending, isPending,
isVerified, isRedirecting,
email, email,
}: { }: {
isHostedMode: boolean; isHostedMode: boolean;
errorMessage: string | null; errorMessage: string | null;
isWaiting: boolean;
isPending: boolean; isPending: boolean;
isVerified: boolean; isRedirecting: boolean;
email: string | undefined; email: string | undefined;
}) { }) {
if (!isHostedMode) { if (!isHostedMode) {
@ -73,12 +71,10 @@ function getVerifyEmailPageCopy({
}; };
} }
if (isWaiting) { if (isRedirecting) {
return { return {
title: "Verify your email", title: "Email confirmed",
helperText: email helperText: "You're all set. Taking you to your account now.",
? `Click the link we sent to ${email} to verify your email.`
: "Check your inbox for the link to verify your email.",
}; };
} }
@ -89,16 +85,15 @@ function getVerifyEmailPageCopy({
}; };
} }
if (isVerified) { // Default: the user just signed up (or reloaded this page) and still needs to
return { // click the verification link. There is never a sign-in CTA here — an
title: "Email confirmed", // unverified hosted user would be bounced straight back by the verification
helperText: "You're all set. Taking you to your account now.", // gate.
};
}
return { return {
title: "Sign in to continue", title: "Verify your email",
helperText: "Sign in to continue to your account.", helperText: email
? `Click the link we sent to ${email} to verify your email.`
: "Check your inbox for the link to verify your email.",
}; };
} }
@ -115,23 +110,15 @@ function VerifyEmailPage() {
const email = search.email ?? session?.user?.email; const email = search.email ?? session?.user?.email;
const isVerified = !!session?.user?.emailVerified; const isVerified = !!session?.user?.emailVerified;
const [isResending, setIsResending] = useState(false); const [isResending, setIsResending] = useState(false);
// A hosted user who still needs to verify must see the resend / "check your // Verified (or bypass) users are sent on to the app by the effect below; until
// inbox" state — never a sign-in CTA, which the verification gate would // that lands we show the redirecting state instead of the resend prompt.
// immediately block (the email-verify trap). Keying off `email` (which the const isRedirecting =
// sign-up flow always passes) covers the just-signed-up case even while the isVerified || (bypassEmailVerification && Boolean(session?.user?.id));
// session is still resolving, so we never flash the sign-in fallback.
const isWaiting =
isHostedMode &&
!errorMessage &&
!bypassEmailVerification &&
!isVerified &&
(Boolean(email) || !isPending);
const pageCopy = getVerifyEmailPageCopy({ const pageCopy = getVerifyEmailPageCopy({
isHostedMode, isHostedMode,
errorMessage, errorMessage,
isWaiting,
isPending, isPending,
isVerified, isRedirecting,
email, email,
}); });
@ -229,32 +216,20 @@ function VerifyEmailPage() {
Back to sign in Back to sign in
</Link> </Link>
</div> </div>
) : isWaiting ? ( ) : isPending || isRedirecting ? (
email ? (
<div className="space-y-4">
<button
type="button"
className="btn btn-soft w-full"
onClick={() => void handleResend()}
disabled={isResending}
>
{isResending ? "Sending email..." : "Resend email"}
</button>
</div>
) : null
) : isPending || isVerified ? (
<div className="flex justify-center py-4"> <div className="flex justify-center py-4">
<span className="loading loading-spinner loading-md" /> <span className="loading loading-spinner loading-md" />
</div> </div>
) : ( ) : email ? (
<Link <button
to="/sign-in" type="button"
search={getSignInSearch(redirectTo)}
className="btn btn-soft w-full" className="btn btn-soft w-full"
onClick={() => void handleResend()}
disabled={isResending}
> >
Sign in to continue {isResending ? "Sending email..." : "Resend email"}
</Link> </button>
)} ) : null}
</AuthPageCard> </AuthPageCard>
</AuthPageShell> </AuthPageShell>
); );