Matt 47746d79dd
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m7s
feat(auth): admin access link doubles as magic-login for users with passwords
The original generateAccessLink branched on user state and minted either
an invite URL (forces password setup) or a reset URL (forces password
change). Both required the user to set/change a password — fine for new
users, painful for tech-illiterate sponsor jurors who already have a
working password and just need a fresh login because their JWT went
stale or their email is bouncing.

This adapts the existing invite-token flow to behave as a magic-login
when the user already has a password:

  - auth.ts credentials.authorize: only set mustSetPassword=true if the
    user has no passwordHash. Users who already set one keep it, the
    invite token is consumed, JWT is issued with their current role,
    they're signed in.
  - accept-invite/page.tsx: redirect to / after accept (was hardcoded
    to /set-password). The middleware already enforces the
    /set-password detour when mustSetPassword is true, so users who
    need it still land there; everyone else routes by role.
  - generateAccessLink: drop the reset-password branch. Always emits an
    /accept-invite URL. The flow naturally adapts: setup for new users,
    magic-login for active ones. Audit log records which behavior fired
    (kind: 'setup' | 'magic_login').
  - dialog copy: clearer description for each kind.

Net behavior: Didier (active, has password, stale JWT after role
migration) clicks his link → instant login on /jury, password preserved.
Magali (no password yet) clicks hers → /set-password → onboarding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:35:22 +02:00
2026-04-28 18:55:12 +02:00
2026-04-28 18:55:12 +02:00
Description
No description provided
25 MiB
Languages
TypeScript 99.5%
JavaScript 0.2%
Shell 0.2%
CSS 0.1%