From 36ccc3769a7f9d2484d071d7098038c74e451ff5 Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Tue, 2 Dec 2025 12:46:12 -0300 Subject: [PATCH] Address PR comments --- .../routes/v1/certificate-authority-router.ts | 19 ++-- .../server/routes/v1/certificate-router.ts | 9 +- .../v1/deprecated-certificate-router.ts | 17 ++-- .../v3/deprecated-certificates-router.ts | 4 + .../internal-certificate-authority-service.ts | 28 +++--- .../internal-certificate-authority-types.ts | 2 + .../certificate-request-service.test.ts | 8 +- .../certificate-request-service.ts | 53 ++++++------ .../certificate-request-types.ts | 2 + .../certificate-v3/certificate-v3-service.ts | 86 +++++++++++-------- frontend/src/hooks/api/ca/queries.tsx | 6 +- .../src/hooks/api/certificates/mutations.tsx | 5 +- .../components/CertificateIssuanceModal.tsx | 3 +- .../components/CertificateRenewalModal.tsx | 2 +- .../components/CertificateRequestTracker.tsx | 4 +- .../CreateProfileModal.tsx | 5 +- 16 files changed, 139 insertions(+), 114 deletions(-) diff --git a/backend/src/server/routes/v1/certificate-authority-router.ts b/backend/src/server/routes/v1/certificate-authority-router.ts index 96e0db219..2917270ef 100644 --- a/backend/src/server/routes/v1/certificate-authority-router.ts +++ b/backend/src/server/routes/v1/certificate-authority-router.ts @@ -665,16 +665,15 @@ export const registerCaRouter = async (server: FastifyZodProvider) => { } }, handler: async (req) => { - const response = await server.services.internalCertificateAuthority.issueCertFromCa({ - caId: req.params.caId, - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - ...req.body - }); - - const { certificate, certificateChain, issuingCaCertificate, privateKey, serialNumber, ca } = response; + const { certificate, certificateChain, issuingCaCertificate, privateKey, serialNumber, ca } = + await server.services.internalCertificateAuthority.issueCertFromCa({ + caId: req.params.caId, + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.body + }); await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, diff --git a/backend/src/server/routes/v1/certificate-router.ts b/backend/src/server/routes/v1/certificate-router.ts index 3823f791d..492902a6f 100644 --- a/backend/src/server/routes/v1/certificate-router.ts +++ b/backend/src/server/routes/v1/certificate-router.ts @@ -170,8 +170,7 @@ export const registerCertificateRouter = async (server: FastifyZodProvider) => { serialNumber: z.string().trim(), certificateId: z.string() }) - .nullable() - .optional(), + .nullable(), certificateRequestId: z.string() }) } @@ -373,11 +372,9 @@ export const registerCertificateRouter = async (server: FastifyZodProvider) => { ...req.auditLogInfo, projectId: (req.query as { projectId: string }).projectId, event: { - type: EventType.GET_CERT, + type: EventType.GET_CERTIFICATE_REQUEST, metadata: { - certId: req.params.requestId, - cn: "", - serialNumber: data.serialNumber || "" + certificateRequestId: req.params.requestId } } }); diff --git a/backend/src/server/routes/v1/deprecated-certificate-router.ts b/backend/src/server/routes/v1/deprecated-certificate-router.ts index 73072ea31..955407e4c 100644 --- a/backend/src/server/routes/v1/deprecated-certificate-router.ts +++ b/backend/src/server/routes/v1/deprecated-certificate-router.ts @@ -242,15 +242,14 @@ export const registerDeprecatedCertRouter = async (server: FastifyZodProvider) = } }, handler: async (req) => { - const response = await server.services.internalCertificateAuthority.issueCertFromCa({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - ...req.body - }); - - const { certificate, certificateChain, issuingCaCertificate, privateKey, serialNumber, ca } = response; + const { certificate, certificateChain, issuingCaCertificate, privateKey, serialNumber, ca } = + await server.services.internalCertificateAuthority.issueCertFromCa({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.body + }); await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, diff --git a/backend/src/server/routes/v3/deprecated-certificates-router.ts b/backend/src/server/routes/v3/deprecated-certificates-router.ts index beaffd5f6..fc3a05ecb 100644 --- a/backend/src/server/routes/v3/deprecated-certificates-router.ts +++ b/backend/src/server/routes/v3/deprecated-certificates-router.ts @@ -17,6 +17,7 @@ import { import { extractCertificateRequestFromCSR } from "@app/services/certificate-common/certificate-csr-utils"; import { mapEnumsForValidation } from "@app/services/certificate-common/certificate-utils"; import { EnrollmentType } from "@app/services/certificate-profile/certificate-profile-types"; +import { CertificateRequestStatus } from "@app/services/certificate-request/certificate-request-types"; import { validateTemplateRegexField } from "@app/services/certificate-template/certificate-template-validators"; import { booleanSchema } from "../sanitizedSchemas"; @@ -138,6 +139,7 @@ export const registerCertificatesRouter = async (server: FastifyZodProvider) => }); const certificateRequest = await server.services.certificateRequest.createCertificateRequest({ + status: CertificateRequestStatus.ISSUED, actor: req.permission.type, actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, @@ -244,6 +246,7 @@ export const registerCertificatesRouter = async (server: FastifyZodProvider) => const certificateRequest = await server.services.certificateRequest.createCertificateRequest({ actor: req.permission.type, + status: CertificateRequestStatus.ISSUED, actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, actorOrgId: req.permission.orgId, @@ -365,6 +368,7 @@ export const registerCertificatesRouter = async (server: FastifyZodProvider) => }); const certificateRequest = await server.services.certificateRequest.createCertificateRequest({ + status: CertificateRequestStatus.PENDING, actor: req.permission.type, actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, diff --git a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts index f3c56e322..2b7c155db 100644 --- a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts +++ b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts @@ -1575,15 +1575,16 @@ export const internalCertificateAuthorityServiceFactory = ({ keyUsages, extendedKeyUsages, signatureAlgorithm, - keyAlgorithm + keyAlgorithm, + tx } = dto; let collectionId = pkiCollectionId; if (caId) { - ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId); + ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId, tx); } else if (certificateTemplateId) { - certificateTemplate = await certificateTemplateDAL.getById(certificateTemplateId); + certificateTemplate = await certificateTemplateDAL.getById(certificateTemplateId, tx); if (!certificateTemplate) { throw new NotFoundError({ message: `Certificate template with ID '${certificateTemplateId}' not found` @@ -1591,7 +1592,7 @@ export const internalCertificateAuthorityServiceFactory = ({ } collectionId = certificateTemplate.pkiCollectionId as string; - ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(certificateTemplate.caId); + ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(certificateTemplate.caId, tx); } if (!ca) { @@ -1640,7 +1641,7 @@ export const internalCertificateAuthorityServiceFactory = ({ // check PKI collection if (pkiCollectionId) { - const pkiCollection = await pkiCollectionDAL.findById(pkiCollectionId); + const pkiCollection = await pkiCollectionDAL.findById(pkiCollectionId, tx); if (!pkiCollection) throw new NotFoundError({ message: `PKI collection with ID '${pkiCollectionId}' not found` }); if (pkiCollection.projectId !== ca.projectId) throw new BadRequestError({ message: "Invalid PKI collection" }); } @@ -1909,7 +1910,7 @@ export const internalCertificateAuthorityServiceFactory = ({ plainText: Buffer.from(certificateChainPem) }); - const cert = await certificateDAL.transaction(async (tx) => { + const createSignedCert = async (transaction: Knex) => { const newCert = await certificateDAL.create( { caId: (ca as TCertificateAuthorities).id, @@ -1928,7 +1929,7 @@ export const internalCertificateAuthorityServiceFactory = ({ keyAlgorithm: keyAlgorithm || ca!.internalCa!.keyAlgorithm, signatureAlgorithm: signatureAlgorithm || ca!.internalCa!.keyAlgorithm }, - tx + transaction ); await certificateBodyDAL.create( @@ -1937,7 +1938,7 @@ export const internalCertificateAuthorityServiceFactory = ({ encryptedCertificate, encryptedCertificateChain }, - tx + transaction ); if (collectionId) { @@ -1946,12 +1947,19 @@ export const internalCertificateAuthorityServiceFactory = ({ pkiCollectionId: collectionId, certId: newCert.id }, - tx + transaction ); } return newCert; - }); + }; + + let cert; + if (tx) { + cert = await createSignedCert(tx); + } else { + cert = await certificateDAL.transaction(createSignedCert); + } return { certificate: leafCert, diff --git a/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts b/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts index 60b9c65c5..c13f85aa5 100644 --- a/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts +++ b/backend/src/services/certificate-authority/internal/internal-certificate-authority-types.ts @@ -160,6 +160,7 @@ export type TSignCertFromCaDTO = keyAlgorithm?: string; isFromProfile?: boolean; profileId?: string; + tx?: Knex; } | ({ isInternal: false; @@ -179,6 +180,7 @@ export type TSignCertFromCaDTO = keyAlgorithm?: string; isFromProfile?: boolean; profileId?: string; + tx?: Knex; } & Omit); export type TGetCaCertificateTemplatesDTO = { diff --git a/backend/src/services/certificate-request/certificate-request-service.test.ts b/backend/src/services/certificate-request/certificate-request-service.test.ts index 2df3a2354..5e6b870bf 100644 --- a/backend/src/services/certificate-request/certificate-request-service.test.ts +++ b/backend/src/services/certificate-request/certificate-request-service.test.ts @@ -71,7 +71,8 @@ describe("CertificateRequestService", () => { actorOrgId: "550e8400-e29b-41d4-a716-446655440002", projectId: "550e8400-e29b-41d4-a716-446655440003", profileId: "550e8400-e29b-41d4-a716-446655440004", - commonName: "test.example.com" + commonName: "test.example.com", + status: CertificateRequestStatus.PENDING }; it("should create certificate request successfully", async () => { @@ -105,12 +106,13 @@ describe("CertificateRequestService", () => { actionProjectType: ActionProjectType.CertificateManager }); expect(mockCertificateRequestDAL.create).toHaveBeenCalledWith( - expect.objectContaining({ + { status: CertificateRequestStatus.PENDING, projectId: "550e8400-e29b-41d4-a716-446655440003", profileId: "550e8400-e29b-41d4-a716-446655440004", commonName: "test.example.com" - }) + }, + undefined ); expect(result).toEqual(mockCreatedRequest); }); diff --git a/backend/src/services/certificate-request/certificate-request-service.ts b/backend/src/services/certificate-request/certificate-request-service.ts index 67cd6d77c..15450ee6e 100644 --- a/backend/src/services/certificate-request/certificate-request-service.ts +++ b/backend/src/services/certificate-request/certificate-request-service.ts @@ -12,6 +12,7 @@ import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal"; import { TCertificateServiceFactory } from "@app/services/certificate/certificate-service"; +import { ActorType } from "../auth/auth-type"; import { TCertificateRequestDALFactory } from "./certificate-request-dal"; import { CertificateRequestStatus, @@ -44,7 +45,8 @@ const certificateRequestDataSchema = z notAfter: z.date().optional(), keyAlgorithm: z.string().max(100).optional(), signatureAlgorithm: z.string().max(100).optional(), - metadata: z.string().max(2000).optional() + metadata: z.string().max(2000).optional(), + certificateId: z.string().optional() }) .refine( (data) => { @@ -94,39 +96,36 @@ export const certificateRequestServiceFactory = ({ actorOrgId, projectId, tx, + status, ...requestData }: TCreateCertificateRequestDTO & { tx?: Knex }) => { - const { permission } = await permissionService.getProjectPermission({ - actor, - actorId, - projectId, - actorAuthMethod, - actorOrgId, - actionProjectType: ActionProjectType.CertificateManager - }); + if (actor !== ActorType.ACME_ACCOUNT) { + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager + }); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionCertificateActions.Create, - ProjectPermissionSub.Certificates - ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionCertificateActions.Create, + ProjectPermissionSub.Certificates + ); + } // Validate input data before creating the request const validatedData = validateCertificateRequestData(requestData); - const certificateRequest = tx - ? await certificateRequestDAL.create( - { - status: CertificateRequestStatus.PENDING, - projectId, - ...validatedData - }, - tx - ) - : await certificateRequestDAL.create({ - status: CertificateRequestStatus.PENDING, - projectId, - ...validatedData - }); + const certificateRequest = await certificateRequestDAL.create( + { + status, + projectId, + ...validatedData + }, + tx + ); return certificateRequest; }; diff --git a/backend/src/services/certificate-request/certificate-request-types.ts b/backend/src/services/certificate-request/certificate-request-types.ts index 98fe05fe5..c8a00de7e 100644 --- a/backend/src/services/certificate-request/certificate-request-types.ts +++ b/backend/src/services/certificate-request/certificate-request-types.ts @@ -19,6 +19,8 @@ export type TCreateCertificateRequestDTO = TProjectPermission & { keyAlgorithm?: string; signatureAlgorithm?: string; metadata?: string; + status: CertificateRequestStatus; + certificateId?: string; }; export type TGetCertificateRequestDTO = TProjectPermission & { diff --git a/backend/src/services/certificate-v3/certificate-v3-service.ts b/backend/src/services/certificate-v3/certificate-v3-service.ts index 21e315a19..1c888a6e5 100644 --- a/backend/src/services/certificate-v3/certificate-v3-service.ts +++ b/backend/src/services/certificate-v3/certificate-v3-service.ts @@ -19,10 +19,8 @@ import { TCertificateBodyDALFactory } from "@app/services/certificate/certificat import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal"; import { TCertificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal"; import { - CertExtendedKeyUsage, CertKeyAlgorithm, CertKeyType, - CertKeyUsage, CertSignatureAlgorithm, CertStatus } from "@app/services/certificate/certificate-types"; @@ -58,15 +56,14 @@ import { bufferToString, buildCertificateSubjectFromTemplate, buildSubjectAlternativeNamesFromTemplate, - convertExtendedKeyUsageArrayFromLegacy, convertExtendedKeyUsageArrayToLegacy, - convertKeyUsageArrayFromLegacy, convertKeyUsageArrayToLegacy, mapEnumsForValidation, normalizeDateForApi, removeRootCaFromChain } from "../certificate-common/certificate-utils"; import { TCertificateRequestServiceFactory } from "../certificate-request/certificate-request-service"; +import { CertificateRequestStatus } from "../certificate-request/certificate-request-types"; import { TCertificateSyncDALFactory } from "../certificate-sync/certificate-sync-dal"; import { TCertificateRequest } from "../certificate-template-v2/certificate-template-v2-types"; import { TPkiSyncDALFactory } from "../pki-sync/pki-sync-dal"; @@ -307,14 +304,15 @@ const extractCertificateFromBuffer = (certData: Buffer | { rawData: Buffer } | s return bufferToString(certData as unknown as Buffer); }; -const parseKeyUsages = (keyUsages: unknown): CertKeyUsage[] => { +const parseKeyUsages = (keyUsages: unknown): CertKeyUsageType[] => { if (!keyUsages) return []; - const validKeyUsages = Object.values(CertKeyUsage); + const validKeyUsages = Object.values(CertKeyUsageType); if (Array.isArray(keyUsages)) { return keyUsages.filter( - (usage): usage is CertKeyUsage => typeof usage === "string" && validKeyUsages.includes(usage as CertKeyUsage) + (usage): usage is CertKeyUsageType => + typeof usage === "string" && validKeyUsages.includes(usage as CertKeyUsageType) ); } @@ -322,21 +320,21 @@ const parseKeyUsages = (keyUsages: unknown): CertKeyUsage[] => { return keyUsages .split(",") .map((usage) => usage.trim()) - .filter((usage): usage is CertKeyUsage => validKeyUsages.includes(usage as CertKeyUsage)); + .filter((usage): usage is CertKeyUsageType => validKeyUsages.includes(usage as CertKeyUsageType)); } return []; }; -const parseExtendedKeyUsages = (extendedKeyUsages: unknown): CertExtendedKeyUsage[] => { +const parseExtendedKeyUsages = (extendedKeyUsages: unknown): CertExtendedKeyUsageType[] => { if (!extendedKeyUsages) return []; - const validExtendedKeyUsages = Object.values(CertExtendedKeyUsage); + const validExtendedKeyUsages = Object.values(CertExtendedKeyUsageType); if (Array.isArray(extendedKeyUsages)) { return extendedKeyUsages.filter( - (usage): usage is CertExtendedKeyUsage => - typeof usage === "string" && validExtendedKeyUsages.includes(usage as CertExtendedKeyUsage) + (usage): usage is CertExtendedKeyUsageType => + typeof usage === "string" && validExtendedKeyUsages.includes(usage as CertExtendedKeyUsageType) ); } @@ -344,7 +342,9 @@ const parseExtendedKeyUsages = (extendedKeyUsages: unknown): CertExtendedKeyUsag return extendedKeyUsages .split(",") .map((usage) => usage.trim()) - .filter((usage): usage is CertExtendedKeyUsage => validExtendedKeyUsages.includes(usage as CertExtendedKeyUsage)); + .filter((usage): usage is CertExtendedKeyUsageType => + validExtendedKeyUsages.includes(usage as CertExtendedKeyUsageType) + ); } return []; @@ -972,7 +972,9 @@ export const certificateV3ServiceFactory = ({ notBefore: certificateRequest.notBefore, notAfter: certificateRequest.notAfter, keyAlgorithm: effectiveKeyAlgorithm, - signatureAlgorithm: effectiveSignatureAlgorithm + signatureAlgorithm: effectiveSignatureAlgorithm, + status: CertificateRequestStatus.ISSUED, + certificateId: selfSignedResult.certificateData.id }); return { ...selfSignedResult, certificateRequestId: certRequestResult.id }; @@ -1048,7 +1050,8 @@ export const certificateV3ServiceFactory = ({ actorId, actorAuthMethod, actorOrgId, - isFromProfile: true + isFromProfile: true, + tx }); const certificateRecord = await certificateDAL.findById(certResult.certificateId); @@ -1066,7 +1069,7 @@ export const certificateV3ServiceFactory = ({ if (finalRenewBeforeDays !== undefined) { updateData.renewBeforeDays = finalRenewBeforeDays; } - await certificateDAL.updateById(certificateRecord.id, updateData); + await certificateDAL.updateById(certificateRecord.id, updateData, tx); const certRequestResult = await certificateRequestService.createCertificateRequest({ actor, @@ -1075,6 +1078,7 @@ export const certificateV3ServiceFactory = ({ actorOrgId, projectId: profile.projectId, tx, + caId: ca.id, profileId: profile.id, commonName: certificateRequest.commonName, altNames: certificateRequest.altNames?.map((san) => san.value).join(","), @@ -1083,7 +1087,9 @@ export const certificateV3ServiceFactory = ({ notBefore: certificateRequest.notBefore, notAfter: certificateRequest.notAfter, keyAlgorithm: effectiveKeyAlgorithm, - signatureAlgorithm: effectiveSignatureAlgorithm + signatureAlgorithm: effectiveSignatureAlgorithm, + status: CertificateRequestStatus.ISSUED, + certificateId: certResult.certificateId }); return { ...certResult, cert: certificateRecord, certificateRequestId: certRequestResult.id }; @@ -1197,7 +1203,8 @@ export const certificateV3ServiceFactory = ({ notAfter: normalizeDateForApi(notAfter), signatureAlgorithm: effectiveSignatureAlgorithm, keyAlgorithm: effectiveKeyAlgorithm, - isFromProfile: true + isFromProfile: true, + tx }); const signedCertRecord = await certificateDAL.findById(certResult.certificateId); @@ -1215,7 +1222,7 @@ export const certificateV3ServiceFactory = ({ if (finalRenewBeforeDays !== undefined) { updateData.renewBeforeDays = finalRenewBeforeDays; } - await certificateDAL.updateById(signedCertRecord.id, updateData); + await certificateDAL.updateById(signedCertRecord.id, updateData, tx); const certRequestResult = await certificateRequestService.createCertificateRequest({ actor, @@ -1224,6 +1231,7 @@ export const certificateV3ServiceFactory = ({ actorOrgId, projectId: profile.projectId, tx, + caId: ca.id, profileId: profile.id, csr, commonName: mappedCertificateRequest.commonName, @@ -1233,7 +1241,9 @@ export const certificateV3ServiceFactory = ({ notBefore, notAfter, keyAlgorithm: effectiveKeyAlgorithm, - signatureAlgorithm: effectiveSignatureAlgorithm + signatureAlgorithm: effectiveSignatureAlgorithm, + status: CertificateRequestStatus.ISSUED, + certificateId: certResult.certificateId }); return { ...certResult, cert: signedCertRecord, certificateRequestId: certRequestResult.id }; @@ -1370,6 +1380,7 @@ export const certificateV3ServiceFactory = ({ actorAuthMethod, actorOrgId, projectId: profile.projectId, + caId: ca.id, profileId: profile.id, commonName: certificateOrder.commonName || "", keyUsages: certificateOrder.keyUsages ? convertEnumsToStringArray(certificateOrder.keyUsages) : [], @@ -1380,7 +1391,8 @@ export const certificateV3ServiceFactory = ({ signatureAlgorithm: certificateOrder.signatureAlgorithm || "", altNames: certificateOrder.altNames?.map((san) => san.value).join(",") || "", notBefore: certificateOrder.notBefore, - notAfter: certificateOrder.notAfter + notAfter: certificateOrder.notAfter, + status: CertificateRequestStatus.PENDING }); await certificateIssuanceQueue.queueCertificateIssuance({ @@ -1554,10 +1566,8 @@ export const certificateV3ServiceFactory = ({ const certificateRequest = { commonName: originalCert.commonName || undefined, - keyUsages: convertKeyUsageArrayFromLegacy(parseKeyUsages(originalCert.keyUsages)), - extendedKeyUsages: convertExtendedKeyUsageArrayFromLegacy( - parseExtendedKeyUsages(originalCert.extendedKeyUsages) - ), + keyUsages: parseKeyUsages(originalCert.keyUsages), + extendedKeyUsages: parseExtendedKeyUsages(originalCert.extendedKeyUsages), subjectAlternativeNames: originalCert.altNames ? originalCert.altNames.split(",").map((san) => detectSanType(san.trim())) : [], @@ -1622,8 +1632,10 @@ export const certificateV3ServiceFactory = ({ ttl, notBefore: normalizeDateForApi(notBefore), notAfter: normalizeDateForApi(notAfter), - keyUsages: parseKeyUsages(originalCert.keyUsages), - extendedKeyUsages: parseExtendedKeyUsages(originalCert.extendedKeyUsages), + keyUsages: convertKeyUsageArrayToLegacy(parseKeyUsages(originalCert.keyUsages)), + extendedKeyUsages: convertExtendedKeyUsageArrayToLegacy( + parseExtendedKeyUsages(originalCert.extendedKeyUsages) + ), signatureAlgorithm: originalSignatureAlgorithm, keyAlgorithm: originalKeyAlgorithm, isFromProfile: true, @@ -1736,18 +1748,19 @@ export const certificateV3ServiceFactory = ({ actorOrgId, projectId: originalCert.projectId, tx, + caId: ca?.id || originalCert.caId || undefined, profileId: originalCert.profileId || undefined, commonName: originalCert.commonName || undefined, altNames: originalCert.altNames || undefined, - keyUsages: convertKeyUsageArrayFromLegacy(parseKeyUsages(originalCert.keyUsages)), - extendedKeyUsages: convertExtendedKeyUsageArrayFromLegacy( - parseExtendedKeyUsages(originalCert.extendedKeyUsages) - ), + keyUsages: parseKeyUsages(originalCert.keyUsages), + extendedKeyUsages: parseExtendedKeyUsages(originalCert.extendedKeyUsages), notBefore: new Date(newCert.notBefore), notAfter: new Date(newCert.notAfter), keyAlgorithm: originalKeyAlgorithm, signatureAlgorithm: originalSignatureAlgorithm, - metadata: `Renewed from certificate ID: ${originalCert.id}` + metadata: `Renewed from certificate ID: ${originalCert.id}`, + status: CertificateRequestStatus.ISSUED, + certificateId: newCert.id }); return { @@ -1783,13 +1796,12 @@ export const certificateV3ServiceFactory = ({ caId: ca.id, commonName: originalCert.commonName || undefined, altNames: originalCert.altNames || undefined, - keyUsages: convertKeyUsageArrayFromLegacy(parseKeyUsages(originalCert.keyUsages)), - extendedKeyUsages: convertExtendedKeyUsageArrayFromLegacy( - parseExtendedKeyUsages(originalCert.extendedKeyUsages) - ), + keyUsages: parseKeyUsages(originalCert.keyUsages), + extendedKeyUsages: parseExtendedKeyUsages(originalCert.extendedKeyUsages), keyAlgorithm: originalKeyAlgorithm, signatureAlgorithm: originalSignatureAlgorithm, - metadata: `Renewed from certificate ID: ${originalCert.id}` + metadata: `Renewed from certificate ID: ${originalCert.id}`, + status: CertificateRequestStatus.PENDING }); certificateRequestId = certificateRequest.id; diff --git a/frontend/src/hooks/api/ca/queries.tsx b/frontend/src/hooks/api/ca/queries.tsx index 09e4c0f3b..d2e1836bb 100644 --- a/frontend/src/hooks/api/ca/queries.tsx +++ b/frontend/src/hooks/api/ca/queries.tsx @@ -189,10 +189,12 @@ export const useGetCaCertTemplates = (caId: string) => { export const useGetAzureAdcsTemplates = ({ caId, - projectId + projectId, + isAzureAdcsCa }: { caId: string; projectId: string; + isAzureAdcsCa: boolean; }) => { return useQuery({ queryKey: caKeys.getAzureAdcsTemplates(caId, projectId), @@ -202,6 +204,6 @@ export const useGetAzureAdcsTemplates = ({ }>(`/api/v1/cert-manager/ca/azure-ad-cs/${caId}/templates?projectId=${projectId}`); return data; }, - enabled: Boolean(caId && projectId) + enabled: Boolean(caId && projectId && isAzureAdcsCa) }); }; diff --git a/frontend/src/hooks/api/certificates/mutations.tsx b/frontend/src/hooks/api/certificates/mutations.tsx index e3e6d6c36..03605ac90 100644 --- a/frontend/src/hooks/api/certificates/mutations.tsx +++ b/frontend/src/hooks/api/certificates/mutations.tsx @@ -195,10 +195,7 @@ export const useUnifiedCertificateIssuance = () => { const { projectSlug, ...requestData } = body; const { data } = await apiRequest.post( "/api/v1/cert-manager/certificates", - requestData, - { - params: { projectSlug } - } + requestData ); return data; }, diff --git a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateIssuanceModal.tsx b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateIssuanceModal.tsx index b5531dacf..fff941681 100644 --- a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateIssuanceModal.tsx +++ b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateIssuanceModal.tsx @@ -298,7 +298,6 @@ export const CertificateIssuanceModal = ({ popUp, handlePopUpToggle, profileId } const formattedSans = formatSubjectAltNames(subjectAltNames); if (formattedSans && formattedSans.length > 0) { request.attributes.altNames = formattedSans; - request.attributes.subjectAlternativeNames = formattedSans; } } @@ -325,7 +324,7 @@ export const CertificateIssuanceModal = ({ popUp, handlePopUpToggle, profileId } } else { // Certificate request - async processing createNotification({ - text: `Certificate request submitted successfully. This may take a few minutes to process. Request ID: ${response.certificateRequestId}`, + text: `Certificate request submitted successfully. This may take a few minutes to process. Certificate Request ID: ${response.certificateRequestId}`, type: "success" }); handlePopUpToggle("issueCertificate", false); diff --git a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRenewalModal.tsx b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRenewalModal.tsx index 48482c064..3459beed5 100644 --- a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRenewalModal.tsx +++ b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRenewalModal.tsx @@ -25,7 +25,7 @@ export const CertificateRenewalModal = ({ popUp, handlePopUpToggle }: Props) => }); const notificationText = result.certificateRequestId - ? `Certificate renewal initiated successfully. Request ID: ${result.certificateRequestId}` + ? `Certificate renewal initiated successfully. Certificate Request ID: ${result.certificateRequestId}` : "Certificate renewed successfully"; createNotification({ diff --git a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRequestTracker.tsx b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRequestTracker.tsx index 69f9ef446..2d6453963 100644 --- a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRequestTracker.tsx +++ b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificateRequestTracker.tsx @@ -71,7 +71,9 @@ export const CertificateRequestTracker = ({ requestId, onCertificateIssued }: Pr
{getStatusIcon()} - Request ID: {requestId} + + Certificate Request ID: {requestId} +
diff --git a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx index e7530027b..138e60de3 100644 --- a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx +++ b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx @@ -447,7 +447,8 @@ export const CreateProfileModal = ({ // Fetch Azure ADCS templates if needed const { data: azureAdcsTemplatesData } = useGetAzureAdcsTemplates({ caId: watchedCertificateAuthorityId || "", - projectId: currentProject?.id || "" + projectId: currentProject?.id || "", + isAzureAdcsCa }); useEffect(() => { @@ -732,7 +733,7 @@ export const CreateProfileModal = ({ name="externalConfigs.template" render={({ field: { onChange, value }, fieldState: { error } }) => (