fix: persist active account across reload, remount views on switch
Aligns with upstream stalwartlabs/webui@189e270 (v1.0.7, "fixes #17"), reviewed after they independently landed a fix for the same issue: - authStore now persists activeAccountId (sessionStorage) and setSession preserves it across a session refresh instead of always resetting to primaryAccountId, so a hard reload keeps you on the group account you had selected instead of bouncing back to your own. - switchAccount now clears cacheStore (displayNames/objectLists) when actually changing account, since those were resolved against the previous account and would otherwise show stale labels. - The ErrorBoundary wrapping MainContent is now keyed on activeAccountId, forcing a full remount of every view on switch. This is more robust than gating individual components' fetch effects on activeAccountId (our earlier fix in DynamicList.tsx, kept as-is — harmless now, but no longer load-bearing on its own) since it covers every current and future view type, not just lists. Verified against a live instance: switching to a group account updates the JMAP accountId immediately (no tab switch needed), and a full page reload keeps the group account active instead of resetting to admin. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
8c1e826d63
commit
bd00b4e922
@@ -6,6 +6,7 @@
|
||||
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { useAuthStore } from './authStore';
|
||||
import { useCacheStore } from './cacheStore';
|
||||
|
||||
const initialState = {
|
||||
accessToken: null,
|
||||
@@ -21,6 +22,7 @@ const initialState = {
|
||||
describe('authStore', () => {
|
||||
beforeEach(() => {
|
||||
useAuthStore.setState(initialState);
|
||||
useCacheStore.setState({ displayNames: {}, objectLists: {} });
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
@@ -124,6 +126,26 @@ describe('authStore', () => {
|
||||
|
||||
expect(useAuthStore.getState().activeAccountId).toBe('acc-1');
|
||||
});
|
||||
|
||||
it('preserves the previously active account across a reload if still valid', () => {
|
||||
useAuthStore.setState({ activeAccountId: 'acc-2' });
|
||||
const accounts = {
|
||||
'acc-1': { name: 'Personal', isPersonal: true },
|
||||
'acc-2': { name: 'Shared', isPersonal: false },
|
||||
};
|
||||
|
||||
useAuthStore.getState().setSession(accounts, 'acc-1', 'https://api');
|
||||
|
||||
expect(useAuthStore.getState().activeAccountId).toBe('acc-2');
|
||||
});
|
||||
|
||||
it('falls back to primaryAccountId if the previously active account is gone', () => {
|
||||
useAuthStore.setState({ activeAccountId: 'acc-removed' });
|
||||
|
||||
useAuthStore.getState().setSession({ 'acc-1': { name: 'A', isPersonal: true } }, 'acc-1', 'https://api');
|
||||
|
||||
expect(useAuthStore.getState().activeAccountId).toBe('acc-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('switchAccount', () => {
|
||||
@@ -149,6 +171,33 @@ describe('authStore', () => {
|
||||
useAuthStore.getState().switchAccount('nonexistent');
|
||||
expect(useAuthStore.getState().activeAccountId).toBe('a1');
|
||||
});
|
||||
|
||||
it('clears the cache store when switching to a different account', () => {
|
||||
useAuthStore.setState({
|
||||
accounts: {
|
||||
a1: { name: 'A1', isPersonal: true },
|
||||
a2: { name: 'A2', isPersonal: false },
|
||||
},
|
||||
activeAccountId: 'a1',
|
||||
});
|
||||
useCacheStore.getState().setDisplayNames('x:Domain', { d1: 'example.org' });
|
||||
|
||||
useAuthStore.getState().switchAccount('a2');
|
||||
|
||||
expect(useCacheStore.getState().displayNames).toEqual({});
|
||||
});
|
||||
|
||||
it('does not clear the cache store when "switching" to the already-active account', () => {
|
||||
useAuthStore.setState({
|
||||
accounts: { a1: { name: 'A1', isPersonal: true } },
|
||||
activeAccountId: 'a1',
|
||||
});
|
||||
useCacheStore.getState().setDisplayNames('x:Domain', { d1: 'example.org' });
|
||||
|
||||
useAuthStore.getState().switchAccount('a1');
|
||||
|
||||
expect(useCacheStore.getState().displayNames).toEqual({ 'x:Domain': { d1: 'example.org' } });
|
||||
});
|
||||
});
|
||||
|
||||
describe('logout', () => {
|
||||
|
||||
Reference in New Issue
Block a user