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: "
" + html.EscapeString(text) + "
", 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("验证码邮件发送失败,请检查通知通道配置") }