mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
* feat: support WebAuthn Touch ID platform authenticator on macOS
Adds `app.configureWebAuthn({ touchID: { keychainAccessGroup } })` to enable
the Secure Enclave platform authenticator for `navigator.credentials`.
Credentials are stored under the app-supplied keychain access group with a
per-session metadata secret that is generated on first use and persisted in
prefs.
Also introduces `ElectronAuthenticatorRequestClientDelegate` and wires it via
`ContentBrowserClient::GetWebAuthenticationRequestDelegate()` so that
discoverable-credential `get()` calls with multiple matches emit a new
`select-webauthn-account` session event instead of DCHECK-failing in the base
delegate. If no listener is registered (or the callback is invoked with no
credential), the request is cancelled with NotAllowedError rather than
silently auto-selecting.
Tests use the DevTools virtual authenticator so the account-selection flow is
exercised in CI without entitlements or real hardware.
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* fix: register request delegate as FidoRequestHandlerBase observer
The base AuthenticatorRequestClientDelegate::StartObserving() is a no-op, so
observer() on the request handler stayed null. MakeCredentialRequestHandler::
SpecializeRequestForAuthenticator dereferences observer()->SupportsPIN() when
residentKey is 'preferred', crashing with SEGV when a real FIDO2 HID key is
dispatched.
Override StartObserving/StopObserving to register via a ScopedObservation like
ChromeAuthenticatorRequestDelegate does. Added a virtual-authenticator
regression test for create() with residentKey: 'preferred'.
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* chore: update copyright attribution for new webauthn files
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* fix: address review feedback on webauthn account-select event
- Encode credentialId and userHandle as URL-safe base64 without padding so
the values match PublicKeyCredential.id from navigator.credentials.get()
byte-for-byte; tests now assert the equality rather than transcoding.
- Cancel the pending request when the listener invokes the callback with a
credentialId that does not match any account, instead of leaving the
request hanging while the listener retries. The TypeError still surfaces
so the misuse remains visible to the developer.
- DCHECK that the Touch ID config helpers run on the UI thread, encoding
the threading invariant the read-then-write metadata-secret pref relies
on.
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* fix: oxfmt formatting in webauthn spec
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* fix: use out-param form of base::Base64UrlEncode
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* fix: silently cancel webauthn account select on unknown credentialId
Throwing back into the listener bubbles up as an unhandled exception in
the main process. Match the no-args branch exactly so the listener sees a
single consistent failure mode (cancel + NotAllowedError) whether it
declines deliberately or by mistake.
Co-authored-by: Samuel Attard <sattard@anthropic.com>
* chore: node script/lint.js --js --fix
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>