@revealui/core 0.10.0 → 0.10.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/AdminDashboard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAUjC,UAAU,mBAAmB;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA8YD,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAqB,EAAE,EAAE,mBAAmB,+BAmVpF"}
1
+ {"version":3,"file":"AdminDashboard.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/AdminDashboard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAUjC,UAAU,mBAAmB;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2YD,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAqB,EAAE,EAAE,mBAAmB,+BAmVpF"}
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { logger } from '@revealui/core/utils/logger';
4
4
  import { useCallback, useEffect, useReducer, useState } from 'react';
5
- import { APIError, APIErrorType, apiClient } from '../utils/index.js';
5
+ import { APIError, APIErrorType, apiClient, postSignOut } from '../utils/index.js';
6
6
  import { CollectionList } from './CollectionList.js';
7
7
  import { DocumentForm } from './DocumentForm.js';
8
8
  import { GlobalForm } from './GlobalForm.js';
@@ -66,10 +66,7 @@ function SignOutButton() {
66
66
  const handleSignOut = useCallback(async () => {
67
67
  setLoading(true);
68
68
  try {
69
- await fetch('/api/auth/sign-out', {
70
- method: 'POST',
71
- credentials: 'include',
72
- });
69
+ await postSignOut();
73
70
  }
74
71
  catch {
75
72
  // Sign out even if the API call fails - clear client state regardless
@@ -1 +1 @@
1
- {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/utils/apiClient.ts"],"names":[],"mappings":"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"}
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';
@@ -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
+ }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@revealui/core",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "RevealUI's runtime engine — admin UI, REST API, auth, rich text, plugin system, and access control. The heart of the open-source platform.",
5
5
  "license": "MIT",
6
6
  "dependencies": {
7
- "@electric-sql/pglite": "^0.5.1",
7
+ "@electric-sql/pglite": "^0.5.2",
8
8
  "@lexical/clipboard": "^0.45.0",
9
9
  "@lexical/code": "^0.45.0",
10
10
  "@lexical/html": "^0.45.0",