diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index 651faede4..f671c76f7 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -173,7 +173,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const workspaces = await server.services.project.getProjects({ includeRoles: req.query.includeRoles, diff --git a/backend/src/services/project/project-dal.ts b/backend/src/services/project/project-dal.ts index bdcee1e61..54bef02d1 100644 --- a/backend/src/services/project/project-dal.ts +++ b/backend/src/services/project/project-dal.ts @@ -22,6 +22,56 @@ export type TProjectDALFactory = ReturnType; export const projectDALFactory = (db: TDbClient) => { const projectOrm = ormify(db, TableName.Project); + const findIdentityProjects = async (identityId: string, orgId: string, projectType: ProjectType | "all") => { + try { + const workspaces = await db(TableName.IdentityProjectMembership) + .where({ identityId }) + .join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`) + .where(`${TableName.Project}.orgId`, orgId) + .andWhere((qb) => { + if (projectType !== "all") { + void qb.where(`${TableName.Project}.type`, projectType); + } + }) + .leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`) + .select( + selectAllTableCols(TableName.Project), + db.ref("id").withSchema(TableName.Project).as("_id"), + db.ref("id").withSchema(TableName.Environment).as("envId"), + db.ref("slug").withSchema(TableName.Environment).as("envSlug"), + db.ref("name").withSchema(TableName.Environment).as("envName") + ) + .orderBy([ + { column: `${TableName.Project}.name`, order: "asc" }, + { column: `${TableName.Environment}.position`, order: "asc" } + ]); + + const nestedWorkspaces = sqlNestRelationships({ + data: workspaces, + key: "id", + parentMapper: ({ _id, ...el }) => ({ _id, ...ProjectsSchema.parse(el) }), + childrenMapper: [ + { + key: "envId", + label: "environments" as const, + mapper: ({ envId: id, envSlug: slug, envName: name }) => ({ + id, + slug, + name + }) + } + ] + }); + + return nestedWorkspaces.map((workspace) => ({ + ...workspace, + organization: workspace.orgId + })); + } catch (error) { + throw new DatabaseError({ error, name: "Find identity projects" }); + } + }; + const findUserProjects = async (userId: string, orgId: string, projectType: ProjectType | "all") => { try { const workspaces = await db @@ -443,6 +493,7 @@ export const projectDALFactory = (db: TDbClient) => { return { ...projectOrm, findUserProjects, + findIdentityProjects, setProjectUpgradeStatus, findAllProjectsByIdentity, findProjectGhostUser, diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts index 46f609777..6b132f654 100644 --- a/backend/src/services/project/project-service.ts +++ b/backend/src/services/project/project-service.ts @@ -573,12 +573,16 @@ export const projectServiceFactory = ({ const getProjects = async ({ actorId, + actor, includeRoles, actorAuthMethod, actorOrgId, type = ProjectType.SecretManager }: TListProjectsDTO) => { - const workspaces = await projectDAL.findUserProjects(actorId, actorOrgId, type); + const workspaces = + actor === ActorType.IDENTITY + ? await projectDAL.findIdentityProjects(actorId, actorOrgId, type) + : await projectDAL.findUserProjects(actorId, actorOrgId, type); if (includeRoles) { const { permission } = await permissionService.getUserOrgPermission(