diff --git a/apps/web/lib/buildLegacyCtx.tsx b/apps/web/lib/buildLegacyCtx.tsx index 14430210a3..22817f0cf6 100644 --- a/apps/web/lib/buildLegacyCtx.tsx +++ b/apps/web/lib/buildLegacyCtx.tsx @@ -26,6 +26,25 @@ const buildLegacyCookies = (cookies: ReadonlyRequestCookies) => { return createProxifiedObject(cookiesObject); }; +function decodeParams(params: Params): Params { + return Object.entries(params).reduce((acc, [key, value]) => { + // Handle array values + if (Array.isArray(value)) { + acc[key] = value.map((item) => decodeURIComponent(item)); + return acc; + } + + // Handle single values + if (value !== undefined) { + acc[key] = decodeURIComponent(value); + } else { + acc[key] = value; + } + + return acc; + }, {} as Params); +} + export const buildLegacyCtx = ( headers: ReadonlyHeaders, cookies: ReadonlyRequestCookies, @@ -34,7 +53,10 @@ export const buildLegacyCtx = ( ) => { return { query: { ...searchParams, ...params }, - params, + // decoding is required to be backward compatible with Pages Router + // because Next.js App Router does not auto-decode query params while Pages Router does + // e.g., params: { name: "John%20Doe" } => params: { name: "John Doe" } + params: decodeParams(params), req: { headers: buildLegacyHeaders(headers), cookies: buildLegacyCookies(cookies) }, res: new Proxy(Object.create(null), { // const { req, res } = ctx - valid diff --git a/apps/web/server/lib/[user]/getServerSideProps.ts b/apps/web/server/lib/[user]/getServerSideProps.ts index 0bacd5fec0..e9468f80a6 100644 --- a/apps/web/server/lib/[user]/getServerSideProps.ts +++ b/apps/web/server/lib/[user]/getServerSideProps.ts @@ -106,6 +106,9 @@ export const getServerSideProps: GetServerSideProps = async (cont if (isDynamicGroup) { const destinationUrl = `/${usernameList.join("+")}/dynamic`; + + // EXAMPLE - context.params: { orgSlug: 'acme', user: 'member0+owner1' } + // EXAMPLE - context.query: { redirect: 'undefined', orgRedirection: 'undefined', user: 'member0+owner1' } const originalQueryString = new URLSearchParams(context.query as Record).toString(); const destinationWithQuery = `${destinationUrl}?${originalQueryString}`; log.debug(`Dynamic group detected, redirecting to ${destinationUrl}`); diff --git a/packages/lib/defaultEvents.ts b/packages/lib/defaultEvents.ts index 81f7422252..8a1061a78e 100644 --- a/packages/lib/defaultEvents.ts +++ b/packages/lib/defaultEvents.ts @@ -178,7 +178,7 @@ export const getUsernameList = (users: string | string[] | undefined): string[] // So, even though this code handles even if individual user is dynamic link, that isn't a possibility right now. users = arrayCast(users); - const allUsers = users.map((user) => user.replace(/( |%20|%2b)/g, "+").split("+")).flat(); + const allUsers = users.map((user) => user.replace(/( |%20|%2b)/gi, "+").split("+")).flat(); return Array.prototype.concat(...allUsers.map((userSlug) => slugify(userSlug))); };