From 5ebab3d8590751bf91ff7cac421fd2fc5b9aca42 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 1 Sep 2026 17:42:58 +0000 Subject: [PATCH] fix: remove Original-Recipient field from MDNs According to Original-Recipient field values in MDNs MUST NOT be included if the information about original recipient is not available. Original recipient may be obtained from ORCPT parameter of SMTP envelope or from Original-Recipient header which MTAs are expected to convert Original-Recipient to. The way we have been using Original-Recipient field is not correct. Technically we should look for Original-Recipient header on the message when downloading it from IMAP and then copy the value into MDN, but simply assuming it is never there is more correct than always assuming it is the same as our current address. I also grepped for Original-Recipient and removed it together with Reporting-UA from the tests. Orignal-Recipient is now only left in NDN (bounce messages) test data, there it is correct as this field is added by MTAs that have direct access to ORCPT parameter. --- src/mimefactory.rs | 8 +++----- src/mimefactory/mimefactory_tests.rs | 2 -- src/mimeparser/mimeparser_tests.rs | 9 --------- src/receive_imf/receive_imf_tests.rs | 2 -- test-data/message/mdn_without_message_reference.eml | 1 - 5 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 6c9eaf6df..b6308812e 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -2238,11 +2238,10 @@ impl MimeFactory { // second body part: machine-readable, always REQUIRED by RFC 6522 let message_text2 = format!( - "Original-Recipient: rfc822;{}\r\n\ - Final-Recipient: rfc822;{}\r\n\ + "Final-Recipient: rfc822;{}\r\n\ Original-Message-ID: <{}>\r\n\ Disposition: manual-action/MDN-sent-automatically; displayed\r\n", - self.from_addr, self.from_addr, rfc724_mid + self.from_addr, rfc724_mid ); let extension_fields = if additional_msg_ids.is_empty() { @@ -2527,8 +2526,7 @@ fn keyupdate_body(from_addr: &str) -> MimePart<'static> { message.add_part(MimePart::new( "message/disposition-notification", format!( - "Original-Recipient: rfc822;{from_addr}\r\n\ - Final-Recipient: rfc822;{from_addr}\r\n\ + "Final-Recipient: rfc822;{from_addr}\r\n\ Disposition: automatic-action/MDN-sent-automatically; processed\r\n" ), )); diff --git a/src/mimefactory/mimefactory_tests.rs b/src/mimefactory/mimefactory_tests.rs index 885ab4d40..b59d872b9 100644 --- a/src/mimefactory/mimefactory_tests.rs +++ b/src/mimefactory/mimefactory_tests.rs @@ -269,8 +269,6 @@ async fn test_subject_mdn() { --SNIPP\r\n\ Content-Type: message/disposition-notification\r\n\ \r\n\ - Reporting-UA: Delta Chat 1.28.0\r\n\ - Original-Recipient: rfc822;bob@example.com\r\n\ Final-Recipient: rfc822;bob@example.com\r\n\ Original-Message-ID: <2893@example.com>\r\n\ Disposition: manual-action/MDN-sent-automatically; displayed\r\n\ diff --git a/src/mimeparser/mimeparser_tests.rs b/src/mimeparser/mimeparser_tests.rs index e542c1037..96fd58b7b 100644 --- a/src/mimeparser/mimeparser_tests.rs +++ b/src/mimeparser/mimeparser_tests.rs @@ -570,8 +570,6 @@ This is no guarantee the content was read.\n\ --kJBbU58X1xeWNHgBtTbMk80M5qnV4N\n\ Content-Type: message/disposition-notification\n\ \n\ -Reporting-UA: Delta Chat 1.0.0-beta.22\n\ -Original-Recipient: rfc822;bob@example.org\n\ Final-Recipient: rfc822;bob@example.org\n\ Original-Message-ID: \n\ Disposition: manual-action/MDN-sent-automatically; displayed\n\ @@ -626,8 +624,6 @@ This is no guarantee the content was read.\n\ --kJBbU58X1xeWNHgBtTbMk80M5qnV4N\n\ Content-Type: message/disposition-notification\n\ \n\ -Reporting-UA: Delta Chat 1.0.0-beta.22\n\ -Original-Recipient: rfc822;bob@example.org\n\ Final-Recipient: rfc822;bob@example.org\n\ Original-Message-ID: \n\ Disposition: manual-action/MDN-sent-automatically; displayed\n\ @@ -650,8 +646,6 @@ This is no guarantee the content was read.\n\ --zuOJlsTfZAukyawEPVdIgqWjaM9w2W\n\ Content-Type: message/disposition-notification\n\ \n\ -Reporting-UA: Delta Chat 1.0.0-beta.22\n\ -Original-Recipient: rfc822;bob@example.org\n\ Final-Recipient: rfc822;bob@example.org\n\ Original-Message-ID: \n\ Disposition: manual-action/MDN-sent-automatically; displayed\n\ @@ -697,8 +691,6 @@ This is no guarantee the content was read.\n\ --kJBbU58X1xeWNHgBtTbMk80M5qnV4N\n\ Content-Type: message/disposition-notification\n\ \n\ -Reporting-UA: Delta Chat 1.0.0-beta.22\n\ -Original-Recipient: rfc822;bob@example.org\n\ Final-Recipient: rfc822;bob@example.org\n\ Original-Message-ID: \n\ Disposition: manual-action/MDN-sent-automatically; displayed\n\ @@ -1574,7 +1566,6 @@ async fn test_ignore_read_receipt_to_self() -> Result<()> { --SNIPP\r\n\ Content-Type: message/disposition-notification\r\n\ \r\n\ - Original-Recipient: rfc822;bob@example.com\r\n\ Final-Recipient: rfc822;bob@example.com\r\n\ Original-Message-ID: \r\n\ Disposition: manual-action/MDN-sent-automatically; displayed\r\n\ diff --git a/src/receive_imf/receive_imf_tests.rs b/src/receive_imf/receive_imf_tests.rs index 1c6ad18dd..1c5c9eca6 100644 --- a/src/receive_imf/receive_imf_tests.rs +++ b/src/receive_imf/receive_imf_tests.rs @@ -251,8 +251,6 @@ async fn test_mdn_and_alias() -> Result<()> { --SNIPP\n\ Content-Type: message/disposition-notification\n\ \n\ - Reporting-UA: Delta Chat 1.28.0\n\ - Original-Recipient: rfc822;bob@example.com\n\ Final-Recipient: rfc822;bob@example.com\n\ Original-Message-ID: <{msg_id}>\n\ Disposition: manual-action/MDN-sent-automatically; displayed\n\ diff --git a/test-data/message/mdn_without_message_reference.eml b/test-data/message/mdn_without_message_reference.eml index 14591ec95..d9e40809d 100644 --- a/test-data/message/mdn_without_message_reference.eml +++ b/test-data/message/mdn_without_message_reference.eml @@ -15,7 +15,6 @@ Read receipts do not guarantee sth. was read. --SNIPP Content-Type: message/disposition-notification -Original-Recipient: rfc822;bob@example.net Final-Recipient: rfc822;bob@example.net Disposition: automatic-action/MDN-sent-automatically; processed