import React, { useContext, useEffect, useState } from 'react'; import { Form, Formik, FormikHelpers } from 'formik'; import { object, string } from 'yup'; import getTwoFactorTokenData, { TwoFactorTokenData } from '@/api/account/getTwoFactorTokenData'; import enableAccountTwoFactor from '@/api/account/enableAccountTwoFactor'; import { Actions, useStoreActions } from 'easy-peasy'; import { ApplicationStore } from '@/state'; import FlashMessageRender from '@/components/FlashMessageRender'; import Field from '@/components/elements/Field'; import tw from 'twin.macro'; import Button from '@/components/elements/Button'; import asModal from '@/hoc/asModal'; import ModalContext from '@/context/ModalContext'; import QRCode from 'qrcode.react'; import CopyOnClick from '@/components/elements/CopyOnClick'; interface Values { code: string; } const SetupTwoFactorModal = () => { const [ token, setToken ] = useState(null); const [ recoveryTokens, setRecoveryTokens ] = useState([]); const { dismiss, setPropOverrides } = useContext(ModalContext); const updateUserData = useStoreActions((actions: Actions) => actions.user.updateUserData); const { clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes); useEffect(() => { getTwoFactorTokenData() .then(setToken) .catch(error => { console.error(error); clearAndAddHttpError({ error, key: 'account:two-factor' }); }); }, []); const submit = ({ code }: Values, { setSubmitting }: FormikHelpers) => { setPropOverrides(state => ({ ...state, showSpinnerOverlay: true })); enableAccountTwoFactor(code) .then(tokens => { setRecoveryTokens(tokens); }) .catch(error => { console.error(error); clearAndAddHttpError({ error, key: 'account:two-factor' }); }) .then(() => { setSubmitting(false); setPropOverrides(state => ({ ...state, showSpinnerOverlay: false })); }); }; useEffect(() => { setPropOverrides(state => ({ ...state, closeOnEscape: !recoveryTokens.length, closeOnBackground: !recoveryTokens.length, })); return () => { if (recoveryTokens.length > 0) { updateUserData({ useTotp: true }); } }; }, [ recoveryTokens ]); return ( {recoveryTokens.length > 0 ? <>

Two-factor authentication enabled

Two-factor authentication has been enabled on your account. Should you lose access to your authenticator device, you'll need to use one of the codes displayed below in order to access your account.

These codes will not be displayed again. Please take note of them now by storing them in a secure repository such as a password manager.

                        {recoveryTokens.map(token => {token})}
                    
:
{!token ? : }
{token &&
Alternatively, enter the following token into your authenticator application:
{token.secret}
}
}
); }; export default asModal()(SetupTwoFactorModal);