@exdst-sitecore-content-sdk/astro 0.0.1
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/LICENSE.txt +202 -0
- package/README.md +3 -0
- package/package.json +101 -0
- package/src/client/index.ts +12 -0
- package/src/client/sitecore-astro-client.test.ts +271 -0
- package/src/client/sitecore-astro-client.ts +137 -0
- package/src/components/AstroImage.astro +114 -0
- package/src/components/Date.astro +76 -0
- package/src/components/DefaultEmptyFieldEditingComponentImage.astro +24 -0
- package/src/components/DefaultEmptyFieldEditingComponentText.astro +12 -0
- package/src/components/EditingScripts.astro +49 -0
- package/src/components/EmptyRendering.astro +3 -0
- package/src/components/ErrorBoundary.astro +77 -0
- package/src/components/FieldMetadata.astro +30 -0
- package/src/components/File.astro +46 -0
- package/src/components/HiddenRendering.astro +22 -0
- package/src/components/Image.astro +155 -0
- package/src/components/Link.astro +105 -0
- package/src/components/MissingComponent.astro +39 -0
- package/src/components/Placeholder/EmptyPlaceholder.astro +9 -0
- package/src/components/Placeholder/Placeholder.astro +100 -0
- package/src/components/Placeholder/PlaceholderMetadata.astro +102 -0
- package/src/components/Placeholder/PlaceholderUtils.astro +153 -0
- package/src/components/Placeholder/index.ts +5 -0
- package/src/components/Placeholder/models.ts +82 -0
- package/src/components/Placeholder/placeholder-utils.test.ts +162 -0
- package/src/components/Placeholder/placeholder-utils.ts +80 -0
- package/src/components/RenderWrapper.astro +31 -0
- package/src/components/RichText.astro +59 -0
- package/src/components/Text.astro +97 -0
- package/src/components/sharedTypes/index.ts +1 -0
- package/src/components/sharedTypes/props.ts +17 -0
- package/src/config/define-config.test.ts +526 -0
- package/src/config/define-config.ts +99 -0
- package/src/config/index.ts +1 -0
- package/src/config-cli/define-cli-config.test.ts +95 -0
- package/src/config-cli/define-cli-config.ts +50 -0
- package/src/config-cli/index.ts +1 -0
- package/src/context.ts +68 -0
- package/src/editing/constants.ts +8 -0
- package/src/editing/editing-config-middleware.test.ts +166 -0
- package/src/editing/editing-config-middleware.ts +111 -0
- package/src/editing/editing-render-middleware.test.ts +801 -0
- package/src/editing/editing-render-middleware.ts +288 -0
- package/src/editing/index.ts +16 -0
- package/src/editing/render-middleware.test.ts +57 -0
- package/src/editing/render-middleware.ts +51 -0
- package/src/editing/utils.test.ts +852 -0
- package/src/editing/utils.ts +308 -0
- package/src/enhancers/WithEmptyFieldEditingComponent.astro +56 -0
- package/src/enhancers/WithFieldMetadata.astro +31 -0
- package/src/env.d.ts +12 -0
- package/src/index.ts +16 -0
- package/src/middleware/index.ts +24 -0
- package/src/middleware/middleware.test.ts +507 -0
- package/src/middleware/middleware.ts +167 -0
- package/src/middleware/multisite-middleware.test.ts +672 -0
- package/src/middleware/multisite-middleware.ts +147 -0
- package/src/middleware/robots-middleware.test.ts +113 -0
- package/src/middleware/robots-middleware.ts +47 -0
- package/src/middleware/sitemap-middleware.test.ts +152 -0
- package/src/middleware/sitemap-middleware.ts +65 -0
- package/src/services/component-props-service.ts +182 -0
- package/src/sharedTypes/component-props.ts +17 -0
- package/src/site/index.ts +1 -0
- package/src/test-data/components/Bar.astro +0 -0
- package/src/test-data/components/Baz.astro +0 -0
- package/src/test-data/components/Foo.astro +0 -0
- package/src/test-data/components/Hero.variant.astro +0 -0
- package/src/test-data/components/NotComponent.bsx +0 -0
- package/src/test-data/components/Qux.astro +0 -0
- package/src/test-data/components/folded/Folded.astro +0 -0
- package/src/test-data/components/folded/random-file-2.docx +0 -0
- package/src/test-data/components/random-file.txt +0 -0
- package/src/test-data/helpers.ts +46 -0
- package/src/test-data/personalizeData.ts +63 -0
- package/src/tools/generate-map.ts +83 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/templating/components.test.ts +305 -0
- package/src/tools/templating/components.ts +49 -0
- package/src/tools/templating/constants.ts +4 -0
- package/src/tools/templating/default-component.test.ts +31 -0
- package/src/tools/templating/default-component.ts +63 -0
- package/src/tools/templating/index.ts +2 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/utils.test.ts +48 -0
- package/src/utils/utils.ts +52 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { debug, NativeDataFetcher } from '@sitecore-content-sdk/core';
|
|
2
|
+
import {
|
|
3
|
+
QUERY_PARAM_EDITING_SECRET,
|
|
4
|
+
EDITING_ALLOWED_ORIGINS,
|
|
5
|
+
} from '@sitecore-content-sdk/core/editing';
|
|
6
|
+
import { getEditingSecret } from '../utils';
|
|
7
|
+
import { getEnforcedCorsHeaders } from '@sitecore-content-sdk/core/utils';
|
|
8
|
+
import { LayoutServicePageState } from '@sitecore-content-sdk/core/layout';
|
|
9
|
+
import { RenderMiddlewareBase } from './render-middleware';
|
|
10
|
+
import {
|
|
11
|
+
cleanupPreviewCookies,
|
|
12
|
+
getCSPHeader,
|
|
13
|
+
getEditingRenderQueryParams,
|
|
14
|
+
getEditingRequestHtml,
|
|
15
|
+
getHeadersForPropagation,
|
|
16
|
+
getPreviewCookies,
|
|
17
|
+
getQueryParamsForPropagation,
|
|
18
|
+
getRequiredEditingParamsList,
|
|
19
|
+
mapEditingParams,
|
|
20
|
+
PreviewCookies,
|
|
21
|
+
resolveServerUrl,
|
|
22
|
+
} from './utils';
|
|
23
|
+
import * as cookie from 'cookie';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for the Editing Render Middleware.
|
|
27
|
+
*/
|
|
28
|
+
export type EditingRenderMiddlewareConfig = {
|
|
29
|
+
/**
|
|
30
|
+
* Function used to determine route/page URL to render.
|
|
31
|
+
* This may be necessary for certain custom routing configurations.
|
|
32
|
+
* @param {string} itemPath The Sitecore relative item path e.g. '/styleguide'
|
|
33
|
+
* @returns {string} The URL to render
|
|
34
|
+
* @default `${itemPath}`
|
|
35
|
+
*/
|
|
36
|
+
resolvePageUrl?: (itemPath: string) => string;
|
|
37
|
+
/**
|
|
38
|
+
* The internal host URL for the application, used for server-side requests for page rendering during editing.
|
|
39
|
+
*/
|
|
40
|
+
sitecoreInternalEditingHostUrl?: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Middleware / handler for use in the editing render API route (e.g. '/api/editing/render')
|
|
45
|
+
* which is required for Sitecore editing support.
|
|
46
|
+
*/
|
|
47
|
+
export class EditingRenderMiddleware extends RenderMiddlewareBase {
|
|
48
|
+
private dataFetcher: NativeDataFetcher;
|
|
49
|
+
/**
|
|
50
|
+
* @param {EditingRenderMiddlewareConfig} [config] Editing render middleware config
|
|
51
|
+
*/
|
|
52
|
+
constructor(public config?: EditingRenderMiddlewareConfig) {
|
|
53
|
+
super();
|
|
54
|
+
this.dataFetcher = new NativeDataFetcher({ debugger: debug.editing });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Gets the API route handler
|
|
59
|
+
* @returns route handler
|
|
60
|
+
*/
|
|
61
|
+
public getHandler(): (req: Request) => Promise<Response> {
|
|
62
|
+
return this.handler;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Gets the preview data cookies string
|
|
67
|
+
* @param {object} data preview data
|
|
68
|
+
* @returns Cookie string with the preview data
|
|
69
|
+
*/
|
|
70
|
+
private getPreviewDataCookies = (data: {
|
|
71
|
+
[key: string]: string | string[] | undefined;
|
|
72
|
+
}): string => {
|
|
73
|
+
return cookie.serialize(
|
|
74
|
+
PreviewCookies.PREVIEW_DATA,
|
|
75
|
+
JSON.stringify(data, (_, value) => (value === null ? undefined : value)),
|
|
76
|
+
{
|
|
77
|
+
httpOnly: true,
|
|
78
|
+
path: '/',
|
|
79
|
+
maxAge: 3,
|
|
80
|
+
sameSite: 'none',
|
|
81
|
+
secure: true,
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
private handler = async (_req: Request): Promise<Response> => {
|
|
87
|
+
const { method, headers } = _req;
|
|
88
|
+
const url = new URL(_req.url.toLowerCase());
|
|
89
|
+
const query = getEditingRenderQueryParams(url.searchParams);
|
|
90
|
+
|
|
91
|
+
debug.editing('editing render middleware start: %o', {
|
|
92
|
+
method,
|
|
93
|
+
query,
|
|
94
|
+
headers,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const _res = new Response();
|
|
98
|
+
_res.headers.append('Content-Type', 'application/json; charset=utf-8');
|
|
99
|
+
|
|
100
|
+
const corsHeaders = getEnforcedCorsHeaders({
|
|
101
|
+
requestMethod: _req.method,
|
|
102
|
+
headers: _req.headers,
|
|
103
|
+
allowedOrigins: EDITING_ALLOWED_ORIGINS,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (!corsHeaders) {
|
|
107
|
+
debug.editing(
|
|
108
|
+
'invalid origin host - set allowed origins in JSS_ALLOWED_ORIGINS environment variable'
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return new Response(
|
|
112
|
+
JSON.stringify({
|
|
113
|
+
html: `<html><body>Requests from origin ${_req.headers?.get(
|
|
114
|
+
'origin'
|
|
115
|
+
)} not allowed</body></html>`,
|
|
116
|
+
}),
|
|
117
|
+
{
|
|
118
|
+
status: 401,
|
|
119
|
+
headers: _res.headers,
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Object.keys(corsHeaders).forEach((key) => {
|
|
125
|
+
_res.headers.append(key, corsHeaders[key]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Validate secret
|
|
129
|
+
const secret = query[QUERY_PARAM_EDITING_SECRET];
|
|
130
|
+
if (secret !== getEditingSecret()) {
|
|
131
|
+
debug.editing('invalid editing secret - sent "%s" expected "%s"', secret, getEditingSecret());
|
|
132
|
+
|
|
133
|
+
return new Response(
|
|
134
|
+
JSON.stringify({
|
|
135
|
+
html: '<html><body>Missing or invalid secret</body></html>',
|
|
136
|
+
}),
|
|
137
|
+
{
|
|
138
|
+
status: 401,
|
|
139
|
+
headers: _res.headers,
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (_req.method === 'OPTIONS') {
|
|
145
|
+
debug.editing('preflight request');
|
|
146
|
+
|
|
147
|
+
// CORS headers are set by enforceCors
|
|
148
|
+
return new Response(null, {
|
|
149
|
+
status: 204,
|
|
150
|
+
headers: _res.headers,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (_req.method !== 'GET') {
|
|
155
|
+
debug.editing('invalid method - sent %s expected GET', _req.method);
|
|
156
|
+
|
|
157
|
+
_res.headers.append('Allow', 'GET');
|
|
158
|
+
|
|
159
|
+
return new Response(
|
|
160
|
+
JSON.stringify({
|
|
161
|
+
html: `<html><body>Invalid request method '${_req.method}'</body></html>`,
|
|
162
|
+
}),
|
|
163
|
+
{
|
|
164
|
+
status: 405,
|
|
165
|
+
headers: _res.headers,
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const startTimestamp = Date.now();
|
|
171
|
+
|
|
172
|
+
const mode = query.mode;
|
|
173
|
+
|
|
174
|
+
const requiredQueryParams = getRequiredEditingParamsList(mode);
|
|
175
|
+
|
|
176
|
+
const missingQueryParams = requiredQueryParams.filter((param) => !query[param]);
|
|
177
|
+
|
|
178
|
+
// Validate query parameters
|
|
179
|
+
if (missingQueryParams.length) {
|
|
180
|
+
debug.editing('missing required query parameters: %o', missingQueryParams);
|
|
181
|
+
|
|
182
|
+
return new Response(
|
|
183
|
+
JSON.stringify({
|
|
184
|
+
html: `<html><body>Missing required query parameters: ${missingQueryParams.join(
|
|
185
|
+
', '
|
|
186
|
+
)}</body></html>`,
|
|
187
|
+
}),
|
|
188
|
+
{
|
|
189
|
+
status: 400,
|
|
190
|
+
headers: _res.headers,
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const previewDataParams = mapEditingParams(query as { [key: string]: string });
|
|
196
|
+
|
|
197
|
+
const previewDataCookies = this.getPreviewDataCookies({
|
|
198
|
+
...previewDataParams,
|
|
199
|
+
variantIds: previewDataParams.variantIds?.split(','),
|
|
200
|
+
});
|
|
201
|
+
_res.headers.append('Set-Cookie', previewDataCookies);
|
|
202
|
+
|
|
203
|
+
// Set Preview mode identifier cookie, if the page is rendered in Sitecore Preview mode
|
|
204
|
+
if (mode === LayoutServicePageState.Preview) {
|
|
205
|
+
const previewCookies = getPreviewCookies(query.sc_site as string);
|
|
206
|
+
|
|
207
|
+
previewCookies.forEach((cookie) => {
|
|
208
|
+
_res.headers.append('Set-Cookie', cookie);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Restrict the page to be rendered only within the allowed origins
|
|
213
|
+
_res.headers.append('Content-Security-Policy', getCSPHeader());
|
|
214
|
+
|
|
215
|
+
const encodedRoute = encodeURI(query.route);
|
|
216
|
+
const route = this.config?.resolvePageUrl?.(encodedRoute) || encodedRoute;
|
|
217
|
+
|
|
218
|
+
const base = this.config?.sitecoreInternalEditingHostUrl || resolveServerUrl(_req);
|
|
219
|
+
const requestUrl = new URL(route, base);
|
|
220
|
+
|
|
221
|
+
// Grab the preview cookies to send on to the render request
|
|
222
|
+
const cookies = _res.headers.getSetCookie();
|
|
223
|
+
|
|
224
|
+
// Make actual render request for page route, passing on preview cookies as well as any approved query string parameters.
|
|
225
|
+
// Note timestamp effectively disables caching the request (no amount of cache headers seemed to do it)
|
|
226
|
+
try {
|
|
227
|
+
debug.editing('fetching page route for %s', query.route);
|
|
228
|
+
|
|
229
|
+
// Get query string parameters to propagate on subsequent requests (e.g. for deployment protection bypass)
|
|
230
|
+
const propagatedQsParams = getQueryParamsForPropagation(query as { [key: string]: string });
|
|
231
|
+
|
|
232
|
+
// Get headers to propagate on subsequent requests
|
|
233
|
+
const propagatedHeaders = getHeadersForPropagation(headers);
|
|
234
|
+
|
|
235
|
+
const html = await getEditingRequestHtml(
|
|
236
|
+
requestUrl,
|
|
237
|
+
propagatedQsParams,
|
|
238
|
+
propagatedHeaders,
|
|
239
|
+
cookies,
|
|
240
|
+
this.dataFetcher
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
// remove preview cookies to not leak them to the browser
|
|
244
|
+
if (cookies && Array.isArray(cookies)) {
|
|
245
|
+
const filteredCookies = cleanupPreviewCookies(cookies);
|
|
246
|
+
_res.headers.delete('Set-Cookie');
|
|
247
|
+
filteredCookies?.forEach((cookie) => {
|
|
248
|
+
_res.headers.append('Set-Cookie', cookie);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
debug.editing('editing render middleware end in %dms: %o', Date.now() - startTimestamp, {
|
|
253
|
+
status: 200,
|
|
254
|
+
route,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
_res.headers.set('Content-Type', 'text/html; charset=utf-8');
|
|
258
|
+
|
|
259
|
+
return new Response(html, {
|
|
260
|
+
status: 200,
|
|
261
|
+
headers: _res.headers,
|
|
262
|
+
});
|
|
263
|
+
} catch (err) {
|
|
264
|
+
const error = err as Record<string, unknown>;
|
|
265
|
+
|
|
266
|
+
console.error(error);
|
|
267
|
+
|
|
268
|
+
if (error.response) {
|
|
269
|
+
console.info(
|
|
270
|
+
// eslint-disable-next-line quotes
|
|
271
|
+
"Hint: for non-standard server or Next.js route configurations, you may need to override 'resolvePageUrl' or set the 'sitecoreInternalEditingHostUrl' (or SITECORE_INTERNAL_EDITING_HOST_URL env variable) available on the 'EditingRenderMiddleware' config."
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// remove preview cookies to not leak them to the browser
|
|
276
|
+
const filteredCookies = cleanupPreviewCookies(cookies);
|
|
277
|
+
_res.headers.delete('Set-Cookie');
|
|
278
|
+
filteredCookies?.forEach((cookie) => {
|
|
279
|
+
_res.headers.append('Set-Cookie', cookie);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
return new Response(`<html><body>${error}</body></html>`, {
|
|
283
|
+
status: 500,
|
|
284
|
+
headers: _res.headers,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export {
|
|
2
|
+
EditingConfigMiddleware,
|
|
3
|
+
EditingConfigMiddlewareConfig,
|
|
4
|
+
} from './editing-config-middleware';
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
EditingRenderMiddleware,
|
|
8
|
+
EditingRenderMiddlewareConfig,
|
|
9
|
+
} from './editing-render-middleware';
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
isDesignLibraryPreviewData,
|
|
13
|
+
getQueryParamsForPropagation,
|
|
14
|
+
getHeadersForPropagation,
|
|
15
|
+
PreviewCookies,
|
|
16
|
+
} from './utils';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* eslint-disable dot-notation */
|
|
2
|
+
import chai from 'chai';
|
|
3
|
+
import chaiString from 'chai-string';
|
|
4
|
+
import { QUERY_PARAM_EDITING_SECRET } from '@sitecore-content-sdk/core/editing';
|
|
5
|
+
import { RenderMiddlewareBase } from './render-middleware';
|
|
6
|
+
import {
|
|
7
|
+
QUERY_PARAM_VERCEL_PROTECTION_BYPASS,
|
|
8
|
+
QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE,
|
|
9
|
+
EDITING_PASS_THROUGH_HEADERS,
|
|
10
|
+
} from './constants';
|
|
11
|
+
|
|
12
|
+
const expect = chai.use(chaiString).expect;
|
|
13
|
+
|
|
14
|
+
describe('RenderMiddlewareBase', () => {
|
|
15
|
+
class SampleMiddleware extends RenderMiddlewareBase {}
|
|
16
|
+
|
|
17
|
+
describe('getQueryParamsForPropagation', () => {
|
|
18
|
+
it('should construct query params for protection bypass', () => {
|
|
19
|
+
const middleware = new SampleMiddleware();
|
|
20
|
+
|
|
21
|
+
const secret = 'secret1234';
|
|
22
|
+
const vercelBypassToken = 'token1234Vercel';
|
|
23
|
+
const vercelBypassCookie = 'samesitenone';
|
|
24
|
+
const query = new URLSearchParams({
|
|
25
|
+
[QUERY_PARAM_EDITING_SECRET]: secret,
|
|
26
|
+
[QUERY_PARAM_VERCEL_PROTECTION_BYPASS]: vercelBypassToken,
|
|
27
|
+
[QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE]: vercelBypassCookie,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const approvedQuery = new URLSearchParams({
|
|
31
|
+
[QUERY_PARAM_VERCEL_PROTECTION_BYPASS]: vercelBypassToken,
|
|
32
|
+
[QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE]: vercelBypassCookie,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
expect(middleware['getQueryParamsForPropagation'](query)).to.deep.equal(approvedQuery);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('getHeadersForPropagation', () => {
|
|
40
|
+
it('should return approved headers', () => {
|
|
41
|
+
const middleware = new SampleMiddleware();
|
|
42
|
+
|
|
43
|
+
const allHeaders = new Headers();
|
|
44
|
+
const approvedHeaders = new Headers();
|
|
45
|
+
|
|
46
|
+
EDITING_PASS_THROUGH_HEADERS.forEach((key) => {
|
|
47
|
+
allHeaders.append(key, `${key}-value`);
|
|
48
|
+
approvedHeaders.append(key, `${key}-value`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
allHeaders.append('nope', 'nope');
|
|
52
|
+
allHeaders.append('should-not-pass', 'n/a');
|
|
53
|
+
|
|
54
|
+
expect(middleware['getHeadersForPropagation'](allHeaders)).to.deep.equal(approvedHeaders);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
QUERY_PARAM_VERCEL_PROTECTION_BYPASS,
|
|
3
|
+
QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE,
|
|
4
|
+
EDITING_PASS_THROUGH_HEADERS,
|
|
5
|
+
} from './constants';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Base class for middleware that handles pages and components rendering in Sitecore Editors.
|
|
9
|
+
* @deprecated getQueryParamsForPropagation and getHeadersForPropagation methods have been moved to separate exports
|
|
10
|
+
*/
|
|
11
|
+
export abstract class RenderMiddlewareBase {
|
|
12
|
+
/**
|
|
13
|
+
* Gets query parameters that should be passed along to subsequent requests (e.g. for deployment protection bypass)
|
|
14
|
+
* @param {object} query URLSearchParams object from incoming URL
|
|
15
|
+
* @returns URLSearchParams object of approved query parameters
|
|
16
|
+
*/
|
|
17
|
+
protected getQueryParamsForPropagation = (query: URLSearchParams): URLSearchParams => {
|
|
18
|
+
const params = new URLSearchParams();
|
|
19
|
+
if (query.get(QUERY_PARAM_VERCEL_PROTECTION_BYPASS)) {
|
|
20
|
+
params.append(
|
|
21
|
+
QUERY_PARAM_VERCEL_PROTECTION_BYPASS,
|
|
22
|
+
query.get(QUERY_PARAM_VERCEL_PROTECTION_BYPASS) as string
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
if (query.get(QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE)) {
|
|
26
|
+
params.append(
|
|
27
|
+
QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE,
|
|
28
|
+
query.get(QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE) as string
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return params;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get headers that should be passed along to subsequent requests
|
|
36
|
+
* @param {IncomingHttpHeaders} headers Incoming HTTP Headers
|
|
37
|
+
* @returns Object of approved headers
|
|
38
|
+
*/
|
|
39
|
+
protected getHeadersForPropagation = (headers: Headers): Headers => {
|
|
40
|
+
// Filter and normalize headers
|
|
41
|
+
const filteredHeaders = EDITING_PASS_THROUGH_HEADERS.reduce((acc, header) => {
|
|
42
|
+
const value = headers.get(header);
|
|
43
|
+
if (value) {
|
|
44
|
+
acc.append(header, Array.isArray(value) ? value.join(', ') : value);
|
|
45
|
+
}
|
|
46
|
+
return acc;
|
|
47
|
+
}, new Headers());
|
|
48
|
+
|
|
49
|
+
return filteredHeaders;
|
|
50
|
+
};
|
|
51
|
+
}
|