This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new bbe9ffd979 JAMES-5431 add SanitizeMimeMessageId mailet  (#2718)
bbe9ffd979 is described below

commit bbe9ffd97980193b69b243c63c31697e1c09b044
Author: AlaeMghirbi <alae.mghirbi6...@gmail.com>
AuthorDate: Fri May 16 03:53:06 2025 +0200

    JAMES-5431 add SanitizeMimeMessageId mailet  (#2718)
---
 .../servers/partials/SanitizeMimeMessageId.adoc    | 28 +++++++++
 .../servers/partials/configure/mailets.adoc        |  4 +-
 .../transport/mailets/SanitizeMimeMessageId.java   | 52 ++++++++++++++++
 .../mailets/SanitizeMimeMessageIdTest.java         | 72 ++++++++++++++++++++++
 4 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/docs/modules/servers/partials/SanitizeMimeMessageId.adoc 
b/docs/modules/servers/partials/SanitizeMimeMessageId.adoc
new file mode 100644
index 0000000000..6a45c354b3
--- /dev/null
+++ b/docs/modules/servers/partials/SanitizeMimeMessageId.adoc
@@ -0,0 +1,28 @@
+=== SanitizeMimeMessageId Mailet
+
+Some email clients, such as Outlook for Android, may send emails **without a 
`Message-ID` header**.
+
+== Why is this needed?
+ The absence of the `Message-ID` header can cause emails to be rejected by 
downstream mail servers,
+ as required by RFC 5322 specifications. For example, Gmail rejects messages 
without this header with
+ an error like the following:
+ 550-5.7.1 [IP] Messages missing a valid Message-ID header are not
+ 550-5.7.1 accepted. For more information, go to
+ 550-5.7.1 https://support.google.com/mail/?p=RfcMessageNonCompliant and review
+ 550 5.7.1 RFC 5322 specifications.
+
+To mitigate this, the `SanitizeMimeMessageId` mailet will automatically add a 
`Message-ID` to emails **that lack one**.
+
+== Configuration
+
+You can configure it simply by adding the following in your 
`mailetcontainer.xml` file:
+
+....
+<mailet match="All" class="SanitizeMimeMessageId"/>
+....
+
+== Behavior
+
+- If a `Message-ID` header already exists: nothing is done.
+- If the header is missing: a new one is generated and added.
+
diff --git a/docs/modules/servers/partials/configure/mailets.adoc 
b/docs/modules/servers/partials/configure/mailets.adoc
index adcdff20d6..d89df01b5c 100644
--- a/docs/modules/servers/partials/configure/mailets.adoc
+++ b/docs/modules/servers/partials/configure/mailets.adoc
@@ -147,4 +147,6 @@ include::partial$UseHeaderRecipients.adoc[]
 
 include::partial$WrapText.adoc[]
 
-include::partial$SubAddressing.adoc[]
\ No newline at end of file
+include::partial$SubAddressing.adoc[]
+
+include::partial$SanitizeMimeMessageId.adoc[]
\ No newline at end of file
diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/SanitizeMimeMessageId.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/SanitizeMimeMessageId.java
new file mode 100644
index 0000000000..4f43ad2be0
--- /dev/null
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/SanitizeMimeMessageId.java
@@ -0,0 +1,52 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.transport.mailets;
+
+import jakarta.mail.MessagingException;
+
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+
+/**
+* The `SanitizeMimeMessageId` mailet is designed to address a specific issue 
where some email clients, such as Outlook for Android, do not add the MIME 
`Message-ID` header to the emails they send.
+* The absence of the `Message-ID` header can cause emails to be rejected by 
downstream mail servers,
+* as required by RFC 5322 specifications.
+*
+* Sample configuration:
+*
+* <pre><code>
+* &lt;mailet match="All" class="SanitizeMimeMessageId"&gt;
+* &lt;/mailet&gt;
+* </code></pre>
+*/
+public class SanitizeMimeMessageId extends GenericMailet {
+
+    @Override
+    public void service(Mail mail) throws MessagingException {
+        if (mail.getMessage().getMessageID() == null) {
+            mail.getMessage().saveChanges();
+        }
+    }
+
+    @Override
+    public String getMailetInfo() {
+        return "SanitizeMimeMessageId Mailet";
+    }
+}
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/SanitizeMimeMessageIdTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/SanitizeMimeMessageIdTest.java
new file mode 100644
index 0000000000..9ca4c10c88
--- /dev/null
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/SanitizeMimeMessageIdTest.java
@@ -0,0 +1,72 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.transport.mailets;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Properties;
+
+import jakarta.mail.Session;
+import jakarta.mail.internet.MimeMessage;
+
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.FakeMailetConfig;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class SanitizeMimeMessageIdTest {
+
+    private SanitizeMimeMessageId testee;
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        testee = new SanitizeMimeMessageId();
+        testee.init(FakeMailetConfig.builder()
+            .mailetName("SanitizeMimeMessageId")
+            .build());
+    }
+
+    @Test
+    public void shouldAddMessageIdWhenMissing() throws Exception {
+        MimeMessage mimeMessage = new 
MimeMessage(Session.getDefaultInstance(new Properties()));
+        FakeMail mail = FakeMail.builder()
+            .name("mail")
+            .mimeMessage(mimeMessage)
+            .build();
+
+        testee.service(mail);
+
+        assertThat(mail.getMessage().getHeader("Message-ID")).isNotNull();
+    }
+
+    @Test
+    public void shouldNotModifyExistingMessageId() throws Exception {
+        MimeMessage mimeMessage = new 
MimeMessage(Session.getDefaultInstance(new Properties()));
+        mimeMessage.setHeader("Message-ID", "<existing...@domain.com>");
+        FakeMail mail = FakeMail.builder()
+            .name("mail")
+            .mimeMessage(mimeMessage)
+            .build();
+
+        testee.service(mail);
+
+        
assertThat(mail.getMessage().getHeader("Message-ID")).containsExactly("<existing...@domain.com>");
+    }
+}
+


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to