Scert/backend/internal/notification/security.go
xuans 07229adadc 收敛Smail系统通知SMTP通道并更新验收清单
完成Smail系统通知SMTP路由、验证码发送约束和相关回归测试,更新Linux生产测试记录、整改主清单及任务执行清单。
2026-10-01 05:57:07 +08:00

67 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package notification
import (
"context"
"errors"
"fmt"
"html"
"net/mail"
)
// SendSecurityCode 仅向绑定邮箱发送验证码,不使用证书通知的收件人列表。
func (s *Service) SendSecurityCode(ctx context.Context, recipient, code string) error {
if s == nil || (!s.config.HTTPEnabled && !s.config.SMTPEnabled) {
return errors.New("未配置可用的验证码邮件通道")
}
if err := ctx.Err(); err != nil {
return err
}
if len(code) != 8 {
return errors.New("验证码格式无效")
}
for _, value := range code {
if value < '0' || value > '9' {
return errors.New("验证码格式无效")
}
}
fromName, from, err := s.config.SenderIdentity()
if err != nil {
return err
}
for _, value := range []string{from, recipient} {
parsed, err := mail.ParseAddress(value)
if err != nil || parsed.Address != value {
return errors.New("验证码邮件地址无效")
}
}
text := "有人正在部署服务器上重置 Scert 超级管理员密码。\n验证码:" + code +
"\n验证码仅在当前本机重置会话中有效,有效期不超过两分钟。\n如果不是您本人操作,请勿提供此验证码,并检查服务器访问权限。"
payload := mailPayload{
From: address{Name: fromName, Email: from},
To: []address{{Email: recipient}},
Subject: "[Scert] 超级管理员密码重置验证",
Text: text, HTML: "<pre>" + html.EscapeString(text) + "</pre>",
CC: []address{}, BCC: []address{}, Attrs: []any{},
}
if s.config.UsesSmailSystemAccount() {
if !s.config.SMTPEnabled {
return errors.New("Smail 系统通知账号必须启用 SMTP 通道")
}
if err := s.sendSMTPWithRetry(ctx, payload); err != nil {
return fmt.Errorf("SMTP 验证码邮件发送失败:%w", err)
}
return nil
}
if s.config.HTTPEnabled {
if err := s.sendHTTPPayload(ctx, payload); err == nil {
return nil
}
}
if s.config.SMTPEnabled {
if err := s.sendSMTPWithRetry(ctx, payload); err == nil {
return nil
}
}
return errors.New("验证码邮件发送失败,请检查通知通道配置")
}