'use client'; import { useState, useEffect } from 'react'; import { Box, Typography, Card, CardContent, Button, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Alert, CircularProgress, Chip, Stack, List, ListItem, ListItemText, IconButton, Paper, } from '@mui/material'; import { Security, QrCode2, Email, ContentCopy, CheckCircle, } from '@mui/icons-material'; import { mfaApi, type MFAStatus, type TOTPSetupResult } from '@/lib/api/mfa'; import { motion } from 'framer-motion'; export function MFASettings() { const [mfaStatus, setMFAStatus] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); // TOTP Setup Dialog const [totpDialogOpen, setTotpDialogOpen] = useState(false); const [totpSetupData, setTotpSetupData] = useState(null); const [verificationCode, setVerificationCode] = useState(''); const [isVerifying, setIsVerifying] = useState(false); const [copiedCodes, setCopiedCodes] = useState>(new Set()); // Email MFA Dialog const [emailDialogOpen, setEmailDialogOpen] = useState(false); const [isSettingUpEmail, setIsSettingUpEmail] = useState(false); // Disable MFA Dialog const [disableDialogOpen, setDisableDialogOpen] = useState(false); const [isDisabling, setIsDisabling] = useState(false); // Load MFA status on mount useEffect(() => { loadMFAStatus(); }, []); const loadMFAStatus = async () => { try { setIsLoading(true); const status = await mfaApi.getStatus(); setMFAStatus(status); setError(null); } catch (err: any) { console.error('Failed to load MFA status:', err); setError('Failed to load MFA status'); } finally { setIsLoading(false); } }; const handleSetupTOTP = async () => { try { setIsLoading(true); const setupData = await mfaApi.setupTOTP(); setTotpSetupData(setupData); setTotpDialogOpen(true); setError(null); } catch (err: any) { console.error('Failed to setup TOTP:', err); setError(err.response?.data?.message || 'Failed to setup authenticator app'); } finally { setIsLoading(false); } }; const handleVerifyTOTP = async () => { if (!verificationCode || verificationCode.length !== 6) { setError('Please enter a valid 6-digit code'); return; } try { setIsVerifying(true); setError(null); await mfaApi.enableTOTP(verificationCode); setSuccessMessage('Two-factor authentication enabled successfully!'); setTotpDialogOpen(false); setVerificationCode(''); setTotpSetupData(null); await loadMFAStatus(); } catch (err: any) { console.error('Failed to verify TOTP:', err); setError(err.response?.data?.message || 'Invalid verification code'); } finally { setIsVerifying(false); } }; const handleSetupEmailMFA = async () => { try { setIsSettingUpEmail(true); setError(null); await mfaApi.setupEmailMFA(); setSuccessMessage('Email-based 2FA enabled successfully! Check your email for backup codes.'); setEmailDialogOpen(false); await loadMFAStatus(); } catch (err: any) { console.error('Failed to setup email MFA:', err); setError(err.response?.data?.message || 'Failed to setup email 2FA'); } finally { setIsSettingUpEmail(false); } }; const handleDisableMFA = async () => { try { setIsDisabling(true); setError(null); await mfaApi.disableMFA(); setSuccessMessage('Two-factor authentication disabled'); setDisableDialogOpen(false); await loadMFAStatus(); } catch (err: any) { console.error('Failed to disable MFA:', err); setError(err.response?.data?.message || 'Failed to disable 2FA'); } finally { setIsDisabling(false); } }; const copyBackupCode = (code: string, index: number) => { navigator.clipboard.writeText(code); setCopiedCodes(new Set(copiedCodes).add(index)); setTimeout(() => { setCopiedCodes((prev) => { const newSet = new Set(prev); newSet.delete(index); return newSet; }); }, 2000); }; if (isLoading && !mfaStatus) { return ( ); } return ( <> Two-Factor Authentication {mfaStatus?.enabled && ( )} Add an extra layer of security to your account by enabling two-factor authentication. {error && ( setError(null)}> {error} )} {successMessage && ( setSuccessMessage(null)}> {successMessage} )} {!mfaStatus?.enabled ? ( ) : ( Two-factor authentication is currently enabled using{' '} {mfaStatus.method === 'totp' ? 'Authenticator App' : 'Email'}. )} {/* TOTP Setup Dialog */} setTotpDialogOpen(false)} maxWidth="sm" fullWidth> Setup Authenticator App Scan the QR code below with your authenticator app (Google Authenticator, Authy, etc.) {totpSetupData && ( <> {/* QR Code */} QR Code {/* Manual Entry Code */} Can't scan? Enter this code manually: {totpSetupData.secret} {/* Backup Codes */} Save your backup codes Store these codes in a safe place. Each can only be used once. {totpSetupData.backupCodes.map((code, index) => ( copyBackupCode(code, index)} > {copiedCodes.has(index) ? ( ) : ( )} } > ))} {/* Verification Code Input */} setVerificationCode(e.target.value.replace(/\D/g, '').slice(0, 6))} helperText="Enter the 6-digit code from your authenticator app" error={!!error} disabled={isVerifying} /> )} {/* Email MFA Dialog */} setEmailDialogOpen(false)} maxWidth="sm" fullWidth> Setup Email Authentication You will receive a verification code via email each time you log in. Backup codes will be sent to your email. Make sure to save them in a secure place. {/* Disable MFA Dialog */} setDisableDialogOpen(false)} maxWidth="sm" fullWidth> Disable Two-Factor Authentication? Disabling two-factor authentication will make your account less secure. ); }