1
0
mirror of https://github.com/Infisical/infisical.git synced 2025-03-31 22:09:57 +00:00

Fix: Seperate groups / project users additional privileges

This commit is contained in:
Daniel Hougaard
2024-05-04 03:11:58 +02:00
parent a183e94ff4
commit 3c6b7aee9a
5 changed files with 235 additions and 110 deletions
backend/src
ee/services
server/routes

@ -12,27 +12,37 @@ export type TAccessApprovalRequestDALFactory = ReturnType<typeof accessApprovalR
export const accessApprovalRequestDALFactory = (db: TDbClient) => {
const accessApprovalRequestOrm = ormify(db, TableName.AccessApprovalRequest);
const projectUserAdditionalPrivilegeOrm = ormify(db, TableName.ProjectUserAdditionalPrivilege);
const groupProjectUserAdditionalPrivilegeOrm = ormify(db, TableName.GroupProjectUserAdditionalPrivilege);
const deleteMany = async (filter: TFindFilter<TAccessApprovalRequests>, tx?: Knex) => {
const transaction = tx || (await db.transaction());
try {
const handleDeletion = async (processedTx: Knex) => {
const accessApprovalRequests = await accessApprovalRequestOrm.find(filter, { tx: processedTx });
const accessApprovalRequests = await accessApprovalRequestOrm.find(filter, { tx: transaction });
await projectUserAdditionalPrivilegeOrm.delete(
{
$in: {
id: accessApprovalRequests.filter((req) => !!req.privilegeId).map((req) => req.privilegeId!)
}
},
processedTx
);
await projectUserAdditionalPrivilegeOrm.delete(
{
$in: {
id: accessApprovalRequests
.filter((req) => Boolean(req.projectUserPrivilegeId))
.map((req) => req.projectUserPrivilegeId!)
}
},
transaction
);
return accessApprovalRequestOrm.delete(filter, processedTx);
};
await groupProjectUserAdditionalPrivilegeOrm.delete(
{
$in: {
id: accessApprovalRequests
.filter((req) => Boolean(req.groupProjectUserPrivilegeId))
.map((req) => req.groupProjectUserPrivilegeId!)
}
},
transaction
);
if (tx) return await handleDeletion(tx);
return await db.transaction(handleDeletion);
return await accessApprovalRequestOrm.delete(filter, transaction);
} catch (error) {
throw new DatabaseError({ error, name: "DeleteManyAccessApprovalRequest" });
}
@ -45,9 +55,14 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
.leftJoin(
TableName.ProjectUserAdditionalPrivilege,
`${TableName.AccessApprovalRequest}.privilegeId`,
`${TableName.AccessApprovalRequest}.projectUserPrivilegeId`,
`${TableName.ProjectUserAdditionalPrivilege}.id`
)
.leftJoin(
TableName.GroupProjectUserAdditionalPrivilege,
`${TableName.AccessApprovalRequest}.groupProjectUserPrivilegeId`,
`${TableName.GroupProjectUserAdditionalPrivilege}.id`
)
.leftJoin(
TableName.AccessApprovalPolicy,
`${TableName.AccessApprovalRequest}.policyId`,
@ -89,32 +104,81 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
db.ref("status").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerStatus")
)
// Project user additional privilege
.select(
db
.ref("projectMembershipId")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("privilegeProjectMembershipId"),
.as("projectPrivilegeProjectMembershipId"),
db.ref("isTemporary").withSchema(TableName.ProjectUserAdditionalPrivilege).as("projectPrivilegeIsTemporary"),
db
.ref("groupMembershipId")
.ref("temporaryMode")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("privilegeGroupMembershipId"),
db.ref("isTemporary").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeIsTemporary"),
db.ref("temporaryMode").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryMode"),
db.ref("temporaryRange").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryRange"),
.as("projectPrivilegeTemporaryMode"),
db
.ref("temporaryRange")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("projectPrivilegeTemporaryRange"),
db
.ref("temporaryAccessStartTime")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("privilegeTemporaryAccessStartTime"),
.as("projectPrivilegeTemporaryAccessStartTime"),
db
.ref("temporaryAccessEndTime")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("privilegeTemporaryAccessEndTime"),
.as("projectPrivilegeTemporaryAccessEndTime"),
db.ref("permissions").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegePermissions")
db.ref("permissions").withSchema(TableName.ProjectUserAdditionalPrivilege).as("projectPrivilegePermissions")
)
// Group project user additional privilege
.select(
db
.ref("groupProjectMembershipId")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegeGroupProjectMembershipId"),
db
.ref("requestedByUserId")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegeRequestedByUserId"),
db
.ref("isTemporary")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegeIsTemporary"),
db
.ref("temporaryMode")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegeTemporaryMode"),
db
.ref("temporaryRange")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegeTemporaryRange"),
db
.ref("temporaryAccessStartTime")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegeTemporaryAccessStartTime"),
db
.ref("temporaryAccessEndTime")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegeTemporaryAccessEndTime"),
db
.ref("permissions")
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
.as("groupPrivilegePermissions")
)
.orderBy(`${TableName.AccessApprovalRequest}.createdAt`, "desc");
const formattedDocs = sqlNestRelationships({
const projectUserFormattedDocs = sqlNestRelationships({
data: docs,
key: "id",
parentMapper: (doc) => ({
@ -129,20 +193,34 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
secretPath: doc.policySecretPath,
envId: doc.policyEnvId
},
privilege: doc.privilegeId
// eslint-disable-next-line no-nested-ternary
privilege: doc.projectUserPrivilegeId
? {
projectMembershipId: doc.privilegeGroupMembershipId,
groupMembershipId: doc.privilegeGroupMembershipId,
isTemporary: doc.privilegeIsTemporary,
temporaryMode: doc.privilegeTemporaryMode,
temporaryRange: doc.privilegeTemporaryRange,
temporaryAccessStartTime: doc.privilegeTemporaryAccessStartTime,
temporaryAccessEndTime: doc.privilegeTemporaryAccessEndTime,
permissions: doc.privilegePermissions
projectMembershipId: doc.projectMembershipId,
groupMembershipId: null,
requestedByUserId: null,
isTemporary: doc.projectPrivilegeIsTemporary,
temporaryMode: doc.projectPrivilegeTemporaryMode,
temporaryRange: doc.projectPrivilegeTemporaryRange,
temporaryAccessStartTime: doc.projectPrivilegeTemporaryAccessStartTime,
temporaryAccessEndTime: doc.projectPrivilegeTemporaryAccessEndTime,
permissions: doc.projectPrivilegePermissions
}
: null,
: doc.groupProjectUserPrivilegeId
? {
groupMembershipId: doc.groupPrivilegeGroupProjectMembershipId,
requestedByUserId: doc.groupPrivilegeRequestedByUserId,
projectMembershipId: null,
isTemporary: doc.groupPrivilegeIsTemporary,
temporaryMode: doc.groupPrivilegeTemporaryMode,
temporaryRange: doc.groupPrivilegeTemporaryRange,
temporaryAccessStartTime: doc.groupPrivilegeTemporaryAccessStartTime,
temporaryAccessEndTime: doc.groupPrivilegeTemporaryAccessEndTime,
permissions: doc.groupPrivilegePermissions
}
: null,
isApproved: !!doc.privilegeId
isApproved: !!doc.projectUserPrivilegeId
}),
childrenMapper: [
{
@ -155,9 +233,9 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
]
});
if (!formattedDocs) return [];
if (!projectUserFormattedDocs) return [];
return formattedDocs.map((doc) => ({
return projectUserFormattedDocs.map((doc) => ({
...doc,
policy: { ...doc.policy, approvers: doc.approvers }
}));
@ -247,12 +325,6 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
`${TableName.AccessApprovalPolicy}.id`
)
.leftJoin(TableName.Environment, `${TableName.AccessApprovalPolicy}.envId`, `${TableName.Environment}.id`)
.leftJoin(
TableName.ProjectUserAdditionalPrivilege,
`${TableName.AccessApprovalRequest}.privilegeId`,
`${TableName.ProjectUserAdditionalPrivilege}.id`
)
.leftJoin(
TableName.AccessApprovalRequestReviewer,
`${TableName.AccessApprovalRequest}.id`,
@ -282,12 +354,18 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
// an approval is pending if there is no reviewer rejections and no privilege ID is set
const pendingApprovals = formattedRequests.filter(
(req) => !req.privilegeId && !req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
(req) =>
!req.projectUserPrivilegeId &&
!req.groupProjectUserPrivilegeId &&
!req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
);
// an approval is finalized if there are any rejections or a privilege ID is set
const finalizedApprovals = formattedRequests.filter(
(req) => req.privilegeId || req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
(req) =>
req.projectUserPrivilegeId ||
req.groupProjectUserPrivilegeId ||
req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
);
return { pendingCount: pendingApprovals.length, finalizedCount: finalizedApprovals.length };

@ -2,11 +2,10 @@ import { ForbiddenError } from "@casl/ability";
import slugify from "@sindresorhus/slugify";
import ms from "ms";
import { ProjectMembershipRole } from "@app/db/schemas";
import { ProjectMembershipRole, TProjectUserAdditionalPrivilege } from "@app/db/schemas";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { TGroupProjectDALFactory } from "@app/services/group-project/group-project-dal";
import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal";
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
@ -16,7 +15,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal";
import { TAccessApprovalPolicyApproverDALFactory } from "../access-approval-policy/access-approval-policy-approver-dal";
import { TAccessApprovalPolicyDALFactory } from "../access-approval-policy/access-approval-policy-dal";
import { verifyApprovers } from "../access-approval-policy/access-approval-policy-fns";
import { TUserGroupMembershipDALFactory } from "../group/user-group-membership-dal";
import { TGroupProjectUserAdditionalPrivilegeDALFactory } from "../group-project-user-additional-privilege/group-project-user-additional-privilege-dal";
import { TPermissionServiceFactory } from "../permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission";
import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal";
@ -33,14 +32,13 @@ import {
TReviewAccessRequestDTO
} from "./access-approval-request-types";
type TSecretApprovalRequestServiceFactoryDep = {
type TAccessApprovalRequestServiceFactoryDep = {
additionalPrivilegeDAL: Pick<TProjectUserAdditionalPrivilegeDALFactory, "create" | "findById" | "deleteById">;
groupAdditionalPrivilegeDAL: TGroupProjectUserAdditionalPrivilegeDALFactory;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
accessApprovalPolicyApproverDAL: Pick<TAccessApprovalPolicyApproverDALFactory, "find">;
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne">;
projectDAL: Pick<TProjectDALFactory, "checkProjectUpgradeStatus" | "findProjectBySlug">;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findOne">;
groupProjectDAL: Pick<TGroupProjectDALFactory, "findOne">;
accessApprovalRequestDAL: Pick<
TAccessApprovalRequestDALFactory,
| "create"
@ -73,16 +71,15 @@ export const accessApprovalRequestServiceFactory = ({
projectEnvDAL,
permissionService,
accessApprovalRequestDAL,
groupAdditionalPrivilegeDAL,
accessApprovalRequestReviewerDAL,
userGroupMembershipDAL,
groupProjectDAL,
projectMembershipDAL,
accessApprovalPolicyDAL,
accessApprovalPolicyApproverDAL,
additionalPrivilegeDAL,
smtpService,
userDAL
}: TSecretApprovalRequestServiceFactoryDep) => {
}: TAccessApprovalRequestServiceFactoryDep) => {
const createAccessApprovalRequest = async ({
isTemporary,
temporaryRange,
@ -146,12 +143,21 @@ export const accessApprovalRequestServiceFactory = ({
if (duplicateRequests?.length > 0) {
for await (const duplicateRequest of duplicateRequests) {
if (duplicateRequest.privilegeId) {
const privilege = await additionalPrivilegeDAL.findById(duplicateRequest.privilegeId);
let foundPrivilege: Pick<
TProjectUserAdditionalPrivilege,
"temporaryAccessEndTime" | "isTemporary" | "id"
> | null = null;
const isExpired = new Date() > new Date(privilege.temporaryAccessEndTime || ("" as string));
if (duplicateRequest.projectUserPrivilegeId) {
foundPrivilege = await additionalPrivilegeDAL.findById(duplicateRequest.projectUserPrivilegeId);
} else if (duplicateRequest.groupProjectUserPrivilegeId) {
foundPrivilege = await groupAdditionalPrivilegeDAL.findById(duplicateRequest.groupProjectUserPrivilegeId);
}
if (!isExpired || !privilege.isTemporary) {
if (foundPrivilege) {
const isExpired = new Date() > new Date(foundPrivilege.temporaryAccessEndTime || ("" as string));
if (!isExpired || !foundPrivilege.isTemporary) {
throw new BadRequestError({ message: "You already have an active privilege with the same criteria" });
}
} else {
@ -241,7 +247,7 @@ export const accessApprovalRequestServiceFactory = ({
const accessApprovalRequest = await accessApprovalRequestDAL.findById(requestId);
if (!accessApprovalRequest?.privilegeId) {
if (!accessApprovalRequest?.projectUserPrivilegeId && !accessApprovalRequest?.groupProjectUserPrivilegeId) {
throw new BadRequestError({ message: "Access request must be approved to be deleted" });
}
@ -258,7 +264,11 @@ export const accessApprovalRequestServiceFactory = ({
throw new UnauthorizedError({ message: "Only policy approvers can delete access requests" });
}
await additionalPrivilegeDAL.deleteById(accessApprovalRequest.privilegeId);
if (accessApprovalRequest.projectUserPrivilegeId) {
await additionalPrivilegeDAL.deleteById(accessApprovalRequest.projectUserPrivilegeId);
} else if (accessApprovalRequest.groupProjectUserPrivilegeId) {
await groupAdditionalPrivilegeDAL.deleteById(accessApprovalRequest.groupProjectUserPrivilegeId);
}
return { request: accessApprovalRequest };
};
@ -368,7 +378,8 @@ export const accessApprovalRequestServiceFactory = ({
throw new BadRequestError({ message: "Temporary range is required for temporary access" });
}
let privilegeId: string | null = null;
let projectUserPrivilegeId: string | null = null;
let groupProjectMembershipId: string | null = null;
if (!accessApprovalRequest.groupMembershipId && !accessApprovalRequest.projectMembershipId) {
throw new BadRequestError({ message: "Project membership or group membership is required" });
@ -376,57 +387,83 @@ export const accessApprovalRequestServiceFactory = ({
// Permanent access
if (!accessApprovalRequest.isTemporary && !accessApprovalRequest.temporaryRange) {
let groupUserMembershipId: string | null = null;
if (accessApprovalRequest.groupMembershipId) {
const groupProjectMembership = await groupProjectDAL.findOne({
id: accessApprovalRequest.groupMembershipId
});
if (!groupProjectMembership) throw new BadRequestError({ message: "Group not found" });
// Group user privilege
const groupProjectUserAdditionalPrivilege = await groupAdditionalPrivilegeDAL.create(
{
groupProjectMembershipId: accessApprovalRequest.groupMembershipId,
requestedByUserId: accessApprovalRequest.requestedByUserId,
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
permissions: JSON.stringify(accessApprovalRequest.permissions)
},
tx
);
const userGroupMembershipId = await userGroupMembershipDAL.findOne({
groupId: groupProjectMembership.groupId
});
if (!userGroupMembershipId) throw new BadRequestError({ message: "User group membership not found" });
groupUserMembershipId = userGroupMembershipId.id;
groupProjectMembershipId = groupProjectUserAdditionalPrivilege.id;
} else {
// Project user privilege
const privilege = await additionalPrivilegeDAL.create(
{
projectMembershipId: accessApprovalRequest.projectMembershipId!,
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
permissions: JSON.stringify(accessApprovalRequest.permissions)
},
tx
);
projectUserPrivilegeId = privilege.id;
}
const privilege = await additionalPrivilegeDAL.create(
{
groupMembershipId: groupUserMembershipId || null,
projectMembershipId: accessApprovalRequest.projectMembershipId || null,
groupProjectId: accessApprovalRequest.groupMembershipId ? accessApprovalRequest.projectId : null,
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
permissions: JSON.stringify(accessApprovalRequest.permissions)
},
tx
);
privilegeId = privilege.id;
} else {
// Temporary access
const relativeTempAllocatedTimeInMs = ms(accessApprovalRequest.temporaryRange!);
const startTime = new Date();
const privilege = await additionalPrivilegeDAL.create(
{
projectMembershipId: accessApprovalRequest.projectMembershipId || null,
groupMembershipId: accessApprovalRequest.groupMembershipId || null,
groupProjectId: accessApprovalRequest.groupMembershipId ? accessApprovalRequest.projectId : null,
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
permissions: JSON.stringify(accessApprovalRequest.permissions),
isTemporary: true,
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: accessApprovalRequest.temporaryRange!,
temporaryAccessStartTime: startTime,
temporaryAccessEndTime: new Date(new Date(startTime).getTime() + relativeTempAllocatedTimeInMs)
},
tx
);
privilegeId = privilege.id;
if (accessApprovalRequest.groupMembershipId) {
// Group user privilege
const groupProjectUserAdditionalPrivilege = await groupAdditionalPrivilegeDAL.create(
{
groupProjectMembershipId: accessApprovalRequest.groupMembershipId,
requestedByUserId: accessApprovalRequest.requestedByUserId,
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
permissions: JSON.stringify(accessApprovalRequest.permissions),
isTemporary: true,
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: accessApprovalRequest.temporaryRange!,
temporaryAccessStartTime: startTime,
temporaryAccessEndTime: new Date(new Date(startTime).getTime() + relativeTempAllocatedTimeInMs)
},
tx
);
groupProjectMembershipId = groupProjectUserAdditionalPrivilege.id;
} else {
const privilege = await additionalPrivilegeDAL.create(
{
projectMembershipId: accessApprovalRequest.projectMembershipId!,
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
permissions: JSON.stringify(accessApprovalRequest.permissions),
isTemporary: true,
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: accessApprovalRequest.temporaryRange!,
temporaryAccessStartTime: startTime,
temporaryAccessEndTime: new Date(new Date(startTime).getTime() + relativeTempAllocatedTimeInMs)
},
tx
);
projectUserPrivilegeId = privilege.id;
}
}
await accessApprovalRequestDAL.updateById(accessApprovalRequest.id, { privilegeId }, tx);
if (projectUserPrivilegeId) {
await accessApprovalRequestDAL.updateById(accessApprovalRequest.id, { projectUserPrivilegeId }, tx);
} else if (groupProjectMembershipId) {
await accessApprovalRequestDAL.updateById(
accessApprovalRequest.id,
{ groupProjectUserPrivilegeId: groupProjectMembershipId },
tx
);
} else {
throw new BadRequestError({ message: "No privilege was created" });
}
}
return newReview;

@ -0,0 +1,12 @@
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { ormify } from "@app/lib/knex";
export type TGroupProjectUserAdditionalPrivilegeDALFactory = ReturnType<
typeof groupProjectUserAdditionalPrivilegeDALFactory
>;
export const groupProjectUserAdditionalPrivilegeDALFactory = (db: TDbClient) => {
const orm = ormify(db, TableName.GroupProjectUserAdditionalPrivilege);
return orm;
};

@ -59,8 +59,6 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
if (!dto.isTemporary) {
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.create({
projectMembershipId,
groupMembershipId: null,
groupProjectId: null,
slug,
permissions: customPermission
});
@ -70,8 +68,6 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
const relativeTempAllocatedTimeInMs = ms(dto.temporaryRange);
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.create({
projectMembershipId,
groupMembershipId: null,
groupProjectId: null,
slug,
permissions: customPermission,
isTemporary: true,

@ -22,6 +22,7 @@ import { dynamicSecretLeaseServiceFactory } from "@app/ee/services/dynamic-secre
import { groupDALFactory } from "@app/ee/services/group/group-dal";
import { groupServiceFactory } from "@app/ee/services/group/group-service";
import { userGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
import { groupProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/group-project-user-additional-privilege/group-project-user-additional-privilege-dal";
import { identityProjectAdditionalPrivilegeDALFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-dal";
import { identityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service";
import { ldapConfigDALFactory } from "@app/ee/services/ldap-config/ldap-config-dal";
@ -217,6 +218,8 @@ export const registerRoutes = async (
const accessApprovalPolicyApproverDAL = accessApprovalPolicyApproverDALFactory(db);
const accessApprovalRequestReviewerDAL = accessApprovalRequestReviewerDALFactory(db);
const groupProjectUserAdditionalPrivilegeDAL = groupProjectUserAdditionalPrivilegeDALFactory(db);
const sapApproverDAL = secretApprovalPolicyApproverDALFactory(db);
const secretApprovalPolicyDAL = secretApprovalPolicyDALFactory(db);
const secretApprovalRequestDAL = secretApprovalRequestDALFactory(db);
@ -618,11 +621,10 @@ export const registerRoutes = async (
permissionService,
accessApprovalRequestReviewerDAL,
additionalPrivilegeDAL: projectUserAdditionalPrivilegeDAL,
groupAdditionalPrivilegeDAL: groupProjectUserAdditionalPrivilegeDAL,
projectMembershipDAL,
accessApprovalPolicyDAL,
accessApprovalRequestDAL,
groupProjectDAL,
userGroupMembershipDAL,
projectEnvDAL,
userDAL,
smtpService,