fix(web): refresh expired OIDC tokens before API calls
The overview background graph and the Knowledge Base graph both rendered empty because the SPA's OIDC access token expired (~5 min TTL) and was never refreshed. fetchWithAuth called getToken() synchronously (no refresh); ensureToken returned the stale token without refreshing; storeTokens discarded expires_in; the resulting 401 made fetchGraph return null and both graphs drew nothing, with no error surfaced. - oidc.ts: track expiresAt from expires_in; getToken() returns null within 30s of expiry; ensureToken/initOIDC refresh instead of returning stale tokens; isOIDCConfigured no longer claims configured on expired-only state - config.ts: fetchWithAuth awaits ensureToken (refresh on demand), falls back to static token if OIDC can't yield one, flushes OIDC session on 401; sseUrl is async + refreshes before constructing the EventSource - stores/events.ts: connect() awaits the now-async sseUrl
This commit is contained in:
@@ -6,6 +6,22 @@ e2e-validated, committed (`337d577`), pushed to `main`, and deployed to
|
||||
next blocker** (refuse `complete_task` without writeback — the knowledge
|
||||
loop is still drifting).
|
||||
|
||||
**2026-07-14 (PM) — OIDC token-refresh fix (unplanned, root-cause for the
|
||||
empty graph symptom):** the overview background graph and the Knowledge Base
|
||||
graph both rendered empty because the SPA's OIDC access token expired
|
||||
(~5 min TTL) and was never refreshed. `fetchWithAuth` called `getToken()`
|
||||
synchronously (no refresh); `ensureToken` returned the stale token without
|
||||
refreshing; `storeTokens` discarded `expires_in`; and the resulting 401
|
||||
made `fetchGraph` return `null` → both graphs drew nothing, with no error
|
||||
surfaced. Fixed structurally in `web/src/lib/oidc.ts` +
|
||||
`web/src/lib/config.ts` + `web/src/lib/stores/events.ts`: tokens now carry
|
||||
`expiresAt`, `getToken()` returns null within 30s of expiry, `fetchWithAuth`
|
||||
awaits `ensureToken()` (refreshes on demand), `sseUrl` is async + refreshes
|
||||
before constructing the EventSource, and a 401 flushes the OIDC session so
|
||||
the static token fallback takes over. Build passes. Not yet committed or
|
||||
deployed (pending operator verification). Not part of any numbered phase
|
||||
above — filed here because it was the highest-impact surface symptom.
|
||||
|
||||
## Shipped (2026-07-14, v0.5.0 — commit 337d577, deployed)
|
||||
|
||||
| Fix | File(s) | Validation |
|
||||
|
||||
@@ -17,7 +17,7 @@ went sideways, open an investigation.
|
||||
| 2026-07-14 | [Session reliability & UX audit](2026-07-14-session-reliability-and-ux-audit.md) | Done — all 21 fixes deployed |
|
||||
| 2026-07-14 | [Tool timeline in sidebar](2026-07-14-tool-timeline-sidebar.md) | Done — deployed v0.3.2 |
|
||||
| 2026-07-14 | [Unified agent activity indicator](2026-07-14-unified-agent-indicator.md) | Done — deployed v0.3.3 |
|
||||
| 2026-07-14 | [Post-fix session remainders: empty responses & plan drift](2026-07-14-post-fix-session-remainders.md) | In Progress — Phases A + B.1-B.3 + F.3 shipped, e2e-validated, committed (337d577), deployed v0.5.0; Phases C, D, E, F.1-F.2 remain (D.1 is the next blocker) |
|
||||
| 2026-07-14 | [Post-fix session remainders: empty responses & plan drift](2026-07-14-post-fix-session-remainders.md) | In Progress — Phases A + B.1-B.3 + F.3 shipped, e2e-validated, committed (337d577), deployed v0.5.0; Phases C, D, E, F.1-F.2 remain (D.1 next blocker). **PM:** OIDC token-refresh fix (root-cause for empty graphs) implemented, not yet committed/deployed |
|
||||
|
||||
## Done
|
||||
|
||||
|
||||
Reference in New Issue
Block a user