From 02743f3e1c44cece5eff80de9e801c9371c9e162 Mon Sep 17 00:00:00 2001 From: tomerqodo Date: Sun, 25 Jan 2026 12:03:42 +0200 Subject: [PATCH 1/2] Apply PR changes (squashed due to cherry-pick conflicts) --- .../controllers/bookings.controller.ts | 38 ++++---- .../e2e/booking-access-auth.e2e-spec.ts | 90 +++++++++---------- .../outputs/get-booking-recordings.output.ts | 8 -- .../outputs/get-booking-transcripts.output.ts | 7 -- 4 files changed, 61 insertions(+), 82 deletions(-) diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts index 1b332ae1138080..6f14185ca14c88 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts @@ -212,10 +212,9 @@ export class BookingsController_2024_08_13 { } @Get("/:bookingUid/recordings") - // @Pbac(["booking.readRecordings"]) + @Pbac(["booking.readRecordings"]) @Permissions([BOOKING_READ]) - @UseGuards(BookingUidGuard) - // @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) + @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) @ApiHeader(API_KEY_OR_ACCESS_TOKEN_HEADER) @ApiOperation({ summary: "Get all the recordings for the booking", @@ -230,16 +229,13 @@ export class BookingsController_2024_08_13 { return { status: SUCCESS_STATUS, data: recordings, - message: - "This endpoint will require authentication in a future release. Please update your integration to include valid credentials. See https://cal.com/docs/api-reference/v2/introduction#authentication for details.", }; } @Get("/:bookingUid/transcripts") - // @Pbac(["booking.readRecordings"]) + @Pbac(["booking.readRecordings"]) @Permissions([BOOKING_READ]) - @UseGuards(BookingUidGuard) - // @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) + @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) @ApiHeader(API_KEY_OR_ACCESS_TOKEN_HEADER) @ApiOperation({ summary: "Get Cal Video real time transcript download links for the booking", @@ -258,8 +254,6 @@ export class BookingsController_2024_08_13 { return { status: SUCCESS_STATUS, data: transcripts ?? [], - message: - "This endpoint will require authentication in a future release. Please update your integration to include valid credentials. See https://cal.com/docs/api-reference/v2/introduction#authentication for details.", }; } @@ -397,18 +391,18 @@ export class BookingsController_2024_08_13 { Please make sure to pass in the cal-api-version header value as mentioned in the Headers section. Not passing the correct value will default to an older version of this endpoint. `, }) - async markNoShow( - @Param("bookingUid") bookingUid: string, - @Body() body: MarkAbsentBookingInput_2024_08_13, - @GetUser() user: ApiAuthGuardUser - ): Promise { - const booking = await this.bookingsService.markAbsent(bookingUid, user.id, body, user.uuid); - - return { - status: SUCCESS_STATUS, - data: booking, - }; - } + async markNoShow( + @Param("bookingUid") bookingUid: string, + @Body() body: MarkAbsentBookingInput_2024_08_13, + @GetUser() user: ApiAuthGuardUser + ): Promise { + const booking = await this.bookingsService.markAbsent(bookingUid, user.id, body, user.uuid); + + return { + status: SUCCESS_STATUS, + data: booking, + }; + } @Post("/:bookingUid/reassign") @HttpCode(HttpStatus.OK) diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-access-auth.e2e-spec.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-access-auth.e2e-spec.ts index 68f9adea8221e0..7d9313f9c00820 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-access-auth.e2e-spec.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/booking-access-auth.e2e-spec.ts @@ -185,51 +185,51 @@ describe("Bookings Endpoints 2024-08-13", () => { }); }); - // describe("GET /v2/bookings/:bookingUid/recordings - Authorization", () => { - // it("should allow booking organizer to access recordings", async () => { - // const calVideoService = app.get(CalVideoService); - // jest.spyOn(calVideoService, "getRecordings").mockResolvedValue([]); - - // const response = await request(app.getHttpServer()) - // .get(`/v2/bookings/${testBooking.uid}/recordings`) - // .set("Authorization", `Bearer ${ownerApiKey}`) - // .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) - // .expect(200); - - // expect(response.body.status).toEqual(SUCCESS_STATUS); - // }); - - // it("should return 403 when unauthorized user tries to access recordings", async () => { - // await request(app.getHttpServer()) - // .get(`/v2/bookings/${testBooking.uid}/recordings`) - // .set("Authorization", `Bearer ${unauthorizedApiKey}`) - // .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) - // .expect(403); - // }); - // }); - - // describe("GET /v2/bookings/:bookingUid/transcripts - Authorization", () => { - // it("should allow booking organizer to access transcripts", async () => { - // const calVideoService = app.get(CalVideoService); - // jest.spyOn(calVideoService, "getTranscripts").mockResolvedValue([]); - - // const response = await request(app.getHttpServer()) - // .get(`/v2/bookings/${testBooking.uid}/transcripts`) - // .set("Authorization", `Bearer ${ownerApiKey}`) - // .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) - // .expect(200); - - // expect(response.body.status).toEqual(SUCCESS_STATUS); - // }); - - // it("should return 403 when unauthorized user tries to access transcripts", async () => { - // await request(app.getHttpServer()) - // .get(`/v2/bookings/${testBooking.uid}/transcripts`) - // .set("Authorization", `Bearer ${unauthorizedApiKey}`) - // .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) - // .expect(403); - // }); - // }); + describe("GET /v2/bookings/:bookingUid/recordings - Authorization", () => { + it("should allow booking organizer to access recordings", async () => { + const calVideoService = app.get(CalVideoService); + jest.spyOn(calVideoService, "getRecordings").mockResolvedValue([]); + + const response = await request(app.getHttpServer()) + .get(`/v2/bookings/${testBooking.uid}/recordings`) + .set("Authorization", `Bearer ${ownerApiKey}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .expect(200); + + expect(response.body.status).toEqual(SUCCESS_STATUS); + }); + + it("should return 403 when unauthorized user tries to access recordings", async () => { + await request(app.getHttpServer()) + .get(`/v2/bookings/${testBooking.uid}/recordings`) + .set("Authorization", `Bearer ${unauthorizedApiKey}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .expect(403); + }); + }); + + describe("GET /v2/bookings/:bookingUid/transcripts - Authorization", () => { + it("should allow booking organizer to access transcripts", async () => { + const calVideoService = app.get(CalVideoService); + jest.spyOn(calVideoService, "getTranscripts").mockResolvedValue([]); + + const response = await request(app.getHttpServer()) + .get(`/v2/bookings/${testBooking.uid}/transcripts`) + .set("Authorization", `Bearer ${ownerApiKey}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .expect(200); + + expect(response.body.status).toEqual(SUCCESS_STATUS); + }); + + it("should return 403 when unauthorized user tries to access transcripts", async () => { + await request(app.getHttpServer()) + .get(`/v2/bookings/${testBooking.uid}/transcripts`) + .set("Authorization", `Bearer ${unauthorizedApiKey}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .expect(403); + }); + }); afterAll(async () => { await bookingsRepositoryFixture.deleteById(testBooking.id); diff --git a/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts b/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts index 4b8cafbc05816f..a56128d0764ef7 100644 --- a/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts +++ b/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts @@ -55,12 +55,4 @@ export class GetBookingRecordingsOutput { @ValidateNested({ each: true }) @Type(() => RecordingItem) data!: RecordingItem[]; - - @ApiProperty({ - example: "This endpoint will require authentication in a future release.", - required: false, - }) - @IsString() - @IsOptional() - message?: string; } diff --git a/packages/platform/types/bookings/2024-08-13/outputs/get-booking-transcripts.output.ts b/packages/platform/types/bookings/2024-08-13/outputs/get-booking-transcripts.output.ts index d9322cba67ce36..21ceb5cfdafec9 100644 --- a/packages/platform/types/bookings/2024-08-13/outputs/get-booking-transcripts.output.ts +++ b/packages/platform/types/bookings/2024-08-13/outputs/get-booking-transcripts.output.ts @@ -14,11 +14,4 @@ export class GetBookingTranscriptsOutput { @IsArray() @IsString({ each: true }) data!: string[]; - - @ApiProperty({ - example: "This endpoint will require authentication in a future release.", - required: false, - }) - @IsString() - message?: string; } From eb21d268d50f181cf116ecad39bf79d0918da1e2 Mon Sep 17 00:00:00 2001 From: tomerqodo Date: Sun, 25 Jan 2026 12:03:42 +0200 Subject: [PATCH 2/2] update pr --- .../bookings/2024-08-13/controllers/bookings.controller.ts | 6 +++--- .../2024-08-13/outputs/get-booking-recordings.output.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts index 6f14185ca14c88..dd03319ed0cc17 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts @@ -213,7 +213,7 @@ export class BookingsController_2024_08_13 { @Get("/:bookingUid/recordings") @Pbac(["booking.readRecordings"]) - @Permissions([BOOKING_READ]) + @Permissions([BOOKING_WRITE]) @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) @ApiHeader(API_KEY_OR_ACCESS_TOKEN_HEADER) @ApiOperation({ @@ -224,7 +224,7 @@ export class BookingsController_2024_08_13 { `, }) async getBookingRecordings(@Param("bookingUid") bookingUid: string): Promise { - const recordings = await this.calVideoService.getRecordings(bookingUid); + const recordings = this.calVideoService.getRecordings(bookingUid); return { status: SUCCESS_STATUS, @@ -235,7 +235,7 @@ export class BookingsController_2024_08_13 { @Get("/:bookingUid/transcripts") @Pbac(["booking.readRecordings"]) @Permissions([BOOKING_READ]) - @UseGuards(ApiAuthGuard, BookingUidGuard, BookingPbacGuard) + @UseGuards(BookingPbacGuard, ApiAuthGuard, BookingUidGuard) @ApiHeader(API_KEY_OR_ACCESS_TOKEN_HEADER) @ApiOperation({ summary: "Get Cal Video real time transcript download links for the booking", diff --git a/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts b/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts index a56128d0764ef7..ae2fd83f29c0e0 100644 --- a/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts +++ b/packages/platform/types/bookings/2024-08-13/outputs/get-booking-recordings.output.ts @@ -3,6 +3,7 @@ import { Type } from "class-transformer"; import { IsEnum, ValidateNested, IsNumber, IsString, IsOptional, IsUrl } from "class-validator"; import { SUCCESS_STATUS, ERROR_STATUS } from "@calcom/platform-constants"; +import type { BookingRepository } from "@calcom/features/bookings/lib/BookingRepository"; export class RecordingItem { @ApiProperty({ example: "1234567890" })