mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 19:33:11 +02:00
Add configurable SMTP TLS/SSL options (#5204)
## Summary - add optional STARTTLS and SSL-related fields to mail settings with defaults matching prior behavior - apply the new mail properties in the SMTP JavaMail configuration, including trust and hostname verification overrides - update mail settings template and tests to cover default behavior and explicit TLS/SSL overrides - clarify STARTTLS naming and sslTrust usage with examples in property comments and the settings template - default sslTrust to a wildcard when unset so TLS connections accept any host by default unless tightened ## Testing - ./gradlew :proprietary:test --tests stirling.software.proprietary.security.service.MailConfigTest --console plain ------ [Codex Task](https://chatgpt.com/codex/tasks/task_b_693864b2a6648328ae75c7e88a726a65)
This commit is contained in:
@@ -574,6 +574,16 @@ public class ApplicationProperties {
|
|||||||
private String username;
|
private String username;
|
||||||
@ToString.Exclude private String password;
|
@ToString.Exclude private String password;
|
||||||
private String from;
|
private String from;
|
||||||
|
// STARTTLS upgrades a plain SMTP connection to TLS after connecting (RFC 3207)
|
||||||
|
private Boolean startTlsEnable = true;
|
||||||
|
private Boolean startTlsRequired;
|
||||||
|
// SSL/TLS wrapper for implicit TLS (typically port 465)
|
||||||
|
private Boolean sslEnable;
|
||||||
|
// Hostnames or patterns (e.g., "smtp.example.com" or "*") to trust for TLS certificates;
|
||||||
|
// defaults to "*" (trust all) when not set
|
||||||
|
private String sslTrust;
|
||||||
|
// Enables hostname verification for TLS connections
|
||||||
|
private Boolean sslCheckServerIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ mail:
|
|||||||
username: '' # SMTP server username
|
username: '' # SMTP server username
|
||||||
password: '' # SMTP server password
|
password: '' # SMTP server password
|
||||||
from: '' # sender email address
|
from: '' # sender email address
|
||||||
|
startTlsEnable: true # enable STARTTLS (explicit TLS upgrade after connecting) when supported by the SMTP server
|
||||||
|
startTlsRequired: false # require STARTTLS; connection fails if the upgrade command is not supported
|
||||||
|
sslEnable: false # enable SSL/TLS wrapper for implicit TLS (typically used with port 465)
|
||||||
|
sslTrust: '' # optional trusted host override, e.g. "smtp.example.com" or "*"; defaults to "*" (trust all) when empty
|
||||||
|
sslCheckServerIdentity: false # enable hostname verification when using SSL/TLS
|
||||||
|
|
||||||
legal:
|
legal:
|
||||||
termsAndConditions: https://www.stirling.com/legal/terms-of-service # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
termsAndConditions: https://www.stirling.com/legal/terms-of-service # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||||
|
|||||||
+27
-2
@@ -33,7 +33,8 @@ public class MailConfig {
|
|||||||
|
|
||||||
// Creates a new instance of JavaMailSenderImpl, which is a Spring implementation
|
// Creates a new instance of JavaMailSenderImpl, which is a Spring implementation
|
||||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||||
mailSender.setHost(mailProperties.getHost());
|
String host = mailProperties.getHost();
|
||||||
|
mailSender.setHost(host);
|
||||||
mailSender.setPort(mailProperties.getPort());
|
mailSender.setPort(mailProperties.getPort());
|
||||||
mailSender.setDefaultEncoding("UTF-8");
|
mailSender.setDefaultEncoding("UTF-8");
|
||||||
|
|
||||||
@@ -70,8 +71,32 @@ public class MailConfig {
|
|||||||
log.info("SMTP authentication disabled - no credentials provided");
|
log.info("SMTP authentication disabled - no credentials provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean startTlsEnabled =
|
||||||
|
mailProperties.getStartTlsEnable() == null || mailProperties.getStartTlsEnable();
|
||||||
// Enables STARTTLS to encrypt the connection if supported by the SMTP server
|
// Enables STARTTLS to encrypt the connection if supported by the SMTP server
|
||||||
props.put("mail.smtp.starttls.enable", "true");
|
props.put("mail.smtp.starttls.enable", Boolean.toString(startTlsEnabled));
|
||||||
|
if (mailProperties.getStartTlsRequired() != null) {
|
||||||
|
props.put(
|
||||||
|
"mail.smtp.starttls.required", mailProperties.getStartTlsRequired().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mailProperties.getSslEnable() != null) {
|
||||||
|
props.put("mail.smtp.ssl.enable", mailProperties.getSslEnable().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trust the configured host to allow STARTTLS with self-signed certificates
|
||||||
|
String sslTrust = mailProperties.getSslTrust();
|
||||||
|
if (sslTrust == null || sslTrust.trim().isEmpty()) {
|
||||||
|
sslTrust = "*";
|
||||||
|
}
|
||||||
|
if (sslTrust != null && !sslTrust.trim().isEmpty()) {
|
||||||
|
props.put("mail.smtp.ssl.trust", sslTrust);
|
||||||
|
}
|
||||||
|
if (mailProperties.getSslCheckServerIdentity() != null) {
|
||||||
|
props.put(
|
||||||
|
"mail.smtp.ssl.checkserveridentity",
|
||||||
|
mailProperties.getSslCheckServerIdentity().toString());
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the configured mail sender, ready to send emails
|
// Returns the configured mail sender, ready to send emails
|
||||||
return mailSender;
|
return mailSender;
|
||||||
|
|||||||
+32
-1
@@ -27,6 +27,11 @@ class MailConfigTest {
|
|||||||
when(mailProps.getPort()).thenReturn(587);
|
when(mailProps.getPort()).thenReturn(587);
|
||||||
when(mailProps.getUsername()).thenReturn("[email protected]");
|
when(mailProps.getUsername()).thenReturn("[email protected]");
|
||||||
when(mailProps.getPassword()).thenReturn("password");
|
when(mailProps.getPassword()).thenReturn("password");
|
||||||
|
when(mailProps.getStartTlsEnable()).thenReturn(null);
|
||||||
|
when(mailProps.getStartTlsRequired()).thenReturn(null);
|
||||||
|
when(mailProps.getSslEnable()).thenReturn(null);
|
||||||
|
when(mailProps.getSslTrust()).thenReturn(null);
|
||||||
|
when(mailProps.getSslCheckServerIdentity()).thenReturn(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -50,6 +55,32 @@ class MailConfigTest {
|
|||||||
() -> assertEquals("password", impl.getPassword()),
|
() -> assertEquals("password", impl.getPassword()),
|
||||||
() -> assertEquals("UTF-8", impl.getDefaultEncoding()),
|
() -> assertEquals("UTF-8", impl.getDefaultEncoding()),
|
||||||
() -> assertEquals("true", props.getProperty("mail.smtp.auth")),
|
() -> assertEquals("true", props.getProperty("mail.smtp.auth")),
|
||||||
() -> assertEquals("true", props.getProperty("mail.smtp.starttls.enable")));
|
() -> assertEquals("true", props.getProperty("mail.smtp.starttls.enable")),
|
||||||
|
() -> assertEquals(null, props.getProperty("mail.smtp.starttls.required")),
|
||||||
|
() -> assertEquals(null, props.getProperty("mail.smtp.ssl.enable")),
|
||||||
|
() -> assertEquals("*", props.getProperty("mail.smtp.ssl.trust")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRespectExplicitTlsOverrides() {
|
||||||
|
ApplicationProperties appProps = mock(ApplicationProperties.class);
|
||||||
|
when(mailProps.getStartTlsEnable()).thenReturn(false);
|
||||||
|
when(mailProps.getStartTlsRequired()).thenReturn(true);
|
||||||
|
when(mailProps.getSslEnable()).thenReturn(true);
|
||||||
|
when(mailProps.getSslTrust()).thenReturn("*");
|
||||||
|
when(mailProps.getSslCheckServerIdentity()).thenReturn(true);
|
||||||
|
when(appProps.getMail()).thenReturn(mailProps);
|
||||||
|
|
||||||
|
MailConfig config = new MailConfig(appProps);
|
||||||
|
JavaMailSenderImpl impl = (JavaMailSenderImpl) config.javaMailSender();
|
||||||
|
|
||||||
|
Properties props = impl.getJavaMailProperties();
|
||||||
|
|
||||||
|
assertAll(
|
||||||
|
() -> assertEquals("false", props.getProperty("mail.smtp.starttls.enable")),
|
||||||
|
() -> assertEquals("true", props.getProperty("mail.smtp.starttls.required")),
|
||||||
|
() -> assertEquals("true", props.getProperty("mail.smtp.ssl.enable")),
|
||||||
|
() -> assertEquals("*", props.getProperty("mail.smtp.ssl.trust")),
|
||||||
|
() -> assertEquals("true", props.getProperty("mail.smtp.ssl.checkserveridentity")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user