diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 9643e396b6..233e8981cb 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1457,6 +1457,9 @@ PATH = ;; Mail from address, RFC 5322. This can be just an email address, or the `"Name" ` format ;FROM = ;; +;; Sometimes it is helpful to use a different address on the envelope. Set this to use ENVELOPE_FROM as the from on the envelope. Set to `<>` to send an empty address. +;ENVELOPE_FROM = +;; ;; Mailer user name and password ;; Please Note: Authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via STARTTLS) or `HOST=localhost`. ;USER = diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index a087b253e9..ae4f754170 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -606,6 +606,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type - Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`. - `FROM`: **\**: Mail from address, RFC 5322. This can be just an email address, or the "Name" \ format. +- `ENVELOPE_FROM`: **\**: Address set as the From address on the SMTP mail envelope. Set to `<>` to send an empty address. - `USER`: **\**: Username of mailing user (usually the sender's e-mail address). - `PASSWD`: **\**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password. - Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information. diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index d2fac440ac..1bcd63a914 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -16,13 +16,15 @@ import ( // Mailer represents mail service. type Mailer struct { // Mailer - Name string - From string - FromName string - FromEmail string - SendAsPlainText bool - MailerType string - SubjectPrefix string + Name string + From string + EnvelopeFrom string + OverrideEnvelopeFrom bool `ini:"-"` + FromName string + FromEmail string + SendAsPlainText bool + MailerType string + SubjectPrefix string // SMTP sender Host string @@ -73,6 +75,7 @@ func newMailService() { SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute), } MailService.From = sec.Key("FROM").MustString(MailService.User) + MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("") if sec.HasKey("ENABLE_HTML_ALTERNATIVE") { log.Warn("ENABLE_HTML_ALTERNATIVE is deprecated, use SEND_AS_PLAIN_TEXT") @@ -93,6 +96,21 @@ func newMailService() { MailService.FromName = parsed.Name MailService.FromEmail = parsed.Address + switch MailService.EnvelopeFrom { + case "": + MailService.OverrideEnvelopeFrom = false + case "<>": + MailService.EnvelopeFrom = "" + MailService.OverrideEnvelopeFrom = true + default: + parsed, err = mail.ParseAddress(MailService.EnvelopeFrom) + if err != nil { + log.Fatal("Invalid mailer.ENVELOPE_FROM (%s): %v", MailService.EnvelopeFrom, err) + } + MailService.OverrideEnvelopeFrom = true + MailService.EnvelopeFrom = parsed.Address + } + if MailService.MailerType == "" { MailService.MailerType = "smtp" } diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index fae8d473e3..0c0c626627 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -210,8 +210,14 @@ func (s *smtpSender) Send(from string, to []string, msg io.WriterTo) error { } } - if err = client.Mail(from); err != nil { - return fmt.Errorf("Mail: %v", err) + if opts.OverrideEnvelopeFrom { + if err = client.Mail(opts.EnvelopeFrom); err != nil { + return fmt.Errorf("Mail: %v", err) + } + } else { + if err = client.Mail(from); err != nil { + return fmt.Errorf("Mail: %v", err) + } } for _, rec := range to { @@ -242,7 +248,12 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error { var closeError error var waitError error - args := []string{"-f", from, "-i"} + envelopeFrom := from + if setting.MailService.OverrideEnvelopeFrom { + envelopeFrom = setting.MailService.EnvelopeFrom + } + + args := []string{"-f", envelopeFrom, "-i"} args = append(args, setting.MailService.SendmailArgs...) args = append(args, to...) log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args)