From 7a3d056e7703a3f9afc95ebd0d8639b97e9d81e4 Mon Sep 17 00:00:00 2001 From: jinnrry Date: Sat, 27 Apr 2024 12:51:59 +0800 Subject: [PATCH] v2.4.6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、优化初始化设置时的操作说明 2、发件人和发件时间修复 3、发件空指针异常修复 --- fe/src/i18n/i18n.js | 2 + fe/src/views/SetupView.vue | 16 +++++-- server/config/config.go | 9 ++++ server/controllers/email/send.go | 69 ++++++++++++++++++------------ server/controllers/setup.go | 11 ++++- server/http_server/setup_server.go | 11 ++++- server/res_init/init.go | 1 - server/services/setup/dns.go | 27 ++---------- server/utils/ip/ip.go | 32 ++++++++++++++ server/utils/send/send.go | 7 ++- 10 files changed, 125 insertions(+), 60 deletions(-) create mode 100644 server/utils/ip/ip.go diff --git a/fe/src/i18n/i18n.js b/fe/src/i18n/i18n.js index 3890587..4b26e7c 100644 --- a/fe/src/i18n/i18n.js +++ b/fe/src/i18n/i18n.js @@ -86,6 +86,7 @@ var lang = { "move":"Move to group", "del_rule_confirm":"Are you sure to delete this?", "rule_params":"Executed params", + "autoSSLWarn":"PMail is not currently running on port 80. If you want PMail to manage SSL certificates automatically, please forward the /.well-known/* route to PMail. See https://github.com/Jinnrry/PMail/issues/94 for details." }; @@ -178,6 +179,7 @@ var zhCN = { "move":"移动分组", "del_rule_confirm":"确定要删除吗?", "rule_params":"执行参数", + "autoSSLWarn":"PMail当前未使用80端口启动,如果想要PMail自动管理SSL证书,请将/.well-known/*路由转发到PMail。 详见https://github.com/Jinnrry/PMail/issues/94" } switch (navigator.language) { diff --git a/fe/src/views/SetupView.vue b/fe/src/views/SetupView.vue index fa9f6dc..3b4df5a 100644 --- a/fe/src/views/SetupView.vue +++ b/fe/src/views/SetupView.vue @@ -95,8 +95,8 @@ -
+

{{ lang.setDNS }}

{{ lang.dns_desc }}
@@ -121,6 +121,10 @@
+ +

{{ lang.setSSL }}

@@ -142,9 +146,11 @@ - + +
+
{{ @@ -192,6 +198,8 @@ const fullscreenLoading = ref(false) const dnsInfos = ref([ ]) +const port = ref(80) + const setPassword = () => { if (adminSettings.hadSeted) { active.value++; @@ -279,7 +287,8 @@ const getSSLConfig = () => { if (res.errorNo != 0) { ElMessage.error(res.errorMsg) } else { - sslSettings.type = res.data + sslSettings.type = res.data.type + port.value = res.data.port } }) } @@ -368,6 +377,5 @@ const next = () => { flex-direction: column; } - #next {} \ No newline at end of file diff --git a/server/config/config.go b/server/config/config.go index 68bb94f..fca85a7 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -33,6 +33,15 @@ type Config struct { WebPushToken string `json:"webPushToken"` Tables map[string]string `json:"-"` TablesInitData map[string]string `json:"-"` + setupPort int // 初始化阶段端口 +} + +func (c *Config) GetSetupPort() int { + return c.setupPort +} + +func (c *Config) SetSetupPort(setupPort int) { + c.setupPort = setupPort } const DBTypeMySQL = "mysql" diff --git a/server/controllers/email/send.go b/server/controllers/email/send.go index 417e7fa..b141133 100644 --- a/server/controllers/email/send.go +++ b/server/controllers/email/send.go @@ -1,9 +1,11 @@ package email import ( + "database/sql" "encoding/base64" "encoding/json" log "github.com/sirupsen/logrus" + "github.com/spf13/cast" "io" "net/http" "pmail/config" @@ -13,6 +15,7 @@ import ( "pmail/hooks" "pmail/hooks/framework" "pmail/i18n" + "pmail/models" "pmail/utils/async" "pmail/utils/context" "pmail/utils/send" @@ -107,6 +110,18 @@ func Send(ctx *context.Context, w http.ResponseWriter, req *http.Request) { Name: reqData.From.Name, EmailAddress: reqData.From.Email, } + if reqData.Sender.Email != "" { + e.Sender = &parsemail.User{ + Name: reqData.Sender.Name, + EmailAddress: reqData.Sender.Email, + } + } else { + e.Sender = &parsemail.User{ + Name: reqData.From.Name, + EmailAddress: reqData.From.Email, + } + } + e.Text = []byte(reqData.Text) e.HTML = []byte(reqData.HTML) e.Subject = reqData.Subject @@ -138,36 +153,36 @@ func Send(ctx *context.Context, w http.ResponseWriter, req *http.Request) { } log.WithContext(ctx).Debugf("插件执行--SendBefore End") - // 邮件落库 - sql := "INSERT INTO email (type,subject, reply_to, from_name, from_address, `to`, bcc, cc, text, html, sender, attachments,spf_check, dkim_check, create_time,send_user_id,error) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" - sqlRes, sqlerr := db.Instance.Exec(db.WithContext(ctx, sql), - 1, - e.Subject, - json2string(e.ReplyTo), - e.From.Name, - e.From.EmailAddress, - json2string(e.To), - json2string(e.Bcc), - json2string(e.Cc), - e.Text, - e.HTML, - json2string(e.Sender), - json2string(e.Attachments), - 1, - 1, - time.Now(), - ctx.UserID, - "", - ) - emailId, _ := sqlRes.LastInsertId() - - if sqlerr != nil || emailId <= 0 { + modelEmail := models.Email{ + Type: 1, + Subject: e.Subject, + ReplyTo: json2string(e.ReplyTo), + FromName: e.From.Name, + FromAddress: e.From.EmailAddress, + To: json2string(e.To), + Bcc: json2string(e.Bcc), + Cc: json2string(e.Cc), + Text: sql.NullString{String: string(e.Text), Valid: true}, + Html: sql.NullString{String: string(e.HTML), Valid: true}, + Sender: json2string(e.Sender), + Attachments: json2string(e.Attachments), + SPFCheck: 1, + DKIMCheck: 1, + SendUserID: ctx.UserID, + SendDate: time.Now(), + Status: 1, + CreateTime: time.Now(), + } + + _, err = db.Instance.Insert(&modelEmail) + + if err != nil || modelEmail.Id <= 0 { log.Println("mysql insert error:", err.Error()) response.NewErrorResponse(response.ServerError, i18n.GetText(ctx.Lang, "send_fail"), err.Error()).FPrint(w) return } - e.MessageId = emailId + e.MessageId = cast.ToInt64(modelEmail.Id) async.New(ctx).Process(func(p any) { errMsg := "" @@ -189,12 +204,12 @@ func Send(ctx *context.Context, w http.ResponseWriter, req *http.Request) { if err != nil { errMsg = err.Error() - _, err := db.Instance.Exec(db.WithContext(ctx, "update email set status =2 ,error=? where id = ? "), errMsg, emailId) + _, err := db.Instance.Exec(db.WithContext(ctx, "update email set status =2 ,error=? where id = ? "), errMsg, modelEmail.Id) if err != nil { log.WithContext(ctx).Errorf("sql Error :%+v", err) } } else { - _, err := db.Instance.Exec(db.WithContext(ctx, "update email set status =1 where id = ? "), emailId) + _, err := db.Instance.Exec(db.WithContext(ctx, "update email set status =1 where id = ? "), modelEmail.Id) if err != nil { log.WithContext(ctx).Errorf("sql Error :%+v", err) } diff --git a/server/controllers/setup.go b/server/controllers/setup.go index c955a0d..5d530da 100644 --- a/server/controllers/setup.go +++ b/server/controllers/setup.go @@ -26,6 +26,11 @@ func AcmeChallenge(w http.ResponseWriter, r *http.Request) { } } +type sslResponse struct { + Port int `json:"port"` + Type string `json:"type"` +} + func Setup(ctx *context.Context, w http.ResponseWriter, req *http.Request) { reqBytes, err := io.ReadAll(req.Body) if err != nil { @@ -121,7 +126,11 @@ func Setup(ctx *context.Context, w http.ResponseWriter, req *http.Request) { if reqData["step"] == "ssl" && reqData["action"] == "get" { sslType := ssl.GetSSL() - response.NewSuccessResponse(sslType).FPrint(w) + res := sslResponse{ + Type: sslType, + Port: config.Instance.GetSetupPort(), + } + response.NewSuccessResponse(res).FPrint(w) return } diff --git a/server/http_server/setup_server.go b/server/http_server/setup_server.go index 8ad74a4..8dc47f7 100644 --- a/server/http_server/setup_server.go +++ b/server/http_server/setup_server.go @@ -6,12 +6,12 @@ import ( log "github.com/sirupsen/logrus" "io/fs" "net/http" + "pmail/config" "pmail/controllers" + "pmail/utils/ip" "time" ) -var ip string - // 项目初始化引导用的服务,初始化引导结束后即退出 var setupServer *http.Server @@ -29,7 +29,14 @@ func SetupStart() { HttpPort := 80 flag.IntVar(&HttpPort, "p", 80, "初始化阶段Http服务端口") flag.Parse() + config.Instance.SetSetupPort(HttpPort) log.Infof("HttpServer Start On Port :%d", HttpPort) + if HttpPort == 80 { + log.Infof("Please click http://%s to continue.\n", ip.GetIp()) + } else { + log.Infof("Please click http://%s:%d to continue.", ip.GetIp(), HttpPort) + } + setupServer = &http.Server{ Addr: fmt.Sprintf(":%d", HttpPort), Handler: mux, diff --git a/server/res_init/init.go b/server/res_init/init.go index 2358b6b..e587813 100644 --- a/server/res_init/init.go +++ b/server/res_init/init.go @@ -23,7 +23,6 @@ func Init(serverVersion string) { if !config.IsInit { dirInit() - log.Infof("Please click http://127.0.0.1 to continue.\n") go http_server.SetupStart() <-signal.InitChan http_server.SetupStop() diff --git a/server/services/setup/dns.go b/server/services/setup/dns.go index 6282fcd..f3cd6e2 100644 --- a/server/services/setup/dns.go +++ b/server/services/setup/dns.go @@ -1,14 +1,12 @@ package setup import ( - "encoding/json" "fmt" - "io" - "net/http" "pmail/i18n" "pmail/services/auth" "pmail/utils/context" "pmail/utils/errors" + "pmail/utils/ip" ) type DNSItem struct { @@ -26,30 +24,11 @@ func GetDNSSettings(ctx *context.Context) ([]*DNSItem, error) { } ret := []*DNSItem{ - {Type: "A", Host: "smtp", Value: getIp(), TTL: 3600, Tips: i18n.GetText(ctx.Lang, "ip_taps")}, - {Type: "A", Host: "pop", Value: getIp(), TTL: 3600, Tips: i18n.GetText(ctx.Lang, "ip_taps")}, + {Type: "A", Host: "smtp", Value: ip.GetIp(), TTL: 3600, Tips: i18n.GetText(ctx.Lang, "ip_taps")}, + {Type: "A", Host: "pop", Value: ip.GetIp(), TTL: 3600, Tips: i18n.GetText(ctx.Lang, "ip_taps")}, {Type: "MX", Host: "-", Value: fmt.Sprintf("smtp.%s", configData.Domain), TTL: 3600}, {Type: "TXT", Host: "-", Value: "v=spf1 a mx ~all", TTL: 3600}, {Type: "TXT", Host: "default._domainkey", Value: auth.DkimGen(), TTL: 3600}, } return ret, nil } - -func getIp() string { - resp, err := http.Get("http://ip-api.com/json/?lang=zh-CN ") - if err != nil { - return "Your Server IP" - } - defer resp.Body.Close() - - if resp.StatusCode == 200 { - body, err := io.ReadAll(resp.Body) - if err == nil { - var queryRes map[string]string - _ = json.Unmarshal(body, &queryRes) - - return queryRes["query"] - } - } - return "Your Server IP" -} diff --git a/server/utils/ip/ip.go b/server/utils/ip/ip.go new file mode 100644 index 0000000..ca24939 --- /dev/null +++ b/server/utils/ip/ip.go @@ -0,0 +1,32 @@ +package ip + +import ( + "encoding/json" + "io" + "net/http" +) + +var ip string + +func GetIp() string { + if ip != "" { + return ip + } + + resp, err := http.Get("http://ip-api.com/json/?lang=zh-CN ") + if err != nil { + return "[Your Server IP]" + } + defer resp.Body.Close() + + if resp.StatusCode == 200 { + body, err := io.ReadAll(resp.Body) + if err == nil { + var queryRes map[string]string + _ = json.Unmarshal(body, &queryRes) + ip = queryRes["query"] + return queryRes["query"] + } + } + return "[Your Server IP]" +} diff --git a/server/utils/send/send.go b/server/utils/send/send.go index 31c543c..43a9336 100644 --- a/server/utils/send/send.go +++ b/server/utils/send/send.go @@ -188,7 +188,12 @@ func Send(ctx *context.Context, e *parsemail.Email) (error, map[string]error) { orgMap := map[string]error{} errMap.Range(func(key, value any) bool { - orgMap[key.(string)] = value.(error) + if value != nil { + orgMap[key.(string)] = value.(error) + }else { + orgMap[key.(string)] = nil + } + return true })