feat: Implement MFA Step-Up for OAuth

This commit is contained in:
gpt-engineer-app[bot]
2025-10-14 13:52:11 +00:00
parent 7aa219efe5
commit ccfa83faee
6 changed files with 225 additions and 9 deletions

View File

@@ -2,21 +2,46 @@ import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Shield } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '@/hooks/useAuth';
import { useEffect, useState } from 'react';
export function MFARequiredAlert() {
const navigate = useNavigate();
const { checkAalStepUp } = useAuth();
const [needsVerification, setNeedsVerification] = useState(false);
useEffect(() => {
checkAalStepUp().then(result => {
setNeedsVerification(result.needsStepUp);
});
}, [checkAalStepUp]);
const handleAction = () => {
if (needsVerification) {
// User has MFA enrolled but needs to verify
sessionStorage.setItem('mfa_step_up_required', 'true');
navigate('/auth/mfa-step-up');
} else {
// User needs to enroll in MFA
navigate('/settings?tab=security');
}
};
return (
<Alert variant="destructive" className="my-4">
<Shield className="h-4 w-4" />
<AlertTitle>Two-Factor Authentication Required</AlertTitle>
<AlertDescription className="mt-2 space-y-3">
<p>Your role requires two-factor authentication to access this area.</p>
<p>
{needsVerification
? 'Please verify your identity with two-factor authentication to access this area.'
: 'Your role requires two-factor authentication to access this area.'}
</p>
<Button
onClick={() => navigate('/settings?tab=security')}
onClick={handleAction}
size="sm"
>
Set up MFA
{needsVerification ? 'Verify Now' : 'Set up MFA'}
</Button>
</AlertDescription>
</Alert>

View File

@@ -111,16 +111,31 @@ export function TOTPSetup() {
if (verifyError) throw verifyError;
// Check if user signed in via OAuth
const { data: { session } } = await supabase.auth.getSession();
const provider = session?.user?.app_metadata?.provider;
const isOAuthUser = provider === 'google' || provider === 'discord';
toast({
title: 'TOTP Enabled',
description: 'Please sign in again to activate MFA protection.'
description: isOAuthUser
? 'Please verify with your authenticator code to continue.'
: 'Please sign in again to activate MFA protection.'
});
// Force sign out to get new session with AAL2
setTimeout(async () => {
await supabase.auth.signOut();
window.location.href = '/auth';
}, 2000);
if (isOAuthUser) {
// For OAuth users, trigger step-up flow immediately
setTimeout(() => {
sessionStorage.setItem('mfa_step_up_required', 'true');
window.location.href = '/auth/mfa-step-up';
}, 1500);
} else {
// For email/password users, force sign out to require MFA on next login
setTimeout(async () => {
await supabase.auth.signOut();
window.location.href = '/auth';
}, 2000);
}
} catch (error: any) {
toast({
title: 'Error',