feat(auth): mandatory 2FA (TOTP + WebAuthn passkeys) with hard enrollment gate, AAL2 step-up, and single-use recovery codes
This commit is contained in:
+8
-2
@@ -29,6 +29,10 @@ export default function LoginPage() {
|
||||
setError(
|
||||
'Email verification failed or the link expired. Sign in below to resend a confirmation email.',
|
||||
);
|
||||
} else if (params.get('mfa_reset') === '1') {
|
||||
setResendInfo(
|
||||
'Your two-factor methods were reset. Sign in to set up a new one.',
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -59,7 +63,9 @@ export default function LoginPage() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
router.push('/dashboard');
|
||||
// Hand off to the MFA gate: the challenge page completes step-up (or
|
||||
// redirects to enrollment for users without a verified factor).
|
||||
router.push('/security/challenge');
|
||||
router.refresh();
|
||||
});
|
||||
}
|
||||
@@ -120,7 +126,7 @@ export default function LoginPage() {
|
||||
)}
|
||||
<div className="row" style={{ marginTop: '1rem' }}>
|
||||
<button type="submit" disabled={isPending}>
|
||||
{isPending ? 'Signing in…' : 'Sign in'}
|
||||
{isPending ? 'Verifying…' : 'Sign in'}
|
||||
</button>
|
||||
<Link className="muted" href="/signup">
|
||||
Need an account?
|
||||
|
||||
Reference in New Issue
Block a user