From b402c367d331c24b1507bdbc0596c06c933b1d55 Mon Sep 17 00:00:00 2001 From: erio Date: Tue, 14 Apr 2026 01:38:42 +0800 Subject: [PATCH] fix: add opportunistic STARTTLS to sendMailPlain for 587 port compatibility smtp.SendMail automatically upgrades to STARTTLS when the server supports it. Our replacement sendMailPlain skipped this, causing credentials to be sent in plaintext on port 587. Add STARTTLS negotiation before Auth to restore the original security behavior. --- backend/internal/service/email_service.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/internal/service/email_service.go b/backend/internal/service/email_service.go index 425887cd..9cfd3bbd 100644 --- a/backend/internal/service/email_service.go +++ b/backend/internal/service/email_service.go @@ -196,6 +196,14 @@ func (s *EmailService) sendMailPlain(addr string, auth smtp.Auth, from, to strin } defer func() { _ = client.Close() }() + // Opportunistic STARTTLS: upgrade to encrypted connection if the server supports it. + // This mirrors the behavior of smtp.SendMail which we replaced for timeout support. + if ok, _ := client.Extension("STARTTLS"); ok { + if err = client.StartTLS(&tls.Config{ServerName: host, MinVersion: tls.VersionTLS12}); err != nil { + return fmt.Errorf("starttls: %w", err) + } + } + if err = client.Auth(auth); err != nil { return fmt.Errorf("smtp auth: %w", err) }