fix(ui): persist Control UI gateway token in sessionStorage#39615
fix(ui): persist Control UI gateway token in sessionStorage#39615KathenZK wants to merge 3 commits intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR fixes the refresh-disconnect UX for the Control UI by persisting the gateway auth token in Key changes:
One logic gap is present: the early-return path in Confidence Score: 3/5
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 53ef2d97ea
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ui/src/ui/storage.ts
Outdated
| : defaults.gatewayUrl, | ||
| // Gateway auth is intentionally in-memory only; scrub any legacy persisted token on load. | ||
| token: defaults.token, | ||
| token: loadSessionToken() ?? defaults.token, |
There was a problem hiding this comment.
Read session token even when local settings are absent
The new token hydration only runs inside the branch that successfully reads/parses openclaw.control.settings.v1, so when that localStorage key is missing (for example after key reset, manual localStorage clear, or any path where only sessionStorage remains), loadSettings() returns defaults and drops a valid session token on refresh. This breaks the commit’s stated session-persistence behavior because token recovery is now unintentionally gated on unrelated persisted UI settings.
Useful? React with 👍 / 👎.
ui/src/ui/storage.ts
Outdated
| persistSettings(next); | ||
| persistSessionToken(next.token); |
There was a problem hiding this comment.
Persist session token before writing local settings
saveSettings() writes localStorage first and only then writes sessionStorage, so if localStorage.setItem throws (e.g., quota/security errors in private or restricted contexts), the function exits before persisting the gateway token to sessionStorage. In those environments the new refresh-survives-within-tab behavior silently fails even though sessionStorage itself could still be usable.
Useful? React with 👍 / 👎.
|
Repro that motivated this patch:
Observed result today:
Expected result:
That’s why |
|
Good catch — I’ve addressed that edge case. What changed in the follow-up commit:
This keeps the two code paths consistent and matches the intended contract for session-scoped token persistence. |
|
Refreshing this PR and clarifying scope. This PR fixes the Control UI refresh/token-persistence problem only by keeping the gateway token in What it fixes:
What it does not try to fix:
I also addressed the earlier edge case noted in review:
CI is green after the update. If maintainers still want this split, targeted UX fix, this should be ready for review/merge. |
ae263b5 to
159f125
Compare
|
It looks like main has since moved to a more complete gateway-scoped session-token approach, which overlaps with the original intent of this PR. The original goal here was to fix the refresh/token-loss UX and establish session-scoped persistence without falling back to localStorage. If maintainers consider the current mainline implementation to have fully superseded this PR, I’m happy for this to be closed as covered by the newer approach. |
Summary
sessionStorage?token=/#token=working as beforelocalStoragepersistence for gateway authWhy
Today the Control UI imports
tokenfrom the URL, strips it from the address bar, and keeps it in memory only. That means a normal page refresh drops the token and disconnects the UI.This is especially painful for loopback/local dashboard use, where the expected UX is:
sessionStorageis a reasonable middle ground:localStoragepersistenceImplementation
sessionStorageduring settings bootstrapsessionStorageinsaveSettingslocalStoragetoken-freeTests
ui/src/ui/storage.node.test.tsui/src/ui/navigation.browser.test.tsNotes
This preserves the existing security intent of not storing the gateway token in
localStorage, while fixing the refresh-disconnect UX.