@plone/volto 16.31.5 → 16.31.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.changelog.draft CHANGED
@@ -1,12 +1,7 @@
1
- ## 16.31.5 (2024-05-06)
1
+ ## 16.31.7 (2024-05-21)
2
2
 
3
3
  ### Bugfix
4
4
 
5
- - Fix image disappears after pressing the Enter key on title field in image content-type. @iFlameing [#5973](https://github.com/plone/volto/issues/5973)
6
- - Fix 301 and 302 redirects. @robgietema [#6001](https://github.com/plone/volto/issues/6001)
7
-
8
- ### Documentation
9
-
10
- - Block search engines from indexing content on Netlify preview builds. @stevepiercy [#5916](https://github.com/plone/volto/issues/5916)
5
+ - Return a redirect response from Volto server-side rendering if the API request was redirected. @JeffersonBledsoe @mamico [#4834](https://github.com/plone/volto/issues/4834)
11
6
 
12
7
 
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ build:
3
+ os: "ubuntu-22.04"
4
+ tools:
5
+ python: "3.12"
6
+ jobs:
7
+ post_checkout:
8
+ # Cancel the Read the Docs build
9
+ # https://docs.readthedocs.io/en/stable/build-customization.html#cancel-build-based-on-a-condition
10
+ - exit 183;
package/CHANGELOG.md CHANGED
@@ -8,6 +8,18 @@
8
8
 
9
9
  <!-- towncrier release notes start -->
10
10
 
11
+ ## 16.31.7 (2024-05-21)
12
+
13
+ ### Bugfix
14
+
15
+ - Return a redirect response from Volto server-side rendering if the API request was redirected. @JeffersonBledsoe @mamico [#4834](https://github.com/plone/volto/issues/4834)
16
+
17
+ ## 16.31.6 (2024-05-09)
18
+
19
+ ### Bugfix
20
+
21
+ - Revert "Fix 301 and 302 redirects" which was not working correctly. @davisagli [#6009](https://github.com/plone/volto/issues/6009)
22
+
11
23
  ## 16.31.5 (2024-05-06)
12
24
 
13
25
  ### Bugfix
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "16.31.5",
12
+ "version": "16.31.7",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plone/volto-slate",
3
- "version": "16.31.5",
3
+ "version": "16.31.7",
4
4
  "description": "Slate.js integration with Volto",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -203,13 +203,10 @@ class View extends Component {
203
203
  */
204
204
  render() {
205
205
  const { views } = config;
206
- if (this.props.error && this.props.error.code === 301) {
207
- const redirect = flattenToAppURL(this.props.error.url).split('?')[0];
208
- return <Redirect to={`${redirect}${this.props.location.search}`} />;
209
- } else if (this.props.error && this.props.error.status === 302) {
210
- const redirect = flattenToAppURL(
211
- this.props.error.response.header.location,
212
- ).split('?')[0];
206
+ if ([301, 302].includes(this.props.error?.code)) {
207
+ const redirect = flattenToAppURL(this.props.error.url)
208
+ .split('?')[0]
209
+ .replace('/++api++', '');
213
210
  return <Redirect to={`${redirect}${this.props.location.search}`} />;
214
211
  } else if (this.props.error && !this.props.connectionRefused) {
215
212
  let FoundView;
@@ -22,6 +22,7 @@ beforeAll(() => {
22
22
  });
23
23
  config.settings.publicURL = 'https://plone.org';
24
24
  });
25
+ global.__SERVER__ = true; // eslint-disable-line no-underscore-dangle
25
26
 
26
27
  const mockStore = configureStore();
27
28
 
@@ -1,7 +0,0 @@
1
- # Packages
2
-
3
- This directory is intended to contain packages related to Volto ecosystem.
4
-
5
- It was never intended to convert this repo in a monorepo.
6
-
7
- Main Volto package is still located in the root, and it's intended to continue doing so.
@@ -1,39 +0,0 @@
1
- /**
2
- * Sitemap helper.
3
- * @module helpers/Sitemap
4
- */
5
-
6
- import superagent from 'superagent';
7
- import config from '@plone/volto/registry';
8
- import { addHeadersFactory } from '@plone/volto/helpers/Proxy/Proxy';
9
-
10
- /**
11
- * Get a resource image/file with authenticated (if token exist) API headers
12
- * @function getAPIResourceWithAuth
13
- * @param {Object} req Request object
14
- * @return {string} The response with the image
15
- */
16
- export const getAPIResourceWithAuth = (req) =>
17
- new Promise((resolve, reject) => {
18
- const { settings } = config;
19
- const APISUFIX = settings.legacyTraverse ? '' : '/++api++';
20
-
21
- let apiPath = '';
22
- if (settings.internalApiPath && __SERVER__) {
23
- apiPath = settings.internalApiPath;
24
- } else if (__DEVELOPMENT__ && settings.devProxyToApiPath) {
25
- apiPath = settings.devProxyToApiPath;
26
- } else {
27
- apiPath = settings.apiPath;
28
- }
29
- const request = superagent
30
- .get(`${apiPath}${APISUFIX}${req.path}`)
31
- .maxResponseSize(settings.maxResponseSize)
32
- .responseType('blob');
33
- const authToken = req.universalCookies.get('auth_token');
34
- if (authToken) {
35
- request.set('Authorization', `Bearer ${authToken}`);
36
- }
37
- request.use(addHeadersFactory(req));
38
- request.then(resolve).catch(reject);
39
- });
@@ -1,117 +0,0 @@
1
- /**
2
- * Api helper.
3
- * @module helpers/Api
4
- */
5
-
6
- import superagent from 'superagent';
7
- import Cookies from 'universal-cookie';
8
- import config from '@plone/volto/registry';
9
- import { addHeadersFactory } from '@plone/volto/helpers/Proxy/Proxy';
10
- import { stripQuerystring } from '@plone/volto/helpers';
11
-
12
- const methods = ['get', 'post', 'put', 'patch', 'del'];
13
-
14
- /**
15
- * Format the url.
16
- * @function formatUrl
17
- * @param {string} path Path (or URL) to be formatted.
18
- * @returns {string} Formatted path.
19
- */
20
- function formatUrl(path) {
21
- const { settings } = config;
22
- const APISUFIX = settings.legacyTraverse ? '' : '/++api++';
23
-
24
- if (path.startsWith('http://') || path.startsWith('https://')) return path;
25
-
26
- const adjustedPath = path[0] !== '/' ? `/${path}` : path;
27
- let apiPath = '';
28
- if (settings.internalApiPath && __SERVER__) {
29
- apiPath = settings.internalApiPath;
30
- } else if (settings.apiPath) {
31
- apiPath = settings.apiPath;
32
- }
33
-
34
- return `${apiPath}${APISUFIX}${adjustedPath}`;
35
- }
36
-
37
- /**
38
- * Api class.
39
- * @class Api
40
- */
41
- class Api {
42
- /**
43
- * Constructor
44
- * @method constructor
45
- * @constructs Api
46
- */
47
- constructor(req) {
48
- const cookies = new Cookies();
49
-
50
- methods.forEach((method) => {
51
- this[method] = (
52
- path,
53
- { params, data, type, headers = {}, checkUrl = false } = {},
54
- ) => {
55
- let request;
56
- let promise = new Promise((resolve, reject) => {
57
- request = superagent[method](formatUrl(path)).redirects(0);
58
-
59
- if (params) {
60
- request.query(params);
61
- }
62
-
63
- let authToken;
64
- if (req) {
65
- // We are in SSR
66
- authToken = req.universalCookies.get('auth_token');
67
- request.use(addHeadersFactory(req));
68
- } else {
69
- authToken = cookies.get('auth_token');
70
- }
71
- if (authToken) {
72
- request.set('Authorization', `Bearer ${authToken}`);
73
- }
74
-
75
- request.set('Accept', 'application/json');
76
-
77
- if (type) {
78
- request.type(type);
79
- }
80
-
81
- Object.keys(headers).forEach((key) => request.set(key, headers[key]));
82
-
83
- if (data) {
84
- request.send(data);
85
- }
86
-
87
- request.end((err, response) => {
88
- if (
89
- checkUrl &&
90
- request.url &&
91
- request.xhr &&
92
- encodeURI(stripQuerystring(request.url)) !==
93
- stripQuerystring(request.xhr.responseURL)
94
- ) {
95
- if (request.xhr.responseURL?.length === 0) {
96
- return reject({
97
- code: 408,
98
- status: 408,
99
- url: request.xhr.responseURL,
100
- });
101
- }
102
- return reject({
103
- code: 301,
104
- url: request.xhr.responseURL,
105
- });
106
- }
107
- return err ? reject(err) : resolve(response.body || response.text);
108
- });
109
- });
110
- promise.request = request;
111
- return promise;
112
- };
113
- });
114
- }
115
- }
116
-
117
- export default Api;
@@ -1,43 +0,0 @@
1
- import config from '@plone/volto/registry';
2
- import Api from './Api';
3
-
4
- jest.mock('superagent', () => ({
5
- get: jest.fn((url) => ({
6
- redirects: jest.fn(() => ({
7
- url,
8
- query: jest.fn(),
9
- set: jest.fn(),
10
- type: jest.fn(),
11
- send: jest.fn(),
12
- end: jest.fn(),
13
- })),
14
- })),
15
- }));
16
-
17
- beforeAll(() => {
18
- config.settings.legacyTraverse = false;
19
- });
20
-
21
- const api = new Api();
22
- const { settings } = config;
23
-
24
- test('get request', () => {});
25
-
26
- describe('Api', () => {
27
- it('prefixes relative path', () => {
28
- const promise = api.get('');
29
- expect(promise.request.url).toBe(`${settings.apiPath}/++api++/`);
30
- });
31
- it('does not prefix absolute path', () => {
32
- const promise = api.get('/test');
33
- expect(promise.request.url).toBe(`${settings.apiPath}/++api++/test`);
34
- });
35
- it('does not change http URL provided as path', () => {
36
- const promise = api.get('http://example.com');
37
- expect(promise.request.url).toBe('http://example.com');
38
- });
39
- it('does not change https URL provided as path', () => {
40
- const promise = api.get('https://example.com');
41
- expect(promise.request.url).toBe('https://example.com');
42
- });
43
- });
@@ -1,49 +0,0 @@
1
- // import superagent from 'superagent';
2
- import config from '@plone/volto/registry';
3
- import Api from './Api';
4
-
5
- // jest.mock('react-cookie', () => ({
6
- // load: jest.fn(() => 'token'),
7
- // }));
8
- //
9
-
10
- jest.mock('superagent', () => ({
11
- get: jest.fn((url) => ({
12
- redirects: jest.fn(() => ({
13
- url,
14
- query: jest.fn(),
15
- set: jest.fn(),
16
- type: jest.fn(),
17
- send: jest.fn(),
18
- end: jest.fn(),
19
- })),
20
- })),
21
- }));
22
-
23
- beforeAll(() => {
24
- config.settings.legacyTraverse = true;
25
- });
26
-
27
- const api = new Api();
28
- const { settings } = config;
29
-
30
- test('get request', () => {});
31
-
32
- describe('Api', () => {
33
- it('prefixes relative path', () => {
34
- const promise = api.get('');
35
- expect(promise.request.url).toBe(`${settings.apiPath}/`);
36
- });
37
- it('does not prefix absolute path', () => {
38
- const promise = api.get('/test');
39
- expect(promise.request.url).toBe(`${settings.apiPath}/test`);
40
- });
41
- it('does not change http URL provided as path', () => {
42
- const promise = api.get('http://example.com');
43
- expect(promise.request.url).toBe('http://example.com');
44
- });
45
- it('does not change https URL provided as path', () => {
46
- const promise = api.get('https://example.com');
47
- expect(promise.request.url).toBe('https://example.com');
48
- });
49
- });