Fix frontend settings persistence for API client - #30
Conversation
Co-authored-by: up2itnow0822 <up2itnow0822@gmail.com>
| const normalizedUrl = url.trim(); | ||
| storage.setItem(BACKEND_BASE_URL_KEY, normalizedUrl); | ||
| for (const legacyKey of LEGACY_BACKEND_BASE_URL_KEYS) { | ||
| storage.removeItem(legacyKey); | ||
| } |
There was a problem hiding this comment.
persistBackendBaseUrl stores an empty string in backend_base_url when the user clears the URL field and saves. Combined with the removal of all legacy keys, a user who accidentally saves an empty value will have their previous server URL permanently erased. persistSessionAuthToken correctly guards against empty values with an early return — the same pattern should apply here.
| const normalizedUrl = url.trim(); | |
| storage.setItem(BACKEND_BASE_URL_KEY, normalizedUrl); | |
| for (const legacyKey of LEGACY_BACKEND_BASE_URL_KEYS) { | |
| storage.removeItem(legacyKey); | |
| } | |
| const normalizedUrl = url.trim(); | |
| if (!normalizedUrl) { | |
| storage.removeItem(BACKEND_BASE_URL_KEY); | |
| return; | |
| } | |
| storage.setItem(BACKEND_BASE_URL_KEY, normalizedUrl); | |
| for (const legacyKey of LEGACY_BACKEND_BASE_URL_KEYS) { | |
| storage.removeItem(legacyKey); | |
| } |
| export function persistSessionAuthToken(token: string): void { | ||
| const normalizedToken = token.trim(); | ||
| if (!normalizedToken) return; | ||
|
|
||
| browserSessionStorage()?.setItem(AUTH_TOKEN_KEY, normalizedToken); | ||
| } |
There was a problem hiding this comment.
No mechanism to clear a stored session token
persistSessionAuthToken('') is a no-op (intentionally), but once a token is saved there is no UI path to delete it. If a user's API key is rotated or revoked, requests will keep sending a stale Authorization header until the tab is closed. Consider adding a clearSessionAuthToken() helper and a "clear" action in the UI.
| const BACKEND_BASE_URL_KEY = 'backend_base_url'; | ||
| const LEGACY_BACKEND_BASE_URL_KEYS = ['api_url', 'agentnexus_backend_url']; | ||
| const AUTH_TOKEN_KEY = 'auth_token'; |
There was a problem hiding this comment.
Stale
auth_token entry not cleaned up from localStorage
getBackendBaseUrl has an explicit LEGACY_BACKEND_BASE_URL_KEYS list for migration. Auth tokens have no analogous cleanup: the old api.ts read localStorage.getItem('auth_token'), and AUTH_TOKEN_KEY reuses the same string but now targets sessionStorage. Any pre-existing auth_token in localStorage is silently abandoned — never read, never deleted.
There was a problem hiding this comment.
Duplicate draft — recommend close
This PR overlaps with #35 (most complete), #34, #33, #32, and #31. All six drafts target the same frontend settings/API-client persistence bug.
#35 includes apiConfig.ts, session-scoped auth tokens, legacy key migration, and unit tests (4/4 passing).
Action
Close this PR in favor of #35 after it is marked ready and merged.
Sent by Cursor Automation: Untitled


Summary
Validation
Known pre-existing gate failures
next lintis not a valid Next 16 command in this setup.sendCallsSync/sendTransactionSync).Greptile Summary
This PR introduces a shared
settings-storagemodule that unifies three previously inconsistent localStorage keys for the backend URL into one canonical key with a migration fallback list, moves auth tokens fromlocalStoragetosessionStorage, and wires both the settings page and modal to use the new helpers.persistBackendBaseUrldestructive empty-save: clearing the URL field and saving removes all legacy keys while writing'', permanently discarding the user's server URL — unlikepersistSessionAuthTokenwhich guards against empty values.getBackendBaseUrlhandles three legacy keys gracefully, butgetSessionAuthTokenhas nolocalStoragefallback or cleanup for the previously-usedauth_tokenkey.persistSessionAuthTokenmeans there is no UI action to remove a stored session token short of closing the tab.Confidence Score: 3/5
The core key-unification logic is sound, but persistBackendBaseUrl has a destructive edge case when the URL field is saved empty: it removes all legacy keys while writing an empty string, permanently discarding the user's configured server URL.
The empty-URL path in persistBackendBaseUrl removes every legacy key and stores '' in their place — any user who clears the field and saves loses their server address irrecoverably. The auth token migration gap is a secondary concern that could silently drop authentication for users with a token stored by an earlier code path.
frontend/src/lib/settings-storage.ts — the empty-URL branch of persistBackendBaseUrl and the absence of a localStorage fallback/cleanup in getSessionAuthToken both need attention before merging.
Important Files Changed
persistBackendBaseUrl('')stores an empty string and removes all legacy keys — diverges from the symmetrical guard inpersistSessionAuthToken. Auth token migration path from localStorage is also missing.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[SettingsModal / SettingsPage handleSave] -->|url| B[persistBackendBaseUrl] A -->|token| C[persistSessionAuthToken] B --> D{url empty?} D -- No --> E[localStorage: set backend_base_url, remove legacy keys] D -- Yes --> F[localStorage: set backend_base_url=empty, remove legacy keys - URL lost] C --> G{token empty?} G -- No --> H[sessionStorage: set auth_token] G -- Yes --> I[no-op - existing token kept, no delete path] J[api.ts interceptors] -->|getBackendBaseUrl| K[localStorage: backend_base_url, api_url, agentnexus_backend_url, env var fallback] J -->|getSessionAuthToken| L[sessionStorage: auth_token - no localStorage fallback]Reviews (1): Last reviewed commit: "fix: keep frontend settings aligned with..." | Re-trigger Greptile