Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses passkey (notably YubiKey) sign-in getting “stuck” by adding an abort path for conditional mediation and adjusting the sign-in UI copy/presentation.
Changes:
- Abort any in-flight conditional WebAuthn mediation when the user explicitly clicks the passkey sign-in button.
- Refactor conditional mediation flow to run under an
AbortControllerand ignore abort errors. - Update the sessions sign-in view to show a visible “Sign in with a passkey” control and tweak duplicate-registration messaging.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| lib/action_pack/passkey/form_helper.rb | Updates duplicate-registration error copy. |
| app/views/sessions/new.html.erb | Makes the passkey sign-in button visible and restyles it. |
| app/javascript/lib/action_pack/passkey.js | Adds abortable conditional mediation to prevent WebAuthn requests from blocking manual sign-in. |
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #perform = async () => { | ||
| await this.abortConditionalMediation?.() | ||
| this.button.disabled = true |
There was a problem hiding this comment.
abortConditionalMediation() is awaited before starting a manual click (#perform), but the conditional flow also awaits refreshChallenge() which uses fetch() without an AbortSignal. As a result, aborting conditional mediation won’t cancel an in-flight challenge refresh, and the user click can still block until that request completes (which undermines the goal of “unsticking” sign-in on slow/hung networks). Consider threading the same AbortController signal through refreshChallenge (and into fetch({ signal })) so aborting conditional mediation reliably unblocks the manual ceremony start.
No description provided.