fix: email-address with apostrophe not accepted (#15535)
Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
This commit is contained in:
co-authored by
Keith Williams
Omar López
Amit Sharma
parent
5927b42560
commit
2be9fc8bc0
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { _AttendeeModel as Attendee } from "@calcom/prisma/zod";
|
||||
|
||||
import { timeZone } from "~/lib/validations/shared/timeZone";
|
||||
@@ -14,7 +15,7 @@ export const schemaAttendeeBaseBodyParams = Attendee.pick({
|
||||
const schemaAttendeeCreateParams = z
|
||||
.object({
|
||||
bookingId: z.number().int(),
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
name: z.string(),
|
||||
timeZone: timeZone,
|
||||
})
|
||||
@@ -23,7 +24,7 @@ const schemaAttendeeCreateParams = z
|
||||
const schemaAttendeeEditParams = z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
email: z.string().email().optional(),
|
||||
email: emailSchema.optional(),
|
||||
timeZone: timeZone.optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { withValidation } from "next-validations";
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
|
||||
import { baseApiParams } from "./baseApiParams";
|
||||
|
||||
// Extracted out as utility function so can be reused
|
||||
// at different endpoints that require this validation.
|
||||
export const schemaQueryAttendeeEmail = baseApiParams.extend({
|
||||
attendeeEmail: z.string().email(),
|
||||
attendeeEmail: emailSchema,
|
||||
});
|
||||
|
||||
export const schemaQuerySingleOrMultipleAttendeeEmails = z.object({
|
||||
attendeeEmail: z.union([z.string().email(), z.array(z.string().email())]).optional(),
|
||||
attendeeEmail: z.union([emailSchema, z.array(emailSchema)]).optional(),
|
||||
});
|
||||
|
||||
export const withValidQueryAttendeeEmail = withValidation({
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { withValidation } from "next-validations";
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
|
||||
import { baseApiParams } from "./baseApiParams";
|
||||
|
||||
// Extracted out as utility function so can be reused
|
||||
// at different endpoints that require this validation.
|
||||
export const schemaQueryUserEmail = baseApiParams.extend({
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
});
|
||||
|
||||
export const schemaQuerySingleOrMultipleUserEmails = z.object({
|
||||
email: z.union([z.string().email(), z.array(z.string().email())]),
|
||||
email: z.union([emailSchema, z.array(emailSchema)]),
|
||||
});
|
||||
|
||||
export const withValidQueryUserEmail = withValidation({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { checkUsername } from "@calcom/lib/server/checkUsername";
|
||||
import { _UserModel as User } from "@calcom/prisma/zod";
|
||||
import { iso8601 } from "@calcom/prisma/zod-utils";
|
||||
@@ -92,7 +93,7 @@ export const schemaUserBaseBodyParams = User.pick({
|
||||
// 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({
|
||||
email: z.string().email().toLowerCase(),
|
||||
email: emailSchema.toLowerCase(),
|
||||
username: usernameSchema,
|
||||
weekStart: z.nativeEnum(weekdays).optional(),
|
||||
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
@@ -115,7 +116,7 @@ const schemaUserEditParams = z.object({
|
||||
// merging both BaseBodyParams with RequiredParams, and omiting whatever we want at the end.
|
||||
|
||||
const schemaUserCreateParams = z.object({
|
||||
email: z.string().email().toLowerCase(),
|
||||
email: emailSchema.toLowerCase(),
|
||||
username: usernameSchema,
|
||||
weekStart: z.nativeEnum(weekdays).optional(),
|
||||
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import {
|
||||
Dialog,
|
||||
@@ -37,7 +38,7 @@ const SecondaryEmailModal = ({
|
||||
const formMethods = useForm<FormValues>({
|
||||
resolver: zodResolver(
|
||||
z.object({
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { z } from "zod";
|
||||
|
||||
import { isPasswordValid } from "@calcom/features/auth/lib/isPasswordValid";
|
||||
import { WEBSITE_URL } from "@calcom/lib/constants";
|
||||
import { emailRegex } from "@calcom/lib/emailSchema";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { EmailField, EmptyScreen, Label, PasswordField, TextField } from "@calcom/ui";
|
||||
|
||||
@@ -39,7 +40,7 @@ export const AdminUser = (props: { onSubmit: () => void; onError: () => void; on
|
||||
username: z
|
||||
.string()
|
||||
.refine((val) => val.trim().length >= 1, { message: t("at_least_characters", { count: 1 }) }),
|
||||
email_address: z.string().email({ message: t("enter_valid_email") }),
|
||||
email_address: z.string().regex(emailRegex, { message: t("enter_valid_email") }),
|
||||
full_name: z.string().min(3, t("at_least_characters", { count: 3 })),
|
||||
password: z.string().superRefine((data, ctx) => {
|
||||
const isStrict = true;
|
||||
|
||||
@@ -6,20 +6,21 @@ import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiu
|
||||
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
|
||||
import { getFeatureFlag } from "@calcom/features/flags/server/utils";
|
||||
import { IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { IS_GOOGLE_LOGIN_ENABLED } from "@server/lib/constants";
|
||||
import { ssrInit } from "@server/lib/ssr";
|
||||
|
||||
const checkValidEmail = (email: string) => z.string().email().safeParse(email).success;
|
||||
const checkValidEmail = (email: string) => emailSchema.safeParse(email).success;
|
||||
|
||||
const querySchema = z.object({
|
||||
username: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((val) => val || ""),
|
||||
email: z.string().email().optional(),
|
||||
email: emailSchema.optional(),
|
||||
});
|
||||
|
||||
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
|
||||
@@ -12,6 +12,7 @@ import { z } from "zod";
|
||||
import { SAMLLogin } from "@calcom/features/auth/SAMLLogin";
|
||||
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
|
||||
import { HOSTED_CAL_FEATURES, WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants";
|
||||
import { emailRegex } from "@calcom/lib/emailSchema";
|
||||
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
|
||||
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
|
||||
import { useLastUsed, LastUsed } from "@calcom/lib/hooks/useLastUsed";
|
||||
@@ -59,7 +60,7 @@ PageProps & WithNonceProps<{}>) {
|
||||
email: z
|
||||
.string()
|
||||
.min(1, `${t("error_required_field")}`)
|
||||
.email(`${t("enter_valid_email")}`),
|
||||
.regex(emailRegex, `${t("enter_valid_email")}`),
|
||||
...(!!totpEmail ? {} : { password: z.string().min(1, `${t("error_required_field")}`) }),
|
||||
})
|
||||
// Passthrough other fields like totpCode
|
||||
|
||||
@@ -12,6 +12,7 @@ import { z } from "zod";
|
||||
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
|
||||
import SectionBottomActions from "@calcom/features/settings/SectionBottomActions";
|
||||
import { APP_NAME, FULL_NAME_LENGTH_MAX_LIMIT } from "@calcom/lib/constants";
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { md } from "@calcom/lib/markdownIt";
|
||||
@@ -523,12 +524,12 @@ const ProfileForm = ({
|
||||
.max(FULL_NAME_LENGTH_MAX_LIMIT, {
|
||||
message: t("max_limit_allowed_hint", { limit: FULL_NAME_LENGTH_MAX_LIMIT }),
|
||||
}),
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
bio: z.string(),
|
||||
secondaryEmails: z.array(
|
||||
z.object({
|
||||
id: z.number(),
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
emailVerified: z.union([z.string(), z.null()]).optional(),
|
||||
emailPrimary: z.boolean().optional(),
|
||||
})
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { z } from "zod";
|
||||
|
||||
import { passwordResetRequest } from "@calcom/features/auth/lib/passwordResetRequest";
|
||||
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { defaultHandler } from "@calcom/lib/server";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const email = z
|
||||
.string()
|
||||
.email()
|
||||
.transform((val) => val.toLowerCase())
|
||||
.safeParse(req.body?.email);
|
||||
const email = emailSchema.transform((val) => val.toLowerCase()).safeParse(req.body?.email);
|
||||
|
||||
if (!email.success) {
|
||||
return res.status(400).json({ message: "email is required" });
|
||||
|
||||
@@ -3,6 +3,7 @@ import z from "zod";
|
||||
|
||||
import { hashPassword } from "@calcom/features/auth/lib/hashPassword";
|
||||
import { isPasswordValid } from "@calcom/features/auth/lib/isPasswordValid";
|
||||
import { emailRegex } from "@calcom/lib/emailSchema";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { defaultHandler, defaultResponder } from "@calcom/lib/server";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
@@ -14,7 +15,7 @@ const querySchema = z.object({
|
||||
.string()
|
||||
.refine((val) => val.trim().length >= 1, { message: "Please enter at least one character" }),
|
||||
full_name: z.string().min(3, "Please enter at least 3 characters"),
|
||||
email_address: z.string().email({ message: "Please enter a valid email" }),
|
||||
email_address: z.string().regex(emailRegex, { message: "Please enter a valid email" }),
|
||||
password: z.string().refine((val) => isPasswordValid(val.trim(), false, true), {
|
||||
message:
|
||||
"The password must be a minimum of 15 characters long containing at least one number and have a mixture of uppercase and lowercase letters",
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import getRawBody from "raw-body";
|
||||
import z from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { default as webPrisma } from "@calcom/prisma";
|
||||
|
||||
export const config = {
|
||||
@@ -13,7 +14,7 @@ export const config = {
|
||||
|
||||
const helpscoutRequestBodySchema = z.object({
|
||||
customer: z.object({
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { z } from "zod";
|
||||
|
||||
import { symmetricEncrypt } from "@calcom/lib/crypto";
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { defaultResponder } from "@calcom/lib/server";
|
||||
import prisma from "@calcom/prisma";
|
||||
@@ -14,7 +15,7 @@ import { CalendarService } from "../lib";
|
||||
const formSchema = z
|
||||
.object({
|
||||
url: z.string().url(),
|
||||
username: z.string().email(),
|
||||
username: emailSchema,
|
||||
password: z.string(),
|
||||
authenticationMethod: z.number().default(ExchangeAuthentication.STANDARD),
|
||||
exchangeVersion: z.number().default(ExchangeVersion.Exchange2016),
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Controller, useForm } from "react-hook-form";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import z from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { Alert, Button, EmailField, Form, PasswordField, SelectField, TextField } from "@calcom/ui";
|
||||
|
||||
@@ -22,7 +23,7 @@ interface IFormData {
|
||||
const schema = z
|
||||
.object({
|
||||
url: z.string().url(),
|
||||
username: z.string().email(),
|
||||
username: emailSchema,
|
||||
password: z.string(),
|
||||
authenticationMethod: z.number().default(ExchangeAuthentication.STANDARD),
|
||||
exchangeVersion: z.number().default(ExchangeVersion.Exchange2016),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
@@ -75,7 +76,7 @@ export const responseHandler = async ({ ctx, input }: ResponseHandlerOptions) =>
|
||||
}
|
||||
let schema;
|
||||
if (field.type === "email") {
|
||||
schema = z.string().email();
|
||||
schema = emailSchema;
|
||||
} else if (field.type === "phone") {
|
||||
schema = z.any();
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useFormContext } from "react-hook-form";
|
||||
import z from "zod";
|
||||
|
||||
import { HOSTED_CAL_FEATURES } from "@calcom/lib/constants";
|
||||
import { emailRegex } from "@calcom/lib/emailSchema";
|
||||
import { LastUsed, useLastUsed } from "@calcom/lib/hooks/useLastUsed";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
@@ -17,7 +18,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().email({ message: "Please enter a valid email" }),
|
||||
email: z.string().regex(emailRegex, { message: "Please enter a valid email" }),
|
||||
});
|
||||
|
||||
export function SAMLLogin({
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useMemo, useState } from "react";
|
||||
import { Controller, useForm, useFormContext } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
import { trpc, type RouterOutputs } from "@calcom/trpc/react";
|
||||
@@ -46,7 +47,7 @@ const attributeSchema = z.object({
|
||||
const editSchema = z.object({
|
||||
name: z.string(),
|
||||
username: z.string(),
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
avatar: z.string(),
|
||||
bio: z.string(),
|
||||
role: z.enum([MembershipRole.MEMBER, MembershipRole.ADMIN, MembershipRole.OWNER]),
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
/** @see https://github.com/colinhacks/zod/issues/3155#issuecomment-2060045794 */
|
||||
export const emailRegex =
|
||||
/^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.']*)[A-Z0-9_+'-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
|
||||
|
||||
export const emailSchema = z.string().regex(emailRegex);
|
||||
@@ -202,7 +202,7 @@ model DestinationCalendar {
|
||||
id Int @id @default(autoincrement())
|
||||
integration String
|
||||
externalId String
|
||||
/// @zod.email()
|
||||
/// @zod.custom(imports.emailSchema)
|
||||
primaryEmail String?
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
userId Int? @unique
|
||||
@@ -247,7 +247,7 @@ model User {
|
||||
id Int @id @default(autoincrement())
|
||||
username String?
|
||||
name String?
|
||||
/// @zod.email()
|
||||
/// @zod.custom(imports.emailSchema)
|
||||
email String
|
||||
emailVerified DateTime?
|
||||
password UserPassword?
|
||||
@@ -578,7 +578,7 @@ model Booking {
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
userId Int?
|
||||
// User's email at the time of booking
|
||||
/// @zod.email()
|
||||
/// @zod.custom(imports.emailSchema)
|
||||
userPrimaryEmail String?
|
||||
references BookingReference[]
|
||||
eventType EventType? @relation(fields: [eventTypeId], references: [id])
|
||||
|
||||
@@ -18,6 +18,7 @@ import { isPasswordValid } from "@calcom/features/auth/lib/isPasswordValid";
|
||||
import type { FieldType as FormBuilderFieldType } from "@calcom/features/form-builder/schema";
|
||||
import { fieldsSchema as formBuilderFieldsSchema } from "@calcom/features/form-builder/schema";
|
||||
import { isSupportedTimeZone } from "@calcom/lib/date-fns";
|
||||
import { emailSchema as emailRegexSchema, emailRegex } from "@calcom/lib/emailSchema";
|
||||
import { slugify } from "@calcom/lib/slugify";
|
||||
import { EventTypeCustomInputType } from "@calcom/prisma/enums";
|
||||
|
||||
@@ -699,11 +700,12 @@ export const unlockedManagedEventTypeProps = {
|
||||
destinationCalendar: allManagedEventTypeProps.destinationCalendar,
|
||||
};
|
||||
|
||||
export const emailSchema = emailRegexSchema;
|
||||
|
||||
// The PR at https://github.com/colinhacks/zod/pull/2157 addresses this issue and improves email validation
|
||||
// I introduced this refinement(to be used with z.email()) as a short term solution until we upgrade to a zod
|
||||
// version that will include updates in the above PR.
|
||||
export const emailSchemaRefinement = (value: string) => {
|
||||
const emailRegex = /^([A-Z0-9_+-]+\.?)*[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}$/i;
|
||||
return emailRegex.test(value);
|
||||
};
|
||||
|
||||
@@ -711,7 +713,7 @@ export const signupSchema = z.object({
|
||||
// Username is marked optional here because it's requirement depends on if it's the Organization invite or a team invite which isn't easily done in zod
|
||||
// It's better handled beyond zod in `validateAndGetCorrectedUsernameAndEmail`
|
||||
username: z.string().optional(),
|
||||
email: z.string().email({ message: "Invalid email" }),
|
||||
email: z.string().regex(emailRegex, { message: "Invalid email" }),
|
||||
password: z.string().superRefine((data, ctx) => {
|
||||
const isStrict = false;
|
||||
const result = isPasswordValid(data, true, isStrict);
|
||||
@@ -730,7 +732,7 @@ export const signupSchema = z.object({
|
||||
});
|
||||
|
||||
export const ZVerifyCodeInputSchema = z.object({
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
code: z.string(),
|
||||
});
|
||||
|
||||
@@ -743,4 +745,4 @@ export const getStringAsNumberRequiredSchema = (t: TFunction) =>
|
||||
export const bookingSeatDataSchema = z.object({
|
||||
description: z.string().optional(),
|
||||
responses: bookingResponses,
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,9 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
|
||||
export const ZSamlTenantProductInputSchema = z.object({
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
});
|
||||
|
||||
export type TSamlTenantProductInputSchema = z.infer<typeof ZSamlTenantProductInputSchema>;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
|
||||
const BillingType = z.enum(["PER_BOOKING", "PER_USER"]);
|
||||
const BillingPeriod = z.enum(["MONTHLY", "ANNUALLY"]);
|
||||
|
||||
@@ -9,7 +11,7 @@ export const ZCreateSelfHostedLicenseSchema = z.object({
|
||||
entityPrice: z.number().nonnegative(),
|
||||
billingPeriod: BillingPeriod,
|
||||
overages: z.number().nonnegative(),
|
||||
billingEmail: z.string().email(),
|
||||
billingEmail: emailSchema,
|
||||
});
|
||||
|
||||
export type TCreateSelfHostedLicenseSchema = z.infer<typeof ZCreateSelfHostedLicenseSchema>;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
|
||||
export const ZResendVerifyEmailSchema = z
|
||||
.object({
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
})
|
||||
.optional();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
|
||||
export enum BillingPeriod {
|
||||
@@ -10,7 +11,7 @@ export enum BillingPeriod {
|
||||
export const ZCreateInputSchema = z.object({
|
||||
name: z.string(),
|
||||
slug: z.string().transform((val) => slugify(val.trim())),
|
||||
orgOwnerEmail: z.string().email(),
|
||||
orgOwnerEmail: emailSchema,
|
||||
language: z.string().optional(),
|
||||
seats: z.number().optional(),
|
||||
pricePerSeat: z.number().optional(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { MAX_NB_INVITES } from "@calcom/lib/constants";
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
export const ZInviteMemberInputSchema = z.object({
|
||||
@@ -12,7 +13,7 @@ export const ZInviteMemberInputSchema = z.object({
|
||||
.union([
|
||||
z.string(),
|
||||
z.object({
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
role: z.nativeEnum(MembershipRole),
|
||||
}),
|
||||
])
|
||||
@@ -47,7 +48,7 @@ export const ZInviteMemberInputSchema = z.object({
|
||||
.refine(
|
||||
(value) => {
|
||||
if (Array.isArray(value)) {
|
||||
return !value.some((email) => !z.string().email().safeParse(email).success);
|
||||
return !value.some((email) => !emailSchema.safeParse(email).success);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -179,7 +179,9 @@ describe("Invite Member Utils", () => {
|
||||
|
||||
it("should not throw an error if the email is valid", () => {
|
||||
const validEmail = "valid-email@example.com";
|
||||
const validEmailWithApostrophe = "valid'email@example.com";
|
||||
expect(() => checkInputEmailIsValid(validEmail)).not.toThrow();
|
||||
expect(() => checkInputEmailIsValid(validEmailWithApostrophe)).not.toThrow();
|
||||
});
|
||||
});
|
||||
describe("getOrgConnectionInfo", () => {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { emailSchema } from "@calcom/lib/emailSchema";
|
||||
|
||||
export const ZResendInvitationInputSchema = z.object({
|
||||
teamId: z.number(),
|
||||
email: z.string().email(),
|
||||
email: emailSchema,
|
||||
language: z.string(),
|
||||
isOrg: z.boolean().default(false),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user