cal.pub0.org/lib/validations/user.ts

154 lines
4.5 KiB
TypeScript

import { z } from "zod";
import { _UserModel as User } from "@calcom/prisma/zod";
import { timeZone } from "@lib/validations/shared/timeZone";
import { jsonSchema } from "./shared/jsonSchema";
// @note: These are the ONLY values allowed as weekStart. So user don't introduce bad data.
enum weekdays {
MONDAY = "Monday",
TUESDAY = "Tuesday",
WEDNESDAY = "Wednesday",
THURSDAY = "Thursday",
FRIDAY = "Friday",
SATURDAY = "Saturday",
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,
timeZone: true,
weekStart: true,
endTime: true,
metadata: true,
bufferTime: true,
theme: true,
defaultScheduleId: true,
locale: true,
timeFormat: true,
brandColor: true,
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
// Here we can both require or not (adding optional or nullish) and also rewrite validations for any value
// for example making weekStart only accept weekdays as input
const schemaUserEditParams = z.object({
weekStart: z.nativeEnum(weekdays).optional(),
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
darkBrandColor: z.string().min(4).max(9).regex(/^#/).optional(),
timeZone: timeZone.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().nullable(),
timeFormat: z.nativeEnum(timeFormat).optional(),
defaultScheduleId: z
.number()
.refine((id: number) => id > 0)
.optional()
.nullable(),
locale: z.nativeEnum(locales).optional().nullable(),
metadata: jsonSchema.optional(),
});
// @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.
const schemaUserCreateParams = z.object({
email: z.string().email(),
weekStart: z.nativeEnum(weekdays).optional(),
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
darkBrandColor: z.string().min(4).max(9).regex(/^#/).optional(),
timeZone: timeZone.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().nullable(),
timeFormat: z.nativeEnum(timeFormat).optional(),
defaultScheduleId: z
.number()
.refine((id: number) => id > 0)
.optional()
.nullable(),
locale: z.nativeEnum(locales).optional(),
metadata: jsonSchema,
createdDate: z.string().or(z.date()).optional(),
});
// @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(schemaUserEditParams).omit({});
export const schemaUserCreateBodyParams = schemaUserBaseBodyParams.merge(schemaUserCreateParams).omit({});
// @note: These are the values that are always returned when reading a user
export const schemaUserReadPublic = User.pick({
id: true,
username: true,
name: true,
email: true,
emailVerified: true,
bio: true,
avatar: true,
metadata: true,
timeZone: true,
weekStart: true,
endTime: true,
bufferTime: true,
theme: true,
defaultScheduleId: true,
locale: true,
timeFormat: true,
brandColor: true,
darkBrandColor: true,
allowDynamicBooking: true,
away: true,
createdDate: true,
verified: true,
invitedTo: true,
}).merge(schemaUserEditBodyParams);