Skip to content

Commit 2ea9e7b

Browse files
committed
Moved DKIM api to dedicated DkimConfig class and added feature to exclude certain headers from the default list of headers to sign
1 parent cb4df25 commit 2ea9e7b

File tree

16 files changed

+332
-245
lines changed

16 files changed

+332
-245
lines changed

modules/core-module/src/main/java/org/simplejavamail/api/email/Email.java

Lines changed: 14 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import jakarta.mail.internet.MimeMessage;
55
import org.jetbrains.annotations.NotNull;
66
import org.jetbrains.annotations.Nullable;
7+
import org.simplejavamail.api.email.config.DkimConfig;
78
import org.simplejavamail.api.internal.smimesupport.model.PlainSmimeDetails;
89
import org.simplejavamail.api.mailer.config.Pkcs12Config;
910
import org.simplejavamail.internal.util.MiscUtil;
1011

11-
import java.io.File;
1212
import java.io.InputStream;
1313
import java.io.Serializable;
1414
import java.security.cert.X509Certificate;
@@ -17,6 +17,7 @@
1717
import java.util.Date;
1818
import java.util.List;
1919
import java.util.Map;
20+
import java.util.Set;
2021
import java.util.TimeZone;
2122

2223
import static java.lang.Boolean.TRUE;
@@ -151,25 +152,13 @@ public class Email implements Serializable {
151152
*/
152153
// mime message is not serializable, so transient
153154
private transient final MimeMessage emailToForward;
154-
155-
/**
156-
* @see EmailPopulatingBuilder#signWithDomainKey(InputStream, String, String)
157-
* @see EmailPopulatingBuilder#signWithDomainKey(byte[], String, String)
158-
* @see EmailPopulatingBuilder#signWithDomainKey(File, String, String)
159-
*/
160-
private final byte[] dkimPrivateKeyData;
161-
162-
/**
163-
* @see EmailPopulatingBuilder#signWithDomainKey(InputStream, String, String)
164-
* @see EmailPopulatingBuilder#signWithDomainKey(File, String, String)
165-
*/
166-
private final String dkimSigningDomain;
155+
167156

168157
/**
169-
* @see EmailPopulatingBuilder#signWithDomainKey(InputStream, String, String)
170-
* @see EmailPopulatingBuilder#signWithDomainKey(File, String, String)
158+
* @see EmailPopulatingBuilder#signWithDomainKey(DkimConfig)
159+
* @see EmailPopulatingBuilder#signWithDomainKey(byte[], String, String, Set)
171160
*/
172-
private final String dkimSelector;
161+
private DkimConfig dkimConfig;
173162

174163
/**
175164
* @see EmailPopulatingBuilder#signWithSmime(Pkcs12Config)
@@ -277,16 +266,8 @@ public Email(@NotNull final EmailPopulatingBuilder builder) {
277266
} else {
278267
returnReceiptTo = builder.getReturnReceiptTo();
279268
}
280-
281-
if (builder.getDkimPrivateKeyData() != null) {
282-
this.dkimPrivateKeyData = builder.getDkimPrivateKeyData();
283-
this.dkimSigningDomain = builder.getDkimSigningDomain();
284-
this.dkimSelector = builder.getDkimSelector();
285-
} else {
286-
this.dkimPrivateKeyData = null;
287-
this.dkimSigningDomain = null;
288-
this.dkimSelector = null;
289-
}
269+
270+
this.dkimConfig = builder.getDkimConfig();
290271
}
291272

292273
/**
@@ -333,10 +314,8 @@ public String toString() {
333314
",\n\tcontentTransferEncoding='" + contentTransferEncoding + '\'' +
334315
",\n\tsubject='" + subject + '\'' +
335316
",\n\trecipients=" + recipients);
336-
if (!MiscUtil.valueNullOrEmpty(dkimSigningDomain)) {
337-
s += ",\n\tapplyDKIMSignature=" + true +
338-
",\n\t\tdkimSelector=" + dkimSelector +
339-
",\n\t\tdkimSigningDomain=" + dkimSigningDomain;
317+
if (!MiscUtil.valueNullOrEmpty(dkimConfig)) {
318+
s += ",\n\tdkimConfig=" + dkimConfig;
340319
}
341320
if (TRUE.equals(useDispositionNotificationTo)) {
342321
s += ",\n\tuseDispositionNotificationTo=" + true +
@@ -552,31 +531,14 @@ public Map<String, Collection<String>> getHeaders() {
552531
}
553532

554533
/**
555-
* @see EmailPopulatingBuilder#signWithDomainKey(InputStream, String, String)
534+
* @see EmailPopulatingBuilder#signWithDomainKey(DkimConfig)
535+
* @see EmailPopulatingBuilder#signWithDomainKey(byte[], String, String, Set)
556536
*/
557537
@Nullable
558-
public byte[] getDkimPrivateKeyData() {
559-
return dkimPrivateKeyData != null ? dkimPrivateKeyData.clone() : null;
538+
public DkimConfig getDkimConfig() {
539+
return dkimConfig;
560540
}
561541

562-
/**
563-
* @see EmailPopulatingBuilder#signWithDomainKey(InputStream, String, String)
564-
* @see EmailPopulatingBuilder#signWithDomainKey(File, String, String)
565-
*/
566-
@Nullable
567-
public String getDkimSigningDomain() {
568-
return dkimSigningDomain;
569-
}
570-
571-
/**
572-
* @see EmailPopulatingBuilder#signWithDomainKey(InputStream, String, String)
573-
* @see EmailPopulatingBuilder#signWithDomainKey(File, String, String)
574-
*/
575-
@Nullable
576-
public String getDkimSelector() {
577-
return dkimSelector;
578-
}
579-
580542
/**
581543
* @see EmailPopulatingBuilder#signWithSmime(Pkcs12Config)
582544
* @see EmailPopulatingBuilder#signWithSmime(InputStream, String, String, String)

modules/core-module/src/main/java/org/simplejavamail/api/email/EmailPopulatingBuilder.java

Lines changed: 20 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import jakarta.mail.util.ByteArrayDataSource;
88
import org.jetbrains.annotations.NotNull;
99
import org.jetbrains.annotations.Nullable;
10+
import org.simplejavamail.api.email.config.DkimConfig;
1011
import org.simplejavamail.api.internal.clisupport.model.Cli;
1112
import org.simplejavamail.api.internal.clisupport.model.CliBuilderApiType;
1213
import org.simplejavamail.api.mailer.config.Pkcs12Config;
1314

14-
import java.io.ByteArrayInputStream;
1515
import java.io.File;
1616
import java.io.InputStream;
1717
import java.net.URL;
@@ -20,11 +20,11 @@
2020
import java.util.Date;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.Set;
2324
import java.util.regex.Pattern;
2425

2526
import static java.util.regex.Pattern.compile;
2627

27-
2828
/**
2929
* Fluent interface Builder for populating {@link Email} instances. An instance of this builder can only be obtained through one of the builder
3030
* starters on {@link EmailStartingBuilder}.
@@ -37,8 +37,8 @@
3737
public interface EmailPopulatingBuilder {
3838

3939
/**
40-
* Regular Expression to find all {@code <img src="...">} entries in an HTML document.It needs to cater for various things, like more whitespaces including newlines on any place, HTML is not case
41-
* sensitive and there can be arbitrary text between "IMG" and "SRC" like IDs and other things.
40+
* Regular Expression to find all {@code <img src="...">} entries in an HTML document.It needs to cater for various things, like more whitespaces including newlines on any
41+
* place, HTML is not case-sensitive and there can be arbitrary text between "IMG" and "SRC" like IDs and other things.
4242
*/
4343
Pattern IMG_SRC_PATTERN = compile("(?<imageTagStart><[Ii][Mm][Gg]\\s*[^>]*?\\s+[Ss][Rr][Cc]\\s*=\\s*[\"'])(?<src>[^\"']+?)(?<imageSrcEnd>[\"'])");
4444

@@ -1137,55 +1137,34 @@ public interface EmailPopulatingBuilder {
11371137
* Delegates to {@link #withAttachment(String, DataSource)} for each attachment.
11381138
*/
11391139
EmailPopulatingBuilder withAttachments(@NotNull List<AttachmentResource> attachments);
1140-
1141-
/**
1142-
* Delegates to {@link #signWithDomainKey(InputStream, String, String)} with a {@link ByteArrayInputStream} wrapped around the prodived {@code
1143-
* dkimPrivateKey} data.
1144-
* <p>
1145-
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.DKIMModule#NAME}.
1146-
*/
1147-
@Cli.ExcludeApi(reason = "delegated method is an identical api from CLI point of view")
1148-
@SuppressWarnings("unused")
1149-
EmailPopulatingBuilder signWithDomainKey(@NotNull byte[] dkimPrivateKey, @NotNull String signingDomain, @NotNull String dkimSelector);
1150-
1151-
/**
1152-
* Delegates to {@link #signWithDomainKey(InputStream, String, String)} with a {@link ByteArrayInputStream} wrapped around the prodived {@code
1153-
* dkimPrivateKey} string converted to UTF_8 byte array.
1154-
* <p>
1155-
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.DKIMModule#NAME}.
1156-
*/
1157-
@Cli.ExcludeApi(reason = "delegated method is an identical api from CLI point of view")
1158-
@SuppressWarnings("unused")
1159-
EmailPopulatingBuilder signWithDomainKey(@NotNull String dkimPrivateKey, @NotNull String signingDomain, @NotNull String dkimSelector);
1160-
1140+
11611141
/**
11621142
* Primes this email for signing with a DKIM domain key. Actual signing is done when sending using a <code>Mailer</code>.
11631143
* <p>
11641144
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.DKIMModule#NAME}.
11651145
*
1166-
* @param dkimPrivateKeyInputStream De key content used to sign for the sending party.
1167-
* @param signingDomain The domain being authorized to send.
1168-
* @param dkimSelector Additional domain specifier.
1146+
* @param dkimPrivateKey De key content used to sign for the sending party.
1147+
* @param signingDomain The domain being authorized to send.
1148+
* @param dkimSelector Additional domain specifier.
1149+
* @param excludedHeadersFromDkimDefaultSigningList Allows you to exclude headers being signed, as might be the case when another mail transfer agent. For example, Amazon SES doesn't want Message-ID and Date Headers to be signed as they have internal mechanisms to handle these headers.
11691150
*
11701151
* @see <a href="https://postmarkapp.com/guides/dkim">more on DKIM 1</a>
11711152
* @see <a href="https://github.com/markenwerk/java-utils-mail-dkim">more on DKIM 2</a>
11721153
* @see <a href="http://www.gettingemaildelivered.com/dkim-explained-how-to-set-up-and-use-domainkeys-identified-mail-effectively">more on DKIM 3</a>
11731154
* @see <a href="https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail">more on DKIM 4</a>
11741155
* @see <a href="https://github.com/bbottema/dkim-verify">List of explanations all tags in a <em>DKIM-Signature</em> header</a>
1175-
* @see #signWithDomainKey(byte[], String, String)
1176-
* @see #signWithDomainKey(String, String, String)
1177-
* @see #signWithDomainKey(File, String, String)
1156+
* @see #signWithDomainKey(DkimConfig)
11781157
*/
1179-
EmailPopulatingBuilder signWithDomainKey(@NotNull InputStream dkimPrivateKeyInputStream, @NotNull String signingDomain, @NotNull String dkimSelector);
1180-
1158+
@SuppressWarnings("unused")
1159+
EmailPopulatingBuilder signWithDomainKey(@NotNull byte[] dkimPrivateKey, @NotNull String signingDomain, @NotNull String dkimSelector, @Nullable Set<String> excludedHeadersFromDkimDefaultSigningList);
1160+
11811161
/**
1182-
* As {@link #signWithDomainKey(InputStream, String, String)}, but with a File reference that is later read as {@code InputStream}.
1183-
* <p>
1184-
* <strong>Note:</strong> this only works in combination with the {@value org.simplejavamail.internal.modules.DKIMModule#NAME}.
1162+
* @see #signWithDomainKey(byte[], String, String, Set)
11851163
*/
11861164
@Cli.ExcludeApi(reason = "delegated method is an identical api from CLI point of view")
1187-
EmailPopulatingBuilder signWithDomainKey(@NotNull File dkimPrivateKeyFile, @NotNull String signingDomain, @NotNull String dkimSelector);
1188-
1165+
@SuppressWarnings("unused")
1166+
EmailPopulatingBuilder signWithDomainKey(@NotNull DkimConfig dkimConfig);
1167+
11891168
/**
11901169
* Signs this email with an <a href="https://tools.ietf.org/html/rfc5751">S/MIME</a> signature, so the receiving client
11911170
* can verify whether the email content was tampered with.
@@ -1633,26 +1612,11 @@ public interface EmailPopulatingBuilder {
16331612
Map<String, Collection<String>> getHeaders();
16341613

16351614
/**
1636-
* @see #signWithDomainKey(InputStream, String, String)
1637-
* @see #signWithDomainKey(byte[], String, String)
1638-
* @see #signWithDomainKey(File, String, String)
1639-
*/
1640-
@Nullable
1641-
byte[] getDkimPrivateKeyData();
1642-
1643-
/**
1644-
* @see #signWithDomainKey(InputStream, String, String)
1645-
* @see #signWithDomainKey(File, String, String)
1646-
*/
1647-
@Nullable
1648-
String getDkimSigningDomain();
1649-
1650-
/**
1651-
* @see #signWithDomainKey(InputStream, String, String)
1652-
* @see #signWithDomainKey(File, String, String)
1615+
* @see #signWithDomainKey(DkimConfig)
1616+
* @see #signWithDomainKey(byte[], String, String, Set)
16531617
*/
16541618
@Nullable
1655-
String getDkimSelector();
1619+
DkimConfig getDkimConfig();
16561620

16571621
/**
16581622
* @see #withDispositionNotificationTo()

0 commit comments

Comments
 (0)