chore: sync
This commit is contained in:
167
sproutgate-backend/internal/email/mailer.go
Normal file
167
sproutgate-backend/internal/email/mailer.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package email
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"sproutgate-backend/internal/storage"
|
||||
)
|
||||
|
||||
func SendVerificationEmail(cfg storage.EmailConfig, to string, code string, expiresIn time.Duration) error {
|
||||
if strings.TrimSpace(to) == "" {
|
||||
return fmt.Errorf("email is required")
|
||||
}
|
||||
fromName := strings.TrimSpace(cfg.FromName)
|
||||
if fromName == "" {
|
||||
fromName = "萌芽账户认证中心"
|
||||
}
|
||||
fromAddress := strings.TrimSpace(cfg.FromAddress)
|
||||
if fromAddress == "" {
|
||||
return fmt.Errorf("from address is required")
|
||||
}
|
||||
username := strings.TrimSpace(cfg.Username)
|
||||
if username == "" {
|
||||
username = fromAddress
|
||||
}
|
||||
subject := "萌芽账户认证中心 - 邮箱验证"
|
||||
encodedName := mime.QEncoding.Encode("UTF-8", fromName)
|
||||
fromHeader := fmt.Sprintf("%s <%s>", encodedName, fromAddress)
|
||||
|
||||
body := fmt.Sprintf("您的验证码是:%s\n有效期:%d 分钟\n\n如非本人操作,请忽略此邮件。",
|
||||
code, int(expiresIn.Minutes()))
|
||||
|
||||
var msg bytes.Buffer
|
||||
msg.WriteString("From: " + fromHeader + "\r\n")
|
||||
msg.WriteString("To: " + to + "\r\n")
|
||||
msg.WriteString("Subject: " + mime.QEncoding.Encode("UTF-8", subject) + "\r\n")
|
||||
msg.WriteString("MIME-Version: 1.0\r\n")
|
||||
msg.WriteString("Content-Type: text/plain; charset=\"UTF-8\"\r\n")
|
||||
msg.WriteString("Content-Transfer-Encoding: 8bit\r\n")
|
||||
msg.WriteString("\r\n")
|
||||
msg.WriteString(body)
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", cfg.SMTPHost, cfg.SMTPPort)
|
||||
auth := smtp.PlainAuth("", username, cfg.Password, cfg.SMTPHost)
|
||||
encryption := strings.ToUpper(strings.TrimSpace(cfg.Encryption))
|
||||
|
||||
if cfg.SMTPPort == 465 || encryption == "SSL" {
|
||||
tlsConfig := &tls.Config{
|
||||
ServerName: cfg.SMTPHost,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: false,
|
||||
}
|
||||
conn, err := tls.Dial("tcp", addr, tlsConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := smtp.NewClient(conn, cfg.SMTPHost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
if err := client.Auth(auth); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.Mail(fromAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.Rcpt(to); err != nil {
|
||||
return err
|
||||
}
|
||||
writer, err := client.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := writer.Write(msg.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writer.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Quit()
|
||||
}
|
||||
|
||||
return smtp.SendMail(addr, auth, fromAddress, []string{to}, msg.Bytes())
|
||||
}
|
||||
|
||||
func SendResetPasswordEmail(cfg storage.EmailConfig, to string, code string, expiresIn time.Duration) error {
|
||||
if strings.TrimSpace(to) == "" {
|
||||
return fmt.Errorf("email is required")
|
||||
}
|
||||
fromName := strings.TrimSpace(cfg.FromName)
|
||||
if fromName == "" {
|
||||
fromName = "萌芽账户认证中心"
|
||||
}
|
||||
fromAddress := strings.TrimSpace(cfg.FromAddress)
|
||||
if fromAddress == "" {
|
||||
return fmt.Errorf("from address is required")
|
||||
}
|
||||
username := strings.TrimSpace(cfg.Username)
|
||||
if username == "" {
|
||||
username = fromAddress
|
||||
}
|
||||
subject := "萌芽账户认证中心 - 重置密码"
|
||||
encodedName := mime.QEncoding.Encode("UTF-8", fromName)
|
||||
fromHeader := fmt.Sprintf("%s <%s>", encodedName, fromAddress)
|
||||
|
||||
body := fmt.Sprintf("您的重置密码验证码是:%s\n有效期:%d 分钟\n\n如非本人操作,请忽略此邮件。",
|
||||
code, int(expiresIn.Minutes()))
|
||||
|
||||
var msg bytes.Buffer
|
||||
msg.WriteString("From: " + fromHeader + "\r\n")
|
||||
msg.WriteString("To: " + to + "\r\n")
|
||||
msg.WriteString("Subject: " + mime.QEncoding.Encode("UTF-8", subject) + "\r\n")
|
||||
msg.WriteString("MIME-Version: 1.0\r\n")
|
||||
msg.WriteString("Content-Type: text/plain; charset=\"UTF-8\"\r\n")
|
||||
msg.WriteString("Content-Transfer-Encoding: 8bit\r\n")
|
||||
msg.WriteString("\r\n")
|
||||
msg.WriteString(body)
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", cfg.SMTPHost, cfg.SMTPPort)
|
||||
auth := smtp.PlainAuth("", username, cfg.Password, cfg.SMTPHost)
|
||||
encryption := strings.ToUpper(strings.TrimSpace(cfg.Encryption))
|
||||
|
||||
if cfg.SMTPPort == 465 || encryption == "SSL" {
|
||||
tlsConfig := &tls.Config{
|
||||
ServerName: cfg.SMTPHost,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: false,
|
||||
}
|
||||
conn, err := tls.Dial("tcp", addr, tlsConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := smtp.NewClient(conn, cfg.SMTPHost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
if err := client.Auth(auth); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.Mail(fromAddress); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.Rcpt(to); err != nil {
|
||||
return err
|
||||
}
|
||||
writer, err := client.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := writer.Write(msg.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writer.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Quit()
|
||||
}
|
||||
|
||||
return smtp.SendMail(addr, auth, fromAddress, []string{to}, msg.Bytes())
|
||||
}
|
||||
Reference in New Issue
Block a user