From d98e45c7a6c0f09e33a1f50d94c726e975c80ed8 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:37:54 +0100 Subject: [PATCH] WIP --- src/components/routingActions.js | 17 ++++++++++--- src/sdk.js | 42 ++++++++++++++++++++------------ src/sdk.spec.js | 27 +++++++++----------- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/components/routingActions.js b/src/components/routingActions.js index a86ad6ec7..fc7988d81 100644 --- a/src/components/routingActions.js +++ b/src/components/routingActions.js @@ -12,9 +12,20 @@ const ROUTES_MAP = { stap: validateActionArgs(stepSlug => `stap/${stepSlug}`), }; -export const getRedirectPathname = (action, actionArgs) => { - if (typeof actionArgs === 'string') { - return ROUTES_MAP[action](...actionArgs.split(',')); +export const getRedirectPathname = (action, actionParams) => { + switch (action) { + case 'cosign': + return `cosign?submission_uuid=${actionParams.get('submission_uuid')}`; + case 'afspraak-annuleren': + return 'afspraak-annuleren'; + case 'afspraak-maken': + return 'afspraak-maken'; + case 'stap': + return `stap/${actionParams.get('next_step')}`; + } + + if (typeof actionParams === 'string') { + return ROUTES_MAP[action](...actionParams.split(',')); } return ROUTES_MAP[action](); }; diff --git a/src/sdk.js b/src/sdk.js index 152964d7f..0e6747d98 100644 --- a/src/sdk.js +++ b/src/sdk.js @@ -97,9 +97,14 @@ class OpenForm { initialiseSentry(sentryDSN, sentryEnv); // ensure that the basename has no trailing slash (for react router) - let pathname = basePath || window.location.pathname; - if (pathname.endsWith('/')) { - pathname = pathname.slice(0, pathname.length - 1); + let pathname; + if (!this.useHashRouting) { + pathname = basePath || window.location.pathname; + if (pathname.endsWith('/')) { + pathname = pathname.slice(0, pathname.length - 1); + } + } else { + pathname = ''; } this.basePath = pathname; this.calculateClientBaseUrl(); @@ -109,26 +114,33 @@ class OpenForm { // calculate the client-side base URL, as this is recorded in backend calls for // submissions. const clientBase = resolvePath(this.basePath).pathname; // has leading slash - const prefix = this.useHashRouting ? window.location.pathname : ''; // may have trailing slash - this.clientBaseUrl = new URL( - this.useHashRouting ? `${prefix}#${clientBase}` : clientBase, - window.location.origin - ).href; + this.clientBaseUrl = new URL(clientBase, window.location.origin).href; } async init() { ReactModal.setAppElement(this.targetNode); const query = new URLSearchParams(document.location.search); - const action = query.get('_action'); + const action = query.get('_of_action'); if (action) { // Perform pre-redirect based on this action: this is decoupled from the backend - const actionParams = query.get('_action_params'); - query.delete('_action'); - query.delete('_action_params'); - const newUrl = `${document.location.origin}${this.useHashRouting ? '/#' : ''}${ - this.basePath - }/${getRedirectPathname(action, actionParams)}${query.size ? '?' + query : ''}`; + + // 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}`; window.history.replaceState(null, '', newUrl); } diff --git a/src/sdk.spec.js b/src/sdk.spec.js index 327edb8be..e2ca12b08 100644 --- a/src/sdk.spec.js +++ b/src/sdk.spec.js @@ -141,20 +141,20 @@ describe('OpenForm', () => { it.each([ [ - '/some-subpath?_action=afspraak-annuleren', + '/some-subpath?_of_action=afspraak-annuleren', 'http://localhost/some-subpath/afspraak-annuleren', ], [ - '/some-subpath?_action=afspraak-maken', + '/some-subpath?_of_action=afspraak-maken', 'http://localhost/some-subpath/afspraak-maken/producten', ], [ - '/some-subpath?_action=cosign&_action_params=check', - 'http://localhost/some-subpath/cosign/check', + '/some-subpath?_of_action=cosign&_of_action_params=submission_uuid%3Dabc', + 'http://localhost/some-subpath/cosign?submission_uuid=abc', ], [ - '/some-subpath?_action=stap&_action_params=step-1', - 'http://localhost/some-subpath/stap/startpagina', // SDK redirects to start page + '/some-subpath?_of_action=stap&_of_action_params=next_step%3Dstep-1', + 'http://localhost/some-subpath/startpagina', // SDK redirects to start page ], ])('should handle action redirects correctly', async (initialUrl, expected) => { mswServer.use(...apiMocks); @@ -175,20 +175,17 @@ describe('OpenForm', () => { it.each([ [ - '/some-subpath?_action=afspraak-annuleren', + '/some-subpath?_of_action=afspraak-annuleren', 'http://localhost/#/some-subpath/afspraak-annuleren', ], + ['/some-subpath?_of_action=afspraak-maken', 'http://localhost/#/some-subpath/afspraak-maken'], [ - '/some-subpath?_action=afspraak-maken', - 'http://localhost/#/some-subpath/afspraak-maken/producten', + '/some-subpath?_of_action=cosign&_of_action_params=submission_uuid%3Dabc', + 'http://localhost/#/some-subpath/cosign?submission_uuid=abc', ], [ - '/some-subpath?_action=cosign&_action_params=check', - 'http://localhost/#/some-subpath/cosign/check', - ], - [ - '/some-subpath?_action=stap&_action_params=step-1', - 'http://localhost/#/some-subpath/startpagina', // SDK redirects to start page + '/some-subpath?_of_action=stap&_of_action_params=next_step%3Dstep-1', + 'http://localhost/#/some-subpath/stap/step-1', // SDK redirects to start page ], ])( 'should handle action redirects correctly (hash based routing)',