/* * Copyright (C) 2026 Fluxer Contributors * * This file is part of Fluxer. * * Fluxer is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Fluxer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Fluxer. If not, see . */ import FormField from '@app/components/auth/FormField'; import styles from '@app/components/auth/MfaScreen.module.css'; import {Button} from '@app/components/uikit/button/Button'; import {useMfaController} from '@app/hooks/useLoginFlow'; import type {LoginSuccessPayload, MfaChallenge} from '@app/viewmodels/auth/AuthFlow'; import {Trans, useLingui} from '@lingui/react/macro'; import {useId} from 'react'; interface MfaScreenProps { challenge: MfaChallenge; inviteCode?: string; onSuccess: (payload: LoginSuccessPayload) => Promise | void; onCancel: () => void; } const MfaScreen = ({challenge, inviteCode, onSuccess, onCancel}: MfaScreenProps) => { const {t} = useLingui(); const codeId = useId(); const { form, isLoading, fieldErrors, selectedMethod, setSelectedMethod, smsSent, handleSendSms, handleWebAuthn, isWebAuthnLoading, supports, } = useMfaController({ ticket: challenge.ticket, methods: {sms: challenge.sms, totp: challenge.totp, webauthn: challenge.webauthn}, inviteCode, onLoginSuccess: onSuccess, }); if (!selectedMethod && (supports.sms || supports.webauthn || supports.totp)) { return (

Two-factor authentication

Choose a verification method

{supports.totp && ( )} {supports.sms && ( )} {supports.webauthn && ( )}
); } return (

Two-factor authentication

{selectedMethod === 'sms' ? ( Enter the 6-digit code sent to your phone. ) : ( Enter the 6-digit code from your authenticator app or one of your backup codes. )}

{selectedMethod === 'sms' && !smsSent && supports.sms && (
)} {supports.webauthn && (
)}
form.setValue('code', value)} error={form.getError('code') || fieldErrors?.code} />
{(supports.sms || supports.webauthn || supports.totp) && ( )}
); }; export default MfaScreen;