From 6468565d40038100954c68d3ce937a2d9ff46f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Pichon?= Date: Thu, 23 Jan 2025 11:21:53 +0100 Subject: [PATCH] fix: merge query for no-hash routes --- packages/iframe-coordinator/src/HostRouter.ts | 10 +++++- .../src/specs/HostRouter.spec.ts | 36 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/iframe-coordinator/src/HostRouter.ts b/packages/iframe-coordinator/src/HostRouter.ts index 7440d75..e67c01c 100644 --- a/packages/iframe-coordinator/src/HostRouter.ts +++ b/packages/iframe-coordinator/src/HostRouter.ts @@ -179,10 +179,18 @@ function applyRoute(urlStr: string, route: string): string { const newUrl = new URL(urlStr, window.location.href); if (newUrl.hash) { const baseClientRoute = stripTrailingSlash(newUrl.hash); + // This supports non-standard query params in hash route directly newUrl.hash = `${baseClientRoute}/${route}`; } else { const baseClientPath = stripTrailingSlash(newUrl.pathname); - newUrl.pathname = `${baseClientPath}/${route}`; + // Here, we merge host query params and route query params + const routeUrl = new URL(route, window.location.href); + newUrl.pathname = `${baseClientPath}${routeUrl.pathname}`; + const query = new URLSearchParams(newUrl.search); + for (const [key, value] of routeUrl.searchParams) { + query.set(key, value); + } + newUrl.search = query.toString(); } return newUrl.toString(); } diff --git a/packages/iframe-coordinator/src/specs/HostRouter.spec.ts b/packages/iframe-coordinator/src/specs/HostRouter.spec.ts index 52c7cef..950ad2b 100644 --- a/packages/iframe-coordinator/src/specs/HostRouter.spec.ts +++ b/packages/iframe-coordinator/src/specs/HostRouter.spec.ts @@ -17,6 +17,14 @@ describe("HostRouter", () => { url: "http://example.com/my/pushstate/app/?query=works", assignedRoute: "noHash", }, + noClientHashNoQuery: { + url: "http://example.com/my/pushstate/app/noquery/", + assignedRoute: "noHash/noQuery", + }, + noClientHashMergeQuery: { + url: "http://example.com/my/pushstate/app/mergequery/?alpha=true", + assignedRoute: "noHash/mergeQuery", + }, withSandboxAndAllow: { url: clientUrl, assignedRoute: "route/two", @@ -85,6 +93,34 @@ describe("HostRouter", () => { expect(clientInfo.id).toBe("noClientHash"); }); + it("should append to the path when the client url has no hash and no query", () => { + const clientInfo = hostRouter.getClientTarget( + "noHash/noQuery/foo/bar?query=works", + ); + if (!clientInfo) { + fail(); + return; + } + expect(clientInfo.url).toBe( + "http://example.com/my/pushstate/app/noquery/foo/bar?query=works", + ); + expect(clientInfo.id).toBe("noClientHashNoQuery"); + }); + + it("should append to the path when the client url has no hash and merging query", () => { + const clientInfo = hostRouter.getClientTarget( + "noHash/mergeQuery/foo/bar?beta=true", + ); + if (!clientInfo) { + fail(); + return; + } + expect(clientInfo.url).toBe( + "http://example.com/my/pushstate/app/mergequery/foo/bar?alpha=true&beta=true", + ); + expect(clientInfo.id).toBe("noClientHashMergeQuery"); + }); + it('should return "allow" and "sandbox" config options if they exist', () => { const clientInfo = hostRouter.getClientTarget("route/two/"); if (!clientInfo) {