diff --git a/ui/src/components/cliproxy/control-panel-embed.tsx b/ui/src/components/cliproxy/control-panel-embed.tsx
index 704dab5a..2b0346df 100644
--- a/ui/src/components/cliproxy/control-panel-embed.tsx
+++ b/ui/src/components/cliproxy/control-panel-embed.tsx
@@ -22,6 +22,8 @@ interface ControlPanelEmbedProps {
port?: number;
}
+// These keys intentionally mirror the upstream management-center auth schema.
+// Keep them in sync with external/Cli-Proxy-API-Management-Center/src/stores/useAuthStore.ts.
const CONTROL_PANEL_AUTH_STORAGE_KEY = 'cli-proxy-auth';
const CONTROL_PANEL_LOGIN_FLAG_KEY = 'isLoggedIn';
const CONTROL_PANEL_API_BASE_KEY = 'apiBase';
@@ -153,6 +155,16 @@ export function ControlPanelEmbed({ port = CLIPROXY_DEFAULT_PORT }: ControlPanel
}
}, [authTokensError]);
+ useEffect(() => {
+ if (isRemote) {
+ return;
+ }
+
+ return () => {
+ clearLocalControlPanelSession();
+ };
+ }, [isRemote]);
+
const iframeLoaded = loadedFrameKey === iframeKey;
const isLoading = !isSessionReady || !iframeLoaded;
diff --git a/ui/tests/unit/components/cliproxy/control-panel-embed.test.tsx b/ui/tests/unit/components/cliproxy/control-panel-embed.test.tsx
index e7a7790d..e70c0a52 100644
--- a/ui/tests/unit/components/cliproxy/control-panel-embed.test.tsx
+++ b/ui/tests/unit/components/cliproxy/control-panel-embed.test.tsx
@@ -76,7 +76,7 @@ describe('ControlPanelEmbed', () => {
vi.stubGlobal('fetch', fetchMock);
- render();
+ const { unmount } = render();
await waitFor(() => {
expect(fetchMock).toHaveBeenCalledWith('/api/settings/auth/tokens/raw');
@@ -108,6 +108,15 @@ describe('ControlPanelEmbed', () => {
expect(window.localStorage.setItem).toHaveBeenCalledWith('managementKey', 'custom-secret');
expect(window.localStorage.setItem).toHaveBeenCalledWith('isLoggedIn', 'true');
});
+
+ vi.clearAllMocks();
+ unmount();
+
+ expect(window.localStorage.removeItem).toHaveBeenCalledWith('cli-proxy-auth');
+ expect(window.localStorage.removeItem).toHaveBeenCalledWith('apiBase');
+ expect(window.localStorage.removeItem).toHaveBeenCalledWith('apiUrl');
+ expect(window.localStorage.removeItem).toHaveBeenCalledWith('managementKey');
+ expect(window.localStorage.removeItem).toHaveBeenCalledWith('isLoggedIn');
});
it('clears stale local control-panel session keys when token bootstrap fails', async () => {