diff --git a/backend/app/dto/request/website_ssl.go b/backend/app/dto/request/website_ssl.go index 9ec8fc6a9..e605bff86 100644 --- a/backend/app/dto/request/website_ssl.go +++ b/backend/app/dto/request/website_ssl.go @@ -86,7 +86,6 @@ type WebsiteCASearch struct { type WebsiteCACreate struct { CommonName string `json:"commonName" validate:"required"` Country string `json:"country" validate:"required"` - Email string `json:"email" validate:"required"` Organization string `json:"organization" validate:"required"` OrganizationUint string `json:"organizationUint"` Name string `json:"name" validate:"required"` diff --git a/backend/app/dto/response/website_ssl.go b/backend/app/dto/response/website_ssl.go index 167bd6a10..1cb4062ce 100644 --- a/backend/app/dto/response/website_ssl.go +++ b/backend/app/dto/response/website_ssl.go @@ -25,4 +25,10 @@ type WebsiteDnsAccountDTO struct { type WebsiteCADTO struct { model.WebsiteCA + CommonName string `json:"commonName" ` + Country string `json:"country"` + Organization string `json:"organization"` + OrganizationUint string `json:"organizationUint"` + Province string `json:"province" ` + City string `json:"city"` } diff --git a/backend/app/service/website_ca.go b/backend/app/service/website_ca.go index c71b6dcad..f3001063c 100644 --- a/backend/app/service/website_ca.go +++ b/backend/app/service/website_ca.go @@ -35,7 +35,7 @@ type WebsiteCAService struct { type IWebsiteCAService interface { Page(search request.WebsiteCASearch) (int64, []response.WebsiteCADTO, error) Create(create request.WebsiteCACreate) (*request.WebsiteCACreate, error) - GetCA(id uint) (response.WebsiteCADTO, error) + GetCA(id uint) (*response.WebsiteCADTO, error) Delete(id uint) error ObtainSSL(req request.WebsiteCAObtain) error } @@ -69,9 +69,10 @@ func (w WebsiteCAService) Create(create request.WebsiteCACreate) (*request.Websi } pkixName := pkix.Name{ - CommonName: create.CommonName, - Country: []string{create.Country}, - Organization: []string{create.Organization}, + CommonName: create.CommonName, + Country: []string{create.Country}, + Organization: []string{create.Organization}, + OrganizationalUnit: []string{create.OrganizationUint}, } if create.Province != "" { pkixName.Province = []string{create.Province} @@ -138,14 +139,29 @@ func (w WebsiteCAService) Create(create request.WebsiteCACreate) (*request.Websi return &create, nil } -func (w WebsiteCAService) GetCA(id uint) (response.WebsiteCADTO, error) { +func (w WebsiteCAService) GetCA(id uint) (*response.WebsiteCADTO, error) { + res := &response.WebsiteCADTO{} ca, err := websiteCARepo.GetFirst(commonRepo.WithByID(id)) if err != nil { - return response.WebsiteCADTO{}, err + return nil, err } - return response.WebsiteCADTO{ - WebsiteCA: ca, - }, nil + res.WebsiteCA = ca + certBlock, _ := pem.Decode([]byte(ca.CSR)) + if certBlock == nil { + return nil, buserr.New("ErrSSLCertificateFormat") + } + cert, err := x509.ParseCertificate(certBlock.Bytes) + if err != nil { + return nil, err + } + res.CommonName = cert.Issuer.CommonName + res.Organization = strings.Join(cert.Issuer.Organization, ",") + res.Country = strings.Join(cert.Issuer.Country, ",") + res.Province = strings.Join(cert.Issuer.Province, ",") + res.City = strings.Join(cert.Issuer.Locality, ",") + res.OrganizationUint = strings.Join(cert.Issuer.OrganizationalUnit, ",") + + return res, nil } func (w WebsiteCAService) Delete(id uint) error { @@ -157,7 +173,6 @@ func (w WebsiteCAService) Delete(id uint) error { } func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error { - var ( domains []string ips []net.IP diff --git a/backend/router/ro_website_ca.go b/backend/router/ro_website_ca.go index 965b31ea3..8bf4a37b4 100644 --- a/backend/router/ro_website_ca.go +++ b/backend/router/ro_website_ca.go @@ -17,5 +17,6 @@ func (a *WebsiteDnsAccountRouter) InitWebsiteCARouter(Router *gin.RouterGroup) { groupRouter.POST("/del", baseApi.DeleteWebsiteCA) groupRouter.POST("/obtain", baseApi.ObtainWebsiteCA) groupRouter.POST("/renew", baseApi.RenewWebsiteCA) + groupRouter.GET("/:id", baseApi.GetWebsiteCA) } } diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index e2a8524fd..aa1f9f6f1 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -18935,7 +18935,6 @@ const docTemplate = `{ "required": [ "commonName", "country", - "email", "keyType", "name", "organization" @@ -18950,9 +18949,6 @@ const docTemplate = `{ "country": { "type": "string" }, - "email": { - "type": "string" - }, "keyType": { "type": "string", "enum": [ @@ -19532,12 +19528,18 @@ const docTemplate = `{ "autoRenew": { "type": "boolean" }, + "description": { + "type": "string" + }, "dir": { "type": "string" }, "dnsAccountId": { "type": "integer" }, + "id": { + "type": "integer" + }, "keyType": { "type": "string" }, @@ -19576,33 +19578,17 @@ const docTemplate = `{ "request.WebsiteSSLUpdate": { "type": "object", "required": [ - "id", - "type" + "id" ], "properties": { "autoRenew": { "type": "boolean" }, - "certificate": { - "type": "string" - }, "description": { "type": "string" }, "id": { "type": "integer" - }, - "privateKey": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "autoRenew", - "description", - "certificate", - "privateKey" - ] } } }, @@ -20189,6 +20175,15 @@ const docTemplate = `{ "response.WebsiteCADTO": { "type": "object", "properties": { + "city": { + "type": "string" + }, + "commonName": { + "type": "string" + }, + "country": { + "type": "string" + }, "createdAt": { "type": "string" }, @@ -20204,9 +20199,18 @@ const docTemplate = `{ "name": { "type": "string" }, + "organization": { + "type": "string" + }, + "organizationUint": { + "type": "string" + }, "privateKey": { "type": "string" }, + "province": { + "type": "string" + }, "updatedAt": { "type": "string" } diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index f0609d654..e1f135cc0 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -18928,7 +18928,6 @@ "required": [ "commonName", "country", - "email", "keyType", "name", "organization" @@ -18943,9 +18942,6 @@ "country": { "type": "string" }, - "email": { - "type": "string" - }, "keyType": { "type": "string", "enum": [ @@ -19525,12 +19521,18 @@ "autoRenew": { "type": "boolean" }, + "description": { + "type": "string" + }, "dir": { "type": "string" }, "dnsAccountId": { "type": "integer" }, + "id": { + "type": "integer" + }, "keyType": { "type": "string" }, @@ -19569,33 +19571,17 @@ "request.WebsiteSSLUpdate": { "type": "object", "required": [ - "id", - "type" + "id" ], "properties": { "autoRenew": { "type": "boolean" }, - "certificate": { - "type": "string" - }, "description": { "type": "string" }, "id": { "type": "integer" - }, - "privateKey": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "autoRenew", - "description", - "certificate", - "privateKey" - ] } } }, @@ -20182,6 +20168,15 @@ "response.WebsiteCADTO": { "type": "object", "properties": { + "city": { + "type": "string" + }, + "commonName": { + "type": "string" + }, + "country": { + "type": "string" + }, "createdAt": { "type": "string" }, @@ -20197,9 +20192,18 @@ "name": { "type": "string" }, + "organization": { + "type": "string" + }, + "organizationUint": { + "type": "string" + }, "privateKey": { "type": "string" }, + "province": { + "type": "string" + }, "updatedAt": { "type": "string" } diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index b42e30262..c6219c447 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -3747,8 +3747,6 @@ definitions: type: string country: type: string - email: - type: string keyType: enum: - P256 @@ -3769,7 +3767,6 @@ definitions: required: - commonName - country - - email - keyType - name - organization @@ -4145,10 +4142,14 @@ definitions: type: boolean autoRenew: type: boolean + description: + type: string dir: type: string dnsAccountId: type: integer + id: + type: integer keyType: type: string otherDomains: @@ -4180,24 +4181,12 @@ definitions: properties: autoRenew: type: boolean - certificate: - type: string description: type: string id: type: integer - privateKey: - type: string - type: - enum: - - autoRenew - - description - - certificate - - privateKey - type: string required: - id - - type type: object request.WebsiteSSLUpload: properties: @@ -4586,6 +4575,12 @@ definitions: type: object response.WebsiteCADTO: properties: + city: + type: string + commonName: + type: string + country: + type: string createdAt: type: string csr: @@ -4596,8 +4591,14 @@ definitions: type: string name: type: string + organization: + type: string + organizationUint: + type: string privateKey: type: string + province: + type: string updatedAt: type: string type: object diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index badf3e902..bf9e9247f 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -473,7 +473,6 @@ export namespace Website { name: string; commonName: string; country: string; - email: string; organization: string; organizationUint: string; keyType: string; @@ -481,6 +480,15 @@ export namespace Website { city: string; } + export interface CADTO extends CA { + commonName: string; + country: string; + organization: string; + organizationUint: string; + province: string; + city: string; + } + export interface SSLObtainByCA { id: number; domains: string; diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index b5cdc366f..bd1d26ceb 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -270,3 +270,7 @@ export const DownloadFile = (params: Website.SSLDownload) => { timeout: TimeoutEnum.T_40S, }); }; + +export const GetCA = (id: number) => { + return http.get(`/websites/ca/${id}`); +}; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 399223c73..5cb514b75 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1851,6 +1851,7 @@ const message = { dir: 'directory', pushDirHelper: 'Two files will be generated in this directory, the certificate file: fullchain.pem and the key file: privkey.pem', + organizationDetail: 'Organization Details', }, firewall: { create: 'Create rule', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 54d421e78..e4208e3b5 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -1737,6 +1737,7 @@ const message = { pushDir: '推送憑證到本機目錄', dir: '目錄', pushDirHelper: '會在此目錄下產生兩個文件,憑證檔案:fullchain.pem 金鑰檔案:privkey.pem', + organizationDetail: '機構詳情', }, firewall: { create: '創建規則', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index cf091d09e..8991d45cb 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1737,6 +1737,7 @@ const message = { pushDir: '推送证书到本地目录', dir: '目录', pushDirHelper: '会在此目录下生成两个文件,证书文件:fullchain.pem 密钥文件:privkey.pem', + organizationDetail: '机构详情', }, firewall: { create: '创建规则', diff --git a/frontend/src/views/website/ssl/ca/create/index.vue b/frontend/src/views/website/ssl/ca/create/index.vue index 98808edf2..91f742263 100644 --- a/frontend/src/views/website/ssl/ca/create/index.vue +++ b/frontend/src/views/website/ssl/ca/create/index.vue @@ -15,9 +15,6 @@ - - - @@ -72,7 +69,6 @@ const caForm = ref(); const em = defineEmits(['close']); const rules = ref({ - email: [Rules.requiredInput, Rules.email], keyType: [Rules.requiredSelect], name: [Rules.requiredInput, Rules.name], country: [Rules.requiredSelect], @@ -82,7 +78,6 @@ const rules = ref({ const initData = () => ({ name: '', - email: '', keyType: 'P256', commonName: '', country: 'CN', diff --git a/frontend/src/views/website/ssl/ca/detail/index.vue b/frontend/src/views/website/ssl/ca/detail/index.vue new file mode 100644 index 000000000..6a7f5aa6d --- /dev/null +++ b/frontend/src/views/website/ssl/ca/detail/index.vue @@ -0,0 +1,103 @@ + + diff --git a/frontend/src/views/website/ssl/ca/index.vue b/frontend/src/views/website/ssl/ca/index.vue index 4fe573f2b..dce97e7e4 100644 --- a/frontend/src/views/website/ssl/ca/index.vue +++ b/frontend/src/views/website/ssl/ca/index.vue @@ -7,28 +7,29 @@ - - + + + - + + @@ -41,7 +42,8 @@ import { DeleteCA, SearchCAs } from '@/api/modules/website'; import i18n from '@/lang'; import { reactive, ref } from 'vue'; import Create from './create/index.vue'; -import { getKeyName } from '@/utils/util'; +import Detail from './detail/index.vue'; +import { getKeyName, dateFormat } from '@/utils/util'; import Obtain from './obtain/index.vue'; const open = ref(false); @@ -57,6 +59,7 @@ const paginationConfig = reactive({ const opRef = ref(); const obtainRef = ref(); const em = defineEmits(['close']); +const detailRef = ref(); const buttons = [ { @@ -65,6 +68,12 @@ const buttons = [ obtain(row); }, }, + { + label: i18n.global.t('ssl.detail'), + click: function (row: Website.CA) { + detailRef.value.acceptParams(row.id); + }, + }, { label: i18n.global.t('commons.button.delete'), click: function (row: Website.CA) {