diff --git a/lib/helpers/verifyApiKey.ts b/lib/helpers/verifyApiKey.ts index 81bbb8db07..38fa6b44c3 100644 --- a/lib/helpers/verifyApiKey.ts +++ b/lib/helpers/verifyApiKey.ts @@ -9,9 +9,9 @@ import prisma from "@calcom/prisma"; declare module "next" { export interface NextApiRequest extends IncomingMessage { userId: number; - query: { - apiKey: string; - }; + method: string; + query: { [key: string]: string | string[] }; + body: any; } } diff --git a/lib/types.ts b/lib/types.ts index a5c7d8ad21..f61e5d7f1c 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -125,7 +125,7 @@ export type EventTypeCustomInputsResponse = BaseResponse & { event_type_custom_inputs?: Partial[]; }; // From rrule https://jakubroztocil.github.io/rrule freq -enum Frequency { +export enum Frequency { "YEARLY", "MONTHLY", "WEEKLY", @@ -150,6 +150,7 @@ interface EventTypeExtended extends Omit; diff --git a/lib/validations/event-type.ts b/lib/validations/event-type.ts index aee6002089..e3a6d83228 100644 --- a/lib/validations/event-type.ts +++ b/lib/validations/event-type.ts @@ -1,7 +1,11 @@ import { z } from "zod"; +import { AppStoreLocationType, DefaultLocationType } from "@calcom/app-store/locations"; import { _EventTypeModel as EventType } from "@calcom/prisma/zod"; +import { Frequency } from "@lib/types"; +import { timeZone } from "@lib/validations/shared/timeZone"; + import { jsonSchema } from "./shared/jsonSchema"; export const schemaEventTypeBaseBodyParams = EventType.pick({ @@ -87,4 +91,26 @@ export const schemaEventTypeReadPublic = EventType.pick({ description: true, locations: true, metadata: true, -}); +}).merge( + z.object({ + // { dtstart?: Date | undefined; interval?: number | undefined; count?: number | undefined; freq?: Frequency | undefined; until?: Date | undefined; tzid?: string | undefined; } | undefined' + // recurringEvent: jsonSchema.nullable(), + recurringEvent: z.object({ + dtstart: z.date().optional(), + interval: z.number().int().optional(), + count: z.number().int().optional(), + freq: z.nativeEnum(Frequency).optional(), + until: z.date().optional(), + tzid: timeZone, + }), + locations: z.array( + z.object({ + link: z.string().optional(), + address: z.string().optional(), + hostPhoneNumber: z.string().optional(), + type: z.nativeEnum(DefaultLocationType).or(z.nativeEnum(AppStoreLocationType)), + }) + ), + metadata: jsonSchema.nullable(), + }) +); diff --git a/lib/validations/webhook.ts b/lib/validations/webhook.ts index dc8f8bb41f..e3ea709ec9 100644 --- a/lib/validations/webhook.ts +++ b/lib/validations/webhook.ts @@ -24,7 +24,8 @@ export const schemaWebhookCreateBodyParams = schemaWebhookBaseBodyParams.merge(s const schemaWebhookEditParams = z .object({ payloadTemplate: z.string().optional(), - eventTriggers: z.string().optional(), + /** @todo: don't use any here and validate eventTriggers proper */ + eventTriggers: z.any(), subscriberUrl: z.string().optional(), }) .strict(); @@ -37,7 +38,8 @@ export const schemaWebhookReadPublic = Webhook.pick({ eventTypeId: true, payloadTemplate: true, eventTriggers: true, - eventType: true, - app: true, + /** @todo: find out why this breaks the api */ + // eventType: true, + // app: true, appId: true, }); diff --git a/package.json b/package.json index 8f025ebd54..33dd0c54a7 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ }, "devDependencies": { "@calcom/tsconfig": "*", - "@calcom/types": "*", "@typescript-eslint/eslint-plugin": "^5.25.0", "babel-jest": "^28.1.0", "jest": "^28.0.3", diff --git a/pages/api/booking-references/[id].ts b/pages/api/booking-references/[id].ts index 702b77c1a5..f7a14056eb 100644 --- a/pages/api/booking-references/[id].ts +++ b/pages/api/booking-references/[id].ts @@ -22,177 +22,161 @@ export async function bookingReferenceById( res.status(400).json({ message: "Your query was invalid" }); return; } - // const userWithBookings = await prisma.user.findUnique({ - // where: { id: userId }, - // include: { bookings: true }, - // }); - // if (!userWithBookings) throw new Error("User not found"); - // const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat(); - // console.log(userBookingIds); - // const bookingReferences = await prisma.bookingReference - // .findMany({ where: { id: { in: userBookingIds } } }) - // .then((bookingReferences) => { - // console.log(bookingReferences); - // return bookingReferences.map((bookingReference) => bookingReference.id); - // }); + const userWithBookings = await prisma.user.findUnique({ + where: { id: userId }, + include: { bookings: true }, + }); + if (!userWithBookings) throw new Error("User not found"); + const userBookingIds = userWithBookings.bookings.map((booking: { id: number }) => booking.id).flat(); + const bookingReferences = await prisma.bookingReference + .findMany({ where: { id: { in: userBookingIds } } }) + .then((bookingReferences) => bookingReferences.map((bookingReference) => bookingReference.id)); - // res.status(400).json({ message: "Booking reference not found" }); - // return; - // } - // if (userBookingIds.includes(safeQuery.data.id)) { - // if (!bookingReferences?.includes(safeQuery.data.id)) { - // throw new Error("BookingReference: bookingId not found"); - switch (method) { - case "GET": - /** - * @swagger - * /booking-references/{id}: - * get: - * operationId: getBookingReferenceById - * summary: Find a booking reference - * parameters: - * - in: path - * name: id - * schema: - * type: integer - * required: true - * description: ID of the booking reference to get - * tags: - * - booking-references - * responses: - * 200: - * description: OK - * 401: - * description: Authorization information is missing or invalid. - * 404: - * description: BookingReference was not found - */ - // console.log(safeQuery.data.id); - const bookingReference = await prisma.bookingReference.findFirst().catch((error: Error) => { - console.log("hoerr:", error); - }); - // console.log(bookingReference); - if (!bookingReference) res.status(404).json({ message: "Booking reference not found" }); - else res.status(200).json({ booking_reference: bookingReference }); + if (!bookingReferences?.includes(safeQuery.data.id)) res.status(401).json({ message: "Unauthorized" }); + else { + switch (method) { + case "GET": + /** + * @swagger + * /booking-references/{id}: + * get: + * operationId: getBookingReferenceById + * summary: Find a booking reference + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: ID of the booking reference to get + * tags: + * - booking-references + * responses: + * 200: + * description: OK + * 401: + * description: Authorization information is missing or invalid. + * 404: + * description: BookingReference was not found + */ + await prisma.bookingReference + .findFirst({ where: { id: safeQuery.data.id } }) + .then((data) => schemaBookingReferenceReadPublic.parse(data)) + .then((booking_reference) => res.status(200).json({ booking_reference })) + .catch((error: Error) => { + console.log(error); + res.status(404).json({ + message: `BookingReference with id: ${safeQuery.data.id} not found`, + error, + }); + }); - // .then((data) => { - // console.log(data); - // return schemaBookingReferenceReadPublic.parse(data); - // }) - // .then((booking_reference) => res.status(200).json({ booking_reference })) - // .catch((error: Error) => { - // console.log(error); - // res.status(404).json({ - // message: `BookingReference with id: ${safeQuery.data.id} not found`, - // error, - // }); - // }); - break; - case "PATCH": - /** - * @swagger - * /booking-references/{id}: - * patch: - * operationId: editBookingReferenceById - * summary: Edit an existing booking reference - * requestBody: - * description: Edit an existing booking reference related to one of your bookings - * required: true - * content: - * application/json: - * schema: - * type: object - * properties: - * days: - * type: array - * example: email@example.com - * startTime: - * type: string - * example: 1970-01-01T17:00:00.000Z - * endTime: - * type: string - * example: 1970-01-01T17:00:00.000Z - * parameters: - * - in: path - * name: id - * schema: - * type: integer - * required: true - * description: ID of the booking reference to edit - * tags: - * - booking-references - * responses: - * 201: - * description: OK, safeBody.data edited successfuly - * 400: - * description: Bad request. BookingReference body is invalid. - * 401: - * description: Authorization information is missing or invalid. - */ + break; + case "PATCH": + /** + * @swagger + * /booking-references/{id}: + * patch: + * operationId: editBookingReferenceById + * summary: Edit an existing booking reference + * requestBody: + * description: Edit an existing booking reference related to one of your bookings + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * days: + * type: array + * example: email@example.com + * startTime: + * type: string + * example: 1970-01-01T17:00:00.000Z + * endTime: + * type: string + * example: 1970-01-01T17:00:00.000Z + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: ID of the booking reference to edit + * tags: + * - booking-references + * responses: + * 201: + * description: OK, safeBody.data edited successfuly + * 400: + * description: Bad request. BookingReference body is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ - const safeBody = schemaBookingEditBodyParams.safeParse(body); - if (!safeBody.success) { - console.log(safeBody.error); - res.status(400).json({ message: "Invalid request body", error: safeBody.error }); - return; - } - await prisma.bookingReference - .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) - .then((data) => schemaBookingReferenceReadPublic.parse(data)) - .then((booking_reference) => res.status(200).json({ booking_reference })) - .catch((error: Error) => - res.status(404).json({ - message: `BookingReference with id: ${safeQuery.data.id} not found`, - error, + const safeBody = schemaBookingEditBodyParams.safeParse(body); + if (!safeBody.success) { + console.log(safeBody.error); + res.status(400).json({ message: "Invalid request body", error: safeBody.error }); + return; + } + await prisma.bookingReference + .update({ where: { id: safeQuery.data.id }, data: safeBody.data }) + .then((data) => schemaBookingReferenceReadPublic.parse(data)) + .then((booking_reference) => res.status(200).json({ booking_reference })) + .catch((error: Error) => + res.status(404).json({ + message: `BookingReference with id: ${safeQuery.data.id} not found`, + error, + }) + ); + break; + case "DELETE": + /** + * @swagger + * /booking-references/{id}: + * delete: + * operationId: removeBookingReferenceById + * summary: Remove an existing booking reference + * parameters: + * - in: path + * name: id + * schema: + * type: integer + * required: true + * description: ID of the booking reference to delete + * tags: + * - booking-references + * responses: + * 201: + * description: OK, bookingReference removed successfuly + * 400: + * description: Bad request. BookingReference id is invalid. + * 401: + * description: Authorization information is missing or invalid. + */ + await prisma.bookingReference + .delete({ + where: { id: safeQuery.data.id }, }) - ); - break; - case "DELETE": - /** - * @swagger - * /booking-references/{id}: - * delete: - * operationId: removeBookingReferenceById - * summary: Remove an existing booking reference - * parameters: - * - in: path - * name: id - * schema: - * type: integer - * required: true - * description: ID of the booking reference to delete - * tags: - * - booking-references - * responses: - * 201: - * description: OK, bookingReference removed successfuly - * 400: - * description: Bad request. BookingReference id is invalid. - * 401: - * description: Authorization information is missing or invalid. - */ - await prisma.bookingReference - .delete({ - where: { id: safeQuery.data.id }, - }) - .then(() => - res.status(200).json({ - message: `BookingReference with id: ${safeQuery.data.id} deleted`, - }) - ) - .catch((error: Error) => - res.status(404).json({ - message: `BookingReference with id: ${safeQuery.data.id} not found`, - error, - }) - ); - break; + .then(() => + res.status(200).json({ + message: `BookingReference with id: ${safeQuery.data.id} deleted`, + }) + ) + .catch((error: Error) => + res.status(404).json({ + message: `BookingReference with id: ${safeQuery.data.id} not found`, + error, + }) + ); + break; - default: - res.status(405).json({ message: "Method not allowed" }); - break; + default: + res.status(405).json({ message: "Method not allowed" }); + break; + } } - // } else res.status(401).json({ message: "Unauthorized" }); } export default withMiddleware("HTTP_GET_DELETE_PATCH")(