refactor: streamline modal close handlers and completion callbacks across various components

This commit is contained in:
Victor Santos
2025-10-31 18:43:34 -03:00
parent 7d8b28367e
commit b26fb73053
116 changed files with 1865 additions and 2949 deletions
@@ -113,52 +113,44 @@ export const PkiAlertModal = ({ popUp, handlePopUpToggle }: Props) => {
alertUnit,
emails
}: FormData) => {
try {
if (!projectId) return;
if (!projectId) return;
const emailArray = emails
.split(",")
.map((email) => email.trim())
.filter((email) => email.length > 0);
const emailArray = emails
.split(",")
.map((email) => email.trim())
.filter((email) => email.length > 0);
const alertBeforeDays = convertToDays(alertUnit, Number(alertBefore));
const alertBeforeDays = convertToDays(alertUnit, Number(alertBefore));
if (alert) {
// update
await updatePkiAlert({
alertId: alert.id,
pkiCollectionId,
name,
projectId,
alertBeforeDays,
emails: emailArray
});
} else {
// create
await createPkiAlert({
name,
projectId,
pkiCollectionId,
alertBeforeDays,
emails: emailArray
});
}
handlePopUpToggle("pkiAlert", false);
reset();
createNotification({
text: `Successfully ${alert ? "updated" : "created"} alert`,
type: "success"
if (alert) {
// update
await updatePkiAlert({
alertId: alert.id,
pkiCollectionId,
name,
projectId,
alertBeforeDays,
emails: emailArray
});
} catch (err) {
console.error(err);
createNotification({
text: `Failed to ${alert ? "updated" : "created"} alert`,
type: "error"
} else {
// create
await createPkiAlert({
name,
projectId,
pkiCollectionId,
alertBeforeDays,
emails: emailArray
});
}
handlePopUpToggle("pkiAlert", false);
reset();
createNotification({
text: `Successfully ${alert ? "updated" : "created"} alert`,
type: "success"
});
};
return (
@@ -22,27 +22,19 @@ export const PkiAlertsSection = () => {
] as const);
const onRemoveAlertSubmit = async (alertId: string) => {
try {
if (!projectId) return;
if (!projectId) return;
await deletePkiAlert({
alertId,
projectId
});
await deletePkiAlert({
alertId,
projectId
});
createNotification({
text: "Successfully deleted alert",
type: "success"
});
createNotification({
text: "Successfully deleted alert",
type: "success"
});
handlePopUpClose("deletePkiAlert");
} catch (err) {
console.error(err);
createNotification({
text: "Failed to delete alert",
type: "error"
});
}
handlePopUpClose("deletePkiAlert");
};
return (
@@ -62,49 +62,41 @@ export const PkiCollectionModal = ({ popUp, handlePopUpToggle }: Props) => {
}, [pkiCollection]);
const onFormSubmit = async ({ name, description }: FormData) => {
try {
if (!projectId) return;
if (!projectId) return;
if (pkiCollection) {
// update
await updatePkiCollection({
collectionId: pkiCollection.id,
name,
description,
projectId
});
} else {
// create
const { id: collectionId } = await createPkiCollection({
name,
description,
projectId
});
navigate({
to: "/projects/cert-management/$projectId/pki-collections/$collectionId",
params: {
projectId,
collectionId
}
});
}
handlePopUpToggle("pkiCollection", false);
reset();
createNotification({
text: `Successfully ${pkiCollection ? "updated" : "created"} PKI collection`,
type: "success"
if (pkiCollection) {
// update
await updatePkiCollection({
collectionId: pkiCollection.id,
name,
description,
projectId
});
} catch (err) {
console.error(err);
createNotification({
text: `Failed to ${pkiCollection ? "updated" : "created"} PKI collection`,
type: "error"
} else {
// create
const { id: collectionId } = await createPkiCollection({
name,
description,
projectId
});
navigate({
to: "/projects/cert-management/$projectId/pki-collections/$collectionId",
params: {
projectId,
collectionId
}
});
}
handlePopUpToggle("pkiCollection", false);
reset();
createNotification({
text: `Successfully ${pkiCollection ? "updated" : "created"} PKI collection`,
type: "success"
});
};
return (
@@ -22,27 +22,19 @@ export const PkiCollectionSection = () => {
] as const);
const onRemovePkiCollectionSubmit = async (collectionId: string) => {
try {
if (!projectId) return;
if (!projectId) return;
await deletePkiCollection({
collectionId,
projectId
});
await deletePkiCollection({
collectionId,
projectId
});
createNotification({
text: "Successfully deleted PKI collection",
type: "success"
});
createNotification({
text: "Successfully deleted PKI collection",
type: "success"
});
handlePopUpClose("deletePkiCollection");
} catch (err) {
console.error(err);
createNotification({
text: "Failed to delete PKI collection",
type: "error"
});
}
handlePopUpClose("deletePkiCollection");
};
return (
@@ -57,33 +57,26 @@ const Page = () => {
] as const);
const onRemoveCaSubmit = async () => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
await deleteCa({
caName,
projectId: currentProject.id,
type: CaType.INTERNAL
});
await deleteCa({
caName,
projectId: currentProject.id,
type: CaType.INTERNAL
});
createNotification({
text: "Successfully deleted CA",
type: "success"
});
createNotification({
text: "Successfully deleted CA",
type: "success"
});
handlePopUpClose("deleteCa");
navigate({
to: "/projects/cert-management/$projectId/certificate-authorities",
params: {
projectId
}
});
} catch {
createNotification({
text: "Failed to delete CA",
type: "error"
});
}
handlePopUpClose("deleteCa");
navigate({
to: "/projects/cert-management/$projectId/certificate-authorities",
params: {
projectId
}
});
};
return (
@@ -84,27 +84,23 @@ export const CaRenewalModal = ({ popUp, handlePopUpToggle }: Props) => {
// }, [ca, parentCa]);
const onFormSubmit = async ({ type, notAfter }: FormData) => {
try {
if (!projectSlug || !popUpData.caId) return;
if (!projectSlug || !popUpData.caId) return;
await renewCa({
projectSlug,
caId: popUpData.caId,
notAfter,
type
});
await renewCa({
projectSlug,
caId: popUpData.caId,
notAfter,
type
});
handlePopUpToggle("renewCa", false);
handlePopUpToggle("renewCa", false);
createNotification({
text: "Successfully renewed CA",
type: "success"
});
createNotification({
text: "Successfully renewed CA",
type: "success"
});
reset();
} catch (err) {
console.error(err);
}
reset();
};
return (
@@ -48,29 +48,22 @@ export const ExternalCaInstallForm = ({ caId, handlePopUpToggle }: Props) => {
}, []);
const onFormSubmit = async ({ certificate, certificateChain }: FormData) => {
try {
if (!csr || !caId || !currentProject?.slug) return;
if (!csr || !caId || !currentProject?.slug) return;
await importCaCertificate({
caId,
projectSlug: currentProject?.slug,
certificate,
certificateChain
});
await importCaCertificate({
caId,
projectSlug: currentProject?.slug,
certificate,
certificateChain
});
reset();
reset();
createNotification({
text: "Successfully installed certificate for CA",
type: "success"
});
handlePopUpToggle("installCaCert", false);
} catch {
createNotification({
text: "Failed to install certificate for CA",
type: "error"
});
}
createNotification({
text: "Successfully installed certificate for CA",
type: "success"
});
handlePopUpToggle("installCaCert", false);
};
const downloadTxtFile = (filename: string, content: string) => {
@@ -101,37 +101,30 @@ export const InternalCaInstallForm = ({ caId, handlePopUpToggle }: Props) => {
}, [parentCa]);
const onFormSubmit = async ({ notAfter, maxPathLength }: FormData) => {
try {
if (!csr || !caId || !currentProject?.slug) return;
if (!csr || !caId || !currentProject?.slug) return;
const { certificate, certificateChain } = await signIntermediate({
caId: parentCaId,
csr,
maxPathLength: Number(maxPathLength),
notAfter,
notBefore: new Date().toISOString()
});
const { certificate, certificateChain } = await signIntermediate({
caId: parentCaId,
csr,
maxPathLength: Number(maxPathLength),
notAfter,
notBefore: new Date().toISOString()
});
await importCaCertificate({
caId,
projectSlug: currentProject?.slug,
certificate,
certificateChain
});
await importCaCertificate({
caId,
projectSlug: currentProject?.slug,
certificate,
certificateChain
});
reset();
reset();
createNotification({
text: "Successfully installed certificate for CA",
type: "success"
});
handlePopUpToggle("installCaCert", false);
} catch {
createNotification({
text: "Failed to install certificate for CA",
type: "error"
});
}
createNotification({
text: "Successfully installed certificate for CA",
type: "success"
});
handlePopUpToggle("installCaCert", false);
};
function generatePathLengthOpts(parentCaMaxPathLength: number): number[] {
@@ -175,48 +175,40 @@ export const CaModal = ({ popUp, handlePopUpToggle }: Props) => {
status,
configuration
}: FormData) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
if (ca) {
// update
await updateMutateAsync({
caName: ca.name,
projectId: currentProject.id,
name,
type: CaType.INTERNAL,
status,
enableDirectIssuance
});
} else {
// create
await createMutateAsync({
projectId: currentProject.id,
name,
type,
status,
enableDirectIssuance,
configuration: {
...configuration,
maxPathLength: Number(configuration.maxPathLength)
}
});
}
reset();
handlePopUpToggle("ca", false);
createNotification({
text: `Successfully ${ca ? "updated" : "created"} CA`,
type: "success"
if (ca) {
// update
await updateMutateAsync({
caName: ca.name,
projectId: currentProject.id,
name,
type: CaType.INTERNAL,
status,
enableDirectIssuance
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to create CA",
type: "error"
} else {
// create
await createMutateAsync({
projectId: currentProject.id,
name,
type,
status,
enableDirectIssuance,
configuration: {
...configuration,
maxPathLength: Number(configuration.maxPathLength)
}
});
}
reset();
handlePopUpToggle("ca", false);
createNotification({
text: `Successfully ${ca ? "updated" : "created"} CA`,
type: "success"
});
};
return (
@@ -29,44 +29,29 @@ export const CaSection = () => {
] as const);
const onRemoveCaSubmit = async (caName: string) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
await deleteCa({ caName, projectId: currentProject.id, type: CaType.INTERNAL });
await deleteCa({ caName, projectId: currentProject.id, type: CaType.INTERNAL });
createNotification({
text: "Successfully deleted CA",
type: "success"
});
createNotification({
text: "Successfully deleted CA",
type: "success"
});
handlePopUpClose("deleteCa");
} catch {
createNotification({
text: "Failed to delete CA",
type: "error"
});
}
handlePopUpClose("deleteCa");
};
const onUpdateCaStatus = async ({ caName, status }: { caName: string; status: CaStatus }) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
await updateCa({ caName, projectId: currentProject.id, type: CaType.INTERNAL, status });
await updateCa({ caName, projectId: currentProject.id, type: CaType.INTERNAL, status });
createNotification({
text: `Successfully ${status === CaStatus.ACTIVE ? "enabled" : "disabled"} CA`,
type: "success"
});
createNotification({
text: `Successfully ${status === CaStatus.ACTIVE ? "enabled" : "disabled"} CA`,
type: "success"
});
handlePopUpClose("caStatus");
} catch (err) {
console.error(err);
createNotification({
text: `Failed to ${status === CaStatus.ACTIVE ? "enabled" : "disabled"} CA`,
type: "error"
});
}
handlePopUpClose("caStatus");
};
return (
@@ -297,63 +297,55 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
status,
configuration: formConfiguration
}: FormData) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
let configPayload: any;
let configPayload: any;
if (type === CaType.ACME && "dnsAppConnection" in formConfiguration) {
configPayload = {
dnsProviderConfig: formConfiguration.dnsProviderConfig,
directoryUrl: formConfiguration.directoryUrl,
accountEmail: formConfiguration.accountEmail,
dnsAppConnectionId: formConfiguration.dnsAppConnection.id,
eabKid: formConfiguration.eabKid,
eabHmacKey: formConfiguration.eabHmacKey
};
} else if (type === CaType.AZURE_AD_CS && "azureAdcsConnection" in formConfiguration) {
configPayload = {
azureAdcsConnectionId: formConfiguration.azureAdcsConnection.id
};
} else {
throw new Error("Invalid certificate authority configuration");
}
if (type === CaType.ACME && "dnsAppConnection" in formConfiguration) {
configPayload = {
dnsProviderConfig: formConfiguration.dnsProviderConfig,
directoryUrl: formConfiguration.directoryUrl,
accountEmail: formConfiguration.accountEmail,
dnsAppConnectionId: formConfiguration.dnsAppConnection.id,
eabKid: formConfiguration.eabKid,
eabHmacKey: formConfiguration.eabHmacKey
};
} else if (type === CaType.AZURE_AD_CS && "azureAdcsConnection" in formConfiguration) {
configPayload = {
azureAdcsConnectionId: formConfiguration.azureAdcsConnection.id
};
} else {
throw new Error("Invalid certificate authority configuration");
}
if (ca) {
await updateMutateAsync({
caName: ca.name,
projectId: currentProject.id,
name,
type,
status,
enableDirectIssuance: type === CaType.AZURE_AD_CS ? false : enableDirectIssuance,
configuration: configPayload
});
} else {
await createMutateAsync({
projectId: currentProject.id,
name,
type,
status,
enableDirectIssuance: type === CaType.AZURE_AD_CS ? false : enableDirectIssuance,
configuration: configPayload
});
}
reset();
handlePopUpToggle("ca", false);
createNotification({
text: `Successfully ${ca ? "updated" : "created"} CA`,
type: "success"
if (ca) {
await updateMutateAsync({
caName: ca.name,
projectId: currentProject.id,
name,
type,
status,
enableDirectIssuance: type === CaType.AZURE_AD_CS ? false : enableDirectIssuance,
configuration: configPayload
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to create CA",
type: "error"
} else {
await createMutateAsync({
projectId: currentProject.id,
name,
type,
status,
enableDirectIssuance: type === CaType.AZURE_AD_CS ? false : enableDirectIssuance,
configuration: configPayload
});
}
reset();
handlePopUpToggle("ca", false);
createNotification({
text: `Successfully ${ca ? "updated" : "created"} CA`,
type: "success"
});
};
return (
@@ -25,23 +25,16 @@ export const ExternalCaSection = () => {
] as const);
const onRemoveCaSubmit = async (caName: string, type: CaType) => {
try {
if (!currentProject?.id) return;
if (!currentProject?.id) return;
await deleteCa({ caName, type, projectId: currentProject.id });
await deleteCa({ caName, type, projectId: currentProject.id });
createNotification({
text: "Successfully deleted CA",
type: "success"
});
createNotification({
text: "Successfully deleted CA",
type: "success"
});
handlePopUpClose("deleteCa");
} catch {
createNotification({
text: "Failed to delete CA",
type: "error"
});
}
handlePopUpClose("deleteCa");
};
const onUpdateCaStatus = async ({
@@ -53,24 +46,16 @@ export const ExternalCaSection = () => {
type: CaType;
status: CaStatus;
}) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
await updateCa({ caName: name, type, status, projectId: currentProject.id });
await updateCa({ caName: name, type, status, projectId: currentProject.id });
createNotification({
text: `Successfully ${status === CaStatus.ACTIVE ? "enabled" : "disabled"} CA`,
type: "success"
});
createNotification({
text: `Successfully ${status === CaStatus.ACTIVE ? "enabled" : "disabled"} CA`,
type: "success"
});
handlePopUpClose("caStatus");
} catch (err) {
console.error(err);
createNotification({
text: `Failed to ${status === CaStatus.ACTIVE ? "enable" : "disable"} CA`,
type: "error"
});
}
handlePopUpClose("caStatus");
};
return (
@@ -71,38 +71,30 @@ export const CertificateImportModal = ({ popUp, handlePopUpToggle }: Props) => {
chainPem,
collectionId
}: FormData) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
const { serialNumber, certificate, certificateChain, privateKey } = await importCertificate({
projectSlug: currentProject.slug,
const { serialNumber, certificate, certificateChain, privateKey } = await importCertificate({
projectSlug: currentProject.slug,
certificatePem,
privateKeyPem,
chainPem,
pkiCollectionId: collectionId
});
certificatePem,
privateKeyPem,
chainPem,
pkiCollectionId: collectionId
});
reset();
reset();
setCertificateDetails({
serialNumber,
certificate,
certificateChain,
privateKey
});
setCertificateDetails({
serialNumber,
certificate,
certificateChain,
privateKey
});
createNotification({
text: "Successfully imported certificate",
type: "success"
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to import certificate",
type: "error"
});
}
createNotification({
text: "Successfully imported certificate",
type: "success"
});
};
return (
@@ -242,84 +242,72 @@ export const CertificateIssuanceModal = ({ popUp, handlePopUpToggle, profileId }
keyUsages,
extendedKeyUsages
}: FormData) => {
try {
if (!currentProject?.slug) {
createNotification({
text: "Project not found. Please refresh and try again.",
type: "error"
});
return;
}
if (!formProfileId) {
createNotification({
text: "Please select a certificate profile.",
type: "error"
});
return;
}
let commonName = "";
if (
constraints.shouldShowSubjectSection &&
subjectAttributes &&
subjectAttributes.length > 0
) {
commonName = getAttributeValue(subjectAttributes, "common_name");
if (!commonName.trim()) {
createNotification({
text: "Common name is required.",
type: "error"
});
return;
}
}
const certificateRequest: any = {
profileId: formProfileId,
projectSlug: currentProject.slug,
ttl,
signatureAlgorithm,
keyAlgorithm,
keyUsages: filterUsages(keyUsages) as CertKeyUsage[],
extendedKeyUsages: filterUsages(extendedKeyUsages) as CertExtendedKeyUsage[]
};
if (constraints.shouldShowSubjectSection && commonName) {
certificateRequest.commonName = commonName;
}
if (constraints.shouldShowSanSection && subjectAltNames && subjectAltNames.length > 0) {
const formattedSans = formatSubjectAltNames(subjectAltNames);
if (formattedSans && formattedSans.length > 0) {
certificateRequest.altNames = formattedSans;
}
}
const { serialNumber, certificate, certificateChain, privateKey } =
await createCertificate(certificateRequest);
setCertificateDetails({
serialNumber,
certificate,
certificateChain,
privateKey
});
if (!currentProject?.slug) {
createNotification({
text: "Successfully created certificate",
type: "success"
});
} catch (err) {
console.error("Certificate creation failed:", err);
const errorMessage =
err instanceof Error
? err.message
: "An unexpected error occurred while creating the certificate";
createNotification({
text: `Failed to create certificate: ${errorMessage}`,
text: "Project not found. Please refresh and try again.",
type: "error"
});
return;
}
if (!formProfileId) {
createNotification({
text: "Please select a certificate profile.",
type: "error"
});
return;
}
let commonName = "";
if (
constraints.shouldShowSubjectSection &&
subjectAttributes &&
subjectAttributes.length > 0
) {
commonName = getAttributeValue(subjectAttributes, "common_name");
if (!commonName.trim()) {
createNotification({
text: "Common name is required.",
type: "error"
});
return;
}
}
const certificateRequest: any = {
profileId: formProfileId,
projectSlug: currentProject.slug,
ttl,
signatureAlgorithm,
keyAlgorithm,
keyUsages: filterUsages(keyUsages) as CertKeyUsage[],
extendedKeyUsages: filterUsages(extendedKeyUsages) as CertExtendedKeyUsage[]
};
if (constraints.shouldShowSubjectSection && commonName) {
certificateRequest.commonName = commonName;
}
if (constraints.shouldShowSanSection && subjectAltNames && subjectAltNames.length > 0) {
const formattedSans = formatSubjectAltNames(subjectAltNames);
if (formattedSans && formattedSans.length > 0) {
certificateRequest.altNames = formattedSans;
}
}
const { serialNumber, certificate, certificateChain, privateKey } =
await createCertificate(certificateRequest);
setCertificateDetails({
serialNumber,
certificate,
certificateChain,
privateKey
});
createNotification({
text: "Successfully created certificate",
type: "success"
});
},
[
currentProject?.slug,
@@ -163,38 +163,28 @@ export const CertificateManageRenewalModal = ({ popUp, handlePopUpToggle }: Prop
}, [popUp.manageRenewal.isOpen, defaultRenewalDays, reset]);
const onUpdateRenewal = async (data: FormData) => {
try {
if (!currentProject?.slug) {
createNotification({
text: "Unable to update auto-renewal: Project not found. Please refresh the page and try again.",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId: certificateData.certificateId,
renewBeforeDays: data.renewBeforeDays,
projectSlug: currentProject.slug
});
if (!currentProject?.slug) {
createNotification({
text: isAutoRenewalEnabled
? "Auto-renewal configuration updated successfully"
: "Auto-renewal enabled successfully",
type: "success"
});
handlePopUpToggle("manageRenewal", false);
} catch (err) {
console.error(err);
createNotification({
text: isAutoRenewalEnabled
? "Failed to update auto-renewal configuration. Please check your inputs and try again."
: "Failed to enable auto-renewal. Please check your inputs and try again.",
text: "Unable to update auto-renewal: Project not found. Please refresh the page and try again.",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId: certificateData.certificateId,
renewBeforeDays: data.renewBeforeDays,
projectSlug: currentProject.slug
});
createNotification({
text: isAutoRenewalEnabled
? "Auto-renewal configuration updated successfully"
: "Auto-renewal enabled successfully",
type: "success"
});
handlePopUpToggle("manageRenewal", false);
};
const getModalTitle = () => {
@@ -186,45 +186,37 @@ export const CertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
keyUsages,
extendedKeyUsages
}: FormData) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
const { serialNumber, certificate, certificateChain, privateKey } = await createCertificate({
caId: !selectedCertTemplate ? caId : undefined,
certificateTemplateId: selectedCertTemplate ? selectedCertTemplateId : undefined,
projectSlug: currentProject.slug,
pkiCollectionId: collectionId,
commonName,
subjectAltNames,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
const { serialNumber, certificate, certificateChain, privateKey } = await createCertificate({
caId: !selectedCertTemplate ? caId : undefined,
certificateTemplateId: selectedCertTemplate ? selectedCertTemplateId : undefined,
projectSlug: currentProject.slug,
pkiCollectionId: collectionId,
commonName,
subjectAltNames,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
reset();
reset();
setCertificateDetails({
serialNumber,
certificate,
certificateChain,
privateKey
});
setCertificateDetails({
serialNumber,
certificate,
certificateChain,
privateKey
});
createNotification({
text: "Successfully created certificate",
type: "success"
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to create certificate",
type: "error"
});
}
createNotification({
text: "Successfully created certificate",
type: "success"
});
};
useEffect(() => {
@@ -61,34 +61,26 @@ export const CertificateRenewalConfigModal = ({ popUp, handlePopUpToggle }: Prop
const renewBeforeDays = watch("renewBeforeDays");
const onSubmit = async (data: FormData) => {
try {
if (!currentProject?.slug) {
createNotification({
text: "Project not found",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId: certificateData.certificateId,
renewBeforeDays: data.renewBeforeDays,
projectSlug: currentProject.slug
});
if (!currentProject?.slug) {
createNotification({
text: "Successfully updated auto-renewal configuration",
type: "success"
});
handlePopUpToggle("configureRenewal", false);
} catch (err) {
console.error(err);
createNotification({
text: "Failed to update auto-renewal configuration",
text: "Project not found",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId: certificateData.certificateId,
renewBeforeDays: data.renewBeforeDays,
projectSlug: currentProject.slug
});
createNotification({
text: "Successfully updated auto-renewal configuration",
type: "success"
});
handlePopUpToggle("configureRenewal", false);
};
return (
@@ -19,34 +19,26 @@ export const CertificateRenewalDisableModal = ({ popUp, handlePopUpToggle }: Pro
};
const onDisableConfirm = async () => {
try {
if (!currentProject?.slug) {
createNotification({
text: "Project not found",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId: certificateData.certificateId,
projectSlug: currentProject.slug,
enableAutoRenewal: false
});
if (!currentProject?.slug) {
createNotification({
text: "Successfully disabled auto-renewal",
type: "success"
});
handlePopUpToggle("disableRenewal", false);
} catch (err) {
console.error(err);
createNotification({
text: "Failed to disable auto-renewal",
text: "Project not found",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId: certificateData.certificateId,
projectSlug: currentProject.slug,
enableAutoRenewal: false
});
createNotification({
text: "Successfully disabled auto-renewal",
type: "success"
});
handlePopUpToggle("disableRenewal", false);
};
return (
@@ -18,22 +18,18 @@ export const CertificateRenewalModal = ({ popUp, handlePopUpToggle }: Props) =>
const { mutateAsync: renewCertificate, isPending: isRenewing } = useRenewCertificate();
const onRenewConfirm = async () => {
try {
const { certificateId } = popUp.renewCertificate.data as { certificateId: string };
const { certificateId } = popUp.renewCertificate.data as { certificateId: string };
await renewCertificate({
certificateId
});
await renewCertificate({
certificateId
});
createNotification({
text: "Certificate renewed successfully",
type: "success"
});
createNotification({
text: "Certificate renewed successfully",
type: "success"
});
handlePopUpToggle("renewCertificate", false);
} catch (err) {
console.error(err);
}
handlePopUpToggle("renewCertificate", false);
};
const certificateData = popUp.renewCertificate.data as {
@@ -48,31 +48,23 @@ export const CertificateRevocationModal = ({ popUp, handlePopUpToggle }: Props)
});
const onFormSubmit = async ({ revocationReason }: FormData) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
const { serialNumber } = popUp.revokeCertificate.data as { serialNumber: string };
const { serialNumber } = popUp.revokeCertificate.data as { serialNumber: string };
await revokeCertificate({
projectSlug: currentProject.slug,
serialNumber,
revocationReason
});
await revokeCertificate({
projectSlug: currentProject.slug,
serialNumber,
revocationReason
});
reset();
handlePopUpToggle("revokeCertificate", false);
reset();
handlePopUpToggle("revokeCertificate", false);
createNotification({
text: "Successfully revoked certificate",
type: "success"
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to revoke certificate",
type: "error"
});
}
createNotification({
text: "Successfully revoked certificate",
type: "success"
});
};
return (
@@ -159,61 +159,53 @@ export const CertificateTemplateModal = ({ popUp, handlePopUpToggle, caId }: Pro
return;
}
try {
if (certTemplate) {
await updateCertTemplate({
id: certTemplate.id,
projectId: currentProject.id,
pkiCollectionId: collectionId,
caId,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
if (certTemplate) {
await updateCertTemplate({
id: certTemplate.id,
projectId: currentProject.id,
pkiCollectionId: collectionId,
caId,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
createNotification({
text: "Successfully updated certificate template",
type: "success"
});
} else {
await createCertTemplate({
projectId: currentProject.id,
pkiCollectionId: collectionId,
caId,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
createNotification({
text: "Successfully created certificate template",
type: "success"
});
}
reset();
handlePopUpToggle("certificateTemplate", false);
} catch (err) {
console.error(err);
createNotification({
text: "Failed to save changes",
type: "error"
text: "Successfully updated certificate template",
type: "success"
});
} else {
await createCertTemplate({
projectId: currentProject.id,
pkiCollectionId: collectionId,
caId,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
createNotification({
text: "Successfully created certificate template",
type: "success"
});
}
reset();
handlePopUpToggle("certificateTemplate", false);
};
return (
@@ -41,25 +41,17 @@ export const CertificateTemplatesSection = ({ caId }: Props) => {
return;
}
try {
await deleteCertTemplate({
id,
projectId: currentProject.id
});
await deleteCertTemplate({
id,
projectId: currentProject.id
});
createNotification({
text: "Successfully deleted certificate template",
type: "success"
});
createNotification({
text: "Successfully deleted certificate template",
type: "success"
});
handlePopUpClose("deleteCertificateTemplate");
} catch (err) {
console.error(err);
createNotification({
text: "Failed to delete certificate template",
type: "error"
});
}
handlePopUpClose("deleteCertificateTemplate");
};
return (
@@ -41,24 +41,16 @@ export const CertificatesSection = () => {
] as const);
const onRemoveCertificateSubmit = async (serialNumber: string) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
await deleteCert({ serialNumber, projectSlug: currentProject.slug });
await deleteCert({ serialNumber, projectSlug: currentProject.slug });
createNotification({
text: "Successfully deleted certificate",
type: "success"
});
createNotification({
text: "Successfully deleted certificate",
type: "success"
});
handlePopUpClose("deleteCertificate");
} catch (err) {
console.error(err);
createNotification({
text: "Failed to delete certificate",
type: "error"
});
}
handlePopUpClose("deleteCertificate");
};
return (
@@ -200,32 +200,24 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => {
}, [caData]);
const handleDisableAutoRenewal = async (certificateId: string, commonName: string) => {
try {
if (!currentProject?.slug) {
createNotification({
text: "Unable to disable auto-renewal: Project not found. Please refresh the page and try again.",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId,
projectSlug: currentProject.slug,
enableAutoRenewal: false
});
if (!currentProject?.slug) {
createNotification({
text: `Auto-renewal disabled for ${commonName}`,
type: "success"
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to disable auto-renewal. Please try again or contact support if the issue persists.",
text: "Unable to disable auto-renewal: Project not found. Please refresh the page and try again.",
type: "error"
});
return;
}
await updateRenewalConfig({
certificateId,
projectSlug: currentProject.slug,
enableAutoRenewal: false
});
createNotification({
text: `Auto-renewal disabled for ${commonName}`,
type: "success"
});
};
return (
@@ -226,46 +226,32 @@ export const PkiSyncsTable = ({ pkiSyncs }: Props) => {
const isAutoSyncEnabled = !pkiSync.isAutoSyncEnabled;
try {
await updateSync.mutateAsync({
syncId: pkiSync.id,
projectId: pkiSync.projectId,
destination: pkiSync.destination,
isAutoSyncEnabled
});
await updateSync.mutateAsync({
syncId: pkiSync.id,
projectId: pkiSync.projectId,
destination: pkiSync.destination,
isAutoSyncEnabled
});
createNotification({
text: `Successfully ${isAutoSyncEnabled ? "enabled" : "disabled"} auto-sync for ${destinationName} Sync`,
type: "success"
});
} catch {
createNotification({
text: `Failed to ${isAutoSyncEnabled ? "enable" : "disable"} auto-sync for ${destinationName} Sync`,
type: "error"
});
}
createNotification({
text: `Successfully ${isAutoSyncEnabled ? "enabled" : "disabled"} auto-sync for ${destinationName} Sync`,
type: "success"
});
};
const handleTriggerSync = async (pkiSync: TPkiSync) => {
const destinationName = PKI_SYNC_MAP[pkiSync.destination].name;
try {
await triggerSync.mutateAsync({
syncId: pkiSync.id,
destination: pkiSync.destination,
projectId: pkiSync.projectId
});
await triggerSync.mutateAsync({
syncId: pkiSync.id,
destination: pkiSync.destination,
projectId: pkiSync.projectId
});
createNotification({
text: `Successfully triggered ${destinationName} Sync`,
type: "success"
});
} catch {
createNotification({
text: `Failed to trigger ${destinationName} Sync`,
type: "error"
});
}
createNotification({
text: `Successfully triggered ${destinationName} Sync`,
type: "success"
});
};
return (
@@ -45,31 +45,24 @@ export const PkiCollectionPage = () => {
] as const);
const onDeletePkiCollectionSubmit = async (collectionIdToDelete: string) => {
try {
if (!projectId) return;
if (!projectId) return;
await deletePkiCollection({
projectId,
collectionId: collectionIdToDelete
});
await deletePkiCollection({
projectId,
collectionId: collectionIdToDelete
});
createNotification({
text: "Successfully deleted PKI collection",
type: "success"
});
handlePopUpClose("deletePkiCollection");
navigate({
to: "/projects/cert-management/$projectId/certificates",
params: {
projectId
}
});
} catch {
createNotification({
text: "Failed to delete PKI collection",
type: "error"
});
}
createNotification({
text: "Successfully deleted PKI collection",
type: "success"
});
handlePopUpClose("deletePkiCollection");
navigate({
to: "/projects/cert-management/$projectId/certificates",
params: {
projectId
}
});
};
return (
@@ -51,30 +51,22 @@ const Page = () => {
] as const);
const onRemoveSubscriberSubmit = async (subscriberNameToDelete: string) => {
try {
if (!projectId) return;
if (!projectId) return;
await deletePkiSubscriber({ subscriberName: subscriberNameToDelete, projectId });
await deletePkiSubscriber({ subscriberName: subscriberNameToDelete, projectId });
createNotification({
text: "Successfully deleted subscriber",
type: "success"
});
createNotification({
text: "Successfully deleted subscriber",
type: "success"
});
handlePopUpClose("deletePkiSubscriber");
navigate({
to: "/projects/cert-management/$projectId/subscribers",
params: {
projectId
}
});
} catch (err) {
console.error(err);
createNotification({
text: "Failed to delete subscriber",
type: "error"
});
}
handlePopUpClose("deletePkiSubscriber");
navigate({
to: "/projects/cert-management/$projectId/subscribers",
params: {
projectId
}
});
};
return (
@@ -70,36 +70,28 @@ export const PkiSubscriberDetailsSection = ({ subscriberName, handlePopUpOpen }:
useOrderPkiSubscriberCert();
const onIssuePkiSubscriberCert = async () => {
try {
if (pkiSubscriber?.supportsImmediateCertIssuance) {
const response = await issuePkiSubscriberCert({ subscriberName, projectId });
if (pkiSubscriber?.supportsImmediateCertIssuance) {
const response = await issuePkiSubscriberCert({ subscriberName, projectId });
setCertificateDetails({
serialNumber: response.serialNumber,
certificate: response.certificate,
certificateChain: response.certificateChain,
privateKey: response.privateKey
});
setCertificateDetails({
serialNumber: response.serialNumber,
certificate: response.certificate,
certificateChain: response.certificateChain,
privateKey: response.privateKey
});
setIsModalOpen(true);
setIsModalOpen(true);
createNotification({
text: "Successfully issued certificate",
type: "success"
});
} else {
await orderPkiSubscriberCert({ subscriberName, projectId });
createNotification({
text: "Successfully ordered certificate. It will be issued after CA processing which could take a few minutes.",
type: "info"
});
}
} catch (err) {
console.error(err);
createNotification({
text: "Failed to issue certificate",
type: "error"
text: "Successfully issued certificate",
type: "success"
});
} else {
await orderPkiSubscriberCert({ subscriberName, projectId });
createNotification({
text: "Successfully ordered certificate. It will be issued after CA processing which could take a few minutes.",
type: "info"
});
}
};
@@ -276,117 +276,109 @@ export const PkiSubscriberModal = ({ popUp, handlePopUpToggle }: Props) => {
locality,
emailAddress
}: FormData) => {
try {
if (!projectId) return;
if (!caId) {
createNotification({
text: "Please select an Issuing CA",
type: "error"
});
return;
}
// Check if there is already a different subscriber with the same name
const existingNames =
subscribers?.filter((s) => s.id !== pkiSubscriber?.id).map((s) => s.name) || [];
if (existingNames.includes(name.trim())) {
createNotification({
text: "A subscriber with this name already exists.",
type: "error"
});
return;
}
// Validate Azure template for Azure ADCS CA
if (selectedCa?.type === CaType.AZURE_AD_CS && !azureTemplateType) {
createNotification({
text: "Please select an Azure certificate template",
type: "error"
});
return;
}
const keyUsagesList =
selectedCa?.type === CaType.AZURE_AD_CS
? []
: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage);
const extendedKeyUsagesList =
selectedCa?.type === CaType.AZURE_AD_CS
? []
: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage);
const subjectAlternativeNamesList = subjectAlternativeNames
.split(",")
.map((san) => san.trim())
.filter(Boolean);
const autoRenewalPeriodInDays = enableAutoRenewal
? convertTimeUnitValueToDays(renewalUnit, renewalBefore)
: undefined;
// Build properties object
const properties = {
...(selectedCa?.type === CaType.AZURE_AD_CS && azureTemplateType && { azureTemplateType }),
...(organization && { organization }),
...(organizationalUnit && { organizationalUnit }),
...(country && { country }),
...(state && { state }),
...(locality && { locality }),
...(emailAddress && { emailAddress })
};
if (pkiSubscriber) {
await updateMutateAsync({
subscriberName: pkiSubscriber.name,
projectId,
name,
caId,
commonName,
subjectAlternativeNames: subjectAlternativeNamesList,
ttl,
keyUsages: keyUsagesList,
extendedKeyUsages: extendedKeyUsagesList,
enableAutoRenewal,
autoRenewalPeriodInDays,
properties: Object.keys(properties).length > 0 ? properties : undefined
});
} else {
await createMutateAsync({
projectId,
name,
caId,
commonName,
subjectAlternativeNames: subjectAlternativeNamesList,
ttl,
keyUsages: keyUsagesList,
extendedKeyUsages: extendedKeyUsagesList,
enableAutoRenewal,
autoRenewalPeriodInDays,
properties: Object.keys(properties).length > 0 ? properties : undefined
});
}
reset();
handlePopUpToggle("pkiSubscriber", false);
if (!projectId) return;
if (!caId) {
createNotification({
text: `Successfully ${pkiSubscriber ? "updated" : "added"} PKI subscriber`,
type: "success"
});
} catch (err) {
console.error(err);
createNotification({
text: `Failed to ${pkiSubscriber ? "update" : "add"} PKI subscriber`,
text: "Please select an Issuing CA",
type: "error"
});
return;
}
// Check if there is already a different subscriber with the same name
const existingNames =
subscribers?.filter((s) => s.id !== pkiSubscriber?.id).map((s) => s.name) || [];
if (existingNames.includes(name.trim())) {
createNotification({
text: "A subscriber with this name already exists.",
type: "error"
});
return;
}
// Validate Azure template for Azure ADCS CA
if (selectedCa?.type === CaType.AZURE_AD_CS && !azureTemplateType) {
createNotification({
text: "Please select an Azure certificate template",
type: "error"
});
return;
}
const keyUsagesList =
selectedCa?.type === CaType.AZURE_AD_CS
? []
: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage);
const extendedKeyUsagesList =
selectedCa?.type === CaType.AZURE_AD_CS
? []
: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage);
const subjectAlternativeNamesList = subjectAlternativeNames
.split(",")
.map((san) => san.trim())
.filter(Boolean);
const autoRenewalPeriodInDays = enableAutoRenewal
? convertTimeUnitValueToDays(renewalUnit, renewalBefore)
: undefined;
// Build properties object
const properties = {
...(selectedCa?.type === CaType.AZURE_AD_CS && azureTemplateType && { azureTemplateType }),
...(organization && { organization }),
...(organizationalUnit && { organizationalUnit }),
...(country && { country }),
...(state && { state }),
...(locality && { locality }),
...(emailAddress && { emailAddress })
};
if (pkiSubscriber) {
await updateMutateAsync({
subscriberName: pkiSubscriber.name,
projectId,
name,
caId,
commonName,
subjectAlternativeNames: subjectAlternativeNamesList,
ttl,
keyUsages: keyUsagesList,
extendedKeyUsages: extendedKeyUsagesList,
enableAutoRenewal,
autoRenewalPeriodInDays,
properties: Object.keys(properties).length > 0 ? properties : undefined
});
} else {
await createMutateAsync({
projectId,
name,
caId,
commonName,
subjectAlternativeNames: subjectAlternativeNamesList,
ttl,
keyUsages: keyUsagesList,
extendedKeyUsages: extendedKeyUsagesList,
enableAutoRenewal,
autoRenewalPeriodInDays,
properties: Object.keys(properties).length > 0 ? properties : undefined
});
}
reset();
handlePopUpToggle("pkiSubscriber", false);
createNotification({
text: `Successfully ${pkiSubscriber ? "updated" : "added"} PKI subscriber`,
type: "success"
});
};
return (
@@ -33,22 +33,14 @@ export const PkiSubscriberSection = () => {
] as const);
const onRemovePkiSubscriberSubmit = async (subscriberName: string) => {
try {
const subscriber = await deletePkiSubscriber({ subscriberName, projectId });
const subscriber = await deletePkiSubscriber({ subscriberName, projectId });
createNotification({
text: `Successfully deleted PKI subscriber: ${subscriber.name}`,
type: "success"
});
createNotification({
text: `Successfully deleted PKI subscriber: ${subscriber.name}`,
type: "success"
});
handlePopUpClose("deletePkiSubscriber");
} catch (err) {
console.error(err);
createNotification({
text: "Failed to delete PKI subscriber",
type: "error"
});
}
handlePopUpClose("deletePkiSubscriber");
};
const onUpdatePkiSubscriberStatus = async ({
@@ -58,24 +50,16 @@ export const PkiSubscriberSection = () => {
subscriberName: string;
status: PkiSubscriberStatus;
}) => {
try {
if (!currentProject?.slug) return;
if (!currentProject?.slug) return;
await updatePkiSubscriber({ subscriberName, projectId, status });
await updatePkiSubscriber({ subscriberName, projectId, status });
createNotification({
text: `Successfully ${status === PkiSubscriberStatus.ACTIVE ? "enabled" : "disabled"} subscriber`,
type: "success"
});
createNotification({
text: `Successfully ${status === PkiSubscriberStatus.ACTIVE ? "enabled" : "disabled"} subscriber`,
type: "success"
});
handlePopUpClose("pkiSubscriberStatus");
} catch (err) {
console.error(err);
createNotification({
text: `Failed to ${status === PkiSubscriberStatus.ACTIVE ? "enable" : "disable"} subscriber`,
type: "error"
});
}
handlePopUpClose("pkiSubscriberStatus");
};
const subscriberStatusData = popUp?.pkiSubscriberStatus?.data as {
@@ -86,44 +86,28 @@ export const PkiSyncActionTriggers = ({ pkiSync }: Props) => {
}, [pkiSync.id, setIsIdCopied]);
const handleTriggerSync = useCallback(async () => {
try {
await triggerSyncMutation.mutateAsync({
syncId: id,
destination,
projectId
});
createNotification({
text: "PKI sync job queued successfully",
type: "success"
});
} catch (error) {
console.error("Failed to trigger sync:", error);
createNotification({
text: "Failed to trigger PKI sync",
type: "error"
});
}
await triggerSyncMutation.mutateAsync({
syncId: id,
destination,
projectId
});
createNotification({
text: "PKI sync job queued successfully",
type: "success"
});
}, [triggerSyncMutation, id, destination, projectId]);
const handleToggleAutoSync = useCallback(async () => {
try {
await updatePkiSyncMutation.mutateAsync({
syncId: id,
projectId,
destination,
isAutoSyncEnabled: !pkiSync.isAutoSyncEnabled
});
createNotification({
text: `Auto-sync ${pkiSync.isAutoSyncEnabled ? "disabled" : "enabled"} successfully`,
type: "success"
});
} catch (error) {
console.error("Failed to toggle auto-sync:", error);
createNotification({
text: "Failed to toggle auto-sync",
type: "error"
});
}
await updatePkiSyncMutation.mutateAsync({
syncId: id,
projectId,
destination,
isAutoSyncEnabled: !pkiSync.isAutoSyncEnabled
});
createNotification({
text: `Auto-sync ${pkiSync.isAutoSyncEnabled ? "disabled" : "enabled"} successfully`,
type: "success"
});
}, [updatePkiSyncMutation, id, projectId, pkiSync.isAutoSyncEnabled]);
const permissionSubject = subject(ProjectPermissionSub.PkiSyncs, {
@@ -78,25 +78,17 @@ export const PkiTemplateListPage = () => {
const deleteCertTemplate = useDeleteCertTemplateV2();
const onRemovePkiSubscriberSubmit = async () => {
try {
const pkiTemplate = await deleteCertTemplate.mutateAsync({
projectId: currentProject.id,
templateName: popUp?.deleteTemplate?.data?.name
});
const pkiTemplate = await deleteCertTemplate.mutateAsync({
projectId: currentProject.id,
templateName: popUp?.deleteTemplate?.data?.name
});
createNotification({
text: `Successfully deleted PKI template: ${pkiTemplate.name}`,
type: "success"
});
createNotification({
text: `Successfully deleted PKI template: ${pkiTemplate.name}`,
type: "success"
});
handlePopUpClose("deleteTemplate");
} catch (err) {
console.error(err);
createNotification({
text: "Failed to delete PKI subscriber",
type: "error"
});
}
handlePopUpClose("deleteTemplate");
};
return (
@@ -128,59 +128,51 @@ export const PkiTemplateForm = ({ certTemplate, handlePopUpToggle }: Props) => {
return;
}
try {
if (certTemplate) {
await updateCertTemplate({
templateName: certTemplate.name,
projectId: currentProject.id,
caName: ca.name,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
if (certTemplate) {
await updateCertTemplate({
templateName: certTemplate.name,
projectId: currentProject.id,
caName: ca.name,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
createNotification({
text: "Successfully updated certificate template",
type: "success"
});
} else {
await createCertTemplate({
projectId: currentProject.id,
caName: ca.name,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
createNotification({
text: "Successfully created certificate template",
type: "success"
});
}
reset();
handlePopUpToggle(false);
} catch (err) {
console.error(err);
createNotification({
text: "Failed to save changes",
type: "error"
text: "Successfully updated certificate template",
type: "success"
});
} else {
await createCertTemplate({
projectId: currentProject.id,
caName: ca.name,
name,
commonName,
subjectAlternativeName,
ttl,
keyUsages: Object.entries(keyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertKeyUsage),
extendedKeyUsages: Object.entries(extendedKeyUsages)
.filter(([, value]) => value)
.map(([key]) => key as CertExtendedKeyUsage)
});
createNotification({
text: "Successfully created certificate template",
type: "success"
});
}
reset();
handlePopUpToggle(false);
};
return (
@@ -51,22 +51,15 @@ export const CertificateProfilesTab = () => {
const handleDeleteConfirm = async () => {
if (!selectedProfile) return;
try {
await deleteProfile.mutateAsync({
profileId: selectedProfile.id
});
setIsDeleteModalOpen(false);
setSelectedProfile(null);
createNotification({
text: `Certificate profile "${selectedProfile.slug}" deleted successfully`,
type: "success"
});
} catch (error) {
console.error(
`Failed to delete profile "${selectedProfile.slug}" (ID: ${selectedProfile.id}):`,
error
);
}
await deleteProfile.mutateAsync({
profileId: selectedProfile.id
});
setIsDeleteModalOpen(false);
setSelectedProfile(null);
createNotification({
text: `Certificate profile "${selectedProfile.slug}" deleted successfully`,
type: "success"
});
};
return (
@@ -236,64 +236,56 @@ export const CreateProfileModal = ({ isOpen, onClose, profile, mode = "create" }
}, [isEdit, profile, reset]);
const onFormSubmit = async (data: FormData) => {
try {
if (!currentProject?.id && !isEdit) return;
if (!currentProject?.id && !isEdit) return;
if (isEdit) {
const updateData: TUpdateCertificateProfileDTO = {
profileId: profile.id,
slug: data.slug,
description: data.description
};
if (isEdit) {
const updateData: TUpdateCertificateProfileDTO = {
profileId: profile.id,
slug: data.slug,
description: data.description
};
if (data.enrollmentType === "est" && data.estConfig) {
updateData.estConfig = data.estConfig;
} else if (data.enrollmentType === "api" && data.apiConfig) {
updateData.apiConfig = data.apiConfig;
}
await updateProfile.mutateAsync(updateData);
} else {
if (!currentProject?.id) {
throw new Error("Project ID is required for creating a profile");
}
const createData: TCreateCertificateProfileDTO = {
projectId: currentProject.id,
slug: data.slug,
description: data.description,
enrollmentType: data.enrollmentType,
caId: data.certificateAuthorityId,
certificateTemplateId: data.certificateTemplateId
};
if (data.enrollmentType === "est" && data.estConfig) {
createData.estConfig = {
passphrase: data.estConfig.passphrase,
caChain: data.estConfig.caChain || undefined,
disableBootstrapCaValidation: data.estConfig.disableBootstrapCaValidation
};
} else if (data.enrollmentType === "api" && data.apiConfig) {
createData.apiConfig = data.apiConfig;
}
await createProfile.mutateAsync(createData);
if (data.enrollmentType === "est" && data.estConfig) {
updateData.estConfig = data.estConfig;
} else if (data.enrollmentType === "api" && data.apiConfig) {
updateData.apiConfig = data.apiConfig;
}
createNotification({
text: `Certificate profile ${isEdit ? "updated" : "created"} successfully`,
type: "success"
});
await updateProfile.mutateAsync(updateData);
} else {
if (!currentProject?.id) {
throw new Error("Project ID is required for creating a profile");
}
reset();
onClose();
} catch (error) {
console.error(`Error ${isEdit ? "updating" : "creating"} profile:`, error);
createNotification({
text: `Failed to ${isEdit ? "update" : "create"} certificate profile`,
type: "error"
});
const createData: TCreateCertificateProfileDTO = {
projectId: currentProject.id,
slug: data.slug,
description: data.description,
enrollmentType: data.enrollmentType,
caId: data.certificateAuthorityId,
certificateTemplateId: data.certificateTemplateId
};
if (data.enrollmentType === "est" && data.estConfig) {
createData.estConfig = {
passphrase: data.estConfig.passphrase,
caChain: data.estConfig.caChain || undefined,
disableBootstrapCaValidation: data.estConfig.disableBootstrapCaValidation
};
} else if (data.enrollmentType === "api" && data.apiConfig) {
createData.apiConfig = data.apiConfig;
}
await createProfile.mutateAsync(createData);
}
createNotification({
text: `Certificate profile ${isEdit ? "updated" : "created"} successfully`,
type: "success"
});
reset();
onClose();
};
return (
@@ -48,23 +48,15 @@ export const CertificateTemplatesV2Tab = () => {
const handleDeleteConfirm = async () => {
if (!selectedTemplate) return;
try {
await deleteTemplateV2.mutateAsync({
templateId: selectedTemplate.id
});
setIsDeleteModalOpen(false);
setSelectedTemplate(null);
createNotification({
text: `Certificate template "${selectedTemplate.name}" deleted successfully`,
type: "success"
});
} catch (error) {
console.error("Failed to delete template:", error);
createNotification({
text: "Failed to delete certificate template",
type: "error"
});
}
await deleteTemplateV2.mutateAsync({
templateId: selectedTemplate.id
});
setIsDeleteModalOpen(false);
setSelectedTemplate(null);
createNotification({
text: `Certificate template "${selectedTemplate.name}" deleted successfully`,
type: "success"
});
};
return (
@@ -407,59 +407,51 @@ export const CreateTemplateModal = ({ isOpen, onClose, template, mode = "create"
};
const onFormSubmit = async (data: FormData) => {
try {
if (!currentProject?.id && !isEdit) return;
if (!currentProject?.id && !isEdit) return;
const hasEmptyAttributeValues = data.attributes?.some(
(attr) => !attr.value || attr.value.length === 0 || attr.value.some((v) => !v.trim())
);
const hasEmptyAttributeValues = data.attributes?.some(
(attr) => !attr.value || attr.value.length === 0 || attr.value.some((v) => !v.trim())
);
const hasEmptySanValues = data.subjectAlternativeNames?.some(
(san) => !san.value || san.value.length === 0 || san.value.some((v) => !v.trim())
);
if (hasEmptyAttributeValues || hasEmptySanValues) {
createNotification({
text: "All values must be non-empty. Use wildcards (*) if needed.",
type: "error"
});
return;
}
const transformedData = transformToApiFormat(data);
if (isEdit) {
const updateData = {
templateId: template.id,
...transformedData
};
await updateTemplate.mutateAsync(updateData);
} else {
if (!currentProject?.id) {
throw new Error("Project ID is required for creating a template");
}
const createData = {
projectId: currentProject.id,
...transformedData
};
await createTemplate.mutateAsync(createData);
}
const hasEmptySanValues = data.subjectAlternativeNames?.some(
(san) => !san.value || san.value.length === 0 || san.value.some((v) => !v.trim())
);
if (hasEmptyAttributeValues || hasEmptySanValues) {
createNotification({
text: `Certificate template ${isEdit ? "updated" : "created"} successfully`,
type: "success"
});
reset();
onClose();
} catch (error) {
console.error(`Error ${isEdit ? "updating" : "creating"} template:`, error);
createNotification({
text: `Failed to ${isEdit ? "update" : "create"} certificate template`,
text: "All values must be non-empty. Use wildcards (*) if needed.",
type: "error"
});
return;
}
const transformedData = transformToApiFormat(data);
if (isEdit) {
const updateData = {
templateId: template.id,
...transformedData
};
await updateTemplate.mutateAsync(updateData);
} else {
if (!currentProject?.id) {
throw new Error("Project ID is required for creating a template");
}
const createData = {
projectId: currentProject.id,
...transformedData
};
await createTemplate.mutateAsync(createData);
}
createNotification({
text: `Certificate template ${isEdit ? "updated" : "created"} successfully`,
type: "success"
});
reset();
onClose();
};
const addAttribute = () => {