mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-06-18 20:55:39 +08:00
Passkeys used as 2FA (behind `allow_passkeys_for_2fa`) previously shared a single WebAuthn ceremony with second-factor security keys on `/session/2fa`: one merged credential allow-list, posted as the `security_key` method, with `userVerification: "preferred"`. A single ceremony cannot both require user verification for passkeys and accept legacy non-UV security keys, so this splits them: * New `passkey` value (4) in `UserSecondFactor.methods` carries the ceremony intent on the wire. No rows ever store it; passkeys live in `user_security_keys`. * `DiscourseWebauthn.allowed_credentials` now returns `allowed_credential_ids` (second-factor keys only, as before the combined ceremony) plus a separate `passkey_allowed_credential_ids`. * `authenticate_security_key` only accepts second-factor credentials again; the new `authenticate_passkey` only accepts first-factor credentials. A passkey assertion posted to the security key ceremony (or vice versa) fails with an ownership error. * The `/session/2fa` page shows distinct "Use passkey" (UV required) and "Use security key" (UV discouraged) actions instead of one mixed button. * `passkeys_for_2fa_enabled?` is renamed to `passkeys_available_as_second_factor?` (old name kept as an alias) and now ignores disabled passkey rows. No behavior expansion: passkeys still only satisfy `/session/2fa`. This is the first of three stacked PRs completing the `allow_passkeys_for_2fa` rollout so passkeys count as valid 2FA everywhere, including `enforce_second_factor`. The safe ordering is: every login/recovery path must be able to *challenge* a passkey before any path starts *trusting* passkey-only accounts as compliant. |
||
|---|---|---|
| .. | ||
| actions | ||
| auth_manager.rb | ||
| auth_manager_result.rb | ||
| bad_challenge.rb | ||