@fuzdev/fuz_app 0.63.0 → 0.65.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 (181) hide show
  1. package/dist/actions/CLAUDE.md +525 -827
  2. package/dist/actions/broadcast_api.d.ts +1 -1
  3. package/dist/actions/broadcast_api.js +1 -1
  4. package/dist/actions/cancel.d.ts +2 -2
  5. package/dist/actions/cancel.js +3 -3
  6. package/dist/actions/connection_closer.d.ts +65 -0
  7. package/dist/actions/connection_closer.d.ts.map +1 -0
  8. package/dist/actions/connection_closer.js +38 -0
  9. package/dist/actions/register_action_ws.d.ts +2 -2
  10. package/dist/actions/register_action_ws.d.ts.map +1 -1
  11. package/dist/actions/register_action_ws.js +23 -2
  12. package/dist/actions/register_ws_endpoint.d.ts +12 -10
  13. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  14. package/dist/actions/register_ws_endpoint.js +5 -5
  15. package/dist/actions/transports_ws_auth_guard.d.ts +25 -10
  16. package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
  17. package/dist/actions/transports_ws_auth_guard.js +24 -9
  18. package/dist/actions/ws_endpoint_spec.d.ts +119 -0
  19. package/dist/actions/ws_endpoint_spec.d.ts.map +1 -0
  20. package/dist/actions/ws_endpoint_spec.js +13 -0
  21. package/dist/auth/CLAUDE.md +592 -1808
  22. package/dist/auth/account_action_specs.d.ts +1 -1
  23. package/dist/auth/account_actions.d.ts +13 -0
  24. package/dist/auth/account_actions.d.ts.map +1 -1
  25. package/dist/auth/account_actions.js +31 -1
  26. package/dist/auth/account_routes.d.ts +12 -2
  27. package/dist/auth/account_routes.d.ts.map +1 -1
  28. package/dist/auth/account_routes.js +55 -8
  29. package/dist/auth/account_schema.d.ts +4 -4
  30. package/dist/auth/account_schema.d.ts.map +1 -1
  31. package/dist/auth/admin_action_specs.d.ts +8 -8
  32. package/dist/auth/admin_actions.d.ts +11 -0
  33. package/dist/auth/admin_actions.d.ts.map +1 -1
  34. package/dist/auth/admin_actions.js +25 -0
  35. package/dist/auth/api_token_queries.js +1 -1
  36. package/dist/auth/audit_emitter.d.ts +56 -12
  37. package/dist/auth/audit_emitter.d.ts.map +1 -1
  38. package/dist/auth/audit_emitter.js +38 -12
  39. package/dist/auth/audit_log_ddl.d.ts +1 -1
  40. package/dist/auth/audit_log_ddl.d.ts.map +1 -1
  41. package/dist/auth/audit_log_ddl.js +1 -1
  42. package/dist/auth/audit_log_schema.d.ts +5 -3
  43. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  44. package/dist/auth/audit_log_schema.js +5 -3
  45. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  46. package/dist/auth/bootstrap_account.js +1 -5
  47. package/dist/auth/bootstrap_routes.d.ts +8 -2
  48. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  49. package/dist/auth/bootstrap_routes.js +15 -11
  50. package/dist/auth/invite_schema.d.ts +2 -2
  51. package/dist/auth/keyring.d.ts +6 -6
  52. package/dist/auth/keyring.js +8 -8
  53. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -1
  54. package/dist/auth/role_grant_offer_actions.js +4 -2
  55. package/dist/auth/signup_routes.d.ts +1 -1
  56. package/dist/auth/standard_rpc_actions.d.ts +1 -0
  57. package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
  58. package/dist/auth/standard_rpc_actions.js +1 -0
  59. package/dist/db/create_db.d.ts.map +1 -1
  60. package/dist/db/create_db.js +13 -0
  61. package/dist/dev/setup.d.ts +2 -2
  62. package/dist/dev/setup.js +3 -3
  63. package/dist/http/CLAUDE.md +225 -483
  64. package/dist/http/error_schemas.d.ts +0 -4
  65. package/dist/http/error_schemas.d.ts.map +1 -1
  66. package/dist/http/error_schemas.js +0 -4
  67. package/dist/http/ip_canonical.d.ts +100 -0
  68. package/dist/http/ip_canonical.d.ts.map +1 -0
  69. package/dist/http/ip_canonical.js +195 -0
  70. package/dist/http/origin.d.ts +14 -6
  71. package/dist/http/origin.d.ts.map +1 -1
  72. package/dist/http/origin.js +14 -32
  73. package/dist/http/pending_effects.d.ts +1 -1
  74. package/dist/http/pending_effects.js +1 -1
  75. package/dist/http/proxy.d.ts +13 -5
  76. package/dist/http/proxy.d.ts.map +1 -1
  77. package/dist/http/proxy.js +15 -23
  78. package/dist/http/surface.d.ts +50 -0
  79. package/dist/http/surface.d.ts.map +1 -1
  80. package/dist/http/surface.js +27 -1
  81. package/dist/primitive_schemas.d.ts +20 -4
  82. package/dist/primitive_schemas.d.ts.map +1 -1
  83. package/dist/primitive_schemas.js +25 -4
  84. package/dist/realtime/sse_auth_guard.d.ts +16 -4
  85. package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
  86. package/dist/realtime/sse_auth_guard.js +15 -3
  87. package/dist/runtime/mock.js +1 -1
  88. package/dist/server/app_backend.d.ts +66 -19
  89. package/dist/server/app_backend.d.ts.map +1 -1
  90. package/dist/server/app_backend.js +57 -34
  91. package/dist/server/app_server.d.ts +101 -10
  92. package/dist/server/app_server.d.ts.map +1 -1
  93. package/dist/server/app_server.js +105 -6
  94. package/dist/server/env.d.ts +7 -7
  95. package/dist/server/env.d.ts.map +1 -1
  96. package/dist/server/env.js +14 -14
  97. package/dist/server/startup.d.ts.map +1 -1
  98. package/dist/server/startup.js +12 -0
  99. package/dist/server/static.d.ts +4 -4
  100. package/dist/server/static.js +7 -7
  101. package/dist/testing/CLAUDE.md +269 -59
  102. package/dist/testing/admin_integration.d.ts +18 -23
  103. package/dist/testing/admin_integration.d.ts.map +1 -1
  104. package/dist/testing/admin_integration.js +159 -202
  105. package/dist/testing/adversarial_headers.d.ts +6 -0
  106. package/dist/testing/adversarial_headers.d.ts.map +1 -1
  107. package/dist/testing/adversarial_headers.js +13 -5
  108. package/dist/testing/app_server.d.ts +148 -60
  109. package/dist/testing/app_server.d.ts.map +1 -1
  110. package/dist/testing/app_server.js +143 -54
  111. package/dist/testing/attack_surface.d.ts +8 -7
  112. package/dist/testing/attack_surface.d.ts.map +1 -1
  113. package/dist/testing/attack_surface.js +12 -8
  114. package/dist/testing/audit_completeness.d.ts +23 -22
  115. package/dist/testing/audit_completeness.d.ts.map +1 -1
  116. package/dist/testing/audit_completeness.js +199 -158
  117. package/dist/testing/audit_drift_guard.d.ts +116 -0
  118. package/dist/testing/audit_drift_guard.d.ts.map +1 -0
  119. package/dist/testing/audit_drift_guard.js +134 -0
  120. package/dist/testing/bootstrap_success.d.ts +28 -0
  121. package/dist/testing/bootstrap_success.d.ts.map +1 -0
  122. package/dist/testing/bootstrap_success.js +144 -0
  123. package/dist/testing/connection_closer_helpers.d.ts +44 -0
  124. package/dist/testing/connection_closer_helpers.d.ts.map +1 -0
  125. package/dist/testing/connection_closer_helpers.js +48 -0
  126. package/dist/testing/cross_backend/capabilities.d.ts +64 -0
  127. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -0
  128. package/dist/testing/cross_backend/capabilities.js +47 -0
  129. package/dist/testing/cross_backend/setup.d.ts +215 -0
  130. package/dist/testing/cross_backend/setup.d.ts.map +1 -0
  131. package/dist/testing/cross_backend/setup.js +101 -0
  132. package/dist/testing/data_exposure.d.ts +14 -15
  133. package/dist/testing/data_exposure.d.ts.map +1 -1
  134. package/dist/testing/data_exposure.js +127 -146
  135. package/dist/testing/db_entities.d.ts +11 -1
  136. package/dist/testing/db_entities.d.ts.map +1 -1
  137. package/dist/testing/db_entities.js +13 -1
  138. package/dist/testing/integration.d.ts +35 -21
  139. package/dist/testing/integration.d.ts.map +1 -1
  140. package/dist/testing/integration.js +231 -293
  141. package/dist/testing/integration_helpers.d.ts +16 -6
  142. package/dist/testing/integration_helpers.d.ts.map +1 -1
  143. package/dist/testing/integration_helpers.js +7 -7
  144. package/dist/testing/mock_fs.d.ts.map +1 -1
  145. package/dist/testing/mock_fs.js +0 -2
  146. package/dist/testing/rate_limiting.d.ts.map +1 -1
  147. package/dist/testing/rate_limiting.js +13 -4
  148. package/dist/testing/role_grant_helpers.d.ts +31 -0
  149. package/dist/testing/role_grant_helpers.d.ts.map +1 -0
  150. package/dist/testing/role_grant_helpers.js +46 -0
  151. package/dist/testing/round_trip.d.ts +21 -16
  152. package/dist/testing/round_trip.d.ts.map +1 -1
  153. package/dist/testing/round_trip.js +65 -86
  154. package/dist/testing/rpc_helpers.d.ts +2 -1
  155. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  156. package/dist/testing/rpc_round_trip.d.ts +24 -21
  157. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  158. package/dist/testing/rpc_round_trip.js +91 -106
  159. package/dist/testing/schema_introspect.d.ts +106 -0
  160. package/dist/testing/schema_introspect.d.ts.map +1 -0
  161. package/dist/testing/schema_introspect.js +123 -0
  162. package/dist/testing/schema_parity.d.ts +144 -0
  163. package/dist/testing/schema_parity.d.ts.map +1 -0
  164. package/dist/testing/schema_parity.js +233 -0
  165. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  166. package/dist/testing/sse_round_trip.js +12 -6
  167. package/dist/testing/standard.d.ts +57 -25
  168. package/dist/testing/standard.d.ts.map +1 -1
  169. package/dist/testing/standard.js +62 -5
  170. package/dist/testing/stubs.d.ts +22 -3
  171. package/dist/testing/stubs.d.ts.map +1 -1
  172. package/dist/testing/stubs.js +28 -21
  173. package/dist/testing/surface_invariants.d.ts +66 -1
  174. package/dist/testing/surface_invariants.d.ts.map +1 -1
  175. package/dist/testing/surface_invariants.js +103 -1
  176. package/dist/testing/transports/surface_source.d.ts +51 -0
  177. package/dist/testing/transports/surface_source.d.ts.map +1 -0
  178. package/dist/testing/transports/surface_source.js +19 -0
  179. package/dist/ui/SurfaceExplorer.svelte +161 -2
  180. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  181. package/package.json +4 -4
@@ -2,11 +2,14 @@
2
2
  * Bound audit-emit capability.
3
3
  *
4
4
  * `AuditEmitter` closes over the pool-level `Db`, the `on_audit_event`
5
- * subscriber chain, and the optional `AuditLogConfig` at backend-assembly
6
- * time. Consumers reach for `deps.audit.emit(ctx, input)` and never see the
7
- * pool handlers cannot accidentally emit an audit event against the
8
- * request's transactional `db` (which would be rolled back with the parent
9
- * on a handler throw).
5
+ * subscriber chain, and the optional `AuditLogConfig`. Built by the
6
+ * consumer's `audit_factory` callback on `CreateAppBackendOptions`
7
+ * `create_app_backend` invokes the factory once with its constructed
8
+ * `{db, log}` and lands the result on `AppDeps.audit`. Consumers reach
9
+ * for `deps.audit.emit(ctx, input)` and never see the pool — handlers
10
+ * cannot accidentally emit an audit event against the request's
11
+ * transactional `db` (which would be rolled back with the parent on a
12
+ * handler throw).
10
13
  *
11
14
  * Four methods cover every fan-out shape the auth domain needs:
12
15
  *
@@ -26,22 +29,29 @@
26
29
  * the query layer). Runs every listener on the chain; per-listener throws
27
30
  * are isolated.
28
31
  *
29
- * The chain is mutable so server assembly can append additional listeners
30
- * (e.g. the audit-log SSE registry composed by `create_app_server`) after
31
- * the backend is built but before the first request runs.
32
+ * The chain is a documented mutable seam `create_app_server` appends
33
+ * additional listeners after the backend is built (the factory-managed
34
+ * audit-log SSE, per-endpoint WS auth guards and logout closers, any
35
+ * `extra_audit_handlers` on a `WsEndpointSpec`) before the first request
36
+ * runs. Consumers can also append listeners directly on the emitter
37
+ * they return from `audit_factory` for setups that don't pass through
38
+ * `create_app_server`.
32
39
  *
33
40
  * @module
34
41
  */
35
42
  import { query_audit_log } from './audit_log_queries.js';
36
43
  import { builtin_audit_log_config, } from './audit_log_schema.js';
37
44
  /**
38
- * Build a bound `AuditEmitter`. Called once at `create_app_backend` time.
45
+ * Build a bound `AuditEmitter`. Typical caller is the consumer's
46
+ * `audit_factory` callback on `CreateAppBackendOptions` —
47
+ * `create_app_backend` invokes that callback with its constructed
48
+ * `{db, log}` and lands the result on `AppDeps.audit`.
39
49
  *
40
50
  * @param options - pool, logger, optional initial subscriber, optional config
41
51
  * @returns the bound emitter; closes over the pool + config + listener chain
42
52
  */
43
53
  export const create_audit_emitter = (options) => {
44
- const { db, log, audit_log_config = builtin_audit_log_config } = options;
54
+ const { db, log, audit_log_config = builtin_audit_log_config, emit_decorator } = options;
45
55
  const on_event_chain = [];
46
56
  if (options.on_audit_event)
47
57
  on_event_chain.push(options.on_audit_event);
@@ -64,9 +74,14 @@ export const create_audit_emitter = (options) => {
64
74
  log.error('Audit log write failed:', err);
65
75
  }
66
76
  };
67
- const emit = (ctx, input) => {
77
+ const base_emit = (ctx, input) => {
68
78
  ctx.pending_effects.push(emit_pool(input));
69
79
  };
80
+ // The decorated `emit` is what `emit_role_grant_target` captures below
81
+ // and what gets exposed on the returned object — both call shapes
82
+ // route through any `emit_decorator` the caller supplied. Production
83
+ // passes no decorator, so this collapses to `base_emit`.
84
+ const emit = emit_decorator ? emit_decorator(base_emit) : base_emit;
70
85
  const emit_role_grant_target = (ctx, auth, input) => {
71
86
  emit(ctx, {
72
87
  event_type: input.event_type,
@@ -79,5 +94,16 @@ export const create_audit_emitter = (options) => {
79
94
  metadata: input.metadata,
80
95
  });
81
96
  };
82
- return { emit, emit_role_grant_target, emit_pool, notify, on_event_chain };
97
+ // Freeze the slot layout so consumers cannot hot-patch `emit` /
98
+ // `emit_role_grant_target` / `emit_pool` / `notify` after construction.
99
+ // The previous test helper `patch_audit_emit_capture` did exactly this
100
+ // and only happened to work because the four slots were writable —
101
+ // `emit_role_grant_target` calls the closed-over inner `emit`, not
102
+ // `this.emit`, so the patch silently bypassed role-grant-shape emits.
103
+ // Tests that need instrumentation pass `emit_decorator` so the wrap
104
+ // is captured by the closure before the freeze (see
105
+ // `create_emit_ordering_audit_factory`). `on_event_chain` is a
106
+ // frozen reference but its array contents stay mutable —
107
+ // `create_app_server` appends to it post-assembly, by design.
108
+ return Object.freeze({ emit, emit_role_grant_target, emit_pool, notify, on_event_chain });
83
109
  };
@@ -19,6 +19,6 @@
19
19
  *
20
20
  * @module
21
21
  */
22
- export declare const AUDIT_LOG_SCHEMA = "\nCREATE TABLE IF NOT EXISTS audit_log (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n seq SERIAL NOT NULL,\n event_type TEXT NOT NULL,\n outcome TEXT NOT NULL DEFAULT 'success',\n actor_id UUID REFERENCES actor(id) ON DELETE SET NULL,\n account_id UUID REFERENCES account(id) ON DELETE SET NULL,\n target_account_id UUID REFERENCES account(id) ON DELETE SET NULL,\n target_actor_id UUID REFERENCES actor(id) ON DELETE SET NULL,\n ip TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n metadata JSONB\n)";
22
+ export declare const AUDIT_LOG_SCHEMA = "\nCREATE TABLE IF NOT EXISTS audit_log (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n seq BIGSERIAL NOT NULL,\n event_type TEXT NOT NULL,\n outcome TEXT NOT NULL DEFAULT 'success',\n actor_id UUID REFERENCES actor(id) ON DELETE SET NULL,\n account_id UUID REFERENCES account(id) ON DELETE SET NULL,\n target_account_id UUID REFERENCES account(id) ON DELETE SET NULL,\n target_actor_id UUID REFERENCES actor(id) ON DELETE SET NULL,\n ip TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n metadata JSONB\n)";
23
23
  export declare const AUDIT_LOG_INDEXES: string[];
24
24
  //# sourceMappingURL=audit_log_ddl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit_log_ddl.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,gBAAgB,ihBAa3B,CAAC;AAEH,eAAO,MAAM,iBAAiB,UAM7B,CAAC"}
1
+ {"version":3,"file":"audit_log_ddl.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,gBAAgB,ohBAa3B,CAAC;AAEH,eAAO,MAAM,iBAAiB,UAM7B,CAAC"}
@@ -22,7 +22,7 @@
22
22
  export const AUDIT_LOG_SCHEMA = `
23
23
  CREATE TABLE IF NOT EXISTS audit_log (
24
24
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
25
- seq SERIAL NOT NULL,
25
+ seq BIGSERIAL NOT NULL,
26
26
  event_type TEXT NOT NULL,
27
27
  outcome TEXT NOT NULL DEFAULT 'success',
28
28
  actor_id UUID REFERENCES actor(id) ON DELETE SET NULL,
@@ -336,9 +336,11 @@ export interface CreateAuditLogConfigOptions {
336
336
  * Throws when an `extra_events` key collides with a builtin event type, or
337
337
  * fails `AuditEventTypeName` format validation.
338
338
  *
339
- * Call once at startup; pass the result to `create_app_backend` (which
340
- * threads it into `AppDeps.audit`). Builtin handlers omit the
341
- * `audit_log_config` slot and pick up `builtin_audit_log_config`.
339
+ * Call once at startup; pass the result into the consumer's `audit_factory`
340
+ * body typically `({db, log}) => create_audit_emitter({db, log,
341
+ * audit_log_config, ...})` so it gets captured inside the bound
342
+ * `AppDeps.audit` emitter. Builtin handlers omit the `audit_log_config`
343
+ * slot and pick up `builtin_audit_log_config`.
342
344
  *
343
345
  * @throws Error when an `extra_events` key collides with a builtin event type or fails `AuditEventTypeName` format validation
344
346
  */
@@ -1 +1 @@
1
- {"version":3,"file":"audit_log_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit_log_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_log_schema.ts"],"names":[],"mappings":"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"}
@@ -291,9 +291,11 @@ export const builtin_audit_log_config = Object.freeze({
291
291
  * Throws when an `extra_events` key collides with a builtin event type, or
292
292
  * fails `AuditEventTypeName` format validation.
293
293
  *
294
- * Call once at startup; pass the result to `create_app_backend` (which
295
- * threads it into `AppDeps.audit`). Builtin handlers omit the
296
- * `audit_log_config` slot and pick up `builtin_audit_log_config`.
294
+ * Call once at startup; pass the result into the consumer's `audit_factory`
295
+ * body typically `({db, log}) => create_audit_emitter({db, log,
296
+ * audit_log_config, ...})` so it gets captured inside the bound
297
+ * `AppDeps.audit` emitter. Builtin handlers omit the `audit_log_config`
298
+ * slot and pick up `builtin_audit_log_config`.
297
299
  *
298
300
  * @throws Error when an `extra_events` key collides with a builtin event type or fails `AuditEventTypeName` format validation
299
301
  */
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap_account.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_account.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,EACN,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAGnE,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,6DAA6D;AAC7D,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE;QAAC,MAAM,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAC,CAAC;IACnD,wFAAwF;IACxF,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AAED,gCAAgC;AAChC,MAAM,MAAM,uBAAuB,GAChC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,0BAA0B,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAC,GAClE;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,wBAAwB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAC,GAChE;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,mBAAmB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAC,CAAC;AAE/D,qFAAqF;AACrF,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,uBAAuB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,EAAE,CAAC;IACP,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,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,6EAA6E;IAC7E,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAClD,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,oBAAoB,EAC1B,gBAAgB,MAAM,EACtB,OAAO,qBAAqB,KAC1B,OAAO,CAAC,sBAAsB,CA4EhC,CAAC"}
1
+ {"version":3,"file":"bootstrap_account.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_account.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,EACN,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAGnE,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,gDAAgD;AAChD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,6DAA6D;AAC7D,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE;QAAC,MAAM,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAC,CAAC;IACnD,wFAAwF;IACxF,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AAED,gCAAgC;AAChC,MAAM,MAAM,uBAAuB,GAChC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,0BAA0B,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAC,GAClE;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,wBAAwB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAC,GAChE;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,mBAAmB,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAC,CAAC;AAE/D,qFAAqF;AACrF,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,uBAAuB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,EAAE,CAAC;IACP,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,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,6EAA6E;IAC7E,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAClD,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,MAAM,oBAAoB,EAC1B,gBAAgB,MAAM,EACtB,OAAO,qBAAqB,KAC1B,OAAO,CAAC,sBAAsB,CAuEhC,CAAC"}
@@ -9,7 +9,7 @@
9
9
  import { timingSafeEqual } from 'node:crypto';
10
10
  import { ERROR_INVALID_TOKEN, ERROR_ALREADY_BOOTSTRAPPED, ERROR_TOKEN_FILE_MISSING, } from '../http/error_schemas.js';
11
11
  import { ROLE_ADMIN, ROLE_KEEPER } from './role_schema.js';
12
- import { query_create_account_with_actor, query_account_has_any } from './account_queries.js';
12
+ import { query_create_account_with_actor } from './account_queries.js';
13
13
  import { query_create_role_grant } from './role_grant_queries.js';
14
14
  /**
15
15
  * Bootstrap the first account with keeper and admin privileges.
@@ -57,10 +57,6 @@ export const bootstrap_account = async (deps, provided_token, input) => {
57
57
  if (lock_rows.length === 0) {
58
58
  return { ok: false, error: ERROR_ALREADY_BOOTSTRAPPED, status: 403 };
59
59
  }
60
- // Belt-and-suspenders: verify no accounts exist even if lock was available
61
- if (await query_account_has_any({ db: tx })) {
62
- return { ok: false, error: ERROR_ALREADY_BOOTSTRAPPED, status: 403 };
63
- }
64
60
  const tx_deps = { db: tx };
65
61
  const { account, actor } = await query_create_account_with_actor(tx_deps, {
66
62
  username: input.username,
@@ -19,14 +19,20 @@ import type { StatResult } from '../runtime/deps.js';
19
19
  /** Input for `POST /bootstrap`. `token` is the one-shot token file contents. */
20
20
  export declare const BootstrapInput: z.ZodObject<{
21
21
  token: z.ZodString;
22
- username: z.ZodString;
22
+ username: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
23
23
  password: z.ZodString;
24
24
  }, z.core.$strict>;
25
25
  export type BootstrapInput = z.infer<typeof BootstrapInput>;
26
26
  /** Output for `POST /bootstrap`. Session cookie is the operative side effect. */
27
27
  export declare const BootstrapOutput: z.ZodObject<{
28
28
  ok: z.ZodLiteral<true>;
29
- username: z.ZodString;
29
+ account: z.ZodObject<{
30
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
31
+ username: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
32
+ }, z.core.$strict>;
33
+ actor: z.ZodObject<{
34
+ id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
35
+ }, z.core.$strict>;
30
36
  }, z.core.$strict>;
31
37
  export type BootstrapOutput = z.infer<typeof BootstrapOutput>;
32
38
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAoB,KAAK,uBAAuB,EAAC,MAAM,wBAAwB,CAAC;AAGvF,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAkB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAA+B,KAAK,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAYnD,gFAAgF;AAChF,eAAO,MAAM,cAAc;;;;kBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,iFAAiF;AACjF,eAAO,MAAM,eAAe;;;kBAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,8EAA8E;IAC9E,gBAAgB,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,EAAE,EAAE,EAAE,CAAC;IACP,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,wBAAwB,EAC9B,SAAS;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,KAClC,OAAO,CAAC,eAAe,CAwBzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,gBAAgB,EACtB,SAAS,qBAAqB,KAC5B,KAAK,CAAC,SAAS,CAiHjB,CAAC"}
1
+ {"version":3,"file":"bootstrap_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bootstrap_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAoB,KAAK,uBAAuB,EAAC,MAAM,wBAAwB,CAAC;AAGvF,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AACpC,OAAO,EAAkB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAA+B,KAAK,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAWnD,gFAAgF;AAChF,eAAO,MAAM,cAAc;;;;kBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,iFAAiF;AACjF,eAAO,MAAM,eAAe;;;;;;;;;kBAI1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,8EAA8E;IAC9E,gBAAgB,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,EAAE,EAAE,EAAE,CAAC;IACP,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,wBAAwB,EAC9B,SAAS;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,KAClC,OAAO,CAAC,eAAe,CAwBzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,gBAAgB,EACtB,SAAS,qBAAqB,KAC5B,KAAK,CAAC,SAAS,CAkHjB,CAAC"}
@@ -7,6 +7,7 @@
7
7
  * @module
8
8
  */
9
9
  import { z } from 'zod';
10
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
10
11
  import { create_session_and_set_cookie } from './session_middleware.js';
11
12
  import { bootstrap_account } from './bootstrap_account.js';
12
13
  import { Username } from '../primitive_schemas.js';
@@ -14,7 +15,7 @@ import { Password } from './password.js';
14
15
  import { get_route_input } from '../http/route_spec.js';
15
16
  import { get_client_ip } from '../http/proxy.js';
16
17
  import { rate_limit_exceeded_response } from '../rate_limiter.js';
17
- import { ERROR_BOOTSTRAP_NOT_CONFIGURED, ERROR_INVALID_TOKEN, ERROR_ALREADY_BOOTSTRAPPED, ERROR_TOKEN_FILE_MISSING, ERROR_INVALID_JSON_BODY, ERROR_INVALID_REQUEST_BODY, } from '../http/error_schemas.js';
18
+ import { ERROR_INVALID_TOKEN, ERROR_ALREADY_BOOTSTRAPPED, ERROR_TOKEN_FILE_MISSING, ERROR_INVALID_JSON_BODY, ERROR_INVALID_REQUEST_BODY, } from '../http/error_schemas.js';
18
19
  // -- Input/output schemas ---------------------------------------------------
19
20
  /** Input for `POST /bootstrap`. `token` is the one-shot token file contents. */
20
21
  export const BootstrapInput = z.strictObject({
@@ -25,7 +26,8 @@ export const BootstrapInput = z.strictObject({
25
26
  /** Output for `POST /bootstrap`. Session cookie is the operative side effect. */
26
27
  export const BootstrapOutput = z.strictObject({
27
28
  ok: z.literal(true),
28
- username: z.string(),
29
+ account: z.strictObject({ id: Uuid, username: Username }),
30
+ actor: z.strictObject({ id: Uuid }),
29
31
  });
30
32
  /**
31
33
  * Check bootstrap availability at startup.
@@ -85,13 +87,14 @@ export const create_bootstrap_route_specs = (deps, options) => {
85
87
  }),
86
88
  401: z.looseObject({ error: z.literal(ERROR_INVALID_TOKEN) }),
87
89
  403: z.looseObject({ error: z.literal(ERROR_ALREADY_BOOTSTRAPPED) }),
88
- 404: z.looseObject({
89
- error: z.enum([ERROR_TOKEN_FILE_MISSING, ERROR_BOOTSTRAP_NOT_CONFIGURED]),
90
- }),
90
+ 404: z.looseObject({ error: z.literal(ERROR_TOKEN_FILE_MISSING) }),
91
91
  },
92
92
  handler: async (c, route) => {
93
- // Short-circuit if bootstrap already completed
94
- if (!bootstrap_status.available) {
93
+ // Short-circuit if bootstrap already completed or surface-only mounted.
94
+ // In 'surface_only' mode `bootstrap_status.token_path === null` and
95
+ // `available === false`; in 'live' mode after success `available` flips
96
+ // to `false`. Either way the wire shape is 403 ALREADY_BOOTSTRAPPED.
97
+ if (!bootstrap_status.available || token_path === null) {
95
98
  return c.json({ error: ERROR_ALREADY_BOOTSTRAPPED }, 403);
96
99
  }
97
100
  // Per-IP rate limit check (before any token/DB work)
@@ -103,9 +106,6 @@ export const create_bootstrap_route_specs = (deps, options) => {
103
106
  }
104
107
  }
105
108
  const input = get_route_input(c);
106
- if (token_path === null) {
107
- return c.json({ error: ERROR_BOOTSTRAP_NOT_CONFIGURED }, 404);
108
- }
109
109
  // `transaction: false` makes `route.db` the pool. `bootstrap_account`
110
110
  // manages its own transaction internally.
111
111
  const result = await bootstrap_account({
@@ -158,7 +158,11 @@ export const create_bootstrap_route_specs = (deps, options) => {
158
158
  if (!result.token_file_deleted) {
159
159
  throw new Error(`Bootstrap succeeded but token file was not deleted at ${token_path}. Delete it manually and log in.`);
160
160
  }
161
- return c.json({ ok: true, username: result.account.username });
161
+ return c.json({
162
+ ok: true,
163
+ account: { id: result.account.id, username: result.account.username },
164
+ actor: { id: result.actor.id },
165
+ });
162
166
  },
163
167
  },
164
168
  ];
@@ -23,7 +23,7 @@ export interface Invite {
23
23
  export declare const InviteJson: z.ZodObject<{
24
24
  id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
25
25
  email: z.ZodNullable<z.ZodEmail>;
26
- username: z.ZodNullable<z.ZodString>;
26
+ username: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
27
27
  claimed_by: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
28
28
  claimed_at: z.ZodNullable<z.ZodString>;
29
29
  created_at: z.ZodString;
@@ -34,7 +34,7 @@ export type InviteJson = z.infer<typeof InviteJson>;
34
34
  export declare const InviteWithUsernamesJson: z.ZodObject<{
35
35
  id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
36
36
  email: z.ZodNullable<z.ZodEmail>;
37
- username: z.ZodNullable<z.ZodString>;
37
+ username: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
38
38
  claimed_by: z.ZodNullable<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
39
39
  claimed_at: z.ZodNullable<z.ZodString>;
40
40
  created_at: z.ZodString;
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * const keyring = create_keyring(process.env.SECRET_COOKIE_KEYS);
10
+ * const keyring = create_keyring(process.env.SECRET_FUZ_COOKIE_KEYS);
11
11
  * if (!keyring) throw new Error('No keys configured');
12
12
  *
13
13
  * const signed = await keyring.sign('user:123:1700000000');
@@ -47,12 +47,12 @@ export interface Keyring {
47
47
  *
48
48
  * **Security: key rotation is an operational concern.** Old keys remain valid
49
49
  * for verification indefinitely — a leaked old key can forge session cookies
50
- * until it is removed from `SECRET_COOKIE_KEYS`. After rotating to a new
50
+ * until it is removed from `SECRET_FUZ_COOKIE_KEYS`. After rotating to a new
51
51
  * signing key, remove the old key within a grace period (e.g. 24–48 hours,
52
52
  * long enough for active sessions to re-sign with the new key via cookie
53
- * refresh). Treat `SECRET_COOKIE_KEYS` changes as security-critical deploys.
53
+ * refresh). Treat `SECRET_FUZ_COOKIE_KEYS` changes as security-critical deploys.
54
54
  *
55
- * @param env_value - the SECRET_COOKIE_KEYS environment variable
55
+ * @param env_value - the SECRET_FUZ_COOKIE_KEYS environment variable
56
56
  * @returns keyring or null if no keys configured
57
57
  */
58
58
  export declare const create_keyring: (env_value: string | undefined) => Keyring | null;
@@ -63,7 +63,7 @@ export declare const create_keyring: (env_value: string | undefined) => Keyring
63
63
  * or all-separator input like `'____'`), and for each key shorter than
64
64
  * `MIN_KEY_LENGTH` characters.
65
65
  *
66
- * @param env_value - the SECRET_COOKIE_KEYS environment variable
66
+ * @param env_value - the SECRET_FUZ_COOKIE_KEYS environment variable
67
67
  * @returns array of validation errors (empty if valid)
68
68
  */
69
69
  export declare const validate_keyring: (env_value: string | undefined) => Array<string>;
@@ -84,7 +84,7 @@ export type ValidatedKeyringResult = {
84
84
  * Returns a discriminated union so callers handle exit/logging their own way
85
85
  * (e.g. `Deno.exit(1)` vs `runtime.exit(1)`).
86
86
  *
87
- * @param env_value - the SECRET_COOKIE_KEYS environment variable
87
+ * @param env_value - the SECRET_FUZ_COOKIE_KEYS environment variable
88
88
  * @returns `{ok: true, keyring}` or `{ok: false, errors}`
89
89
  */
90
90
  export declare const create_validated_keyring: (env_value: string | undefined) => ValidatedKeyringResult;
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * const keyring = create_keyring(process.env.SECRET_COOKIE_KEYS);
10
+ * const keyring = create_keyring(process.env.SECRET_FUZ_COOKIE_KEYS);
11
11
  * if (!keyring) throw new Error('No keys configured');
12
12
  *
13
13
  * const signed = await keyring.sign('user:123:1700000000');
@@ -30,12 +30,12 @@ const encoder = new TextEncoder();
30
30
  *
31
31
  * **Security: key rotation is an operational concern.** Old keys remain valid
32
32
  * for verification indefinitely — a leaked old key can forge session cookies
33
- * until it is removed from `SECRET_COOKIE_KEYS`. After rotating to a new
33
+ * until it is removed from `SECRET_FUZ_COOKIE_KEYS`. After rotating to a new
34
34
  * signing key, remove the old key within a grace period (e.g. 24–48 hours,
35
35
  * long enough for active sessions to re-sign with the new key via cookie
36
- * refresh). Treat `SECRET_COOKIE_KEYS` changes as security-critical deploys.
36
+ * refresh). Treat `SECRET_FUZ_COOKIE_KEYS` changes as security-critical deploys.
37
37
  *
38
- * @param env_value - the SECRET_COOKIE_KEYS environment variable
38
+ * @param env_value - the SECRET_FUZ_COOKIE_KEYS environment variable
39
39
  * @returns keyring or null if no keys configured
40
40
  */
41
41
  export const create_keyring = (env_value) => {
@@ -75,13 +75,13 @@ export const create_keyring = (env_value) => {
75
75
  * or all-separator input like `'____'`), and for each key shorter than
76
76
  * `MIN_KEY_LENGTH` characters.
77
77
  *
78
- * @param env_value - the SECRET_COOKIE_KEYS environment variable
78
+ * @param env_value - the SECRET_FUZ_COOKIE_KEYS environment variable
79
79
  * @returns array of validation errors (empty if valid)
80
80
  */
81
81
  export const validate_keyring = (env_value) => {
82
82
  const keys = parse_keys(env_value);
83
83
  if (keys.length === 0) {
84
- return ['SECRET_COOKIE_KEYS is required'];
84
+ return ['SECRET_FUZ_COOKIE_KEYS is required'];
85
85
  }
86
86
  const errors = [];
87
87
  for (const [i, key] of keys.entries()) {
@@ -126,7 +126,7 @@ const verify_with_crypto_key = async (signed_value, key) => {
126
126
  * Returns a discriminated union so callers handle exit/logging their own way
127
127
  * (e.g. `Deno.exit(1)` vs `runtime.exit(1)`).
128
128
  *
129
- * @param env_value - the SECRET_COOKIE_KEYS environment variable
129
+ * @param env_value - the SECRET_FUZ_COOKIE_KEYS environment variable
130
130
  * @returns `{ok: true, keyring}` or `{ok: false, errors}`
131
131
  */
132
132
  export const create_validated_keyring = (env_value) => {
@@ -136,7 +136,7 @@ export const create_validated_keyring = (env_value) => {
136
136
  }
137
137
  const keyring = create_keyring(env_value);
138
138
  if (!keyring) {
139
- return { ok: false, errors: ['SECRET_COOKIE_KEYS is required'] };
139
+ return { ok: false, errors: ['SECRET_FUZ_COOKIE_KEYS is required'] };
140
140
  }
141
141
  return { ok: true, keyring };
142
142
  };
@@ -1 +1 @@
1
- {"version":3,"file":"role_grant_offer_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/role_grant_offer_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAGN,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAIN,KAAK,gBAAgB,EACrB,MAAM,kBAAkB,CAAC;AA0B1B,OAAO,EAA4C,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpG,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAEhD,OAAO,EAON,KAAK,kBAAkB,EACvB,MAAM,qCAAqC,CAAC;AAiC7C;;;;;;;;GAQG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAC3C,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,EACrE,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,EACnC,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,qDAAqD;AACrD,MAAM,WAAW,2BAA2B;IAC3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,6BAA6B,CAAC;CAC1C;AA6BD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,EAAE,6BAavC,CAAC;AAIF;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC,GAAG;IAC/C,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD,EACD,UAAS,2BAAgC,KACvC,KAAK,CAAC,SAAS,CAidjB,CAAC"}
1
+ {"version":3,"file":"role_grant_offer_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/role_grant_offer_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAGN,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAIN,KAAK,gBAAgB,EACrB,MAAM,kBAAkB,CAAC;AA0B1B,OAAO,EAA4C,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpG,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAEhD,OAAO,EAON,KAAK,kBAAkB,EACvB,MAAM,qCAAqC,CAAC;AAiC7C;;;;;;;;GAQG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAC3C,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,EACrE,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,EACnC,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,qDAAqD;AACrD,MAAM,WAAW,2BAA2B;IAC3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,6BAA6B,CAAC;CAC1C;AA6BD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,EAAE,6BAavC,CAAC;AAIF;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC,GAAG;IAC/C,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD,EACD,UAAS,2BAAgC,KACvC,KAAK,CAAC,SAAS,CAmdjB,CAAC"}
@@ -130,8 +130,10 @@ export const create_role_grant_offer_actions = (deps, options = {}) => {
130
130
  });
131
131
  };
132
132
  // Returns {offer} only — no auto-accept. Recipient must call
133
- // role_grant_offer_accept; admin tests materialize role_grants via
134
- // query_accept_offer (see testing/admin_integration.ts `offer_and_accept`).
133
+ // role_grant_offer_accept; admin tests drive the full consent flow over
134
+ // RPC (see testing/admin_integration.ts `offer_and_accept`), or seed
135
+ // role_grants directly via create_test_role_grant_direct when the
136
+ // test isn't about the consent path.
135
137
  const create_handler = async (input, ctx) => {
136
138
  const auth = ctx.auth;
137
139
  // Role must include the admin grant path — same gate as admin direct-grant.
@@ -24,7 +24,7 @@ export interface SignupRouteOptions extends AuthSessionRouteOptions {
24
24
  }
25
25
  /** Input for `POST /signup`. `email` is optional and must match any referenced invite. */
26
26
  export declare const SignupInput: z.ZodObject<{
27
- username: z.ZodString;
27
+ username: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
28
28
  password: z.ZodString;
29
29
  email: z.ZodOptional<z.ZodEmail>;
30
30
  }, z.core.$strict>;
@@ -10,6 +10,7 @@
10
10
  * Option routing: shared `roles` flows to both admin and role-grant-offer;
11
11
  * `app_settings` goes to admin only; `default_ttl_ms` and `authorize` go
12
12
  * to role-grant-offer only; `max_tokens` goes to account only;
13
+ * shared `connection_closer` flows to admin + account (role-grant-offer ignores);
13
14
  * `notification_sender` reaches role-grant-offer transparently (admin + account
14
15
  * ignore it).
15
16
  *
@@ -1 +1 @@
1
- {"version":3,"file":"standard_rpc_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/standard_rpc_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAuB,KAAK,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAEN,KAAK,2BAA2B,EAChC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAyB,KAAK,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACvF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,WAAW,yBAChB,SAAQ,kBAAkB,EAAE,2BAA2B,EAAE,oBAAoB;CAAG;AAEjF;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC;IACtF,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B,GACvC,MAAM,sBAAsB,EAC5B,UAAS,yBAA8B,KACrC,KAAK,CAAC,SAAS,CAIjB,CAAC"}
1
+ {"version":3,"file":"standard_rpc_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/standard_rpc_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAuB,KAAK,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAEN,KAAK,2BAA2B,EAChC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAyB,KAAK,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACvF,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,WAAW,yBAChB,SAAQ,kBAAkB,EAAE,2BAA2B,EAAE,oBAAoB;CAAG;AAEjF;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,OAAO,CAAC;IACtF,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAChD;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B,GACvC,MAAM,sBAAsB,EAC5B,UAAS,yBAA8B,KACrC,KAAK,CAAC,SAAS,CAIjB,CAAC"}
@@ -10,6 +10,7 @@
10
10
  * Option routing: shared `roles` flows to both admin and role-grant-offer;
11
11
  * `app_settings` goes to admin only; `default_ttl_ms` and `authorize` go
12
12
  * to role-grant-offer only; `max_tokens` goes to account only;
13
+ * shared `connection_closer` flows to admin + account (role-grant-offer ignores);
13
14
  * `notification_sender` reaches role-grant-offer transparently (admin + account
14
15
  * ignore it).
15
16
  *
@@ -1 +1 @@
1
- {"version":3,"file":"create_db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/create_db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAIxC,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,EAAE,CAAC;IACP,iFAAiF;IACjF,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,GAAU,cAAc,MAAM,KAAG,OAAO,CAAC,cAAc,CAgC5E,CAAC"}
1
+ {"version":3,"file":"create_db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/create_db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,EAAE,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAIxC,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,EAAE,CAAC;IACP,iFAAiF;IACjF,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,GAAU,cAAc,MAAM,KAAG,OAAO,CAAC,cAAc,CA6C5E,CAAC"}
@@ -32,6 +32,19 @@ import { create_pglite_db } from './db_pglite.js';
32
32
  export const create_db = async (database_url) => {
33
33
  if (database_url.startsWith('postgres://') || database_url.startsWith('postgresql://')) {
34
34
  const { default: pg } = await import('pg');
35
+ // Parse int8 (BIGINT) as a JS number. pg defaults to returning int8
36
+ // as a string to avoid 2^53 precision loss; our only int8 column
37
+ // today (`audit_log.seq`) stays well under that bound, and reading
38
+ // as number keeps the wire shape uniform across the SERIAL→BIGSERIAL
39
+ // widening.
40
+ //
41
+ // CAVEAT: pg.types.setTypeParser mutates pg.types globally — every
42
+ // pg.Pool in the process inherits the coercion, including pools the
43
+ // consumer constructs against unrelated databases. Any future int8
44
+ // column that could legitimately exceed 2^53 (file sizes, byte
45
+ // offsets) will silently round; if one lands, localize via a
46
+ // per-pool `types` override instead of widening this global parser.
47
+ pg.types.setTypeParser(20, (val) => Number(val));
35
48
  const pool = new pg.Pool({ connectionString: database_url });
36
49
  const { db, close } = create_pg_db(pool);
37
50
  return {
@@ -51,7 +51,7 @@ export interface ResetDbResult {
51
51
  /** Options for `setup_env_file`. */
52
52
  export interface SetupEnvOptions {
53
53
  /**
54
- * Extra env var replacements beyond the default `SECRET_COOKIE_KEYS`.
54
+ * Extra env var replacements beyond the default `SECRET_FUZ_COOKIE_KEYS`.
55
55
  *
56
56
  * Keys are env var names, values are async generators.
57
57
  * Replaces `^KEY=$` (empty value) patterns in the env file.
@@ -103,7 +103,7 @@ export declare const generate_random_key: (deps: CommandDeps) => Promise<string>
103
103
  */
104
104
  export declare const read_env_var: (deps: Pick<FsReadDeps, "stat" | "read_text_file">, env_path: string, name: string) => Promise<string | undefined>;
105
105
  /**
106
- * Create an env file from its example template, auto-generating `SECRET_COOKIE_KEYS`.
106
+ * Create an env file from its example template, auto-generating `SECRET_FUZ_COOKIE_KEYS`.
107
107
  *
108
108
  * If the file already exists, backfills any empty values that have generators.
109
109
  * Idempotent — safe to re-run.
package/dist/dev/setup.js CHANGED
@@ -69,7 +69,7 @@ export const read_env_var = async (deps, env_path, name) => {
69
69
  };
70
70
  // === Setup helpers ===
71
71
  /**
72
- * Create an env file from its example template, auto-generating `SECRET_COOKIE_KEYS`.
72
+ * Create an env file from its example template, auto-generating `SECRET_FUZ_COOKIE_KEYS`.
73
73
  *
74
74
  * If the file already exists, backfills any empty values that have generators.
75
75
  * Idempotent — safe to re-run.
@@ -84,9 +84,9 @@ export const read_env_var = async (deps, env_path, name) => {
84
84
  export const setup_env_file = async (deps, env_path, example_path, options) => {
85
85
  const log = options?.log ?? default_setup_logger;
86
86
  const set_permissions = options?.set_permissions;
87
- // build the full replacement map (SECRET_COOKIE_KEYS + extras)
87
+ // build the full replacement map (SECRET_FUZ_COOKIE_KEYS + extras)
88
88
  const replacements = {
89
- SECRET_COOKIE_KEYS: () => generate_random_key(deps),
89
+ SECRET_FUZ_COOKIE_KEYS: () => generate_random_key(deps),
90
90
  ...options?.replacements,
91
91
  };
92
92
  const stat = await deps.stat(env_path);