import { useState } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Checkbox } from '@/components/ui/checkbox'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { AlertTriangle, Trash2, Shield, CheckCircle2 } from 'lucide-react'; import { supabase } from '@/integrations/supabase/client'; import { useAuth } from '@/hooks/useAuth'; import { MFAChallenge } from '@/components/auth/MFAChallenge'; import { toast } from '@/hooks/use-toast'; import type { UserRole } from '@/hooks/useUserRole'; import { handleError } from '@/lib/errorHandler'; interface AdminUserDeletionDialogProps { open: boolean; onOpenChange: (open: boolean) => void; targetUser: { userId: string; username: string; email: string; displayName?: string; roles: UserRole[]; }; onDeletionComplete: () => void; } type DeletionStep = 'warning' | 'aal2_verification' | 'final_confirm' | 'deleting' | 'complete'; export function AdminUserDeletionDialog({ open, onOpenChange, targetUser, onDeletionComplete }: AdminUserDeletionDialogProps) { const { session } = useAuth(); const [step, setStep] = useState('warning'); const [confirmationText, setConfirmationText] = useState(''); const [acknowledged, setAcknowledged] = useState(false); const [error, setError] = useState(null); const [factorId, setFactorId] = useState(null); // Reset state when dialog opens/closes const handleOpenChange = (isOpen: boolean) => { if (!isOpen) { setStep('warning'); setConfirmationText(''); setAcknowledged(false); setError(null); setFactorId(null); } onOpenChange(isOpen); }; // Step 1: Show warning and proceed const handleContinueFromWarning = async () => { setError(null); // Check if user needs AAL2 verification const { data: factorsData } = await supabase.auth.mfa.listFactors(); const hasMFAEnrolled = factorsData?.totp?.some(f => f.status === 'verified') || false; if (hasMFAEnrolled) { // Check current AAL from JWT if (session) { const jwt = session.access_token; const payload = JSON.parse(atob(jwt.split('.')[1])); const currentAal = payload.aal || 'aal1'; if (currentAal !== 'aal2') { // Need to verify MFA const verifiedFactor = factorsData?.totp?.find(f => f.status === 'verified'); if (verifiedFactor) { setFactorId(verifiedFactor.id); setStep('aal2_verification'); return; } } } } // If no MFA or already at AAL2, go directly to final confirmation setStep('final_confirm'); }; // Step 2: Handle successful AAL2 verification const handleAAL2Success = () => { setStep('final_confirm'); }; // Step 3: Perform deletion const handleDelete = async () => { setError(null); setStep('deleting'); try { const { data, error: functionError } = await supabase.functions.invoke('admin-delete-user', { body: { targetUserId: targetUser.userId } }); if (functionError) { throw functionError; } if (!data.success) { if (data.errorCode === 'aal2_required') { // Session degraded during deletion, restart AAL2 flow setError('Your session requires re-verification. Please verify again.'); const { data: factorsData } = await supabase.auth.mfa.listFactors(); const verifiedFactor = factorsData?.totp?.find(f => f.status === 'verified'); if (verifiedFactor) { setFactorId(verifiedFactor.id); setStep('aal2_verification'); } else { setStep('warning'); } return; } throw new Error(data.error || 'Failed to delete user'); } // Success setStep('complete'); setTimeout(() => { toast({ title: 'User Deleted', description: `${targetUser.username} has been permanently deleted.`, }); onDeletionComplete(); handleOpenChange(false); }, 2000); } catch (err) { handleError(err, { action: 'Delete User', metadata: { targetUserId: targetUser.userId } }); setError(err instanceof Error ? err.message : 'Failed to delete user'); setStep('final_confirm'); } }; const isDeleteEnabled = confirmationText === 'DELETE' && acknowledged; return ( step === 'deleting' && e.preventDefault()} > {/* Step 1: Warning */} {step === 'warning' && ( <>
Delete User Account
You are about to permanently delete this user's account
{/* User details */}
Username: {targetUser.username}
Email: {targetUser.email}
{targetUser.displayName && (
Display Name: {targetUser.displayName}
)}
Roles: {targetUser.roles.join(', ') || 'None'}
{/* Critical warning */} This action is IMMEDIATE and PERMANENT. It cannot be undone. {/* What will be deleted */}

Will be deleted:

  • User profile and personal information
  • All reviews and ratings
  • Account preferences and settings
  • Authentication credentials
{/* What will be preserved */}

Will be preserved (as anonymous):

  • Content submissions (parks, rides, etc.)
  • Uploaded photos
{error && ( {error} )}
)} {/* Step 2: AAL2 Verification */} {step === 'aal2_verification' && factorId && ( <>
Multi-Factor Authentication Verification Required
This is a critical action that requires additional verification
{error && ( {error} )} { setStep('warning'); setError(null); }} /> )} {/* Step 3: Final Confirmation */} {step === 'final_confirm' && ( <>
Final Confirmation
Type DELETE to confirm permanent deletion
Last chance to cancel!
Deleting {targetUser.username} will immediately and permanently remove their account.
setConfirmationText(e.target.value)} placeholder="Type DELETE" className="font-mono" autoComplete="off" />
setAcknowledged(checked as boolean)} />
{error && ( {error} )}
)} {/* Step 4: Deleting */} {step === 'deleting' && (

Deleting User...

This may take a moment. Please do not close this dialog.

)} {/* Step 5: Complete */} {step === 'complete' && (

User Deleted Successfully

{targetUser.username} has been permanently removed.

)}
); }