mirror of
https://github.com/Jinnrry/PMail.git
synced 2025-02-20 11:43:09 +08:00
parent
096b4b8fed
commit
cc4aa851bc
@ -48,7 +48,7 @@ First go to [spamhaus](https://check.spamhaus.org/) and check your domain name a
|
||||
|
||||
## 2、Run
|
||||
|
||||
`./pmail`
|
||||
`./pmail` (Set the http port for the initialization interface with `-p` )
|
||||
|
||||
Or
|
||||
|
||||
|
@ -53,7 +53,7 @@ PMail是一个追求极简部署流程、极致资源占用的个人域名邮箱
|
||||
|
||||
## 2、运行
|
||||
|
||||
`./pmail`
|
||||
`./pmail` (通过`-p`参数指定初始化界面的http端口)
|
||||
|
||||
或者
|
||||
|
||||
|
@ -1,11 +1,8 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var IsInit bool
|
||||
@ -38,9 +35,6 @@ type Config struct {
|
||||
TablesInitData map[string]string `json:"-"`
|
||||
}
|
||||
|
||||
//go:embed tables/*
|
||||
var tableConfig embed.FS
|
||||
|
||||
const DBTypeMySQL = "mysql"
|
||||
const DBTypeSQLite = "sqlite"
|
||||
const SSLTypeAuto = "0" //自动生成证书
|
||||
@ -76,38 +70,6 @@ func Init() {
|
||||
Instance.Domains = []string{Instance.Domain}
|
||||
}
|
||||
|
||||
// 读取表设置
|
||||
Instance.Tables = map[string]string{}
|
||||
Instance.TablesInitData = map[string]string{}
|
||||
|
||||
root := "tables/mysql"
|
||||
if Instance.DbType == DBTypeSQLite {
|
||||
root = "tables/sqlite"
|
||||
}
|
||||
err = fs.WalkDir(tableConfig, root, func(path string, info fs.DirEntry, err error) error {
|
||||
if !info.IsDir() && strings.HasSuffix(info.Name(), ".sql") {
|
||||
tableName := strings.ReplaceAll(info.Name(), ".sql", "")
|
||||
i, e := tableConfig.ReadFile(path)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
if len(i) == 0 || strings.TrimSpace(string(i)) == "" {
|
||||
return nil
|
||||
}
|
||||
if strings.Contains(path, "data") {
|
||||
Instance.TablesInitData[tableName] = string(i)
|
||||
} else {
|
||||
Instance.Tables[tableName] = string(i)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if Instance.Domain != "" && Instance.IsInit {
|
||||
IsInit = true
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
CREATE table email
|
||||
(
|
||||
id INT unsigned AUTO_INCREMENT PRIMARY KEY COMMENT '自增id',
|
||||
type tinyint(4) NOT NULL DEFAULT 0 COMMENT '邮件类型,0:收到的邮件,1:发送的邮件',
|
||||
group_id int unsigned NOT NULL DEFAULT 0 COMMENT '分组id',
|
||||
subject varchar(1000) NOT NULL DEFAULT '' COMMENT '邮件标题',
|
||||
reply_to json COMMENT '回复人',
|
||||
from_name varchar(50) NOT NULL DEFAULT '' COMMENT '发件人名称',
|
||||
from_address varchar(150) NOT NULL DEFAULT '' COMMENT '发件人邮件地址',
|
||||
`to` json COMMENT '收件人信息',
|
||||
bcc json COMMENT '抄送',
|
||||
cc json COMMENT '抄送',
|
||||
`text` text COMMENT '邮件文本内容',
|
||||
html mediumtext COMMENT 'html格式内容',
|
||||
sender json COMMENT '发件人',
|
||||
attachments json COMMENT '附件内容',
|
||||
spf_check tinyint(1) DEFAULT 0 COMMENT '0未校验,1校验通过,2校验未通过',
|
||||
dkim_check tinyint(1) DEFAULT 0 COMMENT '0未校验,1校验通过,2校验未通过',
|
||||
status tinyint(4) NOT NULL DEFAULT 0 COMMENT '0未发送,1已发送,2发送失败,3删除',
|
||||
send_user_id int unsigned NOT NULL DEFAULT 0 COMMENT '发件人用户id',
|
||||
is_read tinyint(1) NOT NULL DEFAULT 0 COMMENT '未读0,已读1',
|
||||
error text COMMENT '错误信息记录',
|
||||
cron_send_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '定时发送邮件的发送时间',
|
||||
send_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发件日期',
|
||||
create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
|
||||
)COMMENT='邮件内容表'
|
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `group`
|
||||
(
|
||||
id INT unsigned AUTO_INCREMENT PRIMARY KEY COMMENT '自增id',
|
||||
name varchar(10) NOT NULL DEFAULT '' COMMENT '分组名称',
|
||||
user_id INT unsigned NOT NULL DEFAULT 0 COMMENT '用户id',
|
||||
parent_id INT unsigned COMMENT '父级组ID'
|
||||
)COMMENT='分组信息表'
|
@ -1,10 +0,0 @@
|
||||
CREATE TABLE `rule`
|
||||
(
|
||||
id INT unsigned AUTO_INCREMENT PRIMARY KEY COMMENT '自增id',
|
||||
user_id int NOT NULL DEFAULT 0 COMMENT '用户id',
|
||||
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '规则名称',
|
||||
`value` json NOT NULL COMMENT '规则内容',
|
||||
action int not null default 0 comment '执行动作,1已读,2转发,3删除',
|
||||
params varchar(255) not null default '' comment '执行参数',
|
||||
sort int not null default 0 COMMENT '排序,越大约优先'
|
||||
) COMMENT '收信规则表'
|
@ -1,7 +0,0 @@
|
||||
CREATE TABLE sessions
|
||||
(
|
||||
token CHAR(43) PRIMARY KEY,
|
||||
data BLOB NOT NULL,
|
||||
expiry TIMESTAMP(6) NOT NULL,
|
||||
KEY `sessions_expiry_idx` (`expiry`)
|
||||
)COMMENT='系统session数据表';
|
@ -1,8 +0,0 @@
|
||||
CREATE TABLE user
|
||||
(
|
||||
id INT unsigned AUTO_INCREMENT PRIMARY KEY COMMENT '自增id',
|
||||
account varchar(20) COMMENT '账号登陆名',
|
||||
name varchar(10) COMMENT '用户名',
|
||||
password char(32) COMMENT '登陆密码,两次md5加盐,md5(md5(password+"pmail") +"pmail2023")',
|
||||
UNIQUE INDEX udx_account ( account )
|
||||
)COMMENT='登陆信息表'
|
@ -1,8 +0,0 @@
|
||||
CREATE TABLE user_auth
|
||||
(
|
||||
id INT unsigned AUTO_INCREMENT PRIMARY KEY COMMENT '自增id',
|
||||
user_id int COMMENT '用户id',
|
||||
email_account varchar(30) COMMENT '收件人前缀',
|
||||
UNIQUE INDEX udx_uid_ename ( user_id, email_account),
|
||||
UNIQUE INDEX udx_ename_uid ( email_account,user_id )
|
||||
)COMMENT='登陆信息表'
|
@ -1,27 +0,0 @@
|
||||
CREATE table email
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
type tinyint(4) NOT NULL DEFAULT 0,
|
||||
group_id INTEGER NOT NULL DEFAULT 0,
|
||||
subject varchar(1000) NOT NULL DEFAULT '',
|
||||
reply_to json,
|
||||
from_name varchar(50) NOT NULL DEFAULT '',
|
||||
from_address varchar(150) NOT NULL DEFAULT '',
|
||||
`to` json,
|
||||
bcc json,
|
||||
cc json,
|
||||
`text` text,
|
||||
html text,
|
||||
sender json,
|
||||
attachments json ,
|
||||
spf_check tinyint(1) DEFAULT 0 ,
|
||||
dkim_check tinyint(1) DEFAULT 0 ,
|
||||
status tinyint(4) NOT NULL DEFAULT 0 ,
|
||||
send_user_id int unsigned NOT NULL DEFAULT 0 ,
|
||||
is_read tinyint(1) NOT NULL DEFAULT 0 ,
|
||||
error text ,
|
||||
cron_send_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ,
|
||||
send_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ,
|
||||
create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ,
|
||||
update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
@ -1,7 +0,0 @@
|
||||
CREATE TABLE `group`
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name varchar(10) NOT NULL DEFAULT '',
|
||||
parent_id INTEGER NOT NULL DEFAULT 0,
|
||||
user_id INTEGER NOT NULL DEFAULT 0
|
||||
)
|
@ -1,10 +0,0 @@
|
||||
create table rule
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id int,
|
||||
name varchar(255) default '' not null,
|
||||
value json not null,
|
||||
action int default 0 not null,
|
||||
params varchar(255) default '' not null,
|
||||
sort int default 0 not null
|
||||
)
|
@ -1,8 +0,0 @@
|
||||
CREATE TABLE sessions
|
||||
(
|
||||
token TEXT PRIMARY KEY,
|
||||
data BLOB NOT NULL,
|
||||
expiry REAL NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX sessions_expiry_idx ON sessions (expiry);
|
@ -1,8 +0,0 @@
|
||||
CREATE TABLE user
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
account varchar(20),
|
||||
name varchar(10),
|
||||
password char(32)
|
||||
);
|
||||
CREATE UNIQUE INDEX udx_account on user (account);
|
@ -1,9 +0,0 @@
|
||||
CREATE TABLE user_auth
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id int ,
|
||||
email_account varchar(30)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX udx_uid_ename on user_auth ( user_id, email_account);
|
||||
CREATE UNIQUE INDEX udx_ename_uid on user_auth ( email_account,user_id );
|
@ -37,6 +37,10 @@ func GetUserGroup(ctx *context.Context, w http.ResponseWriter, req *http.Request
|
||||
Label: i18n.GetText(ctx.Lang, "sketch"),
|
||||
Tag: dto.SearchTag{Type: 1, Status: 0}.ToString(),
|
||||
},
|
||||
{
|
||||
Label: i18n.GetText(ctx.Lang, "deleted"),
|
||||
Tag: dto.SearchTag{Type: -1, Status: 3}.ToString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -35,9 +35,8 @@ func Login(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
var user models.User
|
||||
|
||||
encodePwd := password.Encode(reqData.Password)
|
||||
|
||||
err = db.Instance.Get(&user, db.WithContext(ctx, "select * from user where account =? and password =?"),
|
||||
reqData.Account, encodePwd)
|
||||
|
||||
_, err = db.Instance.Where("account =? and password =?", reqData.Account, encodePwd).Get(&user)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Errorf("%+v", err)
|
||||
}
|
||||
|
@ -3,16 +3,14 @@ package db
|
||||
import (
|
||||
"fmt"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/jmoiron/sqlx"
|
||||
log "github.com/sirupsen/logrus"
|
||||
_ "modernc.org/sqlite"
|
||||
"pmail/config"
|
||||
"pmail/utils/context"
|
||||
"pmail/utils/errors"
|
||||
"strings"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
var Instance *sqlx.DB
|
||||
var Instance *xorm.Engine
|
||||
|
||||
func Init() error {
|
||||
dsn := config.Instance.DbDSN
|
||||
@ -20,9 +18,9 @@ func Init() error {
|
||||
|
||||
switch config.Instance.DbType {
|
||||
case "mysql":
|
||||
Instance, err = sqlx.Open("mysql", dsn)
|
||||
Instance, err = xorm.NewEngine("mysql", dsn)
|
||||
case "sqlite":
|
||||
Instance, err = sqlx.Open("sqlite", dsn)
|
||||
Instance, err = xorm.NewEngine("sqlite", dsn)
|
||||
default:
|
||||
return errors.New("Database Type Error!")
|
||||
}
|
||||
@ -31,10 +29,7 @@ func Init() error {
|
||||
}
|
||||
Instance.SetMaxOpenConns(100)
|
||||
Instance.SetMaxIdleConns(10)
|
||||
//showMySQLCharacterSet()
|
||||
checkTable()
|
||||
// 处理版本升级带来的数据表变更
|
||||
databaseUpdate()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -45,74 +40,3 @@ func WithContext(ctx *context.Context, sql string) string {
|
||||
}
|
||||
return sql
|
||||
}
|
||||
|
||||
type tables struct {
|
||||
TablesInPmail string `db:"Tables_in_pmail"`
|
||||
}
|
||||
|
||||
func checkTable() {
|
||||
var res []*tables
|
||||
|
||||
var err error
|
||||
if config.Instance.DbType == "sqlite" {
|
||||
err = Instance.Select(&res, "select name as `Tables_in_pmail` from sqlite_master where type='table'")
|
||||
} else {
|
||||
err = Instance.Select(&res, "show tables")
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
existTable := map[string]struct{}{}
|
||||
for _, tableName := range res {
|
||||
existTable[tableName.TablesInPmail] = struct{}{}
|
||||
}
|
||||
|
||||
for tableName, createSQL := range config.Instance.Tables {
|
||||
if createSQL == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := existTable[tableName]; !ok {
|
||||
_, err = Instance.Exec(createSQL)
|
||||
log.Infof("Create Table: %s", createSQL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if initData, ok := config.Instance.TablesInitData[tableName]; ok {
|
||||
if initData != "" {
|
||||
_, err = Instance.Exec(initData)
|
||||
log.Infof("Init Table: %s", initData)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type tableSQL struct {
|
||||
Table string `db:"Table"`
|
||||
CreateTable string `db:"Create Table"`
|
||||
}
|
||||
|
||||
func databaseUpdate() {
|
||||
// 检查email表是否有group id
|
||||
var err error
|
||||
var res []tableSQL
|
||||
if config.Instance.DbType == "sqlite" {
|
||||
err = Instance.Select(&res, "select sql as `Create Table` from sqlite_master where type='table' and tbl_name = 'email'")
|
||||
} else {
|
||||
err = Instance.Select(&res, "show create table `email`")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(res) > 0 && !strings.Contains(res[0].CreateTable, "group_id") {
|
||||
Instance.Exec("alter table email add group_id integer default 0 not null;")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,13 +13,13 @@ require (
|
||||
github.com/emersion/go-smtp v0.21.0
|
||||
github.com/go-acme/lego/v4 v4.16.1
|
||||
github.com/go-sql-driver/mysql v1.8.1
|
||||
github.com/jmoiron/sqlx v1.3.5
|
||||
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.22.0
|
||||
golang.org/x/text v0.14.0
|
||||
modernc.org/sqlite v1.29.6
|
||||
xorm.io/xorm v1.3.9
|
||||
)
|
||||
|
||||
require (
|
||||
@ -27,12 +27,18 @@ require (
|
||||
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.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // 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.58 // 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
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.24.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
@ -44,4 +50,5 @@ require (
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
xorm.io/builder v0.3.13 // indirect
|
||||
)
|
||||
|
@ -1,5 +1,7 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/Jinnrry/gopop v0.0.0-20231113115125-fbdf52ae39ea h1:GISNlu8fPa2K+aySmHPSd9X0PG8GAAFEobq4XIqodMk=
|
||||
github.com/Jinnrry/gopop v0.0.0-20231113115125-fbdf52ae39ea/go.mod h1:xcI6e+jbXWN+T8EWOJtHbAku6pzNqyCHaFvzdeL1r2o=
|
||||
github.com/alexedwards/scs/mysqlstore v0.0.0-20240316134038-7e11d57e8885 h1:C7QAamNjR5yz6di4KJWAKcnxueKBgq4L/JGXhlnu35w=
|
||||
@ -26,30 +28,37 @@ github.com/emersion/go-smtp v0.21.0 h1:ZDZmX9aFUuPlD1lpoT0nC/nozZuIkSCyQIyxdijjC
|
||||
github.com/emersion/go-smtp v0.21.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-acme/lego/v4 v4.16.1 h1:JxZ93s4KG0jL27rZ30UsIgxap6VGzKuREsSkkyzeoCQ=
|
||||
github.com/go-acme/lego/v4 v4.16.1/go.mod h1:AVvwdPned/IWpD/ihHhMsKnveF7HHYAz/CmtXi7OZoE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
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=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
|
||||
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
@ -60,8 +69,18 @@ github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
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=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
@ -73,9 +92,12 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -88,6 +110,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
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=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
@ -97,12 +120,14 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
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-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/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=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -139,6 +164,13 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@ -168,3 +200,7 @@ 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=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
|
||||
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/xorm v1.3.9 h1:TUovzS0ko+IQ1XnNLfs5dqK1cJl1H5uHpWbWqAQ04nU=
|
||||
xorm.io/xorm v1.3.9/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=
|
||||
|
@ -14,6 +14,7 @@ var (
|
||||
"login_exp": "登录已失效",
|
||||
"ip_taps": "这是你服务器IP,确保这个IP正确",
|
||||
"invalid_email_address": "无效的邮箱地址!",
|
||||
"deleted": "垃圾箱",
|
||||
}
|
||||
en = map[string]string{
|
||||
"all_email": "All Email",
|
||||
@ -28,6 +29,7 @@ var (
|
||||
"login_exp": "Login has expired.",
|
||||
"ip_taps": "This is your server's IP, make sure it is correct.",
|
||||
"invalid_email_address": "Invalid e-mail address!",
|
||||
"deleted": "Deleted",
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1,8 +1,12 @@
|
||||
package models
|
||||
|
||||
type User struct {
|
||||
ID int `db:"id"`
|
||||
Account string `db:"account"`
|
||||
Name string `db:"name"`
|
||||
Password string `db:"password"`
|
||||
ID int `xorm:"id unsigned int not null pk autoincr"`
|
||||
Account string `xorm:"varchar(20) notnull unique comment('账号登陆名')"`
|
||||
Name string `xorm:"varchar(10) notnull comment('用户名')"`
|
||||
Password string `xorm:"char(32) notnull comment('登陆密码,两次md5加盐,md5(md5(password+pmail) +pmail2023)')"`
|
||||
}
|
||||
|
||||
func (p User) TableName() string {
|
||||
return "user"
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
package models
|
||||
|
||||
type UserAuth struct {
|
||||
ID int `db:"id"`
|
||||
UserID int `db:"user_id"`
|
||||
EmailAccount string `db:"email_account"`
|
||||
ID int `xorm:"id int unsigned not null pk autoincr"`
|
||||
UserID int `xorm:"user_id int not null unique('uid_account') index comment('用户id')"`
|
||||
EmailAccount string `xorm:"email_account not null unique('uid_account') index comment('收信人前缀')"`
|
||||
}
|
||||
|
||||
func (p UserAuth) TableName() string {
|
||||
return "user_auth"
|
||||
}
|
||||
|
@ -8,30 +8,34 @@ import (
|
||||
)
|
||||
|
||||
type Email struct {
|
||||
Id int `db:"id" json:"id"`
|
||||
Type int8 `db:"type" json:"type"`
|
||||
GroupId int `db:"group_id" json:"group_id"`
|
||||
Subject string `db:"subject" json:"subject"`
|
||||
ReplyTo string `db:"reply_to" json:"reply_to"`
|
||||
FromName string `db:"from_name" json:"from_name"`
|
||||
FromAddress string `db:"from_address" json:"from_address"`
|
||||
To string `db:"to" json:"to"`
|
||||
Bcc string `db:"bcc" json:"bcc"`
|
||||
Cc string `db:"cc" json:"cc"`
|
||||
Text sql.NullString `db:"text" json:"text"`
|
||||
Html sql.NullString `db:"html" json:"html"`
|
||||
Sender string `db:"sender" json:"sender"`
|
||||
Attachments string `db:"attachments" json:"attachments"`
|
||||
SPFCheck int8 `db:"spf_check" json:"spf_check"`
|
||||
DKIMCheck int8 `db:"dkim_check" json:"dkim_check"`
|
||||
Status int8 `db:"status" json:"status"` // 0未发送,1已发送,2发送失败,3删除
|
||||
CronSendTime time.Time `db:"cron_send_time" json:"cron_send_time"`
|
||||
UpdateTime time.Time `db:"update_time" json:"update_time"`
|
||||
SendUserID int `db:"send_user_id" json:"send_user_id"`
|
||||
IsRead int8 `db:"is_read" json:"is_read"`
|
||||
Error sql.NullString `db:"error" json:"error"`
|
||||
SendDate time.Time `db:"send_date" json:"send_date"`
|
||||
CreateTime time.Time `db:"create_time" json:"create_time"`
|
||||
Id int `xorm:"id pk unsigned int autoincr notnull" json:"id"`
|
||||
Type int8 `xorm:"type tinyint(4) notnull default(0) comment('邮件类型,0:收到的邮件,1:发送的邮件')" json:"type"`
|
||||
GroupId int `xorm:"group_id int notnull default(0) comment('分组id')'" json:"group_id"`
|
||||
Subject string `xorm:"subject varchar(1000) notnull default('') comment('邮件标题')" json:"subject"`
|
||||
ReplyTo string `xorm:"reply_to text comment('回复人')" json:"reply_to"`
|
||||
FromName string `xorm:"from_name varchar(50) notnull default('') comment('发件人名称')" json:"from_name"`
|
||||
FromAddress string `xorm:"from_address varchar(100) notnull default('') comment('发件人邮件地址')" json:"from_address"`
|
||||
To string `xorm:"to text comment('收件人地址')" json:"to"`
|
||||
Bcc string `xorm:"bcc text comment('密送')" json:"bcc"`
|
||||
Cc string `xorm:"cc text comment('抄送')" json:"cc"`
|
||||
Text sql.NullString `xorm:"text text comment('文本内容')" json:"text"`
|
||||
Html sql.NullString `xorm:"html mediumtext comment('html内容')" json:"html"`
|
||||
Sender string `xorm:"sender text comment('发送人')" json:"sender"`
|
||||
Attachments string `xorm:"attachments longtext comment('附件')" json:"attachments"`
|
||||
SPFCheck int8 `xorm:"spf_check tinyint(1) comment('spf校验是否通过')" json:"spf_check"`
|
||||
DKIMCheck int8 `xorm:"dkim_check tinyint(1) comment('dkim校验是否通过')" json:"dkim_check"`
|
||||
Status int8 `xorm:"status tinyint(4) notnull default(0) comment('0未发送,1已发送,2发送失败,3删除')" json:"status"` // 0未发送,1已发送,2发送失败,3删除
|
||||
CronSendTime time.Time `xorm:"cron_send_time comment('定时发送时间')" json:"cron_send_time"`
|
||||
UpdateTime time.Time `xorm:"update_time updated comment('更新时间')" json:"update_time"`
|
||||
SendUserID int `xorm:"send_user_id unsigned int notnull default(0) comment('发件人用户id')" json:"send_user_id"`
|
||||
IsRead int8 `xorm:"is_read tinyint(1) comment('是否已读')" json:"is_read"`
|
||||
Error sql.NullString `xorm:"error text comment('投递错误信息')" json:"error"`
|
||||
SendDate time.Time `xorm:"send_date comment('投递时间')" json:"send_date"`
|
||||
CreateTime time.Time `xorm:"create_time created" json:"create_time"`
|
||||
}
|
||||
|
||||
func (p Email) TableName() string {
|
||||
return "email"
|
||||
}
|
||||
|
||||
type attachments struct {
|
||||
|
@ -1,8 +1,12 @@
|
||||
package models
|
||||
|
||||
type Group struct {
|
||||
ID int `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
ParentId int `db:"parent_id" json:"parent_id"`
|
||||
UserId int `db:"user_id" json:"-"`
|
||||
ID int `xorm:"id int unsigned not null pk autoincr" json:"id"`
|
||||
Name string `xorm:"varchar(10) notnull default('') comment('分组名称')" json:"name"`
|
||||
ParentId int `xorm:"parent_id int unsigned notnull default(0) comment('父分组名称')" json:"parent_id"`
|
||||
UserId int `xorm:"user_id int unsigned notnull default(0) comment('用户id')" json:"-"`
|
||||
}
|
||||
|
||||
func (p *Group) TableName() string {
|
||||
return "group"
|
||||
}
|
||||
|
@ -7,13 +7,17 @@ import (
|
||||
)
|
||||
|
||||
type Rule struct {
|
||||
Id int `db:"id" json:"id"`
|
||||
UserId string `db:"user_id" json:"user_id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Value string `db:"value" json:"value"`
|
||||
Action int `db:"action" json:"action"`
|
||||
Params string `db:"params" json:"params"`
|
||||
Sort int `db:"sort" json:"sort"`
|
||||
Id int `xorm:"id int unsigned not null pk autoincr" json:"id"`
|
||||
UserId int `xorm:"user_id notnull default(0) comment('用户id')" json:"user_id"`
|
||||
Name string `xorm:"name notnull default('') comment('规则名称')" json:"name"`
|
||||
Value string `xorm:"value text comment('规则内容')" json:"value"`
|
||||
Action int `xorm:"action notnull default(0) comment('执行动作,1已读,2转发,3删除')" json:"action"`
|
||||
Params string `xorm:"params notnull default('') comment('执行参数')" json:"params"`
|
||||
Sort int `xorm:"sort notnull default(0) comment('排序,越大约优先')" json:"sort"`
|
||||
}
|
||||
|
||||
func (p *Rule) TableName() string {
|
||||
return "rule"
|
||||
}
|
||||
|
||||
func (p *Rule) Save(ctx *context.Context) error {
|
||||
|
@ -100,7 +100,7 @@ func (a action) Pass(session *gopop.Session, pwd string) error {
|
||||
|
||||
encodePwd := password.Encode(pwd)
|
||||
|
||||
err := db.Instance.Get(&user, db.WithContext(session.Ctx.(*context.Context), "select * from user where account =? and password =?"), session.User, encodePwd)
|
||||
_, err := db.Instance.Where("account =? and password =?", session.User, encodePwd).Get(&user)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
log.WithContext(session.Ctx.(*context.Context)).Errorf("%+v", err)
|
||||
}
|
||||
@ -136,7 +136,7 @@ func (a action) Apop(session *gopop.Session, username, digest string) error {
|
||||
|
||||
var user models.User
|
||||
|
||||
err := db.Instance.Get(&user, db.WithContext(session.Ctx.(*context.Context), "select * from user where account =? "), username)
|
||||
_, err := db.Instance.Where("account =? ", username).Get(&user)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
log.WithContext(session.Ctx.(*context.Context)).Errorf("%+v", err)
|
||||
}
|
||||
@ -166,7 +166,7 @@ func (a action) Stat(session *gopop.Session) (msgNum, msgSize int64, err error)
|
||||
log.WithContext(session.Ctx).Debugf("POP3 CMD: STAT")
|
||||
|
||||
var si statInfo
|
||||
err = db.Instance.Get(&si, db.WithContext(session.Ctx.(*context.Context), "select count(1) as `num`, sum(length(text)+length(html)) as `size` from email where type = 0"))
|
||||
_, err = db.Instance.Select("count(1) as `num`, sum(length(text)+length(html)) as `size`").Table("email").Where("type=0 and status=0").Get(&si)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
log.WithContext(session.Ctx.(*context.Context)).Errorf("%+v", err)
|
||||
err = nil
|
||||
@ -197,8 +197,7 @@ func (a action) Uidl(session *gopop.Session, msg string) ([]gopop.UidlItem, erro
|
||||
var err error
|
||||
var ssql string
|
||||
|
||||
ssql = db.WithContext(session.Ctx.(*context.Context), "SELECT id FROM email where type = 0")
|
||||
err = db.Instance.Select(&res, ssql)
|
||||
err = db.Instance.Where("type=0 and status=0").Select("id").Table("email").Find(&res)
|
||||
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
log.WithContext(session.Ctx.(*context.Context)).Errorf("SQL:%s Error: %+v", ssql, err)
|
||||
@ -235,11 +234,9 @@ func (a action) List(session *gopop.Session, msg string) ([]gopop.MailInfo, erro
|
||||
var ssql string
|
||||
|
||||
if listId != 0 {
|
||||
ssql = db.WithContext(session.Ctx.(*context.Context), "SELECT id, ifnull(LENGTH(TEXT) , 0) + ifnull(LENGTH(html) , 0) AS `size` FROM email where id =?")
|
||||
err = db.Instance.Select(&res, ssql, listId)
|
||||
err = db.Instance.Select("id, ifnull(LENGTH(TEXT) , 0) + ifnull(LENGTH(html) , 0) AS `size`").Table("email").Where("id=?", listId).Find(&res)
|
||||
} else {
|
||||
ssql = db.WithContext(session.Ctx.(*context.Context), "SELECT id, ifnull(LENGTH(TEXT) , 0) + ifnull(LENGTH(html) , 0) AS `size` FROM email where type = 0")
|
||||
err = db.Instance.Select(&res, ssql)
|
||||
err = db.Instance.Select("id, ifnull(LENGTH(TEXT) , 0) + ifnull(LENGTH(html) , 0) AS `size`").Table("email").Where("type=0 and status=0").Find(&res)
|
||||
}
|
||||
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"pmail/dto/parsemail"
|
||||
"pmail/hooks"
|
||||
"pmail/http_server"
|
||||
"pmail/models"
|
||||
"pmail/pop3_server"
|
||||
"pmail/services/setup/ssl"
|
||||
"pmail/session"
|
||||
@ -37,6 +38,7 @@ func Init(serverVersion string) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
syncTables()
|
||||
session.Init()
|
||||
hooks.Init(serverVersion)
|
||||
// smtp server start
|
||||
@ -84,3 +86,26 @@ func dirInit() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func syncTables() {
|
||||
err := db.Instance.Sync2(&models.User{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = db.Instance.Sync2(&models.Email{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = db.Instance.Sync2(&models.Group{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = db.Instance.Sync2(&models.Rule{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = db.Instance.Sync2(&models.UserAuth{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ func GetAttachments(ctx *context.Context, emailId int, cid string) (string, []by
|
||||
|
||||
// 获取邮件内容
|
||||
var email models.Email
|
||||
err := db.Instance.Get(&email, db.WithContext(ctx, "select * from email where id = ?"), emailId)
|
||||
_, err := db.Instance.ID(emailId).Get(&email)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("SQL error:%+v", err)
|
||||
return "", nil
|
||||
@ -39,7 +39,7 @@ func GetAttachmentsByIndex(ctx *context.Context, emailId int, index int) (string
|
||||
|
||||
// 获取邮件内容
|
||||
var email models.Email
|
||||
err := db.Instance.Get(&email, db.WithContext(ctx, "select * from email where id = ?"), emailId)
|
||||
_, err := db.Instance.ID(emailId).Get(&email)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("SQL error:%+v", err)
|
||||
return "", nil
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
func HasAuth(ctx *context.Context, email *models.Email) bool {
|
||||
// 获取当前用户的auth
|
||||
var auth []models.UserAuth
|
||||
err := db.Instance.Select(&auth, db.WithContext(ctx, "select * from user_auth where user_id = ?"), ctx.UserID)
|
||||
err := db.Instance.Where("user_id = ?", ctx.UserID).Find(&auth)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("SQL error:%+v", err)
|
||||
return false
|
||||
|
@ -13,8 +13,10 @@ import (
|
||||
func DelEmail(ctx *context.Context, ids []int) error {
|
||||
var emails []*models.Email
|
||||
|
||||
db.Instance.Select(&emails, db.WithContext(ctx, fmt.Sprintf("select * from email where id in (%s)", array.Join(ids, ","))))
|
||||
|
||||
err := db.Instance.ID(ids).Find(&emails)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
for _, email := range emails {
|
||||
// 检查是否有权限
|
||||
hasAuth := auth.HasAuth(ctx, email)
|
||||
@ -23,8 +25,7 @@ func DelEmail(ctx *context.Context, ids []int) error {
|
||||
}
|
||||
}
|
||||
|
||||
//_, err := db.Instance.Exec(db.WithContext(ctx, fmt.Sprintf("delete from email where id in (%s)", array.Join(ids, ","))))
|
||||
_, err := db.Instance.Exec(db.WithContext(ctx, fmt.Sprintf("update email set status = 3 where id in (%s)", array.Join(ids, ","))))
|
||||
_, err = db.Instance.Exec(db.WithContext(ctx, fmt.Sprintf("update email set status = 3 where id in (%s)", array.Join(ids, ","))))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
func GetEmailDetail(ctx *context.Context, id int, markRead bool) (*models.Email, error) {
|
||||
// 获取邮件内容
|
||||
var email models.Email
|
||||
err := db.Instance.Get(&email, db.WithContext(ctx, "select * from email where id = ?"), id)
|
||||
_, err := db.Instance.ID(id).Get(&email)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("SQL error:%+v", err)
|
||||
return nil, err
|
||||
|
@ -23,10 +23,7 @@ func DelGroup(ctx *context.Context, groupId int) (bool, error) {
|
||||
allGroupIds = append(allGroupIds, groupId)
|
||||
|
||||
// 开启一个事务
|
||||
trans, err := db.Instance.Begin()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err)
|
||||
}
|
||||
trans := db.Instance.NewSession()
|
||||
|
||||
res, err := trans.Exec(db.WithContext(ctx, fmt.Sprintf("delete from `group` where id in (%s) and user_id =?", array.Join(allGroupIds, ","))), ctx.UserID)
|
||||
if err != nil {
|
||||
@ -57,7 +54,10 @@ type id struct {
|
||||
func getAllChildId(ctx *context.Context, rootId int) []int {
|
||||
var ids []id
|
||||
var ret []int
|
||||
db.Instance.Select(&ids, db.WithContext(ctx, "select id from `group` where parent_id=? and user_id=?"), rootId, ctx.UserID)
|
||||
err := db.Instance.Table("group").Where("parent_id=? and user_id=?", rootId, ctx.UserID).Find(&ids)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("getAllChildId err: %v", err)
|
||||
}
|
||||
for _, item := range ids {
|
||||
ret = array.Merge(ret, getAllChildId(ctx, item.Id))
|
||||
ret = append(ret, item.Id)
|
||||
@ -89,7 +89,7 @@ func MoveMailToGroup(ctx *context.Context, mailId []int, groupId int) bool {
|
||||
func buildChildren(ctx *context.Context, parentId int) []*GroupItem {
|
||||
var ret []*GroupItem
|
||||
var rootGroup []*models.Group
|
||||
err := db.Instance.Select(&rootGroup, db.WithContext(ctx, "select * from `group` where parent_id=? and user_id=?"), parentId, ctx.UserID)
|
||||
err := db.Instance.Table("group").Where("parent_id=? and user_id=?", parentId, ctx.UserID).Find(&rootGroup)
|
||||
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("SQL Error:%v", err)
|
||||
@ -110,6 +110,6 @@ func buildChildren(ctx *context.Context, parentId int) []*GroupItem {
|
||||
|
||||
func GetGroupList(ctx *context.Context) []*models.Group {
|
||||
var ret []*models.Group
|
||||
db.Instance.Select(&ret, db.WithContext(ctx, "select * from `group` where user_id=?"), ctx.UserID)
|
||||
db.Instance.Table("group").Where("user_id=?", ctx.UserID).Find(&ret)
|
||||
return ret
|
||||
}
|
||||
|
@ -9,17 +9,11 @@ import (
|
||||
"pmail/utils/context"
|
||||
)
|
||||
|
||||
func GetEmailList(ctx *context.Context, tag string, keyword string, offset, limit int) (emailList []*models.Email, total int) {
|
||||
func GetEmailList(ctx *context.Context, tag string, keyword string, offset, limit int) (emailList []*models.Email, total int64) {
|
||||
|
||||
querySQL, queryParams := genSQL(ctx, false, tag, keyword, offset, limit)
|
||||
counterSQL, counterParams := genSQL(ctx, true, tag, keyword, offset, limit)
|
||||
querySQL, queryParams := genSQL(ctx, tag, keyword)
|
||||
|
||||
err := db.Instance.Select(&emailList, db.WithContext(ctx, querySQL), queryParams...)
|
||||
if err != nil {
|
||||
log.Errorf("SQL ERROR: %s ,Error:%s", querySQL, err)
|
||||
}
|
||||
|
||||
err = db.Instance.Get(&total, db.WithContext(ctx, counterSQL), counterParams...)
|
||||
total, err := db.Instance.Table("email").Where(querySQL, queryParams...).Desc("id").Limit(limit, offset).FindAndCount(&emailList)
|
||||
if err != nil {
|
||||
log.Errorf("SQL ERROR: %s ,Error:%s", querySQL, err)
|
||||
}
|
||||
@ -27,12 +21,9 @@ func GetEmailList(ctx *context.Context, tag string, keyword string, offset, limi
|
||||
return
|
||||
}
|
||||
|
||||
func genSQL(ctx *context.Context, counter bool, tag, keyword string, offset, limit int) (string, []any) {
|
||||
func genSQL(ctx *context.Context, tag, keyword string) (string, []any) {
|
||||
|
||||
sql := "select * from email where 1=1 "
|
||||
if counter {
|
||||
sql = "select count(1) from email where 1=1 "
|
||||
}
|
||||
sql := "1=1 "
|
||||
|
||||
sqlParams := []any{}
|
||||
|
||||
@ -61,8 +52,5 @@ func genSQL(ctx *context.Context, counter bool, tag, keyword string, offset, lim
|
||||
sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%")
|
||||
}
|
||||
|
||||
sql += " order by id desc limit ? offset ?"
|
||||
sqlParams = append(sqlParams, limit, offset)
|
||||
|
||||
return sql, sqlParams
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ func GetAllRules(ctx *context.Context) []*dto.Rule {
|
||||
var res []*models.Rule
|
||||
var err error
|
||||
if ctx == nil || ctx.UserID == 0 {
|
||||
err = db.Instance.Select(&res, "select * from rule order by sort desc")
|
||||
err = db.Instance.Decr("sort").Find(&res)
|
||||
} else {
|
||||
err = db.Instance.Select(&res, db.WithContext(ctx, "select * from rule where user_id=? order by sort desc"), ctx.UserID)
|
||||
err = db.Instance.Where("user_id=?", ctx.UserID).Decr("sort").Find(&res)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -29,7 +29,7 @@ func GetDatabaseSettings(ctx *context.Context) (string, string, error) {
|
||||
func GetAdminPassword(ctx *context.Context) (string, error) {
|
||||
|
||||
users := []*models.User{}
|
||||
err := db.Instance.Select(&users, "select * from user")
|
||||
err := db.Instance.Find(&users)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err)
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ func Init() {
|
||||
// 使用db存储session数据,目前为了架构简单,
|
||||
// 暂不引入redis存储,如果日后性能存在瓶颈,可以将session迁移到redis
|
||||
if config.Instance.DbType == "mysql" {
|
||||
Instance.Store = mysqlstore.New(db.Instance.DB)
|
||||
Instance.Store = mysqlstore.New(db.Instance.DB().DB)
|
||||
} else {
|
||||
Instance.Store = sqlite3store.New(db.Instance.DB)
|
||||
Instance.Store = sqlite3store.New(db.Instance.DB().DB)
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ package smtp_server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"github.com/mileusna/spf"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cast"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
@ -13,6 +15,7 @@ import (
|
||||
"pmail/dto/parsemail"
|
||||
"pmail/hooks"
|
||||
"pmail/hooks/framework"
|
||||
"pmail/models"
|
||||
"pmail/services/rule"
|
||||
"pmail/utils/async"
|
||||
"pmail/utils/context"
|
||||
@ -83,12 +86,40 @@ func (s *Session) Data(r io.Reader) error {
|
||||
}
|
||||
|
||||
// 转发
|
||||
err := saveEmail(ctx, email, 1, true, true)
|
||||
err := saveEmail(ctx, email, s.Ctx.UserID, 1, true, true)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("Email Save Error %v", err)
|
||||
}
|
||||
|
||||
send.Send(ctx, email)
|
||||
errMsg := ""
|
||||
err, sendErr := send.Send(ctx, email)
|
||||
|
||||
log.WithContext(ctx).Debugf("插件执行--SendAfter")
|
||||
|
||||
as3 := async.New(ctx)
|
||||
for _, hook := range hooks.HookList {
|
||||
if hook == nil {
|
||||
continue
|
||||
}
|
||||
as3.WaitProcess(func(hk any) {
|
||||
hk.(framework.EmailHook).SendAfter(ctx, email, sendErr)
|
||||
}, hook)
|
||||
}
|
||||
as3.Wait()
|
||||
log.WithContext(ctx).Debugf("插件执行--SendAfter")
|
||||
|
||||
if err != nil {
|
||||
errMsg = err.Error()
|
||||
_, err := db.Instance.Exec(db.WithContext(ctx, "update email set status =2 ,error=? where id = ? "), errMsg, email.MessageId)
|
||||
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 = ? "), email.MessageId)
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("sql Error :%+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// 收件
|
||||
@ -121,7 +152,18 @@ func (s *Session) Data(r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
saveEmail(ctx, email, 0, SPFStatus, dkimStatus)
|
||||
// 垃圾过滤
|
||||
if config.Instance.SpamFilterLevel == 1 && !SPFStatus && !dkimStatus {
|
||||
log.WithContext(ctx).Infoln("垃圾邮件,拒信")
|
||||
return nil
|
||||
}
|
||||
|
||||
if config.Instance.SpamFilterLevel == 2 && !SPFStatus {
|
||||
log.WithContext(ctx).Infoln("垃圾邮件,拒信")
|
||||
return nil
|
||||
}
|
||||
|
||||
saveEmail(ctx, email, 0, 0, SPFStatus, dkimStatus)
|
||||
|
||||
if email.MessageId > 0 {
|
||||
log.WithContext(ctx).Debugf("开始执行邮件规则!")
|
||||
@ -152,7 +194,7 @@ func (s *Session) Data(r io.Reader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveEmail(ctx *context.Context, email *parsemail.Email, emailType int, SPFStatus, dkimStatus bool) error {
|
||||
func saveEmail(ctx *context.Context, email *parsemail.Email, sendUserID int, emailType int, SPFStatus, dkimStatus bool) error {
|
||||
var dkimV, spfV int8
|
||||
if dkimStatus {
|
||||
dkimV = 1
|
||||
@ -161,52 +203,42 @@ func saveEmail(ctx *context.Context, email *parsemail.Email, emailType int, SPFS
|
||||
spfV = 1
|
||||
}
|
||||
|
||||
// 垃圾过滤
|
||||
if config.Instance.SpamFilterLevel == 1 && !SPFStatus && !dkimStatus {
|
||||
log.WithContext(ctx).Infoln("垃圾邮件,拒信")
|
||||
return nil
|
||||
}
|
||||
|
||||
if config.Instance.SpamFilterLevel == 2 && !SPFStatus {
|
||||
log.WithContext(ctx).Infoln("垃圾邮件,拒信")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.WithContext(ctx).Debugf("开始入库!")
|
||||
|
||||
if email == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
sql := "INSERT INTO email (type, send_date, subject, reply_to, from_name, from_address, `to`, bcc, cc, text, html, sender, attachments,spf_check, dkim_check, create_time,is_read,status,group_id) VALUES (?,?,?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
res, err := db.Instance.Exec(sql,
|
||||
emailType,
|
||||
email.Date,
|
||||
email.Subject,
|
||||
json2string(email.ReplyTo),
|
||||
email.From.Name,
|
||||
email.From.EmailAddress,
|
||||
json2string(email.To),
|
||||
json2string(email.Bcc),
|
||||
json2string(email.Cc),
|
||||
email.Text,
|
||||
email.HTML,
|
||||
json2string(email.Sender),
|
||||
json2string(email.Attachments),
|
||||
spfV,
|
||||
dkimV,
|
||||
time.Now(),
|
||||
email.IsRead,
|
||||
email.Status,
|
||||
email.GroupId,
|
||||
)
|
||||
modelEmail := models.Email{
|
||||
Type: cast.ToInt8(emailType),
|
||||
GroupId: email.GroupId,
|
||||
Subject: email.Subject,
|
||||
ReplyTo: json2string(email.ReplyTo),
|
||||
FromName: email.From.Name,
|
||||
FromAddress: email.From.EmailAddress,
|
||||
To: json2string(email.To),
|
||||
Bcc: json2string(email.Bcc),
|
||||
Cc: json2string(email.Cc),
|
||||
Text: sql.NullString{String: string(email.Text), Valid: true},
|
||||
Html: sql.NullString{String: string(email.HTML), Valid: true},
|
||||
Sender: json2string(email.Sender),
|
||||
Attachments: json2string(email.Attachments),
|
||||
SPFCheck: spfV,
|
||||
DKIMCheck: dkimV,
|
||||
SendUserID: sendUserID,
|
||||
SendDate: time.Now(),
|
||||
Status: cast.ToInt8(email.Status),
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
|
||||
_, err := db.Instance.Insert(&modelEmail)
|
||||
|
||||
if err != nil {
|
||||
log.WithContext(ctx).Errorf("db insert error:%+v", err.Error())
|
||||
}
|
||||
insertId, _ := res.LastInsertId()
|
||||
if insertId > 0 {
|
||||
email.MessageId = insertId
|
||||
|
||||
if modelEmail.Id > 0 {
|
||||
email.MessageId = cast.ToInt64(modelEmail.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -81,8 +81,7 @@ func (s *Session) AuthPlain(username, pwd string) error {
|
||||
username = infos[0]
|
||||
}
|
||||
|
||||
err := db.Instance.Get(&user, db.WithContext(s.Ctx, "select * from user where account =? and password =?"),
|
||||
username, encodePwd)
|
||||
_, err := db.Instance.Where("account =? and password =?", username, encodePwd).Get(&user)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Errorf("%+v", err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user