@@ -3,6 +3,7 @@ package services
33import (
44 "errors"
55 "fmt"
6+ netmail "net/mail"
67 "net/url"
78 "strings"
89 "time"
@@ -113,15 +114,15 @@ func (s *AdminTestNotifyConfigService) Run() error {
113114 if err != nil {
114115 return fmt .Errorf ("加载通知配置失败: %w" , err )
115116 }
117+ if err := validateRuntimeChannelConfig (s .Channel , runtimeCfg ); err != nil {
118+ return err
119+ }
116120
117121 now := time .Now ().Format ("2006-01-02 15:04:05" )
118122 baseMsg := fmt .Sprintf ("您好,这是一条 GoInsight 消息通知测试。\n 时间:%s" , now )
119123
120124 switch s .Channel {
121125 case "wechat" :
122- if ! runtimeCfg .Wechat .Enable {
123- return errors .New ("请先启用企业微信通知后再测试" )
124- }
125126 wechatNotifier := notifier .NewWechatNotifier (notifier.WechatNotifierConfig {
126127 Webhook : runtimeCfg .Wechat .Webhook ,
127128 })
@@ -131,9 +132,6 @@ func (s *AdminTestNotifyConfigService) Run() error {
131132 return nil
132133
133134 case "dingtalk" :
134- if ! runtimeCfg .DingTalk .Enable {
135- return errors .New ("请先启用钉钉通知后再测试" )
136- }
137135 dingtalkNotifier := notifier .NewDingTalkNotifier (notifier.DingTalkNotifierConfig {
138136 Webhook : runtimeCfg .DingTalk .Webhook ,
139137 })
@@ -147,10 +145,6 @@ func (s *AdminTestNotifyConfigService) Run() error {
147145 return nil
148146
149147 case "mail" :
150- if ! runtimeCfg .Mail .Enable {
151- return errors .New ("请先启用邮件通知后再测试" )
152- }
153-
154148 var user userModels.InsightUsers
155149 if err := global .App .DB .Table ("insight_users" ).Where ("username = ?" , username ).Take (& user ).Error ; err != nil {
156150 return fmt .Errorf ("邮件测试发送失败: 查询用户邮箱失败(%w)" , err )
@@ -175,6 +169,60 @@ func (s *AdminTestNotifyConfigService) Run() error {
175169 }
176170}
177171
172+ func validateRuntimeChannelConfig (channel string , runtimeCfg * notifier.RuntimeNotifyConfig ) error {
173+ if runtimeCfg == nil {
174+ return errors .New ("通知配置不存在" )
175+ }
176+
177+ switch channel {
178+ case "wechat" :
179+ if ! runtimeCfg .Wechat .Enable {
180+ return errors .New ("请先启用企业微信通知后再测试" )
181+ }
182+ if ! isValidHTTPURL (runtimeCfg .Wechat .Webhook ) {
183+ return errors .New ("企业微信 Webhook 配置不正确,请先保存合法地址" )
184+ }
185+ return nil
186+
187+ case "dingtalk" :
188+ if ! runtimeCfg .DingTalk .Enable {
189+ return errors .New ("请先启用钉钉通知后再测试" )
190+ }
191+ if ! isValidHTTPURL (runtimeCfg .DingTalk .Webhook ) {
192+ return errors .New ("钉钉 Webhook 配置不正确,请先保存合法地址" )
193+ }
194+ if strings .TrimSpace (runtimeCfg .DingTalk .Keywords ) == "" {
195+ return errors .New ("钉钉关键字不能为空,请先完善后再测试" )
196+ }
197+ return nil
198+
199+ case "mail" :
200+ if ! runtimeCfg .Mail .Enable {
201+ return errors .New ("请先启用邮件通知后再测试" )
202+ }
203+ mailUsername := strings .TrimSpace (runtimeCfg .Mail .Username )
204+ if mailUsername == "" {
205+ return errors .New ("邮件发件账号不能为空,请先完善后再测试" )
206+ }
207+ if _ , err := netmail .ParseAddress (mailUsername ); err != nil {
208+ return errors .New ("邮件发件账号格式不正确,请先完善后再测试" )
209+ }
210+ if strings .TrimSpace (runtimeCfg .Mail .Host ) == "" {
211+ return errors .New ("邮件 SMTP 主机不能为空,请先完善后再测试" )
212+ }
213+ if runtimeCfg .Mail .Port < 1 || runtimeCfg .Mail .Port > 65535 {
214+ return errors .New ("邮件 SMTP 端口范围必须为 1-65535" )
215+ }
216+ if strings .TrimSpace (runtimeCfg .Mail .Password ) == "" {
217+ return errors .New ("邮件 SMTP 密码不能为空,请先完善后再测试" )
218+ }
219+ return nil
220+
221+ default :
222+ return errors .New ("不支持的测试渠道" )
223+ }
224+ }
225+
178226func normalizeNoticeURL (raw string ) string {
179227 return strings .TrimRight (strings .TrimSpace (raw ), "/" )
180228}
@@ -202,10 +250,16 @@ func validateNotifyConfigForSave(form *forms.AdminUpdateNotifyConfigForm, hasSto
202250 if form .Wechat .Enable && form .Wechat .Webhook == "" {
203251 return errors .New ("启用企业微信通知时,Webhook 不能为空" )
204252 }
253+ if form .Wechat .Enable && ! isValidHTTPURL (form .Wechat .Webhook ) {
254+ return errors .New ("启用企业微信通知时,Webhook 地址格式不正确" )
255+ }
205256
206257 if form .DingTalk .Enable && form .DingTalk .Webhook == "" {
207258 return errors .New ("启用钉钉通知时,Webhook 不能为空" )
208259 }
260+ if form .DingTalk .Enable && ! isValidHTTPURL (form .DingTalk .Webhook ) {
261+ return errors .New ("启用钉钉通知时,Webhook 地址格式不正确" )
262+ }
209263 if form .DingTalk .Enable && form .DingTalk .Keywords == "" {
210264 return errors .New ("启用钉钉通知时,关键字不能为空" )
211265 }
@@ -214,6 +268,9 @@ func validateNotifyConfigForSave(form *forms.AdminUpdateNotifyConfigForm, hasSto
214268 if form .Mail .Username == "" {
215269 return errors .New ("启用邮件通知时,用户名不能为空" )
216270 }
271+ if _ , err := netmail .ParseAddress (form .Mail .Username ); err != nil {
272+ return errors .New ("启用邮件通知时,用户名必须是合法邮箱" )
273+ }
217274 if form .Mail .Host == "" {
218275 return errors .New ("启用邮件通知时,SMTP 主机不能为空" )
219276 }
0 commit comments