Send the read receipt the sender asked for
JMAP has an extension for this -- RFC 9007's MDN/send -- and Stalwart does not implement it, so ihasmail assembles the RFC 8098 multipart/report itself and sends it the long way round: raw MIME uploaded as a blob, imported, submitted. That is also why the receipt lands in Sent, which is where it honestly belongs. The plumbing is the easy half. A receipt tells whoever asked that the address is live and when the message was read, to an address the sender chose, so the refusals are the feature: nothing marked Auto-Submitted (RFC 3834, or two servers answer each other forever), nothing carrying Precedence bulk/list/junk or a List-Id, nothing already acknowledged, nothing that never arrived. A receipt aimed anywhere other than the sender is offered, but says so first. There is no "always send" setting, only ask or never. Sending is recorded with RFC 3503's $mdnsent keyword on the original rather than remembered locally, so a second look -- or another client entirely -- knows not to ask again. Non-ASCII parts go base64 rather than 8bit, so nothing rests on 8BITMIME surviving every hop. Verified against the mock end to end: the blob uploads, the receipt imports and submits, and the original reads back marked. Not yet exercised against the live server.
This commit is contained in:
@@ -8,6 +8,7 @@ export type Density = "comfortable" | "cozy" | "compact";
|
||||
export type ReadingPane = "right" | "bottom" | "off";
|
||||
export type ImagePolicy = "ask" | "always" | "contacts";
|
||||
export type ComposeFormat = "html" | "text";
|
||||
export type ReadReceiptPolicy = "ask" | "never";
|
||||
|
||||
export interface Template {
|
||||
id: string;
|
||||
@@ -35,6 +36,13 @@ export interface Settings {
|
||||
signatureAboveQuote: boolean;
|
||||
includeQuote: boolean;
|
||||
requestReadReceipt: boolean;
|
||||
/**
|
||||
* What to do when a sender asks for a read receipt. There is deliberately no
|
||||
* "always": an automatic receipt confirms to whoever asked that the address
|
||||
* is live and when it was read, which is exactly what a sender who should
|
||||
* not have that is fishing for. RFC 8098 asks that a person decide each one.
|
||||
*/
|
||||
readReceiptPolicy: ReadReceiptPolicy;
|
||||
confirmDelete: boolean;
|
||||
desktopNotifications: boolean;
|
||||
notificationSound: boolean;
|
||||
@@ -89,6 +97,7 @@ export const DEFAULT_SETTINGS: Settings = {
|
||||
signatureAboveQuote: true,
|
||||
includeQuote: true,
|
||||
requestReadReceipt: false,
|
||||
readReceiptPolicy: "ask",
|
||||
confirmDelete: false,
|
||||
desktopNotifications: false,
|
||||
notificationSound: false,
|
||||
|
||||
Reference in New Issue
Block a user