From 9a62af34b3ce2ee0de40d285358d19323ed94fbf Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Sat, 19 Mar 2022 21:12:38 +0100 Subject: [PATCH 1/5] Replaced the legacy go-mail/mail with wneessen/go-mail --- api/sendform.go | 83 ++++++++++++++++++++++++++---------------------- go.mod | 4 +-- go.sum | 8 ++--- server/server.go | 2 +- 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/api/sendform.go b/api/sendform.go index 3a34801..995c416 100644 --- a/api/sendform.go +++ b/api/sendform.go @@ -2,13 +2,12 @@ package api import ( "fmt" + "github.com/labstack/echo/v4" + "github.com/wneessen/go-mail" "github.com/wneessen/js-mailer/form" "github.com/wneessen/js-mailer/response" "net/http" "time" - - "github.com/go-mail/mail" - "github.com/labstack/echo/v4" ) // SentSuccessful represents confirmation JSON structure for a successfully sent message @@ -55,16 +54,24 @@ func (r *Route) SendForm(c echo.Context) error { } // Compose the mail message - mailMsg := mail.NewMessage() - mailMsg.SetHeader("From", sr.FormObj.Sender) - mailMsg.SetHeader("To", sr.FormObj.Recipients...) - mailMsg.SetHeader("Subject", sr.FormObj.Content.Subject) + var mailerr error + mailMsg := mail.NewMsg() + mailerr = mailMsg.From(sr.FormObj.Sender) + mailerr = mailMsg.To(sr.FormObj.Recipients...) + mailMsg.Subject(sr.FormObj.Content.Subject) if sr.FormObj.ReplyTo.Field != "" { sf := c.FormValue(sr.FormObj.ReplyTo.Field) if sf != "" { - mailMsg.SetHeader("Reply-To", sf) + mailerr = mailMsg.ReplyTo(sf) } } + if mailerr != nil { + c.Logger().Errorf("failed to generate mail object: %s", mailerr) + return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ + Message: "could not connect to configured mail server", + Data: mailerr.Error(), + }) + } mailBody := "The following form fields have been transmitted:\n" for _, k := range sr.FormObj.Content.Fields { @@ -72,24 +79,18 @@ func (r *Route) SendForm(c echo.Context) error { mailBody = fmt.Sprintf("%s\n* %s => %s", mailBody, k, v) } } - mailMsg.SetBody("text/plain", mailBody) + mailMsg.SetBodyString(mail.TypeTextPlain, mailBody) // Send the mail message - mailDailer := GetMailDailer(sr.FormObj) - mailSender, err := mailDailer.Dial() + mc, err := GetMailClient(sr.FormObj) if err != nil { - c.Logger().Errorf("Could not connect to configured mail server: %s", err) + c.Logger().Errorf("Could not create new mail client: %s", err) return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ - Message: "could not connect to configured mail server", + Message: "Cloud not create new mail client", Data: err.Error(), }) } - defer func() { - if err := mailSender.Close(); err != nil { - c.Logger().Errorf("Failed to close mail server connection: %s", err) - } - }() - if err := mail.Send(mailSender, mailMsg); err != nil { + if err := mc.DialAndSend(mailMsg); err != nil { c.Logger().Errorf("Could not send mail message: %s", err) return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ Message: "could not send mail message", @@ -111,36 +112,42 @@ func (r *Route) SendForm(c echo.Context) error { // SendFormConfirmation sends out a confirmation mail if requested in the form func SendFormConfirmation(f *form.Form, r string) error { - mailMsg := mail.NewMessage() - mailMsg.SetHeader("From", f.Sender) - mailMsg.SetHeader("To", r) - mailMsg.SetHeader("Subject", f.Confirmation.Subject) - mailMsg.SetBody("text/plain", f.Confirmation.Content) - mailDailer := GetMailDailer(f) - mailSender, err := mailDailer.Dial() + var mailerr error + mailMsg := mail.NewMsg() + mailerr = mailMsg.From(f.Sender) + mailerr = mailMsg.To(r) + mailMsg.Subject(f.Confirmation.Subject) + mailMsg.SetBodyString(mail.TypeTextPlain, f.Confirmation.Content) + if mailerr != nil { + return fmt.Errorf("failed to create mail message: %w", mailerr) + } + + mc, err := GetMailClient(f) if err != nil { - return fmt.Errorf("could not connect to configured mail server: %w", err) + return fmt.Errorf("failed to create mail client: %w", err) } - if err := mail.Send(mailSender, mailMsg); err != nil { + if err := mc.DialAndSend(mailMsg); err != nil { return fmt.Errorf("could not send confirmation mail message: %w", err) } - if err := mailSender.Close(); err != nil { - return fmt.Errorf("failed to close mail server connection: %w", err) - } return nil } -// GetMailDailer returns a new mail dailer object based on the form configuration -func GetMailDailer(f *form.Form) *mail.Dialer { +// GetMailClient returns a new mail dailer object based on the form configuration +func GetMailClient(f *form.Form) (*mail.Client, error) { var serverTimeout time.Duration serverTimeout, err := time.ParseDuration(f.Server.Timeout) if err != nil { serverTimeout = time.Second * 5 } - mailDailer := mail.NewDialer(f.Server.Host, f.Server.Port, f.Server.Username, f.Server.Password) - mailDailer.Timeout = serverTimeout - if f.Server.ForceTLS { - mailDailer.StartTLSPolicy = mail.MandatoryStartTLS + mc, err := mail.NewClient(f.Server.Host, mail.WithPort(f.Server.Port), + mail.WithUsername(f.Server.Username), mail.WithPassword(f.Server.Password), + mail.WithSMTPAuth(mail.SMTPAuthPlain), mail.WithTimeout(serverTimeout)) + + if err != nil { + return mc, err + } + if !f.Server.ForceTLS { + mc.SetTLSPolicy(mail.TLSOpportunistic) } - return mailDailer + return mc, nil } diff --git a/go.mod b/go.mod index 0c57642..9ae0a19 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,8 @@ go 1.16 require ( github.com/ReneKroon/ttlcache/v2 v2.11.0 github.com/cyphar/filepath-securejoin v0.2.3 - github.com/go-mail/mail v2.3.1+incompatible github.com/kkyr/fig v0.3.0 github.com/labstack/echo/v4 v4.7.2 github.com/labstack/gommon v0.3.1 - gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/mail.v2 v2.3.1 // indirect + github.com/wneessen/go-mail v0.1.5 ) diff --git a/go.sum b/go.sum index 67b9775..6c929ad 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,6 @@ github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-mail/mail v2.3.1+incompatible h1:UzNOn0k5lpfVtO31cK3hn6I4VEVGhe3lX8AJBAxXExM= -github.com/go-mail/mail v2.3.1+incompatible/go.mod h1:VPWjmmNyRsWXQZHVHT3g0YbIINUkSmuKOiLIDkWbL6M= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/kkyr/fig v0.3.0 h1:5bd1amYKp/gsK2bGEUJYzcCrQPKOZp6HZD9K21v9Guo= @@ -38,6 +36,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/wneessen/go-mail v0.1.5 h1:AcJ8labVF/39kuSG8x6CltLhCivgrFCyVFPtodD58FE= +github.com/wneessen/go-mail v0.1.5/go.mod h1:HPX01Zc96mccqd9FY0RlZ/SpyAhVu+TrFfKjiBm0ffQ= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= @@ -90,13 +90,9 @@ golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4f golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= -gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= -gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/server/server.go b/server/server.go index c8896a6..e81c1a6 100644 --- a/server/server.go +++ b/server/server.go @@ -17,7 +17,7 @@ import ( ) // VERSION is the global version string contstant -const VERSION = "0.2.3b" +const VERSION = "0.2.4" // Srv represents the server object type Srv struct { From 2d5b8a252057755bfc6e61e4a459e84254b10d4d Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Sat, 19 Mar 2022 21:19:53 +0100 Subject: [PATCH 2/5] Make GoLinter happy --- api/sendform.go | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/api/sendform.go b/api/sendform.go index 995c416..c200900 100644 --- a/api/sendform.go +++ b/api/sendform.go @@ -54,24 +54,34 @@ func (r *Route) SendForm(c echo.Context) error { } // Compose the mail message - var mailerr error mailMsg := mail.NewMsg() - mailerr = mailMsg.From(sr.FormObj.Sender) - mailerr = mailMsg.To(sr.FormObj.Recipients...) + if err := mailMsg.From(sr.FormObj.Sender); err != nil { + c.Logger().Errorf("failed to set FROM header: %s", err) + return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ + Message: "could not set MAIL FROM header", + Data: err.Error(), + }) + } + if err := mailMsg.To(sr.FormObj.Recipients...); err != nil { + c.Logger().Errorf("failed to set TO header: %s", err) + return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ + Message: "could not set RCPT TO header", + Data: err.Error(), + }) + } mailMsg.Subject(sr.FormObj.Content.Subject) if sr.FormObj.ReplyTo.Field != "" { sf := c.FormValue(sr.FormObj.ReplyTo.Field) if sf != "" { - mailerr = mailMsg.ReplyTo(sf) + if err := mailMsg.ReplyTo(sf); err != nil { + c.Logger().Errorf("failed to set REPLY-TO header: %s", err) + return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ + Message: "could not set REPLY-TO header", + Data: err.Error(), + }) + } } } - if mailerr != nil { - c.Logger().Errorf("failed to generate mail object: %s", mailerr) - return echo.NewHTTPError(http.StatusInternalServerError, &response.ErrorObj{ - Message: "could not connect to configured mail server", - Data: mailerr.Error(), - }) - } mailBody := "The following form fields have been transmitted:\n" for _, k := range sr.FormObj.Content.Fields { @@ -112,16 +122,15 @@ func (r *Route) SendForm(c echo.Context) error { // SendFormConfirmation sends out a confirmation mail if requested in the form func SendFormConfirmation(f *form.Form, r string) error { - var mailerr error mailMsg := mail.NewMsg() - mailerr = mailMsg.From(f.Sender) - mailerr = mailMsg.To(r) + if err := mailMsg.From(f.Sender); err != nil { + return fmt.Errorf("failed to set FROM header: %w", err) + } + if err := mailMsg.To(r); err != nil { + return fmt.Errorf("failed to set TO header: %w", err) + } mailMsg.Subject(f.Confirmation.Subject) mailMsg.SetBodyString(mail.TypeTextPlain, f.Confirmation.Content) - if mailerr != nil { - return fmt.Errorf("failed to create mail message: %w", mailerr) - } - mc, err := GetMailClient(f) if err != nil { return fmt.Errorf("failed to create mail client: %w", err) From c6880c2339c58d5c9330aba328762a6c7215a7bc Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Sun, 20 Mar 2022 17:45:54 +0100 Subject: [PATCH 3/5] Update go-mail to v0.1.6 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9ae0a19..a318c96 100644 --- a/go.mod +++ b/go.mod @@ -8,5 +8,5 @@ require ( github.com/kkyr/fig v0.3.0 github.com/labstack/echo/v4 v4.7.2 github.com/labstack/gommon v0.3.1 - github.com/wneessen/go-mail v0.1.5 + github.com/wneessen/go-mail v0.1.6 ) diff --git a/go.sum b/go.sum index 6c929ad..43c9e6b 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/wneessen/go-mail v0.1.5 h1:AcJ8labVF/39kuSG8x6CltLhCivgrFCyVFPtodD58FE= -github.com/wneessen/go-mail v0.1.5/go.mod h1:HPX01Zc96mccqd9FY0RlZ/SpyAhVu+TrFfKjiBm0ffQ= +github.com/wneessen/go-mail v0.1.6 h1:KrcCvF0FkRGY5+EfPDL0cwQDL+DJ2InSOyQ2wcDKgM8= +github.com/wneessen/go-mail v0.1.6/go.mod h1:HPX01Zc96mccqd9FY0RlZ/SpyAhVu+TrFfKjiBm0ffQ= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= From f7032b78f4dc7c94964cebfe9009e71c94f9178d Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Sun, 20 Mar 2022 18:23:56 +0100 Subject: [PATCH 4/5] Update go-mail to v0.1.7 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a318c96..ff15938 100644 --- a/go.mod +++ b/go.mod @@ -8,5 +8,5 @@ require ( github.com/kkyr/fig v0.3.0 github.com/labstack/echo/v4 v4.7.2 github.com/labstack/gommon v0.3.1 - github.com/wneessen/go-mail v0.1.6 + github.com/wneessen/go-mail v0.1.7 ) diff --git a/go.sum b/go.sum index 43c9e6b..ab4769a 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/wneessen/go-mail v0.1.6 h1:KrcCvF0FkRGY5+EfPDL0cwQDL+DJ2InSOyQ2wcDKgM8= -github.com/wneessen/go-mail v0.1.6/go.mod h1:HPX01Zc96mccqd9FY0RlZ/SpyAhVu+TrFfKjiBm0ffQ= +github.com/wneessen/go-mail v0.1.7 h1:kVPLT7MZozLzuIdzYeFhdY2JQedzKcSVYUxDEGJAJnU= +github.com/wneessen/go-mail v0.1.7/go.mod h1:HPX01Zc96mccqd9FY0RlZ/SpyAhVu+TrFfKjiBm0ffQ= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= From 787f6ca0231ad1694291dabf6377a25b68f0c1f1 Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Mon, 21 Mar 2022 15:02:22 +0100 Subject: [PATCH 5/5] Up go-mail to v0.1.8 and fix Dockerfile to not use alpine --- Dockerfile | 2 +- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2051556..62cb80f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ## Build first -FROM golang:alpine as builder +FROM golang:latest as builder RUN mkdir /builddir ADD . /builddir/ WORKDIR /builddir diff --git a/go.mod b/go.mod index ff15938..5ae2dfa 100644 --- a/go.mod +++ b/go.mod @@ -8,5 +8,5 @@ require ( github.com/kkyr/fig v0.3.0 github.com/labstack/echo/v4 v4.7.2 github.com/labstack/gommon v0.3.1 - github.com/wneessen/go-mail v0.1.7 + github.com/wneessen/go-mail v0.1.8 ) diff --git a/go.sum b/go.sum index ab4769a..ff837bd 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/wneessen/go-mail v0.1.7 h1:kVPLT7MZozLzuIdzYeFhdY2JQedzKcSVYUxDEGJAJnU= -github.com/wneessen/go-mail v0.1.7/go.mod h1:HPX01Zc96mccqd9FY0RlZ/SpyAhVu+TrFfKjiBm0ffQ= +github.com/wneessen/go-mail v0.1.8 h1:HKUs2ND8MozQ73nPwdeol0kJ7yweg6Q3UqMBAUrBzeU= +github.com/wneessen/go-mail v0.1.8/go.mod h1:HPX01Zc96mccqd9FY0RlZ/SpyAhVu+TrFfKjiBm0ffQ= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=