feat: 实现对外邮件投递(外发队列 + MX 直投 + DKIM + 退信 + 管理后台)
- 新增 internal/outbound 模块:MX 查询、SMTP 出站客户端(EHLO/STARTTLS/ MAIL/RCPT/DATA/QUIT)、4xx 临时失败与 5xx 永久失败分类、8BITMIME 支持 - 新增 outbound_messages 队列表与 OutboundStore,后台 worker 指数退避重试 - 永久失败/超限退信到发件人收件箱,包含原因与目标收件人 - 外发邮件使用域名 DKIM 私钥签名(go-msgauth) - SMTP 提交集成:认证用户可发外部收件人,MAIL FROM 必须等于登录用户邮箱, 未认证外部投递明确拒绝(防开放中继) - Web 发信集成:外部收件人自动入队,附件以 multipart/mixed + base64 编码 加入邮件正文 - 每用户每分钟/每日发送限速(max_per_day=0 可禁用外部投递) - 管理后台新增外发队列页面:状态统计、失败原因、手动重试/取消 - 新增 [outbound] 配置段并更新 README / todo.md
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
"mail_go/config"
|
||||
"mail_go/internal/db"
|
||||
"mail_go/internal/imap_server"
|
||||
"mail_go/internal/outbound"
|
||||
"mail_go/internal/pop3_server"
|
||||
"mail_go/internal/smtp_server"
|
||||
"mail_go/internal/storage"
|
||||
@@ -170,8 +171,17 @@ func main() {
|
||||
applyDomainTLSConfig(stores, cfg)
|
||||
ensureSelfSignedTLSConfig(cfg)
|
||||
|
||||
// 6. Start SMTP server
|
||||
smtpSrv := smtp_server.NewSMTPServer(cfg.SMTP, stores, attStorage)
|
||||
// 6. Outbound delivery manager (external mail queue + worker)
|
||||
outboundMgr := outbound.NewManager(cfg.Outbound, cfg.SMTP.Domain, stores)
|
||||
if outboundMgr.Enabled() {
|
||||
outboundMgr.Start()
|
||||
fmt.Println("外发邮件投递服务已启动")
|
||||
} else {
|
||||
fmt.Println("外发邮件投递未启用(outbound.max_per_day = 0)")
|
||||
}
|
||||
|
||||
// 7. Start SMTP server
|
||||
smtpSrv := smtp_server.NewSMTPServer(cfg.SMTP, stores, attStorage, outboundMgr)
|
||||
go func() {
|
||||
if err := smtpSrv.Start(); err != nil {
|
||||
log.Printf("SMTP 服务启动失败: %v", err)
|
||||
@@ -223,8 +233,8 @@ func main() {
|
||||
}()
|
||||
}
|
||||
|
||||
// 9. Start Web server
|
||||
webServer := web.NewWebServer(cfg.Web, stores, attStorage, cfg.Storage, cfg.Auth, cfg.Ban)
|
||||
// 10. Start Web server
|
||||
webServer := web.NewWebServer(cfg.Web, stores, attStorage, cfg.Storage, cfg.Auth, cfg.Ban, outboundMgr)
|
||||
fmt.Printf("Web 服务启动在 %s\n", cfg.Web.Addr)
|
||||
go func() {
|
||||
if err := webServer.Start(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user