import { useState } from 'react' import { Navigate } from 'react-router-dom' import { useAuth } from '../contexts/AuthContext' type MfaStep = 'idle' | 'enrolling' | 'verifying' | 'success' | 'disabling' interface EnrollmentData { factorId: string qrCode: string secret: string } export function Settings() { const { user, loading, mfa, isOAuthUser, enrollMfa, verifyMfaEnrollment, unenrollMfa } = useAuth() const [step, setStep] = useState('idle') const [enrollmentData, setEnrollmentData] = useState(null) const [code, setCode] = useState('') const [error, setError] = useState(null) const [actionLoading, setActionLoading] = useState(false) const [disableFactorId, setDisableFactorId] = useState(null) if (loading) { return (
) } if (!user) { return } const hasMfa = mfa.enrolledFactors.length > 0 async function handleEnroll() { setError(null) setActionLoading(true) const { data, error: enrollError } = await enrollMfa() setActionLoading(false) if (enrollError || !data) { setError(enrollError?.message ?? 'Failed to start MFA enrollment') return } setEnrollmentData(data) setStep('enrolling') } async function handleVerifyEnrollment(e: React.FormEvent) { e.preventDefault() if (!enrollmentData) return setError(null) setActionLoading(true) const { error: verifyError } = await verifyMfaEnrollment(enrollmentData.factorId, code) setActionLoading(false) if (verifyError) { setError(verifyError.message) return } setStep('success') setCode('') } async function handleStartDisable(factorId: string) { setDisableFactorId(factorId) setStep('disabling') setCode('') setError(null) } async function handleConfirmDisable(e: React.FormEvent) { e.preventDefault() if (!disableFactorId) return setError(null) setActionLoading(true) const { error: unenrollError } = await unenrollMfa(disableFactorId) setActionLoading(false) if (unenrollError) { setError(unenrollError.message) return } setStep('idle') setDisableFactorId(null) setCode('') } function handleCancel() { setStep('idle') setEnrollmentData(null) setDisableFactorId(null) setCode('') setError(null) } return (

Settings

Two-Factor Authentication

{isOAuthUser ? (

You signed in with an OAuth provider (Google/Discord). MFA is managed by your provider.

) : ( <> {step === 'idle' && ( <> {hasMfa ? (
MFA is enabled

Your account is protected with two-factor authentication.

) : (

Add an extra layer of security to your account by enabling two-factor authentication with an authenticator app.

{error &&

{error}

}
)} )} {step === 'enrolling' && enrollmentData && (

Scan this QR code with your authenticator app (Google Authenticator, Authy, etc.):

MFA QR Code

Manual entry code (save this as a backup):

{enrollmentData.secret}

Save this code securely. You can use it to restore your authenticator if you lose access to your device.

setCode(e.target.value.replace(/\D/g, ''))} className="w-full px-3 py-2 bg-surface-2 border border-border-default rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-500 text-center text-lg tracking-widest font-mono" autoComplete="one-time-code" />
{error &&

{error}

}
)} {step === 'success' && (
MFA enabled successfully!

Your account is now protected with two-factor authentication. You'll need to enter a code from your authenticator app each time you sign in.

)} {step === 'disabling' && (

To disable MFA, enter a code from your authenticator app to confirm.

setCode(e.target.value.replace(/\D/g, ''))} className="w-full px-3 py-2 bg-surface-2 border border-border-default rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-500 text-center text-lg tracking-widest font-mono" autoComplete="one-time-code" />
{error &&

{error}

}
)} )}
) }