Feature: read receipts (MDN, RFC 8098)
Bulwark had no read-receipt support (JMAP/Stalwart have no native MDN). End-to-end, client-side, in three parts: - Request (compose): a toolbar toggle (MailCheck, green when on) sets Disposition-Notification-To on the outgoing message via the JMAP "header:<name>:asText" create property. Threaded composer -> page -> email-store -> client.sendEmail. Default from requestReadReceiptDefault. - Detect (viewer): reads Disposition-Notification-To case-insensitively from the parsed headers and shows a banner (green Send / red Ignore) in the unified notification bar. Hidden in Sent/Drafts/Trash/Junk and once handled. message/disposition-notification + message/delivery-status report parts are filtered out of the attachment list. - Respond (MDN): lib/mdn.ts builds an RFC 8098 multipart/report (text/plain + message/disposition-notification, UTF-8/base64, localized subject + body). client.sendReadReceipt uploads the blob, imports it into Sent via Email/import, then submits with an explicit envelope. Both Send and Ignore set the $MDNSent keyword (RFC 3503) so no client re-prompts. Behaviour configurable: ask / always / never. New: lib/mdn.ts, read-receipt-banner.tsx. Settings (requestReadReceiptDefault, readReceiptResponse) + UI. All 17 locales.
This commit is contained in:
@@ -150,8 +150,30 @@ export interface IJMAPClient {
|
||||
references?: string[],
|
||||
delayedUntil?: string,
|
||||
envelopeMailFrom?: string,
|
||||
options?: { requestReadReceipt?: boolean },
|
||||
): Promise<SendEmailResult>;
|
||||
|
||||
importEmail(
|
||||
blobId: string,
|
||||
mailboxIds: Record<string, boolean>,
|
||||
keywords?: Record<string, boolean>,
|
||||
accountId?: string,
|
||||
): Promise<string | null>;
|
||||
|
||||
sendReadReceipt(params: {
|
||||
to: string;
|
||||
fromEmail: string;
|
||||
fromName?: string;
|
||||
identityId: string;
|
||||
originalMessageId?: string | string[];
|
||||
originalSubject?: string;
|
||||
originalRecipient?: string;
|
||||
automatic?: boolean;
|
||||
accountId?: string;
|
||||
subject?: string;
|
||||
humanText?: string;
|
||||
}): Promise<void>;
|
||||
|
||||
sendRawEmail(blob: Blob, identityId: string, sentMailboxId: string, draftMailboxId?: string, delayedUntil?: string, envelopeRecipients?: string[]): Promise<SendEmailResult>;
|
||||
getScheduledEmails(limit?: number, position?: number): Promise<{ emails: ScheduledEmail[]; hasMore: boolean; total: number; nextPosition: number }>;
|
||||
cancelEmailSubmission(submissionId: string): Promise<void>;
|
||||
|
||||
Reference in New Issue
Block a user