From 208ba59e65d5124b00c85f0fcefcd15a5dc85d5f Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Thu, 6 Nov 2025 03:28:21 -0300 Subject: [PATCH] Address greptile comments --- backend/src/server/routes/index.ts | 2 +- .../src/server/routes/v2/pki-alert-router.ts | 3 +- .../pki-alert-v2/pki-alert-v2-filter-utils.ts | 4 ++ .../pki-alert-v2/pki-alert-v2-queue.ts | 70 ++++++------------- .../pki-alert-v2/pki-alert-v2-service.ts | 11 ++- .../pki-alert-v2/pki-alert-v2-types.ts | 7 +- frontend/src/hooks/api/pkiAlertsV2/types.ts | 3 +- .../components/CreatePkiAlertV2FormSteps.tsx | 7 +- 8 files changed, 49 insertions(+), 58 deletions(-) diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 54b7e8b5a..5bcb56238 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -2378,7 +2378,7 @@ export const registerRoutes = async ( await dailyReminderQueueService.startSecretReminderMigrationJob(); await dailyExpiringPkiItemAlert.startSendingAlerts(); await pkiSubscriberQueue.startDailyAutoRenewalJob(); - await pkiAlertV2Queue.startDailyAlertProcessing(); + await pkiAlertV2Queue.init(); await certificateV3Queue.init(); await kmsService.startService(hsmStatus); await microsoftTeamsService.start(); diff --git a/backend/src/server/routes/v2/pki-alert-router.ts b/backend/src/server/routes/v2/pki-alert-router.ts index 0a5269225..d1352cda4 100644 --- a/backend/src/server/routes/v2/pki-alert-router.ts +++ b/backend/src/server/routes/v2/pki-alert-router.ts @@ -6,6 +6,7 @@ import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; import { CreatePkiAlertV2Schema, + createSecureAlertBeforeValidator, PkiAlertEventType, PkiFilterRuleSchema, UpdatePkiAlertV2Schema @@ -392,7 +393,7 @@ export const registerPkiAlertRouter = async (server: FastifyZodProvider) => { filters: z.array(PkiFilterRuleSchema), alertBefore: z .string() - .regex(/^\d+[dwmy]$/) + .refine(createSecureAlertBeforeValidator(), "Must be in format like '30d', '1w', '3m', '1y'") .describe("Alert timing (e.g., '30d', '1w')"), limit: z.coerce.number().min(1).max(100).default(20), offset: z.coerce.number().min(0).default(0) diff --git a/backend/src/services/pki-alert-v2/pki-alert-v2-filter-utils.ts b/backend/src/services/pki-alert-v2/pki-alert-v2-filter-utils.ts index f81e98df5..fc4bbc13a 100644 --- a/backend/src/services/pki-alert-v2/pki-alert-v2-filter-utils.ts +++ b/backend/src/services/pki-alert-v2/pki-alert-v2-filter-utils.ts @@ -20,6 +20,10 @@ export const sanitizeLikeInput = (input: string): string => { }; export const parseTimeToPostgresInterval = (duration: string): string => { + if (duration.length > 32) { + throw new Error(`Invalid duration format: ${duration}. Use format like '30d', '1w', '3m', '1y'`); + } + const durationRegex = new RE2("^(\\d+)([dwmy])$"); const match = durationRegex.exec(duration); diff --git a/backend/src/services/pki-alert-v2/pki-alert-v2-queue.ts b/backend/src/services/pki-alert-v2/pki-alert-v2-queue.ts index d42c3f503..d2cd02320 100644 --- a/backend/src/services/pki-alert-v2/pki-alert-v2-queue.ts +++ b/backend/src/services/pki-alert-v2/pki-alert-v2-queue.ts @@ -1,5 +1,6 @@ /* eslint-disable no-await-in-loop */ +import { getConfig } from "@app/lib/config/env"; import { logger } from "@app/lib/logger"; import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue"; @@ -24,6 +25,7 @@ export const pkiAlertV2QueueServiceFactory = ({ pkiAlertV2DAL, pkiAlertHistoryDAL }: TPkiAlertV2QueueServiceFactoryDep) => { + const appCfg = getConfig(); const calculateDeduplicationWindow = (alertBefore: string): number => { const alertDays = parseTimeToDays(alertBefore); @@ -185,60 +187,34 @@ export const pkiAlertV2QueueServiceFactory = ({ ); }; - queueService.start(QueueName.DailyPkiAlertV2Processing, async () => { - logger.info(`${QueueName.DailyPkiAlertV2Processing}: queue task started`); - - try { - await processDailyAlerts(); - logger.info(`${QueueName.DailyPkiAlertV2Processing}: queue task completed successfully`); - } catch (error) { - logger.error(error, `${QueueName.DailyPkiAlertV2Processing}: queue task failed`); - throw error; + const init = async () => { + if (appCfg.isSecondaryInstance) { + return; } - }); - const startDailyAlertProcessing = async () => { - await queueService.stopRepeatableJob( - QueueName.DailyPkiAlertV2Processing, + await queueService.startPg( QueueJobs.DailyPkiAlertV2Processing, - { pattern: "* * * * *", utc: true }, - QueueName.DailyPkiAlertV2Processing + async () => { + try { + logger.info(`${QueueJobs.DailyPkiAlertV2Processing}: queue task started`); + await processDailyAlerts(); + logger.info(`${QueueJobs.DailyPkiAlertV2Processing}: queue task completed successfully`); + } catch (error) { + logger.error(error, `${QueueJobs.DailyPkiAlertV2Processing}: queue task failed`); + throw error; + } + }, + { + batchSize: 1, + workerCount: 1, + pollingIntervalSeconds: 60 + } ); - await queueService.queue(QueueName.DailyPkiAlertV2Processing, QueueJobs.DailyPkiAlertV2Processing, undefined, { - delay: 5000, - jobId: QueueName.DailyPkiAlertV2Processing, - repeat: { pattern: "* * * * *", utc: true } - }); - - logger.info("Daily PKI alert processing job scheduled"); + await queueService.schedulePg(QueueJobs.DailyPkiAlertV2Processing, "* * * * *", undefined, { tz: "UTC" }); }; - const stopDailyAlertProcessing = async () => { - await queueService.stopRepeatableJob( - QueueName.DailyPkiAlertV2Processing, - QueueJobs.DailyPkiAlertV2Processing, - { pattern: "* * * * *", utc: true }, - QueueName.DailyPkiAlertV2Processing - ); - - logger.info("Daily PKI alert processing job stopped"); - }; - - const triggerAlertProcessing = async () => { - await queueService.queue(QueueName.DailyPkiAlertV2Processing, QueueJobs.DailyPkiAlertV2Processing, undefined, { - delay: 1000 - }); - }; - - queueService.listen(QueueName.DailyPkiAlertV2Processing, "failed", (_, err) => { - logger.error(err, `${QueueName.DailyPkiAlertV2Processing}: Daily PKI alert processing failed`); - }); - return { - startDailyAlertProcessing, - stopDailyAlertProcessing, - triggerAlertProcessing, - processDailyAlerts + init }; }; diff --git a/backend/src/services/pki-alert-v2/pki-alert-v2-service.ts b/backend/src/services/pki-alert-v2/pki-alert-v2-service.ts index a0d5fab7b..ab00ef9a6 100644 --- a/backend/src/services/pki-alert-v2/pki-alert-v2-service.ts +++ b/backend/src/services/pki-alert-v2/pki-alert-v2-service.ts @@ -374,6 +374,7 @@ export const pkiAlertV2ServiceFactory = ({ const listCurrentMatchingCertificates = async ({ projectId, filters, + alertBefore, limit = 20, offset = 0, actorId, @@ -392,14 +393,22 @@ export const pkiAlertV2ServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.PkiAlerts); + try { + parseTimeToPostgresInterval(alertBefore); + } catch (error) { + throw new BadRequestError({ message: "Invalid alertBefore format. Use format like '30d', '1w', '3m', '1y'" }); + } + const options: { limit: number; offset: number; showPreview?: boolean; + alertBefore?: string; } = { limit, offset, - showPreview: true + showPreview: true, + alertBefore: parseTimeToPostgresInterval(alertBefore) }; const result = await pkiAlertV2DAL.findMatchingCertificates(projectId, filters, options); diff --git a/backend/src/services/pki-alert-v2/pki-alert-v2-types.ts b/backend/src/services/pki-alert-v2/pki-alert-v2-types.ts index 84e7f2391..64bf834e5 100644 --- a/backend/src/services/pki-alert-v2/pki-alert-v2-types.ts +++ b/backend/src/services/pki-alert-v2/pki-alert-v2-types.ts @@ -8,9 +8,12 @@ const createSecureSlugValidator = () => { return (value: string) => slugRegex.test(value); }; -const createSecureAlertBeforeValidator = () => { +export const createSecureAlertBeforeValidator = () => { const alertBeforeRegex = new RE2("^\\d+[dwmy]$"); - return (value: string) => alertBeforeRegex.test(value); + return (value: string) => { + if (value.length > 32) return false; + return alertBeforeRegex.test(value); + }; }; export enum PkiAlertEventType { diff --git a/frontend/src/hooks/api/pkiAlertsV2/types.ts b/frontend/src/hooks/api/pkiAlertsV2/types.ts index 4453cfadd..3b38118af 100644 --- a/frontend/src/hooks/api/pkiAlertsV2/types.ts +++ b/frontend/src/hooks/api/pkiAlertsV2/types.ts @@ -181,7 +181,8 @@ export const createPkiAlertV2Schema = z.object({ eventType: z.nativeEnum(PkiAlertEventTypeV2), alertBefore: z .string() - .regex(/^\d+[dwmy]$/) + .regex(/^\d+[dwmy]$/, "Must be in format like '30d', '1w', '3m', '1y'") + .refine((val) => val.length <= 32, "Alert timing too long") .optional(), filters: z.array(pkiFilterRuleV2Schema), enabled: z.boolean().default(true), diff --git a/frontend/src/views/PkiAlertsV2Page/components/CreatePkiAlertV2FormSteps.tsx b/frontend/src/views/PkiAlertsV2Page/components/CreatePkiAlertV2FormSteps.tsx index c048f79d6..5def9aa18 100644 --- a/frontend/src/views/PkiAlertsV2Page/components/CreatePkiAlertV2FormSteps.tsx +++ b/frontend/src/views/PkiAlertsV2Page/components/CreatePkiAlertV2FormSteps.tsx @@ -249,7 +249,7 @@ export const CreatePkiAlertV2FormSteps = () => { {watchedFilters?.map((filter, index) => (
@@ -551,10 +551,7 @@ export const CreatePkiAlertV2FormSteps = () => {
{watchedFilters && watchedFilters.length > 0 ? ( watchedFilters.map((filter, index) => ( - + {filter.field .replace(/_/g, " ")