2 Commits

Author SHA1 Message Date
ab84c7bc53 Fix review findings: transaction atomicity, perf, and UI polish
Backend fixes:
- session.py: record_failed/successful_login use flush() not commit()
  — callers own transaction boundary (BUG-2 atomicity fix)
- auth.py: Add explicit commits after record_failed_login where callers
  raise immediately; add commit before TOTP mfa_token return path
- passkeys.py: JOIN credential+user lookup in login/complete (W-1 perf)
- passkeys.py: Move mfa_enforce_pending clear before main commit (S-2)
- passkeys.py: Add Path(ge=1, le=2147483647) on DELETE endpoint (BUG-3)
- auth.py: Switch has_passkeys from COUNT to EXISTS with LIMIT 1 (W-2)
- passkey.py: Add single-worker nonce cache comment (H-1)

Frontend fixes:
- PasskeySection: emerald→green badge colors (W-3 palette)
- PasskeySection: text-[11px]/text-[10px]→text-xs (W-4 a11y minimum)
- PasskeySection: Scope deleteMutation.isPending to per-item (W-5)
- nginx.conf: Permissions-Policy publickey-credentials use (self) (H-2)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 22:59:59 +08:00
e8e3f62ff8 Phase 1: Add passkey (WebAuthn/FIDO2) backend
New files:
- models/passkey_credential.py: PasskeyCredential model with indexed credential_id
- alembic 061: Create passkey_credentials table
- services/passkey.py: Challenge token management (itsdangerous + nonce replay
  protection) and py_webauthn wrappers for registration/authentication
- routers/passkeys.py: 6 endpoints (register begin/complete, login begin/complete,
  list, delete) with full security hardening

Changes:
- config.py: WEBAUTHN_RP_ID, RP_NAME, ORIGIN, CHALLENGE_TTL settings
- main.py: Mount passkey router, add CSRF exemptions for login endpoints
- auth.py: Add has_passkeys to /auth/status response
- nginx.conf: Rate limiting on all passkey endpoints, Permissions-Policy
  updated for publickey-credentials-get/create
- requirements.txt: Add webauthn>=2.1.0

Security: password re-entry for registration (V-02), single-use nonce
challenges (V-01), constant-time login/begin (V-03), shared lockout
counter, generic 401 errors, audit logging on all events.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 22:46:00 +08:00