mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Improvements to cert-syncs
This commit is contained in:
@@ -309,7 +309,7 @@ export const registerSyncPkiEndpoints = ({
|
||||
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/:pkiSyncId/remove",
|
||||
url: "/:pkiSyncId/remove-certificates",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
|
||||
@@ -23,7 +23,9 @@ import {
|
||||
} from "@app/services/certificate/certificate-types";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns";
|
||||
import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
|
||||
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
|
||||
|
||||
@@ -57,12 +59,8 @@ type TAcmeCertificateAuthorityFnsDeps = {
|
||||
"encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey"
|
||||
>;
|
||||
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">;
|
||||
pkiSyncDAL: {
|
||||
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>;
|
||||
};
|
||||
pkiSyncQueue: {
|
||||
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
|
||||
};
|
||||
pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
|
||||
pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById" | "findOne" | "updateById" | "transaction">;
|
||||
};
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ import {
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
|
||||
import { TPkiSubscriberProperties } from "@app/services/pki-subscriber/pki-subscriber-types";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns";
|
||||
import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
|
||||
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
|
||||
|
||||
@@ -56,12 +58,8 @@ type TAzureAdCsCertificateAuthorityFnsDeps = {
|
||||
"encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey"
|
||||
>;
|
||||
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">;
|
||||
pkiSyncDAL: {
|
||||
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>;
|
||||
};
|
||||
pkiSyncQueue: {
|
||||
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
|
||||
};
|
||||
pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
|
||||
pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById" | "findOne" | "updateById" | "transaction">;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal"
|
||||
import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
|
||||
import { TPkiSubscriberDALFactory } from "../pki-subscriber/pki-subscriber-dal";
|
||||
import { SubscriberOperationStatus } from "../pki-subscriber/pki-subscriber-types";
|
||||
import { TPkiSyncDALFactory } from "../pki-sync/pki-sync-dal";
|
||||
import { TPkiSyncQueueFactory } from "../pki-sync/pki-sync-queue";
|
||||
import { AcmeCertificateAuthorityFns } from "./acme/acme-certificate-authority-fns";
|
||||
import { AzureAdCsCertificateAuthorityFns } from "./azure-ad-cs/azure-ad-cs-certificate-authority-fns";
|
||||
import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal";
|
||||
@@ -50,12 +52,8 @@ type TCertificateAuthorityQueueFactoryDep = {
|
||||
certificateSecretDAL: Pick<TCertificateSecretDALFactory, "create">;
|
||||
queueService: TQueueServiceFactory;
|
||||
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById" | "updateById">;
|
||||
pkiSyncDAL: {
|
||||
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>;
|
||||
};
|
||||
pkiSyncQueue: {
|
||||
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
|
||||
};
|
||||
pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
|
||||
pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
|
||||
};
|
||||
|
||||
export type TCertificateAuthorityQueueFactory = ReturnType<typeof certificateAuthorityQueueFactory>;
|
||||
|
||||
@@ -13,6 +13,8 @@ import { TCertificateDALFactory } from "../certificate/certificate-dal";
|
||||
import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
|
||||
import { TKmsServiceFactory } from "../kms/kms-service";
|
||||
import { TPkiSubscriberDALFactory } from "../pki-subscriber/pki-subscriber-dal";
|
||||
import { TPkiSyncDALFactory } from "../pki-sync/pki-sync-dal";
|
||||
import { TPkiSyncQueueFactory } from "../pki-sync/pki-sync-queue";
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import {
|
||||
AcmeCertificateAuthorityFns,
|
||||
@@ -68,12 +70,8 @@ type TCertificateAuthorityServiceFactoryDep = {
|
||||
"encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey"
|
||||
>;
|
||||
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">;
|
||||
pkiSyncDAL: {
|
||||
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>;
|
||||
};
|
||||
pkiSyncQueue: {
|
||||
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
|
||||
};
|
||||
pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
|
||||
pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
|
||||
};
|
||||
|
||||
export type TCertificateAuthorityServiceFactory = ReturnType<typeof certificateAuthorityServiceFactory>;
|
||||
|
||||
@@ -19,7 +19,9 @@ import {
|
||||
TAltNameMapping
|
||||
} from "@app/services/certificate/certificate-types";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns";
|
||||
import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
|
||||
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
|
||||
|
||||
@@ -52,12 +54,8 @@ type TInternalCertificateAuthorityFnsDeps = {
|
||||
certificateDAL: Pick<TCertificateDALFactory, "create" | "transaction">;
|
||||
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
||||
certificateSecretDAL: Pick<TCertificateSecretDALFactory, "create">;
|
||||
pkiSyncDAL: {
|
||||
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>;
|
||||
};
|
||||
pkiSyncQueue: {
|
||||
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
|
||||
};
|
||||
pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
|
||||
pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
|
||||
};
|
||||
|
||||
export const InternalCertificateAuthorityFns = ({
|
||||
|
||||
@@ -22,7 +22,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TPkiCollectionDALFactory } from "@app/services/pki-collection/pki-collection-dal";
|
||||
import { TPkiCollectionItemDALFactory } from "@app/services/pki-collection/pki-collection-item-dal";
|
||||
import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
|
||||
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
|
||||
|
||||
@@ -38,7 +38,7 @@ import { TCertificateAuthoritySecretDALFactory } from "@app/services/certificate
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
|
||||
import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns";
|
||||
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
|
||||
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import RE2 from "re2";
|
||||
|
||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||
import { PkiSync } from "@app/services/pki-sync/pki-sync-enums";
|
||||
|
||||
/**
|
||||
* Azure Key Vault naming constraints for certificates
|
||||
*/
|
||||
export const AZURE_KEY_VAULT_CERTIFICATE_NAMING = {
|
||||
/**
|
||||
* Regular expression pattern for valid Azure Key Vault certificate names
|
||||
* Must contain only alphanumeric characters and hyphens (a-z, A-Z, 0-9, -)
|
||||
* Must be 1-127 characters long
|
||||
*/
|
||||
NAME_PATTERN: new RE2("^[a-zA-Z0-9-]{1,127}$"),
|
||||
|
||||
/**
|
||||
* String of characters that are forbidden in Azure Key Vault certificate names
|
||||
*/
|
||||
FORBIDDEN_CHARACTERS: "!@#$%^&*()+=[]{}|\\:;\"'<>,.?/~` _",
|
||||
|
||||
/**
|
||||
* Maximum length for certificate names in Azure Key Vault
|
||||
*/
|
||||
MAX_NAME_LENGTH: 127,
|
||||
|
||||
/**
|
||||
* Minimum length for certificate names in Azure Key Vault
|
||||
*/
|
||||
MIN_NAME_LENGTH: 1,
|
||||
|
||||
/**
|
||||
* String representation of the allowed character pattern (for UI display)
|
||||
*/
|
||||
ALLOWED_CHARACTER_PATTERN: "^[a-zA-Z0-9-]{1,127}$"
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Azure Key Vault PKI Sync list option configuration
|
||||
*/
|
||||
export const AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION = {
|
||||
name: "Azure Key Vault" as const,
|
||||
connection: AppConnection.AzureKeyVault,
|
||||
destination: PkiSync.AzureKeyVault,
|
||||
canImportCertificates: false,
|
||||
canRemoveCertificates: true,
|
||||
defaultCertificateNameSchema: "Infisical-PKI-Sync-{{certificateId}}",
|
||||
forbiddenCharacters: AZURE_KEY_VAULT_CERTIFICATE_NAMING.FORBIDDEN_CHARACTERS,
|
||||
allowedCharacterPattern: AZURE_KEY_VAULT_CERTIFICATE_NAMING.ALLOWED_CHARACTER_PATTERN,
|
||||
maxCertificateNameLength: AZURE_KEY_VAULT_CERTIFICATE_NAMING.MAX_NAME_LENGTH,
|
||||
minCertificateNameLength: AZURE_KEY_VAULT_CERTIFICATE_NAMING.MIN_NAME_LENGTH
|
||||
} as const;
|
||||
@@ -5,14 +5,12 @@ import * as crypto from "crypto";
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
|
||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||
import { getAzureConnectionAccessToken } from "@app/services/app-connection/azure-key-vault";
|
||||
import { createConnectionQueue, RateLimitConfig } from "@app/services/connection-queue";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { matchesCertificateNameSchema } from "@app/services/pki-sync/pki-sync-fns";
|
||||
import { TCertificateMap } from "@app/services/pki-sync/pki-sync-types";
|
||||
|
||||
import { PkiSync } from "../pki-sync-enums";
|
||||
import { PkiSyncError } from "../pki-sync-errors";
|
||||
import { TPkiSyncWithCredentials } from "../pki-sync-types";
|
||||
import { GetAzureKeyVaultCertificate, TAzureKeyVaultPkiSyncConfig } from "./azure-key-vault-pki-sync-types";
|
||||
@@ -45,19 +43,6 @@ const isInfisicalManagedCertificate = (certificateName: string, pkiSync: TPkiSyn
|
||||
return certificateName.startsWith("Infisical-PKI-Sync-");
|
||||
};
|
||||
|
||||
export const AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION = {
|
||||
name: "Azure Key Vault" as const,
|
||||
connection: AppConnection.AzureKeyVault,
|
||||
destination: PkiSync.AzureKeyVault,
|
||||
canImportCertificates: false,
|
||||
canRemoveCertificates: true,
|
||||
defaultCertificateNameSchema: "Infisical-PKI-Sync-{{certificateId}}",
|
||||
forbiddenCharacters: "!@#$%^&*()+=[]{}|\\:;\"'<>,.?/~` _",
|
||||
allowedCharacterPattern: "^[a-zA-Z0-9-]{1,127}$",
|
||||
maxCertificateNameLength: 127,
|
||||
minCertificateNameLength: 1
|
||||
};
|
||||
|
||||
type TAzureKeyVaultPkiSyncFactoryDeps = {
|
||||
appConnectionDAL: Pick<TAppConnectionDALFactory, "findById" | "updateById">;
|
||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||
|
||||
@@ -5,6 +5,8 @@ import { AppConnection } from "@app/services/app-connection/app-connection-enums
|
||||
import { PkiSync } from "@app/services/pki-sync/pki-sync-enums";
|
||||
import { PkiSyncSchema } from "@app/services/pki-sync/pki-sync-schemas";
|
||||
|
||||
import { AZURE_KEY_VAULT_CERTIFICATE_NAMING } from "./azure-key-vault-pki-sync-constants";
|
||||
|
||||
export const AzureKeyVaultPkiSyncConfigSchema = z.object({
|
||||
vaultBaseUrl: z.string().url()
|
||||
});
|
||||
@@ -22,12 +24,12 @@ const AzureKeyVaultPkiSyncOptionsSchema = z.object({
|
||||
const testName = schema
|
||||
.replace(new RE2("\\{\\{certificateId\\}\\}", "g"), "")
|
||||
.replace(new RE2("\\{\\{environment\\}\\}", "g"), "");
|
||||
const azureNamePattern = new RE2("^[a-zA-Z0-9-]{1,127}$");
|
||||
|
||||
const forbiddenChars = "!@#$%^&*()+=[]{}|\\:;\"'<>,.?/~` _";
|
||||
const hasForbiddenChars = forbiddenChars.split("").some((char) => testName.includes(char));
|
||||
const hasForbiddenChars = AZURE_KEY_VAULT_CERTIFICATE_NAMING.FORBIDDEN_CHARACTERS.split("").some((char) =>
|
||||
testName.includes(char)
|
||||
);
|
||||
|
||||
return azureNamePattern.test(testName) && !hasForbiddenChars;
|
||||
return AZURE_KEY_VAULT_CERTIFICATE_NAMING.NAME_PATTERN.test(testName) && !hasForbiddenChars;
|
||||
},
|
||||
{
|
||||
message:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./azure-key-vault-pki-sync-constants";
|
||||
export * from "./azure-key-vault-pki-sync-fns";
|
||||
export * from "./azure-key-vault-pki-sync-schemas";
|
||||
export * from "./azure-key-vault-pki-sync-types";
|
||||
|
||||
@@ -3,14 +3,11 @@ import { z, ZodSchema } from "zod";
|
||||
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
|
||||
import {
|
||||
AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION,
|
||||
azureKeyVaultPkiSyncFactory
|
||||
} from "./azure-key-vault/azure-key-vault-pki-sync-fns";
|
||||
import { AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION } from "./azure-key-vault/azure-key-vault-pki-sync-constants";
|
||||
import { azureKeyVaultPkiSyncFactory } from "./azure-key-vault/azure-key-vault-pki-sync-fns";
|
||||
import { PkiSync } from "./pki-sync-enums";
|
||||
import { TCertificateMap, TPkiSyncWithCredentials } from "./pki-sync-types";
|
||||
|
||||
@@ -151,36 +148,6 @@ const isAzureKeyVaultPkiSync = (pkiSync: TPkiSyncWithCredentials): boolean => {
|
||||
return pkiSync.destination === PkiSync.AzureKeyVault;
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger auto sync for PKI syncs connected to a PKI subscriber when certificates are issued/revoked/deleted
|
||||
*/
|
||||
export const triggerAutoSyncForSubscriber = async (
|
||||
subscriberId: string,
|
||||
dependencies: {
|
||||
pkiSyncDAL: {
|
||||
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>;
|
||||
};
|
||||
pkiSyncQueue: {
|
||||
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
|
||||
};
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
const pkiSyncs = await dependencies.pkiSyncDAL.find({
|
||||
subscriberId,
|
||||
isAutoSyncEnabled: true
|
||||
});
|
||||
|
||||
// Queue sync jobs for each auto sync enabled PKI sync
|
||||
const syncPromises = pkiSyncs.map((pkiSync) =>
|
||||
dependencies.pkiSyncQueue.queuePkiSyncSyncCertificatesById({ syncId: pkiSync.id })
|
||||
);
|
||||
await Promise.all(syncPromises);
|
||||
} catch (error) {
|
||||
logger.error(error, `Failed to trigger auto sync for subscriber ${subscriberId}:`);
|
||||
}
|
||||
};
|
||||
|
||||
export const PkiSyncFns = {
|
||||
getCertificates: async (
|
||||
pkiSync: TPkiSyncWithCredentials,
|
||||
|
||||
@@ -14,10 +14,8 @@ export const PkiSyncOptionsSchema = z.object({
|
||||
(val) => {
|
||||
if (!val) return true;
|
||||
|
||||
const allowedOptionalPlaceholders = ["{{environment}}"];
|
||||
|
||||
const allowedPlaceholdersRegexPart = ["{{certificateId}}", ...allowedOptionalPlaceholders]
|
||||
.map((p) => p.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")) // Escape regex special characters
|
||||
const allowedPlaceholdersRegexPart = ["{{certificateId}}"]
|
||||
.map((p) => p.replace(new RE2(/[-/\\^$*+?.()|[\]{}]/g), "\\$&")) // Escape regex special characters
|
||||
.join("|");
|
||||
|
||||
const allowedContentRegex = new RE2(`^([a-zA-Z0-9_\\-/]|${allowedPlaceholdersRegexPart})*$`);
|
||||
@@ -33,7 +31,7 @@ export const PkiSyncOptionsSchema = z.object({
|
||||
},
|
||||
{
|
||||
message:
|
||||
"Certificate name schema must include exactly one {{certificateId}} placeholder. It can also include {{environment}} placeholders. Only alphanumeric characters (a-z, A-Z, 0-9), dashes (-), underscores (_), and slashes (/) are allowed besides the placeholders."
|
||||
"Certificate name schema must include exactly one {{certificateId}} placeholder. Only alphanumeric characters (a-z, A-Z, 0-9), dashes (-), underscores (_), and slashes (/) are allowed besides the placeholders."
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
@@ -153,8 +153,8 @@ export const pkiSyncServiceFactory = ({
|
||||
}: Omit<TUpdatePkiSyncDTO, "auditLogInfo" | "projectId">,
|
||||
actor: OrgServiceActor
|
||||
): Promise<TPkiSync> => {
|
||||
const existingSync = await pkiSyncDAL.findById(id);
|
||||
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
const pkiSync = await pkiSyncDAL.findById(id);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor: actor.type,
|
||||
@@ -162,12 +162,9 @@ export const pkiSyncServiceFactory = ({
|
||||
actorAuthMethod: actor.authMethod,
|
||||
actorOrgId: actor.orgId,
|
||||
actionProjectType: ActionProjectType.CertificateManager,
|
||||
projectId: existingSync.projectId
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
let currentSubscriber;
|
||||
if (pkiSync.subscriberId) {
|
||||
currentSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
|
||||
@@ -181,7 +178,7 @@ export const pkiSyncServiceFactory = ({
|
||||
);
|
||||
|
||||
if (name && name !== pkiSync.name) {
|
||||
const existingPkiSync = await pkiSyncDAL.findByNameAndProjectId(name, existingSync.projectId);
|
||||
const existingPkiSync = await pkiSyncDAL.findByNameAndProjectId(name, pkiSync.projectId);
|
||||
if (existingPkiSync) {
|
||||
throw new BadRequestError({ message: "PKI sync with this name already exists" });
|
||||
}
|
||||
@@ -189,7 +186,7 @@ export const pkiSyncServiceFactory = ({
|
||||
|
||||
if (subscriberId) {
|
||||
const subscriber = await pkiSubscriberDAL.findById(subscriberId);
|
||||
if (!subscriber || subscriber.projectId !== existingSync.projectId) {
|
||||
if (!subscriber || subscriber.projectId !== pkiSync.projectId) {
|
||||
throw new NotFoundError({ message: "PKI subscriber not found" });
|
||||
}
|
||||
}
|
||||
@@ -209,9 +206,9 @@ export const pkiSyncServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (syncOptions.canRemoveCertificates === false && providerCapabilities.canRemoveCertificates) {
|
||||
if (syncOptions.canRemoveCertificates && !providerCapabilities.canRemoveCertificates) {
|
||||
throw new BadRequestError({
|
||||
message: `Certificate removal cannot be disabled for ${PKI_SYNC_NAME_MAP[pkiSync.destination]} PKI sync destination`
|
||||
message: `Certificate removal cannot be enabled for ${PKI_SYNC_NAME_MAP[pkiSync.destination]} PKI sync destination`
|
||||
});
|
||||
}
|
||||
|
||||
@@ -237,9 +234,9 @@ export const pkiSyncServiceFactory = ({
|
||||
const deletePkiSync = async (
|
||||
{ id }: Omit<TDeletePkiSyncDTO, "auditLogInfo" | "projectId">,
|
||||
actor: OrgServiceActor
|
||||
): Promise<TPkiSync> => {
|
||||
const existingSync = await pkiSyncDAL.findById(id);
|
||||
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
) => {
|
||||
const pkiSync = await pkiSyncDAL.findById(id);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor: actor.type,
|
||||
@@ -247,12 +244,9 @@ export const pkiSyncServiceFactory = ({
|
||||
actorAuthMethod: actor.authMethod,
|
||||
actorOrgId: actor.orgId,
|
||||
actionProjectType: ActionProjectType.CertificateManager,
|
||||
projectId: existingSync.projectId
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
let pkiSyncSubscriber;
|
||||
if (pkiSync.subscriberId) {
|
||||
pkiSyncSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
|
||||
@@ -265,31 +259,7 @@ export const pkiSyncServiceFactory = ({
|
||||
: ProjectPermissionSub.PkiSyncs
|
||||
);
|
||||
|
||||
await pkiSyncDAL.deleteById(id);
|
||||
return {
|
||||
...pkiSync,
|
||||
description: pkiSync.description || undefined,
|
||||
subscriberId: pkiSync.subscriberId || undefined,
|
||||
syncStatus: pkiSync.syncStatus || undefined,
|
||||
lastSyncedAt: pkiSync.lastSyncedAt || undefined,
|
||||
lastSyncJobId: pkiSync.lastSyncJobId || undefined,
|
||||
lastSyncMessage: pkiSync.lastSyncMessage || undefined,
|
||||
importStatus: pkiSync.importStatus || undefined,
|
||||
lastImportJobId: pkiSync.lastImportJobId || undefined,
|
||||
lastImportMessage: pkiSync.lastImportMessage || undefined,
|
||||
lastImportedAt: pkiSync.lastImportedAt || undefined,
|
||||
removeStatus: pkiSync.removeStatus || undefined,
|
||||
lastRemoveJobId: pkiSync.lastRemoveJobId || undefined,
|
||||
lastRemoveMessage: pkiSync.lastRemoveMessage || undefined,
|
||||
lastRemovedAt: pkiSync.lastRemovedAt || undefined,
|
||||
connection: {
|
||||
...pkiSync.connection,
|
||||
description: pkiSync.connection.description || undefined,
|
||||
gatewayId: pkiSync.connection.gatewayId || undefined,
|
||||
projectId: pkiSync.connection.projectId || undefined,
|
||||
isPlatformManagedCredentials: pkiSync.connection.isPlatformManagedCredentials || undefined
|
||||
}
|
||||
};
|
||||
return pkiSyncDAL.deleteById(id);
|
||||
};
|
||||
|
||||
const listPkiSyncsByProjectId = async ({ projectId }: TListPkiSyncsByProjectId, actor: OrgServiceActor) => {
|
||||
@@ -310,15 +280,10 @@ export const pkiSyncServiceFactory = ({
|
||||
|
||||
const findPkiSyncById = async ({ id, projectId }: TFindPkiSyncByIdDTO, actor: OrgServiceActor) => {
|
||||
const pkiSync = await pkiSyncDAL.findById(id);
|
||||
if (!pkiSync)
|
||||
if (!pkiSync || (projectId && pkiSync.projectId !== projectId)) {
|
||||
throw new NotFoundError({
|
||||
message: `Could not find PKI Sync with ID "${id}"`
|
||||
});
|
||||
|
||||
if (projectId && pkiSync.projectId !== projectId) {
|
||||
throw new NotFoundError({
|
||||
message: `Could not find PKI Sync with ID "${id}" in project "${projectId}"`
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
@@ -349,8 +314,8 @@ export const pkiSyncServiceFactory = ({
|
||||
{ id }: Omit<TTriggerPkiSyncSyncCertificatesByIdDTO, "auditLogInfo" | "projectId">,
|
||||
actor: OrgServiceActor
|
||||
) => {
|
||||
const existingSync = await pkiSyncDAL.findById(id);
|
||||
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
const pkiSync = await pkiSyncDAL.findById(id);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor: actor.type,
|
||||
@@ -358,12 +323,9 @@ export const pkiSyncServiceFactory = ({
|
||||
actorAuthMethod: actor.authMethod,
|
||||
actorOrgId: actor.orgId,
|
||||
actionProjectType: ActionProjectType.CertificateManager,
|
||||
projectId: existingSync.projectId
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
let syncSubscriber;
|
||||
if (pkiSync.subscriberId) {
|
||||
syncSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
|
||||
@@ -385,8 +347,8 @@ export const pkiSyncServiceFactory = ({
|
||||
{ id }: Omit<TTriggerPkiSyncImportCertificatesByIdDTO, "auditLogInfo" | "projectId">,
|
||||
actor: OrgServiceActor
|
||||
) => {
|
||||
const existingSync = await pkiSyncDAL.findById(id);
|
||||
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
const pkiSync = await pkiSyncDAL.findById(id);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor: actor.type,
|
||||
@@ -394,12 +356,9 @@ export const pkiSyncServiceFactory = ({
|
||||
actorAuthMethod: actor.authMethod,
|
||||
actorOrgId: actor.orgId,
|
||||
actionProjectType: ActionProjectType.CertificateManager,
|
||||
projectId: existingSync.projectId
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
// Check if the PKI sync destination supports importing certificates
|
||||
const syncOptions = listPkiSyncOptions().find((option) => option.destination === pkiSync.destination);
|
||||
if (!syncOptions?.canImportCertificates) {
|
||||
@@ -429,8 +388,8 @@ export const pkiSyncServiceFactory = ({
|
||||
{ id }: Omit<TTriggerPkiSyncRemoveCertificatesByIdDTO, "auditLogInfo" | "projectId">,
|
||||
actor: OrgServiceActor
|
||||
) => {
|
||||
const existingSync = await pkiSyncDAL.findById(id);
|
||||
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
const pkiSync = await pkiSyncDAL.findById(id);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor: actor.type,
|
||||
@@ -438,12 +397,9 @@ export const pkiSyncServiceFactory = ({
|
||||
actorAuthMethod: actor.authMethod,
|
||||
actorOrgId: actor.orgId,
|
||||
actionProjectType: ActionProjectType.CertificateManager,
|
||||
projectId: existingSync.projectId
|
||||
projectId: pkiSync.projectId
|
||||
});
|
||||
|
||||
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
|
||||
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
|
||||
|
||||
let removeSubscriber;
|
||||
if (pkiSync.subscriberId) {
|
||||
removeSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
|
||||
|
||||
27
backend/src/services/pki-sync/pki-sync-utils.ts
Normal file
27
backend/src/services/pki-sync/pki-sync-utils.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { logger } from "@app/lib/logger";
|
||||
|
||||
import { TPkiSyncDALFactory } from "./pki-sync-dal";
|
||||
import { TPkiSyncQueueFactory } from "./pki-sync-queue";
|
||||
|
||||
export const triggerAutoSyncForSubscriber = async (
|
||||
subscriberId: string,
|
||||
dependencies: {
|
||||
pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
|
||||
pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
const pkiSyncs = await dependencies.pkiSyncDAL.find({
|
||||
subscriberId,
|
||||
isAutoSyncEnabled: true
|
||||
});
|
||||
|
||||
// Queue sync jobs for each auto sync enabled PKI sync
|
||||
const syncPromises = pkiSyncs.map((pkiSync) =>
|
||||
dependencies.pkiSyncQueue.queuePkiSyncSyncCertificatesById({ syncId: pkiSync.id })
|
||||
);
|
||||
await Promise.all(syncPromises);
|
||||
} catch (error) {
|
||||
logger.error(error, `Failed to trigger auto sync for subscriber ${subscriberId}:`);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user