From 7fc0877c266fbd51e8984e571cba6bbd1ace16cb Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Fri, 2 Jun 2023 21:29:52 +0200 Subject: [PATCH] Set reqBody.end to start + eventType.length (#9296) --- .../features/bookings/lib/handleNewBooking.ts | 45 +++++++++++++++---- packages/prisma/zod-utils.ts | 2 +- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index b3a94b2b5b..b2b687ce3d 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -468,6 +468,13 @@ function getBookingData({ if (val.responses) { const unwantedProps: string[] = []; legacyProps.forEach((legacyProp) => { + if (typeof val[legacyProp as keyof typeof val] !== "undefined") { + console.error( + `Deprecated: Unexpected falsy value for: ${unwantedProps.join( + "," + )}. They can't be used with \`responses\`. This will become a 400 error in the future.` + ); + } if (val[legacyProp as keyof typeof val]) { unwantedProps.push(legacyProp); } @@ -489,7 +496,24 @@ function getBookingData({ } } }); + const reqBody = bookingDataSchema.parse(req.body); + + // Work with Typescript to require reqBody.end + type ReqBodyWithoutEnd = z.infer; + type ReqBodyWithEnd = ReqBodyWithoutEnd & { end: string }; + + const reqBodyWithEnd = (reqBody: ReqBodyWithoutEnd): reqBody is ReqBodyWithEnd => { + // Use the event length to auto-set the event end time. + if (!Object.prototype.hasOwnProperty.call(reqBody, "end")) { + reqBody.end = dayjs.utc(reqBody.start).add(eventType.length, "minutes").format(); + } + return true; + }; + if (!reqBodyWithEnd(reqBody)) { + throw new Error("Internal Error."); + } + // reqBody.end is no longer an optional property. if ("customInputs" in reqBody) { if (reqBody.customInputs) { // Check if required custom inputs exist @@ -667,7 +691,7 @@ async function handler( metadata: true, }, }) - : !!eventType.hosts?.length + : eventType.hosts?.length ? eventType.hosts.map(({ user, isFixed }) => ({ ...user, isFixed, @@ -731,14 +755,17 @@ async function handler( defaultLocationUrl = firstUsersMetadata?.defaultConferencingApp?.appLink; } - if (eventType && eventType.hasOwnProperty("bookingLimits") && eventType?.bookingLimits) { + if ( + Object.prototype.hasOwnProperty.call(eventType, "bookingLimits") || + Object.prototype.hasOwnProperty.call(eventType, "durationLimits") + ) { const startAsDate = dayjs(reqBody.start).toDate(); - await checkBookingLimits(eventType.bookingLimits, startAsDate, eventType.id); - } - - if (eventType && eventType.hasOwnProperty("durationLimits") && eventType?.durationLimits) { - const startAsDate = dayjs(reqBody.start).toDate(); - await checkDurationLimits(eventType.durationLimits, startAsDate, eventType.id); + if (eventType.bookingLimits) { + await checkBookingLimits(eventType.bookingLimits, startAsDate, eventType.id); + } + if (eventType.durationLimits) { + await checkDurationLimits(eventType.durationLimits, startAsDate, eventType.id); + } } if (!eventType.seatsPerTimeSlot) { @@ -911,7 +938,7 @@ async function handler( requiresConfirmation: requiresConfirmation ?? false, eventTypeId: eventType.id, // if seats are not enabled we should default true - seatsShowAttendees: !!eventType.seatsPerTimeSlot ? eventType.seatsShowAttendees : true, + seatsShowAttendees: eventType.seatsPerTimeSlot ? eventType.seatsShowAttendees : true, seatsPerTimeSlot: eventType.seatsPerTimeSlot, }; diff --git a/packages/prisma/zod-utils.ts b/packages/prisma/zod-utils.ts index 9fa2410d78..01738b9172 100644 --- a/packages/prisma/zod-utils.ts +++ b/packages/prisma/zod-utils.ts @@ -161,7 +161,7 @@ export const stringOrNumber = z.union([ export const stringToDayjs = z.string().transform((val) => dayjs(val)); export const bookingCreateBodySchema = z.object({ - end: z.string(), + end: z.string().optional(), eventTypeId: z.number(), eventTypeSlug: z.string().optional(), rescheduleUid: z.string().optional(),