Smail/server/controllers/email/list.go
P家单推人 430c9c6c10
feat(email): 新增 SPF/DKIM 邮件认证追踪 (#354)
新增 EmailAuthentication 统一封装 SPF/DKIM 验证结果与 Dangerous 结论。

重构邮件列表与 SMTP 收信流程,保证认证结果在插件、数据库和列表展示之间一致,并保留伪造邮件处理优先级。

扩展解析邮件 DTO 的认证字段,覆盖历史收件恢复、发送路径隔离、HookDTO 序列化及旧版插件兼容性测试。
2026-08-13 14:24:46 +08:00

110 lines
2.7 KiB
Go

package email
import (
"encoding/json"
"github.com/Jinnrry/pmail/dto"
"github.com/Jinnrry/pmail/dto/parsemail"
"github.com/Jinnrry/pmail/dto/response"
"github.com/Jinnrry/pmail/services/list"
"github.com/Jinnrry/pmail/utils/context"
log "github.com/sirupsen/logrus"
"github.com/spf13/cast"
"io"
"math"
"net/http"
)
type emailListResponse struct {
CurrentPage int `json:"current_page"`
TotalPage int `json:"total_page"`
List []*emilItem `json:"list"`
}
type emilItem struct {
ID int `json:"id"`
Title string `json:"title"`
Desc string `json:"desc"`
Datetime string `json:"datetime"`
IsRead bool `json:"is_read"`
Sender User `json:"sender"`
To []User `json:"to"`
Dangerous bool `json:"dangerous"`
Error string `json:"error"`
}
type User struct {
Name string `json:"Name"`
EmailAddress string `json:"EmailAddress"`
}
type emailRequest struct {
Keyword string `json:"keyword"`
Tag string `json:"tag"`
CurrentPage int `json:"current_page"`
PageSize int `json:"page_size"`
}
func EmailList(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
var lst []*emilItem
reqBytes, err := io.ReadAll(req.Body)
if err != nil {
log.WithContext(ctx).Errorf("%+v", err)
}
var retData emailRequest
err = json.Unmarshal(reqBytes, &retData)
if err != nil {
log.WithContext(ctx).Errorf("%+v", err)
}
offset := 0
if retData.CurrentPage >= 1 {
offset = (retData.CurrentPage - 1) * retData.PageSize
}
if retData.PageSize == 0 {
retData.PageSize = 15
}
var tagInfo dto.SearchTag = dto.SearchTag{
Type: -1,
Status: -1,
GroupId: -1,
}
_ = json.Unmarshal([]byte(retData.Tag), &tagInfo)
emailList, total := list.GetEmailList(ctx, tagInfo, retData.Keyword, false, offset, retData.PageSize)
for _, email := range emailList {
var sender User
_ = json.Unmarshal([]byte(email.Sender), &sender)
if sender.EmailAddress == "" {
sender.EmailAddress = email.FromAddress
sender.Name = email.FromName
}
var tos []User
_ = json.Unmarshal([]byte(email.To), &tos)
authentication := parsemail.NewEmailAuthentication(email.SPFCheck == 1, email.DKIMCheck == 1)
lst = append(lst, &emilItem{
ID: email.Id,
Title: email.Subject,
Desc: email.Text.String,
Datetime: email.SendDate.Format("2006-01-02 15:04:05"),
IsRead: email.IsRead == 1,
Sender: sender,
To: tos,
Dangerous: authentication.Dangerous,
Error: email.Error.String,
})
}
ret := emailListResponse{
CurrentPage: retData.CurrentPage,
TotalPage: cast.ToInt(math.Ceil(cast.ToFloat64(total) / cast.ToFloat64(retData.PageSize))),
List: lst,
}
response.NewSuccessResponse(ret).FPrint(w)
}