a11y(2.2.1): ui-main — warn the user before session expiry and offer an extend affordance#3531
Draft
rosanusi wants to merge 2 commits into
Draft
a11y(2.2.1): ui-main — warn the user before session expiry and offer an extend affordance#3531rosanusi wants to merge 2 commits into
rosanusi wants to merge 2 commits into
Conversation
Silent 401-on-refresh-token-expiry hard-redirected to login, destroying in-flight form state and giving users no warning or extension opportunity. Add JWT exp decoding to schedule a 60s warning modal (alertdialog), a Stay-signed-in button that calls refreshTokens(), and replace handleError's hard redirect on 401 with the modal so form state is preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description & motivation 💭
The ui-main auth flow silently refreshes the access token on every 401. When the refresh token itself expires,
refreshTokens()returnsfalseandhandleErrorhard-redirected the user to the login page viawindow.location.assign()— with no warning, no opportunity to extend, and any in-flight form state (Start Workflow, Cancel/Terminate confirmations, Schedule create/edit) destroyed.SC 2.2.1 (Timing Adjustable, Level A) requires at least one of: turn off the limit, allow adjustment to ≥10×, or warn with ≥20s to extend. None of the three was met.
This PR implements the warn-with-extend path:
expdecoding —setAuthUsernow decodes theexpclaim from the access token and schedules a warning timer 60 s before expiry. The timer is cancelled and rescheduled on every successful token refresh.sessionWarningState(idle | warning | expired) is the single source of truth for the modal, avoids coupling UI to auth internals.SessionWarningModalcomponent — arole="alertdialog"<dialog>that opens onwarningstate with a live countdown (aria-live="polite"), a Stay signed in primary button (callsrefreshTokens(); on failure shifts toexpiredstate), and a Sign out secondary button. Onexpiredstate the modal shifts to "Your session has expired" with a Sign in again button. No auto-redirect — the user controls the navigation so form state in the background remains intact.handleErrorno longer hard-redirects on 401 — callstriggerSessionExpired()instead, making the modal the single session-end decision point. 403 Forbidden still redirects.Files changed (6):
src/lib/stores/session-warning.ts— new store (sessionWarningState,triggerSessionExpired,dismissSessionWarning)src/lib/stores/auth-user.ts— JWTexpdecoding, warning timer scheduling/cancellation insetAuthUser/clearAuthUsersrc/lib/utilities/handle-error.ts— 401 path callstriggerSessionExpired()instead ofwindow.location.assign()src/lib/components/session-warning-modal.svelte— newalertdialogmodalsrc/lib/i18n/locales/en/common.ts— 7 new i18n keyssrc/routes/(app)/+layout.svelte— mountsSessionWarningModalSC 2.2.1 Timing Adjustable (Level A) — current verdict: Fails → Supports
Screenshots (if applicable) 📸
New modal appears 60 s before access-token expiry with a countdown, Stay signed in, and Sign out. If no action is taken the countdown reaches zero and the modal shifts to the expired state.
Design Considerations 🎨
Copy for modal title, body, and button labels is a placeholder — needs designer review before merge, especially the countdown phrasing which affects screen-reader announcement cadence. i18n keys are in
common.tsso copy can be updated without a code change.Testing 🧪
How was this tested 👻
Steps for others to test: 🚶🏽♂️🚶🏽♀️
alertdialogby VoiceOver/NVDA. Confirm the countdown is announced viaaria-live="polite".exp> 60 s ahead).handleErrorno longer issueswindow.location.assignon 401.Checklists
Draft Checklist
Merge Checklist
aria-livecadence)Issue(s) closed
Closes finding from
audit-output/issues/2.2.1-timing-adjustable-verification.mdSection 3.Docs
Any docs updates needed?
No doc changes needed.
A11y-Audit-Ref: 2.2.1-ui-main-session-timeout-warning