Skip to content
This repository was archived by the owner on Jan 28, 2025. It is now read-only.

Commit 58001fc

Browse files
authored
fix(core): handle external redirect destinations with query parameters correctly (#1744)
1 parent 96297b2 commit 58001fc

File tree

3 files changed

+22
-16
lines changed

3 files changed

+22
-16
lines changed

packages/libs/core/src/match.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ export function matchPath(path: string, source: string): Match {
2222
*/
2323
export function compileDestination(
2424
destination: string,
25-
params: object
25+
params: any
2626
): string | null {
2727
try {
2828
const destinationLowerCase = destination.toLowerCase();
2929
if (
3030
destinationLowerCase.startsWith("https://") ||
3131
destinationLowerCase.startsWith("http://")
3232
) {
33-
// Handle external URLs
34-
const { origin, pathname } = new URL(destination);
33+
// Handle external URL redirects
34+
const { origin, pathname, search } = new URL(destination);
3535
const toPath = compile(pathname, { encode: encodeURIComponent });
36-
const compiledDestination = `${origin}${toPath(params)}`;
36+
const compiledDestination = `${origin}${toPath(params)}${search}`;
3737

3838
// Remove trailing slash if original destination didn't have it
3939
if (!destination.endsWith("/") && compiledDestination.endsWith("/")) {

packages/libs/core/src/route/redirect.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ export async function getLanguageRedirectPath(
147147

148148
/**
149149
* Get the redirect of the given path, if it exists.
150-
* @param path
151-
* @param manifest
150+
* @param request
151+
* @param routesManifest
152152
*/
153153
export function getRedirectPath(
154154
request: Request,

packages/libs/core/tests/route/redirect.test.ts

+16-10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ describe("Redirector Tests", () => {
3636
destination: "https://example.com",
3737
statusCode: 308
3838
},
39+
{
40+
source: "/external-2",
41+
destination: "https://example.com/?a=b",
42+
statusCode: 308
43+
},
3944
{
4045
source: "/invalid-destination",
4146
destination: "ftp://example.com",
@@ -46,16 +51,17 @@ describe("Redirector Tests", () => {
4651
});
4752

4853
it.each`
49-
path | expectedRedirect | expectedStatusCode
50-
${"/a"} | ${"/b"} | ${308}
51-
${"/c"} | ${"/d"} | ${302}
52-
${"/old-blog/abc"} | ${"/news/abc"} | ${308}
53-
${"/old-users/1234"} | ${"/users/1234"} | ${307}
54-
${"/old-users/abc"} | ${null} | ${null}
55-
${"/external"} | ${"https://example.com"} | ${308}
56-
${"/invalid-destination"} | ${null} | ${null}
57-
${"/en/a"} | ${"/en/b"} | ${308}
58-
${"/fr/a"} | ${"/fr/b"} | ${308}
54+
path | expectedRedirect | expectedStatusCode
55+
${"/a"} | ${"/b"} | ${308}
56+
${"/c"} | ${"/d"} | ${302}
57+
${"/old-blog/abc"} | ${"/news/abc"} | ${308}
58+
${"/old-users/1234"} | ${"/users/1234"} | ${307}
59+
${"/old-users/abc"} | ${null} | ${null}
60+
${"/external"} | ${"https://example.com"} | ${308}
61+
${"/external-2"} | ${"https://example.com/?a=b"} | ${308}
62+
${"/invalid-destination"} | ${null} | ${null}
63+
${"/en/a"} | ${"/en/b"} | ${308}
64+
${"/fr/a"} | ${"/fr/b"} | ${308}
5965
`(
6066
"redirects path $path to $expectedRedirect",
6167
({ path, expectedRedirect, expectedStatusCode }) => {

0 commit comments

Comments
 (0)