From ad5a51f7d4ede2326d8890704926b42514ccedb5 Mon Sep 17 00:00:00 2001 From: huyanxius <178478063+huyanxius@users.noreply.github.com> Date: Tue, 18 Aug 2026 02:06:35 +0000 Subject: [PATCH] fix(workspace): keep logout resilient to storage errors --- frontend/src/app/layout/app-header.test.tsx | 24 +++++++++++++++++++++ frontend/src/app/layout/app-header.tsx | 1 - 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/layout/app-header.test.tsx b/frontend/src/app/layout/app-header.test.tsx index 1fcffa03..669211cc 100644 --- a/frontend/src/app/layout/app-header.test.tsx +++ b/frontend/src/app/layout/app-header.test.tsx @@ -283,6 +283,30 @@ describe('AppHeader', () => { expect(await screen.findByRole('link', { name: '登录' })).toBeTruthy() }) + it('会话存储清理失败时仍通过共享会话边界退出', async () => { + window.localStorage.setItem('windup.auth.refresh-token', 'stored-refresh-token') + window.sessionStorage.setItem('windup.auth-session.invite-hint-seen.v1', '1') + const apis = createApis() + renderHeader('/projects', apis) + const originalRemoveItem = Storage.prototype.removeItem + const removeItem = vi + .spyOn(Storage.prototype, 'removeItem') + .mockImplementation(function (this: Storage, key) { + if (this === window.sessionStorage) { + throw new DOMException('Storage is disabled', 'SecurityError') + } + originalRemoveItem.call(this, key) + }) + + fireEvent.click(await screen.findByRole('button', { name: '打开账号菜单' })) + fireEvent.click(screen.getByRole('button', { name: '退出登录' })) + + await waitFor(() => expect(screen.getByTestId('location').textContent).toBe('/')) + expect(await screen.findByRole('link', { name: '登录' })).toBeTruthy() + expect(apis.logout).toHaveBeenCalledWith('rotated-refresh-token') + removeItem.mockRestore() + }) + it('没有昵称时使用邮箱展示账号身份', async () => { window.localStorage.setItem('windup.auth.refresh-token', 'stored-refresh-token') const apis = createApis() diff --git a/frontend/src/app/layout/app-header.tsx b/frontend/src/app/layout/app-header.tsx index 76bf54e3..c46dd69a 100644 --- a/frontend/src/app/layout/app-header.tsx +++ b/frontend/src/app/layout/app-header.tsx @@ -120,7 +120,6 @@ export function AppHeader({ quotaApis = defaultQuotaApis }: AppHeaderProps = {}) }, [pathname, session.state.status]) function signOut() { - window.sessionStorage.removeItem(inviteHintStorageKey) const returnHome = () => navigate('/', { replace: true }) void session.logout().then(returnHome, returnHome) }