From a44f781495e9cb2f830795eb35f2af512d21b1c8 Mon Sep 17 00:00:00 2001 From: Max Dor Date: Sat, 27 Apr 2019 16:36:55 +0200 Subject: [PATCH] Properly encode Email notification headers (Fix #137) --- .../connector/email/EmailSmtpConnector.java | 14 +++++++++++++- .../test/notification/EmailNotificationTest.java | 11 ++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java index 8749abc..2c6fb9d 100644 --- a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java +++ b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSmtpConnector.java @@ -31,14 +31,17 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.mail.Header; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeUtility; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.Enumeration; import java.util.Properties; public class EmailSmtpConnector implements EmailConnector { @@ -97,7 +100,16 @@ public class EmailSmtpConnector implements EmailConnector { try { InternetAddress sender = new InternetAddress(senderAddress, senderName); MimeMessage msg = new MimeMessage(session, IOUtils.toInputStream(content, StandardCharsets.UTF_8)); - msg.setHeader("X-Mailer", Mxisd.Agent); + + // We must encode our headers ourselves as we have no guarantee that they were in the provided data. + // This is required to support UTF-8 characters from user display names or room names in the subject header per example + Enumeration
headers = msg.getAllHeaders(); + while (headers.hasMoreElements()) { + Header header = headers.nextElement(); + msg.setHeader(header.getName(), MimeUtility.encodeText(header.getValue())); + } + + msg.setHeader("X-Mailer", MimeUtility.encodeText(Mxisd.Agent)); msg.setSentDate(new Date()); msg.setFrom(sender); msg.setRecipients(Message.RecipientType.TO, recipient); diff --git a/src/test/java/io/kamax/mxisd/test/notification/EmailNotificationTest.java b/src/test/java/io/kamax/mxisd/test/notification/EmailNotificationTest.java index 4350198..5089b46 100644 --- a/src/test/java/io/kamax/mxisd/test/notification/EmailNotificationTest.java +++ b/src/test/java/io/kamax/mxisd/test/notification/EmailNotificationTest.java @@ -60,7 +60,8 @@ public class EmailNotificationTest { private final String user = "mxisd"; private final String notifiee = "john"; private final String sender = user + "@" + domain; - private final String senderEmail = "\"Mxisd Server (Unit Test)\" <" + sender + ">"; + private final String senderName = "\"Mxisd Server あ (Unit Test)\" <" + sender + ">"; + private final String senderNameEncoded = "=?UTF-8?Q?=22Mxisd_Server_=E3=81=82_=28Unit_T?= =?UTF-8?Q?est=29=22_=3Cmxisd=40localhost=3E?= "; private final String target = notifiee + "@" + domain; private Mxisd m; @@ -76,7 +77,7 @@ public class EmailNotificationTest { EmailConfig eCfg = new EmailConfig(); eCfg.setConnector(EmailSmtpConnector.ID); eCfg.getIdentity().setFrom(sender); - eCfg.getIdentity().setName("Mxisd Server (Unit Test)"); + eCfg.getIdentity().setName(senderName); eCfg.getConnectors().put(EmailSmtpConnector.ID, GsonUtil.makeObj(smtpCfg)); MxisdConfig cfg = new MxisdConfig(); @@ -118,7 +119,7 @@ public class EmailNotificationTest { assertEquals(1, gm.getReceivedMessages().length); MimeMessage msg = gm.getReceivedMessages()[0]; assertEquals(1, msg.getFrom().length); - assertEquals(senderEmail, msg.getFrom()[0].toString()); + assertEquals(senderNameEncoded, msg.getFrom()[0].toString()); assertEquals(1, msg.getRecipients(Message.RecipientType.TO).length); } @@ -135,7 +136,7 @@ public class EmailNotificationTest { assertEquals(1, gm.getReceivedMessages().length); MimeMessage msg = gm.getReceivedMessages()[0]; assertEquals(1, msg.getFrom().length); - assertEquals(senderEmail, msg.getFrom()[0].toString()); + assertEquals(senderNameEncoded, msg.getFrom()[0].toString()); assertEquals(1, msg.getRecipients(Message.RecipientType.TO).length); // We just check on the text/plain one. HTML is multipart and it's difficult so we skip @@ -165,7 +166,7 @@ public class EmailNotificationTest { assertEquals(1, gm.getReceivedMessages().length); MimeMessage msg = gm.getReceivedMessages()[0]; assertEquals(1, msg.getFrom().length); - assertEquals(senderEmail, msg.getFrom()[0].toString()); + assertEquals(senderNameEncoded, msg.getFrom()[0].toString()); assertEquals(1, msg.getRecipients(Message.RecipientType.TO).length); // We just check on the text/plain one. HTML is multipart and it's difficult so we skip