fix smtp auth in dev build and add smtp debug logging

This commit is contained in:
Ronni Skansing
2025-09-15 19:31:18 +02:00
parent fe94d1da8e
commit b905117ab9
4 changed files with 75 additions and 9 deletions

View File

@@ -1,5 +1,8 @@
# Changelog
## [1.2.1] - 2025-xx-xx
- Add debug logging to SMTP.
## [1.2.0] - 2025-09-04
- Added support for YmdHis Date and Base64 template functions
- Improved campaign review details

54
backend/log/gomail.go Normal file
View File

@@ -0,0 +1,54 @@
package log
import (
"fmt"
"github.com/wneessen/go-mail/log"
"go.uber.org/zap"
)
// GoMailLoggerAdapter adapts zap.SugaredLogger to go-mail's Logger interface
type GoMailLoggerAdapter struct {
logger *zap.SugaredLogger
}
func (z *GoMailLoggerAdapter) formatLogMessage(l log.Log) string {
direction := "CLIENT"
if l.Direction == log.DirServerToClient {
direction = "SERVER"
}
// format the message with arguments if present
msg := l.Format
if len(l.Messages) > 0 {
// create interface slice for fmt.Sprintf
args := make([]interface{}, len(l.Messages))
for i, m := range l.Messages {
args[i] = m
}
msg = fmt.Sprintf(l.Format, args...)
}
return fmt.Sprintf("SMTP %s: %s", direction, msg)
}
func (z *GoMailLoggerAdapter) Debugf(l log.Log) {
z.logger.Debug(z.formatLogMessage(l))
}
func (z *GoMailLoggerAdapter) Infof(l log.Log) {
z.logger.Info(z.formatLogMessage(l))
}
func (z *GoMailLoggerAdapter) Warnf(l log.Log) {
z.logger.Warn(z.formatLogMessage(l))
}
func (z *GoMailLoggerAdapter) Errorf(l log.Log) {
z.logger.Error(z.formatLogMessage(l))
}
// NewGoMailLoggerAdapter creates a new go-mail logger adapter
func NewGoMailLoggerAdapter(logger *zap.SugaredLogger) *GoMailLoggerAdapter {
return &GoMailLoggerAdapter{logger: logger}
}

View File

@@ -24,6 +24,7 @@ import (
"github.com/phishingclub/phishingclub/data"
"github.com/phishingclub/phishingclub/database"
"github.com/phishingclub/phishingclub/errs"
"github.com/phishingclub/phishingclub/log"
"github.com/phishingclub/phishingclub/model"
"github.com/phishingclub/phishingclub/repository"
"github.com/phishingclub/phishingclub/validate"
@@ -2020,6 +2021,8 @@ func (c *Campaign) sendCampaignMessages(
// Try CRAM-MD5 first when credentials are provided
emailOptionsCRAM5 := append(emailOptions, mail.WithSMTPAuth(mail.SMTPAuthCramMD5))
mc, _ = mail.NewClient(smtpHost.String(), emailOptionsCRAM5...)
mc.SetLogger(log.NewGoMailLoggerAdapter(c.Logger))
mc.SetDebugLog(true)
if build.Flags.Production {
mc.SetTLSPolicy(mail.TLSMandatory)
} else {
@@ -2033,12 +2036,12 @@ func (c *Campaign) sendCampaignMessages(
strings.Contains(err.Error(), "538 ") ||
strings.Contains(err.Error(), "CRAM-MD5") ||
strings.Contains(err.Error(), "authentication failed")) {
c.Logger.Warnw("CRAM-MD5 authentication failed, trying PLAIN auth", "error", err)
c.Logger.Debugf("CRAM-MD5 authentication failed, trying PLAIN auth", "error", err)
emailOptionsBasic := emailOptions
if build.Flags.Production {
emailOptionsBasic = append(emailOptions, mail.WithSMTPAuth(mail.SMTPAuthPlain))
}
emailOptionsBasic = append(emailOptions, mail.WithSMTPAuth(mail.SMTPAuthPlain))
mc, _ = mail.NewClient(smtpHost.String(), emailOptionsBasic...)
mc.SetLogger(log.NewGoMailLoggerAdapter(c.Logger))
mc.SetDebugLog(true)
if build.Flags.Production {
mc.SetTLSPolicy(mail.TLSMandatory)
} else {
@@ -2049,6 +2052,8 @@ func (c *Campaign) sendCampaignMessages(
} else {
// No credentials provided, try without authentication (e.g., local postfix)
mc, _ = mail.NewClient(smtpHost.String(), emailOptions...)
mc.SetLogger(log.NewGoMailLoggerAdapter(c.Logger))
mc.SetDebugLog(true)
if build.Flags.Production {
mc.SetTLSPolicy(mail.TLSMandatory)
} else {

View File

@@ -12,6 +12,7 @@ import (
"github.com/phishingclub/phishingclub/build"
"github.com/phishingclub/phishingclub/data"
"github.com/phishingclub/phishingclub/errs"
"github.com/phishingclub/phishingclub/log"
"github.com/phishingclub/phishingclub/model"
"github.com/phishingclub/phishingclub/repository"
"github.com/phishingclub/phishingclub/validate"
@@ -277,13 +278,14 @@ func (s *SMTPConfiguration) SendTestEmail(
}
// send mail
var mc *mail.Client
// Try different authentication methods based on configuration
// If username is provided, use authentication; otherwise try without auth first
if un := username.String(); len(un) > 0 {
// Try CRAM-MD5 first when credentials are provided
emailOptionsCRAM5 := append(emailOptions, mail.WithSMTPAuth(mail.SMTPAuthCramMD5))
mc, _ = mail.NewClient(smtpHost.String(), emailOptionsCRAM5...)
mc.SetLogger(log.NewGoMailLoggerAdapter(s.Logger))
mc.SetDebugLog(true)
if build.Flags.Production {
mc.SetTLSPolicy(mail.TLSMandatory)
} else {
@@ -297,12 +299,12 @@ func (s *SMTPConfiguration) SendTestEmail(
strings.Contains(err.Error(), "538 ") ||
strings.Contains(err.Error(), "CRAM-MD5") ||
strings.Contains(err.Error(), "authentication failed")) {
s.Logger.Warnw("CRAM-MD5 authentication failed, trying PLAIN auth", "error", err)
s.Logger.Debugf("CRAM-MD5 authentication failed, trying PLAIN auth", "error", err)
emailOptionsBasic := emailOptions
if build.Flags.Production {
emailOptionsBasic = append(emailOptions, mail.WithSMTPAuth(mail.SMTPAuthPlain))
}
emailOptionsBasic = append(emailOptions, mail.WithSMTPAuth(mail.SMTPAuthPlain))
mc, _ = mail.NewClient(smtpHost.String(), emailOptionsBasic...)
mc.SetLogger(log.NewGoMailLoggerAdapter(s.Logger))
mc.SetDebugLog(true)
if build.Flags.Production {
mc.SetTLSPolicy(mail.TLSMandatory)
} else {
@@ -313,6 +315,8 @@ func (s *SMTPConfiguration) SendTestEmail(
} else {
// No credentials provided, try without authentication (e.g., local postfix)
mc, _ = mail.NewClient(smtpHost.String(), emailOptions...)
mc.SetLogger(log.NewGoMailLoggerAdapter(s.Logger))
mc.SetDebugLog(true)
if build.Flags.Production {
mc.SetTLSPolicy(mail.TLSMandatory)
} else {