'use client' import { useState } from 'react' import { AuthenticatorType } from '../../defines' import { useAllauthAPI } from '../../contexts/APIContext' import { useStyles } from '../../contexts/StylesContext' import { AuthCard } from '../AuthCard' import { MFATOTPView } from './MFATOTPView' import { MFAWebAuthnView } from './MFAWebAuthnView' import { MFARecoveryCodesView } from './MFARecoveryCodesView' const MFA_OPTIONS: Record = { [AuthenticatorType.WEBAUTHN]: { label: 'Security Key / Passkey', description: 'Use your registered security key or passkey', }, [AuthenticatorType.TOTP]: { label: 'Authenticator App', description: 'Enter a code from your authenticator app', }, [AuthenticatorType.RECOVERY_CODES]: { label: 'Recovery Code', description: 'Use one of your recovery codes', }, } interface MFAChooserViewProps { types: string[] onSuccess?: () => void onCancel?: () => void isReauth?: boolean } export function MFAChooserView({ types, onSuccess, onCancel, isReauth }: MFAChooserViewProps) { const api = useAllauthAPI() const styles = useStyles() const [selectedType, setSelectedType] = useState(null) const [cancelling, setCancelling] = useState(false) // Filter to only show options that are available const availableOptions = types .filter(type => MFA_OPTIONS[type]) .map(type => ({ type, ...MFA_OPTIONS[type] })) const handleCancel = async () => { setCancelling(true) try { await api.session.logout() onCancel?.() } catch { setCancelling(false) } } const handleBack = types.length > 1 ? () => setSelectedType(null) : undefined // If a type is selected, show that method's view if (selectedType === AuthenticatorType.TOTP) { return ( ) } if (selectedType === AuthenticatorType.WEBAUTHN) { return ( ) } if (selectedType === AuthenticatorType.RECOVERY_CODES) { return ( ) } // Show chooser if (availableOptions.length === 0) { return ( ) } return (

Two-Factor Authentication

Choose how you want to verify your identity.

{availableOptions.map(option => ( ))}
{onCancel && (
)}
) }