From e90fdf5bed605dcc3835a12dcc5747039bf104b5 Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Wed, 27 Jan 2021 19:40:12 +0100 Subject: [PATCH] ui: tfa: make webAuthn abortable and restartable Fix two things: * do not reject the login promise when we get the abort DOMException error * safely save the original challenge string as we work on a reference here and avoid to convert to a UInt8 array twice to avoid an exception. Signed-off-by: Thomas Lamprecht --- www/LoginView.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/www/LoginView.js b/www/LoginView.js index fc3a3586..cd4aa063 100644 --- a/www/LoginView.js +++ b/www/LoginView.js @@ -380,11 +380,13 @@ Ext.define('PBS.login.TfaWindow', { let challenge = view.challenge.webauthn; - // Byte array fixup, keep challenge string: - let challenge_str = challenge.publicKey.challenge; - challenge.publicKey.challenge = PBS.Utils.base64url_to_bytes(challenge_str); - for (const cred of challenge.publicKey.allowCredentials) { - cred.id = PBS.Utils.base64url_to_bytes(cred.id); + if (typeof challenge.string !== 'string') { + // Byte array fixup, keep challenge string: + challenge.string = challenge.publicKey.challenge; + challenge.publicKey.challenge = PBS.Utils.base64url_to_bytes(challenge.string); + for (const cred of challenge.publicKey.allowCredentials) { + cred.id = PBS.Utils.base64url_to_bytes(cred.id); + } } let controller = new AbortController(); @@ -395,7 +397,12 @@ Ext.define('PBS.login.TfaWindow', { //Promise.race( ... hwrsp = await navigator.credentials.get(challenge); } catch (error) { - view.onReject(error); + // we do NOT want to fail login because of canceling the challenge actively, + // in some browser that's the only way to switch over to another method as the + // disallow user input during the time the challenge is active + // checking for error.code === DOMException.ABORT_ERR only works in firefox -.- + this.getViewModel().set('canConfirm', true); + // FIXME: better handling, show some message, ...? return; } finally { let waitingMessage = me.lookup('webAuthnWaiting'); @@ -407,7 +414,7 @@ Ext.define('PBS.login.TfaWindow', { let response = { id: hwrsp.id, type: hwrsp.type, - challenge: challenge_str, + challenge: challenge.string, rawId: PBS.Utils.bytes_to_base64url(hwrsp.rawId), response: { authenticatorData: PBS.Utils.bytes_to_base64url( -- 2.39.5