Recover safely when an active dashboard session expires #309

Closed
opened 2026-08-08 14:30:12 +00:00 by timmy · 0 comments
Owner

Problem

The global session boundary detects API 401 responses and emits stackchain:session-expired, but nothing handles the event. An expired or remotely revoked session therefore leaves stale privileged dashboard content visible while polling and actions continue to fail.

Vertical slice

  • Replace the active dashboard with a deployment-subpath-safe sign-in route on the first same-origin API 401.
  • Debounce concurrent/repeated 401 responses so expiry recovery is single-flight.
  • Explain on the sign-in screen that the session expired and private drafts remain on this device.
  • Preserve existing queued-work recovery after successful reauthentication and keep explicit device sign-out purge behavior unchanged.
  • Do not treat cross-origin 401, 403, 429, network failures, or server errors as local session expiry.

Acceptance criteria

  • A same-origin request returning 401 calls location.replace(<base>login?reason=session-expired) exactly once.
  • A cross-origin 401 and non-401 responses do not trigger expiry recovery.
  • Expiry navigation preserves local/session storage, IndexedDB outboxes, and dashboard caches.
  • Login renders an accessible bounded expiry status with no arbitrary return URL or open redirect.
  • Successful sign-in returns to the dashboard root and clears the token form as today.
  • Focused and full test suites pass.

Non-duplication evidence

All 6 open and 151 closed issue titles were reviewed. Related work #258, #266, #268, and #287 covers authentication, queued-delivery resume, logout revocation, and all-device revocation, but no issue handles an already-open client after a 401. Recent commits #303, #305, and #307 cover stalled refresh, request deadlines, and release-worker shell isolation.

## Problem The global session boundary detects API `401` responses and emits `stackchain:session-expired`, but nothing handles the event. An expired or remotely revoked session therefore leaves stale privileged dashboard content visible while polling and actions continue to fail. ## Vertical slice - Replace the active dashboard with a deployment-subpath-safe sign-in route on the first same-origin API `401`. - Debounce concurrent/repeated `401` responses so expiry recovery is single-flight. - Explain on the sign-in screen that the session expired and private drafts remain on this device. - Preserve existing queued-work recovery after successful reauthentication and keep explicit device sign-out purge behavior unchanged. - Do not treat cross-origin `401`, `403`, `429`, network failures, or server errors as local session expiry. ## Acceptance criteria - A same-origin request returning `401` calls `location.replace(<base>login?reason=session-expired)` exactly once. - A cross-origin `401` and non-`401` responses do not trigger expiry recovery. - Expiry navigation preserves local/session storage, IndexedDB outboxes, and dashboard caches. - Login renders an accessible bounded expiry status with no arbitrary return URL or open redirect. - Successful sign-in returns to the dashboard root and clears the token form as today. - Focused and full test suites pass. ## Non-duplication evidence All 6 open and 151 closed issue titles were reviewed. Related work #258, #266, #268, and #287 covers authentication, queued-delivery resume, logout revocation, and all-device revocation, but no issue handles an already-open client after a `401`. Recent commits #303, #305, and #307 cover stalled refresh, request deadlines, and release-worker shell isolation.
timmy self-assigned this 2026-08-08 14:30:12 +00:00
timmy closed this issue 2026-08-08 14:33:47 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stackchain/stackchain-dashboard#309
No description provided.