diff --git a/.env.example b/.env.example index 20d9aba8f1..8d41876043 100644 --- a/.env.example +++ b/.env.example @@ -356,7 +356,6 @@ E2E_TEST_OIDC_USER_PASSWORD= # provide a value between 0 and 100 to ensure the percentage of traffic # redirected from the legacy to the future pages AB_TEST_BUCKET_PROBABILITY=50 -APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED=0 APP_ROUTER_APPS_SLUG_SETUP_ENABLED=0 # whether we redirect to the future/apps/categories from /apps/categories or not APP_ROUTER_APPS_CATEGORIES_ENABLED=0 diff --git a/apps/web/abTest/middlewareFactory.ts b/apps/web/abTest/middlewareFactory.ts index 59e53e43d5..7d8d85fb88 100644 --- a/apps/web/abTest/middlewareFactory.ts +++ b/apps/web/abTest/middlewareFactory.ts @@ -5,7 +5,6 @@ import { NextResponse, URLPattern } from "next/server"; import { FUTURE_ROUTES_ENABLED_COOKIE_NAME, FUTURE_ROUTES_OVERRIDE_COOKIE_NAME } from "@calcom/lib/constants"; const ROUTES: [URLPattern, boolean][] = [ - ["/apps/installed/:category", process.env.APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED === "1"] as const, ["/apps/:slug/setup", process.env.APP_ROUTER_APPS_SLUG_SETUP_ENABLED === "1"] as const, ["/apps/categories", process.env.APP_ROUTER_APPS_CATEGORIES_ENABLED === "1"] as const, ["/apps/categories/:category", process.env.APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED === "1"] as const, diff --git a/apps/web/app/(use-page-wrapper)/apps/installed/[category]/page.tsx b/apps/web/app/(use-page-wrapper)/apps/installed/[category]/page.tsx new file mode 100644 index 0000000000..ff6d563bc9 --- /dev/null +++ b/apps/web/app/(use-page-wrapper)/apps/installed/[category]/page.tsx @@ -0,0 +1,31 @@ +import type { PageProps } from "app/_types"; +import { _generateMetadata } from "app/_utils"; +import { redirect } from "next/navigation"; +import { z } from "zod"; + +import { AppCategories } from "@calcom/prisma/enums"; + +import InstalledApps from "~/apps/installed/[category]/installed-category-view"; + +const querySchema = z.object({ + category: z.nativeEnum(AppCategories), +}); + +export const generateMetadata = async () => { + return await _generateMetadata( + (t) => t("installed_apps"), + (t) => t("manage_your_connected_apps") + ); +}; + +const InstalledAppsWrapper = async ({ params }: PageProps) => { + const parsedParams = querySchema.safeParse(params); + + if (!parsedParams.success) { + redirect("/apps/installed/calendar"); + } + + return ; +}; + +export default InstalledAppsWrapper; diff --git a/apps/web/app/future/apps/installed/page.tsx b/apps/web/app/(use-page-wrapper)/apps/installed/page.tsx similarity index 100% rename from apps/web/app/future/apps/installed/page.tsx rename to apps/web/app/(use-page-wrapper)/apps/installed/page.tsx diff --git a/apps/web/app/future/apps/installed/[category]/page.tsx b/apps/web/app/future/apps/installed/[category]/page.tsx deleted file mode 100644 index c20bbf0d32..0000000000 --- a/apps/web/app/future/apps/installed/[category]/page.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { withAppDirSsr } from "app/WithAppDirSsr"; -import { _generateMetadata } from "app/_utils"; -import { WithLayout } from "app/layoutHOC"; - -import { getServerSidePropsAppDir } from "@lib/apps/installed/[category]/getServerSideProps"; - -import Page from "~/apps/installed/[category]/installed-category-view"; - -export const generateMetadata = async () => { - return await _generateMetadata( - (t) => t("installed_apps"), - (t) => t("manage_your_connected_apps") - ); -}; - -const getData = withAppDirSsr(getServerSidePropsAppDir); - -export default WithLayout({ getLayout: null, getData, Page }); diff --git a/apps/web/lib/apps/installed/[category]/getServerSideProps.tsx b/apps/web/lib/apps/installed/[category]/getServerSideProps.tsx deleted file mode 100644 index 109032a239..0000000000 --- a/apps/web/lib/apps/installed/[category]/getServerSideProps.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import type { GetServerSidePropsContext } from "next"; -import { z } from "zod"; - -import { AppCategories } from "@calcom/prisma/enums"; - -export type querySchemaType = z.infer; - -export const querySchema = z.object({ - category: z.nativeEnum(AppCategories), -}); - -export async function getServerSideProps(ctx: GetServerSidePropsContext) { - // get return-to cookie and redirect if needed - const { cookies } = ctx.req; - - const returnTo = cookies["return-to"]; - - if (cookies && returnTo) { - ctx.res.setHeader("Set-Cookie", "return-to=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"); - const redirect = { - redirect: { - destination: `${returnTo}`, - permanent: false, - }, - } as const; - - return redirect; - } - - const params = querySchema.safeParse(ctx.params); - - if (!params.success) { - const notFound = { notFound: true } as const; - - return notFound; - } - - return { - props: { - category: params.data.category, - }, - }; -} - -export async function getServerSidePropsAppDir(ctx: GetServerSidePropsContext) { - // get return-to cookie and redirect if needed - const { cookies } = ctx.req; - - const returnTo = cookies["return-to"]; - - if (cookies && returnTo) { - const NextResponse = await import("next/server").then((mod) => mod.NextResponse); - const response = NextResponse.next(); - response.headers.set("Set-Cookie", "return-to=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"); - const redirect = { - redirect: { - destination: `${returnTo}`, - permanent: false, - }, - } as const; - - return redirect; - } - - const params = querySchema.safeParse(ctx.params); - - if (!params.success) { - const notFound = { notFound: true } as const; - - return notFound; - } - - return { - props: { - category: params.data.category, - }, - }; -} diff --git a/apps/web/lib/apps/installed/getServerSideProps.tsx b/apps/web/lib/apps/installed/getServerSideProps.tsx deleted file mode 100644 index a43490aea5..0000000000 --- a/apps/web/lib/apps/installed/getServerSideProps.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export async function getServerSideProps() { - return { redirect: { permanent: false, destination: "/apps/installed/calendar" } }; -} diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts index 69b4dd4dfb..2984493c00 100644 --- a/apps/web/middleware.ts +++ b/apps/web/middleware.ts @@ -63,21 +63,13 @@ const middleware = async (req: NextRequest): Promise> => { requestHeaders.set("x-csp-enforce", "true"); } - if (url.pathname.startsWith("/future/apps/installed")) { - const returnTo = req.cookies.get("return-to")?.value; - if (returnTo !== undefined) { - requestHeaders.set("Set-Cookie", "return-to=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"); + if (url.pathname.startsWith("/apps/installed")) { + const returnTo = req.cookies.get("return-to"); - let validPathname = returnTo; - - try { - validPathname = new URL(returnTo).pathname; - } catch (e) {} - - const nextUrl = url.clone(); - nextUrl.pathname = validPathname; - // TODO: Consider using responseWithHeaders here - return NextResponse.redirect(nextUrl, { headers: requestHeaders }); + if (returnTo?.value) { + const response = NextResponse.redirect(new URL(returnTo.value, req.url), { headers: requestHeaders }); + response.cookies.delete("return-to"); + return response; } } diff --git a/apps/web/modules/apps/installed/[category]/installed-category-view.tsx b/apps/web/modules/apps/installed/[category]/installed-category-view.tsx index ba392420aa..e59480a6db 100644 --- a/apps/web/modules/apps/installed/[category]/installed-category-view.tsx +++ b/apps/web/modules/apps/installed/[category]/installed-category-view.tsx @@ -8,11 +8,9 @@ import type { UpdateUsersDefaultConferencingAppParams } from "@calcom/features/a import DisconnectIntegrationModal from "@calcom/features/apps/components/DisconnectIntegrationModal"; import type { RemoveAppParams } from "@calcom/features/apps/components/DisconnectIntegrationModal"; import type { BulkUpdatParams } from "@calcom/features/eventtypes/components/BulkEditDefaultForEventsModal"; -import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { AppCategories } from "@calcom/prisma/enums"; import { trpc } from "@calcom/trpc/react"; -import type { inferSSRProps } from "@calcom/types/inferSSRProps"; import type { Icon } from "@calcom/ui"; import { AppSkeletonLoader as SkeletonLoader, @@ -23,7 +21,6 @@ import { } from "@calcom/ui"; import { QueryCell } from "@lib/QueryCell"; -import type { querySchemaType, getServerSideProps } from "@lib/apps/installed/[category]/getServerSideProps"; import { CalendarListContainer } from "@components/apps/CalendarListContainer"; import InstalledAppsLayout from "@components/apps/layouts/InstalledAppsLayout"; @@ -183,13 +180,13 @@ type ModalState = { teamId?: number; }; -export type PageProps = inferSSRProps; +type PageProps = { + category: AppCategories; +}; -export default function InstalledApps(props: PageProps) { - const searchParams = useCompatSearchParams(); +export default function InstalledApps({ category }: PageProps) { const { t } = useLocale(); const utils = trpc.useUtils(); - const category = searchParams?.get("category") as querySchemaType["category"]; const categoryList: AppCategories[] = Object.values(AppCategories).filter((category) => { // Exclude calendar and other from categoryList, we handle those slightly differently below return !(category in { other: null, calendar: null }); diff --git a/apps/web/pages/apps/installed/[category].tsx b/apps/web/pages/apps/installed/[category].tsx deleted file mode 100644 index 7a8e670ce1..0000000000 --- a/apps/web/pages/apps/installed/[category].tsx +++ /dev/null @@ -1,12 +0,0 @@ -import PageWrapper from "@components/PageWrapper"; - -import type { PageProps } from "~/apps/installed/[category]/installed-category-view"; -import InstalledApps from "~/apps/installed/[category]/installed-category-view"; - -const Page = (props: PageProps) => ; - -Page.PageWrapper = PageWrapper; - -export { getServerSideProps } from "@lib/apps/installed/[category]/getServerSideProps"; - -export default Page; diff --git a/apps/web/pages/apps/installed/index.tsx b/apps/web/pages/apps/installed/index.tsx deleted file mode 100644 index 02786d55a8..0000000000 --- a/apps/web/pages/apps/installed/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export { getServerSideProps } from "@lib/apps/installed/getServerSideProps"; - -function RedirectPage() { - return; -} - -export default RedirectPage; diff --git a/apps/web/scripts/vercel-app-router-deploy.sh b/apps/web/scripts/vercel-app-router-deploy.sh index 444c8aae1b..b6157d9f46 100755 --- a/apps/web/scripts/vercel-app-router-deploy.sh +++ b/apps/web/scripts/vercel-app-router-deploy.sh @@ -6,7 +6,6 @@ checkRoute () { # These conditionals are used to remove directories from the build that are not needed in production # This is to reduce the size of the build and prevent OOM errors -checkRoute "$APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED" app/future/apps/installed checkRoute "$APP_ROUTER_APPS_SLUG_SETUP_ENABLED" app/future/apps/\[slug\]/setup checkRoute "$APP_ROUTER_APPS_CATEGORIES_ENABLED" app/future/apps/categories checkRoute "$APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED" app/future/apps/categories/\[category\] diff --git a/turbo.json b/turbo.json index b0880ec5c4..40a707ff31 100644 --- a/turbo.json +++ b/turbo.json @@ -242,7 +242,6 @@ "API_KEY_PREFIX", "APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED", "APP_ROUTER_APPS_CATEGORIES_ENABLED", - "APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED", "APP_ROUTER_APPS_SLUG_SETUP_ENABLED", "APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED", "APP_ROUTER_AUTH_LOGIN_ENABLED",