From 87bee98972ec044d166ccca0f239e8df3fc21282 Mon Sep 17 00:00:00 2001 From: MinosChatzidakis Date: Tue, 25 Aug 2026 13:58:49 +0300 Subject: [PATCH] Switched auth plain to auth login in smtp login to meet server's demands --- internal/mailer/mailer.go | 35 ++++++++++++++++++++++++++++++++++- internal/mailer/smtp.go | 7 +++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/internal/mailer/mailer.go b/internal/mailer/mailer.go index 6bfab2e..93f38a3 100644 --- a/internal/mailer/mailer.go +++ b/internal/mailer/mailer.go @@ -1,6 +1,10 @@ package mailer -import "context" +import ( + "context" + "fmt" + "net/smtp" +) // Attachment is a file attached to an outbound email. type Attachment struct { @@ -27,3 +31,32 @@ type Mailer interface { type Noop struct{} func (n *Noop) Send(_ context.Context, _ Message) error { return nil } + + +type loginAuth struct { + username, password string +} + +func LoginAuth(username, password string) smtp.Auth { + return &loginAuth{username, password} +} + +func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { + // This sends: AUTH LOGIN + // The server will then prompt for the username, which your Next() method will catch. + return "LOGIN", nil, nil +} + +func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) { + if more { + switch string(fromServer) { + case "Username:", "VXNlcm5hbWU6": + return []byte(a.username), nil + case "Password:", "UGFzc3dvcmQ6": + return []byte(a.password), nil + default: + return nil, fmt.Errorf("unknown challenge: %s", string(fromServer)) + } + } + return nil, nil +} \ No newline at end of file diff --git a/internal/mailer/smtp.go b/internal/mailer/smtp.go index 26a478b..c31f27f 100644 --- a/internal/mailer/smtp.go +++ b/internal/mailer/smtp.go @@ -136,11 +136,10 @@ func (s *SMTP) Send(ctx context.Context, msg Message) error { defer c.Close() if s.username != "" { - auth := smtp.PlainAuth("", s.username, s.password, s.host) + // Our specific server refuses PLAIN and requires LOGIN + auth := LoginAuth(s.username, s.password) if err := c.Auth(auth); err != nil { - // Don't wrap err — SMTP auth responses can contain server-side - // detail that may expose credential information in logs. - return fmt.Errorf("mailer: SMTP authentication failed") + return fmt.Errorf("mailer: SMTP authentication failed: %w", err) } }