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
This commit is contained in:
@@ -375,9 +375,6 @@ export class ProfileRepository {
|
||||
lockEventTypeCreationForUsers: true,
|
||||
},
|
||||
},
|
||||
members: {
|
||||
select: membershipSelect,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -102,21 +102,16 @@ export async function getUserFromSession(ctx: TRPCContextInner, session: Maybe<S
|
||||
// This helps to prevent reaching the 4MB payload limit by avoiding base64 and instead passing the avatar url
|
||||
|
||||
const locale = user?.locale ?? ctx.locale;
|
||||
|
||||
const isOrgAdmin = !!user.profile?.organization?.members.filter(
|
||||
(member) => (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,
|
||||
|
||||
Reference in New Issue
Block a user