@cosmicdrift/kumiko-dispatcher-live 0.358.0 → 0.360.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/dist/csrf.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export declare const CSRF_COOKIE_NAME = "kumiko_csrf";
2
1
  export declare const CSRF_HEADER_NAME = "X-CSRF-Token";
3
2
  export declare function readCsrfToken(cookieSource?: string): string | undefined;
package/dist/csrf.js CHANGED
@@ -3,6 +3,8 @@
3
3
  // Kumiko's auth-middleware sets two cookies on login (see Vorarbeit A):
4
4
  // - `kumiko_auth` — HttpOnly, carries the JWT. Invisible to JS.
5
5
  // - `kumiko_csrf` — JS-readable, carries a random token.
6
+ // Both carry the `__Host-` prefix when the server writes them Secure and
7
+ // without a Domain (see @cosmicdrift/kumiko-types/session-cookies).
6
8
  //
7
9
  // The double-submit CSRF pattern: every state-changing request echoes the
8
10
  // `kumiko_csrf` value into an `X-CSRF-Token` header. Server compares header
@@ -11,13 +13,13 @@
11
13
  // SameSite=Lax on top-level GETs, or Strict blocks them entirely) but
12
14
  // cannot READ `document.cookie` of our origin — so they can't populate the
13
15
  // header with the matching value.
14
- // Exported constants stay in sync with auth-middleware.ts. Kept here as
15
- // literals rather than imported from @cosmicdrift/kumiko-framework because this
16
+ import { CSRF_COOKIE_BASE, sessionCookieNameCandidates, } from "@cosmicdrift/kumiko-types/session-cookies";
17
+ // Kept here as a literal rather than imported from @cosmicdrift/kumiko-framework because this
16
18
  // package must remain server-dep-free (runs in browsers and React Native).
17
- // If the server ever renames the cookie, this file needs a one-line bump.
18
- export const CSRF_COOKIE_NAME = "kumiko_csrf";
19
+ // The framework's csrf-constants-sync test guards against drift.
19
20
  export const CSRF_HEADER_NAME = "X-CSRF-Token";
20
- // Reads the kumiko_csrf token from document.cookie. Returns undefined when:
21
+ const CSRF_COOKIE_NAMES = sessionCookieNameCandidates(CSRF_COOKIE_BASE);
22
+ // Reads the csrf token from document.cookie. Returns undefined when:
21
23
  // - `document` isn't available (SSR, Web Worker, React Native)
22
24
  // - the cookie was never set (before login, after logout)
23
25
  //
@@ -32,16 +34,19 @@ export function readCsrfToken(cookieSource) {
32
34
  // cookie format: "a=1; b=2; kumiko_csrf=<uuid>; c=3"
33
35
  // Parse by splitting on "; " — cookie values never contain that
34
36
  // delimiter literally (they're percent-encoded if needed).
35
- const pairs = raw.split(/;\s*/);
36
- for (const pair of pairs) {
37
+ const valuesByName = new Map();
38
+ for (const pair of raw.split(/;\s*/)) {
37
39
  const eq = pair.indexOf("=");
38
40
  if (eq < 0)
39
41
  continue;
40
42
  const name = pair.slice(0, eq);
41
- if (name === CSRF_COOKIE_NAME) {
42
- const value = pair.slice(eq + 1);
43
+ if (!valuesByName.has(name))
44
+ valuesByName.set(name, pair.slice(eq + 1));
45
+ }
46
+ for (const name of CSRF_COOKIE_NAMES) {
47
+ const value = valuesByName.get(name);
48
+ if (value !== undefined)
43
49
  return value.length > 0 ? decodeURIComponent(value) : undefined;
44
- }
45
50
  }
46
51
  return undefined;
47
52
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, readCsrfToken } from "./csrf.js";
1
+ export { CSRF_HEADER_NAME, readCsrfToken } from "./csrf.js";
2
2
  export type { LiveDispatcherOptions } from "./dispatcher-live.js";
3
3
  export { createLiveDispatcher } from "./dispatcher-live.js";
4
4
  export { buildAbortError, buildNetworkError, mapServerError } from "./error-mapping.js";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { CSRF_COOKIE_NAME, CSRF_HEADER_NAME, readCsrfToken } from "./csrf.js";
1
+ export { CSRF_HEADER_NAME, readCsrfToken } from "./csrf.js";
2
2
  export { createLiveDispatcher } from "./dispatcher-live.js";
3
3
  export { buildAbortError, buildNetworkError, mapServerError } from "./error-mapping.js";
4
4
  export { LOCALE_HEADER_NAME, readActiveLocale } from "./locale.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dispatcher-live",
3
- "version": "0.358.0",
3
+ "version": "0.360.0",
4
4
  "description": "HTTP-only Dispatcher for Kumiko UIs. Always-online; failures surface immediately. Default client for web admin/cockpit apps.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -24,7 +24,8 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@cosmicdrift/kumiko-headless": "0.358.0"
27
+ "@cosmicdrift/kumiko-headless": "0.360.0",
28
+ "@cosmicdrift/kumiko-types": "0.360.0"
28
29
  },
29
30
  "publishConfig": {
30
31
  "registry": "https://registry.npmjs.org",