From d8410a0ea96d35aaf65b00fc872d51093910f71a Mon Sep 17 00:00:00 2001 From: Eiji Kitamura Date: Wed, 6 Nov 2024 18:23:14 +0900 Subject: [PATCH] Better polyfill --- public/webauthn-polyfill.js | 30 +++++++++++++++++++----------- views/index.html | 8 ++++---- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/public/webauthn-polyfill.js b/public/webauthn-polyfill.js index 700f881..22d3ecf 100644 --- a/public/webauthn-polyfill.js +++ b/public/webauthn-polyfill.js @@ -18,6 +18,21 @@ export class base64url { } if (window.PublicKeyCredential) { + const uap = new UAParser(); + const browser = uap.getBrowser(); + if (!browser?.version) { + throw new Error('Browser major version not found.'); + } + const browserName = browser.name; + const browserVer = parseFloat(browser.version.replace(/^([0-9]+\.[0-9]+).*$/, '$1')); + + const engine = uap.getEngine(); + if (!engine?.version) { + throw new Error('Engine version not found.'); + } + const engineName = engine.name; + const engineVer = parseFloat(engine.version.replace(/^([0-9]+\.[0-9]+)\.*$/, '$1')); + if (!window.PublicKeyCredential?.parseCreationOptionsFromJSON) { PublicKeyCredential.parseCreationOptionsFromJSON = (options) => { const user = { @@ -103,7 +118,9 @@ if (window.PublicKeyCredential) { } } - if (!PublicKeyCredential.getClientCapabilities) { + if (!PublicKeyCredential.getClientCapabilities || + // If this is Safari 17.4+, there's a spec glitch. + (browserName === 'Safari' && browserVer >= 17.4)) { PublicKeyCredential.getClientCapabilities = async () => { let conditionalCreate = false; let conditionalGet = false; @@ -134,20 +151,11 @@ if (window.PublicKeyCredential) { signalUnknownCredential = true; } - const uap = new UAParser(); - const browser = uap.getBrowser(); - const browserName = browser.name; - const browserVer = parseInt(browser.major); - const engine = uap.getEngine(); - const engineName = engine.name; - const engineVer = parseInt(engine.version.replace(/^([0-9]+)\.*$/, '$1')); - // `conditionalCreate` is `true` on Safari 15+ - if (browserName === 'Safari' && browserVer >= 15) { + if (browserName === 'Safari' && browserVer >= 18) { conditionalCreate = true; } // `hybridTransport` is `true` on Firefox 119+, Chromium 108+ and Safari 16+ - // TODO: These version numbers may not be precise. if ((engineName === 'Blink' && engineVer >= 108) || (browserName === 'Firefox' && browserVer >= 119) || (browserName === 'Safari' && browserVer >= 16)) { diff --git a/views/index.html b/views/index.html index 31e3200..78133fb 100644 --- a/views/index.html +++ b/views/index.html @@ -64,11 +64,11 @@

Enter a username

}); // Feature detection: check if WebAuthn and conditional UI are supported. - if (window.PublicKeyCredential && - PublicKeyCredential.isConditionalMediationAvailable) { + if (window.PublicKeyCredential) { try { - const cma= await PublicKeyCredential.isConditionalMediationAvailable(); - if (cma) { + const capabilities = await PublicKeyCredential.getClientCapabilities(); + if (capabilities.passkeyPlatformAuthenticator && + capabilities.conditionalGet) { // If a conditional UI is supported, invoke the conditional `authenticate()` immediately. const user = await authenticate(true); if (user) {