From d8f6be7b1e367644452da2e885b587180b9cd08d Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Sun, 1 Nov 2026 05:42:00 +0100 Subject: [PATCH] fix: delete a finished export's file from the browser when its account signs out --- .../__tests__/mail-export-dialog.test.tsx | 21 +++++++++++++++++++ .../mail-transfer/mail-transfer-host.tsx | 7 +++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/components/mail-transfer/__tests__/mail-export-dialog.test.tsx b/components/mail-transfer/__tests__/mail-export-dialog.test.tsx index ec0175d28..2b0c24149 100644 --- a/components/mail-transfer/__tests__/mail-export-dialog.test.tsx +++ b/components/mail-transfer/__tests__/mail-export-dialog.test.tsx @@ -83,6 +83,27 @@ describe('MailExportDialog', () => { expect(useMailTransferStore.getState().request).toBeNull(); }); + it('signing out stops a running export, or frees a finished one\'s file', async () => { + const { runBeforeSignOut } = await import('@/lib/sign-out-cleanup'); + const controller = new AbortController(); + render(); + act(() => { + openMailExport({ mailboxId: 'inbox' }); + useMailTransferStore.getState().startJob({ kind: 'export', controller, progress: { phase: 'running', exported: 1, failed: 0, failures: [], total: 4, fraction: 0.25 } }); + }); + await act(() => runBeforeSignOut('acc1')); + expect(controller.signal.aborted).toBe(true); + + const discard = vi.fn(async () => {}); + act(() => { + useMailTransferStore.setState({ request: null, visible: false, job: null }); + openMailExport({ mailboxId: 'inbox' }); + useMailTransferStore.getState().startJob({ kind: 'export', controller: new AbortController(), progress: { phase: 'done', exported: 3, failed: 0, failures: [], total: 3, fraction: 1, file: { name: 'a.mbox', size: 1, discard } } }); + }); + await act(() => runBeforeSignOut('acc1')); + expect(discard).toHaveBeenCalled(); + }); + it('runs on in the background and the chip names the export', () => { const controller = new AbortController(); render(); diff --git a/components/mail-transfer/mail-transfer-host.tsx b/components/mail-transfer/mail-transfer-host.tsx index ee8e85174..a69c920e5 100644 --- a/components/mail-transfer/mail-transfer-host.tsx +++ b/components/mail-transfer/mail-transfer-host.tsx @@ -20,9 +20,12 @@ export function MailTransferHost() { const visible = useMailTransferStore((s) => s.visible); const job = useMailTransferStore((s) => s.job); - // An account that signs out takes its running job and its checkpoints with it. + // An account that signs out takes its running job, a finished export's + // file in the browser's private storage, and its checkpoints with it. useEffect(() => onBeforeSignOut(async (accountId) => { - useMailTransferStore.getState().cancelJob(); + const store = useMailTransferStore.getState(); + if (isJobActive(store.job)) store.cancelJob(); + else store.close(); if (accountId !== "all") await clearCheckpointsFor(accountId); }), []);