import { useState } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { Trans } from '@lingui/react/macro'; import { useForm } from 'react-hook-form'; import { match } from 'ts-pattern'; import { z } from 'zod'; import { authClient } from '@documenso/auth/client'; import { downloadFile } from '@documenso/lib/client-only/download-file'; import { AppError } from '@documenso/lib/errors/app-error'; import { Alert, AlertDescription } from '@documenso/ui/primitives/alert'; import { Button } from '@documenso/ui/primitives/button'; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@documenso/ui/primitives/dialog'; import { Form, FormControl, FormField, FormItem, FormMessage, } from '@documenso/ui/primitives/form/form'; import { PinInput, PinInputGroup, PinInputSlot } from '@documenso/ui/primitives/pin-input'; import { RecoveryCodeList } from './recovery-code-list'; export const ZViewRecoveryCodesForm = z.object({ token: z.string().min(1, { message: 'Token is required' }), }); export type TViewRecoveryCodesForm = z.infer; export const ViewRecoveryCodesDialog = () => { const [isOpen, setIsOpen] = useState(false); const [recoveryCodes, setRecoveryCodes] = useState(null); const [error, setError] = useState(null); const form = useForm({ defaultValues: { token: '', }, resolver: zodResolver(ZViewRecoveryCodesForm), }); const onFormSubmit = async ({ token }: TViewRecoveryCodesForm) => { setError(null); try { const data = await authClient.twoFactor.viewRecoveryCodes({ token, }); setRecoveryCodes(data.backupCodes); } catch (err) { const error = AppError.parseError(err); setError(error.code); } }; const downloadRecoveryCodes = () => { if (recoveryCodes) { const blob = new Blob([recoveryCodes.join('\n')], { type: 'text/plain', }); downloadFile({ filename: 'documenso-2FA-recovery-codes.txt', data: blob, }); } }; return ( {recoveryCodes ? (
View Recovery Codes Your recovery codes are listed below. Please store them in a safe place.
) : (
View Recovery Codes Please provide a token from your authenticator, or a backup code.
( {Array(6) .fill(null) .map((_, i) => ( ))} )} /> {error && ( {match(AppError.parseError(error).message) .with('INCORRECT_TWO_FACTOR_CODE', () => ( Invalid code. Please try again. )) .otherwise(() => ( Something went wrong. Please try again or contact support. ))} )}
)}
); };