 ec58a9dd70
			
		
	
	
		ec58a9dd70
		
			
		
	
	
	
	
		
			
			* dotenv refactoring * dotenv fixes * Env variables cleanup * Updates e2e variables * Moves environment file to types * Removes conflicting configs * Readds missing variables * Fixes * More fixes * Update .env.example * Update yarn.lock * Update turbo.json * Fixes e2e * Temp fix * disables cache for lint * Please work * I'm getting desperate here. * Matches node versions * Take 2 * Revert "Take 2" This reverts commit a735f47f2325c2040168e0cd99dea0fc357a791f. * Update .env.example
		
			
				
	
	
		
			167 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { GetServerSidePropsContext } from "next";
 | |
| import { signIn } from "next-auth/react";
 | |
| import { useRouter } from "next/router";
 | |
| import { useEffect } from "react";
 | |
| 
 | |
| import { checkPremiumUsername } from "@calcom/ee/lib/core/checkPremiumUsername";
 | |
| import stripe from "@calcom/stripe/server";
 | |
| import { getPremiumPlanPrice } from "@calcom/stripe/utils";
 | |
| 
 | |
| import { asStringOrNull } from "@lib/asStringOrNull";
 | |
| import { getSession } from "@lib/auth";
 | |
| import prisma from "@lib/prisma";
 | |
| import { isSAMLLoginEnabled, hostedCal, samlTenantID, samlProductID, samlTenantProduct } from "@lib/saml";
 | |
| import { inferSSRProps } from "@lib/types/inferSSRProps";
 | |
| 
 | |
| import { ssrInit } from "@server/lib/ssr";
 | |
| 
 | |
| export type SSOProviderPageProps = inferSSRProps<typeof getServerSideProps>;
 | |
| 
 | |
| export default function Provider(props: SSOProviderPageProps) {
 | |
|   const router = useRouter();
 | |
| 
 | |
|   useEffect(() => {
 | |
|     if (props.provider === "saml") {
 | |
|       const email = typeof router.query?.email === "string" ? router.query?.email : null;
 | |
| 
 | |
|       if (!email) {
 | |
|         router.push("/auth/error?error=" + "Email not provided");
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       if (!props.isSAMLLoginEnabled) {
 | |
|         router.push("/auth/error?error=" + "SAML login not enabled");
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       signIn("saml", {}, { tenant: props.tenant, product: props.product });
 | |
|     } else {
 | |
|       signIn(props.provider);
 | |
|     }
 | |
|   }, []);
 | |
|   return null;
 | |
| }
 | |
| 
 | |
| export const getServerSideProps = async (context: GetServerSidePropsContext) => {
 | |
|   // get query params and typecast them to string
 | |
|   // (would be even better to assert them instead of typecasting)
 | |
|   const providerParam = asStringOrNull(context.query.provider);
 | |
|   const emailParam = asStringOrNull(context.query.email);
 | |
|   const usernameParam = asStringOrNull(context.query.username);
 | |
|   const successDestination = "/getting-started" + (usernameParam ? `?username=${usernameParam}` : "");
 | |
|   if (!providerParam) {
 | |
|     throw new Error(`File is not named sso/[provider]`);
 | |
|   }
 | |
| 
 | |
|   const { req } = context;
 | |
| 
 | |
|   const session = await getSession({ req });
 | |
|   const ssr = await ssrInit(context);
 | |
| 
 | |
|   if (session) {
 | |
|     // Validating if username is Premium, while this is true an email its required for stripe user confirmation
 | |
|     if (usernameParam && session.user.email) {
 | |
|       const availability = await checkPremiumUsername(usernameParam);
 | |
|       if (availability.available && availability.premium) {
 | |
|         const stripePremiumUrl = await getStripePremiumUsernameUrl({
 | |
|           userEmail: session.user.email,
 | |
|           username: usernameParam,
 | |
|           successDestination,
 | |
|         });
 | |
|         if (stripePremiumUrl) {
 | |
|           return {
 | |
|             redirect: {
 | |
|               destination: stripePremiumUrl,
 | |
|               permanent: false,
 | |
|             },
 | |
|           };
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return {
 | |
|       redirect: {
 | |
|         destination: successDestination,
 | |
|         permanent: false,
 | |
|       },
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   let error: string | null = null;
 | |
| 
 | |
|   let tenant = samlTenantID;
 | |
|   let product = samlProductID;
 | |
| 
 | |
|   if (providerParam === "saml" && hostedCal) {
 | |
|     if (!emailParam) {
 | |
|       error = "Email not provided";
 | |
|     } else {
 | |
|       try {
 | |
|         const ret = await samlTenantProduct(prisma, emailParam);
 | |
|         tenant = ret.tenant;
 | |
|         product = ret.product;
 | |
|       } catch (e: any) {
 | |
|         error = e.message;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (error) {
 | |
|     return {
 | |
|       redirect: {
 | |
|         destination: "/auth/error?error=" + error,
 | |
|         permanent: false,
 | |
|       },
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     props: {
 | |
|       trpcState: ssr.dehydrate(),
 | |
|       provider: providerParam,
 | |
|       isSAMLLoginEnabled,
 | |
|       hostedCal,
 | |
|       tenant,
 | |
|       product,
 | |
|       error,
 | |
|     },
 | |
|   };
 | |
| };
 | |
| 
 | |
| type GetStripePremiumUsernameUrl = {
 | |
|   userEmail: string;
 | |
|   username: string;
 | |
|   successDestination: string;
 | |
| };
 | |
| 
 | |
| const getStripePremiumUsernameUrl = async ({
 | |
|   userEmail,
 | |
|   username,
 | |
|   successDestination,
 | |
| }: GetStripePremiumUsernameUrl): Promise<string | null> => {
 | |
|   // @TODO: probably want to check if stripe user email already exists? or not
 | |
|   const customer = await stripe.customers.create({
 | |
|     email: userEmail,
 | |
|     metadata: {
 | |
|       email: userEmail,
 | |
|       username,
 | |
|     },
 | |
|   });
 | |
| 
 | |
|   const checkoutSession = await stripe.checkout.sessions.create({
 | |
|     mode: "subscription",
 | |
|     payment_method_types: ["card"],
 | |
|     customer: customer.id,
 | |
|     line_items: [
 | |
|       {
 | |
|         price: getPremiumPlanPrice(),
 | |
|         quantity: 1,
 | |
|       },
 | |
|     ],
 | |
|     success_url: `${process.env.NEXT_PUBLIC_WEBAPP_URL}${successDestination}&session_id={CHECKOUT_SESSION_ID}`,
 | |
|     cancel_url: process.env.NEXT_PUBLIC_WEBAPP_URL || "https://app.cal.com",
 | |
|     allow_promotion_codes: true,
 | |
|   });
 | |
| 
 | |
|   return checkoutSession.url;
 | |
| };
 |