fix(web): preserve manual auth across hard reloads#2602
Conversation
📝 WalkthroughWalkthroughRuntime bootstrap now caches a manually entered single-user API key in sessionStorage and rehydrates it after credential scrubbing, preserving auth across a second hard reload. The shell auth gate in ChangesRuntime auth persistence fix
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Browser
participant AppShell as "_app.tsx"
participant RuntimeBootstrap
participant SessionStorage
participant TldwConfig
Browser->>RuntimeBootstrap: First load, bootstrap()
RuntimeBootstrap->>TldwConfig: read stored apiKey
RuntimeBootstrap->>TldwConfig: scrub apiKey
RuntimeBootstrap->>SessionStorage: writeRuntimeSessionApiKey(manualKey)
RuntimeBootstrap->>RuntimeBootstrap: set in-memory runtime override
Browser->>RuntimeBootstrap: Second hard reload, bootstrap()
RuntimeBootstrap->>SessionStorage: readRuntimeSessionApiKey()
SessionStorage-->>RuntimeBootstrap: manualKey
RuntimeBootstrap->>RuntimeBootstrap: restore runtime override
Browser->>AppShell: refreshAuthState()
AppShell->>RuntimeBootstrap: getRuntimeApiKey()/getRuntimeApiBearer()
RuntimeBootstrap-->>AppShell: manualKey present
AppShell-->>Browser: render authenticated shell (header + sidebar)
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request addresses an issue where manually entered single-user WebUI authentication is lost on a second hard reload. It introduces a sessionStorage-backed runtime auth bridge to persist the API key across reloads within the same browser session, even after tldwConfig is scrubbed. Additionally, the shell auth gate is updated to recognize these runtime credentials, and corresponding regression tests are added. Feedback on the implementation suggests relaxing the fallback condition to sessionStorage by checking for the absence of a valid existingSingleUserKey rather than strictly checking if existing.apiKey is undefined, which could fail if the key is an empty string or placeholder.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
PR Summary by QodoFix WebUI: preserve manual single-user auth across hard reloads
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
74 rules 1.
|
a19d2ee to
040a37f
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/tldw-frontend/extension/shims/runtime-bootstrap.ts`:
- Around line 571-572: Add a focused regression test for the new session-key
clearing branch in runtime-bootstrap.ts. Extend runtime-bootstrap.test.ts to
exercise the `else if (existing && existingAuthMode !== "single-user")` path in
`runtimeBootstrap`, and assert that `writeRuntimeSessionApiKey(null)` is called
when the auth mode switches away from single-user while an existing session is
present. Keep the existing single-user rehydration coverage intact and add a
separate case specifically for the mode-switch clear behavior.
- Around line 545-572: The manual single-user key precedence logic in
runtime-bootstrap is correct but too dense; extract the derivation into a small
helper such as deriveManualSingleUserKey(existing, envAuthOptedOut) so the main
branch is easier to read. Move the
existingAuthMode/rawExistingSingleUserKey/existingSingleUserKey/sessionSingleUserKey/manualSingleUserKey
decision flow into that helper, then keep the
setRuntimeApiKey/setRuntimeSingleUserApiKeyOverride/writeRuntimeSessionApiKey
branch focused on applying the result.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 02b35937-641e-4d68-916e-a978811ecb34
📒 Files selected for processing (5)
apps/tldw-frontend/__tests__/app/app-layout.test.tsxapps/tldw-frontend/__tests__/extension/runtime-bootstrap.test.tsapps/tldw-frontend/extension/shims/runtime-bootstrap.tsapps/tldw-frontend/pages/_app.tsxbacklog/tasks/task-12127 - Fix-WebUI-auth-persistence-after-runtime-credential-scrub.md
Fixes #2590 by keeping manually entered single-user auth available in sessionStorage after tldwConfig is scrubbed. Count runtime auth material in the WebUI shell gate and add regression coverage for the second hard reload path.
040a37f to
626447b
Compare
Summary
Fixes #2590.
Change summary
This fixes #2590 by preserving manually entered single-user auth in browser session storage after the hardened bootstrap removes the key from localStorage-backed tldwConfig. The implementation uses sessionStorage rather than reintroducing persistent localStorage secrets, so users remain authenticated across hard reloads in the same browser session while the durable tldwConfig stays scrubbed. The shell gate now recognizes runtime auth because the visible WebUI shell should follow the same auth state used by API requests.
Test Plan
bunx vitest run __tests__/extension/runtime-bootstrap.test.ts __tests__/app/app-layout.test.tsx --config vitest.config.tsgit diff --check HEADBandit skipped: frontend TypeScript only.
Summary by cubic
Preserves manually entered single-user auth across hard reloads in the same browser session by rehydrating runtime auth from
sessionStorageaftertldwConfigis scrubbed. Keeps the header/sidebar authenticated without restoring secrets tolocalStorage. Fixes #2590.sessionStoragebridge for manual single-user API keys; rehydrate on later hard reloads and whentldwConfighas a blank/placeholderapiKey; clear the session key on env opt-out or when switching to multi-user.getRuntimeApiKey/getRuntimeApiBearer) in the WebUI shell gate so header and sidebar remain visible.Written for commit 626447b. Summary will update on new commits.