Files
webmail/lib/outgoing/composer-send-options.ts
T
Linus Rath db5ac82f53 feat: keep recent mail on this device and send mail written offline #523
Settings > Backup & reset gets "Keep mail on this device", off until the
user turns it on in this browser. While it is on:

- the JMAP client hands the server's answers to an encrypted cache in
  IndexedDB (AES-GCM, non-extractable key) and answers from it when the
  network is gone: the folder list, the last 30 days of the Inbox and of
  the folders the user opened, bodies and attachments, at most 250 MB,
  oldest out first; a background sync keeps it current
- read, flag, tags and moves made offline are queued and sent in order
  when the server answers again; deleting for good and emptying a folder
  are refused offline
- the composer, quick reply and the S/MIME and PGP plugins' sends that
  complete the composer's go to an outbox once every step up to the
  transport ran (checks, label, signature, plugin send checks); only the
  finished send waits, with files attached offline
- the service worker keeps this build's app shell, so the app also
  starts offline from the kept session and the last policy
- a full sign-out, the idle sign-out and signing one account out delete
  it, a sign-out the user starts asks first when mail is unsent, and the
  login page names what an automatic sign-out deleted; a policy fetch
  that forbids it (devices.noOffline) wipes that account

Not in Lite.
2026-11-01 11:46:11 +01:00

36 lines
1.2 KiB
TypeScript

import type { MessagePriority } from '@/lib/message-priority';
/** What the composer's onSend hands its host beyond the message itself. */
export interface ComposerSendExtras {
requestReadReceipt?: boolean;
requestDsn?: boolean;
requireTls?: boolean;
priority?: MessagePriority;
headers?: Record<string, string>;
labelHeaders?: Record<string, string>;
localAccountId?: string;
draftAccountId?: string;
}
/**
* The options object of useEmailStore.sendEmail for a composer send. Every
* host of the composer (the mail page, a Pro compose tab) passes it whole,
* so none drops the read receipt, DSN, REQUIRETLS, priority, plugin headers
* or the classification label: the Pro tab used to send without them.
*/
export function composerSendOptions(data: ComposerSendExtras): ComposerSendExtras & { outbox: true } {
return {
// Every step of the send ran at Send, so offline mode may keep the
// finished message in its outbox (#523).
outbox: true,
requestReadReceipt: data.requestReadReceipt,
requestDsn: data.requestDsn,
requireTls: data.requireTls,
priority: data.priority,
headers: data.headers,
labelHeaders: data.labelHeaders,
localAccountId: data.localAccountId,
draftAccountId: data.draftAccountId,
};
}