From 43bb5e474a69d38a001be5b80dbf035550d308f2 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Sat, 31 Oct 2026 04:41:02 +0100 Subject: [PATCH] fix: leave a server's own all mailbox out of all mail and unread (bulwarkmail/webmail#1241) --- src/api/__tests__/unified-inbox-filter.test.ts | 9 +++++++++ src/api/unified-inbox.ts | 10 +++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/api/__tests__/unified-inbox-filter.test.ts b/src/api/__tests__/unified-inbox-filter.test.ts index 2ddede99..c6d9e945 100644 --- a/src/api/__tests__/unified-inbox-filter.test.ts +++ b/src/api/__tests__/unified-inbox-filter.test.ts @@ -45,6 +45,15 @@ describe('buildFilter (aggregated views)', () => { }); }); +describe("buildFilter: a server's own all mailbox (bulwarkmail/webmail#1241)", () => { + it('is left out of All mail and Unread', () => { + const withAll = [...MAILBOXES, mailbox('every', 'all')]; + expect(buildFilter(withAll, { view: 'all' })).toEqual({ + operator: 'OR', conditions: [{ inMailbox: 'in' }, { inMailbox: 'projects' }], + }); + }); +}); + describe('buildFilter: searching from All mail', () => { const all = [...MAILBOXES, mailbox('arch', 'archive'), mailbox('drafts', 'drafts'), mailbox('spam', 'junk')]; diff --git a/src/api/unified-inbox.ts b/src/api/unified-inbox.ts index 254a57d0..a49475d4 100644 --- a/src/api/unified-inbox.ts +++ b/src/api/unified-inbox.ts @@ -21,7 +21,7 @@ import { LIST_AUTH_RESULTS_PROPERTY } from '../lib/email-headers'; const EMAIL_LIST_PROPERTIES = [ 'id', 'threadId', 'mailboxIds', 'keywords', 'size', - 'receivedAt', 'from', 'to', 'cc', 'subject', 'preview', 'hasAttachment', + 'receivedAt', 'from', 'to', 'cc', 'subject', 'preview', 'hasAttachment', 'sentAt', // The sender check, for the warning shield on a forged From (#1439). LIST_AUTH_RESULTS_PROPERTY, ]; @@ -32,9 +32,13 @@ const MAILBOX_CACHE_TTL_MS = 60 * 1000; export type UnifiedRole = 'inbox' | 'sent' | 'drafts' | 'junk' | 'archive' | 'trash'; export type CrossView = 'all' | 'unread' | 'starred'; -/** Roles left out of the cross-account All mail / Unread / Starred views. */ +/** + * Roles left out of the cross-account All mail / Unread / Starred views. A + * server's own "all" mailbox holds every message again, so listing it beside + * the real folders doubled them (webmail lib/jmap/types.ts, #1241). + */ export const CROSS_EXCLUDED_ROLES: ReadonlySet = new Set([ - 'junk', 'spam', 'sent', 'archive', 'trash', 'drafts', + 'junk', 'spam', 'sent', 'archive', 'trash', 'drafts', 'all', ]); export interface UnifiedEmail extends Email {