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

Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/master by this push:
     new b0d8516822 [feature] add SSL certificate verification toggle for email 
server (#4327)
b0d8516822 is described below

commit b0d8516822853af240b72cf1c52277eb52d57ec0
Author: NekoPunch <[email protected]>
AuthorDate: Tue Aug 25 20:26:32 2026 -0700

    [feature] add SSL certificate verification toggle for email server (#4327)
---
 .../notice/impl/EmailAlertNotifyHandlerImpl.java   | 13 ++++++++
 .../impl/EmailAlertNotifyHandlerImplTest.java      | 36 ++++++++++++++++++++++
 .../common/entity/dto/MailServerConfig.java        |  2 ++
 web-app/src/app/pojo/EmailNoticeSender.ts          |  1 +
 .../message-server/message-server.component.html   |  8 +++++
 web-app/src/assets/i18n/en-US.json                 |  1 +
 web-app/src/assets/i18n/ja-JP.json                 |  1 +
 web-app/src/assets/i18n/ko-KR.json                 |  1 +
 web-app/src/assets/i18n/pt-BR.json                 |  1 +
 web-app/src/assets/i18n/zh-CN.json                 |  1 +
 web-app/src/assets/i18n/zh-TW.json                 |  1 +
 11 files changed, 66 insertions(+)

diff --git 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java
 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java
index f2d8f7eb02..a0e9fac809 100644
--- 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java
+++ 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java
@@ -98,6 +98,7 @@ public class EmailAlertNotifyHandlerImpl extends 
AbstractAlertNotifyHandlerImpl
                         Properties props = sender.getJavaMailProperties();
                         props.put("mail.smtp.ssl.enable", 
emailNoticeSenderConfig.isEmailSsl());
                         props.put("mail.smtp.starttls.enable", 
emailNoticeSenderConfig.isEmailStarttls());
+                        applySslCertVerify(props, 
emailNoticeSenderConfig.isEmailSslCertVerify());
                         fromUsername = 
emailNoticeSenderConfig.getEmailUsername();
                         useDatabase = true;
                     }
@@ -111,6 +112,7 @@ public class EmailAlertNotifyHandlerImpl extends 
AbstractAlertNotifyHandlerImpl
                     Properties props = sender.getJavaMailProperties();
                     props.put("mail.smtp.ssl.enable", sslEnable);
                     props.put("mail.smtp.starttls.enable", starttlsEnable);
+                    applySslCertVerify(props, true);
                 }
             } catch (Exception e) {
                 log.error("Type not found {}", e.getMessage());
@@ -133,6 +135,17 @@ public class EmailAlertNotifyHandlerImpl extends 
AbstractAlertNotifyHandlerImpl
         }
     }
 
+    // the sender is a singleton, so both branches must set the props to avoid 
stale state
+    private void applySslCertVerify(Properties props, boolean verify) {
+        if (verify) {
+            props.remove("mail.smtp.ssl.trust");
+            props.remove("mail.smtp.ssl.checkserveridentity");
+        } else {
+            props.put("mail.smtp.ssl.trust", "*");
+            props.put("mail.smtp.ssl.checkserveridentity", "false");
+        }
+    }
+
     @Override
     public byte type() {
         return 1;
diff --git 
a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java
 
b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java
index 901b27fae5..31fe45fdad 100644
--- 
a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java
+++ 
b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.hertzbeat.alert.notice.impl;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.lenient;
@@ -124,6 +126,40 @@ class EmailAlertNotifyHandlerImplTest {
         verify(mailSender).send(any(MimeMessage.class));
     }
 
+    @Test
+    public void testSkipSslCertVerifyTrustsAllHosts() throws Exception {
+        Properties props = stubMailConfig(false);
+        emailAlertNotifyHandler.send(receiver, template, groupAlert);
+        assertEquals("*", props.get("mail.smtp.ssl.trust"));
+        assertEquals("false", props.get("mail.smtp.ssl.checkserveridentity"));
+    }
+
+    @Test
+    public void testEnableSslCertVerifyClearsStaleTrustProps() throws 
Exception {
+        Properties props = stubMailConfig(true);
+        props.put("mail.smtp.ssl.trust", "*");
+        props.put("mail.smtp.ssl.checkserveridentity", "false");
+        emailAlertNotifyHandler.send(receiver, template, groupAlert);
+        assertNull(props.get("mail.smtp.ssl.trust"));
+        assertNull(props.get("mail.smtp.ssl.checkserveridentity"));
+    }
+
+    private Properties stubMailConfig(boolean sslCertVerify) {
+        MailServerConfig config = new MailServerConfig();
+        config.setEmailHost("smtp.example.com");
+        config.setEmailPort(465);
+        config.setEmailUsername("[email protected]");
+        config.setEmailPassword("password");
+        config.setEnable(true);
+        config.setEmailSslCertVerify(sslCertVerify);
+        when(generalConfigDao.findByType(any()))
+                
.thenReturn(GeneralConfig.builder().content(JsonUtil.toJson(config)).build());
+        Properties props = new Properties();
+        when(mailSender.getJavaMailProperties()).thenReturn(props);
+        when(mailSender.createMimeMessage()).thenReturn(mimeMessage);
+        return props;
+    }
+
     @Test
     public void testNotifyAlertFailure() {
         when(mailSender.createMimeMessage()).thenThrow(new 
RuntimeException("Test Error"));
diff --git 
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java
 
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java
index 3c99b34ab6..b51b3ea06d 100644
--- 
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java
+++ 
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java
@@ -56,5 +56,7 @@ public class MailServerConfig {
 
     private boolean emailStarttls = false;
 
+    private boolean emailSslCertVerify = true;
+
     private boolean enable = true;
 }
diff --git a/web-app/src/app/pojo/EmailNoticeSender.ts 
b/web-app/src/app/pojo/EmailNoticeSender.ts
index 9d4ffea819..1a8a1c6788 100644
--- a/web-app/src/app/pojo/EmailNoticeSender.ts
+++ b/web-app/src/app/pojo/EmailNoticeSender.ts
@@ -25,6 +25,7 @@ export class EmailNoticeSender {
   emailPassword!: string;
   emailSsl: boolean = true;
   emailStarttls: boolean = false;
+  emailSslCertVerify: boolean = true;
   enable!: boolean;
   creator!: string;
   modifier!: string;
diff --git 
a/web-app/src/app/routes/setting/settings/message-server/message-server.component.html
 
b/web-app/src/app/routes/setting/settings/message-server/message-server.component.html
index a804f51547..57290b5203 100644
--- 
a/web-app/src/app/routes/setting/settings/message-server/message-server.component.html
+++ 
b/web-app/src/app/routes/setting/settings/message-server/message-server.component.html
@@ -134,6 +134,14 @@
           <nz-switch [(ngModel)]="emailSender.emailStarttls" required 
name="emailStarttls" id="emailStarttls"></nz-switch>
         </nz-form-control>
       </nz-form-item>
+      <nz-form-item *ngIf="emailSender.emailSsl || emailSender.emailStarttls">
+        <nz-form-label nzSpan="7" nzFor="emailSslCertVerify" 
nzRequired="true">{{
+          'alert.notice.sender.mail.ssl-cert-verify' | i18n
+        }}</nz-form-label>
+        <nz-form-control nzSpan="12">
+          <nz-switch [(ngModel)]="emailSender.emailSslCertVerify" required 
name="emailSslCertVerify" id="emailSslCertVerify"></nz-switch>
+        </nz-form-control>
+      </nz-form-item>
       <nz-form-item>
         <nz-form-label nzSpan="7" nzFor="emailEnable" nzRequired="true">{{ 
'common.enable' | i18n }}</nz-form-label>
         <nz-form-control nzSpan="12">
diff --git a/web-app/src/assets/i18n/en-US.json 
b/web-app/src/assets/i18n/en-US.json
index 32ac9d0b7f..0b5c837cc5 100644
--- a/web-app/src/assets/i18n/en-US.json
+++ b/web-app/src/assets/i18n/en-US.json
@@ -147,6 +147,7 @@
   "alert.notice.sender.mail.port": "Email Port",
   "alert.notice.sender.mail.ssl": "Enable SSL",
   "alert.notice.sender.mail.starttls": "Enable STARTTLS",
+  "alert.notice.sender.mail.ssl-cert-verify": "Verify SSL Certificate",
   "alert.notice.sender.mail.username": "Email Account",
   "alert.notice.sender.sms.tencent.appId": "Tencent Sms AppId",
   "alert.notice.sender.sms.tencent.secretId": "Tencent Sms SecretId",
diff --git a/web-app/src/assets/i18n/ja-JP.json 
b/web-app/src/assets/i18n/ja-JP.json
index dcdcaeef5d..8df517eec8 100644
--- a/web-app/src/assets/i18n/ja-JP.json
+++ b/web-app/src/assets/i18n/ja-JP.json
@@ -146,6 +146,7 @@
   "alert.notice.sender.mail.port": "メールポート",
   "alert.notice.sender.mail.ssl": "SSLを有効化",
   "alert.notice.sender.mail.starttls": "STARTTLSを有効化",
+  "alert.notice.sender.mail.ssl-cert-verify": "SSL証明書を検証",
   "alert.notice.sender.mail.username": "メールアカウント",
   "alert.notice.sender.sms.tencent.appId": "Tencent Sms AppId",
   "alert.notice.sender.sms.tencent.secretId": "Tencent Sms SecretId",
diff --git a/web-app/src/assets/i18n/ko-KR.json 
b/web-app/src/assets/i18n/ko-KR.json
index 0dd23716b5..1a77de3774 100644
--- a/web-app/src/assets/i18n/ko-KR.json
+++ b/web-app/src/assets/i18n/ko-KR.json
@@ -147,6 +147,7 @@
   "alert.notice.sender.mail.port": "이메일 포트",
   "alert.notice.sender.mail.ssl": "SSL 활성화",
   "alert.notice.sender.mail.starttls": "STARTTLS 활성화",
+  "alert.notice.sender.mail.ssl-cert-verify": "SSL 인증서 검증",
   "alert.notice.sender.mail.username": "이메일 계정",
   "alert.notice.sender.sms.tencent.appId": "Tencent SMS AppId",
   "alert.notice.sender.sms.tencent.secretId": "Tencent SMS SecretId",
diff --git a/web-app/src/assets/i18n/pt-BR.json 
b/web-app/src/assets/i18n/pt-BR.json
index e8761d9a90..bf2a3e6e36 100644
--- a/web-app/src/assets/i18n/pt-BR.json
+++ b/web-app/src/assets/i18n/pt-BR.json
@@ -233,6 +233,7 @@
   "alert.notice.sender.mail.port": "Porta do Email",
   "alert.notice.sender.mail.ssl": "Habilitar SSL",
   "alert.notice.sender.mail.starttls": "Habilitar STARTTLS",
+  "alert.notice.sender.mail.ssl-cert-verify": "Verificar Certificado SSL",
   "alert.notice.sender.mail.enable": "Habilitar Configuração de Email",
   "alert.notice.sender.sms.type": "Tipo de SMS",
   "alert.notice.sender.sms.type.tencent": "SMS Tencent",
diff --git a/web-app/src/assets/i18n/zh-CN.json 
b/web-app/src/assets/i18n/zh-CN.json
index 5282863db7..9c1059dbf0 100644
--- a/web-app/src/assets/i18n/zh-CN.json
+++ b/web-app/src/assets/i18n/zh-CN.json
@@ -147,6 +147,7 @@
   "alert.notice.sender.mail.port": "邮箱端口",
   "alert.notice.sender.mail.ssl": "是否启用SSL",
   "alert.notice.sender.mail.starttls": "是否启用STARTTLS",
+  "alert.notice.sender.mail.ssl-cert-verify": "是否校验SSL证书",
   "alert.notice.sender.mail.username": "邮箱账号",
   "alert.notice.sender.sms.tencent.appId": "腾讯短信AppId",
   "alert.notice.sender.sms.tencent.secretId": "腾讯短信SecretId",
diff --git a/web-app/src/assets/i18n/zh-TW.json 
b/web-app/src/assets/i18n/zh-TW.json
index 239c8375b5..8e4b95974a 100644
--- a/web-app/src/assets/i18n/zh-TW.json
+++ b/web-app/src/assets/i18n/zh-TW.json
@@ -146,6 +146,7 @@
   "alert.notice.sender.mail.port": "郵件端口",
   "alert.notice.sender.mail.ssl": "是否啟用SSL",
   "alert.notice.sender.mail.starttls": "是否啟用STARTTLS",
+  "alert.notice.sender.mail.ssl-cert-verify": "是否校驗SSL證書",
   "alert.notice.sender.mail.username": "郵件帳號",
   "alert.notice.sender.sms.tencent.appId": "騰訊短訊AppId",
   "alert.notice.sender.sms.tencent.secretId": "騰訊短訊SecretId",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to