mirror of
https://github.com/h44z/wg-portal
synced 2025-02-26 05:49:14 +00:00
115 lines
3.1 KiB
Go
115 lines
3.1 KiB
Go
package common
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"io"
|
|
"io/ioutil"
|
|
|
|
"github.com/pkg/errors"
|
|
mail "github.com/xhit/go-simple-mail/v2"
|
|
)
|
|
|
|
type MailEncryption string
|
|
|
|
const (
|
|
MailEncryptionNone MailEncryption = "none"
|
|
MailEncryptionTLS MailEncryption = "tls"
|
|
MailEncryptionStartTLS MailEncryption = "starttls"
|
|
)
|
|
|
|
type MailAuthType string
|
|
|
|
const (
|
|
MailAuthPlain MailAuthType = "plain"
|
|
MailAuthLogin MailAuthType = "login"
|
|
MailAuthCramMD5 MailAuthType = "crammd5"
|
|
)
|
|
|
|
type MailConfig struct {
|
|
Host string `yaml:"host" envconfig:"EMAIL_HOST"`
|
|
Port int `yaml:"port" envconfig:"EMAIL_PORT"`
|
|
TLS bool `yaml:"tls" envconfig:"EMAIL_TLS"` // Deprecated, use MailConfig.Encryption instead.
|
|
Encryption MailEncryption `yaml:"encryption" envconfig:"EMAIL_ENCRYPTION"`
|
|
CertValidation bool `yaml:"certcheck" envconfig:"EMAIL_CERT_VALIDATION"`
|
|
Username string `yaml:"user" envconfig:"EMAIL_USERNAME"`
|
|
Password string `yaml:"pass" envconfig:"EMAIL_PASSWORD"`
|
|
AuthType MailAuthType `yaml:"auth" envconfig:"EMAIL_AUTHTYPE"`
|
|
}
|
|
|
|
type MailAttachment struct {
|
|
Name string
|
|
ContentType string
|
|
Data io.Reader
|
|
Embedded bool
|
|
}
|
|
|
|
// SendEmailWithAttachments sends a mail with optional attachments.
|
|
func SendEmailWithAttachments(cfg MailConfig, sender, replyTo, subject, body, htmlBody string, receivers []string, attachments []MailAttachment) error {
|
|
srv := mail.NewSMTPClient()
|
|
|
|
srv.Host = cfg.Host
|
|
srv.Port = cfg.Port
|
|
srv.Username = cfg.Username
|
|
srv.Password = cfg.Password
|
|
|
|
// TODO: remove this once the deprecated MailConfig.TLS config option has been removed
|
|
if cfg.TLS {
|
|
cfg.Encryption = MailEncryptionStartTLS
|
|
}
|
|
switch cfg.Encryption {
|
|
case MailEncryptionTLS:
|
|
srv.Encryption = mail.EncryptionTLS
|
|
case MailEncryptionStartTLS:
|
|
srv.Encryption = mail.EncryptionSTARTTLS
|
|
default: // MailEncryptionNone
|
|
srv.Encryption = mail.EncryptionNone
|
|
}
|
|
srv.TLSConfig = &tls.Config{InsecureSkipVerify: !cfg.CertValidation}
|
|
switch cfg.AuthType {
|
|
case MailAuthPlain:
|
|
srv.Authentication = mail.AuthPlain
|
|
case MailAuthLogin:
|
|
srv.Authentication = mail.AuthLogin
|
|
case MailAuthCramMD5:
|
|
srv.Authentication = mail.AuthCRAMMD5
|
|
}
|
|
|
|
client, err := srv.Connect()
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to connect via SMTP")
|
|
}
|
|
|
|
if replyTo == "" {
|
|
replyTo = sender
|
|
}
|
|
|
|
email := mail.NewMSG()
|
|
email.SetFrom(sender).
|
|
AddTo(receivers...).
|
|
SetReplyTo(replyTo).
|
|
SetSubject(subject)
|
|
|
|
email.SetBody(mail.TextHTML, htmlBody)
|
|
email.AddAlternative(mail.TextPlain, body)
|
|
|
|
for _, attachment := range attachments {
|
|
attachmentData, err := ioutil.ReadAll(attachment.Data)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to read attachment data for %s", attachment.Name)
|
|
}
|
|
|
|
if attachment.Embedded {
|
|
email.AddInlineData(attachmentData, attachment.Name, attachment.ContentType)
|
|
} else {
|
|
email.AddAttachmentData(attachmentData, attachment.Name, attachment.ContentType)
|
|
}
|
|
}
|
|
|
|
// Call Send and pass the client
|
|
err = email.Send(client)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to send email")
|
|
}
|
|
return nil
|
|
}
|