From fae60f23af9b3d3ea8c7d69c67922db61fe878df Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Thu, 18 Dec 2025 13:06:28 +0800 Subject: [PATCH] feat: download certificate including server certificate and intermedia certificate --- internal/certificate/service.go | 102 +++++++++++------- .../certificate/CertificateDetail.tsx | 1 + 2 files changed, 66 insertions(+), 37 deletions(-) diff --git a/internal/certificate/service.go b/internal/certificate/service.go index 1b73c4d2..c8e667c6 100644 --- a/internal/certificate/service.go +++ b/internal/certificate/service.go @@ -54,35 +54,60 @@ func (s *CertificateService) DownloadArchivedFile(ctx context.Context, req *dtos return nil, err } + canonicalName := strings.Split(certificate.SubjectAltNames, ";")[0] + canonicalName = strings.ReplaceAll(canonicalName, "*", "_") + var buf bytes.Buffer zipWriter := zip.NewWriter(&buf) defer zipWriter.Close() - resp := &dtos.CertificateArchiveFileResp{ - FileFormat: "zip", - } - + var bytes []byte switch strings.ToUpper(req.Format) { case "", "PEM": { - certWriter, err := zipWriter.Create("certbundle.pem") + serverCertPEM, intermediaCertPEM, err := xcert.ExtractCertificatesFromPEM(certificate.Certificate) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to extract certs: %w", err) } - _, err = certWriter.Write([]byte(certificate.Certificate)) + certWriter, err := zipWriter.Create(fmt.Sprintf("%s.pem", canonicalName)) if err != nil { return nil, err + } else { + _, err = certWriter.Write([]byte(certificate.Certificate)) + if err != nil { + return nil, err + } } - keyWriter, err := zipWriter.Create("privkey.pem") + serverCertWriter, err := zipWriter.Create(fmt.Sprintf("%s (server).pem", canonicalName)) if err != nil { return nil, err + } else { + _, err = serverCertWriter.Write([]byte(serverCertPEM)) + if err != nil { + return nil, err + } } - _, err = keyWriter.Write([]byte(certificate.PrivateKey)) + intermediaCertWriter, err := zipWriter.Create(fmt.Sprintf("%s (intermedia).pem", canonicalName)) if err != nil { return nil, err + } else { + _, err = intermediaCertWriter.Write([]byte(intermediaCertPEM)) + if err != nil { + return nil, err + } + } + + keyWriter, err := zipWriter.Create(fmt.Sprintf("%s.key", canonicalName)) + if err != nil { + return nil, err + } else { + _, err = keyWriter.Write([]byte(certificate.PrivateKey)) + if err != nil { + return nil, err + } } err = zipWriter.Close() @@ -90,8 +115,7 @@ func (s *CertificateService) DownloadArchivedFile(ctx context.Context, req *dtos return nil, err } - resp.FileBytes = buf.Bytes() - return resp, nil + bytes = buf.Bytes() } case "PFX": @@ -103,24 +127,24 @@ func (s *CertificateService) DownloadArchivedFile(ctx context.Context, req *dtos return nil, err } - certWriter, err := zipWriter.Create("cert.pfx") - if err != nil { - return nil, err - } - - _, err = certWriter.Write(certPFX) + certWriter, err := zipWriter.Create(fmt.Sprintf("%s.pfx", canonicalName)) if err != nil { return nil, err + } else { + _, err = certWriter.Write(certPFX) + if err != nil { + return nil, err + } } keyWriter, err := zipWriter.Create("pfx-password.txt") if err != nil { return nil, err - } - - _, err = keyWriter.Write([]byte(pfxPassword)) - if err != nil { - return nil, err + } else { + _, err = keyWriter.Write([]byte(pfxPassword)) + if err != nil { + return nil, err + } } err = zipWriter.Close() @@ -128,8 +152,7 @@ func (s *CertificateService) DownloadArchivedFile(ctx context.Context, req *dtos return nil, err } - resp.FileBytes = buf.Bytes() - return resp, nil + bytes = buf.Bytes() } case "JKS": @@ -141,24 +164,24 @@ func (s *CertificateService) DownloadArchivedFile(ctx context.Context, req *dtos return nil, err } - certWriter, err := zipWriter.Create("cert.jks") - if err != nil { - return nil, err - } - - _, err = certWriter.Write(certJKS) + certWriter, err := zipWriter.Create(fmt.Sprintf("%s.jks", canonicalName)) if err != nil { return nil, err + } else { + _, err = certWriter.Write(certJKS) + if err != nil { + return nil, err + } } keyWriter, err := zipWriter.Create("jks-password.txt") if err != nil { return nil, err - } - - _, err = keyWriter.Write([]byte(jksPassword)) - if err != nil { - return nil, err + } else { + _, err = keyWriter.Write([]byte(jksPassword)) + if err != nil { + return nil, err + } } err = zipWriter.Close() @@ -166,13 +189,18 @@ func (s *CertificateService) DownloadArchivedFile(ctx context.Context, req *dtos return nil, err } - resp.FileBytes = buf.Bytes() - return resp, nil + bytes = buf.Bytes() } default: return nil, domain.ErrInvalidParams } + + resp := &dtos.CertificateArchiveFileResp{ + FileFormat: "zip", + FileBytes: bytes, + } + return resp, nil } func (s *CertificateService) RevokeCertificate(ctx context.Context, req *dtos.CertificateRevokeReq) (*dtos.CertificateRevokeResp, error) { diff --git a/ui/src/components/certificate/CertificateDetail.tsx b/ui/src/components/certificate/CertificateDetail.tsx index c9a3a886..085ecf65 100644 --- a/ui/src/components/certificate/CertificateDetail.tsx +++ b/ui/src/components/certificate/CertificateDetail.tsx @@ -115,6 +115,7 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => { }, ], }} + trigger={["click", "hover"]} >