diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index 3dc7daddc..e9ba49127 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -163,6 +163,27 @@ export type ProjectPermissionSet = | [ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback] | [ProjectPermissionActions.Edit, ProjectPermissionSub.Kms]; +const SECRET_PATH_MISSING_SLASH_ERR_MSG = "Invalid Secret Path; it must start with a '/'"; +const SECRET_PATH_PERMISSION_OPERATOR_SCHEMA = z.union([ + z.string().refine((val) => val.startsWith("/"), SECRET_PATH_MISSING_SLASH_ERR_MSG), + z + .object({ + [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ].refine( + (val) => val.startsWith("/"), + SECRET_PATH_MISSING_SLASH_ERR_MSG + ), + [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ].refine( + (val) => val.startsWith("/"), + SECRET_PATH_MISSING_SLASH_ERR_MSG + ), + [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN].refine( + (val) => val.every((el) => el.startsWith("/")), + SECRET_PATH_MISSING_SLASH_ERR_MSG + ), + [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] + }) + .partial() +]); // akhilmhdh: don't modify this for v2 // if you want to update create a new schema const SecretConditionV1Schema = z @@ -177,17 +198,7 @@ const SecretConditionV1Schema = z }) .partial() ]), - secretPath: z.union([ - z.string(), - z - .object({ - [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ], - [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ], - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN], - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] - }) - .partial() - ]) + secretPath: SECRET_PATH_PERMISSION_OPERATOR_SCHEMA }) .partial(); @@ -204,17 +215,7 @@ const SecretConditionV2Schema = z }) .partial() ]), - secretPath: z.union([ - z.string(), - z - .object({ - [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ], - [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ], - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN], - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] - }) - .partial() - ]), + secretPath: SECRET_PATH_PERMISSION_OPERATOR_SCHEMA, secretName: z.union([ z.string(), z diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx index 3a9e311fd..dc850581f 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx @@ -80,6 +80,19 @@ const ConditionSchema = z return true; }, { message: "Duplicate operator found for a condition" } + ) + .refine( + (val) => + val + .filter( + (el) => el.lhs === "secretPath" && el.operator !== PermissionConditionOperators.$GLOB + ) + .every((el) => + el.operator === PermissionConditionOperators.$IN + ? el.rhs.split(",").every((i) => i.trim().startsWith("/")) + : el.rhs.trim().startsWith("/") + ), + { message: "Invalid Secret Path. Must start with '/'" } ); export const projectRoleFormSchema = z.object({ diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx index 0956ab958..ab893cb09 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx @@ -36,6 +36,10 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) name: `permissions.secrets.${position}.conditions` }); + const conditionErrorMessage = + errors?.permissions?.secrets?.[position]?.conditions?.message || + errors?.permissions?.secrets?.[position]?.conditions?.root?.message; + return (

Conditions

@@ -147,10 +151,10 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) ); })}
- {errors?.permissions?.secrets?.[position]?.conditions?.message && ( + {conditionErrorMessage && (
- {errors?.permissions?.secrets?.[position]?.conditions?.message} + {conditionErrorMessage}
)}