From 222e9b6c0cd71846a06047513df908b98c40434e Mon Sep 17 00:00:00 2001 From: "me@jeffersonbledsoe.com" Date: Wed, 31 May 2023 11:12:37 +0100 Subject: [PATCH 1/6] Strip `++api++` from location changes --- src/middleware/blacklistRoutes.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/middleware/blacklistRoutes.js b/src/middleware/blacklistRoutes.js index 3ac863babc..0d6ad295ae 100644 --- a/src/middleware/blacklistRoutes.js +++ b/src/middleware/blacklistRoutes.js @@ -8,18 +8,30 @@ const blacklistRoutes = ({ dispatch, getState }) => (next) => (action) => { switch (action.type) { case '@@router/LOCATION_CHANGE': - const { pathname } = action.payload.location; + let { pathname } = action.payload.location; const { externalRoutes = [] } = config.settings; const route = externalRoutes.find((route) => matchPath(pathname, route.match), ); + let actionToSend = action; + if (pathname.startsWith('/++api++')) { + actionToSend.payload.location.pathname = actionToSend.payload.location.pathname.substring( + 8, + ); + // To handle the `window.location.replace` + pathname = actionToSend.payload.location.pathname; + if (window.history) { + window.history.replaceState(window.history.state, '', pathname); + } + } + if (!route) { - return next(action); + return next(actionToSend); } else { window.location.replace( - route.url ? route.url(action.payload) : pathname, + route.url ? route.url(actionToSend.payload) : pathname, ); } break; From 4638fa90fbee60986001fdf0e8d6098324f4b415 Mon Sep 17 00:00:00 2001 From: "me@jeffersonbledsoe.com" Date: Wed, 7 Jun 2023 17:25:23 +0100 Subject: [PATCH 2/6] Incorporate changes from #4821 with fixes for client transitions, SSR'd pages and support for other 3XX responses --- src/components/theme/View/View.jsx | 13 +++++++++++-- src/helpers/Api/Api.js | 12 ++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/components/theme/View/View.jsx b/src/components/theme/View/View.jsx index 0fb916922b..33d4f2e2c7 100644 --- a/src/components/theme/View/View.jsx +++ b/src/components/theme/View/View.jsx @@ -203,8 +203,17 @@ class View extends Component { */ render() { const { views } = config; - if (this.props.error && this.props.error.code === 301) { - const redirect = flattenToAppURL(this.props.error.url).split('?')[0]; + const status = __SERVER__ + ? this.props.error?.status + : this.props.error?.code; + // Checking to see if it's a 3XX HTTP status code. error.status only works on the server + if (status?.toString()?.[0] === '3') { + const redirectUrl = __SERVER__ + ? this.props.error.response.headers.location + : this.props.error.url; + let redirect = flattenToAppURL(redirectUrl); + // We can hit situations where we end up being redirected to an api route. We don't want that so lets remove ++api++. + redirect = redirect.replace('/++api++', ''); return ; } else if (this.props.error && !this.props.connectionRefused) { let FoundView; diff --git a/src/helpers/Api/Api.js b/src/helpers/Api/Api.js index c91a667ea4..11dad7aea2 100644 --- a/src/helpers/Api/Api.js +++ b/src/helpers/Api/Api.js @@ -80,6 +80,10 @@ class Api { Object.keys(headers).forEach((key) => request.set(key, headers[key])); + if (__SERVER__ && checkUrl && ['get', 'head'].includes(method)) { + request.redirects(0); + } + if (data) { request.send(data); } @@ -104,6 +108,14 @@ class Api { url: request.xhr.responseURL, }); } + + if (err?.status[0] === 3) { + return reject({ + code: err.status, + url: err.response.headers.location, + }); + } + return err ? reject(err) : resolve(response.body || response.text); }); }); From 87ff1f561788c40809934edc12e2c0c683736522 Mon Sep 17 00:00:00 2001 From: "me@jeffersonbledsoe.com" Date: Wed, 7 Jun 2023 17:27:36 +0100 Subject: [PATCH 3/6] changelog --- news/4834.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/4834.feature diff --git a/news/4834.feature b/news/4834.feature new file mode 100644 index 0000000000..91603c7047 --- /dev/null +++ b/news/4834.feature @@ -0,0 +1 @@ +Fix ++api++ in redirections @JeffersonBledsoe @mamico From 781127643099d6040f95075bb6188b597dc47548 Mon Sep 17 00:00:00 2001 From: "me@jeffersonbledsoe.com" Date: Wed, 7 Jun 2023 18:55:45 +0100 Subject: [PATCH 4/6] Fix tests --- src/components/theme/View/View.test.jsx | 1 + src/helpers/Api/Api.plone.rest.test.js | 1 + src/helpers/Api/Api.test.js | 1 + 3 files changed, 3 insertions(+) diff --git a/src/components/theme/View/View.test.jsx b/src/components/theme/View/View.test.jsx index 66d02014c6..338dc192b4 100644 --- a/src/components/theme/View/View.test.jsx +++ b/src/components/theme/View/View.test.jsx @@ -22,6 +22,7 @@ beforeAll(() => { }); config.settings.publicURL = 'https://plone.org'; }); +global.__SERVER__ = true; // eslint-disable-line no-underscore-dangle const mockStore = configureStore(); diff --git a/src/helpers/Api/Api.plone.rest.test.js b/src/helpers/Api/Api.plone.rest.test.js index 80e18682d1..71383caecd 100644 --- a/src/helpers/Api/Api.plone.rest.test.js +++ b/src/helpers/Api/Api.plone.rest.test.js @@ -18,6 +18,7 @@ beforeAll(() => { const api = new Api(); const { settings } = config; +global.__SERVER__ = true; // eslint-disable-line no-underscore-dangle test('get request', () => {}); diff --git a/src/helpers/Api/Api.test.js b/src/helpers/Api/Api.test.js index c877f1724f..bb7f072230 100644 --- a/src/helpers/Api/Api.test.js +++ b/src/helpers/Api/Api.test.js @@ -24,6 +24,7 @@ beforeAll(() => { const api = new Api(); const { settings } = config; +global.__SERVER__ = true; // eslint-disable-line no-underscore-dangle test('get request', () => {}); From 774bbac9a9dcc532e21813b506aeeeeb4fa9045b Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Fri, 22 Mar 2024 17:08:50 +0100 Subject: [PATCH 5/6] move changelog --- {news => packages/volto/news}/4834.feature | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {news => packages/volto/news}/4834.feature (100%) diff --git a/news/4834.feature b/packages/volto/news/4834.feature similarity index 100% rename from news/4834.feature rename to packages/volto/news/4834.feature From 8fdab9f331e66fb6a58b3fb8221246574d66d11a Mon Sep 17 00:00:00 2001 From: David Glick Date: Mon, 13 May 2024 17:13:52 -0700 Subject: [PATCH 6/6] Tidy checks for redirect status codes --- packages/volto/news/4834.bugfix | 1 + packages/volto/news/4834.feature | 1 - packages/volto/src/components/theme/View/View.jsx | 15 ++++----------- packages/volto/src/helpers/Api/Api.js | 2 +- 4 files changed, 6 insertions(+), 13 deletions(-) create mode 100644 packages/volto/news/4834.bugfix delete mode 100644 packages/volto/news/4834.feature diff --git a/packages/volto/news/4834.bugfix b/packages/volto/news/4834.bugfix new file mode 100644 index 0000000000..c083e89766 --- /dev/null +++ b/packages/volto/news/4834.bugfix @@ -0,0 +1 @@ +Return a redirect response from Volto server-side rendering if the API request was redirected. @JeffersonBledsoe @mamico diff --git a/packages/volto/news/4834.feature b/packages/volto/news/4834.feature deleted file mode 100644 index 91603c7047..0000000000 --- a/packages/volto/news/4834.feature +++ /dev/null @@ -1 +0,0 @@ -Fix ++api++ in redirections @JeffersonBledsoe @mamico diff --git a/packages/volto/src/components/theme/View/View.jsx b/packages/volto/src/components/theme/View/View.jsx index 22b7db7e07..5029febaac 100644 --- a/packages/volto/src/components/theme/View/View.jsx +++ b/packages/volto/src/components/theme/View/View.jsx @@ -206,17 +206,10 @@ class View extends Component { */ render() { const { views } = config; - const status = __SERVER__ - ? this.props.error?.status - : this.props.error?.code; - // Checking to see if it's a 3XX HTTP status code. error.status only works on the server - if (status?.toString()?.[0] === '3') { - const redirectUrl = __SERVER__ - ? this.props.error.response.headers.location - : this.props.error.url; - let redirect = flattenToAppURL(redirectUrl); - // We can hit situations where we end up being redirected to an api route. We don't want that so lets remove ++api++. - redirect = redirect.replace('/++api++', ''); + if ([301, 302].includes(this.props.error?.code)) { + const redirect = flattenToAppURL(this.props.error.url) + .split('?')[0] + .replace('/++api++', ''); return ; } else if (this.props.error && !this.props.connectionRefused) { let FoundView; diff --git a/packages/volto/src/helpers/Api/Api.js b/packages/volto/src/helpers/Api/Api.js index 11dad7aea2..57419e116a 100644 --- a/packages/volto/src/helpers/Api/Api.js +++ b/packages/volto/src/helpers/Api/Api.js @@ -109,7 +109,7 @@ class Api { }); } - if (err?.status[0] === 3) { + if ([301, 302].includes(err?.status)) { return reject({ code: err.status, url: err.response.headers.location,