From 01500414963cc705815c7d8d1a31863b118ee683 Mon Sep 17 00:00:00 2001 From: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Date: Tue, 5 Sep 2023 01:13:37 +0530 Subject: [PATCH] fix: improve UX of team invite by copy link (#11009) --- apps/web/pages/auth/login.tsx | 9 +++++- apps/web/pages/signup.tsx | 30 ++++++++++++++----- apps/web/pages/teams/index.tsx | 17 +++++++++++ apps/web/public/static/locales/en/common.json | 1 + 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/apps/web/pages/auth/login.tsx b/apps/web/pages/auth/login.tsx index ca4e752e72..032289bfe6 100644 --- a/apps/web/pages/auth/login.tsx +++ b/apps/web/pages/auth/login.tsx @@ -52,6 +52,8 @@ export default function Login({ totpEmail, }: inferSSRProps & WithNonceProps) { const searchParams = useSearchParams(); + const isTeamInvite = searchParams.get("teamInvite"); + const { t } = useLocale(); const router = useRouter(); const formSchema = z @@ -95,7 +97,9 @@ export default function Login({ callbackUrl = safeCallbackUrl || ""; const LoginFooter = ( - + {t("dont_have_an_account")} ); @@ -184,6 +188,9 @@ export default function Login({ ? LoginFooter : null }> + {isTeamInvite && ( + + )}
diff --git a/apps/web/pages/signup.tsx b/apps/web/pages/signup.tsx index c41025bc99..151186a6d1 100644 --- a/apps/web/pages/signup.tsx +++ b/apps/web/pages/signup.tsx @@ -13,6 +13,7 @@ import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml"; import { useFlagMap } from "@calcom/features/flags/context/provider"; import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; import { IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants"; +import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import slugify from "@calcom/lib/slugify"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry"; @@ -34,6 +35,23 @@ type FormValues = z.infer; type SignupProps = inferSSRProps; +const getSafeCallbackUrl = (url: string | null) => { + if (!url) return null; + + let callbackUrl = url; + + if (/"\//.test(callbackUrl)) callbackUrl = callbackUrl.substring(1); + + // If not absolute URL, make it absolute + if (!/^https?:\/\//.test(callbackUrl)) { + callbackUrl = `${WEBAPP_URL}/${callbackUrl}`; + } + + const safeCallbackUrl = getSafeRedirectUrl(callbackUrl); + + return safeCallbackUrl; +}; + export default function Signup({ prepopulateFormValues, token, orgSlug }: SignupProps) { const searchParams = useSearchParams(); const telemetry = useTelemetry(); @@ -55,6 +73,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup throw new Error(err.message); } }; + const callbackUrl = getSafeCallbackUrl(searchParams.get("callbackUrl")); const signUp: SubmitHandler = async (data) => { await fetch("/api/auth/signup", { @@ -72,13 +91,10 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup .then(async () => { telemetry.event(telemetryEventTypes.signup, collectPageParameters()); const verifyOrGettingStarted = flags["email-verification"] ? "auth/verify-email" : "getting-started"; + await signIn<"credentials">("credentials", { ...data, - callbackUrl: `${ - searchParams?.get("callbackUrl") - ? `${WEBAPP_URL}/${searchParams.get("callbackUrl")}` - : `${WEBAPP_URL}/${verifyOrGettingStarted}` - }?from=signup`, + callbackUrl: `${callbackUrl ? callbackUrl : `${WEBAPP_URL}/${verifyOrGettingStarted}`}?from=signup`, }); }) .catch((err) => { @@ -157,9 +173,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup className="w-full justify-center" onClick={() => signIn("Cal.com", { - callbackUrl: searchParams?.get("callbackUrl") - ? `${WEBAPP_URL}/${searchParams.get("callbackUrl")}` - : `${WEBAPP_URL}/getting-started`, + callbackUrl: callbackUrl ? callbackUrl : `${WEBAPP_URL}/getting-started`, }) }> {t("login_instead")} diff --git a/apps/web/pages/teams/index.tsx b/apps/web/pages/teams/index.tsx index 392c54f59e..892e1bfedb 100644 --- a/apps/web/pages/teams/index.tsx +++ b/apps/web/pages/teams/index.tsx @@ -1,9 +1,11 @@ import type { GetServerSidePropsContext } from "next"; import { getLayout } from "@calcom/features/MainLayout"; +import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { TeamsListing } from "@calcom/features/ee/teams/components"; import { ShellMain } from "@calcom/features/shell/Shell"; import { WEBAPP_URL } from "@calcom/lib/constants"; +import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { Button } from "@calcom/ui"; @@ -41,6 +43,21 @@ function Teams() { export const getServerSideProps = async (context: GetServerSidePropsContext) => { const ssr = await ssrInit(context); await ssr.viewer.me.prefetch(); + const session = await getServerSession({ req: context.req, res: context.res }); + const token = context.query?.token; + const resolvedUrl = context.resolvedUrl; + + const callbackUrl = token ? getSafeRedirectUrl(`${WEBAPP_URL}${resolvedUrl}`) : null; + + if (!session) { + return { + redirect: { + destination: callbackUrl ? `/auth/login?callbackUrl=${callbackUrl}&teamInvite=true` : "/auth/login", + permanent: false, + }, + props: {}, + }; + } return { props: { trpcState: ssr.dehydrate() } }; }; diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index 2f2d9c374a..c2979a5ec2 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -45,6 +45,7 @@ "invite_team_individual_segment": "Invite individual", "invite_team_bulk_segment": "Bulk import", "invite_team_notifcation_badge": "Inv.", + "signin_or_signup_to_accept_invite": "You need to Sign in or Sign up to see team invitation.", "your_event_has_been_scheduled": "Your event has been scheduled", "your_event_has_been_scheduled_recurring": "Your recurring event has been scheduled", "accept_our_license": "Accept our license by changing the .env variable <1>NEXT_PUBLIC_LICENSE_CONSENT to '{{agree}}'.",