From a51682917182ac7691e2fd09e3c01a281eaaa9b8 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 1 Sep 2026 18:31:24 +0000 Subject: [PATCH] feat: remove Final-Recipient from MDNs (and keyupdates) This Final-Recipient was not set to the correct value anyway. We could query the database and find out via `imap` table which transport we have received the message on, but it is not worth the effort as the field is not practically used and cannot be relied on as old versions still send incorrect value. This removes one call to get_primary_self_addr() to make it easier to remove the concept of the "primary" address eventually. --- src/mimefactory.rs | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/mimefactory.rs b/src/mimefactory.rs index b6308812e..e72643036 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -2237,11 +2237,14 @@ impl MimeFactory { ); // second body part: machine-readable, always REQUIRED by RFC 6522 + // + // We do not include the Final-Recipient field. + // According to + // it MUST be present and be the address on which original message was received, + // but practically it is not going to be used. let message_text2 = format!( - "Final-Recipient: rfc822;{}\r\n\ - Original-Message-ID: <{}>\r\n\ + "Original-Message-ID: <{rfc724_mid}>\r\n\ Disposition: manual-action/MDN-sent-automatically; displayed\r\n", - self.from_addr, rfc724_mid ); let extension_fields = if additional_msg_ids.is_empty() { @@ -2513,24 +2516,24 @@ pub(crate) async fn render_symm_encrypted_securejoin_message( /// a `multipart/report` is trashed as an MDN even where unencrypted mail is accepted, /// while a plain text body would end up in a contact request. /// The report deliberately names no original message, see [`crate::keyupdate`]. -fn keyupdate_body(from_addr: &str) -> MimePart<'static> { +fn keyupdate_body() -> MimePart<'static> { // Human-readable first part as RFC 6522 requires, untranslated like in `render_mdn`. let text_part = MimePart::new( "text/plain", "This message updates the sender's encryption key and relay list.", ); - let mut message = MimePart::new( - "multipart/report; report-type=disposition-notification", - vec![text_part], - ); - message.add_part(MimePart::new( + // We do not include the Final-Recipient field. + // Technically it is required for MDNs, but keyupdates + // are sent not in response to any message, + // so we don't have the address on which we received the message either. + let machine_part = MimePart::new( "message/disposition-notification", - format!( - "Final-Recipient: rfc822;{from_addr}\r\n\ - Disposition: automatic-action/MDN-sent-automatically; processed\r\n" - ), - )); - message + "Disposition: automatic-action/MDN-sent-automatically; processed\r\n", + ); + MimePart::new( + "multipart/report; report-type=disposition-notification", + vec![text_part, machine_part], + ) } /// Renders a keyupdate message informing the owners of `recipient_keys` @@ -2545,7 +2548,7 @@ pub(crate) async fn render_keyupdate_message( "Sending keyupdate message to {} recipients.", recipient_keys.len() ); - let message = keyupdate_body(&context.get_primary_self_addr().await?); + let message = keyupdate_body(); let headers = non_chat_headers(context, "Keyupdate").await?; let message = add_headers_to_encrypted_part(message, headers);