From 28bc86e23b50cd5569e2bcfaff58aec381b60673 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Sat, 17 Jul 2021 14:43:15 -0600 Subject: [PATCH] ui(account): implement delete security key button --- .../{deleteKey.ts => deleteWebauthnKey.ts} | 0 ...{registerKey.ts => registerWebauthnKey.ts} | 0 .../dashboard/SecurityKeyContainer.tsx | 50 +++++++++++++++---- 3 files changed, 41 insertions(+), 9 deletions(-) rename resources/scripts/api/account/webauthn/{deleteKey.ts => deleteWebauthnKey.ts} (100%) rename resources/scripts/api/account/webauthn/{registerKey.ts => registerWebauthnKey.ts} (100%) diff --git a/resources/scripts/api/account/webauthn/deleteKey.ts b/resources/scripts/api/account/webauthn/deleteWebauthnKey.ts similarity index 100% rename from resources/scripts/api/account/webauthn/deleteKey.ts rename to resources/scripts/api/account/webauthn/deleteWebauthnKey.ts diff --git a/resources/scripts/api/account/webauthn/registerKey.ts b/resources/scripts/api/account/webauthn/registerWebauthnKey.ts similarity index 100% rename from resources/scripts/api/account/webauthn/registerKey.ts rename to resources/scripts/api/account/webauthn/registerWebauthnKey.ts diff --git a/resources/scripts/components/dashboard/SecurityKeyContainer.tsx b/resources/scripts/components/dashboard/SecurityKeyContainer.tsx index 78a0ccbc2..1d72dbbe4 100644 --- a/resources/scripts/components/dashboard/SecurityKeyContainer.tsx +++ b/resources/scripts/components/dashboard/SecurityKeyContainer.tsx @@ -1,9 +1,13 @@ 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 registerKey from '@/api/account/webauthn/registerKey'; +import registerWebauthnKey from '@/api/account/webauthn/registerWebauthnKey'; import FlashMessageRender from '@/components/FlashMessageRender'; import Button from '@/components/elements/Button'; import ContentBox from '@/components/elements/ContentBox'; @@ -12,9 +16,7 @@ import GreyRowBox from '@/components/elements/GreyRowBox'; import PageContentBlock from '@/components/elements/PageContentBlock'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import useFlash from '@/plugins/useFlash'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faKey, faTrashAlt } from '@fortawesome/free-solid-svg-icons'; -import { format } from 'date-fns'; +import ConfirmationModal from '@/components/elements/ConfirmationModal'; interface Values { name: string; @@ -26,17 +28,16 @@ const AddSecurityKeyForm = ({ onKeyAdded }: { onKeyAdded: (key: WebauthnKey) => const submit = ({ name }: Values, { setSubmitting, resetForm }: FormikHelpers) => { clearFlashes('security_keys'); - registerKey(name) + registerWebauthnKey(name) .then(key => { resetForm(); - setSubmitting(false); onKeyAdded(key); }) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'security_keys', error }); - setSubmitting(false); - }); + }) + .then(() => setSubmitting(false)); }; return ( @@ -71,6 +72,24 @@ export default () => { 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'); @@ -90,6 +109,19 @@ export default () => {
+ { + doDeletion(deleteId); + setDeleteId(null); + }} + onModalDismissed={() => setDeleteId(null)} + > + Are you sure you wish to delete this API key? All requests using it will immediately be + invalidated and will fail. + {keys.length === 0 ? !loading ?

@@ -107,7 +139,7 @@ export default () => { {key.lastUsedAt ? format(key.lastUsedAt, 'MMM do, yyyy HH:mm') : 'Never'}

-