@sitecore-content-sdk/nextjs 2.5.1-canary.20261102062040 → 2.5.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/dist/cjs/components/DesignLibrary/DesignLibraryApp.js +42 -17
- package/dist/cjs/components/DesignLibrary/DesignLibraryRuntime.js +27 -0
- package/dist/cjs/editing/constants.js +7 -1
- package/dist/cjs/route-handler/editing-render-route-handler.js +6 -3
- package/dist/cjs/server-actions/update-server-component-action.js +14 -0
- package/dist/cjs/utils/utils.js +73 -1
- package/dist/esm/components/DesignLibrary/DesignLibraryApp.js +9 -17
- package/dist/esm/components/DesignLibrary/DesignLibraryRuntime.js +20 -0
- package/dist/esm/editing/constants.js +6 -0
- package/dist/esm/route-handler/editing-render-route-handler.js +7 -4
- package/dist/esm/server-actions/update-server-component-action.js +14 -0
- package/dist/esm/utils/utils.js +36 -0
- package/package.json +2 -2
- package/types/components/DesignLibrary/DesignLibraryApp.d.ts +6 -7
- package/types/components/DesignLibrary/DesignLibraryApp.d.ts.map +1 -1
- package/types/components/DesignLibrary/DesignLibraryRuntime.d.ts +10 -0
- package/types/components/DesignLibrary/DesignLibraryRuntime.d.ts.map +1 -0
- package/types/editing/constants.d.ts +6 -0
- package/types/editing/constants.d.ts.map +1 -1
- package/types/route-handler/editing-render-route-handler.d.ts.map +1 -1
- package/types/server-actions/update-server-component-action.d.ts.map +1 -1
- package/types/utils/utils.d.ts +21 -0
- package/types/utils/utils.d.ts.map +1 -1
|
@@ -1,31 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
39
|
exports.DesignLibraryApp = void 0;
|
|
7
40
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
const layout_1 = require("@sitecore-content-sdk/content/layout");
|
|
9
|
-
const DesignLibraryServer_1 = require("./DesignLibraryServer");
|
|
10
|
-
const react_2 = require("@sitecore-content-sdk/react");
|
|
11
41
|
/**
|
|
12
|
-
* Design Library component intended to be used by the NextJs app router application
|
|
13
|
-
* This component serves as a router between client and server component rendering modes
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* - Client components are rendered using the `DesignLibrary` component
|
|
17
|
-
* - Server components are rendered using the `DesignLibraryServer` component
|
|
42
|
+
* Design Library component intended to be used by the NextJs app router application.
|
|
43
|
+
* This component serves as a router between client and server component rendering modes
|
|
44
|
+
* for the Design Library. The client/server runtime is loaded lazily so static import
|
|
45
|
+
* of `DesignLibrary` / `DesignLibraryServer` does not pull those modules into every render.
|
|
18
46
|
* @param {DesingLibraryAppProps} props - The properties for the Design Library App.
|
|
19
47
|
* @public
|
|
20
48
|
*/
|
|
21
|
-
const DesignLibraryApp = (
|
|
22
|
-
|
|
23
|
-
const { route } = page.layout.sitecore;
|
|
24
|
-
if (!route)
|
|
49
|
+
const DesignLibraryApp = async (props) => {
|
|
50
|
+
if (!props.page.layout.sitecore.route)
|
|
25
51
|
return null;
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
const isClient = component && component.componentType === 'client';
|
|
29
|
-
return (react_1.default.createElement(react_1.default.Fragment, null, isClient ? (react_1.default.createElement(react_2.DesignLibrary, null)) : (react_1.default.createElement(DesignLibraryServer_1.DesignLibraryServer, { page: page, componentMap: componentMap, loadServerImportMap: loadServerImportMap, rendering: route }))));
|
|
52
|
+
const { DesignLibraryRuntime } = await Promise.resolve().then(() => __importStar(require('./DesignLibraryRuntime')));
|
|
53
|
+
return react_1.default.createElement(DesignLibraryRuntime, Object.assign({}, props));
|
|
30
54
|
};
|
|
31
55
|
exports.DesignLibraryApp = DesignLibraryApp;
|
|
56
|
+
exports.default = exports.DesignLibraryApp;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DesignLibraryRuntime = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const layout_1 = require("@sitecore-content-sdk/content/layout");
|
|
9
|
+
const DesignLibraryServer_1 = require("./DesignLibraryServer");
|
|
10
|
+
const react_2 = require("@sitecore-content-sdk/react");
|
|
11
|
+
/**
|
|
12
|
+
* Internal Design Library renderer. Routes between client and server
|
|
13
|
+
* implementations after `DesignLibraryApp` has authorized the request.
|
|
14
|
+
* @param {DesingLibraryAppProps} props - The properties for the Design Library App.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
const DesignLibraryRuntime = ({ page, componentMap, loadServerImportMap = react_2.noopLoadImportMap, }) => {
|
|
18
|
+
var _a;
|
|
19
|
+
const { route } = page.layout.sitecore;
|
|
20
|
+
if (!route)
|
|
21
|
+
return null;
|
|
22
|
+
const rendering = (_a = route === null || route === void 0 ? void 0 : route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER]) === null || _a === void 0 ? void 0 : _a[0];
|
|
23
|
+
const component = componentMap.get((rendering === null || rendering === void 0 ? void 0 : rendering.componentName) || '');
|
|
24
|
+
const isClient = component && component.componentType === 'client';
|
|
25
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, isClient ? (react_1.default.createElement(react_2.DesignLibrary, null)) : (react_1.default.createElement(DesignLibraryServer_1.DesignLibraryServer, { page: page, componentMap: componentMap, loadServerImportMap: loadServerImportMap, rendering: route }))));
|
|
26
|
+
};
|
|
27
|
+
exports.DesignLibraryRuntime = DesignLibraryRuntime;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EDITING_PARAMS_HEADER = exports.EDITING_PASS_THROUGH_HEADERS = exports.QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE = exports.QUERY_PARAM_VERCEL_PROTECTION_BYPASS = void 0;
|
|
3
|
+
exports.EDITING_SECRET_HEADER = exports.EDITING_PARAMS_HEADER = exports.EDITING_PASS_THROUGH_HEADERS = exports.QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE = exports.QUERY_PARAM_VERCEL_PROTECTION_BYPASS = void 0;
|
|
4
4
|
exports.QUERY_PARAM_VERCEL_PROTECTION_BYPASS = 'x-vercel-protection-bypass';
|
|
5
5
|
exports.QUERY_PARAM_VERCEL_SET_BYPASS_COOKIE = 'x-vercel-set-bypass-cookie';
|
|
6
6
|
/**
|
|
@@ -13,3 +13,9 @@ exports.EDITING_PASS_THROUGH_HEADERS = ['authorization', 'cookie'];
|
|
|
13
13
|
* route handler to the Next.js page when running in App Router.
|
|
14
14
|
*/
|
|
15
15
|
exports.EDITING_PARAMS_HEADER = 'x-sitecore-editing-params';
|
|
16
|
+
/**
|
|
17
|
+
* Header used to forward the already-validated editing secret from the editing
|
|
18
|
+
* render handler/middleware to the internal Next.js page or server-action request.
|
|
19
|
+
* Do not put this value in `EDITING_PARAMS_HEADER` JSON.
|
|
20
|
+
*/
|
|
21
|
+
exports.EDITING_SECRET_HEADER = 'x-sitecore-editing-secret';
|
|
@@ -94,7 +94,8 @@ const createEditingRenderRouteHandlers = (options) => {
|
|
|
94
94
|
}
|
|
95
95
|
const responseHeaders = expectedCorsHeaders;
|
|
96
96
|
// Validate secret
|
|
97
|
-
|
|
97
|
+
const receivedSecret = query[editing_1.QUERY_PARAM_EDITING_SECRET];
|
|
98
|
+
if (!validateEditingSecret(receivedSecret)) {
|
|
98
99
|
return Response.json({
|
|
99
100
|
html: editing_1.INVALID_SECRET_HTML_MESSAGE,
|
|
100
101
|
}, { status: 401, headers: responseHeaders });
|
|
@@ -161,7 +162,7 @@ const createEditingRenderRouteHandlers = (options) => {
|
|
|
161
162
|
// `EDITING_PARAMS_HEADER` instead via `client.getPreviewInputs`.
|
|
162
163
|
// TODO: Remove preview data from qs before next major release.
|
|
163
164
|
const propagatedQsParams = Object.assign(Object.assign({}, (0, utils_2.getQueryParamsForPropagation)(query)), editingPreviewData);
|
|
164
|
-
const propagatedHeaders = Object.assign(Object.assign({}, (0, utils_2.getHeadersForPropagation)(headers)), { [constants_1.EDITING_PARAMS_HEADER]: JSON.stringify(editingPreviewData) });
|
|
165
|
+
const propagatedHeaders = Object.assign(Object.assign({}, (0, utils_2.getHeadersForPropagation)(headers)), { [constants_1.EDITING_PARAMS_HEADER]: JSON.stringify(editingPreviewData), [constants_1.EDITING_SECRET_HEADER]: receivedSecret });
|
|
165
166
|
const html = await (0, utils_2.getEditingRequestHtml)(requestUrl, propagatedQsParams, propagatedHeaders, convertedCookies, dataFetcher);
|
|
166
167
|
// remove nextjs preview cookies to not leak them to the browser
|
|
167
168
|
const filteredCookies = (0, utils_2.cleanupNextPreviewCookies)(convertedCookies);
|
|
@@ -208,7 +209,8 @@ const createEditingRenderRouteHandlers = (options) => {
|
|
|
208
209
|
});
|
|
209
210
|
}
|
|
210
211
|
// Validate secret
|
|
211
|
-
|
|
212
|
+
const receivedSecret = req.nextUrl.searchParams.get(editing_1.QUERY_PARAM_EDITING_SECRET) || '';
|
|
213
|
+
if (!validateEditingSecret(receivedSecret)) {
|
|
212
214
|
return Response.json({
|
|
213
215
|
html: editing_1.INVALID_SECRET_HTML_MESSAGE,
|
|
214
216
|
}, { status: 401, headers: expectedCorsHeaders !== null && expectedCorsHeaders !== void 0 ? expectedCorsHeaders : {} });
|
|
@@ -244,6 +246,7 @@ const createEditingRenderRouteHandlers = (options) => {
|
|
|
244
246
|
const forwardHeaders = new Headers(req.headers);
|
|
245
247
|
forwardHeaders.set('cookie', forwardCookie);
|
|
246
248
|
forwardHeaders.set(constants_1.EDITING_PARAMS_HEADER, JSON.stringify(editingPreviewData));
|
|
249
|
+
forwardHeaders.set(constants_1.EDITING_SECRET_HEADER, receivedSecret);
|
|
247
250
|
const forwardedResponse = await dataFetcher.fetch(targetUrl.toString(), {
|
|
248
251
|
method: req.method,
|
|
249
252
|
headers: forwardHeaders,
|
|
@@ -8,6 +8,18 @@ const content_1 = require("@sitecore-content-sdk/content");
|
|
|
8
8
|
const codegen_1 = require("@sitecore-content-sdk/content/codegen");
|
|
9
9
|
const tools_1 = require("@sitecore-content-sdk/core/tools");
|
|
10
10
|
const editing_1 = require("@sitecore-content-sdk/content/editing");
|
|
11
|
+
const utils_1 = require("../utils/utils");
|
|
12
|
+
/**
|
|
13
|
+
* Fail-closed secret check for Design Library server actions.
|
|
14
|
+
* Does not log the token.
|
|
15
|
+
*/
|
|
16
|
+
const assertEditingSecretAuthorized = async () => {
|
|
17
|
+
if (await (0, utils_1.isDesignLibraryAuthorizedFromHeaders)()) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
content_1.debug.editing('empty / invalid editing secret');
|
|
21
|
+
throw new Error('Unauthorized');
|
|
22
|
+
};
|
|
11
23
|
/**
|
|
12
24
|
* Server action to update global cache with the provided component updates received from Design Library.
|
|
13
25
|
* Stores the given {@link ComponentUpdateModel} in the global cache using a key based on the component UID.
|
|
@@ -16,6 +28,7 @@ const editing_1 = require("@sitecore-content-sdk/content/editing");
|
|
|
16
28
|
* @returns A Promise that resolves when the cache has been updated.
|
|
17
29
|
*/
|
|
18
30
|
async function updateComponentAction(updatedComponent) {
|
|
31
|
+
await assertEditingSecretAuthorized();
|
|
19
32
|
content_1.debug.editing(`Updating server component cache for Update Component: ${updatedComponent.uid}`);
|
|
20
33
|
(0, tools_1.setCache)(`${editing_1.COMPONENT_UPDATE_CACHE_KEY_PREFIX}${updatedComponent.uid}`, updatedComponent);
|
|
21
34
|
(0, cache_1.refresh)();
|
|
@@ -30,6 +43,7 @@ async function updateComponentAction(updatedComponent) {
|
|
|
30
43
|
* @returns A Promise that resolves when the cache has been updated.
|
|
31
44
|
*/
|
|
32
45
|
async function previewComponentAction(previewEvent, rendering, edgeUrl) {
|
|
46
|
+
await assertEditingSecretAuthorized();
|
|
33
47
|
content_1.debug.editing(`Updating server component cache for Preview Component: ${previewEvent.uid}`);
|
|
34
48
|
const updatedComponent = {
|
|
35
49
|
uid: previewEvent.uid,
|
package/dist/cjs/utils/utils.js
CHANGED
|
@@ -1,8 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseRewriteHeader = exports.isServerSidePropsContext = exports.extractPath = exports.getEditingSecret = exports.handleEditorFastRefresh = void 0;
|
|
36
|
+
exports.parseRewriteHeader = exports.isServerSidePropsContext = exports.extractPath = exports.isDesignLibraryAuthorizedFromHeaders = exports.getEditingRequestHeaders = exports.getConfiguredEditingSecret = exports.getEditingSecret = exports.handleEditorFastRefresh = void 0;
|
|
4
37
|
const editing_1 = require("@sitecore-content-sdk/content/editing");
|
|
5
38
|
const proxy_1 = require("../proxy/proxy");
|
|
39
|
+
const constants_1 = require("../editing/constants");
|
|
6
40
|
/**
|
|
7
41
|
* Since Sitecore editors do not support Fast Refresh:
|
|
8
42
|
* 1. Subscribe on events provided by webpack.
|
|
@@ -42,6 +76,44 @@ const getEditingSecret = () => {
|
|
|
42
76
|
return secret;
|
|
43
77
|
};
|
|
44
78
|
exports.getEditingSecret = getEditingSecret;
|
|
79
|
+
/**
|
|
80
|
+
* Reads the raw configured editing secret without throwing.
|
|
81
|
+
* Empty and whitespace-only values are treated as unset.
|
|
82
|
+
* @returns The trimmed `SITECORE_EDITING_SECRET` value, or an empty string when unset.
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
const getConfiguredEditingSecret = () => {
|
|
86
|
+
return (process.env.SITECORE_EDITING_SECRET || '').trim();
|
|
87
|
+
};
|
|
88
|
+
exports.getConfiguredEditingSecret = getConfiguredEditingSecret;
|
|
89
|
+
/**
|
|
90
|
+
* Reads Next.js request headers when available (App Router / server actions).
|
|
91
|
+
* Returns null when `headers()` is unavailable so Pages Router callers can continue.
|
|
92
|
+
* @returns {Promise<Headers | null>} The request headers, or null.
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
const getEditingRequestHeaders = async () => {
|
|
96
|
+
try {
|
|
97
|
+
const { headers } = await Promise.resolve().then(() => __importStar(require('next/headers')));
|
|
98
|
+
return await headers();
|
|
99
|
+
}
|
|
100
|
+
catch (_a) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
exports.getEditingRequestHeaders = getEditingRequestHeaders;
|
|
105
|
+
/**
|
|
106
|
+
* Authorizes an editing/Design Library request from the internal secret header.
|
|
107
|
+
* Fail-closed: missing headers, empty env, placeholder, or mismatch → false.
|
|
108
|
+
* @returns {Promise<boolean>} True when the request carries a valid editing secret.
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
const isDesignLibraryAuthorizedFromHeaders = async () => {
|
|
112
|
+
const headerList = await (0, exports.getEditingRequestHeaders)();
|
|
113
|
+
const envSecret = (0, exports.getEditingSecret)();
|
|
114
|
+
return envSecret === (headerList === null || headerList === void 0 ? void 0 : headerList.get(constants_1.EDITING_SECRET_HEADER));
|
|
115
|
+
};
|
|
116
|
+
exports.isDesignLibraryAuthorizedFromHeaders = isDesignLibraryAuthorizedFromHeaders;
|
|
45
117
|
/**
|
|
46
118
|
* Extracts the path from the Next.js context parameters.
|
|
47
119
|
* @param {GetStaticPropsContext | GetServerSidePropsContext} context - The Next.js context parameters.
|
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { EDITING_COMPONENT_PLACEHOLDER } from '@sitecore-content-sdk/content/layout';
|
|
3
|
-
import { DesignLibraryServer } from './DesignLibraryServer';
|
|
4
|
-
import { DesignLibrary, noopLoadImportMap } from '@sitecore-content-sdk/react';
|
|
5
2
|
/**
|
|
6
|
-
* Design Library component intended to be used by the NextJs app router application
|
|
7
|
-
* This component serves as a router between client and server component rendering modes
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* - Client components are rendered using the `DesignLibrary` component
|
|
11
|
-
* - Server components are rendered using the `DesignLibraryServer` component
|
|
3
|
+
* Design Library component intended to be used by the NextJs app router application.
|
|
4
|
+
* This component serves as a router between client and server component rendering modes
|
|
5
|
+
* for the Design Library. The client/server runtime is loaded lazily so static import
|
|
6
|
+
* of `DesignLibrary` / `DesignLibraryServer` does not pull those modules into every render.
|
|
12
7
|
* @param {DesingLibraryAppProps} props - The properties for the Design Library App.
|
|
13
8
|
* @public
|
|
14
9
|
*/
|
|
15
|
-
export const DesignLibraryApp = (
|
|
16
|
-
|
|
17
|
-
const { route } = page.layout.sitecore;
|
|
18
|
-
if (!route)
|
|
10
|
+
export const DesignLibraryApp = async (props) => {
|
|
11
|
+
if (!props.page.layout.sitecore.route)
|
|
19
12
|
return null;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const isClient = component && component.componentType === 'client';
|
|
23
|
-
return (React.createElement(React.Fragment, null, isClient ? (React.createElement(DesignLibrary, null)) : (React.createElement(DesignLibraryServer, { page: page, componentMap: componentMap, loadServerImportMap: loadServerImportMap, rendering: route }))));
|
|
13
|
+
const { DesignLibraryRuntime } = await import('./DesignLibraryRuntime');
|
|
14
|
+
return React.createElement(DesignLibraryRuntime, Object.assign({}, props));
|
|
24
15
|
};
|
|
16
|
+
export default DesignLibraryApp;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { EDITING_COMPONENT_PLACEHOLDER } from '@sitecore-content-sdk/content/layout';
|
|
3
|
+
import { DesignLibraryServer } from './DesignLibraryServer';
|
|
4
|
+
import { DesignLibrary, noopLoadImportMap } from '@sitecore-content-sdk/react';
|
|
5
|
+
/**
|
|
6
|
+
* Internal Design Library renderer. Routes between client and server
|
|
7
|
+
* implementations after `DesignLibraryApp` has authorized the request.
|
|
8
|
+
* @param {DesingLibraryAppProps} props - The properties for the Design Library App.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export const DesignLibraryRuntime = ({ page, componentMap, loadServerImportMap = noopLoadImportMap, }) => {
|
|
12
|
+
var _a;
|
|
13
|
+
const { route } = page.layout.sitecore;
|
|
14
|
+
if (!route)
|
|
15
|
+
return null;
|
|
16
|
+
const rendering = (_a = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER]) === null || _a === void 0 ? void 0 : _a[0];
|
|
17
|
+
const component = componentMap.get((rendering === null || rendering === void 0 ? void 0 : rendering.componentName) || '');
|
|
18
|
+
const isClient = component && component.componentType === 'client';
|
|
19
|
+
return (React.createElement(React.Fragment, null, isClient ? (React.createElement(DesignLibrary, null)) : (React.createElement(DesignLibraryServer, { page: page, componentMap: componentMap, loadServerImportMap: loadServerImportMap, rendering: route }))));
|
|
20
|
+
};
|
|
@@ -10,3 +10,9 @@ export const EDITING_PASS_THROUGH_HEADERS = ['authorization', 'cookie'];
|
|
|
10
10
|
* route handler to the Next.js page when running in App Router.
|
|
11
11
|
*/
|
|
12
12
|
export const EDITING_PARAMS_HEADER = 'x-sitecore-editing-params';
|
|
13
|
+
/**
|
|
14
|
+
* Header used to forward the already-validated editing secret from the editing
|
|
15
|
+
* render handler/middleware to the internal Next.js page or server-action request.
|
|
16
|
+
* Do not put this value in `EDITING_PARAMS_HEADER` JSON.
|
|
17
|
+
*/
|
|
18
|
+
export const EDITING_SECRET_HEADER = 'x-sitecore-editing-secret';
|
|
@@ -5,7 +5,7 @@ import { LayoutServicePageState } from '@sitecore-content-sdk/content/layout';
|
|
|
5
5
|
import { getEditingSecret } from '../utils/utils';
|
|
6
6
|
import { draftMode, cookies as nextCokies } from 'next/headers';
|
|
7
7
|
import { mapEditingParams, getEditingRequestHtml, cleanupNextPreviewCookies, getHeadersForPropagation, getQueryParamsForPropagation, getRequiredEditingParamsList, getCSPHeader, resolveServerUrl, PREVIEW_COOKIES, getAllowedQueryParams, } from '../editing/utils';
|
|
8
|
-
import { EDITING_PARAMS_HEADER } from '../editing/constants';
|
|
8
|
+
import { EDITING_PARAMS_HEADER, EDITING_SECRET_HEADER } from '../editing/constants';
|
|
9
9
|
import { SITE_KEY } from '@sitecore-content-sdk/content/site';
|
|
10
10
|
import debug from '../debug';
|
|
11
11
|
/**
|
|
@@ -87,7 +87,8 @@ export const createEditingRenderRouteHandlers = (options) => {
|
|
|
87
87
|
}
|
|
88
88
|
const responseHeaders = expectedCorsHeaders;
|
|
89
89
|
// Validate secret
|
|
90
|
-
|
|
90
|
+
const receivedSecret = query[QUERY_PARAM_EDITING_SECRET];
|
|
91
|
+
if (!validateEditingSecret(receivedSecret)) {
|
|
91
92
|
return Response.json({
|
|
92
93
|
html: INVALID_SECRET_HTML_MESSAGE,
|
|
93
94
|
}, { status: 401, headers: responseHeaders });
|
|
@@ -154,7 +155,7 @@ export const createEditingRenderRouteHandlers = (options) => {
|
|
|
154
155
|
// `EDITING_PARAMS_HEADER` instead via `client.getPreviewInputs`.
|
|
155
156
|
// TODO: Remove preview data from qs before next major release.
|
|
156
157
|
const propagatedQsParams = Object.assign(Object.assign({}, getQueryParamsForPropagation(query)), editingPreviewData);
|
|
157
|
-
const propagatedHeaders = Object.assign(Object.assign({}, getHeadersForPropagation(headers)), { [EDITING_PARAMS_HEADER]: JSON.stringify(editingPreviewData) });
|
|
158
|
+
const propagatedHeaders = Object.assign(Object.assign({}, getHeadersForPropagation(headers)), { [EDITING_PARAMS_HEADER]: JSON.stringify(editingPreviewData), [EDITING_SECRET_HEADER]: receivedSecret });
|
|
158
159
|
const html = await getEditingRequestHtml(requestUrl, propagatedQsParams, propagatedHeaders, convertedCookies, dataFetcher);
|
|
159
160
|
// remove nextjs preview cookies to not leak them to the browser
|
|
160
161
|
const filteredCookies = cleanupNextPreviewCookies(convertedCookies);
|
|
@@ -201,7 +202,8 @@ export const createEditingRenderRouteHandlers = (options) => {
|
|
|
201
202
|
});
|
|
202
203
|
}
|
|
203
204
|
// Validate secret
|
|
204
|
-
|
|
205
|
+
const receivedSecret = req.nextUrl.searchParams.get(QUERY_PARAM_EDITING_SECRET) || '';
|
|
206
|
+
if (!validateEditingSecret(receivedSecret)) {
|
|
205
207
|
return Response.json({
|
|
206
208
|
html: INVALID_SECRET_HTML_MESSAGE,
|
|
207
209
|
}, { status: 401, headers: expectedCorsHeaders !== null && expectedCorsHeaders !== void 0 ? expectedCorsHeaders : {} });
|
|
@@ -237,6 +239,7 @@ export const createEditingRenderRouteHandlers = (options) => {
|
|
|
237
239
|
const forwardHeaders = new Headers(req.headers);
|
|
238
240
|
forwardHeaders.set('cookie', forwardCookie);
|
|
239
241
|
forwardHeaders.set(EDITING_PARAMS_HEADER, JSON.stringify(editingPreviewData));
|
|
242
|
+
forwardHeaders.set(EDITING_SECRET_HEADER, receivedSecret);
|
|
240
243
|
const forwardedResponse = await dataFetcher.fetch(targetUrl.toString(), {
|
|
241
244
|
method: req.method,
|
|
242
245
|
headers: forwardHeaders,
|
|
@@ -4,6 +4,18 @@ import { debug } from '@sitecore-content-sdk/content';
|
|
|
4
4
|
import { fetchGeneratedComponentFromCache, } from '@sitecore-content-sdk/content/codegen';
|
|
5
5
|
import { setCache } from '@sitecore-content-sdk/core/tools';
|
|
6
6
|
import { COMPONENT_UPDATE_CACHE_KEY_PREFIX, COMPONENT_PREVIEW_CACHE_KEY_PREFIX, } from '@sitecore-content-sdk/content/editing';
|
|
7
|
+
import { isDesignLibraryAuthorizedFromHeaders } from '../utils/utils';
|
|
8
|
+
/**
|
|
9
|
+
* Fail-closed secret check for Design Library server actions.
|
|
10
|
+
* Does not log the token.
|
|
11
|
+
*/
|
|
12
|
+
const assertEditingSecretAuthorized = async () => {
|
|
13
|
+
if (await isDesignLibraryAuthorizedFromHeaders()) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
debug.editing('empty / invalid editing secret');
|
|
17
|
+
throw new Error('Unauthorized');
|
|
18
|
+
};
|
|
7
19
|
/**
|
|
8
20
|
* Server action to update global cache with the provided component updates received from Design Library.
|
|
9
21
|
* Stores the given {@link ComponentUpdateModel} in the global cache using a key based on the component UID.
|
|
@@ -12,6 +24,7 @@ import { COMPONENT_UPDATE_CACHE_KEY_PREFIX, COMPONENT_PREVIEW_CACHE_KEY_PREFIX,
|
|
|
12
24
|
* @returns A Promise that resolves when the cache has been updated.
|
|
13
25
|
*/
|
|
14
26
|
export async function updateComponentAction(updatedComponent) {
|
|
27
|
+
await assertEditingSecretAuthorized();
|
|
15
28
|
debug.editing(`Updating server component cache for Update Component: ${updatedComponent.uid}`);
|
|
16
29
|
setCache(`${COMPONENT_UPDATE_CACHE_KEY_PREFIX}${updatedComponent.uid}`, updatedComponent);
|
|
17
30
|
refresh();
|
|
@@ -26,6 +39,7 @@ export async function updateComponentAction(updatedComponent) {
|
|
|
26
39
|
* @returns A Promise that resolves when the cache has been updated.
|
|
27
40
|
*/
|
|
28
41
|
export async function previewComponentAction(previewEvent, rendering, edgeUrl) {
|
|
42
|
+
await assertEditingSecretAuthorized();
|
|
29
43
|
debug.editing(`Updating server component cache for Preview Component: ${previewEvent.uid}`);
|
|
30
44
|
const updatedComponent = {
|
|
31
45
|
uid: previewEvent.uid,
|
package/dist/esm/utils/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isEditorActive, resetEditorChromes } from '@sitecore-content-sdk/content/editing';
|
|
2
2
|
import { REWRITE_HEADER_NAME } from '../proxy/proxy';
|
|
3
|
+
import { EDITING_SECRET_HEADER } from '../editing/constants';
|
|
3
4
|
/**
|
|
4
5
|
* Since Sitecore editors do not support Fast Refresh:
|
|
5
6
|
* 1. Subscribe on events provided by webpack.
|
|
@@ -37,6 +38,41 @@ export const getEditingSecret = () => {
|
|
|
37
38
|
}
|
|
38
39
|
return secret;
|
|
39
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Reads the raw configured editing secret without throwing.
|
|
43
|
+
* Empty and whitespace-only values are treated as unset.
|
|
44
|
+
* @returns The trimmed `SITECORE_EDITING_SECRET` value, or an empty string when unset.
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export const getConfiguredEditingSecret = () => {
|
|
48
|
+
return (process.env.SITECORE_EDITING_SECRET || '').trim();
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Reads Next.js request headers when available (App Router / server actions).
|
|
52
|
+
* Returns null when `headers()` is unavailable so Pages Router callers can continue.
|
|
53
|
+
* @returns {Promise<Headers | null>} The request headers, or null.
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
export const getEditingRequestHeaders = async () => {
|
|
57
|
+
try {
|
|
58
|
+
const { headers } = await import('next/headers');
|
|
59
|
+
return await headers();
|
|
60
|
+
}
|
|
61
|
+
catch (_a) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Authorizes an editing/Design Library request from the internal secret header.
|
|
67
|
+
* Fail-closed: missing headers, empty env, placeholder, or mismatch → false.
|
|
68
|
+
* @returns {Promise<boolean>} True when the request carries a valid editing secret.
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
export const isDesignLibraryAuthorizedFromHeaders = async () => {
|
|
72
|
+
const headerList = await getEditingRequestHeaders();
|
|
73
|
+
const envSecret = getEditingSecret();
|
|
74
|
+
return envSecret === (headerList === null || headerList === void 0 ? void 0 : headerList.get(EDITING_SECRET_HEADER));
|
|
75
|
+
};
|
|
40
76
|
/**
|
|
41
77
|
* Extracts the path from the Next.js context parameters.
|
|
42
78
|
* @param {GetStaticPropsContext | GetServerSidePropsContext} context - The Next.js context parameters.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitecore-content-sdk/nextjs",
|
|
3
|
-
"version": "2.5.1
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@sitecore-content-sdk/content": "^2.4.0",
|
|
99
99
|
"@sitecore-content-sdk/core": "^2.1.4",
|
|
100
100
|
"@sitecore-content-sdk/events": "^2.1.2",
|
|
101
|
-
"@sitecore-content-sdk/react": "2.5.
|
|
101
|
+
"@sitecore-content-sdk/react": "^2.5.0",
|
|
102
102
|
"recast": "^0.23.11",
|
|
103
103
|
"regex-parser": "^2.3.1"
|
|
104
104
|
},
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DesingLibraryAppProps } from './models';
|
|
3
3
|
/**
|
|
4
|
-
* Design Library component intended to be used by the NextJs app router application
|
|
5
|
-
* This component serves as a router between client and server component rendering modes
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Client components are rendered using the `DesignLibrary` component
|
|
9
|
-
* - Server components are rendered using the `DesignLibraryServer` component
|
|
4
|
+
* Design Library component intended to be used by the NextJs app router application.
|
|
5
|
+
* This component serves as a router between client and server component rendering modes
|
|
6
|
+
* for the Design Library. The client/server runtime is loaded lazily so static import
|
|
7
|
+
* of `DesignLibrary` / `DesignLibraryServer` does not pull those modules into every render.
|
|
10
8
|
* @param {DesingLibraryAppProps} props - The properties for the Design Library App.
|
|
11
9
|
* @public
|
|
12
10
|
*/
|
|
13
|
-
export declare const DesignLibraryApp: (
|
|
11
|
+
export declare const DesignLibraryApp: (props: DesingLibraryAppProps) => Promise<React.JSX.Element | null>;
|
|
12
|
+
export default DesignLibraryApp;
|
|
14
13
|
//# sourceMappingURL=DesignLibraryApp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DesignLibraryApp.d.ts","sourceRoot":"","sources":["../../../src/components/DesignLibrary/DesignLibraryApp.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DesignLibraryApp.d.ts","sourceRoot":"","sources":["../../../src/components/DesignLibrary/DesignLibraryApp.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC3B,OAAO,qBAAqB,KAC3B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAKlC,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DesingLibraryAppProps } from './models';
|
|
3
|
+
/**
|
|
4
|
+
* Internal Design Library renderer. Routes between client and server
|
|
5
|
+
* implementations after `DesignLibraryApp` has authorized the request.
|
|
6
|
+
* @param {DesingLibraryAppProps} props - The properties for the Design Library App.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const DesignLibraryRuntime: ({ page, componentMap, loadServerImportMap, }: DesingLibraryAppProps) => React.JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=DesignLibraryRuntime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DesignLibraryRuntime.d.ts","sourceRoot":"","sources":["../../../src/components/DesignLibrary/DesignLibraryRuntime.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAIjD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,8CAIlC,qBAAqB,6BAsBvB,CAAC"}
|
|
@@ -10,4 +10,10 @@ export declare const EDITING_PASS_THROUGH_HEADERS: string[];
|
|
|
10
10
|
* route handler to the Next.js page when running in App Router.
|
|
11
11
|
*/
|
|
12
12
|
export declare const EDITING_PARAMS_HEADER = "x-sitecore-editing-params";
|
|
13
|
+
/**
|
|
14
|
+
* Header used to forward the already-validated editing secret from the editing
|
|
15
|
+
* render handler/middleware to the internal Next.js page or server-action request.
|
|
16
|
+
* Do not put this value in `EDITING_PARAMS_HEADER` JSON.
|
|
17
|
+
*/
|
|
18
|
+
export declare const EDITING_SECRET_HEADER = "x-sitecore-editing-secret";
|
|
13
19
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/editing/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oCAAoC,+BAA+B,CAAC;AACjF,eAAO,MAAM,oCAAoC,+BAA+B,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,UAA8B,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/editing/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oCAAoC,+BAA+B,CAAC;AACjF,eAAO,MAAM,oCAAoC,+BAA+B,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,UAA8B,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,8BAA8B,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,8BAA8B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editing-render-route-handler.d.ts","sourceRoot":"","sources":["../../src/route-handler/editing-render-route-handler.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkB1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;GAGG;AACH,wBAAsB,cAAc,iBAMnC;AAED,KAAK,qBAAqB,GAAG;IAC3B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAAI,SAAS,qBAAqB;eAwDrD,WAAW;
|
|
1
|
+
{"version":3,"file":"editing-render-route-handler.d.ts","sourceRoot":"","sources":["../../src/route-handler/editing-render-route-handler.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkB1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;GAGG;AACH,wBAAsB,cAAc,iBAMnC;AAED,KAAK,qBAAqB,GAAG;IAC3B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAAI,SAAS,qBAAqB;eAwDrD,WAAW;gBA8KV,WAAW;mBAhMd,WAAW;CAuTlC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-server-component-action.d.ts","sourceRoot":"","sources":["../../src/server-actions/update-server-component-action.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EACL,+BAA+B,EAC/B,sBAAsB,EAEvB,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"update-server-component-action.d.ts","sourceRoot":"","sources":["../../src/server-actions/update-server-component-action.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EACL,+BAA+B,EAC/B,sBAAsB,EAEvB,MAAM,uCAAuC,CAAC;AAoB/C,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B;;OAEG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;OAEG;IACH,SAAS,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACtC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,IAAI,EAAE,+BAA+B,CAAC;CACvC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,gBAAgB,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKjG;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,iBAAiB,EAC/B,SAAS,EAAE,kBAAkB,GAAG,IAAI,EACpC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiCf"}
|
package/types/utils/utils.d.ts
CHANGED
|
@@ -8,6 +8,27 @@ import { GetServerSidePropsContext, GetStaticPropsContext } from 'next';
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const handleEditorFastRefresh: (forceReload?: boolean) => void;
|
|
10
10
|
export declare const getEditingSecret: () => string;
|
|
11
|
+
/**
|
|
12
|
+
* Reads the raw configured editing secret without throwing.
|
|
13
|
+
* Empty and whitespace-only values are treated as unset.
|
|
14
|
+
* @returns The trimmed `SITECORE_EDITING_SECRET` value, or an empty string when unset.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export declare const getConfiguredEditingSecret: () => string;
|
|
18
|
+
/**
|
|
19
|
+
* Reads Next.js request headers when available (App Router / server actions).
|
|
20
|
+
* Returns null when `headers()` is unavailable so Pages Router callers can continue.
|
|
21
|
+
* @returns {Promise<Headers | null>} The request headers, or null.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export declare const getEditingRequestHeaders: () => Promise<Headers | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Authorizes an editing/Design Library request from the internal secret header.
|
|
27
|
+
* Fail-closed: missing headers, empty env, placeholder, or mismatch → false.
|
|
28
|
+
* @returns {Promise<boolean>} True when the request carries a valid editing secret.
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export declare const isDesignLibraryAuthorizedFromHeaders: () => Promise<boolean>;
|
|
11
32
|
/**
|
|
12
33
|
* Extracts the path from the Next.js context parameters.
|
|
13
34
|
* @param {GetStaticPropsContext | GetServerSidePropsContext} context - The Next.js context parameters.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAC;AAIxE;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAAI,qBAAmB,KAAG,IA6B7D,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,MAMnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,QAAO,MAE7C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,OAAO,GAAG,IAAI,CAOvE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,QAAa,OAAO,CAAC,OAAO,CAI5E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,qBAAqB,GAAG,yBAAyB,WAMrF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,SAAS,yBAAyB,GAAG,qBAAqB,KACzD,OAAO,IAAI,yBAEb,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,OAAO;;;CAMlD,CAAC"}
|