Vibe coded PR: Reload page on 401 to recover from forward-auth session expiry#924
Open
sherrmann wants to merge 1 commit into
Open
Vibe coded PR: Reload page on 401 to recover from forward-auth session expiry#924sherrmann wants to merge 1 commit into
sherrmann wants to merge 1 commit into
Conversation
When Spoolman is deployed behind a forward-auth reverse proxy (Authelia, oauth2-proxy, Authentik, Caddy forward_auth, etc.) the proxy returns 401 to XHR/fetch requests once the user's session expires. The SPA had no handler -- every query loops on 401, the UI hangs on "Loading..." indefinitely. Add an axios response interceptor that triggers a top-level reload on 401 from idempotent (GET/HEAD) requests so the proxy can redirect through its login portal and back. Mutation 401s fall through to the existing notification provider so unsaved form data is preserved. A 30-second localStorage cooldown bounds the loop if auth recovery fails. The service worker is unregistered before the reload because vite-plugin-pwa's default NavigationRoute serves the precached index.html for navigation requests, which would otherwise prevent the reload from reaching the proxy. vite-plugin-pwa re-registers it on the next page load via registerType: "autoUpdate". No behavior change for users without forward-auth in front: Spoolman v0.23.1 emits no 401s natively, so the interceptor stays dormant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a client-side recovery mechanism for forward-auth session expiry by reloading the SPA when API calls receive a 401, allowing the proxy to redirect the user through its login flow and back.
Changes:
- Introduces an Axios response interceptor that triggers a reload on 401 for idempotent (GET/HEAD) requests.
- Adds a reload cooldown (localStorage-based) and unregisters service workers before reloading to avoid PWA navigation caching.
- Imports the handler from the app entrypoint to install the interceptor at startup.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| client/src/utils/authReloadHandler.ts | Adds 401-handling interceptor, cooldown, and service-worker unregistration prior to reload. |
| client/src/index.tsx | Imports the new handler module to activate the interceptor globally. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Fixes #923
Problem
Behind a forward-auth proxy (Authelia, oauth2-proxy, Authentik, etc.), the proxy returns 401 Unauthorized to XHR once the user's session expires. The SPA shell renders fine, but every backend call fails and a "Loading…" indicator hangs in the corner indefinitely. Recovery today requires manually logging into the auth portal in another tab.
Fix
Axios response interceptor triggers
window.location.reload()on 401. The reload is a top-level GET, so the proxy returns its 302 to the login portal with?rd=set, and the user lands back on the original URL after auth.NavigationRouteserves the precachedindex.htmland would prevent the reload from reaching the proxy. vite-plugin-pwa re-registers viaregisterType: "autoUpdate"on next load.localStoragecooldown bounds the loop if recovery fails.Scope
Two files (~45 lines). No behavior change for users without forward-auth: Spoolman v0.23.1 emits no 401s natively, so the interceptor stays dormant.
If/when native auth lands (#229, #852), the future login endpoint should be excluded here so a wrong-password 401 doesn't reload-loop — one-line guard, left for whoever ships that feature.