From b516a2af4427b16cdf0860ae8bc8c3d308398458 Mon Sep 17 00:00:00 2001 From: Hariom Balhara Date: Wed, 19 Jul 2023 12:45:05 +0530 Subject: [PATCH] Get OAuth working for local (#10054) Co-authored-by: Shivam Kalra --- apps/web/next.config.js | 21 +++++++++++++++++++ packages/app-store/googlecalendar/api/add.ts | 4 ++-- .../app-store/googlecalendar/api/callback.ts | 4 ++-- packages/lib/constants.ts | 8 ++++++- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 8b9f012a7a..6c38dddbb1 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -446,6 +446,27 @@ const nextConfig = { destination: "/apps/installed/conferencing", permanent: true, }, + // OAuth callbacks when sent to localhost:3000(w would be expected) should be redirected to corresponding to WEBAPP_URL + ...(process.env.NODE_ENV === "development" && + // Safer to enable the redirect only when the user is opting to test out organizations + process.env.ORGANIZATIONS_ENABLED && + // Prevent infinite redirect by checking that we aren't already on localhost + process.env.NEXT_PUBLIC_WEBAPP_URL !== "http://localhost:3000" + ? [ + { + has: [ + { + type: "header", + key: "host", + value: "localhost:3000", + }, + ], + source: "/api/integrations/:args*", + destination: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/api/integrations/:args*`, + permanent: false, + }, + ] + : []), ]; if (process.env.NEXT_PUBLIC_WEBAPP_URL === "https://app.cal.com") { diff --git a/packages/app-store/googlecalendar/api/add.ts b/packages/app-store/googlecalendar/api/add.ts index 7860bb91a4..3f377c3eb4 100644 --- a/packages/app-store/googlecalendar/api/add.ts +++ b/packages/app-store/googlecalendar/api/add.ts @@ -1,7 +1,7 @@ import { google } from "googleapis"; import type { NextApiRequest, NextApiResponse } from "next"; -import { WEBAPP_URL } from "@calcom/lib/constants"; +import { WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants"; import { encodeOAuthState } from "../../_utils/encodeOAuthState"; import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug"; @@ -22,7 +22,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) if (typeof appKeys.client_secret === "string") client_secret = appKeys.client_secret; if (!client_id) return res.status(400).json({ message: "Google client_id missing." }); if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." }); - const redirect_uri = WEBAPP_URL + "/api/integrations/googlecalendar/callback"; + const redirect_uri = WEBAPP_URL_FOR_OAUTH + "/api/integrations/googlecalendar/callback"; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri); const authUrl = oAuth2Client.generateAuthUrl({ diff --git a/packages/app-store/googlecalendar/api/callback.ts b/packages/app-store/googlecalendar/api/callback.ts index ce509954df..61c40be381 100644 --- a/packages/app-store/googlecalendar/api/callback.ts +++ b/packages/app-store/googlecalendar/api/callback.ts @@ -1,7 +1,7 @@ import { google } from "googleapis"; import type { NextApiRequest, NextApiResponse } from "next"; -import { WEBAPP_URL, CAL_URL } from "@calcom/lib/constants"; +import { WEBAPP_URL_FOR_OAUTH, CAL_URL } from "@calcom/lib/constants"; import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import prisma from "@calcom/prisma"; @@ -30,7 +30,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) if (!client_id) return res.status(400).json({ message: "Google client_id missing." }); if (!client_secret) return res.status(400).json({ message: "Google client_secret missing." }); - const redirect_uri = WEBAPP_URL + "/api/integrations/googlecalendar/callback"; + const redirect_uri = WEBAPP_URL_FOR_OAUTH + "/api/integrations/googlecalendar/callback"; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uri); diff --git a/packages/lib/constants.ts b/packages/lib/constants.ts index 50b9d1f4e0..7b8ea383cd 100644 --- a/packages/lib/constants.ts +++ b/packages/lib/constants.ts @@ -2,6 +2,8 @@ const VERCEL_URL = process.env.NEXT_PUBLIC_VERCEL_URL ? `https://${process.env.N const RAILWAY_STATIC_URL = process.env.RAILWAY_STATIC_URL ? `https://${process.env.RAILWAY_STATIC_URL}` : ""; const HEROKU_URL = process.env.HEROKU_APP_NAME ? `https://${process.env.HEROKU_APP_NAME}.herokuapp.com` : ""; const RENDER_URL = process.env.RENDER_EXTERNAL_URL ? `https://${process.env.RENDER_EXTERNAL_URL}` : ""; +export const IS_PRODUCTION = process.env.NODE_ENV === "production"; + export const WEBAPP_URL = process.env.NEXT_PUBLIC_WEBAPP_URL || VERCEL_URL || @@ -9,6 +11,11 @@ export const WEBAPP_URL = HEROKU_URL || RENDER_URL || "http://localhost:3000"; + +// OAuth needs to have HTTPS(which is not generally setup locally) and a valid tld(*.local isn't a valid tld) +// So for development purpose, we would stick to localhost only +export const WEBAPP_URL_FOR_OAUTH = IS_PRODUCTION ? WEBAPP_URL : "http://localhost:3000"; + /** @deprecated use `WEBAPP_URL` */ export const BASE_URL = WEBAPP_URL; export const WEBSITE_URL = process.env.NEXT_PUBLIC_WEBSITE_URL || "https://cal.com"; @@ -39,7 +46,6 @@ export const IS_SELF_HOSTED = !( new URL(WEBAPP_URL).hostname.endsWith(".cal.dev") || new URL(WEBAPP_URL).hostname.endsWith(".cal.com") ); export const EMBED_LIB_URL = process.env.NEXT_PUBLIC_EMBED_LIB_URL || `${WEBAPP_URL}/embed/embed.js`; -export const IS_PRODUCTION = process.env.NODE_ENV === "production"; export const TRIAL_LIMIT_DAYS = 14; export const HOSTED_CAL_FEATURES = process.env.NEXT_PUBLIC_HOSTED_CAL_FEATURES || !IS_SELF_HOSTED;