feat: hub console backend — complete API surface
This commit is contained in:
70
internal/mail/mail.go
Normal file
70
internal/mail/mail.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/smtp"
|
||||
|
||||
"doormile/config"
|
||||
)
|
||||
|
||||
func SendOTPEmail(cfg *config.Config, toEmail, code string) error {
|
||||
subject := "Your Doormile verification code"
|
||||
body := fmt.Sprintf(
|
||||
"Your Doormile verification code is %s.\r\n\r\nIt expires in 5 minutes. If you didn't request this, you can ignore this email.",
|
||||
code,
|
||||
)
|
||||
|
||||
msg := []byte(fmt.Sprintf(
|
||||
"From: %s\r\nTo: %s\r\nSubject: %s\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=\"utf-8\"\r\n\r\n%s\r\n",
|
||||
cfg.SMTPFrom, toEmail, subject, body,
|
||||
))
|
||||
|
||||
auth := smtp.PlainAuth("", cfg.SMTPUser, cfg.SMTPPassword, cfg.SMTPHost)
|
||||
|
||||
// Port 465 is implicit TLS (encrypted from the first byte); everything else
|
||||
// (587, 25) goes through smtp.SendMail's opportunistic STARTTLS upgrade.
|
||||
if cfg.SMTPPort == "465" {
|
||||
return sendImplicitTLS(cfg, auth, toEmail, msg)
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%s", cfg.SMTPHost, cfg.SMTPPort)
|
||||
return smtp.SendMail(addr, auth, cfg.SMTPFrom, []string{toEmail}, msg)
|
||||
}
|
||||
|
||||
func sendImplicitTLS(cfg *config.Config, auth smtp.Auth, toEmail string, msg []byte) error {
|
||||
addr := fmt.Sprintf("%s:%s", cfg.SMTPHost, cfg.SMTPPort)
|
||||
|
||||
conn, err := tls.Dial("tcp", addr, &tls.Config{ServerName: cfg.SMTPHost})
|
||||
if err != nil {
|
||||
return fmt.Errorf("tls dial failed: %w", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
client, err := smtp.NewClient(conn, cfg.SMTPHost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("smtp client init failed: %w", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
if err := client.Auth(auth); err != nil {
|
||||
return fmt.Errorf("smtp auth failed: %w", err)
|
||||
}
|
||||
if err := client.Mail(cfg.SMTPFrom); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.Rcpt(toEmail); err != nil {
|
||||
return err
|
||||
}
|
||||
w, err := client.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Quit()
|
||||
}
|
||||
Reference in New Issue
Block a user