From f4f4afad39cd9fc6247f693fb8dc41adfa79d6b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Fri, 15 Nov 2024 19:00:18 -0700 Subject: [PATCH] perf: optimize team admin check queries (#17681) ## What does this PR do? Optimizes team and organization admin checks by: - Removing unnecessary member data fetching in profile repository - Simplifying team admin verification query to directly check membership - Refactoring organization admin check to use the optimized team verification method ## Mandatory Tasks - [x] I have self-reviewed the code - [x] I have updated the developer docs in /docs - [ ] I confirm automated tests are in place ## How should this be tested? 1. Log in as a team admin/owner 2. Verify team admin privileges still work correctly 3. Log in as an organization admin 4. Confirm organization admin permissions are maintained 5. Check that admin-only features remain accessible Expected behavior: - Team admins/owners should retain all their existing permissions - Organization admins should maintain their administrative capabilities - No degradation in admin functionality while improving query performance ## Checklist - I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md) - My code doesn't follow the style guidelines of this project - I haven't commented my code, particularly in hard-to-understand areas - I haven't checked if my changes generate no new warnings --- packages/lib/server/repository/profile.ts | 3 --- packages/lib/server/repository/user.ts | 19 ++++++------------- .../server/middlewares/sessionMiddleware.ts | 13 ++++--------- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/packages/lib/server/repository/profile.ts b/packages/lib/server/repository/profile.ts index abf248930b..e4d7f3cd09 100644 --- a/packages/lib/server/repository/profile.ts +++ b/packages/lib/server/repository/profile.ts @@ -375,9 +375,6 @@ export class ProfileRepository { lockEventTypeCreationForUsers: true, }, }, - members: { - select: membershipSelect, - }, }, }, }, diff --git a/packages/lib/server/repository/user.ts b/packages/lib/server/repository/user.ts index 2023176772..4ef71a4799 100644 --- a/packages/lib/server/repository/user.ts +++ b/packages/lib/server/repository/user.ts @@ -664,25 +664,18 @@ export class UserRepository { return !!teams.length; } static async isAdminOrOwnerOfTeam({ userId, teamId }: { userId: number; teamId: number }) { - const team = await prisma.team.findUnique({ + const isAdminOrOwnerOfTeam = await prisma.membership.findFirst({ where: { - id: teamId, - AND: [ - { - members: { - some: { - userId, - role: { in: [MembershipRole.ADMIN, MembershipRole.OWNER] }, - }, - }, - }, - ], + userId, + teamId, + role: { in: [MembershipRole.ADMIN, MembershipRole.OWNER] }, + accepted: true, }, select: { id: true, }, }); - return !!team; + return !!isAdminOrOwnerOfTeam; } static async getTimeZoneAndDefaultScheduleId({ userId }: { userId: number }) { return await prisma.user.findUnique({ diff --git a/packages/trpc/server/middlewares/sessionMiddleware.ts b/packages/trpc/server/middlewares/sessionMiddleware.ts index 443f16b9a8..ef5a5b5479 100644 --- a/packages/trpc/server/middlewares/sessionMiddleware.ts +++ b/packages/trpc/server/middlewares/sessionMiddleware.ts @@ -102,21 +102,16 @@ export async function getUserFromSession(ctx: TRPCContextInner, session: Maybe (member.role === "ADMIN" || member.role === "OWNER") && member.userId === user.id - ).length; + const isOrgAdmin = await UserRepository.isAdminOrOwnerOfTeam({ + userId: user.id, + teamId: user.profile.organization?.id ?? -1, + }); if (isOrgAdmin) { logger.debug("User is an org admin", safeStringify({ userId: user.id })); } else { logger.debug("User is not an org admin", safeStringify({ userId: user.id })); } - // Want to reduce the amount of data being sent - if (isOrgAdmin && user.profile?.organization?.members) { - user.profile.organization.members = []; - } - const organization = { ...user.profile?.organization, id: user.profile?.organization?.id ?? null,