@fuzdev/fuz_app 0.108.0 → 0.110.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.
Files changed (122) hide show
  1. package/README.md +4 -0
  2. package/dist/actions/CLAUDE.md +1 -1
  3. package/dist/auth/CLAUDE.md +7 -6
  4. package/dist/auth/account_action_specs.d.ts +18 -0
  5. package/dist/auth/account_action_specs.d.ts.map +1 -1
  6. package/dist/auth/account_action_specs.js +14 -1
  7. package/dist/auth/account_actions.d.ts.map +1 -1
  8. package/dist/auth/account_actions.js +6 -2
  9. package/dist/auth/audit_emitter.d.ts +9 -5
  10. package/dist/auth/audit_emitter.d.ts.map +1 -1
  11. package/dist/auth/audit_log_schema.d.ts +7 -1
  12. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  13. package/dist/auth/audit_log_schema.js +16 -1
  14. package/dist/auth/bootstrap_account.d.ts +7 -2
  15. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  16. package/dist/auth/bootstrap_account.js +9 -4
  17. package/dist/auth/bootstrap_routes.d.ts +12 -4
  18. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  19. package/dist/auth/bootstrap_routes.js +26 -7
  20. package/dist/auth/daemon_token_middleware.d.ts +7 -69
  21. package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
  22. package/dist/auth/daemon_token_middleware.js +8 -104
  23. package/dist/auth/deps.d.ts +9 -5
  24. package/dist/auth/deps.d.ts.map +1 -1
  25. package/dist/auth/middleware.js +1 -1
  26. package/dist/auth/migrations.d.ts +7 -0
  27. package/dist/auth/migrations.d.ts.map +1 -1
  28. package/dist/auth/migrations.js +25 -8
  29. package/dist/auth/request_context.d.ts +1 -3
  30. package/dist/auth/request_context.d.ts.map +1 -1
  31. package/dist/auth/request_context.js +2 -5
  32. package/dist/auth/session_cookie.d.ts +18 -36
  33. package/dist/auth/session_cookie.d.ts.map +1 -1
  34. package/dist/auth/session_cookie.js +16 -26
  35. package/dist/auth/session_middleware.d.ts +1 -1
  36. package/dist/auth/session_middleware.d.ts.map +1 -1
  37. package/dist/auth/session_middleware.js +1 -4
  38. package/dist/auth/session_queries.d.ts +14 -30
  39. package/dist/auth/session_queries.d.ts.map +1 -1
  40. package/dist/auth/session_queries.js +15 -45
  41. package/dist/auth/token_lifetime.d.ts +51 -0
  42. package/dist/auth/token_lifetime.d.ts.map +1 -0
  43. package/dist/auth/token_lifetime.js +54 -0
  44. package/dist/db/CLAUDE.md +9 -5
  45. package/dist/db/cell_audit_queries.d.ts +4 -2
  46. package/dist/db/cell_audit_queries.d.ts.map +1 -1
  47. package/dist/db/cell_audit_queries.js +4 -2
  48. package/dist/db/pg_error.d.ts +12 -0
  49. package/dist/db/pg_error.d.ts.map +1 -1
  50. package/dist/db/pg_error.js +15 -1
  51. package/dist/dev/setup.d.ts +5 -9
  52. package/dist/dev/setup.d.ts.map +1 -1
  53. package/dist/dev/setup.js +18 -21
  54. package/dist/http/CLAUDE.md +78 -18
  55. package/dist/http/db_routes.d.ts +96 -3
  56. package/dist/http/db_routes.d.ts.map +1 -1
  57. package/dist/http/db_routes.js +263 -46
  58. package/dist/http/error_schemas.d.ts +12 -1
  59. package/dist/http/error_schemas.d.ts.map +1 -1
  60. package/dist/http/error_schemas.js +12 -1
  61. package/dist/http/pending_effects.d.ts +5 -5
  62. package/dist/http/pending_effects.d.ts.map +1 -1
  63. package/dist/http/pending_effects.js +1 -1
  64. package/dist/runtime/deno.d.ts.map +1 -1
  65. package/dist/runtime/deno.js +27 -1
  66. package/dist/runtime/deps.d.ts +38 -4
  67. package/dist/runtime/deps.d.ts.map +1 -1
  68. package/dist/runtime/fs.d.ts +24 -5
  69. package/dist/runtime/fs.d.ts.map +1 -1
  70. package/dist/runtime/fs.js +38 -7
  71. package/dist/runtime/mock.d.ts +7 -0
  72. package/dist/runtime/mock.d.ts.map +1 -1
  73. package/dist/runtime/mock.js +41 -1
  74. package/dist/runtime/node.d.ts.map +1 -1
  75. package/dist/runtime/node.js +7 -1
  76. package/dist/runtime/secure_file.d.ts +71 -0
  77. package/dist/runtime/secure_file.d.ts.map +1 -0
  78. package/dist/runtime/secure_file.js +125 -0
  79. package/dist/server/app_backend.d.ts +6 -5
  80. package/dist/server/app_backend.d.ts.map +1 -1
  81. package/dist/server/app_backend.js +2 -3
  82. package/dist/testing/CLAUDE.md +36 -1
  83. package/dist/testing/admin_integration.d.ts.map +1 -1
  84. package/dist/testing/admin_integration.js +10 -2
  85. package/dist/testing/app_server.d.ts.map +1 -1
  86. package/dist/testing/app_server.js +13 -8
  87. package/dist/testing/audit_completeness.d.ts.map +1 -1
  88. package/dist/testing/audit_completeness.js +10 -2
  89. package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
  90. package/dist/testing/cross_backend/cell_grant_role.js +34 -1
  91. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
  92. package/dist/testing/cross_backend/cell_relations.js +53 -1
  93. package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
  94. package/dist/testing/cross_backend/conformance_table.js +2 -1
  95. package/dist/testing/cross_backend/query_shape.d.ts +10 -0
  96. package/dist/testing/cross_backend/query_shape.d.ts.map +1 -0
  97. package/dist/testing/cross_backend/query_shape.js +128 -0
  98. package/dist/testing/cross_backend/setup.js +1 -1
  99. package/dist/testing/cross_backend/token_lifetime.d.ts +15 -0
  100. package/dist/testing/cross_backend/token_lifetime.d.ts.map +1 -0
  101. package/dist/testing/cross_backend/token_lifetime.js +99 -0
  102. package/dist/testing/cross_backend/token_scope_surface.js +1 -1
  103. package/dist/testing/daemon_token_rotation.d.ts +83 -0
  104. package/dist/testing/daemon_token_rotation.d.ts.map +1 -0
  105. package/dist/testing/daemon_token_rotation.js +99 -0
  106. package/dist/testing/integration.d.ts.map +1 -1
  107. package/dist/testing/integration.js +15 -3
  108. package/dist/testing/stubs.d.ts.map +1 -1
  109. package/dist/testing/stubs.js +4 -4
  110. package/dist/ui/AccountSessions.svelte +0 -5
  111. package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
  112. package/dist/ui/AdminOverview.svelte +7 -4
  113. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  114. package/dist/ui/AdminSessions.svelte +0 -5
  115. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
  116. package/dist/ui/CLAUDE.md +9 -4
  117. package/dist/ui/table_state.svelte.d.ts +18 -5
  118. package/dist/ui/table_state.svelte.d.ts.map +1 -1
  119. package/dist/ui/table_state.svelte.js +22 -7
  120. package/dist/ui/ui_format.d.ts.map +1 -1
  121. package/dist/ui/ui_format.js +4 -0
  122. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/deps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/deps.ts"],"names":[],"mappings":"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"}
@@ -3,15 +3,34 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import type { FsWriteDeps } from './deps.js';
6
+ import type { FsRemoveDeps, FsWriteDeps } from './deps.js';
7
+ /** Options for `write_file_atomic`. */
8
+ export interface WriteFileAtomicOptions {
9
+ /**
10
+ * POSIX mode for the written file (e.g. `0o600` for secrets). Applied at
11
+ * temp-file creation, so the published file never exists with a laxer
12
+ * mode. Omitted = the runtime default (umask).
13
+ */
14
+ mode?: number;
15
+ }
7
16
  /**
8
17
  * Write a file atomically via temp file + rename.
9
18
  *
10
- * Writes to `<path>.tmp` then renames over `path` so readers either see the
11
- * old contents or the full new contents — never a partial write.
19
+ * Writes to a unique `.{name}.tmp.{pid}.{counter}` sibling with exclusive
20
+ * create (`O_EXCL`), then renames over `path` so readers either see the old
21
+ * contents or the full new contents — never a partial write. The unique name
22
+ * + exclusive create are load-bearing for secret files: a fixed temp name
23
+ * would let a crash-leftover temp be reopened `O_TRUNC` with its old
24
+ * (possibly permissive) mode — `mode` only applies at creation — and the
25
+ * rename would publish that stale inode. Twin of the Rust spine's
26
+ * `fuz_sys::secure_file::write_secure_file` naming scheme.
12
27
  *
13
- * @mutates filesystem - creates `<path>.tmp` then renames it to `path`
28
+ * @param deps - write capabilities; pass `remove` too for best-effort temp cleanup on failure
29
+ * @param path - destination path
30
+ * @param content - full file content
31
+ * @param options - optional `mode` applied at creation
32
+ * @mutates filesystem - creates the unique temp file then renames it to `path`
14
33
  * @throws Error if `write_text_file` or `rename` rejects (permissions, disk full, cross-device rename, etc.)
15
34
  */
16
- export declare const write_file_atomic: (deps: Pick<FsWriteDeps, "write_text_file" | "rename">, path: string, content: string) => Promise<void>;
35
+ export declare const write_file_atomic: (deps: Pick<FsWriteDeps, "write_text_file" | "rename"> & Partial<FsRemoveDeps>, path: string, content: string, options?: WriteFileAtomicOptions) => Promise<void>;
17
36
  //# sourceMappingURL=fs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/fs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,IAAI,CAAC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,CAAC,EACrD,MAAM,MAAM,EACZ,SAAS,MAAM,KACb,OAAO,CAAC,IAAI,CAId,CAAC"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/fs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE3D,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACtC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,IAAI,CAAC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,EAC7E,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,UAAU,sBAAsB,KAC9B,OAAO,CAAC,IAAI,CAoBd,CAAC"}
@@ -3,17 +3,48 @@
3
3
  *
4
4
  * @module
5
5
  */
6
+ import process from 'node:process';
7
+ /** Per-process counter for unique temp names (concurrent same-path writes). */
8
+ let temp_file_counter = 0;
6
9
  /**
7
10
  * Write a file atomically via temp file + rename.
8
11
  *
9
- * Writes to `<path>.tmp` then renames over `path` so readers either see the
10
- * old contents or the full new contents — never a partial write.
12
+ * Writes to a unique `.{name}.tmp.{pid}.{counter}` sibling with exclusive
13
+ * create (`O_EXCL`), then renames over `path` so readers either see the old
14
+ * contents or the full new contents — never a partial write. The unique name
15
+ * + exclusive create are load-bearing for secret files: a fixed temp name
16
+ * would let a crash-leftover temp be reopened `O_TRUNC` with its old
17
+ * (possibly permissive) mode — `mode` only applies at creation — and the
18
+ * rename would publish that stale inode. Twin of the Rust spine's
19
+ * `fuz_sys::secure_file::write_secure_file` naming scheme.
11
20
  *
12
- * @mutates filesystem - creates `<path>.tmp` then renames it to `path`
21
+ * @param deps - write capabilities; pass `remove` too for best-effort temp cleanup on failure
22
+ * @param path - destination path
23
+ * @param content - full file content
24
+ * @param options - optional `mode` applied at creation
25
+ * @mutates filesystem - creates the unique temp file then renames it to `path`
13
26
  * @throws Error if `write_text_file` or `rename` rejects (permissions, disk full, cross-device rename, etc.)
14
27
  */
15
- export const write_file_atomic = async (deps, path, content) => {
16
- const temp_path = path + '.tmp';
17
- await deps.write_text_file(temp_path, content);
18
- await deps.rename(temp_path, path);
28
+ export const write_file_atomic = async (deps, path, content, options) => {
29
+ const slash = path.lastIndexOf('/');
30
+ const dir = slash === -1 ? '' : path.slice(0, slash + 1);
31
+ const name = slash === -1 ? path : path.slice(slash + 1);
32
+ const temp_path = `${dir}.${name}.tmp.${process.pid}.${temp_file_counter++}`;
33
+ try {
34
+ await deps.write_text_file(temp_path, content, {
35
+ mode: options?.mode,
36
+ exclusive: true
37
+ });
38
+ await deps.rename(temp_path, path);
39
+ }
40
+ catch (err) {
41
+ // best-effort cleanup so a failed write doesn't strand the temp
42
+ try {
43
+ await deps.remove?.(temp_path);
44
+ }
45
+ catch {
46
+ // already gone or not removable — the original error wins
47
+ }
48
+ throw err;
49
+ }
19
50
  };
@@ -18,6 +18,13 @@ export interface MockRuntime extends RuntimeDeps {
18
18
  mock_fs: Map<string, string>;
19
19
  /** Mock binary file system (path -> bytes). */
20
20
  mock_fs_bytes: Map<string, Uint8Array>;
21
+ /**
22
+ * Recorded POSIX modes (path -> mode), written by `write_text_file`'s
23
+ * `mode` option. A file with no recorded mode reads as `0o644` (the
24
+ * default-umask hazard) — so `read_secure_file` refuses it unless the
25
+ * writer asked for `0o600` explicitly, mirroring the real runtimes.
26
+ */
27
+ mock_fs_modes: Map<string, number>;
21
28
  /** Mock directories that exist. */
22
29
  mock_dirs: Set<string>;
23
30
  /** Exit calls recorded (exit codes). */
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,aAAa,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAI3F;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC/C,kCAAkC;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,0CAA0C;IAC1C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,+CAA+C;IAC/C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,mCAAmC;IACnC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,wCAAwC;IACxC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1B,gGAAgG;IAChG,aAAa,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC,CAAC;IACxF,sCAAsC;IACtC,qBAAqB,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IACnE,8BAA8B;IAC9B,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,4CAA4C;IAC5C,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjD,yCAAyC;IACzC,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,4BAA4B;IAC5B,WAAW,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IAC1E,wDAAwD;IACxD,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAM,KAAK,CAAC,MAAM,CAAM,KAAG,WAwR9D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,KAAG,IAazD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,EAAE,OAAO,MAAM,KAAG,IAEpE,CAAC;AAEF;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM;CAKxB"}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,aAAa,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAK3F;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC/C,kCAAkC;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,0CAA0C;IAC1C,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,+CAA+C;IAC/C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC;;;;;OAKG;IACH,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,mCAAmC;IACnC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,wCAAwC;IACxC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1B,gGAAgG;IAChG,aAAa,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC,CAAC;IACxF,sCAAsC;IACtC,qBAAqB,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IACnE,8BAA8B;IAC9B,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,4CAA4C;IAC5C,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjD,yCAAyC;IACzC,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,4BAA4B;IAC5B,WAAW,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IAC1E,wDAAwD;IACxD,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAM,KAAK,CAAC,MAAM,CAAM,KAAG,WA8T9D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,KAAG,IAazD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,WAAW,EAAE,OAAO,MAAM,KAAG,IAEpE,CAAC;AAEF;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM;CAKxB"}
@@ -7,6 +7,7 @@
7
7
  *
8
8
  * @module
9
9
  */
10
+ import { assert_secure_mode, assert_secure_size } from './secure_file.js';
10
11
  /**
11
12
  * Create a mock `RuntimeDeps` for testing.
12
13
  *
@@ -32,6 +33,7 @@ export const create_mock_runtime = (args = []) => {
32
33
  const mock_env = new Map();
33
34
  const mock_fs = new Map();
34
35
  const mock_fs_bytes = new Map();
36
+ const mock_fs_modes = new Map();
35
37
  const mock_dirs = new Set();
36
38
  const exit_calls = [];
37
39
  const command_calls = [];
@@ -46,6 +48,7 @@ export const create_mock_runtime = (args = []) => {
46
48
  mock_env,
47
49
  mock_fs,
48
50
  mock_fs_bytes,
51
+ mock_fs_modes,
49
52
  mock_dirs,
50
53
  exit_calls,
51
54
  command_calls,
@@ -122,6 +125,26 @@ export const create_mock_runtime = (args = []) => {
122
125
  error.code = 'ENOENT';
123
126
  throw error;
124
127
  },
128
+ read_secure_file: async (path) => {
129
+ let bytes = mock_fs_bytes.get(path);
130
+ if (bytes === undefined) {
131
+ const content = mock_fs.get(path);
132
+ if (content !== undefined)
133
+ bytes = new TextEncoder().encode(content);
134
+ }
135
+ if (bytes === undefined) {
136
+ const error = new Error(`ENOENT: no such file or directory: ${path}`);
137
+ error.code = 'ENOENT';
138
+ throw error;
139
+ }
140
+ // A file written without an explicit mode reads as 0o644 — the
141
+ // default-umask hazard — so the secure read refuses it unless the
142
+ // writer asked for 0600, mirroring the real runtimes (simulated
143
+ // modes, so no platform gate).
144
+ assert_secure_mode(path, mock_fs_modes.get(path) ?? 0o644);
145
+ assert_secure_size(path, bytes.length);
146
+ return bytes;
147
+ },
125
148
  read_file_stream: async (path) => {
126
149
  let bytes = mock_fs_bytes.get(path);
127
150
  if (bytes === undefined) {
@@ -193,8 +216,15 @@ export const create_mock_runtime = (args = []) => {
193
216
  }
194
217
  return Array.from(seen).sort();
195
218
  },
196
- write_text_file: async (path, content) => {
219
+ write_text_file: async (path, content, options) => {
220
+ if (options?.exclusive && (mock_fs.has(path) || mock_fs_bytes.has(path))) {
221
+ const error = new Error(`EEXIST: file already exists: ${path}`);
222
+ error.code = 'EEXIST';
223
+ throw error;
224
+ }
197
225
  mock_fs.set(path, content);
226
+ if (options?.mode !== undefined)
227
+ mock_fs_modes.set(path, options.mode);
198
228
  },
199
229
  write_file: async (path, data) => {
200
230
  mock_fs_bytes.set(path, data);
@@ -236,10 +266,20 @@ export const create_mock_runtime = (args = []) => {
236
266
  mock_fs_bytes.set(new_path, bytes);
237
267
  mock_fs_bytes.delete(old_path);
238
268
  }
269
+ // the inode's mode travels with the rename (POSIX semantics)
270
+ const mode = mock_fs_modes.get(old_path);
271
+ if (mode !== undefined) {
272
+ mock_fs_modes.set(new_path, mode);
273
+ mock_fs_modes.delete(old_path);
274
+ }
275
+ else {
276
+ mock_fs_modes.delete(new_path);
277
+ }
239
278
  },
240
279
  remove: async (path, options) => {
241
280
  mock_fs.delete(path);
242
281
  mock_fs_bytes.delete(path);
282
+ mock_fs_modes.delete(path);
243
283
  mock_dirs.delete(path);
244
284
  if (options?.recursive) {
245
285
  const prefix = path.endsWith('/') ? path : path + '/';
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,WAAW,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,OAAM,aAAa,CAAC,MAAM,CAAyB,KACjD,WAkMD,CAAC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/node.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,WAAW,CAAC;AAGxE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,OAAM,aAAa,CAAC,MAAM,CAAyB,KACjD,WAwMD,CAAC"}
@@ -13,6 +13,7 @@ import { stat, mkdir, readFile, readdir, writeFile, rename, rm, open } from 'nod
13
13
  import process from 'node:process';
14
14
  import { Readable } from 'node:stream';
15
15
  import { pipeline } from 'node:stream/promises';
16
+ import { load_secure_file_node } from './secure_file.js';
16
17
  /**
17
18
  * Create a `RuntimeDeps` backed by Node.js APIs.
18
19
  *
@@ -50,6 +51,7 @@ export const create_node_runtime = (args = process.argv.slice(2)) => ({
50
51
  },
51
52
  read_text_file: (path) => readFile(path, 'utf-8'),
52
53
  read_file: (path) => readFile(path).then((buf) => new Uint8Array(buf)),
54
+ read_secure_file: load_secure_file_node,
53
55
  // `Readable.toWeb` / `fromWeb` bridge Node streams to the web stream shape
54
56
  // the interface speaks. The casts cross Node's `stream/web` ReadableStream
55
57
  // and the global DOM `ReadableStream` (structurally identical here).
@@ -84,7 +86,11 @@ export const create_node_runtime = (args = process.argv.slice(2)) => ({
84
86
  }
85
87
  },
86
88
  readdir: (path) => readdir(path),
87
- write_text_file: (path, content) => writeFile(path, content, 'utf-8'),
89
+ write_text_file: (path, content, options) => writeFile(path, content, {
90
+ encoding: 'utf-8',
91
+ mode: options?.mode,
92
+ flag: options?.exclusive ? 'wx' : 'w'
93
+ }),
88
94
  write_file: (path, data) => writeFile(path, data),
89
95
  rename: (old_path, new_path) => rename(old_path, new_path),
90
96
  fsync: async (path) => {
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Hardened secret-file read — the TS twin of the Rust spine's
3
+ * `fuz_sys::secure_file::load_secure_file`.
4
+ *
5
+ * The file this guards is typically the highest-value credential on the host
6
+ * (the bootstrap token mints the keeper account), so the read fails loud
7
+ * rather than degrading: a symlink, a group/other-accessible mode, or an
8
+ * oversized file is refused, never returned. The deploy recipe places the
9
+ * token at `0600`, so the check ratifies the shape zap produces; a
10
+ * hand-placed `0644` file fails at boot instead of being read.
11
+ *
12
+ * The Node implementation lives here (`load_secure_file_node`, wired as
13
+ * `create_node_runtime().read_secure_file`); the Deno runtime implements the
14
+ * same contract over `Deno.open` in `runtime/deno.ts`, and the mock honors
15
+ * the mode/size checks over its in-memory map. All three refuse through the
16
+ * shared `assert_secure_mode` / `assert_secure_size` / `read_secure_bounded`
17
+ * helpers so the checks — and their operator-facing messages — can't drift
18
+ * between runtimes.
19
+ *
20
+ * @module
21
+ */
22
+ /**
23
+ * Maximum size for secure files. Prevents DoS from unexpectedly large files;
24
+ * 4 KiB is generous for token/key material. Matches the Rust twin's
25
+ * `MAX_SECURE_FILE_SIZE`.
26
+ */
27
+ export declare const MAX_SECURE_FILE_SIZE = 4096;
28
+ /**
29
+ * Refuse any group/other-accessible mode (only `0600`/`0400` pass).
30
+ *
31
+ * Callers own the platform gating: the real runtimes skip the check where
32
+ * modes aren't meaningful (Node on Windows, a `null` Deno mode); the mock
33
+ * checks its simulated modes unconditionally.
34
+ *
35
+ * @throws Error naming the path, the offending mode, and the `chmod` fix
36
+ */
37
+ export declare const assert_secure_mode: (path: string, mode: number) => void;
38
+ /**
39
+ * Refuse a byte count over `MAX_SECURE_FILE_SIZE`.
40
+ *
41
+ * @throws Error naming the path, the size, and the cap
42
+ */
43
+ export declare const assert_secure_size: (path: string, size: number) => void;
44
+ /**
45
+ * Drain `read_chunk` into a cap-bounded buffer.
46
+ *
47
+ * Reads up to cap + 1 bytes so a file growing between stat and read is still
48
+ * caught (the stat-time size check alone races). `read_chunk` fills the given
49
+ * target from the file's current position and returns the bytes read
50
+ * (`null`/`0` = EOF) — the seam that lets the Node and Deno handle APIs share
51
+ * one loop.
52
+ *
53
+ * @throws Error when more than `MAX_SECURE_FILE_SIZE` bytes arrive
54
+ */
55
+ export declare const read_secure_bounded: (path: string, read_chunk: (target: Uint8Array) => Promise<number | null>) => Promise<Uint8Array>;
56
+ /**
57
+ * Read a secret file with fail-loud checks (Node implementation).
58
+ *
59
+ * - `O_NOFOLLOW` atomically rejects symlinks during open (no TOCTOU window)
60
+ * - the permission check runs on the open descriptor, not the path, so the
61
+ * file can't be swapped between check and read — any group/other access
62
+ * (not `0600`/`0400`) is refused
63
+ * - a size cap bounds the read; the read itself is limited to cap + 1 so a
64
+ * file growing between stat and read is still caught
65
+ *
66
+ * @param path - path to the secret file
67
+ * @returns the file's bytes
68
+ * @throws Error on a missing file, symlink, permissive mode, oversized file, or I/O failure
69
+ */
70
+ export declare const load_secure_file_node: (path: string) => Promise<Uint8Array>;
71
+ //# sourceMappingURL=secure_file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secure_file.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/secure_file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAUzC;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,IAM/D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,IAI/D,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,MAAM,EACZ,YAAY,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,KACxD,OAAO,CAAC,UAAU,CAUpB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,UAAU,CAuB5E,CAAC"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Hardened secret-file read — the TS twin of the Rust spine's
3
+ * `fuz_sys::secure_file::load_secure_file`.
4
+ *
5
+ * The file this guards is typically the highest-value credential on the host
6
+ * (the bootstrap token mints the keeper account), so the read fails loud
7
+ * rather than degrading: a symlink, a group/other-accessible mode, or an
8
+ * oversized file is refused, never returned. The deploy recipe places the
9
+ * token at `0600`, so the check ratifies the shape zap produces; a
10
+ * hand-placed `0644` file fails at boot instead of being read.
11
+ *
12
+ * The Node implementation lives here (`load_secure_file_node`, wired as
13
+ * `create_node_runtime().read_secure_file`); the Deno runtime implements the
14
+ * same contract over `Deno.open` in `runtime/deno.ts`, and the mock honors
15
+ * the mode/size checks over its in-memory map. All three refuse through the
16
+ * shared `assert_secure_mode` / `assert_secure_size` / `read_secure_bounded`
17
+ * helpers so the checks — and their operator-facing messages — can't drift
18
+ * between runtimes.
19
+ *
20
+ * @module
21
+ */
22
+ import { constants } from 'node:fs';
23
+ import { open } from 'node:fs/promises';
24
+ import process from 'node:process';
25
+ /**
26
+ * Maximum size for secure files. Prevents DoS from unexpectedly large files;
27
+ * 4 KiB is generous for token/key material. Matches the Rust twin's
28
+ * `MAX_SECURE_FILE_SIZE`.
29
+ */
30
+ export const MAX_SECURE_FILE_SIZE = 4096;
31
+ /**
32
+ * Whether POSIX file modes are meaningful on this platform. On Windows Node
33
+ * synthesizes modes (always group/other-readable), so enforcing the check
34
+ * would refuse every file; the Rust twin is Unix-only and never faces this.
35
+ * The mock runtime checks unconditionally — its modes are simulated.
36
+ */
37
+ const modes_apply = process.platform !== 'win32';
38
+ /**
39
+ * Refuse any group/other-accessible mode (only `0600`/`0400` pass).
40
+ *
41
+ * Callers own the platform gating: the real runtimes skip the check where
42
+ * modes aren't meaningful (Node on Windows, a `null` Deno mode); the mock
43
+ * checks its simulated modes unconditionally.
44
+ *
45
+ * @throws Error naming the path, the offending mode, and the `chmod` fix
46
+ */
47
+ export const assert_secure_mode = (path, mode) => {
48
+ if ((mode & 0o077) !== 0) {
49
+ throw new Error(`insecure permissions on ${path}: ${(mode & 0o777).toString(8)} (expected 0600) — fix with: chmod 600 ${path}`);
50
+ }
51
+ };
52
+ /**
53
+ * Refuse a byte count over `MAX_SECURE_FILE_SIZE`.
54
+ *
55
+ * @throws Error naming the path, the size, and the cap
56
+ */
57
+ export const assert_secure_size = (path, size) => {
58
+ if (size > MAX_SECURE_FILE_SIZE) {
59
+ throw new Error(`secure file too large: ${path} (${size} bytes, max ${MAX_SECURE_FILE_SIZE})`);
60
+ }
61
+ };
62
+ /**
63
+ * Drain `read_chunk` into a cap-bounded buffer.
64
+ *
65
+ * Reads up to cap + 1 bytes so a file growing between stat and read is still
66
+ * caught (the stat-time size check alone races). `read_chunk` fills the given
67
+ * target from the file's current position and returns the bytes read
68
+ * (`null`/`0` = EOF) — the seam that lets the Node and Deno handle APIs share
69
+ * one loop.
70
+ *
71
+ * @throws Error when more than `MAX_SECURE_FILE_SIZE` bytes arrive
72
+ */
73
+ export const read_secure_bounded = async (path, read_chunk) => {
74
+ const buffer = new Uint8Array(MAX_SECURE_FILE_SIZE + 1);
75
+ let total = 0;
76
+ while (total < buffer.length) {
77
+ const n = await read_chunk(buffer.subarray(total));
78
+ if (n === null || n === 0)
79
+ break;
80
+ total += n;
81
+ }
82
+ assert_secure_size(path, total);
83
+ return buffer.subarray(0, total);
84
+ };
85
+ /**
86
+ * Read a secret file with fail-loud checks (Node implementation).
87
+ *
88
+ * - `O_NOFOLLOW` atomically rejects symlinks during open (no TOCTOU window)
89
+ * - the permission check runs on the open descriptor, not the path, so the
90
+ * file can't be swapped between check and read — any group/other access
91
+ * (not `0600`/`0400`) is refused
92
+ * - a size cap bounds the read; the read itself is limited to cap + 1 so a
93
+ * file growing between stat and read is still caught
94
+ *
95
+ * @param path - path to the secret file
96
+ * @returns the file's bytes
97
+ * @throws Error on a missing file, symlink, permissive mode, oversized file, or I/O failure
98
+ */
99
+ export const load_secure_file_node = async (path) => {
100
+ let handle;
101
+ try {
102
+ handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
103
+ }
104
+ catch (err) {
105
+ // ELOOP means the path was a symlink (O_NOFOLLOW refused it).
106
+ if (err.code === 'ELOOP') {
107
+ throw new Error(`secure file is a symlink: ${path}`);
108
+ }
109
+ throw err;
110
+ }
111
+ try {
112
+ const s = await handle.stat();
113
+ if (modes_apply)
114
+ assert_secure_mode(path, s.mode);
115
+ assert_secure_size(path, s.size);
116
+ // `position: null` reads sequentially from the handle's own cursor.
117
+ return await read_secure_bounded(path, async (target) => {
118
+ const { bytesRead } = await handle.read(target, 0, target.length, null);
119
+ return bytesRead;
120
+ });
121
+ }
122
+ finally {
123
+ await handle.close();
124
+ }
125
+ };
@@ -16,7 +16,6 @@ import { type AuditEmitter } from '../auth/audit_emitter.js';
16
16
  import type { DbType, Db } from '../db/db.js';
17
17
  import type { Keyring } from '../auth/keyring.js';
18
18
  import type { PasswordHashDeps } from '../auth/password.js';
19
- import type { StatResult } from '../runtime/deps.js';
20
19
  import { type MigrationNamespace, type MigrationResult } from '../db/migrate.js';
21
20
  /**
22
21
  * Result of `create_app_backend()` — database metadata + deps bundle.
@@ -83,10 +82,12 @@ export declare const default_audit_factory: AuditFactory;
83
82
  * (e.g., tx uses `runtime.exit(1)` on invalid keys).
84
83
  */
85
84
  export interface CreateAppBackendOptions {
86
- /** Get file/directory stats, or null if path doesn't exist. */
87
- stat: (path: string) => Promise<StatResult | null>;
88
- /** Read a file as text. */
89
- read_text_file: (path: string) => Promise<string>;
85
+ /**
86
+ * Hardened secret-file read for the bootstrap token — pass the runtime's
87
+ * `read_secure_file` (see `FsSecureReadDeps`). Rejects symlinks,
88
+ * group/other-accessible modes, and oversized files.
89
+ */
90
+ read_secure_file: (path: string) => Promise<Uint8Array>;
90
91
  /** Delete a file. */
91
92
  delete_file: (path: string) => Promise<void>;
92
93
  /** Database connection URL (`postgres://`, `file://`, or `memory://`). */
@@ -1 +1 @@
1
- {"version":3,"file":"app_backend.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAkB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAIjG;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,oIAAoI;IACpI,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3D,iEAAiE;IACjE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE;IAAE,EAAE,EAAE,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,YAAY,CAAC;AAE7E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,EAAE,YACF,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACvC,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,EAAE,YAAY,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACzD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAU,SAAS,uBAAuB,KAAG,OAAO,CAAC,UAAU,CAmD7F,CAAC"}
1
+ {"version":3,"file":"app_backend.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAkB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAIjG;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,oIAAoI;IACpI,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3D,iEAAiE;IACjE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE;IAAE,EAAE,EAAE,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,YAAY,CAAC;AAE7E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,EAAE,YACF,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACvC;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,EAAE,YAAY,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACzD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAU,SAAS,uBAAuB,KAAG,OAAO,CAAC,UAAU,CAiD7F,CAAC"}
@@ -39,7 +39,7 @@ export const default_audit_factory = ({ db, log }) => create_audit_emitter({ db,
39
39
  * @throws Error if `migration_namespaces` contains a namespace in `reserved_migration_namespaces`
40
40
  */
41
41
  export const create_app_backend = async (options) => {
42
- const { database_url, keyring, password, stat, read_text_file, delete_file, audit_factory } = options;
42
+ const { database_url, keyring, password, read_secure_file, delete_file, audit_factory } = options;
43
43
  const log = options.log ?? new Logger('server');
44
44
  const { db, close, db_type, db_name } = await create_db(database_url);
45
45
  // Everything after `create_db` can throw — reserved-namespace check,
@@ -69,8 +69,7 @@ export const create_app_backend = async (options) => {
69
69
  keyring,
70
70
  password,
71
71
  db,
72
- stat,
73
- read_text_file,
72
+ read_secure_file,
74
73
  delete_file,
75
74
  log,
76
75
  audit
@@ -32,7 +32,7 @@ time (never runtime), where a throwing guard would break `vite build`.
32
32
  - `stub_handler()` — fresh `Response('stub')`.
33
33
  - `stub_mw` — pass-through middleware (`async (_c, next) => next()`).
34
34
  - `stub_app_deps` — frozen `AppDeps`, every capability throwing, `audit` a no-op `AuditEmitter` from `create_test_audit_emitter`.
35
- - `create_stub_app_deps()` — factory: fresh `AppDeps` with no-op FS/keyring/password, a `create_noop_stub` DB, silent `Logger`, no-op `audit`.
35
+ - `create_stub_app_deps()` — factory: fresh `AppDeps` with no-op keyring/password/`delete_file`, a `read_secure_file` that throws ENOENT (the no-token-file state), a `create_noop_stub` DB, silent `Logger`, no-op `audit`.
36
36
  - `create_test_audit_emitter()` — no-op `AuditEmitter`; `emit` / `emit_role_grant_target` no-op, `emit_pool` resolves immediately, `notify` no-op, `add_listener` throws (use `create_recording_audit_emitter` for a listener-accepting emitter), `listener_count` returns 0.
37
37
  - `create_stub_audit_sse()` — no-op `AuditLogSse` for surface-test wiring without booting real SSE. `subscribe` returns a no-op cleanup; `on_audit_event` no-op; `registry` is a fresh `SubscriberRegistry` (live `.size` / `.close_*` for registry-state tests, isolated per call). For real SSE plumbing build via `create_audit_log_sse` against `create_test_app`.
38
38
  - `create_stub_api_middleware({include_daemon_token?})` — stub `MiddlewareSpec[]` matching `create_auth_middleware_specs`'s output (origin/session/request_context/bearer_auth, optional daemon_token) for surface generation without booting real auth. See `auth/CLAUDE.md` §Middleware for the real stack.
@@ -1397,6 +1397,41 @@ in-process `auth/origin_parity.db.test.ts` + the cross-process
1397
1397
  Rust spine returned a plain-text body — now converged to the canonical TS
1398
1398
  `{error: "forbidden_origin"}` via `fuz_http::forbidden_origin_response()`.
1399
1399
 
1400
+ ### Query-string shape parity — `cross_backend/query_shape.ts`
1401
+
1402
+ `describe_query_shape_cross_tests({setup_test, capabilities, rpc_path?})` —
1403
+ the imperative duplicate-key / unknown-key / phase-order query-semantics
1404
+ suite over the three spine surfaces that read a query:
1405
+ `GET /api/account/status` (no query schema — duplicated `acting` first-wins,
1406
+ unknown keys ignored, anonymous junk query → 401 never a query 400), the
1407
+ JSON-RPC GET endpoint (`method` / `id` / `params` first-wins — a last-wins
1408
+ reader dispatches a different method per backend on the same request), and
1409
+ `GET /api/facts/:hash` (gated on `capabilities.fact_serving`; strict schema —
1410
+ unknown key / malformed `acting` → 400 `invalid_query_params` **before** the
1411
+ 401 guard, duplicated `acting` first-wins). Imperative because duplicated
1412
+ query keys can't be expressed through the structured RPC helpers. Pinned
1413
+ after the Rust spine's derived-serde `Query` extractors were converged onto
1414
+ `fuz_http`'s `query_first` / `assert_known_query_keys` (a pre-handler
1415
+ "duplicate field" 400 is an anonymously observable backend fingerprint).
1416
+ Cross-process only — the per-surface in-process TS pins live beside each
1417
+ module's own tests (`account_status.test.ts`, `action_rpc.test.ts`,
1418
+ `serve_fact_route.db.test.ts`); fuz_app's own wiring is
1419
+ `cross_backend/query_shape.cross.test.ts`.
1420
+
1421
+ ### API-token lifetime parity — `cross_backend/token_lifetime.ts`
1422
+
1423
+ `describe_token_lifetime_cross_tests({setup_test, rpc_path?})` — the
1424
+ imperative round-trip on `account_token_create`'s required `lifetime` union:
1425
+ a `{kind:'ttl', days}` mint returns and stores a bounded `expires_at`
1426
+ (create output + `account_token_list` read-back), `{kind:'eternal'}` stores
1427
+ NULL, and an omitted or out-of-range lifetime 400s identically on both
1428
+ spines. Exists because the action-manifest parity gate captures no param
1429
+ schemas while the Rust spine hand-parses params — a spine that silently
1430
+ dropped the field would answer the same mint with a 200 and an eternal
1431
+ token; only the stored-state read-back catches it. Ungated (mint + list are
1432
+ on every spine's standard surface). Runs both legs
1433
+ (`token_lifetime_parity.db.test.ts` + `token_lifetime.cross.test.ts`).
1434
+
1400
1435
  ### Readiness probe parity — `cross_backend/ready.ts`
1401
1436
 
1402
1437
  `describe_ready_cross_tests({setup_test, capabilities, ready_path?})` — the
@@ -1 +1 @@
1
- {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAkB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uCAAuC;IACvC,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAm3BF,CAAC"}
1
+ {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAkB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uCAAuC;IACvC,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IA23BF,CAAC"}
@@ -594,7 +594,11 @@ export const describe_standard_admin_integration_tests = (options) => {
594
594
  app: { request: fixture.transport },
595
595
  path: rpc_path,
596
596
  spec: account_token_create_action_spec,
597
- params: { name: 'audit-test-token', scope: { kind: 'full' } },
597
+ params: {
598
+ name: 'audit-test-token',
599
+ scope: { kind: 'full' },
600
+ lifetime: { kind: 'eternal' }
601
+ },
598
602
  headers: fixture.create_session_headers()
599
603
  });
600
604
  assert.ok(token_res.ok, `account_token_create failed: ${token_res.ok ? '' : JSON.stringify(token_res.error)}`);
@@ -721,7 +725,11 @@ export const describe_standard_admin_integration_tests = (options) => {
721
725
  app: { request: fixture.transport },
722
726
  path: rpc_path,
723
727
  spec: account_token_create_action_spec,
724
- params: { name: 'admin-b-token', scope: { kind: 'full' } },
728
+ params: {
729
+ name: 'admin-b-token',
730
+ scope: { kind: 'full' },
731
+ lifetime: { kind: 'eternal' }
732
+ },
725
733
  headers: create_headers(admin_b.session_cookie)
726
734
  });
727
735
  assert.ok(token_res.ok, `account_token_create failed: ${token_res.ok ? '' : JSON.stringify(token_res.error)}`);