From 92f71f62d008634a35c54ec3d376301390ce1bb3 Mon Sep 17 00:00:00 2001 From: Scott Pouliot Date: Sat, 25 Apr 2026 15:56:17 -0400 Subject: [PATCH] Fix iOS passkey enrollment sheet appearing on password form submit Switch passkeySupported() from isConditionalMediationAvailable() to isUserVerifyingPlatformAuthenticatorAvailable(). The conditional API signals to iOS 17/18 that the page wants autofill passkey interception, causing Safari to show its own native enrollment bottom sheet when the password Sign In button is clicked. The platform authenticator check simply asks if the device has biometrics, with no UI side-effects. Co-Authored-By: Claude Sonnet 4.6 --- src/PowderCoating.Web/wwwroot/js/passkey.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/PowderCoating.Web/wwwroot/js/passkey.js b/src/PowderCoating.Web/wwwroot/js/passkey.js index f98c08c..47826d3 100644 --- a/src/PowderCoating.Web/wwwroot/js/passkey.js +++ b/src/PowderCoating.Web/wwwroot/js/passkey.js @@ -186,11 +186,21 @@ async function loginWithPasskey() { // ─── Feature detection ──────────────────────────────────────────────────────── -/** True if this browser + platform support WebAuthn conditional UI (passkeys). */ +/** + * True if the device has a user-verifying platform authenticator (Face ID, + * fingerprint, Windows Hello, etc.) that can handle our modal passkey flow. + * + * Deliberately uses isUserVerifyingPlatformAuthenticatorAvailable() rather than + * isConditionalMediationAvailable(). The conditional API signals to iOS Safari + * that the page wants autofill-style passkey interception, which causes iOS 17+ + * to show its own native passkey enrollment sheet when the password form is + * submitted — not what we want. The platform authenticator check simply asks + * "can this device do biometrics?" with no side-effects. + */ async function passkeySupported() { if (!window.PublicKeyCredential) return false; try { - return await PublicKeyCredential.isConditionalMediationAvailable?.() ?? false; + return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(); } catch { return false; }