diff --git a/apps/web/components/booking/BookingListItem.tsx b/apps/web/components/booking/BookingListItem.tsx
index ae0d19f9f2..2c9efd2c02 100644
--- a/apps/web/components/booking/BookingListItem.tsx
+++ b/apps/web/components/booking/BookingListItem.tsx
@@ -542,7 +542,9 @@ function BookingListItem(booking: BookingItemProps) {
{isUpcoming && !isCancelled ? (
<>
- {isPending && userId === booking.user?.id && }
+ {isPending && (userId === booking.user?.id || booking.isUserTeamAdminOrOwner) && (
+
+ )}
{isConfirmed && }
{isRejected && {t("rejected")} }
>
diff --git a/packages/trpc/server/routers/viewer/bookings/_router.tsx b/packages/trpc/server/routers/viewer/bookings/_router.tsx
index bece7c9c2b..7cb7b08682 100644
--- a/packages/trpc/server/routers/viewer/bookings/_router.tsx
+++ b/packages/trpc/server/routers/viewer/bookings/_router.tsx
@@ -75,7 +75,7 @@ export const bookingsRouter = router({
});
}),
- confirm: bookingsProcedure.input(ZConfirmInputSchema).mutation(async ({ input, ctx }) => {
+ confirm: authedProcedure.input(ZConfirmInputSchema).mutation(async ({ input, ctx }) => {
if (!UNSTABLE_HANDLER_CACHE.confirm) {
UNSTABLE_HANDLER_CACHE.confirm = await import("./confirm.handler").then((mod) => mod.confirmHandler);
}
diff --git a/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts b/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts
index a079d5dc01..44e43a9278 100644
--- a/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts
+++ b/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts
@@ -25,12 +25,11 @@ import { TRPCError } from "@trpc/server";
import type { TrpcSessionUser } from "../../../trpc";
import type { TConfirmInputSchema } from "./confirm.schema";
-import type { BookingsProcedureContext } from "./util";
type ConfirmOptions = {
ctx: {
user: NonNullable;
- } & BookingsProcedureContext;
+ };
input: TConfirmInputSchema;
};
@@ -75,6 +74,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
team: {
select: {
parentId: true,
+ members: true,
},
},
workflows: {
@@ -122,7 +122,11 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
},
});
- if (eventType && !eventType.users.find((user) => booking.userId === user.id)) {
+ const membership = booking.eventType?.team?.members.find((membership) => membership.userId === user.id);
+ const isTeamAdminOrOwner =
+ membership?.role === MembershipRole.OWNER || membership?.role === MembershipRole.ADMIN;
+
+ if (eventType && !eventType.users.find((user) => booking.userId === user.id) && !isTeamAdminOrOwner) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "UNAUTHORIZED" });
}
}
diff --git a/packages/trpc/server/routers/viewer/bookings/get.handler.ts b/packages/trpc/server/routers/viewer/bookings/get.handler.ts
index b479d6b1ca..821b09637d 100644
--- a/packages/trpc/server/routers/viewer/bookings/get.handler.ts
+++ b/packages/trpc/server/routers/viewer/bookings/get.handler.ts
@@ -3,7 +3,7 @@ import getAllUserBookings from "@calcom/lib/bookings/getAllUserBookings";
import type { PrismaClient } from "@calcom/prisma";
import { bookingMinimalSelect } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
-import type { BookingStatus } from "@calcom/prisma/enums";
+import { MembershipRole, type BookingStatus } from "@calcom/prisma/enums";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import type { TrpcSessionUser } from "../../../trpc";
@@ -183,6 +183,7 @@ export async function getBookings({
select: {
id: true,
name: true,
+ members: true,
},
},
},
@@ -396,6 +397,11 @@ export async function getBookings({
if (booking.seatsReferences.length && !booking.eventType?.seatsShowAttendees) {
booking.attendees = booking.attendees.filter((attendee) => attendee.email === user.email);
}
+
+ const membership = booking.eventType?.team?.members.find((membership) => membership.userId === user.id);
+ const isUserTeamAdminOrOwner =
+ membership?.role === MembershipRole.OWNER || membership?.role === MembershipRole.ADMIN;
+
return {
...booking,
eventType: {
@@ -407,6 +413,7 @@ export async function getBookings({
},
startTime: booking.startTime.toISOString(),
endTime: booking.endTime.toISOString(),
+ isUserTeamAdminOrOwner,
};
});
return { bookings, recurringInfo };
|