From ef13467aa1ecc4c214cc56e6d7751a6aa392edde Mon Sep 17 00:00:00 2001 From: Victor Tran Date: Mon, 23 Sep 2024 22:00:04 +1000 Subject: [PATCH] Get FIDO challenge asynchronously --- .../modals/account/LoginPasswordModal.tsx | 7 +++++ .../src/helpers/TokenAcquisitionSession.tsx | 26 +++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Parlance.ClientApp/src/components/modals/account/LoginPasswordModal.tsx b/Parlance.ClientApp/src/components/modals/account/LoginPasswordModal.tsx index 8baba1c8..f58055b0 100644 --- a/Parlance.ClientApp/src/components/modals/account/LoginPasswordModal.tsx +++ b/Parlance.ClientApp/src/components/modals/account/LoginPasswordModal.tsx @@ -58,6 +58,13 @@ export function LoginPasswordModal({ } }); + useEffect(() => { + if (acquisitionSession.loginTypes.includes("fido")) { + // Start getting the FIDO token now to save time later + void acquisitionSession.updateFidoToken(); + } + }, []); + return ( void; private readonly _failureFunction: () => void; private loginSessionDetails: Record = {}; + private fidoTokenResponse: Promise | undefined; constructor( username: string, @@ -162,15 +163,24 @@ export class TokenAcquisitionSession { } } + updateFidoToken() { + if (this.fidoTokenResponse) return this.fidoTokenResponse; + this.fidoTokenResponse = Fetch.post( + "/api/user/token", + { + type: "fido", + username: this._username, + }, + ); + return this.fidoTokenResponse; + } + async attemptFido2Login() { Modal.mount(); let details: TokenResponseFido; try { - details = await Fetch.post("/api/user/token", { - type: "fido", - username: this._username, - }); + details = await this.updateFidoToken(); } catch { Modal.mount( , @@ -196,7 +206,10 @@ export class TokenAcquisitionSession { })) as PublicKeyCredential; console.log(assertion); - if (!assertion) throw assertion; + if (!assertion) { + // noinspection ExceptionCaughtLocallyJS + throw assertion; + } const response = assertion.response as AuthenticatorAssertionResponse; @@ -216,6 +229,9 @@ export class TokenAcquisitionSession { }, }); + // Require a new FIDO challenge next time in case this fails + this.fidoTokenResponse = undefined; + await this.attemptLogin({ fido2Details: details, });