140 lines
4.1 KiB
Go
140 lines
4.1 KiB
Go
package models
|
||
|
||
import (
|
||
"database/sql"
|
||
"time"
|
||
|
||
"mengpost-backend/database"
|
||
)
|
||
|
||
// Account 邮箱账户(basic 为密码;oauth_microsoft 使用刷新令牌).
|
||
type Account struct {
|
||
ID int64 `json:"id"`
|
||
Name string `json:"name"`
|
||
Email string `json:"email"`
|
||
Password string `json:"password,omitempty"`
|
||
SMTPHost string `json:"smtp_host"`
|
||
SMTPPort int `json:"smtp_port"`
|
||
IMAPHost string `json:"imap_host"`
|
||
IMAPPort int `json:"imap_port"`
|
||
UseTLS bool `json:"use_tls"`
|
||
AuthType string `json:"auth_type"`
|
||
OAuthRefreshToken string `json:"-"`
|
||
CreatedAt time.Time `json:"created_at"`
|
||
}
|
||
|
||
func readAuthType(ns sql.NullString) string {
|
||
if ns.Valid && ns.String != "" {
|
||
return ns.String
|
||
}
|
||
return AuthTypeBasic
|
||
}
|
||
|
||
func ListAccounts() ([]Account, error) {
|
||
rows, err := database.DB.Query(`
|
||
SELECT id,name,email,smtp_host,smtp_port,imap_host,imap_port,use_tls,
|
||
IFNULL(auth_type,'basic'), created_at
|
||
FROM accounts ORDER BY id DESC`)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
defer rows.Close()
|
||
var out []Account
|
||
for rows.Next() {
|
||
var a Account
|
||
var tls int
|
||
var authType sql.NullString
|
||
if err := rows.Scan(&a.ID, &a.Name, &a.Email, &a.SMTPHost, &a.SMTPPort, &a.IMAPHost, &a.IMAPPort, &tls, &authType, &a.CreatedAt); err != nil {
|
||
return nil, err
|
||
}
|
||
a.UseTLS = tls == 1
|
||
a.AuthType = readAuthType(authType)
|
||
out = append(out, a)
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
func scanFullAccount(row *sql.Row) (*Account, error) {
|
||
var a Account
|
||
var tls int
|
||
var authType, oauthRefresh sql.NullString
|
||
err := row.Scan(&a.ID, &a.Name, &a.Email, &a.Password, &a.SMTPHost, &a.SMTPPort, &a.IMAPHost, &a.IMAPPort, &tls, &authType, &oauthRefresh, &a.CreatedAt)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
a.UseTLS = tls == 1
|
||
a.AuthType = readAuthType(authType)
|
||
if oauthRefresh.Valid {
|
||
a.OAuthRefreshToken = oauthRefresh.String
|
||
}
|
||
return &a, nil
|
||
}
|
||
|
||
func GetAccount(id int64) (*Account, error) {
|
||
row := database.DB.QueryRow(`
|
||
SELECT id,name,email,password,smtp_host,smtp_port,imap_host,imap_port,use_tls,
|
||
IFNULL(auth_type,'basic'), oauth_refresh_token, created_at
|
||
FROM accounts WHERE id=?`, id)
|
||
return scanFullAccount(row)
|
||
}
|
||
|
||
func GetAccountByEmail(email string) (*Account, error) {
|
||
row := database.DB.QueryRow(`
|
||
SELECT id,name,email,password,smtp_host,smtp_port,imap_host,imap_port,use_tls,
|
||
IFNULL(auth_type,'basic'), oauth_refresh_token, created_at
|
||
FROM accounts WHERE email=?`, email)
|
||
return scanFullAccount(row)
|
||
}
|
||
|
||
func CreateAccount(a *Account) error {
|
||
if a.AuthType == "" {
|
||
a.AuthType = AuthTypeBasic
|
||
}
|
||
tls := 0
|
||
if a.UseTLS {
|
||
tls = 1
|
||
}
|
||
var oauth any
|
||
if a.OAuthRefreshToken != "" {
|
||
oauth = a.OAuthRefreshToken
|
||
}
|
||
res, err := database.DB.Exec(
|
||
`INSERT INTO accounts(name,email,password,smtp_host,smtp_port,imap_host,imap_port,use_tls,auth_type,oauth_refresh_token)
|
||
VALUES(?,?,?,?,?,?,?,?,?,?)`,
|
||
a.Name, a.Email, a.Password, a.SMTPHost, a.SMTPPort, a.IMAPHost, a.IMAPPort, tls, a.AuthType, oauth,
|
||
)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
id, _ := res.LastInsertId()
|
||
a.ID = id
|
||
return nil
|
||
}
|
||
|
||
func UpdateAccount(a *Account) error {
|
||
tls := 0
|
||
if a.UseTLS {
|
||
tls = 1
|
||
}
|
||
if a.AuthType == "" {
|
||
a.AuthType = AuthTypeBasic
|
||
}
|
||
_, err := database.DB.Exec(
|
||
`UPDATE accounts SET name=?,email=?,password=COALESCE(NULLIF(?, ''), password),smtp_host=?,smtp_port=?,imap_host=?,imap_port=?,use_tls=?,auth_type=?,
|
||
oauth_refresh_token=COALESCE(NULLIF(?, ''), oauth_refresh_token) WHERE id=?`,
|
||
a.Name, a.Email, a.Password, a.SMTPHost, a.SMTPPort, a.IMAPHost, a.IMAPPort, tls, a.AuthType,
|
||
a.OAuthRefreshToken, a.ID,
|
||
)
|
||
return err
|
||
}
|
||
|
||
func UpdateAccountOAuthRefresh(id int64, refresh string) error {
|
||
_, err := database.DB.Exec(`UPDATE accounts SET oauth_refresh_token=? WHERE id=?`, refresh, id)
|
||
return err
|
||
}
|
||
|
||
func DeleteAccount(id int64) error {
|
||
_, err := database.DB.Exec(`DELETE FROM accounts WHERE id=?`, id)
|
||
return err
|
||
}
|