fix: forget an account's saved sender identities when it is signed out

This commit is contained in:
Linus Rath
2026-10-31 20:36:40 +01:00
parent 5d91243451
commit 2c40bc6709
3 changed files with 18 additions and 1 deletions
+9 -1
View File
@@ -5,7 +5,7 @@ import fs from 'node:fs';
import path from 'node:path';
import AsyncStorage from '@react-native-async-storage/async-storage';
import type { Identity } from '../../api/types';
import { loadComposerIdentities, readCachedIdentities } from '../identity-cache';
import { forgetCachedIdentities, loadComposerIdentities, readCachedIdentities } from '../identity-cache';
const me = { id: 'i1', name: 'User A', email: 'usera@example.org', mayDelete: false } as Identity;
const offline = () => Promise.reject(new Error('Network request failed'));
@@ -15,6 +15,14 @@ beforeEach(async () => {
});
describe('composer identities', () => {
it('drops the kept identities when the login leaves the device', async () => {
await loadComposerIdentities('usera@host', async () => [me]);
await forgetCachedIdentities('usera@host');
expect(await readCachedIdentities('usera@host')).toEqual([]);
const auth = fs.readFileSync(path.resolve(__dirname, '../../stores/auth-store.ts'), 'utf8');
expect(auth).toMatch(/async function forgetRemovedAccount\(accountId: string\): Promise<void> \{\s*void forgetCachedIdentities\(accountId\);/);
});
it('keeps what the server said for the login', async () => {
const result = await loadComposerIdentities('usera@host', async () => [me]);
expect(result).toEqual({ identities: [me], fresh: true, error: null });
+7
View File
@@ -27,6 +27,13 @@ export async function readCachedIdentities(localAccountId: string | null | undef
}
}
/** Drop the identities kept for a login that left this device. */
export async function forgetCachedIdentities(localAccountId: string): Promise<void> {
try {
await AsyncStorage.removeItem(keyFor(localAccountId));
} catch { /* best effort */ }
}
/** Keep what the server just said, for the next composer opened offline. */
export async function writeCachedIdentities(localAccountId: string | null | undefined, identities: Identity[]): Promise<void> {
if (!localAccountId) return;
+2
View File
@@ -1,3 +1,4 @@
import { forgetCachedIdentities } from '../lib/identity-cache';
import { create } from 'zustand';
import {
jmapClient,
@@ -176,6 +177,7 @@ function clearDeviceWideAccountData(): void {
// until nobody is signed in. When it was the last account, the device-wide
// data goes too.
async function forgetRemovedAccount(accountId: string): Promise<void> {
void forgetCachedIdentities(accountId);
try {
const feeds = useCalendarSubscriptionsStore;
// On a cold start the stored list may not have been read yet; written