Skip to content

fix(auth): log why the browser made no passkey at setup - #241

Open
Lethabarb wants to merge 3 commits into
mainfrom
fix/record-passkey-setup-errors
Open

Lethabarb wants to merge 3 commits into
mainfrom
fix/record-passkey-setup-errors

Conversation

@Lethabarb

Copy link
Copy Markdown
Owner

Why

On 10 November 2026 the first manager's passkey setup on an iPhone (Mobile Safari) failed in production after Face ID. Production's logs show the setup page fetched creation options three times, but no credential ever reached the server. The prompt failed inside Safari, and the SPA discarded the error, so there's no record of why.

What

  • POST /api/auth/setup/passkey/failure (needs the enrolment cookie, sign-in rate limit, antiforgery like every change). It logs the browser error's name, SimpleWebAuthn's code and the message at Information in the app's namespace, so it reaches Application Insights. Control characters become spaces, so one entry stays on one line. It answers 204, or 401 and logs nothing without a valid cookie.
  • The SPA sends it, without waiting for it, when the passkey prompt fails on view E (passkey) or view F (password and passkey). A failure the server itself gave (an ApiError) is not sent.
  • Lengths in Limits and limits.ts (100 / 100 / 500), checked by SpaLimitsTests.
  • design.md §6.2 row, §9.5 note, decision D103.

Passkey sign-in is unchanged.

Checks

  • Locally: dotnet build -warnaserror, tsc -b, eslint clean. Tests are left to CI.
  • New: SetupPasskeyFailureEndpointTests (log line, 401, 422 per field), endpoint matrix row, and SPA tests for what's sent (and not sent) from both views.

🤖 Generated with Claude Code

Lethabarb and others added 3 commits November 10, 2026 16:48
A passkey prompt that fails on the device never reaches the server, so the
iPhone setup failure of 10 November 2026 left no record of its cause. When the
prompt fails on view E or F, the SPA now sends the error's name, SimpleWebAuthn's
code and the browser's words to POST /api/auth/setup/passkey/failure, which
needs the enrolment cookie and logs them at Information (D103).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…og line

Also log "none" for a failure with no code, and restore a space the first
commit dropped in ChooseMethod.test.tsx.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…compiles

The previous commit put a raw U+2028 inside a string literal, which C# reads as
a line break.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lethabarb added a commit that referenced this pull request Nov 10, 2026
Main took D104 for the Word-template decision (#246), and open PR #241
also numbers its decision D103, so this branch's hosting-cost decision
becomes D105, the next number no branch claims. design/decisions.md keeps
main's D104 row and adds this one after it; this branch's citations are
renamed in the files it changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant