mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 11:29:42 +00:00
feat: added subscriber cert auto-renewal
This commit is contained in:
@@ -94,6 +94,11 @@ export async function up(knex: Knex): Promise<void> {
|
||||
if (await knex.schema.hasTable(TableName.PkiSubscriber)) {
|
||||
await knex.schema.alterTable(TableName.PkiSubscriber, (t) => {
|
||||
t.string("ttl").nullable().alter();
|
||||
|
||||
t.boolean("enableAutoRenewal").notNullable().defaultTo(false);
|
||||
t.integer("autoRenewalPeriodInDays");
|
||||
t.datetime("lastAutoRenewAt");
|
||||
|
||||
t.string("lastOperationStatus");
|
||||
t.text("lastOperationMessage");
|
||||
t.dateTime("lastOperationAt");
|
||||
@@ -188,6 +193,10 @@ export async function down(knex: Knex): Promise<void> {
|
||||
|
||||
if (await knex.schema.hasTable(TableName.PkiSubscriber)) {
|
||||
await knex.schema.alterTable(TableName.PkiSubscriber, (t) => {
|
||||
t.dropColumn("enableAutoRenewal");
|
||||
t.dropColumn("autoRenewalPeriodInDays");
|
||||
t.dropColumn("lastAutoRenewAt");
|
||||
|
||||
t.dropColumn("lastOperationStatus");
|
||||
t.dropColumn("lastOperationMessage");
|
||||
t.dropColumn("lastOperationAt");
|
||||
|
||||
@@ -20,6 +20,9 @@ export const PkiSubscribersSchema = z.object({
|
||||
keyUsages: z.string().array(),
|
||||
extendedKeyUsages: z.string().array(),
|
||||
status: z.string(),
|
||||
enableAutoRenewal: z.boolean().default(false),
|
||||
autoRenewalPeriodInDays: z.number().nullable().optional(),
|
||||
lastAutoRenewAt: z.date().nullable().optional(),
|
||||
lastOperationStatus: z.string().nullable().optional(),
|
||||
lastOperationMessage: z.string().nullable().optional(),
|
||||
lastOperationAt: z.date().nullable().optional()
|
||||
|
||||
@@ -268,6 +268,7 @@ export enum EventType {
|
||||
GET_PKI_SUBSCRIBER = "get-pki-subscriber",
|
||||
ISSUE_PKI_SUBSCRIBER_CERT = "issue-pki-subscriber-cert",
|
||||
SIGN_PKI_SUBSCRIBER_CERT = "sign-pki-subscriber-cert",
|
||||
AUTOMATED_RENEW_SUBSCRIBER_CERT = "automated-renew-subscriber-cert",
|
||||
LIST_PKI_SUBSCRIBER_CERTS = "list-pki-subscriber-certs",
|
||||
GET_SUBSCRIBER_ACTIVE_CERT_BUNDLE = "get-subscriber-active-cert-bundle",
|
||||
CREATE_KMS = "create-kms",
|
||||
@@ -2099,6 +2100,14 @@ interface IssuePkiSubscriberCert {
|
||||
};
|
||||
}
|
||||
|
||||
interface AutomatedRenewPkiSubscriberCert {
|
||||
type: EventType.AUTOMATED_RENEW_SUBSCRIBER_CERT;
|
||||
metadata: {
|
||||
subscriberId: string;
|
||||
name: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface SignPkiSubscriberCert {
|
||||
type: EventType.SIGN_PKI_SUBSCRIBER_CERT;
|
||||
metadata: {
|
||||
@@ -3103,6 +3112,7 @@ export type Event =
|
||||
| GetPkiSubscriber
|
||||
| IssuePkiSubscriberCert
|
||||
| SignPkiSubscriberCert
|
||||
| AutomatedRenewPkiSubscriberCert
|
||||
| ListPkiSubscriberCerts
|
||||
| GetSubscriberActiveCertBundle
|
||||
| CreateKmsEvent
|
||||
|
||||
@@ -1811,7 +1811,9 @@ export const PKI_SUBSCRIBERS = {
|
||||
subjectAlternativeNames:
|
||||
"A list of Subject Alternative Names (SANs) to be used on certificates issued for this subscriber; these can be host names or email addresses.",
|
||||
keyUsages: "The key usage extension to be used on certificates issued for this subscriber.",
|
||||
extendedKeyUsages: "The extended key usage extension to be used on certificates issued for this subscriber."
|
||||
extendedKeyUsages: "The extended key usage extension to be used on certificates issued for this subscriber.",
|
||||
enableAutoRenewal: "Whether or not to enable auto renewal for the PKI subscriber.",
|
||||
autoRenewalPeriodInDays: "The period in days to auto renew the PKI subscriber's certificates."
|
||||
},
|
||||
UPDATE: {
|
||||
projectId: "The ID of the project to update the PKI subscriber in.",
|
||||
@@ -1825,7 +1827,9 @@ export const PKI_SUBSCRIBERS = {
|
||||
"A comma-delimited list of Subject Alternative Names (SANs) to be used on certificates issued for this subscriber; these can be host names or email addresses.",
|
||||
keyUsages: "The key usage extension to be used on certificates issued for this subscriber to update to.",
|
||||
extendedKeyUsages:
|
||||
"The extended key usage extension to be used on certificates issued for this subscriber to update to."
|
||||
"The extended key usage extension to be used on certificates issued for this subscriber to update to.",
|
||||
enableAutoRenewal: "Whether or not to enable auto renewal for the PKI subscriber.",
|
||||
autoRenewalPeriodInDays: "The period in days to auto renew the PKI subscriber's certificates."
|
||||
},
|
||||
DELETE: {
|
||||
subscriberName: "The name of the PKI subscriber to delete.",
|
||||
|
||||
@@ -37,6 +37,7 @@ export enum QueueName {
|
||||
AuditLogPrune = "audit-log-prune",
|
||||
DailyResourceCleanUp = "daily-resource-cleanup",
|
||||
DailyExpiringPkiItemAlert = "daily-expiring-pki-item-alert",
|
||||
PkiSubscriber = "pki-subscriber",
|
||||
TelemetryInstanceStats = "telemtry-self-hosted-stats",
|
||||
IntegrationSync = "sync-integrations",
|
||||
SecretWebhook = "secret-webhook",
|
||||
@@ -87,7 +88,8 @@ export enum QueueJobs {
|
||||
SecretRotationV2RotateSecrets = "secret-rotation-v2-rotate-secrets",
|
||||
SecretRotationV2SendNotification = "secret-rotation-v2-send-notification",
|
||||
InvalidateCache = "invalidate-cache",
|
||||
CaOrderCertificateForSubscriber = "ca-order-certificate-for-subscriber"
|
||||
CaOrderCertificateForSubscriber = "ca-order-certificate-for-subscriber",
|
||||
PkiSubscriberDailyAutoRenewal = "pki-subscriber-daily-auto-renewal"
|
||||
}
|
||||
|
||||
export type TQueueJobTypes = {
|
||||
@@ -255,6 +257,10 @@ export type TQueueJobTypes = {
|
||||
caType: CaType;
|
||||
};
|
||||
};
|
||||
[QueueName.PkiSubscriber]: {
|
||||
name: QueueJobs.PkiSubscriberDailyAutoRenewal;
|
||||
payload: undefined;
|
||||
};
|
||||
};
|
||||
|
||||
export type TQueueServiceFactory = ReturnType<typeof queueServiceFactory>;
|
||||
|
||||
@@ -134,6 +134,7 @@ import { certificateAuthoritySecretDALFactory } from "@app/services/certificate-
|
||||
import { certificateAuthorityServiceFactory } from "@app/services/certificate-authority/certificate-authority-service";
|
||||
import { externalCertificateAuthorityDALFactory } from "@app/services/certificate-authority/external-certificate-authority-dal";
|
||||
import { internalCertificateAuthorityDALFactory } from "@app/services/certificate-authority/internal/internal-certificate-authority-dal";
|
||||
import { InternalCertificateAuthorityFns } from "@app/services/certificate-authority/internal/internal-certificate-authority-fns";
|
||||
import { internalCertificateAuthorityServiceFactory } from "@app/services/certificate-authority/internal/internal-certificate-authority-service";
|
||||
import { certificateTemplateDALFactory } from "@app/services/certificate-template/certificate-template-dal";
|
||||
import { certificateTemplateEstConfigDALFactory } from "@app/services/certificate-template/certificate-template-est-config-dal";
|
||||
@@ -202,6 +203,7 @@ import { pkiCollectionDALFactory } from "@app/services/pki-collection/pki-collec
|
||||
import { pkiCollectionItemDALFactory } from "@app/services/pki-collection/pki-collection-item-dal";
|
||||
import { pkiCollectionServiceFactory } from "@app/services/pki-collection/pki-collection-service";
|
||||
import { pkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
|
||||
import { pkiSubscriberQueueServiceFactory } from "@app/services/pki-subscriber/pki-subscriber-queue";
|
||||
import { pkiSubscriberServiceFactory } from "@app/services/pki-subscriber/pki-subscriber-service";
|
||||
import { projectDALFactory } from "@app/services/project/project-dal";
|
||||
import { projectQueueFactory } from "@app/services/project/project-queue";
|
||||
@@ -1700,6 +1702,28 @@ export const registerRoutes = async (
|
||||
pkiSubscriberDAL
|
||||
});
|
||||
|
||||
const internalCaFns = InternalCertificateAuthorityFns({
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityCertDAL,
|
||||
certificateAuthoritySecretDAL,
|
||||
certificateAuthorityCrlDAL,
|
||||
certificateDAL,
|
||||
certificateBodyDAL,
|
||||
certificateSecretDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const pkiSubscriberQueue = pkiSubscriberQueueServiceFactory({
|
||||
queueService,
|
||||
pkiSubscriberDAL,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityQueue,
|
||||
certificateDAL,
|
||||
auditLogService,
|
||||
internalCaFns
|
||||
});
|
||||
|
||||
const pkiSubscriberService = pkiSubscriberServiceFactory({
|
||||
pkiSubscriberDAL,
|
||||
certificateAuthorityDAL,
|
||||
@@ -1712,7 +1736,8 @@ export const registerRoutes = async (
|
||||
projectDAL,
|
||||
kmsService,
|
||||
permissionService,
|
||||
certificateAuthorityQueue
|
||||
certificateAuthorityQueue,
|
||||
internalCaFns
|
||||
});
|
||||
|
||||
await secretRotationV2QueueServiceFactory({
|
||||
@@ -1735,6 +1760,7 @@ export const registerRoutes = async (
|
||||
await telemetryQueue.startTelemetryCheck();
|
||||
await dailyResourceCleanUp.startCleanUp();
|
||||
await dailyExpiringPkiItemAlert.startSendingAlerts();
|
||||
await pkiSubscriberQueue.startDailyAutoRenewalJob();
|
||||
await kmsService.startService();
|
||||
await microsoftTeamsService.start();
|
||||
|
||||
|
||||
@@ -110,7 +110,9 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
|
||||
.array()
|
||||
.default([])
|
||||
.transform((arr) => Array.from(new Set(arr)))
|
||||
.describe(PKI_SUBSCRIBERS.CREATE.extendedKeyUsages)
|
||||
.describe(PKI_SUBSCRIBERS.CREATE.extendedKeyUsages),
|
||||
enableAutoRenewal: z.boolean().optional().describe(PKI_SUBSCRIBERS.CREATE.enableAutoRenewal),
|
||||
autoRenewalPeriodInDays: z.number().min(1).optional().describe(PKI_SUBSCRIBERS.CREATE.autoRenewalPeriodInDays)
|
||||
}),
|
||||
response: {
|
||||
200: sanitizedPkiSubscriber
|
||||
@@ -195,7 +197,9 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
|
||||
.array()
|
||||
.transform((arr) => Array.from(new Set(arr)))
|
||||
.optional()
|
||||
.describe(PKI_SUBSCRIBERS.UPDATE.extendedKeyUsages)
|
||||
.describe(PKI_SUBSCRIBERS.UPDATE.extendedKeyUsages),
|
||||
enableAutoRenewal: z.boolean().optional().describe(PKI_SUBSCRIBERS.UPDATE.enableAutoRenewal),
|
||||
autoRenewalPeriodInDays: z.number().min(1).optional().describe(PKI_SUBSCRIBERS.UPDATE.autoRenewalPeriodInDays)
|
||||
}),
|
||||
response: {
|
||||
200: sanitizedPkiSubscriber
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
import { TCertificateDALFactory } from "../certificate/certificate-dal";
|
||||
import { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal";
|
||||
import { CaStatus, CaType } from "../certificate-authority/certificate-authority-enums";
|
||||
import { TCertificateAuthorityQueueFactory } from "../certificate-authority/certificate-authority-queue";
|
||||
import { InternalCertificateAuthorityFns } from "../certificate-authority/internal/internal-certificate-authority-fns";
|
||||
import { TPkiSubscriberDALFactory } from "./pki-subscriber-dal";
|
||||
import { PkiSubscriberStatus, SubscriberOperationStatus } from "./pki-subscriber-types";
|
||||
|
||||
type TPkiSubscriberQueueServiceFactoryDep = {
|
||||
queueService: TQueueServiceFactory;
|
||||
pkiSubscriberDAL: TPkiSubscriberDALFactory;
|
||||
certificateAuthorityDAL: TCertificateAuthorityDALFactory;
|
||||
certificateAuthorityQueue: TCertificateAuthorityQueueFactory;
|
||||
internalCaFns: ReturnType<typeof InternalCertificateAuthorityFns>;
|
||||
certificateDAL: TCertificateDALFactory;
|
||||
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
|
||||
};
|
||||
|
||||
export const pkiSubscriberQueueServiceFactory = ({
|
||||
queueService,
|
||||
pkiSubscriberDAL,
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityQueue,
|
||||
internalCaFns,
|
||||
certificateDAL,
|
||||
auditLogService
|
||||
}: TPkiSubscriberQueueServiceFactoryDep) => {
|
||||
queueService.start(QueueName.PkiSubscriber, async (job) => {
|
||||
if (job.name === QueueJobs.PkiSubscriberDailyAutoRenewal) {
|
||||
logger.info(`${QueueJobs.PkiSubscriberDailyAutoRenewal}: queue task started`);
|
||||
|
||||
const BATCH_SIZE = 100;
|
||||
let offset = 0;
|
||||
let hasMore = true;
|
||||
|
||||
while (hasMore) {
|
||||
// fetch PKI subscribers with auto renewal enabled in batches
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const pkiSubscribers = await pkiSubscriberDAL.find(
|
||||
{
|
||||
enableAutoRenewal: true,
|
||||
$notNull: ["autoRenewalPeriodInDays"],
|
||||
status: PkiSubscriberStatus.ACTIVE
|
||||
},
|
||||
{
|
||||
limit: BATCH_SIZE,
|
||||
offset
|
||||
}
|
||||
);
|
||||
|
||||
if (pkiSubscribers.length === 0) {
|
||||
hasMore = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Process each subscriber in the batch concurrently
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await Promise.all(
|
||||
pkiSubscribers.map(async (subscriber) => {
|
||||
try {
|
||||
const cert = await certificateDAL.findLatestActiveCertForSubscriber({ subscriberId: subscriber.id });
|
||||
let shouldRenew = false;
|
||||
if (!cert || !cert.notAfter) {
|
||||
shouldRenew = true;
|
||||
} else {
|
||||
const now = new Date();
|
||||
const expiry = new Date(cert.notAfter);
|
||||
const daysUntilExpiry = (expiry.getTime() - now.getTime()) / (1000 * 60 * 60 * 24);
|
||||
shouldRenew = daysUntilExpiry <= subscriber.autoRenewalPeriodInDays!;
|
||||
}
|
||||
|
||||
if (shouldRenew) {
|
||||
// Get the CA for the subscriber
|
||||
if (!subscriber.caId) {
|
||||
await pkiSubscriberDAL.updateById(subscriber.id, {
|
||||
lastOperationStatus: SubscriberOperationStatus.FAILED,
|
||||
lastOperationMessage: "No CA assigned to subscriber",
|
||||
lastOperationAt: new Date()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(subscriber.caId);
|
||||
if (!ca) {
|
||||
await pkiSubscriberDAL.updateById(subscriber.id, {
|
||||
lastOperationStatus: SubscriberOperationStatus.FAILED,
|
||||
lastOperationMessage: "CA not found",
|
||||
lastOperationAt: new Date()
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if CA is active
|
||||
if (ca.status !== CaStatus.ACTIVE) {
|
||||
await pkiSubscriberDAL.updateById(subscriber.id, {
|
||||
lastOperationStatus: SubscriberOperationStatus.FAILED,
|
||||
lastOperationMessage: "CA is not active",
|
||||
lastOperationAt: new Date()
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Order new certificate based on CA type
|
||||
if (ca.externalCa?.id && ca.externalCa.type === CaType.ACME) {
|
||||
await certificateAuthorityQueue.orderCertificateForSubscriber({
|
||||
subscriberId: subscriber.id,
|
||||
caType: ca.externalCa.type
|
||||
});
|
||||
} else if (ca.internalCa?.id) {
|
||||
// For internal CAs, we can issue certificates directly
|
||||
await internalCaFns.issueCertificate(subscriber, ca);
|
||||
}
|
||||
|
||||
// Update last auto-renew timestamp
|
||||
await pkiSubscriberDAL.updateById(subscriber.id, {
|
||||
lastAutoRenewAt: new Date(),
|
||||
lastOperationStatus: SubscriberOperationStatus.SUCCESS,
|
||||
lastOperationMessage: "Triggered certificate auto-renewal",
|
||||
lastOperationAt: new Date()
|
||||
});
|
||||
|
||||
await auditLogService.createAuditLog({
|
||||
projectId: subscriber.projectId,
|
||||
actor: {
|
||||
type: ActorType.PLATFORM,
|
||||
metadata: {}
|
||||
},
|
||||
event: {
|
||||
type: EventType.AUTOMATED_RENEW_SUBSCRIBER_CERT,
|
||||
metadata: {
|
||||
subscriberId: subscriber.id,
|
||||
name: subscriber.name
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// Log error and update subscriber status
|
||||
logger.error(error, `Failed to auto-renew certificate for subscriber ${subscriber.id}`);
|
||||
await pkiSubscriberDAL.updateById(subscriber.id, {
|
||||
lastOperationStatus: SubscriberOperationStatus.FAILED,
|
||||
lastOperationMessage: error instanceof Error ? error.message : "Unknown error",
|
||||
lastOperationAt: new Date()
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
offset += BATCH_SIZE;
|
||||
}
|
||||
|
||||
logger.info(`${QueueJobs.PkiSubscriberDailyAutoRenewal}: queue task completed`);
|
||||
}
|
||||
});
|
||||
|
||||
// we do a repeat cron job in utc timezone at 12 Midnight each day
|
||||
const startDailyAutoRenewalJob = async () => {
|
||||
// clear previous job
|
||||
await queueService.stopRepeatableJob(
|
||||
QueueName.PkiSubscriber,
|
||||
QueueJobs.PkiSubscriberDailyAutoRenewal,
|
||||
// { pattern: "0 0 * * *", utc: true },
|
||||
{ pattern: "*/30 * * * * *", utc: true },
|
||||
QueueName.PkiSubscriber // just a job id
|
||||
);
|
||||
|
||||
await queueService.queue(QueueName.PkiSubscriber, QueueJobs.PkiSubscriberDailyAutoRenewal, undefined, {
|
||||
delay: 5000,
|
||||
jobId: QueueName.PkiSubscriber,
|
||||
repeat: { pattern: "*/30 * * * * *", utc: true }
|
||||
});
|
||||
};
|
||||
|
||||
queueService.listen(QueueName.PkiSubscriber, "failed", (_, err) => {
|
||||
logger.error(err, `${QueueName.PkiSubscriber}: failed`);
|
||||
});
|
||||
|
||||
return {
|
||||
startDailyAutoRenewalJob
|
||||
};
|
||||
};
|
||||
@@ -15,7 +15,10 @@ export const sanitizedPkiSubscriber = PkiSubscribersSchema.pick({
|
||||
extendedKeyUsages: true,
|
||||
lastOperationStatus: true,
|
||||
lastOperationMessage: true,
|
||||
lastOperationAt: true
|
||||
lastOperationAt: true,
|
||||
enableAutoRenewal: true,
|
||||
autoRenewalPeriodInDays: true,
|
||||
lastAutoRenewAt: true
|
||||
}).extend({
|
||||
supportsImmediateCertIssuance: z.boolean().optional()
|
||||
});
|
||||
|
||||
@@ -78,6 +78,7 @@ type TPkiSubscriberServiceFactoryDep = {
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction" | "findById" | "find">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "decryptWithKmsKey" | "encryptWithKmsKey">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
internalCaFns: ReturnType<typeof InternalCertificateAuthorityFns>;
|
||||
};
|
||||
|
||||
export type TPkiSubscriberServiceFactory = ReturnType<typeof pkiSubscriberServiceFactory>;
|
||||
@@ -94,20 +95,9 @@ export const pkiSubscriberServiceFactory = ({
|
||||
projectDAL,
|
||||
kmsService,
|
||||
permissionService,
|
||||
certificateAuthorityQueue
|
||||
certificateAuthorityQueue,
|
||||
internalCaFns
|
||||
}: TPkiSubscriberServiceFactoryDep) => {
|
||||
const internalCaFns = InternalCertificateAuthorityFns({
|
||||
certificateAuthorityDAL,
|
||||
certificateAuthorityCertDAL,
|
||||
certificateAuthoritySecretDAL,
|
||||
certificateAuthorityCrlDAL,
|
||||
certificateDAL,
|
||||
certificateBodyDAL,
|
||||
certificateSecretDAL,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const createSubscriber = async ({
|
||||
name,
|
||||
commonName,
|
||||
@@ -117,6 +107,8 @@ export const pkiSubscriberServiceFactory = ({
|
||||
subjectAlternativeNames,
|
||||
keyUsages,
|
||||
extendedKeyUsages,
|
||||
enableAutoRenewal,
|
||||
autoRenewalPeriodInDays,
|
||||
projectId,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
@@ -139,6 +131,12 @@ export const pkiSubscriberServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
if (enableAutoRenewal) {
|
||||
if (!autoRenewalPeriodInDays) {
|
||||
throw new BadRequestError({ message: "autoRenewalPeriodInDays is required when enableAutoRenewal is true" });
|
||||
}
|
||||
}
|
||||
|
||||
const newSubscriber = await pkiSubscriberDAL.create({
|
||||
caId,
|
||||
projectId,
|
||||
@@ -148,7 +146,9 @@ export const pkiSubscriberServiceFactory = ({
|
||||
ttl,
|
||||
subjectAlternativeNames,
|
||||
keyUsages,
|
||||
extendedKeyUsages
|
||||
extendedKeyUsages,
|
||||
enableAutoRenewal,
|
||||
autoRenewalPeriodInDays
|
||||
});
|
||||
|
||||
return newSubscriber;
|
||||
@@ -210,6 +210,8 @@ export const pkiSubscriberServiceFactory = ({
|
||||
subjectAlternativeNames,
|
||||
keyUsages,
|
||||
extendedKeyUsages,
|
||||
enableAutoRenewal,
|
||||
autoRenewalPeriodInDays,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actor,
|
||||
@@ -237,6 +239,12 @@ export const pkiSubscriberServiceFactory = ({
|
||||
})
|
||||
);
|
||||
|
||||
if (enableAutoRenewal) {
|
||||
if (!autoRenewalPeriodInDays && !subscriber.autoRenewalPeriodInDays) {
|
||||
throw new BadRequestError({ message: "autoRenewalPeriodInDays is required when enableAutoRenewal is true" });
|
||||
}
|
||||
}
|
||||
|
||||
const updatedSubscriber = await pkiSubscriberDAL.updateById(subscriber.id, {
|
||||
caId,
|
||||
name,
|
||||
@@ -245,7 +253,9 @@ export const pkiSubscriberServiceFactory = ({
|
||||
ttl,
|
||||
subjectAlternativeNames,
|
||||
keyUsages,
|
||||
extendedKeyUsages
|
||||
extendedKeyUsages,
|
||||
enableAutoRenewal,
|
||||
autoRenewalPeriodInDays
|
||||
});
|
||||
|
||||
return updatedSubscriber;
|
||||
|
||||
@@ -16,6 +16,8 @@ export type TCreatePkiSubscriberDTO = {
|
||||
subjectAlternativeNames: string[];
|
||||
keyUsages: CertKeyUsage[];
|
||||
extendedKeyUsages: CertExtendedKeyUsage[];
|
||||
enableAutoRenewal?: boolean;
|
||||
autoRenewalPeriodInDays?: number;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TGetPkiSubscriberDTO = {
|
||||
@@ -32,6 +34,8 @@ export type TUpdatePkiSubscriberDTO = {
|
||||
subjectAlternativeNames?: string[];
|
||||
keyUsages?: CertKeyUsage[];
|
||||
extendedKeyUsages?: CertExtendedKeyUsage[];
|
||||
enableAutoRenewal?: boolean;
|
||||
autoRenewalPeriodInDays?: number;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TDeletePkiSubscriberDTO = {
|
||||
|
||||
Reference in New Issue
Block a user