diff --git a/backend/app/api/v1/website_ssl.go b/backend/app/api/v1/website_ssl.go index be42f49f8..2a5e3f78f 100644 --- a/backend/app/api/v1/website_ssl.go +++ b/backend/app/api/v1/website_ssl.go @@ -38,6 +38,19 @@ func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) { helper.SuccessWithData(c, res) } +func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) { + var req dto.WebsiteSSLRenew + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := websiteSSLService.Renew(req.SSLID); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, nil) +} + func (b *BaseApi) ApplyWebsiteSSL(c *gin.Context) { var req dto.WebsiteSSLApply if err := c.ShouldBindJSON(&req); err != nil { @@ -73,10 +86,24 @@ func (b *BaseApi) DeleteWebsiteSSL(c *gin.Context) { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - if err := websiteSSLService.Delete(id); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } helper.SuccessWithData(c, nil) } + +func (b *BaseApi) GetWebsiteSSL(c *gin.Context) { + + websiteId, err := helper.GetIntParamByKey(c, "websiteId") + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + websiteSSL, err := websiteSSLService.GetWebsiteSSL(websiteId) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, websiteSSL) +} diff --git a/backend/app/dto/website_ssl.go b/backend/app/dto/website_ssl.go index ae3cc93df..06160ff13 100644 --- a/backend/app/dto/website_ssl.go +++ b/backend/app/dto/website_ssl.go @@ -10,15 +10,15 @@ type SSLProvider string const ( DNSAccount = "dnsAccount" - DnsCommon = "dnsCommon" + DnsManual = "dnsManual" Http = "http" ) type WebsiteSSLCreate struct { - Domains []string `json:"domains" validate:"required"` + PrimaryDomain string `json:"primaryDomain" validate:"required"` + OtherDomains string `json:"otherDomains"` Provider SSLProvider `json:"provider" validate:"required"` - WebsiteID uint `json:"websiteId" validate:"required"` - AcmeAccountID uint `json:"acmeAccountId"` + AcmeAccountID uint `json:"acmeAccountId" validate:"required"` DnsAccountID uint `json:"dnsAccountId"` } @@ -37,3 +37,7 @@ type WebsiteDNSRes struct { Value string `json:"value"` Type string `json:"type"` } + +type WebsiteSSLRenew struct { + SSLID uint `json:"SSLId" validate:"required"` +} diff --git a/backend/app/model/website_ssl.go b/backend/app/model/website_ssl.go index 1e17743ef..3afafcc06 100644 --- a/backend/app/model/website_ssl.go +++ b/backend/app/model/website_ssl.go @@ -4,16 +4,18 @@ import "time" type WebSiteSSL struct { BaseModel - Alias string `gorm:"type:varchar(64);not null" json:"alias"` - PrivateKey string `gorm:"type:longtext;not null" json:"privateKey"` - Pem string `gorm:"type:longtext;not null" json:"pem"` - Domain string `gorm:"type:varchar(256);not null" json:"domain"` - CertURL string `gorm:"type:varchar(256);not null" json:"certURL"` - Type string `gorm:"type:varchar(64);not null" json:"type"` - IssuerName string `gorm:"type:varchar(64);not null" json:"issuerName"` - DnsAccountID uint `gorm:"type:integer;not null" json:"dnsAccountId"` - ExpireDate time.Time `json:"expireDate"` - StartDate time.Time `json:"startDate"` + PrimaryDomain string `gorm:"type:varchar(256);not null" json:"primaryDomain"` + PrivateKey string `gorm:"type:longtext;not null" json:"privateKey"` + Pem string `gorm:"type:longtext;not null" json:"pem"` + Domains string `gorm:"type:varchar(256);not null" json:"domains"` + CertURL string `gorm:"type:varchar(256);not null" json:"certURL"` + Type string `gorm:"type:varchar(64);not null" json:"type"` + Provider string `gorm:"type:varchar(64);not null" json:"provider"` + Organization string `gorm:"type:varchar(64);not null" json:"organization"` + DnsAccountID uint `gorm:"type:integer;not null" json:"dnsAccountId"` + AcmeAccountID uint `gorm:"type:integer;not null" json:"acmeAccountId"` + ExpireDate time.Time `json:"expireDate"` + StartDate time.Time `json:"startDate"` } func (w WebSiteSSL) TableName() string { diff --git a/backend/app/service/website_ssl.go b/backend/app/service/website_ssl.go index 8aac0a664..d42a79da0 100644 --- a/backend/app/service/website_ssl.go +++ b/backend/app/service/website_ssl.go @@ -3,6 +3,7 @@ package service import ( "context" "crypto/x509" + "encoding/pem" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/utils/ssl" @@ -31,48 +32,59 @@ func (w WebSiteSSLService) Create(create dto.WebsiteSSLCreate) (dto.WebsiteSSLCr if err != nil { return res, err } - dnsAccount, err := websiteDnsRepo.GetFirst(commonRepo.WithByID(create.DnsAccountID)) - if err != nil { - return res, err - } + client, err := ssl.NewPrivateKeyClient(acmeAccount.Email, acmeAccount.PrivateKey) if err != nil { return res, err } - if create.Provider == dto.Http { - } else { + switch create.Provider { + case dto.DNSAccount: + dnsAccount, err := websiteDnsRepo.GetFirst(commonRepo.WithByID(create.DnsAccountID)) + + if err != nil { + return res, err + } + if err := client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization); err != nil { return res, err } + case dto.Http: + case dto.DnsManual: + } - resource, err := client.GetSSL(create.Domains) + domains := []string{create.PrimaryDomain} + otherDomainArray := strings.Split(create.OtherDomains, "\n") + if create.OtherDomains != "" { + domains = append(otherDomainArray, domains...) + } + resource, err := client.ObtainSSL(domains) if err != nil { return res, err } - var websiteSSL model.WebSiteSSL - - //TODO 判断同一个账号下的证书 - websiteSSL.Alias = create.Domains[0] - websiteSSL.Domain = strings.Join(create.Domains, ",") + websiteSSL.DnsAccountID = create.DnsAccountID + websiteSSL.AcmeAccountID = acmeAccount.ID + websiteSSL.Provider = string(create.Provider) + websiteSSL.Domains = strings.Join(otherDomainArray, ",") + websiteSSL.PrimaryDomain = create.PrimaryDomain websiteSSL.PrivateKey = string(resource.PrivateKey) websiteSSL.Pem = string(resource.Certificate) websiteSSL.CertURL = resource.CertURL - - cert, err := x509.ParseCertificate([]byte(websiteSSL.Pem)) + certBlock, _ := pem.Decode(resource.Certificate) + cert, err := x509.ParseCertificate(certBlock.Bytes) if err != nil { return dto.WebsiteSSLCreate{}, err } websiteSSL.ExpireDate = cert.NotAfter websiteSSL.StartDate = cert.NotBefore websiteSSL.Type = cert.Issuer.CommonName - websiteSSL.IssuerName = cert.Issuer.Organization[0] + websiteSSL.Organization = cert.Issuer.Organization[0] - if err := createPemFile(websiteSSL); err != nil { - return dto.WebsiteSSLCreate{}, err - } + //if err := createPemFile(websiteSSL); err != nil { + // return dto.WebsiteSSLCreate{}, err + //} if err := websiteSSLRepo.Create(context.TODO(), &websiteSSL); err != nil { return res, err @@ -81,6 +93,55 @@ func (w WebSiteSSLService) Create(create dto.WebsiteSSLCreate) (dto.WebsiteSSLCr return create, nil } +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.NewPrivateKeyClient(acmeAccount.Email, acmeAccount.PrivateKey) + if err != nil { + return err + } + switch websiteSSL.Provider { + case dto.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 dto.Http: + case dto.DnsManual: + + } + + 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] + + return websiteSSLRepo.Save(websiteSSL) +} + func (w WebSiteSSLService) Apply(apply dto.WebsiteSSLApply) (dto.WebsiteSSLApply, error) { websiteSSL, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(apply.SSLID)) if err != nil { @@ -96,10 +157,10 @@ func (w WebSiteSSLService) Apply(apply dto.WebsiteSSLApply) (dto.WebsiteSSLApply nginxParams := getNginxParamsFromStaticFile(dto.SSL) for i, param := range nginxParams { if param.Name == "ssl_certificate" { - nginxParams[i].Params = []string{path.Join("/etc/nginx/ssl", websiteSSL.Alias, "fullchain.pem")} + nginxParams[i].Params = []string{path.Join("/etc/nginx/ssl", websiteSSL.PrimaryDomain, "fullchain.pem")} } if param.Name == "ssl_certificate_key" { - nginxParams[i].Params = []string{path.Join("/etc/nginx/ssl", websiteSSL.Alias, "privkey.pem")} + nginxParams[i].Params = []string{path.Join("/etc/nginx/ssl", websiteSSL.PrimaryDomain, "privkey.pem")} } } if err := updateNginxConfig(website, nginxParams, dto.SSL); err != nil { @@ -134,6 +195,20 @@ func (w WebSiteSSLService) GetDNSResolve(req dto.WebsiteDNSReq) (dto.WebsiteDNSR return res, nil } +func (w WebSiteSSLService) GetWebsiteSSL(websiteId uint) (dto.WebsiteSSLDTO, error) { + var res dto.WebsiteSSLDTO + website, err := websiteRepo.GetFirst(commonRepo.WithByID(websiteId)) + if err != nil { + return res, err + } + websiteSSL, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(website.WebSiteSSLID)) + if err != nil { + return res, err + } + res.WebSiteSSL = websiteSSL + return res, nil +} + func (w WebSiteSSLService) Delete(id uint) error { return websiteSSLRepo.DeleteBy(commonRepo.WithByID(id)) } diff --git a/backend/app/service/website_utils.go b/backend/app/service/website_utils.go index 74dd5c572..1b00e3bbc 100644 --- a/backend/app/service/website_utils.go +++ b/backend/app/service/website_utils.go @@ -318,7 +318,7 @@ func createPemFile(websiteSSL model.WebSiteSSL) error { return err } - configDir := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "ssl", websiteSSL.Alias) + configDir := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "ssl", websiteSSL.PrimaryDomain) fileOp := files.NewFileOp() if !fileOp.Stat(configDir) { diff --git a/backend/router/ro_website_ssl.go b/backend/router/ro_website_ssl.go index d337ab955..e3cf0fdf3 100644 --- a/backend/router/ro_website_ssl.go +++ b/backend/router/ro_website_ssl.go @@ -16,9 +16,11 @@ func (a *WebsiteSSLRouter) InitWebsiteSSLRouter(Router *gin.RouterGroup) { baseApi := v1.ApiGroupApp.BaseApi { groupRouter.POST("/search", baseApi.PageWebsiteSSL) + groupRouter.POST("/renew", baseApi.RenewWebsiteSSL) groupRouter.POST("", baseApi.CreateWebsiteSSL) groupRouter.POST("/apply", baseApi.ApplyWebsiteSSL) groupRouter.POST("/resolve", baseApi.GetDNSResolve) - groupRouter.POST("/:id", baseApi.DeleteWebsiteSSL) + groupRouter.DELETE("/:id", baseApi.DeleteWebsiteSSL) + groupRouter.GET("/:websiteId", baseApi.GetWebsiteSSL) } } diff --git a/backend/server/server.go b/backend/server/server.go index 2d4f0b56a..f559ebabf 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -51,7 +51,7 @@ type server interface { func initServer(address string, router *gin.Engine) server { s := endless.NewServer(address, router) s.ReadHeaderTimeout = 20 * time.Second - s.WriteTimeout = 20 * time.Second + s.WriteTimeout = 60 * time.Second s.MaxHeaderBytes = 1 << 20 return s } diff --git a/backend/utils/nginx/private.key b/backend/utils/nginx/private.key index 0827a95e3..631b12085 100644 --- a/backend/utils/nginx/private.key +++ b/backend/utils/nginx/private.key @@ -1,27 +1,27 @@ -----BEGIN privateKey----- -MIIEpAIBAAKCAQEAk+3c1uehn2/YRZI/GVUb0mM51OxGTyiGtaVp9rCCMx9ajvgN -eVkF+yBqd7C3B2doKUe4Nprl0j1w3mM1Ol0FisqBjOm7DNq212//CtyjCYrbmCDE -DNXDI+3k7SImPGxDoCRQl/4rcRSZGAJe/BdW3U70UZU5203B8AWf5c8basWaB4gU -3rGK08f6qqQRGkoEL5W+b5LHxJO1xNrFDdRh0Qi3hzl8c5fIcqCgSQikyGoCSSLh -deoiCxl2ASuJ9xgbr7MLP5oN68T5AXduhbo87bsuweKxwe2D0XlM1PbfUGismqjR -zD/rPa0QRnRis5e0qxyyi5I8lmODa0kn6tAFsQIDAQABAoIBABCj1Q+nhpq0rhNF -XCuxUyvbVYoJ+e61lFGihcTmHf86K6mhZYKc7PtOritAiZYfn6vlEWezDN8VYjjh -1/70r8bo+KGtOQk9IQwi4QGLyBsur3zxUpxO/2BvRi0Whk6Nrx24eAhg4uoZcw8s -VRruVSsX0ovKyXNNz978AvyKy367B8x3ZWQdjS35qerP23FCPlrEsdQpm531M6L7 -lihX4oV9EVyRxmZOohR2nPy5TBxE9oQOSGNzsExO6zaOw6uq0MvOhu3ih1foQVA0 -IilCvJMwzaeufF2u0LKcHmo7OHPNqDwOYWmgf//q3FBkOi05FVI/rO084ENJcJFz -5TDtSHECgYEAw9QqMr9p9su4VTFAG3+2+9FnL8Bo6xgUtkeKGJr4PapnVRn28SIS -Qv6SupcB/CBNuUX9NV1GbBjL9XJreTWW3FVWiwsBmIoJ+Z1RUn5/WD66jIVHfbzl -cpw/yECeoKOJL0QRqPneNBfAYbsw6+PFpybKSCZ3f7adAGhOI3aPk+MCgYEAwWHt -cgss3RyFKbG5Tpo87Pf7R/PNOIEhLrXgQr7E+9Iw6YYDy6DMw/3SrH1w5DEr4nc+ -Pim41TMytdhwiPZXSEppL1lavhU1VGJuiQT59h5bB+XJUVKRf91otat8ILS3n3L5 -l2Ob3BUEkLSjW4lIcxQxG3c8/rV9UH0zLoNx/FsCgYEAwIGL7hE/MK55ib39oEq/ -bfMfddC3Ewy8J6hR9/g3uh8Or5jzqX3t58/sG+Mgv2JeJZjI3rHP7am+ro2JW0E0 -CWsWxV7Pdc2VGr3s2KSjuPMJXeQTMGcGQ9GX3dqwVYgN7toCZlMjfaAvraNf5zQk -9DlsttqhtHmnA2SGE9SUNjMCgYBxZ91YkOcpcA1Diz7xso/iI/cPlhEWftuXyf8P -BVL9nqEigX3+T3llwpdmolWu7Isgzu8Ig20qUlD9xUURfO1oroKKyurlKAjTSLor -zmhMBjc6JW5vK226P3yldUBg6bn5XvKx7i873HOF7PkTuCltmzzFL6LseEBaEGIQ -d/NDmwKBgQCKWe1wwyeiqhmJXV/AGMNNECeLdH8G9kBKt6OAPMISxDHQOkP3GDkG -HwqE00jCweDdDUHEbZ0gW299KCe8u6kBD5UWKiuUARBpiudlOvoKazCnhNKrCDfz -nAQrIod4nus0mRhVTBwxzmBPsdQ/rgmtGUd+RutxPgJJzjCVMAsFeQ== +MIIEogIBAAKCAQEAzyO15932XuFy8akJwckUD67T6bJRpRYlobPjmNVGwHWQVWK7 +UerUE9zWUcqPvI0fcau/llvgihjEbmfDdQEXUOdgLkZTo8xJSh5I0NyuQ69X1ltV +f3QxYgmgdOB/xIcIn5RKlkJ2R6BAUNMl523FrEZsDqXrVvNUijy7K+Euc3YjSBQT +crEqJy32nrbLfT6WrvoKz0aT7ygzIdbwr3xErQmI3aKv3YRmBYMVRTVYVwFJWnAh ++MawfrzW39DCBusNjVSWkuJCeHAUMGsrSJl2dnePR69eyQ4syxS8j6TWjKitqkQ/ +qH3LJAp6uMnRj2we761R5xH4UU11Go4iGiQZOwIDAQABAoIBACm+IY9bbKXMOxS2 +IvA5bGCIs83ZkJh7MRQ4IzqOaFaqmm6KmgM1Fo32J/6Nmo+9xMNsgAx18XcC7Lrv +EDWJBcDZD8njhEFzDqXwGm50um2LbWEWQNGRgc4m8H39K+JX8AXwpWNIe3uNsMhY +9L+BoJ9KBcah6x43pSbCfFmoZGsB27M/smMGM6cLH6b042oLKmvqcpepHkRE8ulg +p0AercIWkSPbwKtZPsvT6YOMJaxeM4TXdQ1PYHzHmhozuC7/HrJfD2DrNT8ZXk/9 +t68d+iMgHT2HUnptkq0FT1gyo1QjBQD3d2vEbuLomOlWlqUNpUw2KCBEvno80vnb +dkcRTgECgYEA9ZDvFcKBVGzcMJKbIvNaLqs1V6ZRr6ejgHM7jsvFbIhTEPVZbARr +ZmYYw4Ox+SkX10j/49e+33c35t/YvcBdtwOZFZfZb0/nhUA378IgpzGsPCtRJ4kk +fryCxJAQ1OOos+HOQcU/Attj7qCN/pZzpGxn9CTomMwjU1+oh72nUjsCgYEA1/DN +ndJyHSbfTLQ7Pxy7SNgeb7Pnf7+JrRLoDU25j3WOQyMFUKie6tyErKz+EOriuL14 +CXfXdU2IBZPjlC911OP8yvfr9ZjehFQVY1K5XybSfVDjCFOgACeTTJQscuJtS/1K +qWi+S3c9URyG9Jwx3eVEFJOunw9nKrEFqTLq5QECgYAk8f1GhND4ZrhqBmSYyYwT +4WZRHZDEoLAUr0GSpk25mnkE4CTn/3I5IbswDyxDlE8l8LGvEdKBxGoArkTpp3ty +AXSSrxnjiV4HyjWgONC41txW4R2AmT2IY8w4zoP5w5aqGZrygj6Mq31JdZZnazNS +1Yx+St9DvdLCxG2SnpIB6QKBgEjyXNNysv/sEMT9oYIJd6786xM7B/ocvyqLV36f +Ag9XW+6MFxCPVdfrFJqsectHPb3Aq5svM8a5oTiZI+j8O2bmeZArPjeiI5E6Qlti +J6LgH30b5QX8EfHbbKQS7g0FNnzUHPOroZUmu7z50REy7pmSCHSXCwdKkcRXNp1Y +yQcBAoGAZfeK3WoHce0cTZKdll2Jppl3zG1U8CCUNBS7mL+kJcJNW6kEkvBqhD4q +XvRSkLmiEwcz20TyjqTThhuxpL8s1FrfjUtckoQQJHgMr63u/Y8ypAKMLAkwfZsT +kjXbp912RYSRhIme/hdrNoDK7BNEFSQ6A78DHZlRL3prGbovwDw= -----END privateKey----- diff --git a/backend/utils/ssl/acme.go b/backend/utils/ssl/acme.go index 22302199d..7f38442d1 100644 --- a/backend/utils/ssl/acme.go +++ b/backend/utils/ssl/acme.go @@ -85,9 +85,8 @@ func NewPrivateKeyClient(email string, privateKey string) (*AcmeClient, error) { func newConfig(user *AcmeUser) *lego.Config { config := lego.NewConfig(user) - config.CADirURL = "https://acme-v02.api.letsencrypt.org/directory" + config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory" config.UserAgent = "acm_go/0.0.1" config.Certificate.KeyType = certcrypto.RSA2048 - return config } diff --git a/backend/utils/ssl/client.go b/backend/utils/ssl/client.go index 7822ce37e..fc12183d4 100644 --- a/backend/utils/ssl/client.go +++ b/backend/utils/ssl/client.go @@ -99,12 +99,12 @@ func (c *AcmeClient) UseDns(dnsType DnsType, params string) error { } } - return c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(6*time.Minute)) + return c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(3*time.Minute)) } func (c *AcmeClient) UseManualDns(domains []string) (*Resolve, error) { p := &manualDnsProvider{} - if err := c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(6*time.Minute)); err != nil { + if err := c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(3*time.Minute)); err != nil { return nil, nil } @@ -124,7 +124,7 @@ func (c *AcmeClient) UseHTTP() { } -func (c *AcmeClient) GetSSL(domains []string) (certificate.Resource, error) { +func (c *AcmeClient) ObtainSSL(domains []string) (certificate.Resource, error) { request := certificate.ObtainRequest{ Domains: domains, @@ -139,6 +139,20 @@ func (c *AcmeClient) GetSSL(domains []string) (certificate.Resource, error) { return *certificates, nil } +func (c *AcmeClient) RenewSSL(certUrl string) (certificate.Resource, error) { + + certificates, err := c.Client.Certificate.Get(certUrl, true) + if err != nil { + return certificate.Resource{}, err + } + certificates, err = c.Client.Certificate.Renew(*certificates, true, true, "") + if err != nil { + return certificate.Resource{}, err + } + + return *certificates, nil +} + type Resolve struct { Key string Value string diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 0808a2472..0666a32cc 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -118,9 +118,10 @@ export namespace WebSite { } export interface SSL extends CommonModel { + primaryDomain: string; privateKey: string; pem: string; - domain: string; + otherDomains: string; certURL: string; type: string; issuerName: string; @@ -129,9 +130,9 @@ export namespace WebSite { } export interface SSLCreate { - domains: string[]; + primaryDomain: string; + otherDomains: string; provider: string; - websiteId: number; acmeAccountId: number; dnsAccountId: number; } @@ -141,6 +142,10 @@ export namespace WebSite { SSLId: number; } + export interface SSLRenew { + SSLId: number; + } + export interface AcmeAccount extends CommonModel { email: string; url: string; diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index 0a77e2904..15a56cfce 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -98,10 +98,18 @@ export const DeleteSSL = (id: number) => { return http.delete(`/websites/ssl/${id}`); }; +export const GetWebsiteSSL = (websiteId: number) => { + return http.get(`/websites/ssl/${websiteId}`); +}; + export const ApplySSL = (req: WebSite.SSLApply) => { return http.post(`/websites/ssl/apply`, req); }; +export const RenewSSL = (req: WebSite.SSLRenew) => { + return http.post(`/websites/ssl/renew`, req); +}; + export const GetDnsResolve = (req: WebSite.DNSResolveReq) => { return http.post(`/websites/ssl/resolve`, req); }; diff --git a/frontend/src/hooks/use-delete-data.ts b/frontend/src/hooks/use-delete-data.ts index f3fddb3a5..34dd40070 100644 --- a/frontend/src/hooks/use-delete-data.ts +++ b/frontend/src/hooks/use-delete-data.ts @@ -37,6 +37,7 @@ export const useDeleteData =

( }) .finally(() => { loading = false; - }); + }) + .catch(() => {}); }); }; diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index e86a5f364..e53c56bb4 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -131,6 +131,7 @@ export default { project: '项目', config: '配置', firewall: '防火墙', + ssl: '证书', database: '数据库', container: '容器', cronjob: '计划任务', @@ -704,7 +705,7 @@ export default { manual: '手动解析', key: '密钥', check: '查看', - accountManage: '账户管理', + acmeAccountManage: 'Acme 账户管理', email: '邮箱', addAccount: '新增账户', acmeAccount: 'Acme 账户', @@ -714,5 +715,10 @@ export default { brand: '品牌', deploySSL: '部署', deploySSLHelper: '确定部署证书?', + ssl: '证书', + dnsAccountManage: 'DNS 账户管理', + renewSSL: '续签', + renewHelper: '确定续签证书?', + renewSuccess: '续签证书', }, }; diff --git a/frontend/src/routers/modules/website.ts b/frontend/src/routers/modules/website.ts index 5bba5e388..2b0d4fe7c 100644 --- a/frontend/src/routers/modules/website.ts +++ b/frontend/src/routers/modules/website.ts @@ -13,21 +13,29 @@ const webSiteRouter = { { path: '/websites', name: 'Website', - component: () => import('@/views/website/project/index.vue'), + component: () => import('@/views/website/website/index.vue'), meta: { - title: 'menu.project', + title: 'menu.website', }, }, { path: '/websites/:id/config/:tab', name: 'WebsiteConfig', - component: () => import('@/views/website/project/config/index.vue'), + component: () => import('@/views/website/website/config/index.vue'), hidden: true, props: true, meta: { activeMenu: '/websites', }, }, + { + path: '/websites/ssl', + name: 'SSL', + component: () => import('@/views/website/ssl/index.vue'), + meta: { + title: 'menu.ssl', + }, + }, { path: '/websites/nginx', name: 'Config', @@ -36,14 +44,6 @@ const webSiteRouter = { title: 'menu.config', }, }, - { - path: '/websites/firewall', - name: 'Firewall', - component: () => import('@/views/website/project/index.vue'), - meta: { - title: 'menu.firewall', - }, - }, ], }; diff --git a/frontend/src/views/website/firewall/index.vue b/frontend/src/views/website/firewall/index.vue deleted file mode 100644 index cdfc73be6..000000000 --- a/frontend/src/views/website/firewall/index.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/views/website/project/config/ssl/current/index.vue b/frontend/src/views/website/project/config/ssl/current/index.vue deleted file mode 100644 index 59e912f39..000000000 --- a/frontend/src/views/website/project/config/ssl/current/index.vue +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/frontend/src/views/website/project/config/ssl/index.vue b/frontend/src/views/website/project/config/ssl/index.vue deleted file mode 100644 index e43955454..000000000 --- a/frontend/src/views/website/project/config/ssl/index.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - diff --git a/frontend/src/views/website/project/config/ssl/ssl/index.vue b/frontend/src/views/website/project/config/ssl/ssl/index.vue deleted file mode 100644 index 482c11c01..000000000 --- a/frontend/src/views/website/project/config/ssl/ssl/index.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - diff --git a/frontend/src/views/website/project/config/ssl/ssl/account/create/index.vue b/frontend/src/views/website/ssl/acme-account/create/index.vue similarity index 100% rename from frontend/src/views/website/project/config/ssl/ssl/account/create/index.vue rename to frontend/src/views/website/ssl/acme-account/create/index.vue diff --git a/frontend/src/views/website/project/config/ssl/ssl/account/index.vue b/frontend/src/views/website/ssl/acme-account/index.vue similarity index 94% rename from frontend/src/views/website/project/config/ssl/ssl/account/index.vue rename to frontend/src/views/website/ssl/acme-account/index.vue index c87a995b2..513e9c209 100644 --- a/frontend/src/views/website/project/config/ssl/ssl/account/index.vue +++ b/frontend/src/views/website/ssl/acme-account/index.vue @@ -1,5 +1,5 @@