@revealui/core 0.9.0 → 0.10.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.
Files changed (58) hide show
  1. package/README.md +8 -0
  2. package/dist/client/admin/components/AdminDashboard.d.ts +7 -1
  3. package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
  4. package/dist/client/admin/components/AdminDashboard.js +13 -16
  5. package/dist/client/admin/components/CollectionList.d.ts +2 -1
  6. package/dist/client/admin/components/CollectionList.d.ts.map +1 -1
  7. package/dist/client/admin/components/CollectionList.js +5 -5
  8. package/dist/client/admin/components/DocumentForm.d.ts +2 -1
  9. package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
  10. package/dist/client/admin/components/DocumentForm.js +16 -16
  11. package/dist/client/admin/components/GlobalForm.d.ts +2 -1
  12. package/dist/client/admin/components/GlobalForm.d.ts.map +1 -1
  13. package/dist/client/admin/components/GlobalForm.js +3 -3
  14. package/dist/client/admin/context/ServerFunctionContext.d.ts +1 -1
  15. package/dist/client/admin/context/ServerFunctionContext.d.ts.map +1 -1
  16. package/dist/client/admin/layout.d.ts +1 -1
  17. package/dist/client/admin/layout.d.ts.map +1 -1
  18. package/dist/client/admin/layout.js +5 -1
  19. package/dist/client/admin/page.d.ts +2 -2
  20. package/dist/client/admin/page.d.ts.map +1 -1
  21. package/dist/client/admin/page.js +10 -3
  22. package/dist/client/admin/utils/apiClient.d.ts.map +1 -1
  23. package/dist/client/admin/utils/apiClient.js +2 -12
  24. package/dist/client/admin/utils/csrf.d.ts +25 -0
  25. package/dist/client/admin/utils/csrf.d.ts.map +1 -0
  26. package/dist/client/admin/utils/csrf.js +51 -0
  27. package/dist/client/admin/utils/index.d.ts +1 -0
  28. package/dist/client/admin/utils/index.d.ts.map +1 -1
  29. package/dist/client/admin/utils/index.js +1 -0
  30. package/dist/client/richtext/RichTextEditor.d.ts +1 -1
  31. package/dist/client/richtext/RichTextEditor.d.ts.map +1 -1
  32. package/dist/client/richtext/components/ImageUploadButton.d.ts.map +1 -1
  33. package/dist/client/richtext/components/ImageUploadButton.js +2 -5
  34. package/dist/client/richtext/components/upload.d.ts +21 -0
  35. package/dist/client/richtext/components/upload.d.ts.map +1 -0
  36. package/dist/client/richtext/components/upload.js +29 -0
  37. package/dist/client/richtext/plugins/CollaborationPlugin.d.ts +1 -1
  38. package/dist/client/richtext/plugins/CollaborationPlugin.d.ts.map +1 -1
  39. package/dist/client/richtext/plugins/ToolbarPlugin.d.ts +1 -1
  40. package/dist/client/richtext/plugins/ToolbarPlugin.d.ts.map +1 -1
  41. package/dist/nextjs/withRevealUI.d.ts +7 -2
  42. package/dist/nextjs/withRevealUI.d.ts.map +1 -1
  43. package/dist/nextjs/withRevealUI.js +9 -99
  44. package/dist/revforge-license.d.ts +4 -2
  45. package/dist/revforge-license.d.ts.map +1 -1
  46. package/dist/revforge-license.js +21 -3
  47. package/dist/richtext/exports/server/rsc.d.ts +3 -3
  48. package/dist/richtext/exports/server/rsc.d.ts.map +1 -1
  49. package/dist/storage/_sigv4.d.ts +76 -0
  50. package/dist/storage/_sigv4.d.ts.map +1 -0
  51. package/dist/storage/_sigv4.js +134 -0
  52. package/dist/storage/_xml.d.ts +26 -0
  53. package/dist/storage/_xml.d.ts.map +1 -0
  54. package/dist/storage/_xml.js +75 -0
  55. package/dist/storage/r2.d.ts +14 -2
  56. package/dist/storage/r2.d.ts.map +1 -1
  57. package/dist/storage/r2.js +107 -44
  58. package/package.json +22 -23
@@ -2,14 +2,21 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  export function RootPage({ config }) {
3
3
  const collections = (config.collections || []);
4
4
  const globals = (config.globals || []);
5
- return (_jsxs("div", { className: "min-h-screen bg-gray-50", children: [_jsx("header", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-gray-900", children: "RevealUI Admin" }) }), _jsx("div", { className: "flex items-center space-x-4", children: _jsx("span", { className: "text-sm text-gray-500", children: "v0.1.0" }) })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-white overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Collections icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-gray-500 truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-gray-900", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-gray-50 px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1", children: collections.map((collection) => (_jsxs("li", { className: "text-gray-600", children: [_jsx("span", { className: "font-medium", children: collection.slug }), _jsxs("span", { className: "ml-2 text-xs text-gray-400", children: ["(", collection.fields?.length || 0, " fields)"] })] }, collection.slug))) })) : (_jsx("p", { className: "text-gray-500", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-white overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Globals icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-gray-500 truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-gray-900", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-gray-50 px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1", children: globals.map((global) => (_jsxs("li", { className: "text-gray-600", children: [_jsx("span", { className: "font-medium", children: global.slug }), _jsxs("span", { className: "ml-2 text-xs text-gray-400", children: ["(", global.fields?.length || 0, " fields)"] })] }, global.slug))) })) : (_jsx("p", { className: "text-gray-500", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-white overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-green-100 rounded-full flex items-center justify-center", children: _jsxs("svg", { className: "h-5 w-5 text-green-600", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "System operational" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })] }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-gray-500 truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-gray-900", children: "Operational" })] }) })] }) }), _jsx("div", { className: "bg-gray-50 px-5 py-3", children: _jsxs("div", { className: "text-sm text-gray-600", children: ["RevealUI admin is running successfully with ", collections.length, " collections and", ' ', globals.length, " globals configured."] }) })] })] }) }) })] }));
5
+ // Server component: white-label kits override via REVEALUI_BRAND_NAME /
6
+ // REVEALUI_TENANT_NAME. `||` not `??`: Compose `${VAR:-}` interpolation
7
+ // delivers unset vars as empty strings.
8
+ const siteName = process.env.REVEALUI_BRAND_NAME || process.env.REVEALUI_TENANT_NAME || 'RevealUI';
9
+ return (_jsxs("div", { className: "min-h-screen bg-background", children: [_jsx("header", { className: "bg-card shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-foreground", children: `${siteName} Admin` }) }), _jsx("div", { className: "flex items-center space-x-4", children: _jsx("span", { className: "text-sm text-muted-foreground", children: "v0.1.0" }) })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Collections icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1", children: collections.map((collection) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: collection.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", collection.fields?.length || 0, " fields)"] })] }, collection.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-muted-foreground", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "Globals icon" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1", children: globals.map((global) => (_jsxs("li", { className: "text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: global.slug }), _jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", global.fields?.length || 0, " fields)"] })] }, global.slug))) })) : (_jsx("p", { className: "text-muted-foreground", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-card overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-success/15 rounded-full flex items-center justify-center", children: _jsxs("svg", { className: "h-5 w-5 text-success", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("title", { children: "System operational" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })] }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-muted-foreground truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-foreground", children: "Operational" })] }) })] }) }), _jsx("div", { className: "bg-muted px-5 py-3", children: _jsxs("div", { className: "text-sm text-muted-foreground", children: [siteName, " admin is running successfully with ", collections.length, " collections and", ' ', globals.length, " globals configured."] }) })] })] }) }) })] }));
6
10
  }
7
11
  export function NotFoundPage() {
8
12
  return (_jsxs("div", { children: [_jsx("h1", { children: "404 - Page Not Found" }), _jsx("p", { children: "The requested admin page could not be found." })] }));
9
13
  }
10
14
  export function generatePageMetadata() {
15
+ // Server-side, resolved per call. White-label kits override via env.
16
+ // `||` not `??`: Compose `${VAR:-}` delivers unset vars as empty strings.
17
+ const siteName = process.env.REVEALUI_BRAND_NAME || process.env.REVEALUI_TENANT_NAME || 'RevealUI';
11
18
  return {
12
- title: 'RevealUI Admin',
13
- description: 'RevealUI Content Management System',
19
+ title: `${siteName} Admin`,
20
+ description: `${siteName} Content Management System`,
14
21
  };
15
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/apiClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,cAAc;IAC7C,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IACX,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AAED,oBAAY,YAAY;IACtB,OAAO,YAAY;IACnB,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,UAAU,eAAe;IACzB,QAAQ,cAAc;IACtB,MAAM,WAAW;CAClB;AAED,qBAAa,QAAS,SAAQ,KAAK;IAExB,IAAI,EAAE,YAAY;IAElB,MAAM,CAAC,EAAE,MAAM;IACf,KAAK,CAAC,EAAE,MAAM;gBAHd,IAAI,EAAE,YAAY,EACzB,OAAO,EAAE,MAAM,EACR,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,KAAK,CAAC,EAAE,MAAM,YAAA;CAKxB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA+BD;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,gBAAqB;IAW1C;;OAEG;YACW,OAAO;IAoGrB;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAuBtD;;OAEG;IACG,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAUvE;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAY7D;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAY7D;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IASnD;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhF;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KACxD,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjB;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAerE;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;CAe1E;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC"}
1
+ {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/apiClient.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  * API Client for RevealUI Admin Dashboard
3
3
  * Handles all API communication with authentication and error handling
4
4
  */
5
+ import { readCsrfToken } from './csrf.js';
5
6
  export var APIErrorType;
6
7
  (function (APIErrorType) {
7
8
  APIErrorType["Network"] = "network";
@@ -65,18 +66,7 @@ export class APIClient {
65
66
  async request(endpoint, options = {}) {
66
67
  const Unsafe = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
67
68
  const method = (options.method ?? 'GET').toUpperCase();
68
- let csrfToken;
69
- if (Unsafe.has(method) && typeof document !== 'undefined') {
70
- for (const part of document.cookie.split(';')) {
71
- const eqIdx = part.indexOf('=');
72
- if (eqIdx === -1)
73
- continue;
74
- if (part.slice(0, eqIdx).trim() === 'revealui-csrf') {
75
- csrfToken = part.slice(eqIdx + 1).trim() || undefined;
76
- break;
77
- }
78
- }
79
- }
69
+ const csrfToken = Unsafe.has(method) ? readCsrfToken() : undefined;
80
70
  const headers = {
81
71
  'Content-Type': 'application/json',
82
72
  ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}),
@@ -0,0 +1,25 @@
1
+ /**
2
+ * CSRF helpers for the admin client.
3
+ *
4
+ * The admin proxy and the api server's csrfMiddleware require any unsafe
5
+ * request carrying a `revealui-session` cookie to echo the JS-readable
6
+ * `revealui-csrf` cookie as an `X-CSRF-Token` header. The token is re-read
7
+ * immediately before each request because the proxy re-issues the cookie
8
+ * whenever it no longer validates against the current session (e.g. after
9
+ * re-login or session rotation).
10
+ */
11
+ /**
12
+ * Read the `revealui-csrf` cookie value. Returns `undefined` outside the
13
+ * browser, when the cookie is absent, or when its value is empty.
14
+ */
15
+ export declare function readCsrfToken(): string | undefined;
16
+ /**
17
+ * POST `/api/auth/sign-out`, echoing the CSRF cookie as `X-CSRF-Token` when
18
+ * one is readable. Sign-out always runs with a session cookie, so without the
19
+ * header the admin proxy rejects the request with 403 "CSRF token missing"
20
+ * and the server-side session is never revoked. When no cookie is readable
21
+ * the request stays byte-identical to the historical bare fetch (no `headers`
22
+ * key at all).
23
+ */
24
+ export declare function postSignOut(): Promise<Response>;
25
+ //# sourceMappingURL=csrf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/csrf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,SAAS,CAgBlD;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAOrD"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * CSRF helpers for the admin client.
3
+ *
4
+ * The admin proxy and the api server's csrfMiddleware require any unsafe
5
+ * request carrying a `revealui-session` cookie to echo the JS-readable
6
+ * `revealui-csrf` cookie as an `X-CSRF-Token` header. The token is re-read
7
+ * immediately before each request because the proxy re-issues the cookie
8
+ * whenever it no longer validates against the current session (e.g. after
9
+ * re-login or session rotation).
10
+ */
11
+ /**
12
+ * Read the `revealui-csrf` cookie value. Returns `undefined` outside the
13
+ * browser, when the cookie is absent, or when its value is empty.
14
+ */
15
+ export function readCsrfToken() {
16
+ if (typeof document === 'undefined')
17
+ return undefined;
18
+ for (const part of document.cookie.split(';')) {
19
+ const eqIdx = part.indexOf('=');
20
+ if (eqIdx === -1)
21
+ continue;
22
+ if (part.slice(0, eqIdx).trim() === 'revealui-csrf') {
23
+ const raw = part.slice(eqIdx + 1).trim();
24
+ if (!raw)
25
+ return undefined;
26
+ try {
27
+ return decodeURIComponent(raw);
28
+ }
29
+ catch {
30
+ return raw;
31
+ }
32
+ }
33
+ }
34
+ return undefined;
35
+ }
36
+ /**
37
+ * POST `/api/auth/sign-out`, echoing the CSRF cookie as `X-CSRF-Token` when
38
+ * one is readable. Sign-out always runs with a session cookie, so without the
39
+ * header the admin proxy rejects the request with 403 "CSRF token missing"
40
+ * and the server-side session is never revoked. When no cookie is readable
41
+ * the request stays byte-identical to the historical bare fetch (no `headers`
42
+ * key at all).
43
+ */
44
+ export async function postSignOut() {
45
+ const csrfToken = readCsrfToken();
46
+ return fetch('/api/auth/sign-out', {
47
+ method: 'POST',
48
+ credentials: 'include',
49
+ ...(csrfToken ? { headers: { 'X-CSRF-Token': csrfToken } } : {}),
50
+ });
51
+ }
@@ -2,4 +2,5 @@
2
2
  * Admin utilities exports
3
3
  */
4
4
  export * from './apiClient.js';
5
+ export * from './csrf.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
@@ -2,3 +2,4 @@
2
2
  * Admin utilities exports
3
3
  */
4
4
  export * from './apiClient.js';
5
+ export * from './csrf.js';
@@ -42,7 +42,7 @@ export interface RichTextEditorProps {
42
42
  }
43
43
  export { FloatingToolbarPlugin } from './plugins/FloatingToolbarPlugin.js';
44
44
  export { ToolbarPlugin } from './plugins/ToolbarPlugin.js';
45
- export declare function RichTextEditor({ editorConfig, initialValue, onChange, onSerializedChange, placeholder, className, editable, autoFocus, onError, namespace, collaborative, documentId, providerFactory, shouldBootstrap, username, cursorColor, clientType, agentModel, }: RichTextEditorProps): import("react/jsx-runtime").JSX.Element;
45
+ export declare function RichTextEditor({ editorConfig, initialValue, onChange, onSerializedChange, placeholder, className, editable, autoFocus, onError, namespace, collaborative, documentId, providerFactory, shouldBootstrap, username, cursorColor, clientType, agentModel, }: RichTextEditorProps): import("react").JSX.Element;
46
46
  export declare const richTextEditorStyles = "\n.revealui-rich-text-editor {\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n overflow: hidden;\n font-family: system-ui, -apple-system, sans-serif;\n}\n\n.editor-toolbar {\n display: flex;\n gap: 4px;\n padding: 8px;\n border-bottom: 1px solid #e2e8f0;\n background: #f8fafc;\n}\n\n.editor-toolbar--floating {\n border-bottom: none;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n background: white;\n padding: 6px;\n transition: opacity 0.2s ease;\n}\n\n.toolbar-btn {\n padding: 6px 10px;\n border: 1px solid #e2e8f0;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 14px;\n transition: all 0.15s ease;\n}\n\n.toolbar-btn:hover {\n background: #f1f5f9;\n}\n\n.toolbar-btn.active {\n background: #3b82f6;\n color: white;\n border-color: #3b82f6;\n}\n\n.editor-container {\n position: relative;\n min-height: 150px;\n}\n\n.editor-input {\n padding: 16px;\n outline: none;\n min-height: 150px;\n}\n\n.editor-placeholder {\n position: absolute;\n top: 16px;\n left: 16px;\n color: #94a3b8;\n pointer-events: none;\n user-select: none;\n}\n\n.editor-paragraph {\n margin: 0 0 8px 0;\n}\n\n.editor-heading-h1 { font-size: 2em; font-weight: bold; margin: 0 0 12px 0; }\n.editor-heading-h2 { font-size: 1.5em; font-weight: bold; margin: 0 0 10px 0; }\n.editor-heading-h3 { font-size: 1.25em; font-weight: bold; margin: 0 0 8px 0; }\n.editor-heading-h4 { font-size: 1em; font-weight: bold; margin: 0 0 8px 0; }\n.editor-heading-h5 { font-size: 0.875em; font-weight: bold; margin: 0 0 8px 0; }\n.editor-heading-h6 { font-size: 0.75em; font-weight: bold; margin: 0 0 8px 0; }\n\n.editor-quote {\n border-left: 4px solid #e2e8f0;\n padding-left: 16px;\n margin: 0 0 8px 0;\n color: #64748b;\n}\n\n.editor-list-ol { list-style: decimal; padding-left: 24px; margin: 0 0 8px 0; }\n.editor-list-ul { list-style: disc; padding-left: 24px; margin: 0 0 8px 0; }\n.editor-listitem { margin: 4px 0; }\n\n.editor-link { color: #3b82f6; text-decoration: underline; }\n\n.editor-text-bold { font-weight: bold; }\n.editor-text-italic { font-style: italic; }\n.editor-text-underline { text-decoration: underline; }\n.editor-text-strikethrough { text-decoration: line-through; }\n.editor-text-code {\n background: #f1f5f9;\n padding: 2px 4px;\n border-radius: 4px;\n font-family: monospace;\n}\n.editor-text-subscript { vertical-align: sub; font-size: smaller; }\n.editor-text-superscript { vertical-align: super; font-size: smaller; }\n\n.editor-code {\n background: #1e293b;\n color: #e2e8f0;\n padding: 16px;\n border-radius: 4px;\n font-family: monospace;\n overflow-x: auto;\n margin: 8px 0;\n}\n\n.collab-cursors-container {\n position: relative;\n pointer-events: none;\n}\n\n.cursor-agent {\n animation: cursor-agent-pulse 2s ease-in-out infinite;\n}\n\n@keyframes cursor-agent-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n\n.cursor-inactive {\n opacity: 0.2;\n transition: opacity 1s ease-out;\n}\n";
47
47
  export default RichTextEditor;
48
48
  //# sourceMappingURL=RichTextEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../../src/client/richtext/RichTextEditor.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EACV,WAAW,EAEX,aAAa,EAEb,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EACV,cAAc,IAAI,oBAAoB,EAEvC,MAAM,yBAAyB,CAAC;AAWjC,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,8CAA8C;IAC9C,YAAY,CAAC,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAAC;IACrD,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/D,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC3D,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACxD,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,QAAQ,CAAC;IACxE,+DAA+D;IAC/D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA+ID,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AA2B3D,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,WAA+B,EAC/B,SAAc,EACd,QAAe,EACf,SAAiB,EACjB,OAAO,EACP,SAA4B,EAC5B,aAAqB,EACrB,UAAU,EACV,eAAe,EACf,eAAuB,EACvB,QAAQ,EACR,WAAW,EACX,UAAU,EACV,UAAU,GACX,EAAE,mBAAmB,2CA+GrB;AAMD,eAAO,MAAM,oBAAoB,0+FAmIhC,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../../src/client/richtext/RichTextEditor.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EACV,WAAW,EAEX,aAAa,EAEb,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EACV,cAAc,IAAI,oBAAoB,EAEvC,MAAM,yBAAyB,CAAC;AAWjC,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,8CAA8C;IAC9C,YAAY,CAAC,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAAC;IACrD,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/D,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC3D,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACxD,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,QAAQ,CAAC;IACxE,+DAA+D;IAC/D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA+ID,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AA2B3D,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,WAA+B,EAC/B,SAAc,EACd,QAAe,EACf,SAAiB,EACjB,OAAO,EACP,SAA4B,EAC5B,aAAqB,EACrB,UAAU,EACV,eAAe,EACf,eAAuB,EACvB,QAAQ,EACR,WAAW,EACX,UAAU,EACV,UAAU,GACX,EAAE,mBAAmB,+BA+GrB;AAMD,eAAO,MAAM,oBAAoB,0+FAmIhC,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,UAAU,sBAAsB;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqBD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA0I9D,CAAC"}
1
+ {"version":3,"file":"ImageUploadButton.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/ImageUploadButton.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,UAAU,sBAAsB;IAC9B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqBD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAsI9D,CAAC"}
@@ -9,6 +9,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
9
9
  import { logger } from '@revealui/core/utils/logger';
10
10
  import { useCallback, useRef, useState } from 'react';
11
11
  import { INSERT_IMAGE_COMMAND } from '../nodes/ImageNode.js';
12
+ import { postMediaUpload } from './upload.js';
12
13
  /** Default maximum file size: 10 MB */
13
14
  const DEFAULT_MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
14
15
  const getUploadUrl = (payload) => {
@@ -64,11 +65,7 @@ export const ImageUploadButton = ({ onUploadStart, onUploadComplete, onUploadErr
64
65
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
65
66
  let response;
66
67
  try {
67
- response = await fetch(uploadEndpoint, {
68
- method: 'POST',
69
- body: formData,
70
- signal: controller.signal,
71
- });
68
+ response = await postMediaUpload(uploadEndpoint, formData, controller.signal);
72
69
  }
73
70
  finally {
74
71
  clearTimeout(timeoutId);
@@ -0,0 +1,21 @@
1
+ /**
2
+ * RevealUI Rich Text Editor - media upload POST
3
+ *
4
+ * The admin proxy and the api server's csrfMiddleware require any unsafe
5
+ * request carrying a `revealui-session` cookie to echo the JS-readable
6
+ * `revealui-csrf` cookie as an `X-CSRF-Token` header. The editor's default
7
+ * `/api/media` endpoint is not CSRF-exempt, so the historical bare upload
8
+ * POST was rejected with 403 "CSRF token missing" in the admin app. The
9
+ * token is re-read immediately before each request because the proxy
10
+ * re-issues the cookie whenever it no longer validates against the current
11
+ * session (e.g. after re-login or session rotation).
12
+ */
13
+ /**
14
+ * POST `body` to `uploadEndpoint`, echoing the CSRF cookie as `X-CSRF-Token`
15
+ * when one is readable. `Content-Type` is never set here - `fetch` derives
16
+ * the multipart boundary from the FormData body, and an explicit value would
17
+ * break it. When no cookie is readable the request stays byte-identical to
18
+ * the historical bare fetch (no `headers` key at all).
19
+ */
20
+ export declare function postMediaUpload(uploadEndpoint: string, body: FormData, signal: AbortSignal): Promise<Response>;
21
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/components/upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,QAAQ,CAAC,CAQnB"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * RevealUI Rich Text Editor - media upload POST
3
+ *
4
+ * The admin proxy and the api server's csrfMiddleware require any unsafe
5
+ * request carrying a `revealui-session` cookie to echo the JS-readable
6
+ * `revealui-csrf` cookie as an `X-CSRF-Token` header. The editor's default
7
+ * `/api/media` endpoint is not CSRF-exempt, so the historical bare upload
8
+ * POST was rejected with 403 "CSRF token missing" in the admin app. The
9
+ * token is re-read immediately before each request because the proxy
10
+ * re-issues the cookie whenever it no longer validates against the current
11
+ * session (e.g. after re-login or session rotation).
12
+ */
13
+ import { readCsrfToken } from '../../admin/utils/csrf.js';
14
+ /**
15
+ * POST `body` to `uploadEndpoint`, echoing the CSRF cookie as `X-CSRF-Token`
16
+ * when one is readable. `Content-Type` is never set here - `fetch` derives
17
+ * the multipart boundary from the FormData body, and an explicit value would
18
+ * break it. When no cookie is readable the request stays byte-identical to
19
+ * the historical bare fetch (no `headers` key at all).
20
+ */
21
+ export async function postMediaUpload(uploadEndpoint, body, signal) {
22
+ const csrfToken = readCsrfToken();
23
+ return fetch(uploadEndpoint, {
24
+ method: 'POST',
25
+ body,
26
+ signal,
27
+ ...(csrfToken ? { headers: { 'X-CSRF-Token': csrfToken } } : {}),
28
+ });
29
+ }
@@ -9,5 +9,5 @@ export interface CollaborationPluginProps {
9
9
  clientType?: 'human' | 'agent';
10
10
  agentModel?: string;
11
11
  }
12
- export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, clientType, agentModel, }: CollaborationPluginProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, clientType, agentModel, }: CollaborationPluginProps): import("react").JSX.Element;
13
13
  //# sourceMappingURL=CollaborationPlugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollaborationPlugin.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/plugins/CollaborationPlugin.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE/B,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,QAAQ,CAAC;IACvE,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,EAAE,EACF,eAAe,EACf,eAAe,EACf,QAAQ,EACR,WAAW,EACX,UAAoB,EACpB,UAAU,GACX,EAAE,wBAAwB,2CAiB1B"}
1
+ {"version":3,"file":"CollaborationPlugin.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/plugins/CollaborationPlugin.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE/B,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,QAAQ,CAAC;IACvE,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,EAAE,EACF,eAAe,EACf,eAAe,EACf,QAAQ,EACR,WAAW,EACX,UAAoB,EACpB,UAAU,GACX,EAAE,wBAAwB,+BAiB1B"}
@@ -3,6 +3,6 @@ export interface ToolbarPluginProps {
3
3
  features: RichTextFeature[];
4
4
  variant?: 'fixed' | 'inline' | 'floating';
5
5
  }
6
- export declare function ToolbarPlugin({ features, variant }: ToolbarPluginProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export declare function ToolbarPlugin({ features, variant }: ToolbarPluginProps): import("react").JSX.Element | null;
7
7
  export default ToolbarPlugin;
8
8
  //# sourceMappingURL=ToolbarPlugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolbarPlugin.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/plugins/ToolbarPlugin.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAsClE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC3C;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAiB,EAAE,EAAE,kBAAkB,kDA4ZhF;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ToolbarPlugin.d.ts","sourceRoot":"","sources":["../../../../src/client/richtext/plugins/ToolbarPlugin.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAsClE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC3C;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAiB,EAAE,EAAE,kBAAkB,sCA4ZhF;AAED,eAAe,aAAa,CAAC"}
@@ -40,8 +40,13 @@ export interface WithRevealUIOptions {
40
40
  * Next.js configuration wrapper for RevealUI
41
41
  * Provides webpack aliases, environment variables, and build configuration
42
42
  *
43
- * Sets up `@revealui/config` alias to import the RevealUI config file.
44
- * The alias works with both Webpack (Next.js < 15) and Turbopack (Next.js 16+).
43
+ * MUST NOT alias the `@revealui/config` package specifier: that is a real
44
+ * workspace package (type-safe env config). Aliasing it to the app's
45
+ * revealui.config.ts shadows the package in every server bundle, so
46
+ * `config.reveal` / `config.database` reads resolve against the CMS instance
47
+ * config and come back undefined at runtime (prod admin passkey/MFA 500s,
48
+ * 2026-06-10). Apps load their CMS config via relative imports or their own
49
+ * `@reveal-config` alias instead.
45
50
  */
46
51
  export declare function withRevealUI(nextConfig?: NextConfig, options?: WithRevealUIOptions): NextConfig;
47
52
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"withRevealUI.d.ts","sourceRoot":"","sources":["../../src/nextjs/withRevealUI.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,UAAU,UAAU;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,CACR,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,KAC9E,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,OAAO,CACrB,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAC1E,CAAC;IACF,MAAM,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;KAAE,CAAC;IAC7D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAOD,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uBAAuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,UAAU,GAAE,UAAe,EAC3B,OAAO,GAAE,mBAAwB,GAChC,UAAU,CAgMZ"}
1
+ {"version":3,"file":"withRevealUI.d.ts","sourceRoot":"","sources":["../../src/nextjs/withRevealUI.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,UAAU,UAAU;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,CACR,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,KAC9E,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,OAAO,CACrB,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAC1E,CAAC;IACF,MAAM,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;KAAE,CAAC;IAC7D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAOD,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uBAAuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,UAAU,GAAE,UAAe,EAC3B,OAAO,GAAE,mBAAwB,GAChC,UAAU,CA2FZ"}
@@ -1,4 +1,3 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
3
2
  import { fileURLToPath } from 'node:url';
4
3
  // Get __dirname equivalent for ESM
@@ -9,39 +8,16 @@ const __dirname = path.dirname(__filename);
9
8
  * Next.js configuration wrapper for RevealUI
10
9
  * Provides webpack aliases, environment variables, and build configuration
11
10
  *
12
- * Sets up `@revealui/config` alias to import the RevealUI config file.
13
- * The alias works with both Webpack (Next.js < 15) and Turbopack (Next.js 16+).
11
+ * MUST NOT alias the `@revealui/config` package specifier: that is a real
12
+ * workspace package (type-safe env config). Aliasing it to the app's
13
+ * revealui.config.ts shadows the package in every server bundle, so
14
+ * `config.reveal` / `config.database` reads resolve against the CMS instance
15
+ * config and come back undefined at runtime (prod admin passkey/MFA 500s,
16
+ * 2026-06-10). Apps load their CMS config via relative imports or their own
17
+ * `@reveal-config` alias instead.
14
18
  */
15
19
  export function withRevealUI(nextConfig = {}, options = {}) {
16
20
  const { configPath = './revealui.config.ts', admin = true, adminRoute = '/admin', apiRoute = '/api', } = options;
17
- /**
18
- * Resolve config file path with validation
19
- * Attempts multiple extensions (.ts, .js, .mjs) if base path doesn't exist
20
- */
21
- const resolveConfigPath = (baseDir) => {
22
- const basePath = path.isAbsolute(configPath) ? configPath : path.resolve(baseDir, configPath);
23
- // Try exact path first
24
- if (fs.existsSync(basePath)) {
25
- return basePath;
26
- }
27
- // Try with extensions if no extension provided
28
- const extensions = ['.ts', '', '.mjs'];
29
- const baseWithoutExt = path.parse(basePath);
30
- for (const ext of extensions) {
31
- const candidate = path.format({
32
- ...baseWithoutExt,
33
- base: undefined,
34
- ext: ext,
35
- });
36
- if (fs.existsSync(candidate)) {
37
- return candidate;
38
- }
39
- }
40
- // If not found, throw helpful error
41
- throw new Error(`RevealUI config file not found: ${basePath}\n` +
42
- `Searched for: ${basePath}, ${extensions.map((ext) => path.format({ ...baseWithoutExt, base: undefined, ext })).join(', ')}\n` +
43
- `Please ensure the config file exists or provide a valid configPath option.`);
44
- };
45
21
  return {
46
22
  ...nextConfig,
47
23
  // Environment variables for RevealUI
@@ -61,34 +37,6 @@ export function withRevealUI(nextConfig = {}, options = {}) {
61
37
  if (nextConfig.webpack) {
62
38
  config = nextConfig.webpack(config, context);
63
39
  }
64
- // Resolve config path at execution time (when webpack runs)
65
- // This ensures we're using the correct cwd for the Next.js project
66
- const projectRoot = context.dir || process.cwd();
67
- let resolvedConfigPath;
68
- try {
69
- resolvedConfigPath = resolveConfigPath(projectRoot);
70
- }
71
- catch (error) {
72
- // In development, warn but don't fail - allow for dynamic config creation
73
- if (dev) {
74
- // Lazy import logger to avoid ESM resolution issues at module load time
75
- import('../instance/logger.js')
76
- .then(({ defaultLogger }) => {
77
- defaultLogger.warn(error instanceof Error ? error.message : String(error));
78
- })
79
- .catch(() => {
80
- // Logger failed to load - silently continue (already falling back to default config path)
81
- });
82
- // Use fallback path
83
- resolvedConfigPath = path.isAbsolute(configPath)
84
- ? configPath
85
- : path.resolve(projectRoot, configPath);
86
- }
87
- else {
88
- // In production, fail fast
89
- throw error;
90
- }
91
- }
92
40
  // Add RevealUI-specific webpack aliases
93
41
  const resolve = (config.resolve || {});
94
42
  config.resolve = resolve;
@@ -96,9 +44,6 @@ export function withRevealUI(nextConfig = {}, options = {}) {
96
44
  ...resolve.alias,
97
45
  // RevealUI core aliases - resolve to source index file
98
46
  '@revealui/core': path.resolve(__dirname, '../index'),
99
- // Config alias - resolves to the actual config file path in the Next.js project
100
- // Use absolute path for reliable resolution
101
- '@revealui/config': resolvedConfigPath,
102
47
  };
103
48
  // Also ensure it's in resolve.modules if needed (for some edge cases)
104
49
  if (!resolve.modules) {
@@ -106,43 +51,8 @@ export function withRevealUI(nextConfig = {}, options = {}) {
106
51
  }
107
52
  return config;
108
53
  },
109
- // Turbopack configuration (Next.js 16+)
110
- // IMPORTANT: Turbopack's resolveAlias must be resolved at config evaluation time
111
- // Turbopack should read tsconfig.json paths, but we also set it explicitly here for reliability
112
- // If next.config.mjs already set @revealui/config, we respect it (it uses __dirname which is reliable).
113
- turbopack: {
114
- ...nextConfig.turbopack,
115
- resolveAlias: {
116
- // Start with existing aliases from next.config.mjs (which includes @revealui/config)
117
- ...nextConfig.turbopack?.resolveAlias,
118
- // RevealUI core aliases - use relative path for Turbopack compatibility
119
- // Don't set @revealui/core here - let next.config.mjs handle it via the @revealui alias
120
- // Ensure @revealui/config is set (next.config.mjs should have it, but ensure it's there)
121
- // Use the existing one if present (prefer relative path for Turbopack)
122
- // Otherwise resolve it to relative path from project root
123
- '@revealui/config': nextConfig.turbopack?.resolveAlias?.['@revealui/config'] ||
124
- (() => {
125
- // Prefer relative path for Turbopack (matches tsconfig.json format)
126
- if (!path.isAbsolute(configPath)) {
127
- return configPath;
128
- }
129
- // If absolute, convert to relative from project root
130
- try {
131
- const projectRoot = process.cwd();
132
- const resolved = resolveConfigPath(projectRoot);
133
- if (fs.existsSync(resolved)) {
134
- // Return relative path from project root
135
- return path.relative(projectRoot, resolved);
136
- }
137
- }
138
- catch {
139
- // Fall through to fallback
140
- }
141
- // Fallback: use configPath as-is (should be relative)
142
- return configPath;
143
- })(),
144
- },
145
- },
54
+ // Turbopack config passes through verbatim via the `...nextConfig` spread —
55
+ // withRevealUI injects no resolveAlias entries (see the docstring constraint).
146
56
  // Headers for RevealUI
147
57
  async headers() {
148
58
  const existingHeaders = nextConfig.headers ? await nextConfig.headers() : [];
@@ -50,8 +50,10 @@ export interface IssueRevForgeLicenseResult {
50
50
  * Issue a signed RevForge license JWT for a paying customer.
51
51
  *
52
52
  * @throws Error on invalid slug, invalid tier, mutually-exclusive flag combos,
53
- * or non-positive numeric overrides. The error message names the offending
54
- * field so callers can surface it directly to the operator.
53
+ * non-positive numeric overrides, or a private/public pair that is not a
54
+ * matching Ed25519 keypair. The error message names the offending field (or, for
55
+ * the keypair case, carries the `REVFORGE_LICENSE_KEYPAIR_MISMATCH` prefix) so
56
+ * callers can surface it directly to the operator.
55
57
  */
56
58
  export declare function issueRevForgeLicense(opts: IssueRevForgeLicenseOptions, keys: {
57
59
  privateKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"revforge-license.d.ts","sourceRoot":"","sources":["../src/revforge-license.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEvE,eAAO,MAAM,YAAY,QAAyB,CAAC;AAEnD,eAAO,MAAM,oBAAoB,uCAAwC,CAAC;AAC1E,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,0DAA0D;IAC1D,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oFAAoF;IACpF,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC;CACtD;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,2BAA2B,EACjC,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,0BAA0B,CAAC,CAoErC"}
1
+ {"version":3,"file":"revforge-license.d.ts","sourceRoot":"","sources":["../src/revforge-license.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAsB,KAAK,cAAc,EAAsB,MAAM,cAAc,CAAC;AAE3F,eAAO,MAAM,YAAY,QAAyB,CAAC;AAEnD,eAAO,MAAM,oBAAoB,uCAAwC,CAAC;AAC1E,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,0DAA0D;IAC1D,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oFAAoF;IACpF,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC;CACtD;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,2BAA2B,EACjC,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,0BAA0B,CAAC,CAuFrC"}
@@ -10,15 +10,17 @@
10
10
  * descriptive metadata. The CLI wrapper (scripts/setup/issue-revforge-license.ts)
11
11
  * handles argv parsing and reading keys from the environment.
12
12
  */
13
- import { generateLicenseKey } from './license.js';
13
+ import { generateLicenseKey, validateLicenseKey } from './license.js';
14
14
  export const SLUG_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
15
15
  export const VALID_REVFORGE_TIERS = ['pro', 'max', 'enterprise'];
16
16
  /**
17
17
  * Issue a signed RevForge license JWT for a paying customer.
18
18
  *
19
19
  * @throws Error on invalid slug, invalid tier, mutually-exclusive flag combos,
20
- * or non-positive numeric overrides. The error message names the offending
21
- * field so callers can surface it directly to the operator.
20
+ * non-positive numeric overrides, or a private/public pair that is not a
21
+ * matching Ed25519 keypair. The error message names the offending field (or, for
22
+ * the keypair case, carries the `REVFORGE_LICENSE_KEYPAIR_MISMATCH` prefix) so
23
+ * callers can surface it directly to the operator.
22
24
  */
23
25
  export async function issueRevForgeLicense(opts, keys) {
24
26
  if (!SLUG_PATTERN.test(opts.slug)) {
@@ -61,6 +63,22 @@ export async function issueRevForgeLicense(opts, keys) {
61
63
  : 365 * 24 * 60 * 60;
62
64
  const issuedAtMs = Date.now();
63
65
  const licenseKey = await generateLicenseKey(payload, keys.privateKey, expiresInSeconds, keys.publicKey);
66
+ // Pair-match guard: prove the supplied public key can verify the JWT we just
67
+ // signed with the supplied private key. If it cannot, the two are not a
68
+ // matching Ed25519 keypair, and issuing anyway would hand back a license whose
69
+ // baked REVEALUI_LICENSE_PUBLIC_KEY crash-loops the kit at boot with
70
+ // "LICENSE VALIDATION FAILED" (apps/server validateLicenseAtStartup). Reusing
71
+ // the runtime verifier (validateLicenseKey) guarantees this check agrees
72
+ // exactly with the deployment-time check, so a mismatched pair can never reach
73
+ // a stamped customer kit.
74
+ const keypairSelfCheck = await validateLicenseKey(licenseKey, keys.publicKey);
75
+ if (keypairSelfCheck === null) {
76
+ throw new Error('REVFORGE_LICENSE_KEYPAIR_MISMATCH: the supplied public key cannot verify a ' +
77
+ 'license JWT signed by the supplied private key, so they are not a matching ' +
78
+ 'Ed25519 keypair. A kit issued with this pair would crash at boot with ' +
79
+ 'LICENSE VALIDATION FAILED. Source REVEALUI_LICENSE_PRIVATE_KEY and ' +
80
+ 'REVEALUI_LICENSE_PUBLIC_KEY from the same keypair in revvault and retry.');
81
+ }
64
82
  const expiresAt = expiresInSeconds === null ? null : new Date(issuedAtMs + expiresInSeconds * 1000).toISOString();
65
83
  return {
66
84
  licenseKey,
@@ -93,11 +93,11 @@ export declare function $generateHtmlFromNodes(data: SerializedEditorState | nul
93
93
  /**
94
94
  * Server component for rendering Lexical content in table cells
95
95
  */
96
- export declare function RscEntryLexicalCell({ data, className }: RscEntryLexicalCellProps): import("react/jsx-runtime").JSX.Element | null;
96
+ export declare function RscEntryLexicalCell({ data, className }: RscEntryLexicalCellProps): JSX.Element | null;
97
97
  /**
98
98
  * Server component for rendering Lexical content in form fields
99
99
  */
100
- export declare function RscEntryLexicalField({ data, className }: RscEntryLexicalFieldProps): import("react/jsx-runtime").JSX.Element | null;
100
+ export declare function RscEntryLexicalField({ data, className }: RscEntryLexicalFieldProps): JSX.Element | null;
101
101
  /**
102
102
  * Generic RSC component for rendering Lexical content
103
103
  */
@@ -114,6 +114,6 @@ export interface RichTextContentProps {
114
114
  caption?: string;
115
115
  }, index: number) => JSX.Element | null;
116
116
  }
117
- export declare function RichTextContent({ data, className, renderBlock, renderLink, renderImage, }: RichTextContentProps): import("react/jsx-runtime").JSX.Element | null;
117
+ export declare function RichTextContent({ data, className, renderBlock, renderLink, renderImage, }: RichTextContentProps): JSX.Element | null;
118
118
  export default RichTextContent;
119
119
  //# sourceMappingURL=rsc.d.ts.map