* Initial plan
* Warn user when credentials have expired in multiuser mode
Agent-Logs-Url: https://github.com/lstein/InvokeAI/sessions/f0947cda-b15c-475d-b7f4-2d553bdf2cd6
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
* Address code review: avoid multiple localStorage reads in base query
Agent-Logs-Url: https://github.com/lstein/InvokeAI/sessions/f0947cda-b15c-475d-b7f4-2d553bdf2cd6
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
* bugfix(multiuser): ask user to log back in when authentication token expires
* feat: sliding window session expiry with token refresh
Backend:
- SlidingWindowTokenMiddleware refreshes JWT on each mutating request
(POST/PUT/PATCH/DELETE), returning a new token in X-Refreshed-Token
response header. GET requests don't refresh (they're often background
fetches that shouldn't reset the inactivity timer).
- CORS expose_headers updated to allow X-Refreshed-Token.
Frontend:
- dynamicBaseQuery picks up X-Refreshed-Token from responses and
updates localStorage so subsequent requests use the fresh expiry.
- 401 handler only triggers sessionExpiredLogout when a token was
actually sent (not for unauthenticated background requests).
- ProtectedRoute polls localStorage every 5s and listens for storage
events to detect token removal (e.g. manual deletion, other tabs).
Result: session expires after TOKEN_EXPIRATION_NORMAL (1 day) of
inactivity, not a fixed time after login. Any user-initiated action
resets the clock.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore(backend): ruff
* fix: address review feedback on auth token handling
Bug fixes:
- ProtectedRoute: only treat 401 errors as session expiry, not
transient 500/network errors that should not force logout
- Token refresh: use explicit remember_me claim in JWT instead of
inferring from remaining lifetime, preventing silent downgrade of
7-day tokens to 1-day when <24h remains
- TokenData: add remember_me field, set during login
Tests (6 new):
- Mutating requests (POST/PUT/DELETE) return X-Refreshed-Token
- GET requests do not return X-Refreshed-Token
- Unauthenticated requests do not return X-Refreshed-Token
- Remember-me token refreshes to 7-day duration even near expiry
- Normal token refreshes to 1-day duration
- remember_me claim preserved through refresh cycle
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore(backend): ruff
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lstein <111189+lstein@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Jonathan <34005131+JPPhoto@users.noreply.github.com>