mirror of https://gitee.com/answerdev/answer.git
feat: support admin modify smtp config
This commit is contained in:
parent
c8da6a3087
commit
41e1175620
|
@ -163,7 +163,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
||||||
reasonController := controller.NewReasonController(reasonService)
|
reasonController := controller.NewReasonController(reasonService)
|
||||||
themeController := controller_backyard.NewThemeController()
|
themeController := controller_backyard.NewThemeController()
|
||||||
siteInfoRepo := repo.NewSiteInfo(dataData)
|
siteInfoRepo := repo.NewSiteInfo(dataData)
|
||||||
siteInfoService := service.NewSiteInfoService(siteInfoRepo)
|
siteInfoService := service.NewSiteInfoService(siteInfoRepo, emailService)
|
||||||
siteInfoController := controller_backyard.NewSiteInfoController(siteInfoService)
|
siteInfoController := controller_backyard.NewSiteInfoController(siteInfoService)
|
||||||
siteinfoController := controller.NewSiteinfoController(siteInfoService)
|
siteinfoController := controller.NewSiteinfoController(siteInfoService)
|
||||||
notificationRepo := notification.NewNotificationRepo(dataData)
|
notificationRepo := notification.NewNotificationRepo(dataData)
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -4,8 +4,8 @@ go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Chain-Zhang/pinyin v0.1.3
|
github.com/Chain-Zhang/pinyin v0.1.3
|
||||||
|
github.com/anargu/gin-brotli v0.0.0-20220116052358-12bf532d5267
|
||||||
github.com/bwmarrin/snowflake v0.3.0
|
github.com/bwmarrin/snowflake v0.3.0
|
||||||
github.com/gin-contrib/gzip v0.0.6
|
|
||||||
github.com/gin-gonic/gin v1.8.1
|
github.com/gin-gonic/gin v1.8.1
|
||||||
github.com/go-playground/locales v0.14.0
|
github.com/go-playground/locales v0.14.0
|
||||||
github.com/go-playground/universal-translator v0.18.0
|
github.com/go-playground/universal-translator v0.18.0
|
||||||
|
@ -16,7 +16,6 @@ require (
|
||||||
github.com/google/wire v0.5.0
|
github.com/google/wire v0.5.0
|
||||||
github.com/jinzhu/copier v0.3.5
|
github.com/jinzhu/copier v0.3.5
|
||||||
github.com/jinzhu/now v1.1.5
|
github.com/jinzhu/now v1.1.5
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
|
||||||
github.com/lib/pq v1.10.2
|
github.com/lib/pq v1.10.2
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||||
github.com/mojocn/base64Captcha v1.3.5
|
github.com/mojocn/base64Captcha v1.3.5
|
||||||
|
@ -33,6 +32,7 @@ require (
|
||||||
github.com/swaggo/swag v1.8.6
|
github.com/swaggo/swag v1.8.6
|
||||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
|
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
|
||||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc
|
golang.org/x/net v0.0.0-20220927171203-f486391704dc
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
xorm.io/builder v0.3.12
|
xorm.io/builder v0.3.12
|
||||||
xorm.io/core v0.7.3
|
xorm.io/core v0.7.3
|
||||||
xorm.io/xorm v1.3.2
|
xorm.io/xorm v1.3.2
|
||||||
|
@ -40,7 +40,6 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/anargu/gin-brotli v0.0.0-20220116052358-12bf532d5267 // indirect
|
|
||||||
github.com/andybalholm/brotli v1.0.1 // indirect
|
github.com/andybalholm/brotli v1.0.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||||
|
@ -86,6 +85,7 @@ require (
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
golang.org/x/tools v0.1.12 // indirect
|
golang.org/x/tools v0.1.12 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -351,8 +351,6 @@ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
@ -1016,6 +1014,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@ -1026,6 +1026,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/segmentfault/answer/internal/base/translator"
|
"github.com/segmentfault/answer/internal/base/translator"
|
||||||
myErrors "github.com/segmentfault/pacman/errors"
|
myErrors "github.com/segmentfault/pacman/errors"
|
||||||
"github.com/segmentfault/pacman/i18n"
|
"github.com/segmentfault/pacman/i18n"
|
||||||
|
"github.com/segmentfault/pacman/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MyValidator my validator
|
// MyValidator my validator
|
||||||
|
@ -92,6 +93,7 @@ func (m *MyValidator) Check(value interface{}) (errField *ErrorField, err error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var valErrors validator.ValidationErrors
|
var valErrors validator.ValidationErrors
|
||||||
if !errors.As(err, &valErrors) {
|
if !errors.As(err, &valErrors) {
|
||||||
|
log.Error(err)
|
||||||
return nil, errors.New("validate check exception")
|
return nil, errors.New("validate check exception")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,3 +80,34 @@ func (sc *SiteInfoController) UpdateInterface(ctx *gin.Context) {
|
||||||
err := sc.siteInfoService.SaveSiteInterface(ctx, req)
|
err := sc.siteInfoService.SaveSiteInterface(ctx, req)
|
||||||
handler.HandleResponse(ctx, err, nil)
|
handler.HandleResponse(ctx, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSMTPConfig get smtp config
|
||||||
|
// @Summary GetSMTPConfig get smtp config
|
||||||
|
// @Description GetSMTPConfig get smtp config
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Tags admin
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} handler.RespBody{data=schema.SiteInterfaceResp}
|
||||||
|
// @Router /answer/admin/api/setting/smtp [get]
|
||||||
|
func (sc *SiteInfoController) GetSMTPConfig(ctx *gin.Context) {
|
||||||
|
resp, err := sc.siteInfoService.GetSMTPConfig(ctx)
|
||||||
|
handler.HandleResponse(ctx, err, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSMTPConfig update smtp config
|
||||||
|
// @Summary update smtp config
|
||||||
|
// @Description update smtp config
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Tags admin
|
||||||
|
// @Produce json
|
||||||
|
// @Param data body schema.SiteInterfaceReq true "general"
|
||||||
|
// @Success 200 {object} handler.RespBody{}
|
||||||
|
// @Router /answer/admin/api/setting/smtp [put]
|
||||||
|
func (sc *SiteInfoController) UpdateSMTPConfig(ctx *gin.Context) {
|
||||||
|
req := &schema.UpdateSMTPConfigReq{}
|
||||||
|
if handler.BindAndCheck(ctx, req) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := sc.siteInfoService.UpdateSMTPConfig(ctx, req)
|
||||||
|
handler.HandleResponse(ctx, err, nil)
|
||||||
|
}
|
||||||
|
|
|
@ -120,3 +120,14 @@ func (cr *configRepo) GetConfigById(id int, value any) (err error) {
|
||||||
value = json.Unmarshal([]byte(conf.(string)), value)
|
value = json.Unmarshal([]byte(conf.(string)), value)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cr *configRepo) SetConfig(key, value string) (err error) {
|
||||||
|
id := Key2IDMapping[key]
|
||||||
|
_, err = cr.data.DB.ID(id).Update(&entity.Config{Value: value})
|
||||||
|
if err != nil {
|
||||||
|
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
|
} else {
|
||||||
|
Key2ValueMapping[key] = value
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -223,4 +223,6 @@ func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) {
|
||||||
r.GET("/siteinfo/interface", a.siteInfoController.GetInterface)
|
r.GET("/siteinfo/interface", a.siteInfoController.GetInterface)
|
||||||
r.PUT("/siteinfo/general", a.siteInfoController.UpdateGeneral)
|
r.PUT("/siteinfo/general", a.siteInfoController.UpdateGeneral)
|
||||||
r.PUT("/siteinfo/interface", a.siteInfoController.UpdateInterface)
|
r.PUT("/siteinfo/interface", a.siteInfoController.UpdateInterface)
|
||||||
|
r.GET("/setting/smtp", a.siteInfoController.GetSMTPConfig)
|
||||||
|
r.PUT("/setting/smtp", a.siteInfoController.UpdateSMTPConfig)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,3 +24,25 @@ type SiteInfoResp struct {
|
||||||
General *SiteGeneralResp `json:"general"`
|
General *SiteGeneralResp `json:"general"`
|
||||||
Face *SiteInterfaceResp `json:"interface"`
|
Face *SiteInterfaceResp `json:"interface"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateSMTPConfigReq get smtp config request
|
||||||
|
type UpdateSMTPConfigReq struct {
|
||||||
|
FromEmailAddress string `validate:"omitempty,gt=0,lte=256" json:"from_email_address"`
|
||||||
|
FromName string `validate:"omitempty,gt=0,lte=256" json:"from_name"`
|
||||||
|
SMTPHost string `validate:"omitempty,gt=0,lte=256" json:"smtp_host"`
|
||||||
|
SMTPPort int `validate:"omitempty,min=1,max=65535" json:"smtp_port"`
|
||||||
|
Encryption string `validate:"omitempty,oneof=SSL" json:"encryption"` // "" SSL TLS
|
||||||
|
SMTPUsername string `validate:"omitempty,gt=0,lte=256" json:"smtp_username"`
|
||||||
|
SMTPPassword string `validate:"omitempty,gt=0,lte=256" json:"smtp_password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSMTPConfigResp get smtp config response
|
||||||
|
type GetSMTPConfigResp struct {
|
||||||
|
FromEmailAddress string `json:"from_email_address"`
|
||||||
|
FromName string `json:"from_name"`
|
||||||
|
SMTPHost string `json:"smtp_host"`
|
||||||
|
SMTPPort int `json:"smtp_port"`
|
||||||
|
Encryption string `json:"encryption"` // "" SSL TLS
|
||||||
|
SMTPUsername string `json:"smtp_username"`
|
||||||
|
SMTPPassword string `json:"smtp_password"`
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ type ConfigRepo interface {
|
||||||
GetArrayString(key string) ([]string, error)
|
GetArrayString(key string) ([]string, error)
|
||||||
GetConfigType(key string) (int, error)
|
GetConfigType(key string) (int, error)
|
||||||
GetConfigById(id int, value any) (err error)
|
GetConfigById(id int, value any) (err error)
|
||||||
|
SetConfig(key, value string) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigService user service
|
// ConfigService user service
|
||||||
|
|
|
@ -3,14 +3,14 @@ package export
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/smtp"
|
|
||||||
|
|
||||||
"github.com/jordan-wright/email"
|
"github.com/segmentfault/answer/internal/base/reason"
|
||||||
"github.com/segmentfault/answer/internal/service/config"
|
"github.com/segmentfault/answer/internal/service/config"
|
||||||
|
"github.com/segmentfault/pacman/errors"
|
||||||
"github.com/segmentfault/pacman/log"
|
"github.com/segmentfault/pacman/log"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
"gopkg.in/gomail.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EmailService kit service
|
// EmailService kit service
|
||||||
|
@ -35,18 +35,24 @@ func NewEmailService(configRepo config.ConfigRepo, emailRepo EmailRepo) *EmailSe
|
||||||
|
|
||||||
// EmailConfig email config
|
// EmailConfig email config
|
||||||
type EmailConfig struct {
|
type EmailConfig struct {
|
||||||
EmailWebName string `json:"email_web_name"`
|
FromEmailAddress string `json:"from_email_address"`
|
||||||
EmailFrom string `json:"email_from"`
|
FromName string `json:"from_name"`
|
||||||
EmailFromPass string `json:"email_from_pass"`
|
SMTPHost string `json:"smtp_host"`
|
||||||
EmailFromHostname string `json:"email_from_hostname"`
|
SMTPPort int `json:"smtp_port"`
|
||||||
EmailFromSMTP string `json:"email_from_smtp"`
|
Encryption string `json:"encryption"` // "" SSL
|
||||||
EmailFromName string `json:"email_from_name"`
|
SMTPUsername string `json:"smtp_username"`
|
||||||
EmailRegisterTitle string `json:"email_register_title"`
|
SMTPPassword string `json:"smtp_password"`
|
||||||
EmailRegisterBody string `json:"email_register_body"`
|
|
||||||
EmailPassResetTitle string `json:"email_pass_reset_title"`
|
RegisterTitle string `json:"register_title"`
|
||||||
EmailPassResetBody string `json:"email_pass_reset_body"`
|
RegisterBody string `json:"register_body"`
|
||||||
EmailChangeTitle string `json:"email_change_title"`
|
PassResetTitle string `json:"pass_reset_title"`
|
||||||
EmailChangeBody string `json:"email_change_body"`
|
PassResetBody string `json:"pass_reset_body"`
|
||||||
|
ChangeTitle string `json:"change_title"`
|
||||||
|
ChangeBody string `json:"change_body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EmailConfig) IsSSL() bool {
|
||||||
|
return e.Encryption == "SSL"
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegisterTemplateData struct {
|
type RegisterTemplateData struct {
|
||||||
|
@ -65,25 +71,28 @@ type ChangeEmailTemplateData struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send email send
|
// Send email send
|
||||||
func (es *EmailService) Send(ctx context.Context, emailAddr, title, body, code, content string) {
|
func (es *EmailService) Send(ctx context.Context, toEmailAddr, subject, body, code, codeContent string) {
|
||||||
emailClient := email.NewEmail()
|
ec, err := es.GetEmailConfig()
|
||||||
|
|
||||||
ec, err := es.getEmailConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
emailClient.From = fmt.Sprintf("%s <%s>", ec.EmailFromName, ec.EmailFrom)
|
m := gomail.NewMessage()
|
||||||
emailClient.To = []string{emailAddr}
|
m.SetHeader("From", ec.FromEmailAddress)
|
||||||
emailClient.Subject = title
|
m.SetHeader("To", toEmailAddr)
|
||||||
emailClient.HTML = []byte(body)
|
m.SetHeader("Subject", subject)
|
||||||
err = emailClient.Send(ec.EmailFromSMTP, smtp.PlainAuth("", ec.EmailFrom, ec.EmailFromPass, ec.EmailFromHostname))
|
m.SetBody("text/html", body)
|
||||||
if err != nil {
|
|
||||||
|
d := gomail.NewDialer(ec.SMTPHost, ec.SMTPPort, ec.SMTPUsername, ec.SMTPPassword)
|
||||||
|
if ec.IsSSL() {
|
||||||
|
d.SSL = true
|
||||||
|
}
|
||||||
|
if err := d.DialAndSend(m); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = es.emailRepo.SetCode(ctx, code, content)
|
err = es.emailRepo.SetCode(ctx, code, codeContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -100,13 +109,15 @@ func (es *EmailService) VerifyUrlExpired(ctx context.Context, code string) (cont
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string, err error) {
|
func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string, err error) {
|
||||||
ec, err := es.getEmailConfig()
|
ec, err := es.GetEmailConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
templateData := RegisterTemplateData{ec.EmailWebName, registerUrl}
|
templateData := RegisterTemplateData{
|
||||||
tmpl, err := template.New("register_title").Parse(ec.EmailRegisterTitle)
|
SiteName: ec.FromName, RegisterUrl: registerUrl,
|
||||||
|
}
|
||||||
|
tmpl, err := template.New("register_title").Parse(ec.RegisterTitle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
@ -117,7 +128,7 @@ func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err = template.New("register_body").Parse(ec.EmailRegisterBody)
|
tmpl, err = template.New("register_body").Parse(ec.RegisterBody)
|
||||||
err = tmpl.Execute(bodyBuf, templateData)
|
err = tmpl.Execute(bodyBuf, templateData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
@ -127,13 +138,13 @@ func (es *EmailService) RegisterTemplate(registerUrl string) (title, body string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body string, err error) {
|
func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body string, err error) {
|
||||||
ec, err := es.getEmailConfig()
|
ec, err := es.GetEmailConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
templateData := PassResetTemplateData{ec.EmailWebName, passResetUrl}
|
templateData := PassResetTemplateData{SiteName: ec.FromName, PassResetUrl: passResetUrl}
|
||||||
tmpl, err := template.New("pass_reset_title").Parse(ec.EmailPassResetTitle)
|
tmpl, err := template.New("pass_reset_title").Parse(ec.PassResetTitle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
@ -144,7 +155,7 @@ func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body stri
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err = template.New("pass_reset_body").Parse(ec.EmailPassResetBody)
|
tmpl, err = template.New("pass_reset_body").Parse(ec.PassResetBody)
|
||||||
err = tmpl.Execute(bodyBuf, templateData)
|
err = tmpl.Execute(bodyBuf, templateData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
@ -153,16 +164,16 @@ func (es *EmailService) PassResetTemplate(passResetUrl string) (title, body stri
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body string, err error) {
|
func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body string, err error) {
|
||||||
ec, err := es.getEmailConfig()
|
ec, err := es.GetEmailConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
templateData := ChangeEmailTemplateData{
|
templateData := ChangeEmailTemplateData{
|
||||||
SiteName: ec.EmailWebName,
|
SiteName: ec.FromName,
|
||||||
ChangeEmailUrl: changeEmailUrl,
|
ChangeEmailUrl: changeEmailUrl,
|
||||||
}
|
}
|
||||||
tmpl, err := template.New("email_change_title").Parse(ec.EmailChangeTitle)
|
tmpl, err := template.New("email_change_title").Parse(ec.ChangeTitle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
@ -173,7 +184,7 @@ func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, err = template.New("email_change_body").Parse(ec.EmailChangeBody)
|
tmpl, err = template.New("email_change_body").Parse(ec.ChangeBody)
|
||||||
err = tmpl.Execute(bodyBuf, templateData)
|
err = tmpl.Execute(bodyBuf, templateData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
@ -181,7 +192,7 @@ func (es *EmailService) ChangeEmailTemplate(changeEmailUrl string) (title, body
|
||||||
return titleBuf.String(), bodyBuf.String(), nil
|
return titleBuf.String(), bodyBuf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *EmailService) getEmailConfig() (ec *EmailConfig, err error) {
|
func (es *EmailService) GetEmailConfig() (ec *EmailConfig, err error) {
|
||||||
emailConf, err := es.configRepo.GetString("email.config")
|
emailConf, err := es.configRepo.GetString("email.config")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -189,7 +200,13 @@ func (es *EmailService) getEmailConfig() (ec *EmailConfig, err error) {
|
||||||
ec = &EmailConfig{}
|
ec = &EmailConfig{}
|
||||||
err = json.Unmarshal([]byte(emailConf), ec)
|
err = json.Unmarshal([]byte(emailConf), ec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
return ec, nil
|
return ec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEmailConfig set email config
|
||||||
|
func (es *EmailService) SetEmailConfig(ec *EmailConfig) (err error) {
|
||||||
|
data, _ := json.Marshal(ec)
|
||||||
|
return es.configRepo.SetConfig("email.config", string(data))
|
||||||
|
}
|
||||||
|
|
|
@ -4,20 +4,24 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
"github.com/segmentfault/answer/internal/base/reason"
|
"github.com/segmentfault/answer/internal/base/reason"
|
||||||
"github.com/segmentfault/answer/internal/entity"
|
"github.com/segmentfault/answer/internal/entity"
|
||||||
"github.com/segmentfault/answer/internal/schema"
|
"github.com/segmentfault/answer/internal/schema"
|
||||||
|
"github.com/segmentfault/answer/internal/service/export"
|
||||||
"github.com/segmentfault/answer/internal/service/siteinfo_common"
|
"github.com/segmentfault/answer/internal/service/siteinfo_common"
|
||||||
"github.com/segmentfault/pacman/errors"
|
"github.com/segmentfault/pacman/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SiteInfoService struct {
|
type SiteInfoService struct {
|
||||||
siteInfoRepo siteinfo_common.SiteInfoRepo
|
siteInfoRepo siteinfo_common.SiteInfoRepo
|
||||||
|
emailService *export.EmailService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSiteInfoService(siteInfoRepo siteinfo_common.SiteInfoRepo) *SiteInfoService {
|
func NewSiteInfoService(siteInfoRepo siteinfo_common.SiteInfoRepo, emailService *export.EmailService) *SiteInfoService {
|
||||||
return &SiteInfoService{
|
return &SiteInfoService{
|
||||||
siteInfoRepo: siteInfoRepo,
|
siteInfoRepo: siteInfoRepo,
|
||||||
|
emailService: emailService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,3 +117,22 @@ func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.Site
|
||||||
err = s.siteInfoRepo.SaveByType(ctx, siteType, &data)
|
err = s.siteInfoRepo.SaveByType(ctx, siteType, &data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSMTPConfig get smtp config
|
||||||
|
func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (
|
||||||
|
resp *schema.GetSMTPConfigResp, err error) {
|
||||||
|
emailConfig, err := s.emailService.GetEmailConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp = &schema.GetSMTPConfigResp{}
|
||||||
|
_ = copier.Copy(resp, emailConfig)
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSMTPConfig get smtp config
|
||||||
|
func (s *SiteInfoService) UpdateSMTPConfig(ctx context.Context, req *schema.UpdateSMTPConfigReq) (err error) {
|
||||||
|
ec := &export.EmailConfig{}
|
||||||
|
_ = copier.Copy(ec, req)
|
||||||
|
return s.emailService.SetEmailConfig(ec)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue