Skip to content

feat(admin): passkey login, 7-day sessions, role-based admin management#77

Open
ericrihm wants to merge 3 commits into
mainfrom
feat/admin-auth-passkeys
Open

feat(admin): passkey login, 7-day sessions, role-based admin management#77
ericrihm wants to merge 3 commits into
mainfrom
feat/admin-auth-passkeys

Conversation

@ericrihm
Copy link
Copy Markdown
Owner

Summary

  • Passkey/WebAuthn login: instant biometric login for admin dashboard — no email wait. Manual WebAuthn implementation using Web Crypto API (zero npm dependencies). Supports ES256 (P-256) and RS256 passkeys.
  • 7-day sessions: session cookie extended from 24h to 7 days, reducing daily re-login friction.
  • Admin identity + roles: isAdmin() now returns { id, email, role } instead of boolean. Two roles: owner (full control, admin management) and admin (operator). Bearer token treated as owner.
  • Admin management UI: owners can invite admins by email (sends magic link invite), view admin list with passkey counts, and remove admins. Owner-only section in dashboard.
  • Passkey management: register, list, and remove passkeys from the dashboard. Login page shows "Sign in with passkey" button when WebAuthn is supported.
  • Migration 014: admin_passkeys table for WebAuthn credentials, invited_by/display_name columns on admin_users, owner role upgrade.

New endpoints

Endpoint Method Purpose
/api/admin/auth/passkey/register-options POST Generate WebAuthn registration challenge
/api/admin/auth/passkey/register-verify POST Verify and store passkey registration
/api/admin/auth/passkey/auth-options POST Generate WebAuthn authentication challenge
/api/admin/auth/passkey/auth-verify POST Verify passkey login, issue session cookie
/api/admin/auth/passkeys GET/DELETE List/remove own passkeys
/api/admin/auth/admins GET/POST/DELETE List/invite/remove admin accounts (owner-only)
/api/admin/auth/me GET Current admin identity + role

Test plan

  • Full test suite passes (460 tests, 0 failures)
  • Deploy to preview, verify passkey enrollment flow
  • Verify passkey login after enrollment
  • Verify 7-day session persists across browser restarts
  • Verify admin invite sends email with magic link
  • Verify operator role cannot access admin management endpoints

🤖 Generated with Claude Code

…w tests

- Rewrite card() from innerHTML to createElement+textContent (XSS fix)
- Chain tip cards pass plain text instead of HTML wrappers
- Analytics: Promise.all → Promise.allSettled with per-section errors
- Heartbeat/chain status indicators add ✓/✗ symbols (a11y)
- Suspend confirmation shows full user name + ID
- New test suites: streams (6), suspend (6), email-suppression (8)\n
- WebAuthn/passkey authentication for instant admin login (no email wait)
- Manual WebAuthn implementation using Web Crypto API (zero npm deps)
- Session extended from 24h to 7 days
- isAdmin() returns { id, email, role } for identity-aware endpoints
- Roles: owner (full control + admin management) vs admin (operator)
- Admin management: invite by email, remove, list with passkey counts
- Migration 014: admin_passkeys table, admin_users columns
- Dashboard UI: passkey login button, enrollment, admin list (owner only)
- 39 new tests across 5 test files (460 total, all passing)\n
@ericrihm ericrihm enabled auto-merge (squash) April 25, 2026 03:19
Codex CLI (GPT-5.4) review caught two issues:
- Invite form used raw fetch() instead of postJson(), missing the
  Authorization header in bearer-token auth mode (would 401)
- register-verify.js had unused challengeKey and allChallenges variables\n
@ericrihm ericrihm force-pushed the feat/admin-auth-passkeys branch from 4e5e8a3 to 0e0d2fb Compare May 11, 2026 13:25
@ericrihm ericrihm force-pushed the feat/admin-auth-passkeys branch from 0e0d2fb to c679119 Compare May 11, 2026 14:37
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