diff --git a/lib/helpers/safeParseJSON.ts b/lib/helpers/safeParseJSON.ts new file mode 100644 index 0000000000..3681e42273 --- /dev/null +++ b/lib/helpers/safeParseJSON.ts @@ -0,0 +1,14 @@ +export default function parseJSONSafely(str: string) { + try { + return JSON.parse(str); + } catch (e) { + console.error((e as Error).message); + if ((e as Error).message.includes("Unexpected token")) { + return { + success: false, + message: `Invalid JSON in the body: ${(e as Error).message}`, + }; + } + return {}; + } +} diff --git a/pages/api/schedules/[id].ts b/pages/api/schedules/[id].ts index adc26e7b6d..4ef7a85b6d 100644 --- a/pages/api/schedules/[id].ts +++ b/pages/api/schedules/[id].ts @@ -1,5 +1,6 @@ import type { NextApiRequest, NextApiResponse } from "next"; +import safeParseJSON from "@lib/helpers/safeParseJSON"; import { withMiddleware } from "@lib/helpers/withMiddleware"; import type { ScheduleResponse } from "@lib/types"; import { schemaSingleScheduleBodyParams, schemaSchedulePublic } from "@lib/validations/schedule"; @@ -12,13 +13,18 @@ export async function scheduleById( { method, query, body, userId, isAdmin, prisma }: NextApiRequest, res: NextApiResponse ) { - const safeQuery = schemaQueryIdParseInt.safeParse(query); - const safeBody = schemaSingleScheduleBodyParams.safeParse(body); + body = safeParseJSON(body); + if (!body.success) { + res.status(400).json({ message: body.message }); + } + + const safe = schemaScheduleBodyParams.safeParse(body); if (!safeBody.success) { res.status(400).json({ message: "Bad request" }); return; } - + + const safeQuery = schemaQueryIdParseInt.safeParse(query); if (safeBody.data.userId && !isAdmin) { res.status(401).json({ message: "Unauthorized" }); return; diff --git a/pages/api/schedules/index.ts b/pages/api/schedules/index.ts index 7380a4faa2..3b8abc776f 100644 --- a/pages/api/schedules/index.ts +++ b/pages/api/schedules/index.ts @@ -2,6 +2,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { getAvailabilityFromSchedule, DEFAULT_SCHEDULE } from "@calcom/lib/availability"; +import safeParseJSON from "@lib/helpers/safeParseJSON"; import { withMiddleware } from "@lib/helpers/withMiddleware"; import { ScheduleResponse, SchedulesResponse } from "@lib/types"; import { @@ -14,6 +15,11 @@ async function createOrlistAllSchedules( { method, body, userId, isAdmin, prisma }: NextApiRequest, res: NextApiResponse ) { + body = safeParseJSON(body); + if (!body.success) { + res.status(400).json({ message: body.message }); + } + const safe = schemaScheduleBodyParams.safeParse(body); if (!safe.success) {