From e26e0d185c61b009312a591a8983e725bad9a130 Mon Sep 17 00:00:00 2001 From: Abin Simon Date: Sat, 23 Dec 2023 00:57:22 +0530 Subject: [PATCH] Add a toggle to skip email validation (#97) * Use email passed from downstream as-is * Add toggle to disable address parsing and validation * Add note in README about skipping email validation --- README.md | 2 ++ email.go | 71 ++++++++++++++++++++++++++++++++----------------------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index e7f00ec..4610f50 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,8 @@ Note 1: by default duplicated recipients throws an error, from `v2.13.0` you can Note 2: by default Bcc header is not set in email. From `v2.14.0` you can use `email.AddBccToHeader = true` to add this. +Note 3: by default all addresses are validated against RFC5322. Setting `email.UseProvidedAddress = true` skips this validation, but requires you to ensure a valid address is sent. + ## Download This package uses go modules. diff --git a/email.go b/email.go index 64ba7f9..5ca9f8f 100644 --- a/email.go +++ b/email.go @@ -18,25 +18,30 @@ import ( // Email represents an email message. type Email struct { - from string - sender string - replyTo string - returnPath string - recipients []string - headers textproto.MIMEHeader - parts []part - attachments []*File - inlines []*File - Charset string - Encoding encoding - Error error - SMTPServer *smtpClient - DkimMsg string - AllowDuplicateAddress bool + from string + sender string + replyTo string + returnPath string + recipients []string + headers textproto.MIMEHeader + parts []part + attachments []*File + inlines []*File + Charset string + Encoding encoding + Error error + SMTPServer *smtpClient + DkimMsg string + + // UseProvidedAddress if set to true will disable any parsing and + // validation of addresses and uses the address provided by the user + // without any modifications + UseProvidedAddress bool // AllowEmptyAttachments if enabled, allows you you attach empty // items, a file without any associated data AllowEmptyAttachments bool + AllowDuplicateAddress bool AddBccToHeader bool preserveOriginalRecipient bool dsn []DSN @@ -315,6 +320,8 @@ func (email *Email) AddBcc(addresses ...string) *Email { // AddAddresses allows you to add addresses to the specified address header. func (email *Email) AddAddresses(header string, addresses ...string) *Email { + var err error + if email.Error != nil { return email } @@ -334,16 +341,20 @@ func (email *Email) AddAddresses(header string, addresses ...string) *Email { } // check to see if the addresses are valid - for i := range addresses { - var address = new(mail.Address) - var err error + for i, address := range addresses { + fullAddress := address - // ignore parse the address if empty + // ignore empty addresses if len(addresses[i]) > 0 { - address, err = mail.ParseAddress(addresses[i]) - if err != nil { - email.Error = errors.New("Mail Error: " + err.Error() + "; Header: [" + header + "] Address: [" + addresses[i] + "]") - return email + if !email.UseProvidedAddress { + parsed, err := mail.ParseAddress(addresses[i]) + if err != nil { + email.Error = errors.New("Mail Error: " + err.Error() + "; Header: [" + header + "] Address: [" + addresses[i] + "]") + return email + } + + address = parsed.Address + fullAddress = parsed.String() } } else { continue @@ -370,16 +381,16 @@ func (email *Email) AddAddresses(header string, addresses ...string) *Email { if len(email.from) > 0 && header == "From" { email.headers.Del("From") } - email.from = address.Address + email.from = address case "Sender": - email.sender = address.Address + email.sender = address case "Reply-To": - email.replyTo = address.Address + email.replyTo = address case "Return-Path": - email.returnPath = address.Address + email.returnPath = address default: // check that the address was added to the recipients list - email.recipients, err = addAddress(email.recipients, address.Address, email.AllowDuplicateAddress) + email.recipients, err = addAddress(email.recipients, address, email.AllowDuplicateAddress) if err != nil { email.Error = errors.New("Mail Error: " + err.Error() + "; Header: [" + header + "] Address: [" + addresses[i] + "]") return email @@ -396,13 +407,13 @@ func (email *Email) AddAddresses(header string, addresses ...string) *Email { // add Bcc only if AddBccToHeader is true if header == "Bcc" && email.AddBccToHeader { - email.headers.Add(header, address.String()) + email.headers.Add(header, fullAddress) } // add all addresses to the headers except for Bcc and Return-Path if header != "Bcc" && header != "Return-Path" { // add the address to the headers - email.headers.Add(header, address.String()) + email.headers.Add(header, fullAddress) } }