From f4d09ece43311c8cb3bce6d5d2f2d450572a2db4 Mon Sep 17 00:00:00 2001 From: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Date: Mon, 29 Sep 2025 12:06:55 +0100 Subject: [PATCH] chore: (PBAC) readonly eventTypes (#24131) * Chore(PBAC): readonly eventTypes * Set readonly value --- .../eventtypes/lib/getEventTypeById.ts | 2 +- .../eventtypes/lib/getEventTypesByViewer.ts | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/features/eventtypes/lib/getEventTypeById.ts b/packages/features/eventtypes/lib/getEventTypeById.ts index c9b3fae9b6..4c92c8b7fb 100644 --- a/packages/features/eventtypes/lib/getEventTypeById.ts +++ b/packages/features/eventtypes/lib/getEventTypeById.ts @@ -1,4 +1,5 @@ //import "server-only"; +import type { LocationObject } from "@calcom/app-store/locations"; import { getLocationGroupedOptions } from "@calcom/app-store/server"; import { getEventTypeAppData } from "@calcom/app-store/utils"; import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; @@ -10,7 +11,6 @@ import { parseBookingLimit } from "@calcom/lib/intervalLimits/isBookingLimits"; import { parseDurationLimit } from "@calcom/lib/intervalLimits/isDurationLimits"; import { parseEventTypeColor } from "@calcom/lib/isEventTypeColor"; import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent"; -import type { LocationObject } from "@calcom/app-store/locations"; import { getTranslation } from "@calcom/lib/server/i18n"; import { EventTypeRepository } from "@calcom/lib/server/repository/eventTypeRepository"; import { UserRepository } from "@calcom/lib/server/repository/user"; diff --git a/packages/features/eventtypes/lib/getEventTypesByViewer.ts b/packages/features/eventtypes/lib/getEventTypesByViewer.ts index b0914ed269..40a592ae0f 100644 --- a/packages/features/eventtypes/lib/getEventTypesByViewer.ts +++ b/packages/features/eventtypes/lib/getEventTypesByViewer.ts @@ -2,6 +2,7 @@ import { orderBy } from "lodash"; import { hasFilter } from "@calcom/features/filters/lib/hasFilter"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client"; @@ -51,6 +52,15 @@ export const getEventTypesByViewer = async (user: User, filters?: Filters, forRo if (isFilterSet && filters?.upIds && !isUpIdInFilter) { shouldListUserEvents = true; } + + // Get teams where user has eventType.read permission for PBAC readonly check + const permissionCheckService = new PermissionCheckService(); + const teamsWithEventTypeReadPermission = await permissionCheckService.getTeamIdsWithPermission({ + userId: user.id, + permission: "eventType.read", + fallbackRoles: [MembershipRole.MEMBER, MembershipRole.ADMIN, MembershipRole.OWNER], + }); + const eventTypeRepo = new EventTypeRepository(prisma); const [profileMemberships, profileEventTypes] = await Promise.all([ MembershipRepository.findAllByUpIdIncludeTeamWithMembersAndEventTypes( @@ -281,13 +291,7 @@ export const getEventTypesByViewer = async (user: User, filters?: Filters, forRo }, metadata: { membershipCount: team.members.length, - readOnly: - membership.role === - (team.parentId - ? orgMembership && compareMembership(orgMembership, membership.role) - ? orgMembership - : MembershipRole.MEMBER - : MembershipRole.MEMBER), + readOnly: !teamsWithEventTypeReadPermission.includes(team.id), }, eventTypes: eventTypes .filter(filterByTeamIds)