Newer
Older
wg-portal / internal / common / email.go
@Christoph Haas Christoph Haas on 10 Nov 2020 1 KB wip: mail...
package common

import (
	"crypto/tls"
	"io"
	"net/smtp"
	"strconv"
	"strings"

	"github.com/jordan-wright/email"
)

type MailConfig struct {
	Host           string `yaml:"host" envconfig:"EMAIL_HOST"`
	Port           int    `yaml:"port" envconfig:"EMAIL_PORT"`
	TLS            bool   `yaml:"tls" envconfig:"EMAIL_TLS"`
	CertValidation bool   `yaml:"certcheck" envconfig:"EMAIL_CERT_VALIDATION"`
	Username       string `yaml:"user" envconfig:"EMAIL_USERNAME"`
	Password       string `yaml:"pass" envconfig:"EMAIL_PASSWORD"`
}

type MailAttachment struct {
	Name        string
	ContentType string
	Data        io.Reader
	Embedded    bool
}

// SendEmailWithAttachments sends a mail with attachments.
func SendEmailWithAttachments(cfg MailConfig, sender, replyTo, subject, body string, htmlBody string, receivers []string, attachments []MailAttachment) error {
	e := email.NewEmail()

	hostname := cfg.Host + ":" + strconv.Itoa(cfg.Port)
	subject = strings.Trim(subject, "\n\r\t")
	sender = strings.Trim(sender, "\n\r\t")
	replyTo = strings.Trim(replyTo, "\n\r\t")
	if replyTo == "" {
		replyTo = sender
	}

	var auth smtp.Auth
	if cfg.Username == "" {
		auth = nil
	} else {
		// Set up authentication information.
		auth = smtp.PlainAuth(
			"",
			cfg.Username,
			cfg.Password,
			cfg.Host,
		)
	}

	// Set email data.
	e.From = sender
	e.To = receivers
	e.ReplyTo = []string{replyTo}
	e.Subject = subject
	e.Text = []byte(body)
	if htmlBody != "" {
		e.HTML = []byte(htmlBody)
	}

	for _, attachment := range attachments {
		a, err := e.Attach(attachment.Data, attachment.Name, attachment.ContentType)
		if err != nil {
			return err
		}
		if attachment.Embedded {
			a.HTMLRelated = true
		}
	}

	if cfg.CertValidation {
		return e.Send(hostname, auth)
	} else {
		return e.SendWithStartTLS(hostname, auth, &tls.Config{InsecureSkipVerify: true})
	}
}