From 5106a7ebc7da99978ae6eb55c06df128573f4f66 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:12:13 +0100 Subject: [PATCH] Drop support for basepath in hash based routing --- src/sdk.js | 54 +++++++++++++++++++++++++++---------------------- src/sdk.spec.js | 27 +++++++++++++------------ 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/sdk.js b/src/sdk.js index 0e6747d98..381f16aea 100644 --- a/src/sdk.js +++ b/src/sdk.js @@ -96,53 +96,59 @@ class OpenForm { CSPNonce.setValue(CSPNonceValue); initialiseSentry(sentryDSN, sentryEnv); - // ensure that the basename has no trailing slash (for react router) let pathname; if (!this.useHashRouting) { pathname = basePath || window.location.pathname; if (pathname.endsWith('/')) { + // ensure that the basename has no trailing slash (for react router) pathname = pathname.slice(0, pathname.length - 1); } } else { pathname = ''; } this.basePath = pathname; + this.makeRedirect(); this.calculateClientBaseUrl(); } - calculateClientBaseUrl() { - // calculate the client-side base URL, as this is recorded in backend calls for - // submissions. - const clientBase = resolvePath(this.basePath).pathname; // has leading slash - this.clientBaseUrl = new URL(clientBase, window.location.origin).href; - } - - async init() { - ReactModal.setAppElement(this.targetNode); - + makeRedirect() { + // Perform pre-redirect based on this action: this is decoupled from the backend const query = new URLSearchParams(document.location.search); const action = query.get('_of_action'); if (action) { - // Perform pre-redirect based on this action: this is decoupled from the backend - // as actionParams is in the form `q1%3Dquery1%26q2%3Dquery2`, we first URL decode and then parse it: const actionParams = new URLSearchParams(decodeURIComponent(query.get('_of_action_params'))); query.delete('_of_action'); query.delete('_of_action_params'); - // This contains the origin and base path that OF does not control (e.g. when hosted on a CMS which already has a basepath), - // alongside with the remaining query parameters that aren't related to OF. - const unrelatedUrlPart = `${window.location.origin}${window.location.pathname}${ - query.size ? '?' + query : '' - }`; - // This is the part that we handle: optional hash based prefix followed by the reidrect path - const openFormsPart = `${this.useHashRouting ? '/#' : ''}/${getRedirectPathname( - action, - actionParams - )}`; - const newUrl = `${unrelatedUrlPart}${openFormsPart}`; + const redirectPath = getRedirectPathname(action, actionParams); + + let newUrl; + if (!this.useHashRouting) { + newUrl = `${window.location.origin}${window.location.pathname}/${redirectPath}${ + query.size ? '?' + query : '' + }`; + } else { + // No pathname with hash based routing + // TODO use query.size once we have better browser support + newUrl = `${window.location.origin}/${ + [...query].length ? '?' + query : '' + }#/${redirectPath}`; + } + window.history.replaceState(null, '', newUrl); } + } + + calculateClientBaseUrl() { + // calculate the client-side base URL, as this is recorded in backend calls for + // submissions. + const clientBase = resolvePath(this.basePath).pathname; // has leading slash + this.clientBaseUrl = new URL(clientBase, window.location.origin).href; + } + + async init() { + ReactModal.setAppElement(this.targetNode); this.url = `${this.baseUrl}forms/${this.formId}`; this.targetNode.textContent = `Loading form...`; diff --git a/src/sdk.spec.js b/src/sdk.spec.js index e2ca12b08..573a17489 100644 --- a/src/sdk.spec.js +++ b/src/sdk.spec.js @@ -125,18 +125,17 @@ describe('OpenForm', () => { expect(form.clientBaseUrl).toEqual('http://localhost/some-subpath'); }); - it('should correctly set the formUrl (hash based routing)', () => { + it("shouldn't take basepath into account (hash based routing)", () => { mswServer.use(...apiMocks); - window.history.pushState({}, 'Dummy title', '/some-server-side/path'); + window.history.pushState({}, 'Dummy title', '/some-path'); const formRoot = document.createElement('div'); const form = new OpenForm(formRoot, { baseUrl: BASE_URL, - basePath: '/some-subpath/', formId: '81a22589-abce-4147-a2a3-62e9a56685aa', useHashRouting: true, }); - expect(form.clientBaseUrl).toEqual('http://localhost/some-server-side/path#/some-subpath'); + expect(form.clientBaseUrl).toEqual('http://localhost/'); }); it.each([ @@ -146,7 +145,7 @@ describe('OpenForm', () => { ], [ '/some-subpath?_of_action=afspraak-maken', - 'http://localhost/some-subpath/afspraak-maken/producten', + 'http://localhost/some-subpath/afspraak-maken/producten', // SDK redirects to producten ], [ '/some-subpath?_of_action=cosign&_of_action_params=submission_uuid%3Dabc', @@ -175,17 +174,20 @@ describe('OpenForm', () => { it.each([ [ - '/some-subpath?_of_action=afspraak-annuleren', - 'http://localhost/#/some-subpath/afspraak-annuleren', + '/?_of_action=afspraak-annuleren&unrelated_q=1', + 'http://localhost/?unrelated_q=1#/afspraak-annuleren', ], - ['/some-subpath?_of_action=afspraak-maken', 'http://localhost/#/some-subpath/afspraak-maken'], [ - '/some-subpath?_of_action=cosign&_of_action_params=submission_uuid%3Dabc', - 'http://localhost/#/some-subpath/cosign?submission_uuid=abc', + '/?_of_action=afspraak-maken&unrelated_q=1', + 'http://localhost/?unrelated_q=1#/afspraak-maken/producten', // SDK redirects to producten ], [ - '/some-subpath?_of_action=stap&_of_action_params=next_step%3Dstep-1', - 'http://localhost/#/some-subpath/stap/step-1', // SDK redirects to start page + '/?_of_action=cosign&_of_action_params=submission_uuid%3Dabc&unrelated_q=1', + 'http://localhost/?unrelated_q=1#/cosign?submission_uuid=abc', + ], + [ + '/?_of_action=stap&_of_action_params=next_step%3Dstep-1&unrelated_q=1', + 'http://localhost/?unrelated_q=1#/startpagina', // SDK redirects to start page ], ])( 'should handle action redirects correctly (hash based routing)', @@ -195,7 +197,6 @@ describe('OpenForm', () => { window.history.pushState(null, '', initialUrl); const form = new OpenForm(formRoot, { baseUrl: BASE_URL, - basePath: '/some-subpath', formId: '81a22589-abce-4147-a2a3-62e9a56685aa', useHashRouting: true, lang: 'nl',