refactor(secret-sync): consolidate secret name validation to a single check in SecretNameSchema

This commit is contained in:
Victor Santos
2025-10-23 17:20:31 -03:00
parent 761a898484
commit 41e3026658
2 changed files with 15 additions and 6 deletions
+3 -3
View File
@@ -43,6 +43,6 @@ export const GenericResourceNameSchema = z
export const BaseSecretNameSchema = z.string().trim().min(1); export const BaseSecretNameSchema = z.string().trim().min(1);
export const SecretNameSchema = BaseSecretNameSchema.refine( export const SecretNameSchema = BaseSecretNameSchema.refine(
(el) => !el.includes(":"), (el) => !el.includes(":") && !el.includes("/"),
"Secret name cannot contain colon." "Secret name cannot contain colon or forward slash."
).refine((el) => !el.includes("/"), "Secret name cannot contain forward slash."); );
@@ -11,6 +11,7 @@ import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue"; import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
import { SecretNameSchema } from "@app/server/lib/schemas";
import { decryptAppConnectionCredentials } from "@app/services/app-connection/app-connection-fns"; import { decryptAppConnectionCredentials } from "@app/services/app-connection/app-connection-fns";
import { ActorType } from "@app/services/auth/auth-type"; import { ActorType } from "@app/services/auth/auth-type";
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
@@ -63,7 +64,6 @@ import { TAppConnectionDALFactory } from "../app-connection/app-connection-dal";
import { TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service"; import { TFolderCommitServiceFactory } from "../folder-commit/folder-commit-service";
import { TNotificationServiceFactory } from "../notification/notification-service"; import { TNotificationServiceFactory } from "../notification/notification-service";
import { NotificationType } from "../notification/notification-types"; import { NotificationType } from "../notification/notification-types";
import { SecretNameSchema } from "@app/server/lib/schemas";
export type TSecretSyncQueueFactory = ReturnType<typeof secretSyncQueueFactory>; export type TSecretSyncQueueFactory = ReturnType<typeof secretSyncQueueFactory>;
@@ -409,14 +409,23 @@ export const secretSyncQueueFactory = ({
if (!Object.keys(importedSecrets).length) return {}; if (!Object.keys(importedSecrets).length) return {};
let invalidNameCount = 0;
let errorMessage = "";
for (const [key] of Object.entries(importedSecrets)) { for (const [key] of Object.entries(importedSecrets)) {
const result = SecretNameSchema.safeParse(key); const result = SecretNameSchema.safeParse(key);
if (!result.success) { if (!result.success) {
const errorMessage = result.error.issues[0]?.message || "Invalid secret name"; invalidNameCount += 1;
throw new Error(`Invalid secret name "${key}": ${errorMessage}`); if (errorMessage === "") errorMessage = result.error.issues[0]?.message;
} }
} }
if (invalidNameCount > 0) {
throw new Error(
`Found ${invalidNameCount} invalid secret name${invalidNameCount === 1 ? "" : "s"}. ${errorMessage}`
);
}
const importedSecretMap: TSecretMap = {}; const importedSecretMap: TSecretMap = {};
const secretMap = await $getInfisicalSecrets(secretSync, false); const secretMap = await $getInfisicalSecrets(secretSync, false);