mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
fix(mana-notify): support insecure TLS for internal SMTP (Stalwart)
Add SMTP_INSECURE_TLS env var to skip certificate verification for internal Docker-network SMTP connections. Stalwart's self-signed cert uses 'localhost' as CN which doesn't match the 'stalwart' hostname. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d5b76bd646
commit
3714b3ae67
3 changed files with 58 additions and 19 deletions
|
|
@ -12,20 +12,22 @@ import (
|
|||
)
|
||||
|
||||
type EmailService struct {
|
||||
host string
|
||||
port int
|
||||
user string
|
||||
password string
|
||||
from string
|
||||
host string
|
||||
port int
|
||||
user string
|
||||
password string
|
||||
from string
|
||||
insecureTLS bool
|
||||
}
|
||||
|
||||
func NewEmailService(cfg *config.Config) *EmailService {
|
||||
return &EmailService{
|
||||
host: cfg.SMTPHost,
|
||||
port: cfg.SMTPPort,
|
||||
user: cfg.SMTPUser,
|
||||
password: cfg.SMTPPassword,
|
||||
from: cfg.SMTPFrom,
|
||||
host: cfg.SMTPHost,
|
||||
port: cfg.SMTPPort,
|
||||
user: cfg.SMTPUser,
|
||||
password: cfg.SMTPPassword,
|
||||
from: cfg.SMTPFrom,
|
||||
insecureTLS: cfg.SMTPInsecureTLS,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,10 +87,44 @@ func (s *EmailService) Send(msg *EmailMessage) EmailResult {
|
|||
|
||||
auth := smtp.PlainAuth("", s.user, s.password, s.host)
|
||||
|
||||
tlsConfig := &tls.Config{ServerName: s.host}
|
||||
tlsConfig := &tls.Config{ServerName: s.host, InsecureSkipVerify: s.insecureTLS}
|
||||
conn, err := tls.Dial("tcp", addr, tlsConfig)
|
||||
if err != nil {
|
||||
// Try STARTTLS fallback
|
||||
// Try STARTTLS fallback — use custom dialer to support insecure TLS
|
||||
if s.insecureTLS {
|
||||
c, dialErr := smtp.Dial(addr)
|
||||
if dialErr != nil {
|
||||
slog.Error("email send failed", "to", msg.To, "error", dialErr, "duration", time.Since(start))
|
||||
return EmailResult{Success: false, Error: dialErr.Error()}
|
||||
}
|
||||
defer c.Close()
|
||||
if err := c.StartTLS(tlsConfig); err != nil {
|
||||
// Continue without TLS for internal connections
|
||||
slog.Warn("STARTTLS failed, continuing without TLS", "error", err)
|
||||
}
|
||||
if err := c.Auth(auth); err != nil {
|
||||
return EmailResult{Success: false, Error: err.Error()}
|
||||
}
|
||||
if err := c.Mail(fromAddr); err != nil {
|
||||
return EmailResult{Success: false, Error: err.Error()}
|
||||
}
|
||||
if err := c.Rcpt(msg.To); err != nil {
|
||||
return EmailResult{Success: false, Error: err.Error()}
|
||||
}
|
||||
w, err := c.Data()
|
||||
if err != nil {
|
||||
return EmailResult{Success: false, Error: err.Error()}
|
||||
}
|
||||
if _, err := w.Write([]byte(builder.String())); err != nil {
|
||||
return EmailResult{Success: false, Error: err.Error()}
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return EmailResult{Success: false, Error: err.Error()}
|
||||
}
|
||||
c.Quit()
|
||||
slog.Info("email sent via STARTTLS (insecure)", "to", msg.To, "duration", time.Since(start))
|
||||
return EmailResult{Success: true}
|
||||
}
|
||||
err = smtp.SendMail(addr, auth, fromAddr, []string{msg.To}, []byte(builder.String()))
|
||||
if err != nil {
|
||||
slog.Error("email send failed", "to", msg.To, "error", err, "duration", time.Since(start))
|
||||
|
|
|
|||
|
|
@ -19,12 +19,13 @@ type Config struct {
|
|||
ServiceKey string
|
||||
ManaCoreAuthURL string
|
||||
|
||||
// SMTP (Brevo)
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
SMTPUser string
|
||||
SMTPPassword string
|
||||
SMTPFrom string
|
||||
// SMTP
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
SMTPUser string
|
||||
SMTPPassword string
|
||||
SMTPFrom string
|
||||
SMTPInsecureTLS bool
|
||||
|
||||
// Expo Push
|
||||
ExpoAccessToken string
|
||||
|
|
@ -58,7 +59,8 @@ func Load() *Config {
|
|||
SMTPPort: envutil.GetInt("SMTP_PORT", 587),
|
||||
SMTPUser: envutil.Get("SMTP_USER", ""),
|
||||
SMTPPassword: envutil.Get("SMTP_PASSWORD", ""),
|
||||
SMTPFrom: envutil.Get("SMTP_FROM", "ManaCore <noreply@mana.how>"),
|
||||
SMTPFrom: envutil.Get("SMTP_FROM", "ManaCore <noreply@mana.how>"),
|
||||
SMTPInsecureTLS: envutil.GetBool("SMTP_INSECURE_TLS", false),
|
||||
|
||||
ExpoAccessToken: envutil.Get("EXPO_ACCESS_TOKEN", ""),
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue