| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  | import { GetServerSidePropsContext } from "next"; | 
					
						
							| 
									
										
										
										
											2022-01-07 20:23:37 +00:00
										 |  |  | import { signIn } from "next-auth/react"; | 
					
						
							| 
									
										
										
										
											2021-09-22 19:52:38 +00:00
										 |  |  | import { useRouter } from "next/router"; | 
					
						
							| 
									
										
										
										
											2022-01-13 20:05:23 +00:00
										 |  |  | import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; | 
					
						
							| 
									
										
										
										
											2021-09-22 19:52:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-16 23:36:43 +00:00
										 |  |  | import { Alert } from "@calcom/ui/Alert"; | 
					
						
							|  |  |  | import Button from "@calcom/ui/Button"; | 
					
						
							|  |  |  | import { EmailField, PasswordField, TextField } from "@calcom/ui/form/fields"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  | import { asStringOrNull } from "@lib/asStringOrNull"; | 
					
						
							| 
									
										
										
										
											2022-02-27 22:34:08 +00:00
										 |  |  | import { NEXT_PUBLIC_BASE_URL } from "@lib/config/constants"; | 
					
						
							| 
									
										
										
										
											2021-10-14 14:24:21 +00:00
										 |  |  | import { useLocale } from "@lib/hooks/useLocale"; | 
					
						
							| 
									
										
										
										
											2021-08-27 12:35:20 +00:00
										 |  |  | import prisma from "@lib/prisma"; | 
					
						
							| 
									
										
										
										
											2022-01-13 20:05:23 +00:00
										 |  |  | import { isSAMLLoginEnabled } from "@lib/saml"; | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  | import { inferSSRProps } from "@lib/types/inferSSRProps"; | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 19:52:38 +00:00
										 |  |  | import { HeadSeo } from "@components/seo/head-seo"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-13 20:05:23 +00:00
										 |  |  | import { IS_GOOGLE_LOGIN_ENABLED } from "@server/lib/constants"; | 
					
						
							| 
									
										
										
										
											2021-11-16 17:12:08 +00:00
										 |  |  | import { ssrInit } from "@server/lib/ssr"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  | type Props = inferSSRProps<typeof getServerSideProps>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type FormValues = { | 
					
						
							|  |  |  |   username: string; | 
					
						
							|  |  |  |   email: string; | 
					
						
							|  |  |  |   password: string; | 
					
						
							|  |  |  |   passwordcheck: string; | 
					
						
							|  |  |  |   apiError: string; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default function Signup({ email }: Props) { | 
					
						
							| 
									
										
										
										
											2021-10-14 14:24:21 +00:00
										 |  |  |   const { t } = useLocale(); | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |   const router = useRouter(); | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |   const methods = useForm<FormValues>(); | 
					
						
							|  |  |  |   const { | 
					
						
							|  |  |  |     register, | 
					
						
							|  |  |  |     formState: { errors, isSubmitting }, | 
					
						
							|  |  |  |   } = methods; | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |   methods.setValue("email", email); | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |   const handleErrors = async (resp: Response) => { | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |     if (!resp.ok) { | 
					
						
							|  |  |  |       const err = await resp.json(); | 
					
						
							|  |  |  |       throw new Error(err.message); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |   const signUp: SubmitHandler<FormValues> = async (data) => { | 
					
						
							|  |  |  |     await fetch("/api/auth/signup", { | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |       body: JSON.stringify({ | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |         ...data, | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |       }), | 
					
						
							|  |  |  |       headers: { | 
					
						
							|  |  |  |         "Content-Type": "application/json", | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       method: "POST", | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |       .then(handleErrors) | 
					
						
							| 
									
										
										
										
											2022-02-21 20:09:56 +00:00
										 |  |  |       .then( | 
					
						
							|  |  |  |         async () => | 
					
						
							|  |  |  |           await signIn("Cal.com", { | 
					
						
							| 
									
										
										
										
											2022-02-27 22:34:08 +00:00
										 |  |  |             callbackUrl: (`${NEXT_PUBLIC_BASE_URL}/${router.query.callbackUrl}` || "") as string, | 
					
						
							| 
									
										
										
										
											2022-02-21 20:09:56 +00:00
										 |  |  |           }) | 
					
						
							|  |  |  |       ) | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |       .catch((err) => { | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |         methods.setError("apiError", { message: err.message }); | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |       }); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |     <div | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |       className="flex min-h-screen flex-col justify-center bg-gray-50 py-12 sm:px-6 lg:px-8" | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |       aria-labelledby="modal-title" | 
					
						
							|  |  |  |       role="dialog" | 
					
						
							|  |  |  |       aria-modal="true"> | 
					
						
							| 
									
										
										
										
											2021-10-14 14:24:21 +00:00
										 |  |  |       <HeadSeo title={t("sign_up")} description={t("sign_up")} /> | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |       <div className="sm:mx-auto sm:w-full sm:max-w-md"> | 
					
						
							| 
									
										
										
										
											2022-02-09 22:32:31 +00:00
										 |  |  |         <h2 className="font-cal text-center text-3xl font-extrabold text-gray-900"> | 
					
						
							| 
									
										
										
										
											2021-10-14 14:24:21 +00:00
										 |  |  |           {t("create_your_account")} | 
					
						
							|  |  |  |         </h2> | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |       </div> | 
					
						
							|  |  |  |       <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |         <div className="mx-2 bg-white px-4 py-8 shadow sm:rounded-lg sm:px-10"> | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |           {/* TODO: Refactor as soon as /availability is live */} | 
					
						
							|  |  |  |           <FormProvider {...methods}> | 
					
						
							|  |  |  |             <form onSubmit={methods.handleSubmit(signUp)} className="space-y-6 bg-white"> | 
					
						
							|  |  |  |               {errors.apiError && <Alert severity="error" message={errors.apiError?.message} />} | 
					
						
							|  |  |  |               <div className="space-y-2"> | 
					
						
							|  |  |  |                 <TextField | 
					
						
							|  |  |  |                   addOnLeading={ | 
					
						
							| 
									
										
										
										
											2022-03-09 22:17:46 +00:00
										 |  |  |                     <span className="inline-flex items-center rounded-l-sm border border-r-0 border-gray-300 bg-gray-50 px-3 text-sm text-gray-500"> | 
					
						
							| 
									
										
										
										
											2022-03-26 00:39:38 +00:00
										 |  |  |                       {process.env.NEXT_PUBLIC_WEBSITE_URL}/ | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                     </span> | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                   labelProps={{ className: "block text-sm font-medium text-gray-700" }} | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                   className="block w-full min-w-0 flex-grow rounded-none rounded-r-sm border-gray-300 lowercase focus:border-black focus:ring-black sm:text-sm" | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                   {...register("username")} | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |                   required | 
					
						
							|  |  |  |                 /> | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                 <EmailField | 
					
						
							|  |  |  |                   {...register("email")} | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                   className="mt-1 block w-full rounded-md border border-gray-300 bg-gray-100 px-3 py-2 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm" | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                 /> | 
					
						
							|  |  |  |                 <PasswordField | 
					
						
							|  |  |  |                   labelProps={{ | 
					
						
							|  |  |  |                     className: "block text-sm font-medium text-gray-700", | 
					
						
							|  |  |  |                   }} | 
					
						
							|  |  |  |                   {...register("password")} | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                   className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm" | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |                 /> | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                 <PasswordField | 
					
						
							|  |  |  |                   label={t("confirm_password")} | 
					
						
							|  |  |  |                   labelProps={{ | 
					
						
							|  |  |  |                     className: "block text-sm font-medium text-gray-700", | 
					
						
							|  |  |  |                   }} | 
					
						
							|  |  |  |                   {...register("passwordcheck", { | 
					
						
							|  |  |  |                     validate: (value) => | 
					
						
							|  |  |  |                       value === methods.watch("password") || (t("error_password_mismatch") as string), | 
					
						
							|  |  |  |                   })} | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                   className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-black focus:outline-none focus:ring-black sm:text-sm" | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                 /> | 
					
						
							|  |  |  |               </div> | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |               <div className="flex space-x-2 rtl:space-x-reverse"> | 
					
						
							|  |  |  |                 <Button loading={isSubmitting} className="w-7/12 justify-center"> | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                   {t("create_account")} | 
					
						
							|  |  |  |                 </Button> | 
					
						
							|  |  |  |                 <Button | 
					
						
							|  |  |  |                   color="secondary" | 
					
						
							| 
									
										
										
										
											2022-02-09 00:05:13 +00:00
										 |  |  |                   className="w-5/12 justify-center" | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                   onClick={() => | 
					
						
							| 
									
										
										
										
											2022-02-21 20:09:56 +00:00
										 |  |  |                     signIn("Cal.com", { | 
					
						
							| 
									
										
										
										
											2022-02-27 22:34:08 +00:00
										 |  |  |                       callbackUrl: (`${NEXT_PUBLIC_BASE_URL}/${router.query.callbackUrl}` || "") as string, | 
					
						
							| 
									
										
										
										
											2022-02-21 20:09:56 +00:00
										 |  |  |                     }) | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |                   }> | 
					
						
							|  |  |  |                   {t("login_instead")} | 
					
						
							|  |  |  |                 </Button> | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |               </div> | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |             </form> | 
					
						
							|  |  |  |           </FormProvider> | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |         </div> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  | export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { | 
					
						
							| 
									
										
										
										
											2021-11-16 17:12:08 +00:00
										 |  |  |   const ssr = await ssrInit(ctx); | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |   const token = asStringOrNull(ctx.query.token); | 
					
						
							|  |  |  |   if (!token) { | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |     return { | 
					
						
							|  |  |  |       notFound: true, | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   const verificationRequest = await prisma.verificationRequest.findUnique({ | 
					
						
							|  |  |  |     where: { | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  |       token, | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // for now, disable if no verificationRequestToken given or token expired
 | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |   if (!verificationRequest || verificationRequest.expires < new Date()) { | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |     return { | 
					
						
							|  |  |  |       notFound: true, | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const existingUser = await prisma.user.findFirst({ | 
					
						
							|  |  |  |     where: { | 
					
						
							|  |  |  |       AND: [ | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |           email: verificationRequest.identifier, | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           emailVerified: { | 
					
						
							|  |  |  |             not: null, | 
					
						
							|  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (existingUser) { | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |     return { | 
					
						
							| 
									
										
										
										
											2021-11-16 17:12:08 +00:00
										 |  |  |       redirect: { | 
					
						
							|  |  |  |         permanent: false, | 
					
						
							| 
									
										
										
										
											2022-02-27 22:34:08 +00:00
										 |  |  |         destination: "/auth/login?callbackUrl=" + `${NEXT_PUBLIC_BASE_URL}/${ctx.query.callbackUrl}`, | 
					
						
							| 
									
										
										
										
											2021-11-16 17:12:08 +00:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-08-02 20:51:57 +00:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-09 21:29:31 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 17:12:08 +00:00
										 |  |  |   return { | 
					
						
							|  |  |  |     props: { | 
					
						
							| 
									
										
										
										
											2022-01-13 20:05:23 +00:00
										 |  |  |       isGoogleLoginEnabled: IS_GOOGLE_LOGIN_ENABLED, | 
					
						
							|  |  |  |       isSAMLLoginEnabled, | 
					
						
							| 
									
										
										
										
											2021-11-16 17:12:08 +00:00
										 |  |  |       email: verificationRequest.identifier, | 
					
						
							|  |  |  |       trpcState: ssr.dehydrate(), | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-11-11 05:44:53 +00:00
										 |  |  | }; |