import { useState } from 'react'; import { Card, Title, Text, Stack, Group, Button, TextInput, PasswordInput, Alert, Code, SimpleGrid, Badge, Image, } from '@mantine/core'; import { IconShieldCheck, IconShieldOff, IconAlertCircle } from '@tabler/icons-react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { notifications } from '@mantine/notifications'; import api from '../../services/api'; export function MfaSettings() { const queryClient = useQueryClient(); const [setupData, setSetupData] = useState(null); const [recoveryCodes, setRecoveryCodes] = useState(null); const [verifyCode, setVerifyCode] = useState(''); const [disablePassword, setDisablePassword] = useState(''); const [showDisable, setShowDisable] = useState(false); const { data: mfaStatus, isLoading } = useQuery({ queryKey: ['mfa-status'], queryFn: async () => { const { data } = await api.get('/auth/mfa/status'); return data; }, }); const setupMutation = useMutation({ mutationFn: () => api.post('/auth/mfa/setup'), onSuccess: ({ data }) => setSetupData(data), onError: (err: any) => notifications.show({ message: err.response?.data?.message || 'Setup failed', color: 'red' }), }); const enableMutation = useMutation({ mutationFn: (token: string) => api.post('/auth/mfa/enable', { token }), onSuccess: ({ data }) => { setRecoveryCodes(data.recoveryCodes); setSetupData(null); setVerifyCode(''); queryClient.invalidateQueries({ queryKey: ['mfa-status'] }); notifications.show({ message: 'MFA enabled successfully', color: 'green' }); }, onError: (err: any) => notifications.show({ message: err.response?.data?.message || 'Invalid code', color: 'red' }), }); const disableMutation = useMutation({ mutationFn: (password: string) => api.post('/auth/mfa/disable', { password }), onSuccess: () => { setShowDisable(false); setDisablePassword(''); queryClient.invalidateQueries({ queryKey: ['mfa-status'] }); notifications.show({ message: 'MFA disabled', color: 'orange' }); }, onError: (err: any) => notifications.show({ message: err.response?.data?.message || 'Invalid password', color: 'red' }), }); if (isLoading) return null; return (
Two-Factor Authentication (MFA) Add an extra layer of security to your account
{mfaStatus?.enabled ? 'Enabled' : 'Disabled'}
{/* Recovery codes display (shown once after enable) */} {recoveryCodes && ( } title="Save your recovery codes"> These codes can be used to access your account if you lose your authenticator. Save them securely — they will not be shown again. {recoveryCodes.map((code, i) => ( {code} ))} )} {!mfaStatus?.enabled && !setupData && ( )} {/* QR Code Setup */} {setupData && ( Scan this QR code with your authenticator app (Google Authenticator, Authy, etc.): Manual entry key: {setupData.secret} setVerifyCode(e.currentTarget.value)} maxLength={6} /> )} {/* Disable MFA */} {mfaStatus?.enabled && !showDisable && ( )} {showDisable && ( Disabling MFA will make your account less secure. Enter your password to confirm. setDisablePassword(e.currentTarget.value)} /> )}
); }