refactor(api): separate Yggdrasil routes from v1 API group
All checks were successful
Build / build (push) Successful in 2m15s
Build / build-docker (push) Successful in 1m2s

Move Yggdrasil API endpoints from /api/v1/yggdrasil to /api/yggdrasil for
better route organization and compatibility with standard Yggdrasil protocol.
Also upgrade Go to 1.25, update dependencies, and migrate email package from
jordan-wright/email to gopkg.in/mail.v2. Remove deprecated UUID design plan.
This commit is contained in:
2026-02-24 02:18:15 +08:00
parent 29f0bad2bc
commit 1da0ee1ed1
9 changed files with 337 additions and 603 deletions

View File

@@ -3,13 +3,11 @@ package email
import (
"crypto/tls"
"fmt"
"net/smtp"
"net/textproto"
"carrotskin/pkg/config"
"github.com/jordan-wright/email"
"go.uber.org/zap"
gomail "gopkg.in/mail.v2"
)
// Service 邮件服务
@@ -36,7 +34,7 @@ func (s *Service) SendVerificationCode(to, code, purpose string) error {
subject := s.getSubject(purpose)
body := s.getBody(code, purpose)
return s.send([]string{to}, subject, body)
return s.send(to, subject, body)
}
// SendResetPassword 发送重置密码邮件
@@ -55,23 +53,13 @@ func (s *Service) SendChangeEmail(to, code string) error {
}
// send 发送邮件
func (s *Service) send(to []string, subject, body string) error {
e := email.NewEmail()
e.From = fmt.Sprintf("%s <%s>", s.cfg.FromName, s.cfg.Username)
e.To = to
e.Subject = subject
e.HTML = []byte(body)
e.Headers = textproto.MIMEHeader{}
func (s *Service) send(to, subject, body string) error {
m := gomail.NewMessage()
m.SetHeader("From", fmt.Sprintf("%s <%s>", s.cfg.FromName, s.cfg.Username))
m.SetHeader("To", to)
m.SetHeader("Subject", subject)
m.SetBody("text/html", body)
// SMTP认证
auth := smtp.PlainAuth("", s.cfg.Username, s.cfg.Password, s.cfg.SMTPHost)
// 发送邮件
addr := fmt.Sprintf("%s:%d", s.cfg.SMTPHost, s.cfg.SMTPPort)
// 判断端口决定发送方式
// 465端口使用SSL/TLS隐式TLS
// 587端口使用STARTTLS显式TLS
var err error
if s.cfg.SMTPPort == 465 {
// 使用SSL/TLS连接适用于465端口
@@ -79,15 +67,28 @@ func (s *Service) send(to []string, subject, body string) error {
ServerName: s.cfg.SMTPHost,
InsecureSkipVerify: false, // 生产环境建议设置为false
}
err = e.SendWithTLS(addr, auth, tlsConfig)
d := &gomail.Dialer{
Host: s.cfg.SMTPHost,
Port: s.cfg.SMTPPort,
Username: s.cfg.Username,
Password: s.cfg.Password,
TLSConfig: tlsConfig,
}
err = d.DialAndSend(m)
} else {
// 使用STARTTLS连接适用于587端口等
err = e.Send(addr, auth)
d := &gomail.Dialer{
Host: s.cfg.SMTPHost,
Port: s.cfg.SMTPPort,
Username: s.cfg.Username,
Password: s.cfg.Password,
}
err = d.DialAndSend(m)
}
if err != nil {
s.logger.Error("发送邮件失败",
zap.Strings("to", to),
zap.String("to", to),
zap.String("subject", subject),
zap.String("smtp_host", s.cfg.SMTPHost),
zap.Int("smtp_port", s.cfg.SMTPPort),
@@ -97,7 +98,7 @@ func (s *Service) send(to []string, subject, body string) error {
}
s.logger.Info("邮件发送成功",
zap.Strings("to", to),
zap.String("to", to),
zap.String("subject", subject),
)