feat: Implement modal-based MFA step-up

This commit is contained in:
gpt-engineer-app[bot]
2025-10-17 19:17:46 +00:00
parent 152a90ae9d
commit 0eac7f3d7d
6 changed files with 123 additions and 116 deletions

View File

@@ -93,6 +93,24 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
// Track auth method for audit logging
setAuthMethod('password');
// Check if MFA step-up is required
const { handlePostAuthFlow } = await import('@/lib/authService');
const postAuthResult = await handlePostAuthFlow(data.session, 'password');
if (postAuthResult.success && postAuthResult.data.shouldRedirect) {
console.log('[AuthModal] MFA step-up required');
// Get the TOTP factor ID
const { data: factors } = await supabase.auth.mfa.listFactors();
const totpFactor = factors?.totp?.find(f => f.status === 'verified');
if (totpFactor) {
setMfaFactorId(totpFactor.id);
setLoading(false);
return; // Stay in modal, show MFA challenge
}
}
toast({
title: "Welcome back!",

View File

@@ -0,0 +1,34 @@
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { MFAChallenge } from './MFAChallenge';
import { Shield } from 'lucide-react';
interface MFAStepUpModalProps {
open: boolean;
factorId: string;
onSuccess: () => void;
onCancel: () => void;
}
export function MFAStepUpModal({ open, factorId, onSuccess, onCancel }: MFAStepUpModalProps) {
return (
<Dialog open={open} onOpenChange={(isOpen) => !isOpen && onCancel()}>
<DialogContent className="sm:max-w-md" onInteractOutside={(e) => e.preventDefault()}>
<DialogHeader>
<div className="flex items-center gap-2 justify-center mb-2">
<Shield className="h-6 w-6 text-primary" />
<DialogTitle>Additional Verification Required</DialogTitle>
</div>
<DialogDescription className="text-center">
Your role requires two-factor authentication. Please verify your identity to continue.
</DialogDescription>
</DialogHeader>
<MFAChallenge
factorId={factorId}
onSuccess={onSuccess}
onCancel={onCancel}
/>
</DialogContent>
</Dialog>
);
}