feat: add Docker deployment and Microsoft OAuth support
This commit is contained in:
73
mengpost-backend/services/smtp_oauth.go
Normal file
73
mengpost-backend/services/smtp_oauth.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
|
||||
smtpp "github.com/emersion/go-smtp"
|
||||
"gopkg.in/gomail.v2"
|
||||
|
||||
"mengpost-backend/models"
|
||||
)
|
||||
|
||||
// sendMailMicrosoftOAuth 使用 XOAUTH2 + STARTTLS 连接 smtp.office365.com:587.
|
||||
func sendMailMicrosoftOAuth(acc *models.Account, to, subject, body string, html bool) error {
|
||||
if AppCfg == nil {
|
||||
return fmt.Errorf("服务未配置 OAuth")
|
||||
}
|
||||
mt, err := RefreshMicrosoftAccess(context.Background(), AppCfg, acc.OAuthRefreshToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if mt.RefreshToken != "" {
|
||||
_ = models.UpdateAccountOAuthRefresh(acc.ID, mt.RefreshToken)
|
||||
}
|
||||
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", acc.Email)
|
||||
m.SetHeader("To", to)
|
||||
m.SetHeader("Subject", subject)
|
||||
if html {
|
||||
m.SetBody("text/html", body)
|
||||
} else {
|
||||
m.SetBody("text/plain", body)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if _, err := m.WriteTo(&buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", acc.SMTPHost, acc.SMTPPort)
|
||||
tlsCfg := &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
ServerName: acc.SMTPHost,
|
||||
}
|
||||
c, err := smtpp.DialStartTLS(addr, tlsCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
if err := c.Auth(NewXOAUTH2Client(acc.Email, mt.AccessToken)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.Mail(acc.Email, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.Rcpt(to, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
w, err := c.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(buf.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Quit()
|
||||
}
|
||||
Reference in New Issue
Block a user