diff --git a/backend/src/db/schemas/access-approval-policies.ts b/backend/src/db/schemas/access-approval-policies.ts index 19a98675f..ea57c54d2 100644 --- a/backend/src/db/schemas/access-approval-policies.ts +++ b/backend/src/db/schemas/access-approval-policies.ts @@ -11,7 +11,7 @@ export const AccessApprovalPoliciesSchema = z.object({ id: z.string().uuid(), name: z.string(), approvals: z.number().default(1), - secretPath: z.string().nullable().optional(), + secretPath: z.string(), envId: z.string().uuid(), createdAt: z.date(), updatedAt: z.date(), diff --git a/backend/src/db/schemas/secret-approval-policies.ts b/backend/src/db/schemas/secret-approval-policies.ts index 8b9174456..0273e617c 100644 --- a/backend/src/db/schemas/secret-approval-policies.ts +++ b/backend/src/db/schemas/secret-approval-policies.ts @@ -10,7 +10,7 @@ import { TImmutableDBKeys } from "./models"; export const SecretApprovalPoliciesSchema = z.object({ id: z.string().uuid(), name: z.string(), - secretPath: z.string().nullable().optional(), + secretPath: z.string(), approvals: z.number().default(1), envId: z.string().uuid(), createdAt: z.date(), diff --git a/backend/src/ee/routes/v1/access-approval-policy-router.ts b/backend/src/ee/routes/v1/access-approval-policy-router.ts index 9e7e22241..177f5e1fd 100644 --- a/backend/src/ee/routes/v1/access-approval-policy-router.ts +++ b/backend/src/ee/routes/v1/access-approval-policy-router.ts @@ -2,6 +2,7 @@ import { nanoid } from "nanoid"; import { z } from "zod"; import { ApproverType, BypasserType } from "@app/ee/services/access-approval-policy/access-approval-policy-types"; +import { removeTrailingSlash } from "@app/lib/fn"; import { EnforcementLevel } from "@app/lib/types"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -19,7 +20,7 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi body: z.object({ projectSlug: z.string().trim(), name: z.string().optional(), - secretPath: z.string().trim().min(1, { message: "Secret path cannot be empty" }), + secretPath: z.string().trim().min(1, { message: "Secret path cannot be empty" }).transform(removeTrailingSlash), environment: z.string(), approvers: z .discriminatedUnion("type", [ @@ -171,7 +172,12 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi }), body: z.object({ name: z.string().optional(), - secretPath: z.string().trim().min(1, { message: "Secret path cannot be empty" }).optional(), + secretPath: z + .string() + .trim() + .min(1, { message: "Secret path cannot be empty" }) + .optional() + .transform((val) => (val ? removeTrailingSlash(val) : val)), approvers: z .discriminatedUnion("type", [ z.object({ diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts index 9fa48ca15..995534f8f 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts @@ -53,7 +53,7 @@ export interface TAccessApprovalPolicyDALFactory envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string; @@ -93,7 +93,7 @@ export interface TAccessApprovalPolicyDALFactory envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string; @@ -116,7 +116,7 @@ export interface TAccessApprovalPolicyDALFactory envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; }>; findLastValidPolicy: ( @@ -138,7 +138,7 @@ export interface TAccessApprovalPolicyDALFactory envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; } | undefined @@ -190,7 +190,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; }>; deleteAccessApprovalPolicy: ({ @@ -214,7 +214,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string; @@ -252,7 +252,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; }>; getAccessApprovalPolicyByProjectSlug: ({ @@ -286,7 +286,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string; @@ -337,7 +337,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string; diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts index 1622ad5c3..fa487d0b7 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts @@ -320,16 +320,10 @@ export const accessApprovalPolicyServiceFactory = ({ throw new BadRequestError({ message: "Approvals cannot be greater than approvers" }); } - // Case: Previously we allowed secret path to be null, but now we don't. - // This check ensures that we have a secret path to match with for finding conflicting policies. - if (!secretPath && !accessApprovalPolicy.secretPath) { - throw new BadRequestError({ message: "Secret path is required to update the policy" }); - } - if ( await $policyExists({ envId: accessApprovalPolicy.envId, - secretPath: secretPath || accessApprovalPolicy.secretPath || "", + secretPath: secretPath || accessApprovalPolicy.secretPath, policyId: accessApprovalPolicy.id }) ) { diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts index 6806c7123..f3f195914 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts @@ -122,7 +122,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; }>; deleteAccessApprovalPolicy: ({ @@ -146,7 +146,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string; @@ -218,7 +218,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string; @@ -269,7 +269,7 @@ export interface TAccessApprovalPolicyServiceFactory { envId: string; enforcementLevel: string; allowedSelfApprovals: boolean; - secretPath?: string | null | undefined; + secretPath: string; deletedAt?: Date | null | undefined; environment: { id: string;