From 9ab4c510fea038f380fb3141f0fdfe54244db61e Mon Sep 17 00:00:00 2001 From: garronej Date: Thu, 20 Apr 2023 20:08:47 +0200 Subject: [PATCH] #209 --- src/login/pages/WebauthnAuthenticate.tsx | 55 +++++++++++++++++------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/login/pages/WebauthnAuthenticate.tsx b/src/login/pages/WebauthnAuthenticate.tsx index 7e34f8ed..068de835 100644 --- a/src/login/pages/WebauthnAuthenticate.tsx +++ b/src/login/pages/WebauthnAuthenticate.tsx @@ -7,6 +7,9 @@ import type { PageProps } from "keycloakify/login/pages/PageProps"; import { useGetClassName } from "keycloakify/login/lib/useGetClassName"; import type { KcContext } from "../kcContext"; import type { I18n } from "../i18n"; +import { assert } from "tsafe/assert"; +import { is } from "tsafe/is"; +import { typeGuard } from "tsafe/typeGuard"; export default function WebauthnAuthenticate(props: PageProps, I18n>) { const { kcContext, i18n, doUseDefaultCss, Template, classes } = props; @@ -21,10 +24,24 @@ export default function WebauthnAuthenticate(props: PageProps(null); + const webAuthnAuthenticate = useConstCallback(async () => { if (!isUserIdentified) { return; } + + const submitForm = async (): Promise => { + const formElement = formElementRef.current; + + if (formElement === null) { + await new Promise(resolve => setTimeout(resolve, 100)); + return submitForm(); + } + + formElement.submit(); + }; + const allowCredentials = authenticators.authenticators.map( authenticator => ({ @@ -57,30 +74,36 @@ export default function WebauthnAuthenticate(props: PageProps(result)); + if (!("authenticatorData" in result.response)) { + return; + } + const response = result.response; + const clientDataJSON = response.clientDataJSON; + + assert( + typeGuard(response, "signature" in response && response.authenticatorData instanceof ArrayBuffer), + "response not an AuthenticatorAssertionResponse" + ); + const authenticatorData = response.authenticatorData; const signature = response.signature; - setClientDataJSON(base64url.stringify(new Uint8Array(clientDataJSON), { pad: false })); - setAuthenticatorData(base64url.stringify(new Uint8Array(authenticatorData), { pad: false })); - setSignature(base64url.stringify(new Uint8Array(signature), { pad: false })); + setClientDataJSON(base64url.stringify(new Uint8Array(clientDataJSON), { "pad": false })); + setAuthenticatorData(base64url.stringify(new Uint8Array(authenticatorData), { "pad": false })); + setSignature(base64url.stringify(new Uint8Array(signature), { "pad": false })); setCredentialId(result.id); - setUserHandle(base64url.stringify(new Uint8Array(response.userHandle!), { pad: false })); - submitForm(); + setUserHandle(base64url.stringify(new Uint8Array(response.userHandle!), { "pad": false })); } catch (err) { setError(String(err)); - submitForm(); } - }); - const webAuthForm = useRef(null); - const submitForm = useConstCallback(() => { - webAuthForm.current!.submit(); + submitForm(); }); const [clientDataJSON, setClientDataJSON] = useState(""); @@ -93,7 +116,7 @@ export default function WebauthnAuthenticate(props: PageProps
-
+