From 5c9243d6911bcfa823ead3f82c714969e446da66 Mon Sep 17 00:00:00 2001 From: x032205 Date: Thu, 7 Aug 2025 23:15:48 -0400 Subject: [PATCH 1/3] feat(access-policies): Allow policy limits on access request times --- ...808021941_access-policy-max-time-period.ts | 19 ++++++++ .../db/schemas/access-approval-policies.ts | 3 +- .../v1/access-approval-policy-router.ts | 43 +++++++++++++++++-- .../v1/access-approval-request-router.ts | 3 +- .../access-approval-policy-dal.ts | 3 ++ .../access-approval-policy-service.ts | 12 ++++-- .../access-approval-policy-types.ts | 13 +++++- .../access-approval-request-dal.ts | 14 ++++-- .../access-approval-request-service.ts | 9 ++++ .../access-approval-request-types.ts | 1 + .../src/hooks/api/accessApproval/mutation.tsx | 12 ++++-- .../src/hooks/api/accessApproval/types.ts | 4 ++ .../SpecificPrivilegeSection.tsx | 18 ++++++++ .../components/AccessPolicyModal.tsx | 22 +++++++++- .../SecretListView/SecretDetailSidebar.tsx | 13 ++++-- 15 files changed, 166 insertions(+), 23 deletions(-) create mode 100644 backend/src/db/migrations/20250808021941_access-policy-max-time-period.ts diff --git a/backend/src/db/migrations/20250808021941_access-policy-max-time-period.ts b/backend/src/db/migrations/20250808021941_access-policy-max-time-period.ts new file mode 100644 index 000000000..218260b3e --- /dev/null +++ b/backend/src/db/migrations/20250808021941_access-policy-max-time-period.ts @@ -0,0 +1,19 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas/models"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasColumn(TableName.AccessApprovalPolicy, "maxTimePeriod"))) { + await knex.schema.alterTable(TableName.AccessApprovalPolicy, (t) => { + t.string("maxTimePeriod").nullable(); // Ex: 1h - Null is permanent + }); + } +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasColumn(TableName.AccessApprovalPolicy, "maxTimePeriod")) { + await knex.schema.alterTable(TableName.AccessApprovalPolicy, (t) => { + t.dropColumn("maxTimePeriod"); + }); + } +} diff --git a/backend/src/db/schemas/access-approval-policies.ts b/backend/src/db/schemas/access-approval-policies.ts index ea57c54d2..66ed79ab7 100644 --- a/backend/src/db/schemas/access-approval-policies.ts +++ b/backend/src/db/schemas/access-approval-policies.ts @@ -17,7 +17,8 @@ export const AccessApprovalPoliciesSchema = z.object({ updatedAt: z.date(), enforcementLevel: z.string().default("hard"), deletedAt: z.date().nullable().optional(), - allowedSelfApprovals: z.boolean().default(true) + allowedSelfApprovals: z.boolean().default(true), + maxTimePeriod: z.string().nullable().optional() }); export type TAccessApprovalPolicies = z.infer; 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 ef44344de..f5278476f 100644 --- a/backend/src/ee/routes/v1/access-approval-policy-router.ts +++ b/backend/src/ee/routes/v1/access-approval-policy-router.ts @@ -3,6 +3,7 @@ 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 { ms } from "@app/lib/ms"; import { EnforcementLevel } from "@app/lib/types"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -71,7 +72,24 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi .optional(), approvals: z.number().min(1).default(1), enforcementLevel: z.nativeEnum(EnforcementLevel).default(EnforcementLevel.Hard), - allowedSelfApprovals: z.boolean().default(true) + allowedSelfApprovals: z.boolean().default(true), + maxTimePeriod: z + .string() + .trim() + .optional() + .transform((val, ctx) => { + if (val === undefined) return undefined; + const parsedMs = ms(val); + + if (typeof parsedMs !== "number" || parsedMs <= 0) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Invalid time period format or value. Must be a positive duration (e.g., '1h', '30m', '2d')." + }); + return z.NEVER; + } + return val; + }) }) .refine( (val) => Boolean(val.environment) || Boolean(val.environments), @@ -124,7 +142,8 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi .array() .nullable() .optional(), - bypassers: z.object({ type: z.nativeEnum(BypasserType), id: z.string().nullable().optional() }).array() + bypassers: z.object({ type: z.nativeEnum(BypasserType), id: z.string().nullable().optional() }).array(), + maxTimePeriod: z.string().nullable().optional() }) .array() .nullable() @@ -233,7 +252,24 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi stepNumber: z.number().int() }) .array() + .optional(), + maxTimePeriod: z + .string() + .trim() .optional() + .transform((val, ctx) => { + if (val === undefined) return undefined; + const parsedMs = ms(val); + + if (typeof parsedMs !== "number" || parsedMs <= 0) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Invalid time period format or value. Must be a positive duration (e.g., '1h', '30m', '2d')." + }); + return z.NEVER; + } + return val; + }) }), response: { 200: z.object({ @@ -314,7 +350,8 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi }) .array() .nullable() - .optional() + .optional(), + maxTimePeriod: z.string().nullable().optional() }) }) } diff --git a/backend/src/ee/routes/v1/access-approval-request-router.ts b/backend/src/ee/routes/v1/access-approval-request-router.ts index 7a70d6374..c9e7b0d5c 100644 --- a/backend/src/ee/routes/v1/access-approval-request-router.ts +++ b/backend/src/ee/routes/v1/access-approval-request-router.ts @@ -128,7 +128,8 @@ export const registerAccessApprovalRequestRouter = async (server: FastifyZodProv envId: z.string(), enforcementLevel: z.string(), deletedAt: z.date().nullish(), - allowedSelfApprovals: z.boolean() + allowedSelfApprovals: z.boolean(), + maxTimePeriod: z.string().nullable().optional() }), reviewers: 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 9baf762d6..78221d988 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 @@ -56,6 +56,7 @@ export interface TAccessApprovalPolicyDALFactory allowedSelfApprovals: boolean; secretPath: string; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; projectId: string; bypassers: ( | { @@ -96,6 +97,7 @@ export interface TAccessApprovalPolicyDALFactory allowedSelfApprovals: boolean; secretPath: string; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; environments: { id: string; name: string; @@ -141,6 +143,7 @@ export interface TAccessApprovalPolicyDALFactory allowedSelfApprovals: boolean; secretPath: string; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; } | undefined >; 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 0b3c4e128..95d1a9877 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 @@ -100,7 +100,8 @@ export const accessApprovalPolicyServiceFactory = ({ environments, enforcementLevel, allowedSelfApprovals, - approvalsRequired + approvalsRequired, + maxTimePeriod }) => { const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); @@ -219,7 +220,8 @@ export const accessApprovalPolicyServiceFactory = ({ secretPath, name, enforcementLevel, - allowedSelfApprovals + allowedSelfApprovals, + maxTimePeriod }, tx ); @@ -318,7 +320,8 @@ export const accessApprovalPolicyServiceFactory = ({ enforcementLevel, allowedSelfApprovals, approvalsRequired, - environments + environments, + maxTimePeriod }: TUpdateAccessApprovalPolicy) => { const groupApprovers = approvers.filter((approver) => approver.type === ApproverType.Group); @@ -461,7 +464,8 @@ export const accessApprovalPolicyServiceFactory = ({ secretPath, name, enforcementLevel, - allowedSelfApprovals + allowedSelfApprovals, + maxTimePeriod }, tx ); 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 27ec228f7..0ed8b0582 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 @@ -41,6 +41,7 @@ export type TCreateAccessApprovalPolicy = { enforcementLevel: EnforcementLevel; allowedSelfApprovals: boolean; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; + maxTimePeriod?: string; } & Omit; export type TUpdateAccessApprovalPolicy = { @@ -60,6 +61,7 @@ export type TUpdateAccessApprovalPolicy = { allowedSelfApprovals: boolean; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; environments?: string[]; + maxTimePeriod?: string; } & Omit; export type TDeleteAccessApprovalPolicy = { @@ -104,7 +106,8 @@ export interface TAccessApprovalPolicyServiceFactory { environment, enforcementLevel, allowedSelfApprovals, - approvalsRequired + approvalsRequired, + maxTimePeriod }: TCreateAccessApprovalPolicy) => Promise<{ environment: { name: string; @@ -135,6 +138,7 @@ export interface TAccessApprovalPolicyServiceFactory { allowedSelfApprovals: boolean; secretPath: string; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; }>; deleteAccessApprovalPolicy: ({ policyId, @@ -159,6 +163,7 @@ export interface TAccessApprovalPolicyServiceFactory { allowedSelfApprovals: boolean; secretPath: string; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; environment: { id: string; name: string; @@ -185,7 +190,8 @@ export interface TAccessApprovalPolicyServiceFactory { enforcementLevel, allowedSelfApprovals, approvalsRequired, - environments + environments, + maxTimePeriod }: TUpdateAccessApprovalPolicy) => Promise<{ environment: { id: string; @@ -208,6 +214,7 @@ export interface TAccessApprovalPolicyServiceFactory { allowedSelfApprovals: boolean; secretPath?: string | null | undefined; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; }>; getAccessApprovalPolicyByProjectSlug: ({ actorId, @@ -242,6 +249,7 @@ export interface TAccessApprovalPolicyServiceFactory { allowedSelfApprovals: boolean; secretPath: string; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; environment: { id: string; name: string; @@ -298,6 +306,7 @@ export interface TAccessApprovalPolicyServiceFactory { allowedSelfApprovals: boolean; secretPath: string; deletedAt?: Date | null | undefined; + maxTimePeriod?: string | null; environment: { id: string; name: string; diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts b/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts index 9872df067..68f9240a6 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts @@ -63,6 +63,7 @@ export interface TAccessApprovalRequestDALFactory extends Omit { @@ -595,7 +600,8 @@ export const accessApprovalRequestDALFactory = (db: TDbClient): TAccessApprovalR secretPath: el.policySecretPath, enforcementLevel: el.policyEnforcementLevel, allowedSelfApprovals: el.policyAllowedSelfApprovals, - deletedAt: el.policyDeletedAt + deletedAt: el.policyDeletedAt, + maxTimePeriod: el.policyMaxTimePeriod }, requestedByUser: { userId: el.requestedByUserId, diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts index dcbe717da..58f5c57db 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts @@ -156,6 +156,15 @@ export const accessApprovalRequestServiceFactory = ({ throw new BadRequestError({ message: "The policy linked to this request has been deleted" }); } + // Check if the requested time falls under policy.maxTimePeriod + if (policy.maxTimePeriod) { + if (!temporaryRange || ms(temporaryRange) > ms(policy.maxTimePeriod)) { + throw new BadRequestError({ + message: `Requested access time range is limited to ${policy.maxTimePeriod} by policy` + }); + } + } + const approverIds: string[] = []; const approverGroupIds: string[] = []; diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-types.ts b/backend/src/ee/services/access-approval-request/access-approval-request-types.ts index 9066aec8f..88a46192b 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-types.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-types.ts @@ -82,6 +82,7 @@ export interface TAccessApprovalRequestServiceFactory { allowedSelfApprovals: boolean; envId: string; deletedAt: Date | null | undefined; + maxTimePeriod?: string | null; }; projectId: string; environment: string; diff --git a/frontend/src/hooks/api/accessApproval/mutation.tsx b/frontend/src/hooks/api/accessApproval/mutation.tsx index ad7917a8f..69637243f 100644 --- a/frontend/src/hooks/api/accessApproval/mutation.tsx +++ b/frontend/src/hooks/api/accessApproval/mutation.tsx @@ -26,7 +26,8 @@ export const useCreateAccessApprovalPolicy = () => { secretPath, enforcementLevel, allowedSelfApprovals, - approvalsRequired + approvalsRequired, + maxTimePeriod }) => { const { data } = await apiRequest.post("/api/v1/access-approvals/policies", { environments, @@ -38,7 +39,8 @@ export const useCreateAccessApprovalPolicy = () => { name, enforcementLevel, allowedSelfApprovals, - approvalsRequired + approvalsRequired, + maxTimePeriod }); return data; }, @@ -64,7 +66,8 @@ export const useUpdateAccessApprovalPolicy = () => { enforcementLevel, allowedSelfApprovals, approvalsRequired, - environments + environments, + maxTimePeriod }) => { const { data } = await apiRequest.patch(`/api/v1/access-approvals/policies/${id}`, { approvals, @@ -75,7 +78,8 @@ export const useUpdateAccessApprovalPolicy = () => { enforcementLevel, allowedSelfApprovals, approvalsRequired, - environments + environments, + maxTimePeriod }); return data; }, diff --git a/frontend/src/hooks/api/accessApproval/types.ts b/frontend/src/hooks/api/accessApproval/types.ts index bc569165b..5d2344977 100644 --- a/frontend/src/hooks/api/accessApproval/types.ts +++ b/frontend/src/hooks/api/accessApproval/types.ts @@ -18,6 +18,7 @@ export type TAccessApprovalPolicy = { approvers?: Approver[]; bypassers?: Bypasser[]; allowedSelfApprovals: boolean; + maxTimePeriod?: string; }; export enum ApproverType { @@ -93,6 +94,7 @@ export type TAccessApprovalRequest = { enforcementLevel: EnforcementLevel; deletedAt: Date | null; allowedSelfApprovals: boolean; + maxTimePeriod: string | null; }; reviewers: { @@ -173,6 +175,7 @@ export type TCreateAccessPolicyDTO = { enforcementLevel?: EnforcementLevel; allowedSelfApprovals: boolean; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; + maxTimePeriod?: string; }; export type TUpdateAccessPolicyDTO = { @@ -188,6 +191,7 @@ export type TUpdateAccessPolicyDTO = { // for invalidating list projectSlug: string; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; + maxTimePeriod?: string; }; export type TDeleteSecretPolicyDTO = { diff --git a/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx b/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx index 0256d3219..5dd439744 100644 --- a/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx @@ -220,6 +220,24 @@ export const SpecificPrivilegeSecretForm = ({ return; } + const policy = policies.find( + (p) => + p.environments.find((e) => e.slug === selectedEnvironment) && p.secretPath === secretPath + ); + + if ( + policy?.maxTimePeriod && + (!data.temporaryAccess.isTemporary || + ms(data.temporaryAccess.temporaryRange) > ms(policy.maxTimePeriod)) + ) { + createNotification({ + type: "error", + text: `Requested access time range is limited to ${policy.maxTimePeriod} by policy`, + title: "Error" + }); + return; + } + const actions = [ { action: ProjectPermissionActions.Read, allowed: data.read }, { action: ProjectPermissionActions.Create, allowed: data.create }, diff --git a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/ApprovalPolicyList/components/AccessPolicyModal.tsx b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/ApprovalPolicyList/components/AccessPolicyModal.tsx index b254b8ac7..d55556470 100644 --- a/frontend/src/pages/secret-manager/SecretApprovalsPage/components/ApprovalPolicyList/components/AccessPolicyModal.tsx +++ b/frontend/src/pages/secret-manager/SecretApprovalsPage/components/ApprovalPolicyList/components/AccessPolicyModal.tsx @@ -91,7 +91,8 @@ const formSchema = z }) .array() .default([]) - .optional() + .optional(), + maxTimePeriod: z.string().trim().optional() }) .superRefine((data, ctx) => { if (data.policyType === PolicyType.ChangePolicy) { @@ -440,6 +441,25 @@ const Form = ({ )} /> + + {isAccessPolicyType && ( + ( + + + + )} + /> + )} + {!isAccessPolicyType && ( Date: Thu, 7 Aug 2025 23:25:36 -0400 Subject: [PATCH 2/3] Greptile review fixes --- .../v1/access-approval-policy-router.ts | 54 +++++++------------ .../src/hooks/api/accessApproval/types.ts | 2 +- 2 files changed, 21 insertions(+), 35 deletions(-) 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 f5278476f..a232ae603 100644 --- a/backend/src/ee/routes/v1/access-approval-policy-router.ts +++ b/backend/src/ee/routes/v1/access-approval-policy-router.ts @@ -10,6 +10,24 @@ import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { sapPubSchema } from "@app/server/routes/sanitizedSchemas"; import { AuthMode } from "@app/services/auth/auth-type"; +const maxTimePeriodSchema = z + .string() + .trim() + .optional() + .transform((val, ctx) => { + if (val === undefined) return undefined; + const parsedMs = ms(val); + + if (typeof parsedMs !== "number" || parsedMs <= 0) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Invalid time period format or value. Must be a positive duration (e.g., '1h', '30m', '2d')." + }); + return z.NEVER; + } + return val; + }); + export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvider) => { server.route({ url: "/", @@ -73,23 +91,7 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi approvals: z.number().min(1).default(1), enforcementLevel: z.nativeEnum(EnforcementLevel).default(EnforcementLevel.Hard), allowedSelfApprovals: z.boolean().default(true), - maxTimePeriod: z - .string() - .trim() - .optional() - .transform((val, ctx) => { - if (val === undefined) return undefined; - const parsedMs = ms(val); - - if (typeof parsedMs !== "number" || parsedMs <= 0) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Invalid time period format or value. Must be a positive duration (e.g., '1h', '30m', '2d')." - }); - return z.NEVER; - } - return val; - }) + maxTimePeriod: maxTimePeriodSchema }) .refine( (val) => Boolean(val.environment) || Boolean(val.environments), @@ -253,23 +255,7 @@ export const registerAccessApprovalPolicyRouter = async (server: FastifyZodProvi }) .array() .optional(), - maxTimePeriod: z - .string() - .trim() - .optional() - .transform((val, ctx) => { - if (val === undefined) return undefined; - const parsedMs = ms(val); - - if (typeof parsedMs !== "number" || parsedMs <= 0) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Invalid time period format or value. Must be a positive duration (e.g., '1h', '30m', '2d')." - }); - return z.NEVER; - } - return val; - }) + maxTimePeriod: maxTimePeriodSchema }), response: { 200: z.object({ diff --git a/frontend/src/hooks/api/accessApproval/types.ts b/frontend/src/hooks/api/accessApproval/types.ts index 5d2344977..85c565caa 100644 --- a/frontend/src/hooks/api/accessApproval/types.ts +++ b/frontend/src/hooks/api/accessApproval/types.ts @@ -94,7 +94,7 @@ export type TAccessApprovalRequest = { enforcementLevel: EnforcementLevel; deletedAt: Date | null; allowedSelfApprovals: boolean; - maxTimePeriod: string | null; + maxTimePeriod?: string | null; }; reviewers: { From ce8653e908a0e30c732b9caa4d9528fc0b00a7ea Mon Sep 17 00:00:00 2001 From: x032205 Date: Mon, 11 Aug 2025 15:15:48 -0700 Subject: [PATCH 3/3] Address reviews --- backend/src/ee/routes/v1/access-approval-policy-router.ts | 3 ++- .../access-approval-policy/access-approval-policy-types.ts | 4 ++-- frontend/src/hooks/api/accessApproval/types.ts | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) 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 a232ae603..d8d3bf9ed 100644 --- a/backend/src/ee/routes/v1/access-approval-policy-router.ts +++ b/backend/src/ee/routes/v1/access-approval-policy-router.ts @@ -13,9 +13,10 @@ import { AuthMode } from "@app/services/auth/auth-type"; const maxTimePeriodSchema = z .string() .trim() - .optional() + .nullish() .transform((val, ctx) => { if (val === undefined) return undefined; + if (!val || val === "permanent") return null; const parsedMs = ms(val); if (typeof parsedMs !== "number" || parsedMs <= 0) { 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 0ed8b0582..997849800 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 @@ -41,7 +41,7 @@ export type TCreateAccessApprovalPolicy = { enforcementLevel: EnforcementLevel; allowedSelfApprovals: boolean; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; - maxTimePeriod?: string; + maxTimePeriod?: string | null; } & Omit; export type TUpdateAccessApprovalPolicy = { @@ -61,7 +61,7 @@ export type TUpdateAccessApprovalPolicy = { allowedSelfApprovals: boolean; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; environments?: string[]; - maxTimePeriod?: string; + maxTimePeriod?: string | null; } & Omit; export type TDeleteAccessApprovalPolicy = { diff --git a/frontend/src/hooks/api/accessApproval/types.ts b/frontend/src/hooks/api/accessApproval/types.ts index 85c565caa..fc14352f8 100644 --- a/frontend/src/hooks/api/accessApproval/types.ts +++ b/frontend/src/hooks/api/accessApproval/types.ts @@ -18,7 +18,7 @@ export type TAccessApprovalPolicy = { approvers?: Approver[]; bypassers?: Bypasser[]; allowedSelfApprovals: boolean; - maxTimePeriod?: string; + maxTimePeriod?: string | null; }; export enum ApproverType { @@ -175,7 +175,7 @@ export type TCreateAccessPolicyDTO = { enforcementLevel?: EnforcementLevel; allowedSelfApprovals: boolean; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; - maxTimePeriod?: string; + maxTimePeriod?: string | null; }; export type TUpdateAccessPolicyDTO = { @@ -191,7 +191,7 @@ export type TUpdateAccessPolicyDTO = { // for invalidating list projectSlug: string; approvalsRequired?: { numberOfApprovals: number; stepNumber: number }[]; - maxTimePeriod?: string; + maxTimePeriod?: string | null; }; export type TDeleteSecretPolicyDTO = {