'use client' import { useState } from 'react' import { useAllauthAPI } from '../../contexts/APIContext' import { useAuthContext } from '../../contexts/AuthContext' import { useStyles } from '../../contexts/StylesContext' interface MFAWebAuthnViewProps { onSuccess?: () => void onCancel?: () => void onBack?: () => void isReauth?: boolean } export function MFAWebAuthnView({ onSuccess, onCancel, onBack, isReauth }: MFAWebAuthnViewProps) { const api = useAllauthAPI() const { refresh } = useAuthContext() const styles = useStyles() const [error, setError] = useState(null) const [authenticating, setAuthenticating] = useState(false) const [cancelling, setCancelling] = useState(false) const handleCancel = async () => { setCancelling(true) try { await api.session.logout() onCancel?.() } catch { setCancelling(false) } } const handleWebAuthn = async () => { setError(null) setAuthenticating(true) try { const { startAuthentication } = await import('@simplewebauthn/browser') // Get challenge from server const optionsRes = isReauth ? await api.webauthn.requestOptions.reauthentication() : await api.webauthn.requestOptions.authentication() if (optionsRes.status !== 200 || !optionsRes.data?.request_options?.publicKey) { throw new Error('Failed to get authentication options') } // Perform WebAuthn authentication // The allauth API returns { request_options: { publicKey: {...} } } // @simplewebauthn/browser v13+ expects { optionsJSON: ... } const credential = await startAuthentication({ optionsJSON: optionsRes.data.request_options.publicKey as any }) // Verify with server const res = isReauth ? await api.webauthn.reauthenticate(credential) : await api.webauthn.authenticate(credential) if (res.status === 200) { await refresh() onSuccess?.() } else { setError('Authentication failed. Please try again.') } } catch (e: any) { if (e.name === 'AbortError' || e.name === 'NotAllowedError') { setError(null) } else { setError(e.message || 'Failed to authenticate with security key') } } finally { setAuthenticating(false) } } return (

Security Key

Use your security key to verify your identity.

{error && (

{error}

)}
{onBack && ( )} {onCancel && ( )}
) }