Skip to content

fix(auth): session-expired wording + auto-redirect to /login#87

Merged
samir1498 merged 1 commit into
mainfrom
fix/auth-error-wording
May 26, 2026
Merged

fix(auth): session-expired wording + auto-redirect to /login#87
samir1498 merged 1 commit into
mainfrom
fix/auth-error-wording

Conversation

@samir1498
Copy link
Copy Markdown
Collaborator

Summary

Closes friction #19 (confusing "invalid or revoked key" for expired sessions) and #20 (no auto-redirect to login on session expiry). Two-part fix:

Server (src/middleware/auth.ts): requireAuth now distinguishes credential sources:

  • Bearer header → 401 { code: 'key_invalid' }
  • Cookie only → 401 { code: 'session_expired' }
  • Neither → 401 "authentication required"

Client (src/ui/api.ts): new exported apiFetch shim inspects 401 responses and hash-routes to #/login on code: 'session_expired'. All internal fetch calls in api.ts now go through it. list.ts's monitor-detail fetch also uses it. Other UI surfaces (checkAuth in app.ts, login/setup endpoints) handle 401 explicitly already.

Test plan

  • tests/integration/auth-error-codes.it.spec.ts — 3 new specs covering no-creds, bad-Bearer, bad-cookie paths. All pass locally.
  • tsc --noEmit, format:check clean
  • Manual: log into the dashboard, manually expire your session (delete the oo_session row in postgres), trigger any monitor list refresh → expect redirect to #/login instead of a broken state.

🤖 Generated with Claude Code

…ssion expiry

requireAuth used to return the same "invalid or revoked key" message for
both paths — confusing for dashboard users whose session expired (they
never minted a key). Now the middleware:

  - 401 + code: 'key_invalid'      when the request sent an
                                    Authorization: Bearer header
  - 401 + code: 'session_expired'  when only a cookie was present
  - 401 (no code) "authentication required" when neither was sent

The dashboard's central fetch wrapper (src/ui/api.ts apiFetch) inspects
401 responses and, on code: 'session_expired', hash-routes to #/login.
Without this, an expired session leaves the dashboard polling endlessly
in a confused state. apiFetch is now used everywhere in api.ts and from
list.ts's row-edit fetch. Other UI entry points already handle 401
explicitly (checkAuth in app.ts) so they don't double-redirect.

Test: tests/integration/auth-error-codes.it.spec.ts covers all three
paths (no creds, bad Bearer, bad cookie).

Closes friction #19, #20.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@samir1498 samir1498 merged commit a4a2af2 into main May 26, 2026
5 checks passed
@samir1498 samir1498 deleted the fix/auth-error-wording branch May 26, 2026 15:53
@samir1498 samir1498 mentioned this pull request May 26, 2026
samir1498 added a commit that referenced this pull request May 26, 2026
…sh (#89)

Three PRs merged after v1.25.1: #86 (per-assertion failure breakdown
on API monitor detail), #87 (session-expired error wording +
auto-redirect to login), #88 (I've-copied-it dismiss + back-link
wording + domain consistency).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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