You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: detect WebAuthn extensions by asking the browser (#9)
checkExtensionSupport() tested `'largeBlob' in PublicKeyCredential.prototype`.
Extensions are never properties of that interface — they arrive through
getClientExtensionResults() — so the test answered false in every browser ever
shipped, including ones with complete support. hmacSecret sat beside it
hard-coded to false. Together they meant the encrypted-keystore demo disabled
its own headline feature everywhere, and the checkbox could not be ticked at
all.
Measured on Chrome 148 rather than assumed: the prototype probe returns false
for largeBlob, prf and hmacCreateSecret, while getClientCapabilities() on the
same page reports all three true. Probing appid, credBlob and credProps the
same way also returns false, so this was never a vendor quirk — the question
was asked of the wrong object.
Worth naming what this means for #9. The crash it reported ("No hmac-secret
output from credential") did stop happening, but not because anything was
fixed: the path became unreachable when the detection started answering false
everywhere, which also took the working paths with it. The feature was quiet,
not well.
Now:
- checkExtensionSupport() reads getClientCapabilities(), reports prf alongside
largeBlob and hmacSecret, and returns `known` so callers can tell "the
browser says no" from "the browser cannot say". Treating the second as a
refusal is how a working feature gets disabled.
- extensionSupportFromCredential() reads what the authenticator actually agreed
to, from the registration response. Client support is not authenticator
support; only the ceremony settles it, and the answer belongs to the
credential.
- addLargeBlobToCredentialOptions() takes a support level, still 'required' by
default — under 'preferred' an unsupported authenticator yields a credential
whose secret was never written, which loses the keystore silently.
- The demo offers PRF and prefers it, matching the library default since 0.4.0.
It had hard-coded largeBlob and so never exercised PRF.
Tests: 12 new cases, including the old prototype probe kept as a regression
guard. 57 node tests pass, format and lint clean, the demo builds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0 commit comments