@cmssy/next 16.7.0 → 16.8.0

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/README.md CHANGED
@@ -113,7 +113,8 @@ re-exported from `@cmssy/next` (and `@cmssy/core`).
113
113
  ## Exports
114
114
 
115
115
  `@cmssy/next/server`: `createCmssyPage`, `createCmssyEditPage`,
116
- `createDraftRoute`, `createCmssyRevalidateRoute`, `CmssyLayoutSlot`,
116
+ `createDraftRoute`, `createCmssyRevalidateRoute`, `createCmssyBlockDataRoute`,
117
+ `CmssyLayoutSlot`,
117
118
  `resolveCmssyLayout`, `isCmssyEditMode`. `@cmssy/next/middleware`:
118
119
  `createCmssyProxy`, `cmssyEditRewrite`, `applyCmssyCsp`, `isCmssyEditRequest`.
119
120
  Root: `defineCmssyConfig`, `localizeHref`, `nextRetryMode`, `cmssyCachedFetch`,
package/dist/server.cjs CHANGED
@@ -4,10 +4,10 @@ require('server-only');
4
4
  var headers = require('next/headers');
5
5
  var navigation = require('next/navigation');
6
6
  var react = require('@cmssy/react');
7
+ var core = require('@cmssy/core');
7
8
  var internal$1 = require('@cmssy/react/internal');
8
9
  var internalServer = require('@cmssy/react/internal-server');
9
10
  var internal = require('@cmssy/core/internal');
10
- var core = require('@cmssy/core');
11
11
  var jsxRuntime = require('react/jsx-runtime');
12
12
  var cache = require('next/cache');
13
13
 
@@ -147,7 +147,13 @@ function buildCmssyPageRenderer(config, blocks, options, editRoute) {
147
147
  enabledLocales,
148
148
  edit: {
149
149
  editorOrigin: bridgeOrigin,
150
- ...config.layout ? { layoutRegions: config.layout.regions } : {}
150
+ ...config.layout ? { layoutRegions: config.layout.regions } : {},
151
+ ...config.draftSecret ? {
152
+ blockDataToken: await core.mintCmssyEditToken(
153
+ config.draftSecret,
154
+ { page: page.slug ?? "" }
155
+ )
156
+ } : {}
151
157
  },
152
158
  forms,
153
159
  data: editorData.data,
@@ -218,7 +224,8 @@ async function renderNothingPublishedPage(config, path) {
218
224
  shown
219
225
  ] }),
220
226
  /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: "0 0 1rem" }, children: [
221
- "Your app is wired to workspace ",
227
+ "Your app is wired to workspace",
228
+ " ",
222
229
  /* @__PURE__ */ jsxRuntime.jsxs("code", { children: [
223
230
  config.org,
224
231
  "/",
@@ -379,12 +386,19 @@ async function CmssyLayoutSlot({
379
386
  const { groups, settings, page: routed, element } = layout;
380
387
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children({ groups, settings, page: routed, element }) });
381
388
  }
389
+ function pageOf(body) {
390
+ if (typeof body !== "object" || body === null) return "";
391
+ const page = body.page;
392
+ if (typeof page !== "object" || page === null) return "";
393
+ const slug = page.slug;
394
+ return typeof slug === "string" ? slug : "";
395
+ }
382
396
  function createCmssyBlockDataRoute(config, blocks, options = {}) {
383
397
  return async function POST(request) {
384
- if (!await isCmssyEditMode()) {
398
+ if (!config.draftSecret) {
385
399
  return new Response(
386
- "cmssy: block data is only resolved for a verified editor request",
387
- { status: 403 }
400
+ "cmssy: createCmssyBlockDataRoute needs config.draftSecret to verify the editor",
401
+ { status: 500 }
388
402
  );
389
403
  }
390
404
  let body;
@@ -393,9 +407,18 @@ function createCmssyBlockDataRoute(config, blocks, options = {}) {
393
407
  } catch {
394
408
  return Response.json(
395
409
  { message: "cmssy: body is not JSON" },
396
- {
397
- status: 400
398
- }
410
+ { status: 400 }
411
+ );
412
+ }
413
+ const authorized = await core.verifyCmssyEditToken(
414
+ request.headers.get(core.CMSSY_EDIT_TOKEN_HEADER),
415
+ config.draftSecret,
416
+ { page: pageOf(body) }
417
+ );
418
+ if (!authorized) {
419
+ return new Response(
420
+ "cmssy: block data needs the edit token the editor page was rendered with",
421
+ { status: 403 }
399
422
  );
400
423
  }
401
424
  return react.handleBlockDataRequest(body, { blocks, config, ...options });
package/dist/server.d.cts CHANGED
@@ -56,6 +56,8 @@ interface CmssyBlockDataRouteConfig {
56
56
  appContext?: Record<string, unknown>;
57
57
  workspaceId?: string;
58
58
  }
59
- declare function createCmssyBlockDataRoute(config: CmssyClientConfig, blocks: BlockDefinition[], options?: CmssyBlockDataRouteConfig): (request: Request) => Promise<Response>;
59
+ declare function createCmssyBlockDataRoute(config: CmssyClientConfig & {
60
+ draftSecret?: string;
61
+ }, blocks: BlockDefinition[], options?: CmssyBlockDataRouteConfig): (request: Request) => Promise<Response>;
60
62
 
61
63
  export { type CmssyBlockDataRouteConfig, CmssyDataCacheOptions, type CmssyDraftRouteConfig, CmssyLayoutSlot, type CmssyLayoutSlotProps, type CmssyLayoutSlotRenderProps, type CmssyRevalidateRouteConfig, type ResolveCmssyLayoutOptions, createCmssyBlockDataRoute, createCmssyRevalidateRoute, createDraftRoute, isCmssyEditMode, resolveCmssyLayout };
package/dist/server.d.ts CHANGED
@@ -56,6 +56,8 @@ interface CmssyBlockDataRouteConfig {
56
56
  appContext?: Record<string, unknown>;
57
57
  workspaceId?: string;
58
58
  }
59
- declare function createCmssyBlockDataRoute(config: CmssyClientConfig, blocks: BlockDefinition[], options?: CmssyBlockDataRouteConfig): (request: Request) => Promise<Response>;
59
+ declare function createCmssyBlockDataRoute(config: CmssyClientConfig & {
60
+ draftSecret?: string;
61
+ }, blocks: BlockDefinition[], options?: CmssyBlockDataRouteConfig): (request: Request) => Promise<Response>;
60
62
 
61
63
  export { type CmssyBlockDataRouteConfig, CmssyDataCacheOptions, type CmssyDraftRouteConfig, CmssyLayoutSlot, type CmssyLayoutSlotProps, type CmssyLayoutSlotRenderProps, type CmssyRevalidateRouteConfig, type ResolveCmssyLayoutOptions, createCmssyBlockDataRoute, createCmssyRevalidateRoute, createDraftRoute, isCmssyEditMode, resolveCmssyLayout };
package/dist/server.js CHANGED
@@ -2,10 +2,10 @@ import 'server-only';
2
2
  import { draftMode, headers } from 'next/headers';
3
3
  import { notFound, redirect } from 'next/navigation';
4
4
  import { createCmssyClient, CmssyServerPage, resolveCmssyLayout as resolveCmssyLayout$1, handleBlockDataRequest } from '@cmssy/react';
5
+ import { mintCmssyEditToken, CMSSY_SECRET_QUERY_PARAM, resolveEditorOrigin, verifyCmssyWebhook, CmssyWebhookError, CMSSY_EDIT_HEADER, verifyCmssyEditToken, CMSSY_EDIT_TOKEN_HEADER, CMSSY_EDIT_QUERY_PARAM } from '@cmssy/core';
5
6
  import { CmssyLocaleProvider } from '@cmssy/react/internal';
6
7
  import { blocksToSchemas, resolveEditorBlockData } from '@cmssy/react/internal-server';
7
8
  import { isDevelopment, resolveSiteLocales, splitLocaleFromPath, fetchPage, resolveForms, toCspOrigin, cmssySecretsMatch } from '@cmssy/core/internal';
8
- import { CMSSY_SECRET_QUERY_PARAM, resolveEditorOrigin, verifyCmssyWebhook, CmssyWebhookError, CMSSY_EDIT_HEADER, CMSSY_EDIT_QUERY_PARAM } from '@cmssy/core';
9
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
10
  import { revalidateTag } from 'next/cache';
11
11
 
@@ -145,7 +145,13 @@ function buildCmssyPageRenderer(config, blocks, options, editRoute) {
145
145
  enabledLocales,
146
146
  edit: {
147
147
  editorOrigin: bridgeOrigin,
148
- ...config.layout ? { layoutRegions: config.layout.regions } : {}
148
+ ...config.layout ? { layoutRegions: config.layout.regions } : {},
149
+ ...config.draftSecret ? {
150
+ blockDataToken: await mintCmssyEditToken(
151
+ config.draftSecret,
152
+ { page: page.slug ?? "" }
153
+ )
154
+ } : {}
149
155
  },
150
156
  forms,
151
157
  data: editorData.data,
@@ -216,7 +222,8 @@ async function renderNothingPublishedPage(config, path) {
216
222
  shown
217
223
  ] }),
218
224
  /* @__PURE__ */ jsxs("p", { style: { margin: "0 0 1rem" }, children: [
219
- "Your app is wired to workspace ",
225
+ "Your app is wired to workspace",
226
+ " ",
220
227
  /* @__PURE__ */ jsxs("code", { children: [
221
228
  config.org,
222
229
  "/",
@@ -377,12 +384,19 @@ async function CmssyLayoutSlot({
377
384
  const { groups, settings, page: routed, element } = layout;
378
385
  return /* @__PURE__ */ jsx(Fragment, { children: children({ groups, settings, page: routed, element }) });
379
386
  }
387
+ function pageOf(body) {
388
+ if (typeof body !== "object" || body === null) return "";
389
+ const page = body.page;
390
+ if (typeof page !== "object" || page === null) return "";
391
+ const slug = page.slug;
392
+ return typeof slug === "string" ? slug : "";
393
+ }
380
394
  function createCmssyBlockDataRoute(config, blocks, options = {}) {
381
395
  return async function POST(request) {
382
- if (!await isCmssyEditMode()) {
396
+ if (!config.draftSecret) {
383
397
  return new Response(
384
- "cmssy: block data is only resolved for a verified editor request",
385
- { status: 403 }
398
+ "cmssy: createCmssyBlockDataRoute needs config.draftSecret to verify the editor",
399
+ { status: 500 }
386
400
  );
387
401
  }
388
402
  let body;
@@ -391,9 +405,18 @@ function createCmssyBlockDataRoute(config, blocks, options = {}) {
391
405
  } catch {
392
406
  return Response.json(
393
407
  { message: "cmssy: body is not JSON" },
394
- {
395
- status: 400
396
- }
408
+ { status: 400 }
409
+ );
410
+ }
411
+ const authorized = await verifyCmssyEditToken(
412
+ request.headers.get(CMSSY_EDIT_TOKEN_HEADER),
413
+ config.draftSecret,
414
+ { page: pageOf(body) }
415
+ );
416
+ if (!authorized) {
417
+ return new Response(
418
+ "cmssy: block data needs the edit token the editor page was rendered with",
419
+ { status: 403 }
397
420
  );
398
421
  }
399
422
  return handleBlockDataRequest(body, { blocks, config, ...options });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/next",
3
- "version": "16.7.0",
3
+ "version": "16.8.0",
4
4
  "description": "Next.js App Router bindings for cmssy headless sites (createCmssyPage + draft preview)",
5
5
  "keywords": [
6
6
  "cmssy",
@@ -71,7 +71,7 @@
71
71
  "dist"
72
72
  ],
73
73
  "peerDependencies": {
74
- "@cmssy/react": "^16.7.0",
74
+ "@cmssy/react": "^16.8.0",
75
75
  "next": ">=15",
76
76
  "react": "^18.2.0 || ^19.0.0",
77
77
  "react-dom": "^18.2.0 || ^19.0.0"
@@ -85,12 +85,12 @@
85
85
  "tsup": "^8.3.0",
86
86
  "typescript": "^5.6.0",
87
87
  "vitest": "^2.1.0",
88
- "@cmssy/react": "16.7.0"
88
+ "@cmssy/react": "16.8.0"
89
89
  },
90
90
  "dependencies": {
91
91
  "@cmssy/types": "0.49.0",
92
92
  "server-only": "^0.0.1",
93
- "@cmssy/core": "16.7.0"
93
+ "@cmssy/core": "16.8.0"
94
94
  },
95
95
  "scripts": {
96
96
  "build": "tsup",