import React, { useEffect, useState } from 'react'; import { format } from 'date-fns'; import { Form, Formik, FormikHelpers } from 'formik'; import tw from 'twin.macro'; import { object, string } from 'yup'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faKey, faTrashAlt } from '@fortawesome/free-solid-svg-icons'; import deleteWebauthnKey from '@/api/account/webauthn/deleteWebauthnKey'; import getWebauthnKeys, { WebauthnKey } from '@/api/account/webauthn/getWebauthnKeys'; import registerWebauthnKey from '@/api/account/webauthn/registerWebauthnKey'; import FlashMessageRender from '@/components/FlashMessageRender'; import Button from '@/components/elements/Button'; import ContentBox from '@/components/elements/ContentBox'; import Field from '@/components/elements/Field'; import GreyRowBox from '@/components/elements/GreyRowBox'; import PageContentBlock from '@/components/elements/PageContentBlock'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import useFlash from '@/plugins/useFlash'; import ConfirmationModal from '@/components/elements/ConfirmationModal'; interface Values { name: string; } const AddSecurityKeyForm = ({ onKeyAdded }: { onKeyAdded: (key: WebauthnKey) => void }) => { const { clearFlashes, clearAndAddHttpError } = useFlash(); const submit = ({ name }: Values, { setSubmitting, resetForm }: FormikHelpers) => { clearFlashes('security_keys'); registerWebauthnKey(name) .then(key => { resetForm(); onKeyAdded(key); }) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'security_keys', error }); }) .then(() => setSubmitting(false)); }; return ( {({ isSubmitting }) => (
)}
); }; export default () => { const { clearFlashes, clearAndAddHttpError } = useFlash(); const [ keys, setKeys ] = useState([]); const [ loading, setLoading ] = useState(true); const [ deleteId, setDeleteId ] = useState(null); const doDeletion = (id: number | null) => { if (id === null) { return; } clearFlashes('security_keys'); deleteWebauthnKey(id) .then(() => setKeys(s => ([ ...(s || []).filter(key => key.id !== id), ]))) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'security_keys', error }); }); }; useEffect(() => { clearFlashes('security_keys'); getWebauthnKeys() .then(keys => setKeys(keys)) .then(() => setLoading(false)) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'security_keys', error }); }); }, []); return (
{ doDeletion(deleteId); setDeleteId(null); }} onModalDismissed={() => setDeleteId(null)} > Are you sure you wish to delete this security key? You will no longer be able to authenticate using this key. {keys.length === 0 ? !loading ?

No security keys have been configured for this account.

: null : keys.map((key, index) => ( 0 && tw`mt-2` ]}>

{key.name}

Last used:  {key.lastUsedAt ? format(key.lastUsedAt, 'MMM do, yyyy HH:mm') : 'Never'}

)) }
setKeys(s => ([ ...s!, key ]))}/>
); };