chore: sync

This commit is contained in:
2026-03-18 22:06:43 +08:00
parent e89678e61a
commit 0c4380c3c3
45 changed files with 5883 additions and 2 deletions

View 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())
}