feat: adds full validations for users endpoint
parent
dad70d5a12
commit
4c022d5d07
|
@ -1,4 +1,5 @@
|
|||
import { withValidation } from "next-validations";
|
||||
import * as tzdb from "tzdata";
|
||||
import { z } from "zod";
|
||||
|
||||
import { _UserModel as User } from "@calcom/prisma/zod";
|
||||
|
@ -14,11 +15,45 @@ enum weekdays {
|
|||
SUNDAY = "Sunday",
|
||||
}
|
||||
|
||||
// @note: extracted from apps/web/next-i18next.config.js, update if new locales.
|
||||
enum locales {
|
||||
EN = "en",
|
||||
FR = "fr",
|
||||
IT = "it",
|
||||
RU = "ru",
|
||||
ES = "es",
|
||||
DE = "de",
|
||||
PT = "pt",
|
||||
RO = "ro",
|
||||
NL = "nl",
|
||||
PT_BR = "pt-BR",
|
||||
ES_419 = "es-419",
|
||||
KO = "ko",
|
||||
JA = "ja",
|
||||
PL = "pl",
|
||||
AR = "ar",
|
||||
IW = "iw",
|
||||
ZH_CN = "zh-CN",
|
||||
ZH_TW = "zh-TW",
|
||||
CS = "cs",
|
||||
SR = "sr",
|
||||
SV = "sv",
|
||||
VI = "vi",
|
||||
}
|
||||
enum theme {
|
||||
DARK = "dark",
|
||||
LIGHT = "light",
|
||||
}
|
||||
|
||||
enum timeFormat {
|
||||
TWELVE = 12,
|
||||
TWENTY_FOUR = 24,
|
||||
}
|
||||
|
||||
// @note: These are the values that are editable via PATCH method on the user Model
|
||||
export const schemaUserBaseBodyParams = User.pick({
|
||||
name: true,
|
||||
bio: true,
|
||||
avatar: true,
|
||||
timeZone: true,
|
||||
weekStart: true,
|
||||
endTime: true,
|
||||
|
@ -31,6 +66,8 @@ export const schemaUserBaseBodyParams = User.pick({
|
|||
darkBrandColor: true,
|
||||
allowDynamicBooking: true,
|
||||
away: true,
|
||||
// @note: disallowing avatar changes via API for now. We can add it later if needed. User should upload image via UI.
|
||||
// avatar: true,
|
||||
}).partial();
|
||||
// @note: partial() is used to allow for the user to edit only the fields they want to edit making all optional,
|
||||
// if want to make any required do it in the schemaRequiredParams
|
||||
|
@ -39,9 +76,26 @@ export const schemaUserBaseBodyParams = User.pick({
|
|||
// for example making weekStart only accept weekdays as input
|
||||
const schemaUserRequiredParams = z.object({
|
||||
weekStart: z.nativeEnum(weekdays).optional(),
|
||||
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
timeZone: z
|
||||
.string()
|
||||
// @note: This is a custom validation that checks if the timezone is valid and exists in the tzdb library
|
||||
.refine((tz: string) => Object.keys(tzdb.zones).includes(tz))
|
||||
.optional(),
|
||||
bufferTime: z.number().min(0).max(86400).optional(),
|
||||
startTime: z.number().min(0).max(86400).optional(),
|
||||
endTime: z.number().min(0).max(86400).optional(),
|
||||
theme: z.nativeEnum(theme).optional(),
|
||||
timeFormat: z.nativeEnum(timeFormat).optional(),
|
||||
defaultScheduleId: z
|
||||
.number()
|
||||
.refine((id: number) => id > 0)
|
||||
.optional(),
|
||||
locale: z.nativeEnum(locales),
|
||||
});
|
||||
|
||||
// @note: These are the values that are editable via PATCH method on the user Model
|
||||
// @note: These are the values that are editable via PATCH method on the user Model,
|
||||
// merging both BaseBodyParams with RequiredParams, and omiting whatever we want at the end.
|
||||
export const schemaUserEditBodyParams = schemaUserBaseBodyParams.merge(schemaUserRequiredParams).omit({});
|
||||
|
||||
// @note: These are the values that are always returned when reading a user
|
||||
|
|
|
@ -104,12 +104,23 @@ export async function userById(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||
break;
|
||||
|
||||
case "PATCH":
|
||||
// FIXME: Validate body against different Edit validation, skip username.
|
||||
const safeBody = schemaUserEditBodyParams.safeParse(body);
|
||||
if (!safeBody.success) {
|
||||
res.status(400).json({ message: "Bad request", error: safeBody.error });
|
||||
throw new Error("Invalid request body");
|
||||
}
|
||||
const userSchedules = await prisma.schedule.findMany({
|
||||
where: { userId },
|
||||
});
|
||||
const userSchedulesIds = userSchedules.map((schedule) => schedule.id);
|
||||
// @note: here we make sure user can only make as default his own scheudles
|
||||
if (!userSchedulesIds.includes(Number(safeBody?.data?.defaultScheduleId))) {
|
||||
res.status(400).json({
|
||||
message: "Bad request",
|
||||
error: "Invalid default schedule id",
|
||||
});
|
||||
throw new Error("Invalid request body value: defaultScheduleId");
|
||||
}
|
||||
await prisma.user
|
||||
.update({
|
||||
where: { id: userId },
|
||||
|
|
Loading…
Reference in New Issue