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:
dealerweb
2026-05-30 15:58:39 +02:00
committed by Linus Rath
parent 2ba0003e16
commit bebb394f54
28 changed files with 901 additions and 9 deletions
+22
View File
@@ -260,6 +260,15 @@
"reschedule_prompt": "Wprowadź nową datę/godzinę, np. 2026-05-04T15:30"
},
"email_viewer": {
"read_receipt": {
"prompt": "Nadawca prosi o potwierdzenie przeczytania:",
"send": "Wyślij potwierdzenie",
"ignore": "Ignoruj",
"sent": "Wysłano potwierdzenie przeczytania.",
"send_failed": "Nie udało się wysłać potwierdzenia przeczytania",
"mdn_subject": "Przeczytano: {subject}",
"mdn_body": "To jest potwierdzenie przeczytania wiadomości wysłanej do {recipient}.\n\nUwaga: to potwierdzenie oznacza jedynie, że wiadomość została wyświetlona na komputerze odbiorcy. Nie gwarantuje, że odbiorca przeczytał lub zrozumiał treść."
},
"no_email_selected": "Nie wybrano wiadomości",
"no_email_description": "Wybierz wiadomość z listy, aby ją wyświetlić",
"no_conversation_selected": "Nie wybrano konwersacji",
@@ -545,6 +554,8 @@
"undo_send": "Cofnij wysyłkę"
},
"email_composer": {
"read_receipt_on": "Zażądano potwierdzenia przeczytania (kliknij, aby wyłączyć)",
"read_receipt_off": "Zażądaj potwierdzenia przeczytania",
"new_message": "Nowa wiadomość",
"reply": "Odpowiedz",
"reply_all": "Odpowiedz wszystkim",
@@ -1006,6 +1017,17 @@
}
},
"email_behavior": {
"request_read_receipt": {
"label": "Domyślnie żądaj potwierdzeń przeczytania",
"description": "Włącz wcześniej żądanie potwierdzenia przeczytania podczas tworzenia nowej wiadomości."
},
"read_receipt_response": {
"label": "Odpowiadaj na żądania potwierdzenia przeczytania",
"description": "Co zrobić, gdy przychodząca wiadomość prosi o potwierdzenie przeczytania.",
"ask": "Pytaj za każdym razem",
"always": "Zawsze wysyłaj",
"never": "Nigdy nie wysyłaj"
},
"title": "Zachowanie poczty e-mail",
"description": "Skonfiguruj sposób obsługi wiadomości e-mail",
"mark_read": {