mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 自签证书增加续签功能 (#3079)
This commit is contained in:
parent
807a5071a7
commit
e41661e8d4
@ -116,3 +116,29 @@ func (b *BaseApi) ObtainWebsiteCA(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithOutData(c)
|
helper.SuccessWithOutData(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website CA
|
||||||
|
// @Summary Obtain SSL
|
||||||
|
// @Description 续签 SSL 证书
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteCAObtain true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/ca/obtain [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_cas","output_column":"name","output_value":"name"}],"formatZH":"自签 SSL 证书 [name]","formatEN":"Obtain SSL [name]"}
|
||||||
|
func (b *BaseApi) RenewWebsiteCA(c *gin.Context) {
|
||||||
|
var req request.WebsiteCARenew
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteCAService.ObtainSSL(request.WebsiteCAObtain{
|
||||||
|
SSLID: req.SSLID,
|
||||||
|
Renew: true,
|
||||||
|
Unit: "year",
|
||||||
|
Time: 1,
|
||||||
|
}); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithOutData(c)
|
||||||
|
}
|
||||||
|
@ -65,27 +65,6 @@ func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, res)
|
helper.SuccessWithData(c, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Website SSL
|
|
||||||
// @Summary Reset website ssl
|
|
||||||
// @Description 重置网站 ssl
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body request.WebsiteSSLRenew true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /websites/ssl/renew [post]
|
|
||||||
// @x-panel-log {"bodyKeys":["SSLId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"SSLId","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"重置 ssl [domain]","formatEN":"Renew ssl [domain]"}
|
|
||||||
func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) {
|
|
||||||
var req request.WebsiteSSLRenew
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := websiteSSLService.Renew(req.SSLID); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Website SSL
|
// @Tags Website SSL
|
||||||
// @Summary Apply ssl
|
// @Summary Apply ssl
|
||||||
// @Description 申请证书
|
// @Description 申请证书
|
||||||
|
@ -92,11 +92,18 @@ type WebsiteCACreate struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteCAObtain struct {
|
type WebsiteCAObtain struct {
|
||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
Domains string `json:"domains" validate:"required"`
|
Domains string `json:"domains" validate:"required"`
|
||||||
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
||||||
Time int `json:"time" validate:"required"`
|
Time int `json:"time" validate:"required"`
|
||||||
Unit string `json:"unit" validate:"required"`
|
Unit string `json:"unit" validate:"required"`
|
||||||
PushDir bool `json:"pushDir"`
|
PushDir bool `json:"pushDir"`
|
||||||
Dir string `json:"dir"`
|
Dir string `json:"dir"`
|
||||||
|
AutoRenew bool `json:"autoRenew"`
|
||||||
|
Renew bool `json:"renew"`
|
||||||
|
SSLID uint `json:"sslID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteCARenew struct {
|
||||||
|
SSLID uint `json:"SSLID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ type WebsiteSSL struct {
|
|||||||
Organization string `gorm:"type:varchar(64);not null" json:"organization"`
|
Organization string `gorm:"type:varchar(64);not null" json:"organization"`
|
||||||
DnsAccountID uint `gorm:"type:integer;not null" json:"dnsAccountId"`
|
DnsAccountID uint `gorm:"type:integer;not null" json:"dnsAccountId"`
|
||||||
AcmeAccountID uint `gorm:"type:integer;not null" json:"acmeAccountId"`
|
AcmeAccountID uint `gorm:"type:integer;not null" json:"acmeAccountId"`
|
||||||
|
CaID uint `gorm:"type:integer;not null;default:0" json:"caId"`
|
||||||
AutoRenew bool `gorm:"type:varchar(64);not null" json:"autoRenew"`
|
AutoRenew bool `gorm:"type:varchar(64);not null" json:"autoRenew"`
|
||||||
ExpireDate time.Time `json:"expireDate"`
|
ExpireDate time.Time `json:"expireDate"`
|
||||||
StartDate time.Time `json:"startDate"`
|
StartDate time.Time `json:"startDate"`
|
||||||
|
@ -14,11 +14,12 @@ type ISSLRepo interface {
|
|||||||
WithByAlias(alias string) DBOption
|
WithByAlias(alias string) DBOption
|
||||||
WithByAcmeAccountId(acmeAccountId uint) DBOption
|
WithByAcmeAccountId(acmeAccountId uint) DBOption
|
||||||
WithByDnsAccountId(dnsAccountId uint) DBOption
|
WithByDnsAccountId(dnsAccountId uint) DBOption
|
||||||
|
WithByCAID(caID uint) DBOption
|
||||||
Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error)
|
Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error)
|
||||||
GetFirst(opts ...DBOption) (model.WebsiteSSL, error)
|
GetFirst(opts ...DBOption) (*model.WebsiteSSL, error)
|
||||||
List(opts ...DBOption) ([]model.WebsiteSSL, error)
|
List(opts ...DBOption) ([]model.WebsiteSSL, error)
|
||||||
Create(ctx context.Context, ssl *model.WebsiteSSL) error
|
Create(ctx context.Context, ssl *model.WebsiteSSL) error
|
||||||
Save(ssl model.WebsiteSSL) error
|
Save(ssl *model.WebsiteSSL) error
|
||||||
DeleteBy(opts ...DBOption) error
|
DeleteBy(opts ...DBOption) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +44,12 @@ func (w WebsiteSSLRepo) WithByDnsAccountId(dnsAccountId uint) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteSSLRepo) WithByCAID(caID uint) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("ca_id = ?", caID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error) {
|
func (w WebsiteSSLRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error) {
|
||||||
var sslList []model.WebsiteSSL
|
var sslList []model.WebsiteSSL
|
||||||
db := getDb(opts...).Model(&model.WebsiteSSL{})
|
db := getDb(opts...).Model(&model.WebsiteSSL{})
|
||||||
@ -52,8 +59,8 @@ func (w WebsiteSSLRepo) Page(page, size int, opts ...DBOption) (int64, []model.W
|
|||||||
return count, sslList, err
|
return count, sslList, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) GetFirst(opts ...DBOption) (model.WebsiteSSL, error) {
|
func (w WebsiteSSLRepo) GetFirst(opts ...DBOption) (*model.WebsiteSSL, error) {
|
||||||
var website model.WebsiteSSL
|
var website *model.WebsiteSSL
|
||||||
db := getDb(opts...).Model(&model.WebsiteSSL{})
|
db := getDb(opts...).Model(&model.WebsiteSSL{})
|
||||||
if err := db.Preload("AcmeAccount").Preload("DnsAccount").First(&website).Error; err != nil {
|
if err := db.Preload("AcmeAccount").Preload("DnsAccount").First(&website).Error; err != nil {
|
||||||
return website, err
|
return website, err
|
||||||
@ -74,7 +81,7 @@ func (w WebsiteSSLRepo) Create(ctx context.Context, ssl *model.WebsiteSSL) error
|
|||||||
return getTx(ctx).Create(ssl).Error
|
return getTx(ctx).Create(ssl).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) Save(ssl model.WebsiteSSL) error {
|
func (w WebsiteSSLRepo) Save(ssl *model.WebsiteSSL) error {
|
||||||
return getDb().Save(&ssl).Error
|
return getDb().Save(&ssl).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,7 +619,7 @@ func (w WebsiteService) GetWebsiteHTTPS(websiteId uint) (response.WebsiteHTTPS,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return response.WebsiteHTTPS{}, err
|
return response.WebsiteHTTPS{}, err
|
||||||
}
|
}
|
||||||
res.SSL = websiteSSL
|
res.SSL = *websiteSSL
|
||||||
res.Enable = true
|
res.Enable = true
|
||||||
if website.HttpConfig != "" {
|
if website.HttpConfig != "" {
|
||||||
res.HttpConfig = website.HttpConfig
|
res.HttpConfig = website.HttpConfig
|
||||||
@ -648,7 +648,7 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
|||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
res response.WebsiteHTTPS
|
res response.WebsiteHTTPS
|
||||||
websiteSSL model.WebsiteSSL
|
websiteSSL *model.WebsiteSSL
|
||||||
)
|
)
|
||||||
res.Enable = req.Enable
|
res.Enable = req.Enable
|
||||||
res.SSLProtocol = req.SSLProtocol
|
res.SSLProtocol = req.SSLProtocol
|
||||||
@ -698,7 +698,7 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
website.WebsiteSSLID = websiteSSL.ID
|
website.WebsiteSSLID = websiteSSL.ID
|
||||||
res.SSL = websiteSSL
|
res.SSL = *websiteSSL
|
||||||
}
|
}
|
||||||
if req.Type == constant.SSLManual {
|
if req.Type == constant.SSLManual {
|
||||||
var (
|
var (
|
||||||
@ -758,16 +758,16 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
|||||||
websiteSSL.PrivateKey = privateKey
|
websiteSSL.PrivateKey = privateKey
|
||||||
websiteSSL.Pem = certificate
|
websiteSSL.Pem = certificate
|
||||||
|
|
||||||
res.SSL = websiteSSL
|
res.SSL = *websiteSSL
|
||||||
}
|
}
|
||||||
website.Protocol = constant.ProtocolHTTPS
|
website.Protocol = constant.ProtocolHTTPS
|
||||||
if err := applySSL(website, websiteSSL, req); err != nil {
|
if err := applySSL(website, *websiteSSL, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
website.HttpConfig = req.HttpConfig
|
website.HttpConfig = req.HttpConfig
|
||||||
|
|
||||||
if websiteSSL.ID == 0 {
|
if websiteSSL.ID == 0 {
|
||||||
if err := websiteSSLRepo.Create(ctx, &websiteSSL); err != nil {
|
if err := websiteSSLRepo.Create(ctx, websiteSSL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
website.WebsiteSSLID = websiteSSL.ID
|
website.WebsiteSSLID = websiteSSL.ID
|
||||||
|
@ -149,48 +149,78 @@ func (w WebsiteCAService) GetCA(id uint) (response.WebsiteCADTO, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteCAService) Delete(id uint) error {
|
func (w WebsiteCAService) Delete(id uint) error {
|
||||||
|
ssls, _ := websiteSSLRepo.List(websiteSSLRepo.WithByCAID(id))
|
||||||
|
if len(ssls) > 0 {
|
||||||
|
return buserr.New("ErrDeleteCAWithSSL")
|
||||||
|
}
|
||||||
return websiteCARepo.DeleteBy(commonRepo.WithByID(id))
|
return websiteCARepo.DeleteBy(commonRepo.WithByID(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
||||||
ca, err := websiteCARepo.GetFirst(commonRepo.WithByID(req.ID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
newSSL := &model.WebsiteSSL{
|
|
||||||
Provider: constant.SelfSigned,
|
|
||||||
KeyType: req.KeyType,
|
|
||||||
PushDir: req.PushDir,
|
|
||||||
}
|
|
||||||
if req.PushDir {
|
|
||||||
if !files.NewFileOp().Stat(req.Dir) {
|
|
||||||
return buserr.New(constant.ErrLinkPathNotFound)
|
|
||||||
}
|
|
||||||
newSSL.Dir = req.Dir
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
domains []string
|
domains []string
|
||||||
ips []net.IP
|
ips []net.IP
|
||||||
|
websiteSSL = &model.WebsiteSSL{}
|
||||||
|
err error
|
||||||
|
ca model.WebsiteCA
|
||||||
)
|
)
|
||||||
if req.Domains != "" {
|
if req.Renew {
|
||||||
domainArray := strings.Split(req.Domains, "\n")
|
websiteSSL, err = websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
|
||||||
for _, domain := range domainArray {
|
if err != nil {
|
||||||
if !common.IsValidDomain(domain) {
|
return err
|
||||||
err = buserr.WithName("ErrDomainFormat", domain)
|
}
|
||||||
return err
|
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(websiteSSL.CaID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
existDomains := []string{websiteSSL.PrimaryDomain}
|
||||||
|
if websiteSSL.Domains != "" {
|
||||||
|
existDomains = append(existDomains, strings.Split(websiteSSL.Domains, ",")...)
|
||||||
|
}
|
||||||
|
for _, domain := range existDomains {
|
||||||
|
if ipAddress := net.ParseIP(domain); ipAddress == nil {
|
||||||
|
domains = append(domains, domain)
|
||||||
} else {
|
} else {
|
||||||
if ipAddress := net.ParseIP(domain); ipAddress == nil {
|
ips = append(ips, ipAddress)
|
||||||
domains = append(domains, domain)
|
|
||||||
} else {
|
|
||||||
ips = append(ips, ipAddress)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(domains) > 0 {
|
} else {
|
||||||
newSSL.PrimaryDomain = domains[0]
|
ca, err = websiteCARepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||||
newSSL.Domains = strings.Join(domains[1:], ",")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
websiteSSL = &model.WebsiteSSL{
|
||||||
|
Provider: constant.SelfSigned,
|
||||||
|
KeyType: req.KeyType,
|
||||||
|
PushDir: req.PushDir,
|
||||||
|
CaID: ca.ID,
|
||||||
|
AutoRenew: req.AutoRenew,
|
||||||
|
}
|
||||||
|
if req.PushDir {
|
||||||
|
if !files.NewFileOp().Stat(req.Dir) {
|
||||||
|
return buserr.New(constant.ErrLinkPathNotFound)
|
||||||
|
}
|
||||||
|
websiteSSL.Dir = req.Dir
|
||||||
|
}
|
||||||
|
if req.Domains != "" {
|
||||||
|
domainArray := strings.Split(req.Domains, "\n")
|
||||||
|
for _, domain := range domainArray {
|
||||||
|
if !common.IsValidDomain(domain) {
|
||||||
|
err = buserr.WithName("ErrDomainFormat", domain)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
if ipAddress := net.ParseIP(domain); ipAddress == nil {
|
||||||
|
domains = append(domains, domain)
|
||||||
|
} else {
|
||||||
|
ips = append(ips, ipAddress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(domains) > 0 {
|
||||||
|
websiteSSL.PrimaryDomain = domains[0]
|
||||||
|
websiteSSL.Domains = strings.Join(domains[1:], ",")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +238,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var rootPrivateKey any
|
var rootPrivateKey any
|
||||||
if ssl.KeyType(ca.KeyType) == certcrypto.EC256 || ssl.KeyType(ca.KeyType) == certcrypto.EC384 {
|
if ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC256 || ssl.KeyType(websiteSSL.KeyType) == certcrypto.EC384 {
|
||||||
rootPrivateKey, err = x509.ParseECPrivateKey(rootPrivateKeyBlock.Bytes)
|
rootPrivateKey, err = x509.ParseECPrivateKey(rootPrivateKeyBlock.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -219,7 +249,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
interPrivateKey, interPublicKey, _, err := createPrivateKey(req.KeyType)
|
interPrivateKey, interPublicKey, _, err := createPrivateKey(websiteSSL.KeyType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -249,7 +279,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, publicKey, privateKeyBytes, err := createPrivateKey(req.KeyType)
|
_, publicKey, privateKeyBytes, err := createPrivateKey(websiteSSL.KeyType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -281,21 +311,28 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
|||||||
Bytes: cert.Raw,
|
Bytes: cert.Raw,
|
||||||
}
|
}
|
||||||
pemData := pem.EncodeToMemory(certBlock)
|
pemData := pem.EncodeToMemory(certBlock)
|
||||||
newSSL.Pem = string(pemData)
|
websiteSSL.Pem = string(pemData)
|
||||||
newSSL.PrivateKey = string(privateKeyBytes)
|
websiteSSL.PrivateKey = string(privateKeyBytes)
|
||||||
newSSL.ExpireDate = cert.NotAfter
|
websiteSSL.ExpireDate = cert.NotAfter
|
||||||
newSSL.StartDate = cert.NotBefore
|
websiteSSL.StartDate = cert.NotBefore
|
||||||
newSSL.Type = cert.Issuer.CommonName
|
websiteSSL.Type = cert.Issuer.CommonName
|
||||||
newSSL.Organization = rootCsr.Subject.Organization[0]
|
websiteSSL.Organization = rootCsr.Subject.Organization[0]
|
||||||
|
|
||||||
if err := websiteSSLRepo.Create(context.Background(), newSSL); err != nil {
|
if req.Renew {
|
||||||
return err
|
if err := websiteSSLRepo.Save(websiteSSL); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := websiteSSLRepo.Create(context.Background(), websiteSSL); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
logFile, _ := os.OpenFile(path.Join(constant.SSLLogDir, fmt.Sprintf("%s-ssl-%d.log", newSSL.PrimaryDomain, newSSL.ID)), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
|
||||||
|
logFile, _ := os.OpenFile(path.Join(constant.SSLLogDir, fmt.Sprintf("%s-ssl-%d.log", websiteSSL.PrimaryDomain, websiteSSL.ID)), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
||||||
defer logFile.Close()
|
defer logFile.Close()
|
||||||
logger := log.New(logFile, "", log.LstdFlags)
|
logger := log.New(logFile, "", log.LstdFlags)
|
||||||
logger.Println(i18n.GetMsgWithMap("ApplySSLSuccess", map[string]interface{}{"domain": strings.Join(domains, ",")}))
|
logger.Println(i18n.GetMsgWithMap("ApplySSLSuccess", map[string]interface{}{"domain": strings.Join(domains, ",")}))
|
||||||
saveCertificateFile(*newSSL, logger)
|
saveCertificateFile(websiteSSL, logger)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/i18n"
|
"github.com/1Panel-dev/1Panel/backend/i18n"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
@ -35,7 +34,6 @@ type IWebsiteSSLService interface {
|
|||||||
GetSSL(id uint) (*response.WebsiteSSLDTO, error)
|
GetSSL(id uint) (*response.WebsiteSSLDTO, error)
|
||||||
Search(req request.WebsiteSSLSearch) ([]response.WebsiteSSLDTO, error)
|
Search(req request.WebsiteSSLSearch) ([]response.WebsiteSSLDTO, error)
|
||||||
Create(create request.WebsiteSSLCreate) (request.WebsiteSSLCreate, error)
|
Create(create request.WebsiteSSLCreate) (request.WebsiteSSLCreate, error)
|
||||||
Renew(sslId uint) error
|
|
||||||
GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error)
|
GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error)
|
||||||
GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
|
GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
|
||||||
Delete(ids []uint) error
|
Delete(ids []uint) error
|
||||||
@ -72,7 +70,7 @@ func (w WebsiteSSLService) GetSSL(id uint) (*response.WebsiteSSLDTO, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
res.WebsiteSSL = websiteSSL
|
res.WebsiteSSL = *websiteSSL
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +155,7 @@ func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.Webs
|
|||||||
func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
|
func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
websiteSSL model.WebsiteSSL
|
websiteSSL *model.WebsiteSSL
|
||||||
acmeAccount *model.WebsiteAcmeAccount
|
acmeAccount *model.WebsiteAcmeAccount
|
||||||
dnsAccount *model.WebsiteDnsAccount
|
dnsAccount *model.WebsiteDnsAccount
|
||||||
)
|
)
|
||||||
@ -257,91 +255,17 @@ func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleError(websiteSSL model.WebsiteSSL, err error) {
|
func handleError(websiteSSL *model.WebsiteSSL, err error) {
|
||||||
if websiteSSL.Status == constant.SSLInit || websiteSSL.Status == constant.SSLError {
|
if websiteSSL.Status == constant.SSLInit || websiteSSL.Status == constant.SSLError {
|
||||||
websiteSSL.Status = constant.Error
|
websiteSSL.Status = constant.Error
|
||||||
} else {
|
} else {
|
||||||
websiteSSL.Status = constant.SSLApplyError
|
websiteSSL.Status = constant.SSLApplyError
|
||||||
}
|
}
|
||||||
websiteSSL.Message = err.Error()
|
websiteSSL.Message = err.Error()
|
||||||
legoLogger.Logger.Println(i18n.GetErrMsg("ApplySSLFailed", map[string]interface{}{"domain": websiteSSL.PrimaryDomain, "err": err.Error()}))
|
legoLogger.Logger.Println(i18n.GetErrMsg("ApplySSLFailed", map[string]interface{}{"domain": websiteSSL.PrimaryDomain, "detail": err.Error()}))
|
||||||
_ = websiteSSLRepo.Save(websiteSSL)
|
_ = websiteSSLRepo.Save(websiteSSL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLService) Renew(sslId uint) error {
|
|
||||||
websiteSSL, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(sslId))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(websiteSSL.AcmeAccountID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := ssl.NewAcmeClient(acmeAccount)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch websiteSSL.Provider {
|
|
||||||
case constant.DNSAccount:
|
|
||||||
dnsAccount, err := websiteDnsRepo.GetFirst(commonRepo.WithByID(websiteSSL.DnsAccountID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case constant.Http:
|
|
||||||
appInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := client.UseHTTP(path.Join(constant.AppInstallDir, constant.AppOpenresty, appInstall.Name, "root")); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case constant.SelfSigned:
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
resource, err := client.RenewSSL(websiteSSL.CertURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
websiteSSL.PrivateKey = string(resource.PrivateKey)
|
|
||||||
websiteSSL.Pem = string(resource.Certificate)
|
|
||||||
websiteSSL.CertURL = resource.CertURL
|
|
||||||
certBlock, _ := pem.Decode(resource.Certificate)
|
|
||||||
cert, err := x509.ParseCertificate(certBlock.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
websiteSSL.ExpireDate = cert.NotAfter
|
|
||||||
websiteSSL.StartDate = cert.NotBefore
|
|
||||||
websiteSSL.Type = cert.Issuer.CommonName
|
|
||||||
websiteSSL.Organization = cert.Issuer.Organization[0]
|
|
||||||
|
|
||||||
if err := websiteSSLRepo.Save(websiteSSL); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
websites, _ := websiteRepo.GetBy(websiteRepo.WithWebsiteSSLID(sslId))
|
|
||||||
for _, website := range websites {
|
|
||||||
if err := createPemFile(website, websiteSSL); err != nil {
|
|
||||||
global.LOG.Errorf("create website [%s] ssl file failed! err:%s", website.PrimaryDomain, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(websites) > 0 {
|
|
||||||
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := opNginx(nginxInstall.ContainerName, constant.NginxReload); err != nil {
|
|
||||||
return buserr.New(constant.ErrSSLApply)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteSSLService) GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error) {
|
func (w WebsiteSSLService) GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error) {
|
||||||
acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(req.AcmeAccountID))
|
acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(req.AcmeAccountID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -378,7 +302,7 @@ func (w WebsiteSSLService) GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
res.WebsiteSSL = websiteSSL
|
res.WebsiteSSL = *websiteSSL
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,9 +315,19 @@ func (w WebsiteSSLService) Delete(ids []uint) error {
|
|||||||
names = append(names, oldSSL.PrimaryDomain)
|
names = append(names, oldSSL.PrimaryDomain)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
_ = websiteSSLRepo.DeleteBy(commonRepo.WithByID(id))
|
|
||||||
}
|
}
|
||||||
|
sslSetting, _ := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
||||||
|
if sslSetting.Value == "enable" {
|
||||||
|
sslID, _ := settingRepo.Get(settingRepo.WithByKey("SSLID"))
|
||||||
|
idValue, _ := strconv.Atoi(sslID.Value)
|
||||||
|
if idValue > 0 {
|
||||||
|
oldSSL, _ := websiteSSLRepo.GetFirst(commonRepo.WithByID(uint(idValue)))
|
||||||
|
if oldSSL.ID > 0 {
|
||||||
|
return buserr.New("ErrDeleteWithPanelSSL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = websiteSSLRepo.DeleteBy(commonRepo.WithByID(id))
|
||||||
}
|
}
|
||||||
if len(names) > 0 {
|
if len(names) > 0 {
|
||||||
return buserr.WithName("ErrSSLCannotDelete", strings.Join(names, ","))
|
return buserr.WithName("ErrSSLCannotDelete", strings.Join(names, ","))
|
||||||
@ -491,7 +425,7 @@ func (w WebsiteSSLService) SyncForRestart() error {
|
|||||||
if ssl.Status == constant.SSLApply {
|
if ssl.Status == constant.SSLApply {
|
||||||
ssl.Status = constant.SystemRestart
|
ssl.Status = constant.SystemRestart
|
||||||
ssl.Message = "System restart causing interrupt"
|
ssl.Message = "System restart causing interrupt"
|
||||||
_ = websiteSSLRepo.Save(ssl)
|
_ = websiteSSLRepo.Save(&ssl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -750,7 +750,7 @@ func getWebsiteDomains(domains string, defaultPort int, websiteID uint) (domainM
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveCertificateFile(websiteSSL model.WebsiteSSL, logger *log.Logger) {
|
func saveCertificateFile(websiteSSL *model.WebsiteSSL, logger *log.Logger) {
|
||||||
if websiteSSL.PushDir {
|
if websiteSSL.PushDir {
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
var (
|
var (
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package job
|
package job
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/service"
|
"github.com/1Panel-dev/1Panel/backend/app/service"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"time"
|
"time"
|
||||||
@ -30,9 +32,25 @@ func (ssl *ssl) Run() {
|
|||||||
sub := expireDate.Sub(now)
|
sub := expireDate.Sub(now)
|
||||||
if sub.Hours() < 720 {
|
if sub.Hours() < 720 {
|
||||||
global.LOG.Errorf("Update the SSL certificate for the [%s] domain", s.PrimaryDomain)
|
global.LOG.Errorf("Update the SSL certificate for the [%s] domain", s.PrimaryDomain)
|
||||||
if err := sslService.Renew(s.ID); err != nil {
|
if s.Provider == constant.SelfSigned {
|
||||||
global.LOG.Errorf("Failed to update the SSL certificate for the [%s] domain , err:%s", s.PrimaryDomain, err.Error())
|
caService := service.NewIWebsiteCAService()
|
||||||
continue
|
if err := caService.ObtainSSL(request.WebsiteCAObtain{
|
||||||
|
ID: s.CaID,
|
||||||
|
SSLID: s.ID,
|
||||||
|
Renew: true,
|
||||||
|
Unit: "year",
|
||||||
|
Time: 1,
|
||||||
|
}); err != nil {
|
||||||
|
global.LOG.Errorf("Failed to update the SSL certificate for the [%s] domain , err:%s", s.PrimaryDomain, err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := sslService.ObtainSSL(request.WebsiteSSLApply{
|
||||||
|
ID: s.ID,
|
||||||
|
}); err != nil {
|
||||||
|
global.LOG.Errorf("Failed to update the SSL certificate for the [%s] domain , err:%s", s.PrimaryDomain, err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
global.LOG.Errorf("The SSL certificate for the [%s] domain has been successfully updated", s.PrimaryDomain)
|
global.LOG.Errorf("The SSL certificate for the [%s] domain has been successfully updated", s.PrimaryDomain)
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,8 @@ ApplySSLFailed: 'Application for [{{ .domain }}] certificate failed, {{.detail}}
|
|||||||
ApplySSLSuccess: 'Application for [{{ .domain }}] certificate successful! ! '
|
ApplySSLSuccess: 'Application for [{{ .domain }}] certificate successful! ! '
|
||||||
DNSAccountName: 'DNS account [{{ .name }}] manufacturer [{{.type}}]'
|
DNSAccountName: 'DNS account [{{ .name }}] manufacturer [{{.type}}]'
|
||||||
PushDirLog: 'Certificate pushed to directory [{{ .path }}] {{ .status }}'
|
PushDirLog: 'Certificate pushed to directory [{{ .path }}] {{ .status }}'
|
||||||
|
ErrDeleteCAWithSSL: "There is an issued certificate under the current organization and cannot be deleted"
|
||||||
|
ErrDeleteWithPanelSSL: "Panel SSL configuration uses this certificate and cannot be deleted"
|
||||||
|
|
||||||
#mysql
|
#mysql
|
||||||
ErrUserIsExist: "The current user already exists. Please enter a new user"
|
ErrUserIsExist: "The current user already exists. Please enter a new user"
|
||||||
|
@ -103,6 +103,8 @@ ApplySSLFailed: '申請 [{{ .domain }}] 憑證失敗, {{.detail}} '
|
|||||||
ApplySSLSuccess: '申請 [{{ .domain }}] 憑證成功! ! '
|
ApplySSLSuccess: '申請 [{{ .domain }}] 憑證成功! ! '
|
||||||
DNSAccountName: 'DNS 帳號 [{{ .name }}] 廠商 [{{.type}}]'
|
DNSAccountName: 'DNS 帳號 [{{ .name }}] 廠商 [{{.type}}]'
|
||||||
PushDirLog: '憑證推送到目錄 [{{ .path }}] {{ .status }}'
|
PushDirLog: '憑證推送到目錄 [{{ .path }}] {{ .status }}'
|
||||||
|
ErrDeleteCAWithSSL: "目前機構下存在已簽發證書,無法刪除"
|
||||||
|
ErrDeleteWithPanelSSL: "面板 SSL 配置使用此證書,無法刪除"
|
||||||
|
|
||||||
|
|
||||||
#mysql
|
#mysql
|
||||||
|
@ -103,6 +103,8 @@ ApplySSLFailed: '申请 [{{ .domain }}] 证书失败, {{.detail}} '
|
|||||||
ApplySSLSuccess: '申请 [{{ .domain }}] 证书成功!!'
|
ApplySSLSuccess: '申请 [{{ .domain }}] 证书成功!!'
|
||||||
DNSAccountName: 'DNS 账号 [{{ .name }}] 厂商 [{{.type}}]'
|
DNSAccountName: 'DNS 账号 [{{ .name }}] 厂商 [{{.type}}]'
|
||||||
PushDirLog: '证书推送到目录 [{{ .path }}] {{ .status }}'
|
PushDirLog: '证书推送到目录 [{{ .path }}] {{ .status }}'
|
||||||
|
ErrDeleteCAWithSSL: "当前机构下存在已签发证书,无法删除"
|
||||||
|
ErrDeleteWithPanelSSL: "面板 SSL 配置使用此证书,无法删除"
|
||||||
|
|
||||||
#mysql
|
#mysql
|
||||||
ErrUserIsExist: "当前用户已存在,请重新输入"
|
ErrUserIsExist: "当前用户已存在,请重新输入"
|
||||||
|
@ -27,7 +27,7 @@ var AddWebsiteCA = &gormigrate.Migration{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var UpdateWebsiteSSL = &gormigrate.Migration{
|
var UpdateWebsiteSSL = &gormigrate.Migration{
|
||||||
ID: "20231126-update-website-ssl",
|
ID: "20231127-update-website-ssl",
|
||||||
Migrate: func(tx *gorm.DB) error {
|
Migrate: func(tx *gorm.DB) error {
|
||||||
if err := tx.AutoMigrate(&model.WebsiteSSL{}); err != nil {
|
if err := tx.AutoMigrate(&model.WebsiteSSL{}); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -16,5 +16,6 @@ func (a *WebsiteDnsAccountRouter) InitWebsiteCARouter(Router *gin.RouterGroup) {
|
|||||||
groupRouter.POST("", baseApi.CreateWebsiteCA)
|
groupRouter.POST("", baseApi.CreateWebsiteCA)
|
||||||
groupRouter.POST("/del", baseApi.DeleteWebsiteCA)
|
groupRouter.POST("/del", baseApi.DeleteWebsiteCA)
|
||||||
groupRouter.POST("/obtain", baseApi.ObtainWebsiteCA)
|
groupRouter.POST("/obtain", baseApi.ObtainWebsiteCA)
|
||||||
|
groupRouter.POST("/renew", baseApi.RenewWebsiteCA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ func (a *WebsiteSSLRouter) InitWebsiteSSLRouter(Router *gin.RouterGroup) {
|
|||||||
baseApi := v1.ApiGroupApp.BaseApi
|
baseApi := v1.ApiGroupApp.BaseApi
|
||||||
{
|
{
|
||||||
groupRouter.POST("/search", baseApi.PageWebsiteSSL)
|
groupRouter.POST("/search", baseApi.PageWebsiteSSL)
|
||||||
groupRouter.POST("/renew", baseApi.RenewWebsiteSSL)
|
|
||||||
groupRouter.POST("", baseApi.CreateWebsiteSSL)
|
groupRouter.POST("", baseApi.CreateWebsiteSSL)
|
||||||
groupRouter.POST("/resolve", baseApi.GetDNSResolve)
|
groupRouter.POST("/resolve", baseApi.GetDNSResolve)
|
||||||
groupRouter.POST("/del", baseApi.DeleteWebsiteSSL)
|
groupRouter.POST("/del", baseApi.DeleteWebsiteSSL)
|
||||||
|
@ -11119,7 +11119,7 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "自签 SSL 证书",
|
"description": "续签 SSL 证书",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -12930,57 +12930,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/websites/ssl/renew": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "重置网站 ssl",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website SSL"
|
|
||||||
],
|
|
||||||
"summary": "Reset website ssl",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteSSLRenew"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFunctions": [
|
|
||||||
{
|
|
||||||
"db": "website_ssls",
|
|
||||||
"input_column": "id",
|
|
||||||
"input_value": "SSLId",
|
|
||||||
"isList": false,
|
|
||||||
"output_column": "primary_domain",
|
|
||||||
"output_value": "domain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"bodyKeys": [
|
|
||||||
"SSLId"
|
|
||||||
],
|
|
||||||
"formatEN": "Renew ssl [domain]",
|
|
||||||
"formatZH": "重置 ssl [domain]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/ssl/resolve": {
|
"/websites/ssl/resolve": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -17517,6 +17466,9 @@ const docTemplate = `{
|
|||||||
"autoRenew": {
|
"autoRenew": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"caId": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"certURL": {
|
"certURL": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -18979,6 +18931,9 @@ const docTemplate = `{
|
|||||||
"unit"
|
"unit"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"autoRenew": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"dir": {
|
"dir": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -19002,6 +18957,12 @@ const docTemplate = `{
|
|||||||
"pushDir": {
|
"pushDir": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"renew": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"sslID": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@ -19537,17 +19498,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request.WebsiteSSLRenew": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"SSLId"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"SSLId": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request.WebsiteSSLSearch": {
|
"request.WebsiteSSLSearch": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -11112,7 +11112,7 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "自签 SSL 证书",
|
"description": "续签 SSL 证书",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@ -12923,57 +12923,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/websites/ssl/renew": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"ApiKeyAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "重置网站 ssl",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Website SSL"
|
|
||||||
],
|
|
||||||
"summary": "Reset website ssl",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"description": "request",
|
|
||||||
"name": "request",
|
|
||||||
"in": "body",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/request.WebsiteSSLRenew"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"x-panel-log": {
|
|
||||||
"BeforeFunctions": [
|
|
||||||
{
|
|
||||||
"db": "website_ssls",
|
|
||||||
"input_column": "id",
|
|
||||||
"input_value": "SSLId",
|
|
||||||
"isList": false,
|
|
||||||
"output_column": "primary_domain",
|
|
||||||
"output_value": "domain"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"bodyKeys": [
|
|
||||||
"SSLId"
|
|
||||||
],
|
|
||||||
"formatEN": "Renew ssl [domain]",
|
|
||||||
"formatZH": "重置 ssl [domain]",
|
|
||||||
"paramKeys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/websites/ssl/resolve": {
|
"/websites/ssl/resolve": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -17510,6 +17459,9 @@
|
|||||||
"autoRenew": {
|
"autoRenew": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"caId": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"certURL": {
|
"certURL": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -18972,6 +18924,9 @@
|
|||||||
"unit"
|
"unit"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"autoRenew": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"dir": {
|
"dir": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -18995,6 +18950,12 @@
|
|||||||
"pushDir": {
|
"pushDir": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"renew": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"sslID": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@ -19530,17 +19491,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request.WebsiteSSLRenew": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"SSLId"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"SSLId": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request.WebsiteSSLSearch": {
|
"request.WebsiteSSLSearch": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -2792,6 +2792,8 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
autoRenew:
|
autoRenew:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
caId:
|
||||||
|
type: integer
|
||||||
certURL:
|
certURL:
|
||||||
type: string
|
type: string
|
||||||
createdAt:
|
createdAt:
|
||||||
@ -3770,6 +3772,8 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
request.WebsiteCAObtain:
|
request.WebsiteCAObtain:
|
||||||
properties:
|
properties:
|
||||||
|
autoRenew:
|
||||||
|
type: boolean
|
||||||
dir:
|
dir:
|
||||||
type: string
|
type: string
|
||||||
domains:
|
domains:
|
||||||
@ -3787,6 +3791,10 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
pushDir:
|
pushDir:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
renew:
|
||||||
|
type: boolean
|
||||||
|
sslID:
|
||||||
|
type: integer
|
||||||
time:
|
time:
|
||||||
type: integer
|
type: integer
|
||||||
unit:
|
unit:
|
||||||
@ -4152,13 +4160,6 @@ definitions:
|
|||||||
- primaryDomain
|
- primaryDomain
|
||||||
- provider
|
- provider
|
||||||
type: object
|
type: object
|
||||||
request.WebsiteSSLRenew:
|
|
||||||
properties:
|
|
||||||
SSLId:
|
|
||||||
type: integer
|
|
||||||
required:
|
|
||||||
- SSLId
|
|
||||||
type: object
|
|
||||||
request.WebsiteSSLSearch:
|
request.WebsiteSSLSearch:
|
||||||
properties:
|
properties:
|
||||||
acmeAccountID:
|
acmeAccountID:
|
||||||
@ -11773,7 +11774,7 @@ paths:
|
|||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 自签 SSL 证书
|
description: 续签 SSL 证书
|
||||||
parameters:
|
parameters:
|
||||||
- description: request
|
- description: request
|
||||||
in: body
|
in: body
|
||||||
@ -12904,39 +12905,6 @@ paths:
|
|||||||
formatEN: apply ssl [domain]
|
formatEN: apply ssl [domain]
|
||||||
formatZH: 申请证书 [domain]
|
formatZH: 申请证书 [domain]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
/websites/ssl/renew:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 重置网站 ssl
|
|
||||||
parameters:
|
|
||||||
- description: request
|
|
||||||
in: body
|
|
||||||
name: request
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/request.WebsiteSSLRenew'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
security:
|
|
||||||
- ApiKeyAuth: []
|
|
||||||
summary: Reset website ssl
|
|
||||||
tags:
|
|
||||||
- Website SSL
|
|
||||||
x-panel-log:
|
|
||||||
BeforeFunctions:
|
|
||||||
- db: website_ssls
|
|
||||||
input_column: id
|
|
||||||
input_value: SSLId
|
|
||||||
isList: false
|
|
||||||
output_column: primary_domain
|
|
||||||
output_value: domain
|
|
||||||
bodyKeys:
|
|
||||||
- SSLId
|
|
||||||
formatEN: Renew ssl [domain]
|
|
||||||
formatZH: 重置 ssl [domain]
|
|
||||||
paramKeys: []
|
|
||||||
/websites/ssl/resolve:
|
/websites/ssl/resolve:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
@ -165,10 +165,10 @@ export namespace Website {
|
|||||||
autoRenew: boolean;
|
autoRenew: boolean;
|
||||||
acmeAccountId?: number;
|
acmeAccountId?: number;
|
||||||
status: string;
|
status: string;
|
||||||
|
domains: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SSLDTO extends SSL {
|
export interface SSLDTO extends SSL {
|
||||||
domains: string;
|
|
||||||
logPath: string;
|
logPath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,4 +485,8 @@ export namespace Website {
|
|||||||
pushDir: boolean;
|
pushDir: boolean;
|
||||||
dir: string;
|
dir: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RenewSSLByCA {
|
||||||
|
SSLID: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,10 +124,6 @@ export const ObtainSSL = (req: Website.SSLObtain) => {
|
|||||||
return http.post<any>(`/websites/ssl/obtain`, req);
|
return http.post<any>(`/websites/ssl/obtain`, req);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RenewSSL = (req: Website.SSLRenew) => {
|
|
||||||
return http.post<any>(`/websites/ssl/renew`, req, TimeoutEnum.T_10M);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const UpdateSSL = (req: Website.SSLUpdate) => {
|
export const UpdateSSL = (req: Website.SSLUpdate) => {
|
||||||
return http.post<any>(`/websites/ssl/update`, req);
|
return http.post<any>(`/websites/ssl/update`, req);
|
||||||
};
|
};
|
||||||
@ -263,3 +259,7 @@ export const ObtainSSLByCA = (req: Website.SSLObtainByCA) => {
|
|||||||
export const DeleteCA = (req: Website.DelReq) => {
|
export const DeleteCA = (req: Website.DelReq) => {
|
||||||
return http.post<any>(`/websites/ca/del`, req);
|
return http.post<any>(`/websites/ca/del`, req);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const RenewSSLByCA = (req: Website.RenewSSLByCA) => {
|
||||||
|
return http.post<any>(`/websites/ca/renew`, req);
|
||||||
|
};
|
||||||
|
@ -37,6 +37,7 @@ interface LogProps {
|
|||||||
type: string;
|
type: string;
|
||||||
style: string;
|
style: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
tail: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
|
@ -46,6 +46,7 @@ interface LogProps {
|
|||||||
id?: number;
|
id?: number;
|
||||||
type: string;
|
type: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
tail?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -55,6 +56,7 @@ const props = defineProps({
|
|||||||
id: 0,
|
id: 0,
|
||||||
type: '',
|
type: '',
|
||||||
name: '',
|
name: '',
|
||||||
|
tail: false,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
@ -224,9 +226,16 @@ function isScrolledToBottom(element: HTMLElement): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
tailLog.value = false;
|
if (props.config.tail) {
|
||||||
|
tailLog.value = props.config.tail;
|
||||||
|
} else {
|
||||||
|
tailLog.value = false;
|
||||||
|
}
|
||||||
|
if (tailLog.value) {
|
||||||
|
changeTail(false);
|
||||||
|
}
|
||||||
getContent();
|
getContent();
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (scrollerElement.value) {
|
if (scrollerElement.value) {
|
||||||
scrollerElement.value.addEventListener('scroll', function () {
|
scrollerElement.value.addEventListener('scroll', function () {
|
||||||
|
@ -1809,12 +1809,12 @@ const message = {
|
|||||||
key: 'Private Key',
|
key: 'Private Key',
|
||||||
startDate: 'Effective Time',
|
startDate: 'Effective Time',
|
||||||
organization: 'issuing organization',
|
organization: 'issuing organization',
|
||||||
renewConfirm: 'Are you sure to renew? ',
|
renewConfirm: 'Are you sure you want to apply for a certificate for domain name {0}? ',
|
||||||
autoRenew: 'Automatic renewal',
|
autoRenew: 'Automatic renewal',
|
||||||
autoRenewHelper: 'Automatic renewal 7 days from the expiration time',
|
autoRenewHelper: 'Automatically renew 30 days before expiration',
|
||||||
renewSuccess: 'Renewal succeeded',
|
renewSuccess: 'Renewal successful',
|
||||||
renewWebsite:
|
renewWebsite:
|
||||||
'This certificate has been associated with the following websites, and the renewal will be applied to these websites simultaneously',
|
'This certificate has been associated with the following websites, and the application will be applied to these websites simultaneously',
|
||||||
createAcme: 'Create Account',
|
createAcme: 'Create Account',
|
||||||
acmeHelper: 'Acme account is used to apply for free certificates',
|
acmeHelper: 'Acme account is used to apply for free certificates',
|
||||||
upload: 'Upload Certificate',
|
upload: 'Upload Certificate',
|
||||||
|
@ -1698,11 +1698,11 @@ const message = {
|
|||||||
key: '私鑰',
|
key: '私鑰',
|
||||||
startDate: '生效時間',
|
startDate: '生效時間',
|
||||||
organization: '簽發機構',
|
organization: '簽發機構',
|
||||||
renewConfirm: '是否確定續簽?',
|
renewConfirm: '是否確定給網域名稱 {0} 申請證書? ',
|
||||||
autoRenew: '自動續簽',
|
autoRenew: '自動續簽',
|
||||||
autoRenewHelper: '距離到期時間7天自動續簽',
|
autoRenewHelper: '距離到期時間30天自動續約',
|
||||||
renewSuccess: '續簽成功',
|
renewSuccess: '續簽成功',
|
||||||
renewWebsite: '該證書已經和以下網站關聯,續簽會同步應用到這些網站',
|
renewWebsite: '該證書已經和以下網站關聯,申請會同步應用到這些網站',
|
||||||
createAcme: '創建賬戶',
|
createAcme: '創建賬戶',
|
||||||
acmeHelper: 'Acme 賬戶用於申請免費證書',
|
acmeHelper: 'Acme 賬戶用於申請免費證書',
|
||||||
upload: '上傳證書',
|
upload: '上傳證書',
|
||||||
|
@ -1698,11 +1698,11 @@ const message = {
|
|||||||
key: '私钥',
|
key: '私钥',
|
||||||
startDate: '生效时间',
|
startDate: '生效时间',
|
||||||
organization: '签发机构',
|
organization: '签发机构',
|
||||||
renewConfirm: '是否确定续签?',
|
renewConfirm: '是否确定给域名 {0} 申请证书?',
|
||||||
autoRenew: '自动续签',
|
autoRenew: '自动续签',
|
||||||
autoRenewHelper: '距离到期时间7天自动续签',
|
autoRenewHelper: '距离到期时间30天自动续签',
|
||||||
renewSuccess: '续签成功',
|
renewSuccess: '续签成功',
|
||||||
renewWebsite: '该证书已经和以下网站关联,续签会同步应用到这些网站',
|
renewWebsite: '该证书已经和以下网站关联,申请会同步应用到这些网站',
|
||||||
createAcme: '创建账户',
|
createAcme: '创建账户',
|
||||||
acmeHelper: 'Acme 账户用于申请免费证书',
|
acmeHelper: 'Acme 账户用于申请免费证书',
|
||||||
upload: '上传证书',
|
upload: '上传证书',
|
||||||
|
@ -47,7 +47,7 @@ const open = ref(false);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const dnsResolve = ref<Website.DNSResolve[]>([]);
|
const dnsResolve = ref<Website.DNSResolve[]>([]);
|
||||||
const sslID = ref(0);
|
const sslID = ref(0);
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close', 'submit']);
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
em('close', false);
|
em('close', false);
|
||||||
@ -83,6 +83,7 @@ const submit = () => {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
MsgSuccess(i18n.global.t('ssl.applyStart'));
|
MsgSuccess(i18n.global.t('ssl.applyStart'));
|
||||||
handleClose();
|
handleClose();
|
||||||
|
em('submit', sslID.value);
|
||||||
})
|
})
|
||||||
.finally(() => {});
|
.finally(() => {});
|
||||||
};
|
};
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :label="''" prop="autoRenew">
|
||||||
|
<el-checkbox v-model="obtain.autoRenew" :label="$t('ssl.autoRenew')" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item :label="''" prop="pushDir">
|
<el-form-item :label="''" prop="pushDir">
|
||||||
<el-checkbox v-model="obtain.pushDir" :label="$t('ssl.pushDir')" />
|
<el-checkbox v-model="obtain.pushDir" :label="$t('ssl.pushDir')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -93,6 +96,7 @@ const initData = () => ({
|
|||||||
unit: 'day',
|
unit: 'day',
|
||||||
pushDir: false,
|
pushDir: false,
|
||||||
dir: '',
|
dir: '',
|
||||||
|
autoRenew: true,
|
||||||
});
|
});
|
||||||
const obtain = ref(initData());
|
const obtain = ref(initData());
|
||||||
|
|
||||||
|
@ -96,7 +96,9 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('website.log')" width="100px">
|
<el-table-column :label="$t('website.log')" width="100px">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button>
|
<el-button @click="openLog(row.id)" link type="primary">
|
||||||
|
{{ $t('website.check') }}
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
@ -108,11 +110,7 @@
|
|||||||
<el-table-column :label="$t('ssl.autoRenew')" fix width="100px">
|
<el-table-column :label="$t('ssl.autoRenew')" fix width="100px">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-switch
|
<el-switch
|
||||||
:disabled="
|
:disabled="row.provider === 'dnsManual' || row.provider === 'manual'"
|
||||||
row.provider === 'dnsManual' ||
|
|
||||||
row.provider === 'manual' ||
|
|
||||||
row.provider === 'selfSigned'
|
|
||||||
"
|
|
||||||
v-model="row.autoRenew"
|
v-model="row.autoRenew"
|
||||||
@change="updateConfig(row)"
|
@change="updateConfig(row)"
|
||||||
/>
|
/>
|
||||||
@ -138,10 +136,11 @@
|
|||||||
<Create ref="sslCreateRef" @close="search()"></Create>
|
<Create ref="sslCreateRef" @close="search()"></Create>
|
||||||
<Detail ref="detailRef"></Detail>
|
<Detail ref="detailRef"></Detail>
|
||||||
<SSLUpload ref="sslUploadRef" @close="search()"></SSLUpload>
|
<SSLUpload ref="sslUploadRef" @close="search()"></SSLUpload>
|
||||||
<Apply ref="applyRef" @search="search" />
|
<Apply ref="applyRef" @search="search" @submit="openLog" />
|
||||||
<OpDialog ref="opRef" @search="search" @cancel="search" />
|
<OpDialog ref="opRef" @search="search" @cancel="search" />
|
||||||
<Log ref="logRef" @close="search()" />
|
<Log ref="logRef" @close="search()" />
|
||||||
<CA ref="caRef" @close="search()" />
|
<CA ref="caRef" @close="search()" />
|
||||||
|
<Obtain ref="obtainRef" @close="search()" @submit="openLog" />
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -149,7 +148,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, reactive, ref, computed } from 'vue';
|
import { onMounted, reactive, ref, computed } from 'vue';
|
||||||
import OpDialog from '@/components/del-dialog/index.vue';
|
import OpDialog from '@/components/del-dialog/index.vue';
|
||||||
import { DeleteSSL, ObtainSSL, SearchSSL, UpdateSSL } from '@/api/modules/website';
|
import { DeleteSSL, SearchSSL, UpdateSSL } from '@/api/modules/website';
|
||||||
import DnsAccount from './dns-account/index.vue';
|
import DnsAccount from './dns-account/index.vue';
|
||||||
import AcmeAccount from './acme-account/index.vue';
|
import AcmeAccount from './acme-account/index.vue';
|
||||||
import CA from './ca/index.vue';
|
import CA from './ca/index.vue';
|
||||||
@ -163,6 +162,7 @@ import { GlobalStore } from '@/store';
|
|||||||
import SSLUpload from './upload/index.vue';
|
import SSLUpload from './upload/index.vue';
|
||||||
import Apply from './apply/index.vue';
|
import Apply from './apply/index.vue';
|
||||||
import Log from '@/components/log-dialog/index.vue';
|
import Log from '@/components/log-dialog/index.vue';
|
||||||
|
import Obtain from './obtain/index.vue';
|
||||||
|
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
const paginationConfig = reactive({
|
const paginationConfig = reactive({
|
||||||
@ -183,6 +183,7 @@ const applyRef = ref();
|
|||||||
const logRef = ref();
|
const logRef = ref();
|
||||||
const caRef = ref();
|
const caRef = ref();
|
||||||
let selects = ref<any>([]);
|
let selects = ref<any>([]);
|
||||||
|
const obtainRef = ref();
|
||||||
|
|
||||||
const routerButton = [
|
const routerButton = [
|
||||||
{
|
{
|
||||||
@ -204,7 +205,7 @@ const buttons = [
|
|||||||
{
|
{
|
||||||
label: i18n.global.t('ssl.apply'),
|
label: i18n.global.t('ssl.apply'),
|
||||||
disabled: function (row: Website.SSLDTO) {
|
disabled: function (row: Website.SSLDTO) {
|
||||||
return row.status === 'applying' || row.provider === 'manual' || row.provider === 'selfSigned';
|
return row.status === 'applying' || row.provider === 'manual';
|
||||||
},
|
},
|
||||||
click: function (row: Website.SSLDTO) {
|
click: function (row: Website.SSLDTO) {
|
||||||
if (row.provider === 'dnsManual') {
|
if (row.provider === 'dnsManual') {
|
||||||
@ -268,23 +269,16 @@ const openUpload = () => {
|
|||||||
const openDetail = (id: number) => {
|
const openDetail = (id: number) => {
|
||||||
detailRef.value.acceptParams(id);
|
detailRef.value.acceptParams(id);
|
||||||
};
|
};
|
||||||
const openLog = (row: Website.SSLDTO) => {
|
const openLog = (id: number) => {
|
||||||
logRef.value.acceptParams({ id: row.id, type: 'ssl' });
|
logRef.value.acceptParams({ id: id, type: 'ssl', tail: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
const openCA = () => {
|
const openCA = () => {
|
||||||
caRef.value.acceptParams();
|
caRef.value.acceptParams();
|
||||||
};
|
};
|
||||||
|
|
||||||
const applySSL = (row: Website.SSLDTO) => {
|
const applySSL = (row: Website.SSLDTO) => {
|
||||||
loading.value = true;
|
obtainRef.value.acceptParams({ ssl: row });
|
||||||
ObtainSSL({ ID: row.id })
|
|
||||||
.then(() => {
|
|
||||||
MsgSuccess(i18n.global.t('ssl.applyStart'));
|
|
||||||
search();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteSSL = async (row: any) => {
|
const deleteSSL = async (row: any) => {
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="open"
|
v-model="open"
|
||||||
:title="$t('website.renewSSL')"
|
:title="$t('ssl.apply')"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
width="30%"
|
width="30%"
|
||||||
:before-close="handleClose"
|
:before-close="handleClose"
|
||||||
>
|
>
|
||||||
<div style="text-align: center" v-loading="loading">
|
<div class="text-center" v-loading="loading">
|
||||||
<div v-if="websites.length > 0">
|
<div v-if="ssl.websites && ssl.websites.length > 0">
|
||||||
<span>{{ $t('ssl.renewWebsite') }}</span>
|
<span>{{ $t('ssl.renewWebsite') }}</span>
|
||||||
<div>
|
<div>
|
||||||
<br />
|
<br />
|
||||||
<span>
|
<span>
|
||||||
<span v-for="(website, index) in websites" :key="index">
|
<span v-for="(website, index) in ssl.websites" :key="index">
|
||||||
<el-tag>{{ website.primaryDomain }}</el-tag>
|
<el-tag>{{ website.primaryDomain }}</el-tag>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<span>{{ $t('ssl.renewConfirm') }}</span>
|
<span>{{ $t('ssl.renewConfirm', [ssl.primaryDomain]) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
@ -35,44 +35,42 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Website } from '@/api/interface/website';
|
import { Website } from '@/api/interface/website';
|
||||||
import { RenewSSL } from '@/api/modules/website';
|
import { ObtainSSL, RenewSSLByCA } from '@/api/modules/website';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { reactive, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
interface RenewProps {
|
interface RenewProps {
|
||||||
id: number;
|
ssl: Website.SSL;
|
||||||
websites: Website.Website[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let open = ref(false);
|
const open = ref(false);
|
||||||
let loading = ref(false);
|
const loading = ref(false);
|
||||||
let renewReq = reactive({
|
const em = defineEmits(['close', 'submit']);
|
||||||
SSLId: 0,
|
|
||||||
});
|
|
||||||
const em = defineEmits(['close']);
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
em('close', false);
|
em('close', false);
|
||||||
};
|
};
|
||||||
const websites = ref([]);
|
const ssl = ref();
|
||||||
|
|
||||||
const acceptParams = async (props: RenewProps) => {
|
const acceptParams = async (props: RenewProps) => {
|
||||||
renewReq.SSLId = Number(props.id);
|
ssl.value = props.ssl;
|
||||||
websites.value = props.websites;
|
|
||||||
open.value = true;
|
open.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const submit = () => {
|
const submit = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
RenewSSL(renewReq)
|
try {
|
||||||
.then(() => {
|
if (ssl.value.provider == 'selfSigned') {
|
||||||
handleClose();
|
await RenewSSLByCA({ SSLID: ssl.value.id });
|
||||||
MsgSuccess(i18n.global.t('ssl.renewSuccess'));
|
} else {
|
||||||
})
|
await ObtainSSL({ ID: ssl.value.id });
|
||||||
.finally(() => {
|
}
|
||||||
loading.value = false;
|
handleClose();
|
||||||
});
|
MsgSuccess(i18n.global.t('ssl.applyStart'));
|
||||||
|
loading.value = false;
|
||||||
|
em('submit', ssl.value.id);
|
||||||
|
} catch (error) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
Loading…
x
Reference in New Issue
Block a user