mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 20:11:14 -05:00
110 lines
3.5 KiB
TypeScript
110 lines
3.5 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { supabase } from '@/integrations/supabase/client';
|
|
import { useToast } from '@/hooks/use-toast';
|
|
import { Header } from '@/components/layout/Header';
|
|
import { MFAChallenge } from '@/components/auth/MFAChallenge';
|
|
import { Shield } from 'lucide-react';
|
|
import { getStepUpRequired, getIntendedPath, clearStepUpFlags } from '@/lib/sessionFlags';
|
|
import { getEnrolledFactors } from '@/lib/authService';
|
|
|
|
export default function MFAStepUp() {
|
|
const navigate = useNavigate();
|
|
const { toast } = useToast();
|
|
const [factorId, setFactorId] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const checkStepUpRequired = async () => {
|
|
// Check if this page was accessed via proper flow
|
|
if (!getStepUpRequired()) {
|
|
console.log('[MFAStepUp] No step-up flag found, redirecting to auth');
|
|
navigate('/auth');
|
|
return;
|
|
}
|
|
|
|
// Get enrolled MFA factors
|
|
const factors = await getEnrolledFactors();
|
|
|
|
if (factors.length === 0) {
|
|
console.log('[MFAStepUp] No verified TOTP factor found');
|
|
toast({
|
|
variant: 'destructive',
|
|
title: 'MFA not enrolled',
|
|
description: 'Please enroll in two-factor authentication first.',
|
|
});
|
|
clearStepUpFlags();
|
|
navigate('/settings?tab=security');
|
|
return;
|
|
}
|
|
|
|
setFactorId(factors[0].id);
|
|
};
|
|
|
|
checkStepUpRequired();
|
|
}, [navigate, toast]);
|
|
|
|
const handleSuccess = async () => {
|
|
console.log('[MFAStepUp] MFA verification successful');
|
|
|
|
toast({
|
|
title: 'Verification successful',
|
|
description: 'You now have full access to all features.',
|
|
});
|
|
|
|
// Redirect to home or intended destination
|
|
const intendedPath = getIntendedPath();
|
|
clearStepUpFlags();
|
|
navigate(intendedPath);
|
|
};
|
|
|
|
const handleCancel = async () => {
|
|
console.log('[MFAStepUp] MFA verification cancelled');
|
|
|
|
// Clear flags and redirect to sign-in (less harsh than forcing sign-out)
|
|
clearStepUpFlags();
|
|
|
|
toast({
|
|
title: 'Verification cancelled',
|
|
description: 'Please sign in again to continue.',
|
|
});
|
|
|
|
navigate('/auth');
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background">
|
|
<Header />
|
|
|
|
<main className="container mx-auto px-4 py-16">
|
|
<div className="max-w-md mx-auto">
|
|
<div className="bg-card border rounded-lg p-6 space-y-6">
|
|
<div className="text-center space-y-2">
|
|
<div className="flex justify-center">
|
|
<div className="h-12 w-12 rounded-full bg-primary/10 flex items-center justify-center">
|
|
<Shield className="h-6 w-6 text-primary" />
|
|
</div>
|
|
</div>
|
|
<h2 className="text-2xl font-bold">Additional Verification Required</h2>
|
|
<p className="text-muted-foreground">
|
|
Your role requires two-factor authentication. Please verify your identity to continue.
|
|
</p>
|
|
</div>
|
|
|
|
{factorId ? (
|
|
<MFAChallenge
|
|
factorId={factorId}
|
|
onSuccess={handleSuccess}
|
|
onCancel={handleCancel}
|
|
/>
|
|
) : (
|
|
<div className="flex justify-center py-4">
|
|
<div className="animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full" />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|