From 2756dff735a398aa8959847868153e29b4bbcbbd Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com> Date: Tue, 17 Oct 2023 04:09:22 +0400 Subject: [PATCH] fix: Adds mandatory credentiaId in Destination Calendar API endpoint POST (#11880) --- .../lib/validations/destination-calendar.ts | 3 ++ .../pages/api/destination-calendars/_post.ts | 37 +++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/apps/api/lib/validations/destination-calendar.ts b/apps/api/lib/validations/destination-calendar.ts index 15d1d8672c..371ae5ad51 100644 --- a/apps/api/lib/validations/destination-calendar.ts +++ b/apps/api/lib/validations/destination-calendar.ts @@ -3,6 +3,7 @@ import { z } from "zod"; import { _DestinationCalendarModel as DestinationCalendar } from "@calcom/prisma/zod"; export const schemaDestinationCalendarBaseBodyParams = DestinationCalendar.pick({ + credentialId: true, integration: true, externalId: true, eventTypeId: true, @@ -14,6 +15,7 @@ const schemaDestinationCalendarCreateParams = z .object({ integration: z.string(), externalId: z.string(), + credentialId: z.number(), eventTypeId: z.number().optional(), bookingId: z.number().optional(), userId: z.number().optional(), @@ -45,4 +47,5 @@ export const schemaDestinationCalendarReadPublic = DestinationCalendar.pick({ eventTypeId: true, bookingId: true, userId: true, + credentialId: true, }); diff --git a/apps/api/pages/api/destination-calendars/_post.ts b/apps/api/pages/api/destination-calendars/_post.ts index a6160fc6bc..beccedc30a 100644 --- a/apps/api/pages/api/destination-calendars/_post.ts +++ b/apps/api/pages/api/destination-calendars/_post.ts @@ -30,6 +30,7 @@ import { * required: * - integration * - externalId + * - credentialId * properties: * integration: * type: string @@ -37,12 +38,18 @@ import { * externalId: * type: string * description: 'The external ID of the integration' + * credentialId: + * type: integer + * description: 'The credential ID it is associated with' * eventTypeId: * type: integer * description: 'The ID of the eventType it is associated with' * bookingId: * type: integer * description: 'The booking ID it is associated with' + * userId: + * type: integer + * description: 'The user it is associated with' * tags: * - destination-calendars * responses: @@ -55,17 +62,33 @@ import { */ async function postHandler(req: NextApiRequest) { const { userId, isAdmin, prisma, body } = req; - const parsedBody = schemaDestinationCalendarCreateBodyParams.parse(body); - await checkPermissions(req, userId); - if (!parsedBody.eventTypeId) { - parsedBody.userId = userId; - } + const assignedUserId = isAdmin ? parsedBody.userId || userId : userId; - if (isAdmin) { - parsedBody.userId = parsedBody.userId || userId; + /* Check if credentialId data matches the ownership and integration passed in */ + const credential = await prisma.credential.findFirst({ + where: { type: parsedBody.integration, userId: assignedUserId }, + select: { id: true, type: true, userId: true }, + }); + + if (!credential) + throw new HttpError({ + statusCode: 400, + message: "Bad request, credential id invalid", + }); + + if (parsedBody.eventTypeId) { + const eventType = await prisma.eventType.findFirst({ + where: { id: parsedBody.eventTypeId, userId: parsedBody.userId }, + }); + if (!eventType) + throw new HttpError({ + statusCode: 400, + message: "Bad request, eventTypeId invalid", + }); + parsedBody.userId = undefined; } const destination_calendar = await prisma.destinationCalendar.create({ data: { ...parsedBody } });