mirror of
https://github.com/Jinnrry/PMail.git
synced 2025-02-20 11:43:09 +08:00
feature/2.7.4 (#215)
1、SSL renew过程添加挑战适配器 2、转发邮件保留原始收件人地址 3、支持密送功能 4、升级所有依赖包
This commit is contained in:
parent
9e1a14f6ea
commit
223117283b
@ -23,9 +23,11 @@ let lang = {
|
||||
"date": "Date",
|
||||
"to": "To",
|
||||
"cc": "Cc",
|
||||
"bcc": "Bcc",
|
||||
"sender_desc": "Sender",
|
||||
"to_desc": "Recipient's e-mail address",
|
||||
"cc_desc": "Cc's e-mail address",
|
||||
"cc_desc": "CC's e-mail address",
|
||||
"bcc_desc": "BCC's e-mail address",
|
||||
"send": "send",
|
||||
"add_att": "Add Attachment",
|
||||
"attachment": "Attachment",
|
||||
@ -135,9 +137,11 @@ const zhCN = {
|
||||
"date": "时间",
|
||||
"to": "收件人地址",
|
||||
"cc": "抄送人地址",
|
||||
"bcc": "密送人地址",
|
||||
"sender_desc": "发件人",
|
||||
"to_desc": "接收人邮件地址",
|
||||
"cc_desc": "抄送人邮箱地址",
|
||||
"bcc_desc": "密送人邮箱地址",
|
||||
"send": "发送",
|
||||
"add_att": "添加附件",
|
||||
"attachment": "附件",
|
||||
|
@ -48,6 +48,10 @@
|
||||
:reserve-keyword="false" :placeholder="lang.cc_desc"></el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="lang.bcc" prop="bcc">
|
||||
<el-select v-model="ruleForm.bcc" style="width: 100%;" multiple filterable allow-create
|
||||
:reserve-keyword="false" :placeholder="lang.bcc_desc"></el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="lang.title" prop="subject">
|
||||
<el-input v-model="ruleForm.subject" :placeholder="lang.title"></el-input>
|
||||
@ -153,6 +157,7 @@ const ruleForm = reactive({
|
||||
sender: '',
|
||||
receivers: '',
|
||||
cc: '',
|
||||
bcc: '',
|
||||
subject: '',
|
||||
domains: [],
|
||||
pickDomain: ""
|
||||
@ -216,6 +221,19 @@ const validateCc = function (rule, value, callback) {
|
||||
callback()
|
||||
}
|
||||
|
||||
const validateBcc = function (rule, value, callback) {
|
||||
for (let index = 0; index < ruleForm.bcc.length; index++) {
|
||||
let element = ruleForm.bcc[index];
|
||||
|
||||
console.log(element)
|
||||
if (!checkEmail(element)) {
|
||||
callback(new Error(lang.err_email_format))
|
||||
return
|
||||
}
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
const rules = reactive({
|
||||
sender: [
|
||||
{validator: validateSender, trigger: 'change'}
|
||||
@ -226,6 +244,9 @@ const rules = reactive({
|
||||
cc: [
|
||||
{validator: validateCc, trigger: 'change'}
|
||||
],
|
||||
bcc: [
|
||||
{validator: validateBcc, trigger: 'change'}
|
||||
],
|
||||
subject: [
|
||||
{required: true, message: lang.err_title_must, trigger: 'change'},
|
||||
],
|
||||
@ -267,12 +288,22 @@ const send = function (formEl) {
|
||||
})
|
||||
}
|
||||
|
||||
let objectBccs = []
|
||||
for (let index = 0; index < ruleForm.bcc.length; index++) {
|
||||
let element = ruleForm.bcc[index];
|
||||
objectBccs.push({
|
||||
name: "",
|
||||
email: element
|
||||
})
|
||||
}
|
||||
|
||||
let text = editorRef.value.getText()
|
||||
|
||||
http.post("/api/email/send", {
|
||||
from: {name: ruleForm.nickName, email: ruleForm.sender + "@" + ruleForm.pickDomain},
|
||||
to: objectTos,
|
||||
cc: objectCcs,
|
||||
bcc: objectBccs,
|
||||
subject: ruleForm.subject,
|
||||
text: text,
|
||||
html: valueHtml.value,
|
||||
|
@ -2,13 +2,16 @@ package parsemail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/Jinnrry/pmail/config"
|
||||
"github.com/Jinnrry/pmail/models"
|
||||
"github.com/Jinnrry/pmail/utils/context"
|
||||
"github.com/emersion/go-message"
|
||||
_ "github.com/emersion/go-message/charset"
|
||||
"github.com/emersion/go-message/mail"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cast"
|
||||
"io"
|
||||
"net/textproto"
|
||||
"regexp"
|
||||
@ -57,6 +60,45 @@ type Email struct {
|
||||
Size int
|
||||
}
|
||||
|
||||
func NewEmailFromModel(d models.Email) *Email {
|
||||
|
||||
var To []*User
|
||||
json.Unmarshal([]byte(d.To), &To)
|
||||
|
||||
var ReplyTo []*User
|
||||
json.Unmarshal([]byte(d.ReplyTo), &ReplyTo)
|
||||
|
||||
var Sender *User
|
||||
json.Unmarshal([]byte(d.Sender), &Sender)
|
||||
|
||||
var Bcc []*User
|
||||
json.Unmarshal([]byte(d.Bcc), &Bcc)
|
||||
|
||||
var Cc []*User
|
||||
json.Unmarshal([]byte(d.Cc), &Cc)
|
||||
|
||||
var Attachments []*Attachment
|
||||
json.Unmarshal([]byte(d.Attachments), &Attachments)
|
||||
|
||||
return &Email{
|
||||
MessageId: cast.ToInt64(d.Id),
|
||||
From: &User{
|
||||
Name: d.FromName,
|
||||
EmailAddress: d.FromAddress,
|
||||
},
|
||||
To: To,
|
||||
Subject: d.Subject,
|
||||
Text: []byte(d.Text.String),
|
||||
HTML: []byte(d.Html.String),
|
||||
Sender: Sender,
|
||||
ReplyTo: ReplyTo,
|
||||
Bcc: Bcc,
|
||||
Cc: Cc,
|
||||
Attachments: Attachments,
|
||||
Date: d.SendDate.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
}
|
||||
|
||||
func NewEmailFromReader(to []string, r io.Reader, size int) *Email {
|
||||
ret := &Email{}
|
||||
m, err := message.Read(r)
|
||||
@ -67,10 +109,24 @@ func NewEmailFromReader(to []string, r io.Reader, size int) *Email {
|
||||
ret.Size = size
|
||||
ret.From = buildUser(m.Header.Get("From"))
|
||||
|
||||
if len(to) > 0 {
|
||||
ret.To = buildUsers(to)
|
||||
} else {
|
||||
ret.To = buildUsers(m.Header.Values("To"))
|
||||
smtpTo := buildUsers(to)
|
||||
|
||||
ret.To = buildUsers(m.Header.Values("To"))
|
||||
|
||||
ret.Bcc = []*User{}
|
||||
|
||||
for _, user := range smtpTo {
|
||||
in := false
|
||||
for _, u := range ret.To {
|
||||
if u.EmailAddress == user.EmailAddress {
|
||||
in = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !in {
|
||||
ret.Bcc = append(ret.Bcc, user)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ret.Cc = buildUsers(m.Header.Values("Cc"))
|
||||
@ -191,20 +247,24 @@ func buildUsers(str []string) []*User {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (e *Email) ForwardBuildBytes(ctx *context.Context, forwardAddress string) []byte {
|
||||
func (e *Email) ForwardBuildBytes(ctx *context.Context, sender *models.User) []byte {
|
||||
var b bytes.Buffer
|
||||
|
||||
from := []*mail.Address{{e.From.Name, e.From.EmailAddress}}
|
||||
to := []*mail.Address{
|
||||
{
|
||||
Address: forwardAddress,
|
||||
},
|
||||
to := []*mail.Address{}
|
||||
for _, user := range e.To {
|
||||
to = append(to, &mail.Address{
|
||||
Name: user.Name,
|
||||
Address: user.EmailAddress,
|
||||
})
|
||||
}
|
||||
|
||||
senderAddress := []*mail.Address{{sender.Name, fmt.Sprintf("%s@%s", sender.Account, config.Instance.Domains[0])}}
|
||||
// Create our mail header
|
||||
var h mail.Header
|
||||
h.SetDate(time.Now())
|
||||
h.SetAddressList("From", from)
|
||||
h.SetAddressList("Sender", senderAddress)
|
||||
h.SetAddressList("To", to)
|
||||
h.SetText("Subject", e.Subject)
|
||||
h.SetMessageID(fmt.Sprintf("%d@%s", e.MessageId, config.Instance.Domain))
|
||||
@ -297,6 +357,7 @@ func (e *Email) BuildBytes(ctx *context.Context, dkim bool) []byte {
|
||||
}
|
||||
h.SetMessageID(fmt.Sprintf("%d@%s", e.MessageId, config.Instance.Domain))
|
||||
h.SetAddressList("From", from)
|
||||
h.SetAddressList("Sender", from)
|
||||
h.SetAddressList("To", to)
|
||||
h.SetText("Subject", e.Subject)
|
||||
if len(e.Cc) != 0 {
|
||||
|
@ -8,20 +8,20 @@ require (
|
||||
github.com/alexedwards/scs/postgresstore v0.0.0-20240316134038-7e11d57e8885
|
||||
github.com/alexedwards/scs/sqlite3store v0.0.0-20240316134038-7e11d57e8885
|
||||
github.com/alexedwards/scs/v2 v2.8.0
|
||||
github.com/dlclark/regexp2 v1.11.2
|
||||
github.com/dlclark/regexp2 v1.11.4
|
||||
github.com/emersion/go-message v0.18.1
|
||||
github.com/emersion/go-msgauth v0.6.8
|
||||
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43
|
||||
github.com/emersion/go-smtp v0.21.3
|
||||
github.com/go-acme/lego/v4 v4.17.4
|
||||
github.com/go-acme/lego/v4 v4.18.0
|
||||
github.com/go-sql-driver/mysql v1.8.1
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/mileusna/spf v0.9.5
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cast v1.6.0
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/text v0.16.0
|
||||
modernc.org/sqlite v1.30.1
|
||||
github.com/spf13/cast v1.7.0
|
||||
golang.org/x/crypto v0.27.0
|
||||
golang.org/x/text v0.18.0
|
||||
modernc.org/sqlite v1.33.1
|
||||
xorm.io/builder v0.3.13
|
||||
xorm.io/xorm v1.3.9
|
||||
)
|
||||
@ -30,14 +30,14 @@ require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.3 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/miekg/dns v1.1.61 // indirect
|
||||
github.com/miekg/dns v1.1.62 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
@ -47,13 +47,14 @@ require (
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
golang.org/x/mod v0.19.0 // indirect
|
||||
golang.org/x/net v0.27.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
|
||||
modernc.org/libc v1.54.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/tools v0.25.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect
|
||||
modernc.org/libc v1.61.0 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
|
@ -17,8 +17,8 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.11.2 h1:/u628IuisSTwri5/UKloiIsH8+qF2Pu7xEQX+yIKg68=
|
||||
github.com/dlclark/regexp2 v1.11.2/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
||||
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/emersion/go-message v0.18.1 h1:tfTxIoXFSFRwWaZsgnqS1DSZuGpYGzSmCZD8SK3QA2E=
|
||||
@ -37,10 +37,10 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-acme/lego/v4 v4.17.4 h1:h0nePd3ObP6o7kAkndtpTzCw8shOZuWckNYeUQwo36Q=
|
||||
github.com/go-acme/lego/v4 v4.17.4/go.mod h1:dU94SvPNqimEeb7EVilGGSnS0nU1O5Exir0pQ4QFL4U=
|
||||
github.com/go-jose/go-jose/v4 v4.0.3 h1:o8aphO8Hv6RPmH+GfzVuyf7YXSBibp+8YyHdOoDESGo=
|
||||
github.com/go-jose/go-jose/v4 v4.0.3/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
|
||||
github.com/go-acme/lego/v4 v4.18.0 h1:2hH8KcdRBSb+p5o9VZIm61GAOXYALgILUCSs1Q+OYsk=
|
||||
github.com/go-acme/lego/v4 v4.18.0/go.mod h1:Blkg3izvXpl3zxk7WKngIuwR2I/hvYVP3vRnvgBp7m8=
|
||||
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
|
||||
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
@ -85,8 +85,8 @@ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
|
||||
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/mileusna/spf v0.9.5 h1:P6cmaIBwrhZaP9stXMzGOtxe+gIu65OVbZCmrAv9rgU=
|
||||
github.com/mileusna/spf v0.9.5/go.mod h1:o6IdTae6QptAbLgx/+ueXSTSpkG+f1cqLemQJSew8sI=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -118,8 +118,8 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
@ -135,14 +135,16 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@ -153,16 +155,16 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -184,8 +186,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@ -195,16 +197,16 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
|
||||
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -228,16 +230,16 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
|
||||
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
|
||||
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
|
||||
modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4=
|
||||
modernc.org/ccgo/v4 v4.21.0/go.mod h1:h6kt6H/A2+ew/3MW/p6KEoQmrq/i3pr0J/SiwiaF/g0=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8=
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.54.4 h1:eDr4WnANZv+aRBKNCDo4khJbaHpxoTNOxeXqpznSZyY=
|
||||
modernc.org/libc v1.54.4/go.mod h1:CH8KSvv67UxcGCOLizggw3Zi3yT+sUjLWysK/YeUnqk=
|
||||
modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M=
|
||||
modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a h1:CfbpOLEo2IwNzJdMvE8aiRbPMxoTpgAJeyePh0SmO8M=
|
||||
modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.61.0 h1:eGFcvWpqlnoGwzZeZe3PWJkkKbM/3SUGyk1DVZQ0TpE=
|
||||
modernc.org/libc v1.61.0/go.mod h1:DvxVX89wtGTu+r72MLGhygpfi3aUGgZRdAYGCAVVud0=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
@ -246,8 +248,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk=
|
||||
modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU=
|
||||
modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM=
|
||||
modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
@ -3,8 +3,6 @@ package models
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"github.com/Jinnrry/pmail/dto/parsemail"
|
||||
"github.com/spf13/cast"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -45,42 +43,6 @@ type attachments struct {
|
||||
//Content []byte
|
||||
}
|
||||
|
||||
func (d *Email) GetTos() []*parsemail.User {
|
||||
var ret []*parsemail.User
|
||||
json.Unmarshal([]byte(d.To), &ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (d *Email) GetReplyTo() []*parsemail.User {
|
||||
var ret []*parsemail.User
|
||||
json.Unmarshal([]byte(d.ReplyTo), &ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (d *Email) GetSender() *parsemail.User {
|
||||
var ret *parsemail.User
|
||||
json.Unmarshal([]byte(d.Sender), &ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (d *Email) GetBcc() []*parsemail.User {
|
||||
var ret []*parsemail.User
|
||||
json.Unmarshal([]byte(d.Bcc), &ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (d *Email) GetCc() []*parsemail.User {
|
||||
var ret []*parsemail.User
|
||||
json.Unmarshal([]byte(d.Cc), &ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (d *Email) GetAttachments() []*parsemail.Attachment {
|
||||
var ret []*parsemail.Attachment
|
||||
json.Unmarshal([]byte(d.Attachments), &ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (d *Email) MarshalJSON() ([]byte, error) {
|
||||
type Alias Email
|
||||
|
||||
@ -119,25 +81,3 @@ func (d *Email) MarshalJSON() ([]byte, error) {
|
||||
Attachments: showAtt,
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Email) ToTransObj() *parsemail.Email {
|
||||
|
||||
return &parsemail.Email{
|
||||
MessageId: cast.ToInt64(d.Id),
|
||||
From: &parsemail.User{
|
||||
Name: d.FromName,
|
||||
EmailAddress: d.FromAddress,
|
||||
},
|
||||
To: d.GetTos(),
|
||||
Subject: d.Subject,
|
||||
Text: []byte(d.Text.String),
|
||||
HTML: []byte(d.Html.String),
|
||||
Sender: d.GetSender(),
|
||||
ReplyTo: d.GetReplyTo(),
|
||||
Bcc: d.GetBcc(),
|
||||
Cc: d.GetCc(),
|
||||
Attachments: d.GetAttachments(),
|
||||
Date: d.SendDate.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/Jinnrry/pmail/consts"
|
||||
"github.com/Jinnrry/pmail/db"
|
||||
"github.com/Jinnrry/pmail/dto"
|
||||
"github.com/Jinnrry/pmail/dto/parsemail"
|
||||
"github.com/Jinnrry/pmail/models"
|
||||
"github.com/Jinnrry/pmail/services/del_email"
|
||||
"github.com/Jinnrry/pmail/services/detail"
|
||||
@ -271,7 +272,7 @@ func (a action) Retr(session *gopop.Session, id int64) (string, int64, error) {
|
||||
return "", 0, errors.New("server error")
|
||||
}
|
||||
|
||||
ret := email.ToTransObj().BuildBytes(session.Ctx.(*context.Context), false)
|
||||
ret := parsemail.NewEmailFromModel(email.Email).BuildBytes(session.Ctx.(*context.Context), false)
|
||||
log.WithContext(session.Ctx).Debugf("Retr \n %+v", string(ret))
|
||||
return string(ret), cast.ToInt64(len(ret)), nil
|
||||
|
||||
@ -300,7 +301,7 @@ func (a action) Top(session *gopop.Session, id int64, n int) (string, error) {
|
||||
return "", errors.New("server error")
|
||||
}
|
||||
|
||||
ret := email.ToTransObj().BuildBytes(session.Ctx.(*context.Context), false)
|
||||
ret := parsemail.NewEmailFromModel(email.Email).BuildBytes(session.Ctx.(*context.Context), false)
|
||||
res := strings.Split(string(ret), "\n")
|
||||
headerEndLine := len(res) - 1
|
||||
for i, re := range res {
|
||||
|
@ -60,7 +60,7 @@ func MatchRule(ctx *context.Context, rule *dto.Rule, email *parsemail.Email) boo
|
||||
return true
|
||||
}
|
||||
|
||||
func DoRule(ctx *context.Context, rule *dto.Rule, email *parsemail.Email) {
|
||||
func DoRule(ctx *context.Context, rule *dto.Rule, email *parsemail.Email, user *models.User) {
|
||||
log.WithContext(ctx).Debugf("执行规则:%s", rule.Name)
|
||||
|
||||
switch rule.Action {
|
||||
@ -81,7 +81,7 @@ func DoRule(ctx *context.Context, rule *dto.Rule, email *parsemail.Email) {
|
||||
log.WithContext(ctx).Errorf("Forward Error! loop forwarding!")
|
||||
return
|
||||
}
|
||||
err := send.Forward(ctx, email, rule.Params)
|
||||
err := send.Forward(ctx, email, rule.Params, user)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("Forward Error:%v", err)
|
||||
}
|
||||
|
@ -93,6 +93,24 @@ func renewCertificate(privateKey *ecdsa.PrivateKey, cfg *config.Config) error {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
if cfg.SSLType == config.SSLTypeAutoHTTP {
|
||||
err = client.Challenge.SetHTTP01Provider(GetHttpChallengeInstance())
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
} else if cfg.SSLType == config.SSLTypeAutoDNS {
|
||||
err = client.Challenge.SetDNS01Provider(GetDnsChallengeInstance(), dns01.AddDNSTimeout(60*time.Minute))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
log.Errorf("Please Set DNS Record/请将以下内容添加到DNS记录中:\n")
|
||||
for _, item := range GetDnsChallengeInstance().GetDNSSettings(nil) {
|
||||
log.Errorf("Type:%s\tHost:%s\tValue:%s\n", item.Type, item.Host, item.Value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var reg *registration.Resource
|
||||
|
||||
reg, err = client.Registration.ResolveAccountByKey()
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/Jinnrry/pmail/hooks/framework"
|
||||
"github.com/Jinnrry/pmail/models"
|
||||
"github.com/Jinnrry/pmail/services/rule"
|
||||
"github.com/Jinnrry/pmail/utils/array"
|
||||
"github.com/Jinnrry/pmail/utils/async"
|
||||
"github.com/Jinnrry/pmail/utils/context"
|
||||
"github.com/Jinnrry/pmail/utils/errors"
|
||||
@ -37,6 +38,9 @@ func (s *Session) Data(r io.Reader) error {
|
||||
log.WithContext(ctx).Error("邮件内容无法读取", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.WithContext(ctx).Debugf("%s", string(emailData))
|
||||
|
||||
log.WithContext(ctx).Debugf("开始执行插件ReceiveParseBefore!")
|
||||
for _, hook := range hooks.HookList {
|
||||
if hook == nil {
|
||||
@ -81,7 +85,7 @@ func (s *Session) Data(r io.Reader) error {
|
||||
}
|
||||
|
||||
// 转发
|
||||
_, err := saveEmail(ctx, len(emailData), email, s.Ctx.UserID, 1, true, true)
|
||||
_, err := saveEmail(ctx, len(emailData), email, s.Ctx.UserID, 1, nil, true, true)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("Email Save Error %v", err)
|
||||
}
|
||||
@ -155,7 +159,7 @@ func (s *Session) Data(r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
users, _ := saveEmail(ctx, len(emailData), email, 0, 0, SPFStatus, dkimStatus)
|
||||
users, _ := saveEmail(ctx, len(emailData), email, 0, 0, s.To, SPFStatus, dkimStatus)
|
||||
|
||||
if email.MessageId > 0 {
|
||||
log.WithContext(ctx).Debugf("开始执行邮件规则!")
|
||||
@ -164,7 +168,7 @@ func (s *Session) Data(r io.Reader) error {
|
||||
rs := rule.GetAllRules(ctx, user.ID)
|
||||
for _, r := range rs {
|
||||
if rule.MatchRule(ctx, r, email) {
|
||||
rule.DoRule(ctx, r, email)
|
||||
rule.DoRule(ctx, r, email, user)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,7 +197,7 @@ func (s *Session) Data(r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveEmail(ctx *context.Context, size int, email *parsemail.Email, sendUserID int, emailType int, SPFStatus, dkimStatus bool) ([]*models.User, error) {
|
||||
func saveEmail(ctx *context.Context, size int, email *parsemail.Email, sendUserID int, emailType int, reallyTo []string, SPFStatus, dkimStatus bool) ([]*models.User, error) {
|
||||
var dkimV, spfV int8
|
||||
if dkimStatus {
|
||||
dkimV = 1
|
||||
@ -247,10 +251,23 @@ func saveEmail(ctx *context.Context, size int, email *parsemail.Email, sendUserI
|
||||
if emailType == 0 {
|
||||
// 找到收信人id
|
||||
accounts := []string{}
|
||||
for _, user := range append(append(email.To, email.Cc...), email.Bcc...) {
|
||||
account, _ := user.GetDomainAccount()
|
||||
if account != "" {
|
||||
accounts = append(accounts, account)
|
||||
// 优先取smtp协议中的收件人地址
|
||||
if len(reallyTo) > 0 {
|
||||
for _, s := range reallyTo {
|
||||
account := parsemail.BuilderUser(s)
|
||||
if account != nil {
|
||||
acc, domain := account.GetDomainAccount()
|
||||
if array.InArray(domain, config.Instance.Domains) && acc != "" {
|
||||
accounts = append(accounts, acc)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, user := range append(append(email.To, email.Cc...), email.Bcc...) {
|
||||
account, _ := user.GetDomainAccount()
|
||||
if account != "" {
|
||||
accounts = append(accounts, account)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,16 +287,16 @@ func saveEmail(ctx *context.Context, size int, email *parsemail.Email, sendUserI
|
||||
}
|
||||
}
|
||||
} else {
|
||||
users = append(users, &models.User{ID: 1})
|
||||
err = db.Instance.Table(&models.User{}).Where("is_admin=1").Find(&users)
|
||||
// 当邮件找不到收件人的时候,邮件全部丢给管理员账号
|
||||
// id = 1的账号直接当成管理员账号处理
|
||||
ue := models.UserEmail{EmailID: modelEmail.Id, UserID: 1, Status: cast.ToInt8(email.Status)}
|
||||
_, err = db.Instance.Insert(&ue)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("db insert error:%+v", err.Error())
|
||||
for _, user := range users {
|
||||
ue := models.UserEmail{EmailID: modelEmail.Id, UserID: user.ID, Status: cast.ToInt8(email.Status)}
|
||||
_, err = db.Instance.Insert(&ue)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("db insert error:%+v", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ue := models.UserEmail{EmailID: modelEmail.Id, UserID: ctx.UserID}
|
||||
_, err = db.Instance.Insert(&ue)
|
||||
|
@ -4,7 +4,10 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/Jinnrry/pmail/config"
|
||||
"github.com/Jinnrry/pmail/dto/parsemail"
|
||||
"github.com/Jinnrry/pmail/models"
|
||||
"github.com/Jinnrry/pmail/utils/array"
|
||||
"github.com/Jinnrry/pmail/utils/async"
|
||||
"github.com/Jinnrry/pmail/utils/consts"
|
||||
@ -22,11 +25,14 @@ type mxDomain struct {
|
||||
}
|
||||
|
||||
// Forward 转发邮件
|
||||
func Forward(ctx *context.Context, e *parsemail.Email, forwardAddress string) error {
|
||||
_, fromDomain := e.From.GetDomainAccount()
|
||||
func Forward(ctx *context.Context, e *parsemail.Email, forwardAddress string, user *models.User) error {
|
||||
|
||||
log.WithContext(ctx).Debugf("开始转发邮件")
|
||||
b := e.ForwardBuildBytes(ctx, forwardAddress)
|
||||
sender := fmt.Sprintf("%s@%s", user.Account, config.Instance.Domains[0])
|
||||
|
||||
b := e.ForwardBuildBytes(ctx, user)
|
||||
|
||||
log.WithContext(ctx).Debugf("%s", b)
|
||||
|
||||
var to []*parsemail.User
|
||||
to = []*parsemail.User{
|
||||
@ -76,16 +82,16 @@ func Forward(ctx *context.Context, e *parsemail.Email, forwardAddress string) er
|
||||
domain := domain
|
||||
tos := tos
|
||||
as.WaitProcess(func(p any) {
|
||||
err := smtp.SendMail("", domain.mxHost+":25", nil, e.From.EmailAddress, fromDomain, buildAddress(tos), b)
|
||||
err := smtp.SendMail("", domain.mxHost+":25", nil, sender, config.Instance.Domains[0], buildAddress(tos), b)
|
||||
|
||||
// 使用其他方式发送
|
||||
if err != nil {
|
||||
// EOF 表示未知错误,此时降级为非tls连接发送(目前仅139邮箱有这个问题)
|
||||
if errors.Is(err, smtp.NoSupportSTARTTLSError) || err.Error() == "EOF" {
|
||||
err = smtp.SendMailWithTls("", domain.mxHost+":465", nil, e.From.EmailAddress, fromDomain, buildAddress(tos), b)
|
||||
err = smtp.SendMailWithTls("", domain.mxHost+":465", nil, sender, config.Instance.Domains[0], buildAddress(tos), b)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Warnf("Unsafe! %s Server Not Support SMTPS & STARTTLS", domain.domain)
|
||||
err = smtp.SendMailUnsafe("", domain.mxHost+":25", nil, e.From.EmailAddress, fromDomain, buildAddress(tos), b)
|
||||
err = smtp.SendMailUnsafe("", domain.mxHost+":25", nil, sender, config.Instance.Domains[0], buildAddress(tos), b)
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,12 +99,12 @@ func Forward(ctx *context.Context, e *parsemail.Email, forwardAddress string) er
|
||||
if certificateErr, ok := err.(*tls.CertificateVerificationError); ok {
|
||||
// 单测使用
|
||||
if domain.domain == "localhost" {
|
||||
err = smtp.SendMailUnsafe("", domain.mxHost+":25", nil, e.From.EmailAddress, fromDomain, buildAddress(tos), b)
|
||||
err = smtp.SendMailUnsafe("", domain.mxHost+":25", nil, sender, config.Instance.Domains[0], buildAddress(tos), b)
|
||||
} else if hostnameErr, is := certificateErr.Err.(x509.HostnameError); is {
|
||||
if hostnameErr.Certificate != nil {
|
||||
certificateHostName := hostnameErr.Certificate.DNSNames
|
||||
// 重新选取证书发送
|
||||
err = smtp.SendMail(domainMatch(domain.domain, certificateHostName), domain.mxHost+":25", nil, e.From.EmailAddress, fromDomain, buildAddress(tos), b)
|
||||
err = smtp.SendMail(domainMatch(domain.domain, certificateHostName), domain.mxHost+":25", nil, sender, config.Instance.Domains[0], buildAddress(tos), b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/Jinnrry/pmail/config"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"net"
|
||||
"net/smtp"
|
||||
@ -407,6 +408,9 @@ func SendMailWithTls(domain string, addr string, a smtp.Auth, from string, fromD
|
||||
// library.
|
||||
// 修复TSL验证问题
|
||||
func SendMail(domain string, addr string, a smtp.Auth, from string, fromDomain string, to []string, msg []byte) error {
|
||||
|
||||
log.Debugf("SendMail,%s ,%s ,%s ,%s ,%v ", domain, addr, from, fromDomain, to)
|
||||
|
||||
if err := validateLine(from); err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user