@fuzdev/fuz_app 0.61.0 → 0.63.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 (48) hide show
  1. package/dist/actions/CLAUDE.md +43 -35
  2. package/dist/actions/action_rpc.d.ts +10 -0
  3. package/dist/actions/action_rpc.d.ts.map +1 -1
  4. package/dist/actions/action_rpc.js +1 -1
  5. package/dist/actions/action_spec.d.ts +1 -1
  6. package/dist/actions/action_spec.js +1 -1
  7. package/dist/actions/perform_action.d.ts.map +1 -1
  8. package/dist/actions/perform_action.js +1 -0
  9. package/dist/auth/CLAUDE.md +47 -26
  10. package/dist/auth/account_action_specs.d.ts +6 -0
  11. package/dist/auth/account_action_specs.d.ts.map +1 -1
  12. package/dist/auth/account_action_specs.js +11 -4
  13. package/dist/auth/account_actions.d.ts.map +1 -1
  14. package/dist/auth/account_actions.js +9 -4
  15. package/dist/auth/account_routes.d.ts.map +1 -1
  16. package/dist/auth/account_routes.js +8 -4
  17. package/dist/auth/account_schema.d.ts +2 -2
  18. package/dist/auth/account_schema.js +2 -2
  19. package/dist/auth/actor_lookup_actions.d.ts +1 -1
  20. package/dist/auth/actor_lookup_actions.js +1 -1
  21. package/dist/auth/actor_lookup_queries.d.ts +1 -1
  22. package/dist/auth/actor_lookup_queries.js +1 -1
  23. package/dist/auth/actor_search_action_specs.d.ts +1 -1
  24. package/dist/auth/actor_search_action_specs.js +1 -1
  25. package/dist/auth/actor_search_actions.d.ts +1 -1
  26. package/dist/auth/actor_search_actions.js +1 -1
  27. package/dist/auth/actor_search_queries.d.ts +1 -1
  28. package/dist/auth/actor_search_queries.js +1 -1
  29. package/dist/auth/all_action_spec_registries.d.ts +2 -2
  30. package/dist/auth/all_action_spec_registries.js +2 -2
  31. package/dist/auth/audit_log_routes.d.ts +1 -1
  32. package/dist/auth/audit_log_routes.js +1 -1
  33. package/dist/auth/audit_log_schema.d.ts +25 -0
  34. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  35. package/dist/auth/audit_log_schema.js +16 -0
  36. package/dist/auth/request_context.d.ts +1 -1
  37. package/dist/env/update_env_variable.js +1 -1
  38. package/dist/http/CLAUDE.md +15 -15
  39. package/dist/server/app_server.d.ts +54 -6
  40. package/dist/server/app_server.d.ts.map +1 -1
  41. package/dist/server/app_server.js +32 -4
  42. package/dist/testing/CLAUDE.md +34 -50
  43. package/dist/testing/audit_completeness.d.ts.map +1 -1
  44. package/dist/testing/audit_completeness.js +17 -1
  45. package/dist/ui/CLAUDE.md +13 -18
  46. package/dist/ui/keyed_async_slot.svelte.d.ts +1 -1
  47. package/dist/ui/keyed_async_slot.svelte.js +1 -1
  48. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,IAAI,EAAE,KAAK,OAAO,EAAC,MAAM,MAAM,CAAC;AAGxC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAEN,KAAK,cAAc,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAGN,KAAK,WAAW,EAChB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAEhE,OAAO,EAKN,KAAK,WAAW,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAGjD,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAA2B,KAAK,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAE9E,OAAO,EAEN,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAGN,KAAK,eAAe,EACpB,MAAM,6BAA6B,CAAC;AASrC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAChC,2DAA2D;IAC3D,OAAO,EAAE,UAAU,CAAC;IACpB,6CAA6C;IAC7C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,sCAAsC;IACtC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAE/B,6BAA6B;IAC7B,KAAK,EAAE;QACN,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/B,iBAAiB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;KACtD,CAAC;IAEF;;;;;OAKG;IACH,eAAe,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;;;;;;OAQG;IACH,2BAA2B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,gBAAgB,CAAC;IAEtC,yEAAyE;IACzE,SAAS,CAAC,EAAE;QACX,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,mEAAmE;QACnE,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB;;;WAGG;QACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9E,CAAC;IAEF;;;OAGG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC;IAEtB;;;OAGG;IACH,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAEpE,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,KAAK,CAAC,cAAc,CAAC,CAAC;IAE/E;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,IAAI,GAAG;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;IAEvC,gFAAgF;IAChF,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAE/B;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAEjG,gHAAgH;IAChH,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC;IAExB,mFAAmF;IACnF,qBAAqB,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAE9C,6DAA6D;IAC7D,cAAc,CAAC,EAAE;QAChB,YAAY,EAAE,kBAAkB,CAAC;QACjC,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IAEF;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAExE,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,gBAAgB,EAAE,eAAe,CAAC;IAClC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,yEAAyE;IACzE,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC,iFAAiF;IACjF,0BAA0B,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/C,kFAAkF;IAClF,2BAA2B,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,uGAAuG;IACvG,sBAAsB,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C,0GAA0G;IAC1G,2BAA2B,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD,2EAA2E;IAC3E,YAAY,EAAE,WAAW,CAAC;IAC1B,oFAAoF;IACpF,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;CAC9B;AAED,uCAAuC;AACvC,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,IAAI,CAAC;IACV,wEAAwE;IACxE,YAAY,EAAE,cAAc,CAAC;IAC7B,gBAAgB,EAAE,eAAe,CAAC;IAClC,2EAA2E;IAC3E,YAAY,EAAE,WAAW,CAAC;IAC1B,oGAAoG;IACpG,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,oFAAoF;IACpF,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,mEAAmE;IACnE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,QAAc,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,GAAU,SAAS,gBAAgB,KAAG,OAAO,CAAC,SAAS,CAmRpF,CAAC"}
1
+ {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ import { bodyLimit } from 'hono/body-limit';
13
13
  import { z } from 'zod';
14
14
  import { session_cookie_options, } from '../auth/session_cookie.js';
15
15
  import { create_audit_log_sse, audit_log_event_specs, } from '../realtime/sse_auth_guard.js';
16
+ import { BaseServerEnv } from './env.js';
16
17
  import { query_app_settings_load } from '../auth/app_settings_queries.js';
17
18
  import { create_rate_limiter, default_login_account_rate_limit, default_action_account_rate_limit, default_action_ip_rate_limit, } from '../rate_limiter.js';
18
19
  // Side-effect import: augments Hono's ContextVariableMap so consumers
@@ -31,6 +32,29 @@ import { fuz_auth_guard_resolver } from '../auth/auth_guard_resolver.js';
31
32
  import { create_fuz_authorization_handler } from '../auth/request_context.js';
32
33
  import { ERROR_PAYLOAD_TOO_LARGE } from '../http/error_schemas.js';
33
34
  import { create_rpc_endpoint } from '../actions/action_rpc.js';
35
+ /**
36
+ * Assert that `audit_sse` was wired by `create_app_server` and return it
37
+ * as a non-null `AuditLogSse`. Throws a labelled error when the
38
+ * `audit_log_sse` option was not passed to `create_app_server`.
39
+ *
40
+ * Use in route factories that depend on factory-managed audit SSE:
41
+ *
42
+ * ```ts
43
+ * create_route_specs: (ctx) => create_audit_log_route_specs({
44
+ * stream: require_audit_sse(ctx),
45
+ * }),
46
+ * ```
47
+ *
48
+ * Preferred over `ctx.audit_sse!` — `!` lies to the type system and
49
+ * produces a downstream cannot-read-property crash if a consumer wires
50
+ * the route without enabling the option.
51
+ */
52
+ export const require_audit_sse = (source) => {
53
+ if (!source.audit_sse) {
54
+ throw new Error('audit_sse is null — pass `audit_log_sse: true` (or `{role}`) in `AppServerOptions`');
55
+ }
56
+ return source.audit_sse;
57
+ };
34
58
  /** Default maximum request body size: 1 MiB. */
35
59
  export const DEFAULT_MAX_BODY_SIZE = 1024 * 1024;
36
60
  /**
@@ -42,7 +66,11 @@ export const DEFAULT_MAX_BODY_SIZE = 1024 * 1024;
42
66
  * pass `migration_namespaces` to `create_app_backend`.
43
67
  *
44
68
  * When `audit_log_sse` is set, the SSE registry's listener is appended to
45
- * `backend.deps.audit.on_event_chain` — no shallow-copy of `AppDeps`.
69
+ * `backend.deps.audit.on_event_chain` — no shallow-copy of `AppDeps`. The
70
+ * `audit_sse` field on the returned `AppServer` (and the
71
+ * `AppServerContext` passed to `create_route_specs`) is non-null in that
72
+ * case; consumers can call `require_audit_sse(ctx)` / `require_audit_sse(server)`
73
+ * to assert the invariant.
46
74
  *
47
75
  * @returns assembled Hono app, backend, surface build, and bootstrap status
48
76
  */
@@ -161,7 +189,7 @@ export const create_app_server = async (options) => {
161
189
  const surface_spec = create_app_surface_spec({
162
190
  middleware_specs: surface_middleware,
163
191
  route_specs,
164
- env_schema: options.env_schema,
192
+ env_schema: options.env_schema ?? BaseServerEnv,
165
193
  event_specs: all_event_specs,
166
194
  rpc_endpoints: resolved_rpc_endpoints,
167
195
  });
@@ -269,8 +297,8 @@ export const create_app_server = async (options) => {
269
297
  }
270
298
  // Static file serving
271
299
  if (options.static_serving) {
272
- const { serve_static, spa_fallback } = options.static_serving;
273
- for (const mw of create_static_middleware(serve_static, { spa_fallback })) {
300
+ const { serve_static, root, spa_fallback, is_spa_route } = options.static_serving;
301
+ for (const mw of create_static_middleware(serve_static, { root, spa_fallback, is_spa_route })) {
274
302
  app.use('/*', mw);
275
303
  }
276
304
  }
@@ -6,23 +6,17 @@ round-trip harnesses. Consumers import these to assemble their own test suites
6
6
  against a fuz_app-derived server.
7
7
 
8
8
  For narrative wiring examples (how to call these from a consumer's vitest
9
- setup), see `../../../docs/testing.md`. For fuz_app's own test suite
10
- conventions (`.db.test.ts` suffix, the `db` vitest project, `assert_rejects`),
11
- see `../../test/CLAUDE.md`. This file is a reference index for the helpers
12
- themselves.
9
+ setup), see ../../../docs/testing.md. For fuz_app's own test suite
10
+ conventions, see ../../test/CLAUDE.md. For shared testing conventions
11
+ (`.db.test.ts`, `assert` from vitest, `assert_rejects`, `vi.mock` caveats),
12
+ see Skill(fuz-stack) testing-patterns. This file is a reference index for
13
+ the helpers themselves.
13
14
 
14
15
  ## Production guard — always the first import
15
16
 
16
- Every module in this directory starts with `import './assert_dev_env.js';`
17
- as its first line. The side-effect import reads `DEV` from `esm-env` and
18
- throws if it is false preventing accidental inclusion in production
19
- bundles. SvelteKit and Vite set `DEV` correctly for dev + tests; the
20
- production code path explodes at the first testing-module import.
21
-
22
- When adding a new module to this directory, make this import the first
23
- line. The convention is enforced by grep, not by a linter — break it and
24
- the production bundle still builds, then crashes at runtime on first
25
- module load.
17
+ Every module here starts with `import './assert_dev_env.js';` — reads `DEV`
18
+ from `esm-env` and throws if false, preventing production-bundle inclusion.
19
+ Enforced by grep, not a linter; make this the first line in new modules.
26
20
 
27
21
  ## Stubs, factories, mocks
28
22
 
@@ -40,7 +34,7 @@ module load.
40
34
  | `create_stub_app_deps()` | Factory returning fresh `AppDeps` with no-op FS/keyring/password, a `create_noop_stub` DB, silent `Logger`, no-op `audit`. |
41
35
  | `create_test_audit_emitter()` | No-op `AuditEmitter` for tests that don't assert on audit fan-out. `emit` / `emit_role_grant_target` are no-ops; `emit_pool` resolves immediately; `notify` is a no-op; `on_event_chain` is empty. |
42
36
  | `create_stub_audit_sse()` | No-op `AuditLogSse` for surface-test wiring without booting real SSE. `subscribe` returns a no-op cleanup; `on_audit_event` is a no-op; the `registry` is a fresh `SubscriberRegistry` (live `.size` / `.close_*` for tests touching registry state, isolated per call). For real SSE plumbing, build via `create_audit_log_sse` against `create_test_app`. |
43
- | `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. |
37
+ | `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. |
44
38
  | `create_stub_app_server_context(session_options)` | Stub `AppServerContext` — rate limiters null, `bootstrap_status.available: false`, `app_settings.open_signup: false`. |
45
39
  | `create_test_app_surface_spec(options)` | Builds an `AppSurfaceSpec` that mirrors `create_app_server`'s route assembly: consumer routes + factory-managed bootstrap routes (prefixed via `bootstrap_route_prefix`, default `'/api/account'`) + stub middleware + surface generation. `CreateTestAppSurfaceSpecOptions` accepts `session_options`, `create_route_specs`, `env_schema?`, `event_specs?`, `rpc_endpoints?`, `transform_middleware?`, `bootstrap_route_prefix?`. Single source of truth for attack-surface tests — track `create_app_server` wiring changes here. |
46
40
 
@@ -572,7 +566,7 @@ Options: `{session_options, create_route_specs, app_options?, db_factories?}`.
572
566
 
573
567
  7 test groups covering admin surface: account listing, role_grant grant
574
568
  lifecycle (via `role_grant_offer_create` + `role_grant_revoke` RPC flows —
575
- **not** REST; see `../auth/CLAUDE.md` for `role_grant_offer_action_specs.ts` + `role_grant_offer_actions.ts`), session / token management, audit log reads (RPC),
569
+ **not** REST; see `auth/CLAUDE.md` for `role_grant_offer_action_specs.ts` + `role_grant_offer_actions.ts`), session / token management, audit log reads (RPC),
576
570
  admin-to-admin isolation, error coverage, response schema validation.
577
571
 
578
572
  Required options: `{session_options, create_route_specs, roles: RoleSchemaResult, rpc_endpoints: RpcEndpointsSuiteOption, admin_prefix?, app_options?, db_factories?}`.
@@ -688,7 +682,7 @@ Registry lookups:
688
682
  - unauthenticated → `unauthenticated` (code -32001)
689
683
  - wrong role → `forbidden` (-32002)
690
684
  - authenticated without role → `forbidden`
691
- - **keeper rejects non-daemon credentials** — session and api_token credentials are rejected even when the account has the keeper role (only `daemon_token` passes). The credential-type gate fires before the role gate (see `../auth/CLAUDE.md` §`request_context.ts` for `require_credential_types`).
685
+ - **keeper rejects non-daemon credentials** — session and api_token credentials are rejected even when the account has the keeper role (only `daemon_token` passes). The credential-type gate fires before the role gate (see `auth/CLAUDE.md` §`request_context.ts` for `require_credential_types`).
692
686
  - correct auth passes (not 401/403)
693
687
  - GET unauthenticated for `side_effects: false` reads
694
688
  2. **RPC adversarial envelopes** — fixed set exercising dispatcher steps 1–2: non-JSON body, wrong `jsonrpc` version, missing `jsonrpc` / `method` / `id`, batch array, unknown method, GET missing `method`/`id`, GET invalid JSON params, GET non-object params, GET mutation method → `invalid_request`.
@@ -700,47 +694,37 @@ deps — no DB needed.
700
694
  Options: `{build: () => AppSurfaceSpec, roles: Array<string>}`.
701
695
 
702
696
  **Opt-in bundles need their own per-bundle suite file.** Action bundles
703
- not folded into `create_standard_rpc_actions` (today `self_service_role_actions`
704
- and `actor_lookup_actions`) get zero adversarial / round-trip coverage
705
- from `describe_rpc_attack_surface_tests` + `describe_rpc_round_trip_tests`
706
- unless the consumer ships a `<module>.rpc_suites.db.test.ts` mounting the
707
- opt-in factory on the RPC endpoint and calling both suites. See
708
- `../../test/CLAUDE.md` §Composable Test Suites for the obligation note
709
- and `actor_lookup_actions.rpc_suites.db.test.ts` /
710
- `role_grant_offer_actions.rpc_suites.db.test.ts` as templates.
697
+ not folded into `create_standard_rpc_actions` (today `self_service_role_actions`,
698
+ `actor_lookup_actions`, and `actor_search_actions`) get zero adversarial
699
+ / round-trip coverage from `describe_rpc_attack_surface_tests` +
700
+ `describe_rpc_round_trip_tests` unless the consumer ships a
701
+ `<module>.rpc_suites.db.test.ts` mounting the opt-in factory on the RPC
702
+ endpoint and calling both suites. See ../../test/CLAUDE.md §Composable
703
+ Test Suites for the obligation note; existing
704
+ ../../test/auth/\*.rpc_suites.db.test.ts files are templates.
711
705
 
712
706
  ## Cross-cutting conventions
713
707
 
714
- - **`assert` from vitest, not `expect`.** Project-wide convention
715
- (mirrored in `src/test/CLAUDE.md`). Use `assert_rejects` from
716
- `@fuzdev/fuz_util/testing.js` for async rejection assertions.
717
- - **`.db.test.ts` suffix** for any test file that instantiates a `Db`
718
- (directly or via `create_test_app`, `create_describe_db`,
719
- `create_pglite_factory`). The suffix opts the file into the `db`
720
- vitest project (`isolate: false`, `fileParallelism: false`) so the
721
- PGlite WASM cache is shared across every DB test file.
708
+ Shared conventions (`.db.test.ts` suffix, `isolate: false` semantics,
709
+ `assert` from vitest, `assert_rejects`, `vi.mock` avoidance under
710
+ `isolate: false`) live in Skill(fuz-stack) testing-patterns.
711
+ fuz_app-specific points:
712
+
722
713
  - **`await_pending_effects: true`** is set by `create_test_app`.
723
714
  Fire-and-forget effects (audit logs, session touches, WS fan-out via
724
715
  `emit_after_commit`) resolve before the response returns, so tests
725
716
  can assert on side effects inline without manual flushing.
726
- - **Avoid `vi.mock()` inside `.db.test.ts`.** With `isolate: false`,
727
- module-level mocks leak across files. When a mock is unavoidable
728
- (e.g. `middleware.ts` uses them module-level for bearer auth tests),
729
- always pair with `vi.restoreAllMocks()` in `afterEach` to contain
730
- the blast radius.
731
- - **Deep-path imports only.** `testing/` follows the package
732
- convention import from the canonical module (`./db.js`,
733
- `./rpc_helpers.js`, etc.), never a barrel. fuz_app's `dist/` doesn't
734
- ship one.
735
- - **DI via small `*Deps` interfaces.** Stub factories here accept the
736
- same narrow `*Deps` contracts production code uses — never
737
- `Pick<GodType, ...>`. New helpers that need env/fs/logger access
738
- should take `EnvDeps` / `FsReadDeps` / `Logger` from
739
- `runtime/deps.ts` or `@fuzdev/fuz_util/log.js`.
717
+ - **Deep-path imports only.** Import from the canonical module
718
+ (`testing/db.js`, `testing/rpc_helpers.js`, etc.); fuz_app's `dist/` ships no
719
+ barrel.
720
+ - **DI via small `*Deps` interfaces.** Stub factories accept the same
721
+ narrow `*Deps` contracts production code uses — never
722
+ `Pick<GodType, ...>`. New helpers needing env/fs/logger take
723
+ `EnvDeps` / `FsReadDeps` / `Logger` from `runtime/deps.ts` or
724
+ `@fuzdev/fuz_util/log.js`.
740
725
  - **Keep the shared echo routes in sync with public surface.** When
741
726
  middleware or public API gains a new context variable, header, or
742
727
  field, update the echo in `middleware.ts`
743
728
  (`create_bearer_auth_test_app`, `create_test_middleware_stack_app`)
744
- alongside the assertions in `src/test/auth/*.test.ts`. The two move
745
- together — drift between them shows up as a missed assertion, not a
746
- test failure.
729
+ alongside the assertions in `src/test/auth/*.test.ts`. Drift surfaces
730
+ as a missed assertion, not a test failure.
@@ -1 +1 @@
1
- {"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAIrD,OAAO,EAGN,KAAK,eAAe,EAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAKjB,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;;;;;;;;;OAWG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AAoDD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,IAkgBzF,CAAC"}
1
+ {"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAIrD,OAAO,EAGN,KAAK,eAAe,EAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAKjB,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;;;;;;;;;OAWG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AA2ED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,IAihBzF,CAAC"}
@@ -27,12 +27,23 @@ import { admin_session_revoke_all_action_spec, admin_token_revoke_all_action_spe
27
27
  import { account_session_list_action_spec, account_session_revoke_action_spec, account_session_revoke_all_action_spec, account_token_create_action_spec, account_token_list_action_spec, account_token_revoke_action_spec, } from '../auth/account_action_specs.js';
28
28
  /** Query audit log events from the database. */
29
29
  const query_audit_events = async (db) => {
30
- return db.query('SELECT event_type, seq FROM audit_log ORDER BY seq');
30
+ return db.query('SELECT event_type, seq, metadata FROM audit_log ORDER BY seq');
31
31
  };
32
32
  /** Assert that audit events contain the expected event type. */
33
33
  const assert_has_event = (events, expected, context) => {
34
34
  assert.ok(events.some((e) => e.event_type === expected), `Expected '${expected}' audit event after ${context}`);
35
35
  };
36
+ /**
37
+ * Assert that an event type was emitted with the expected `credential_type`
38
+ * recorded in metadata — defense-in-depth coverage for the spec gate
39
+ * documented in `docs/security.md` §Credential-channel gating.
40
+ */
41
+ const assert_event_credential_type = (events, expected, credential_type, context) => {
42
+ const match = events.find((e) => e.event_type === expected);
43
+ assert.ok(match, `Expected '${expected}' audit event after ${context}`);
44
+ const recorded = (match.metadata ?? {}).credential_type;
45
+ assert.strictEqual(recorded, credential_type, `Expected '${expected}' audit metadata.credential_type === '${credential_type}' after ${context} (got ${JSON.stringify(recorded)})`);
46
+ };
36
47
  /** Build CreateTestAppOptions with admin+keeper roles. */
37
48
  const build_options = (options, db) => ({
38
49
  session_options: options.session_options,
@@ -138,6 +149,7 @@ export const describe_audit_completeness_tests = (options) => {
138
149
  assert.ok(res.ok, `account_token_create failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
139
150
  const events = await query_audit_events(test_app.backend.deps.db);
140
151
  assert_has_event(events, 'token_create', 'account_token_create RPC');
152
+ assert_event_credential_type(events, 'token_create', 'session', 'account_token_create RPC');
141
153
  });
142
154
  test('token revoke produces token_revoke event', async () => {
143
155
  const test_app = await create_test_app(build_options(options, get_db()));
@@ -162,6 +174,7 @@ export const describe_audit_completeness_tests = (options) => {
162
174
  assert.ok(res.ok, `account_token_revoke failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
163
175
  const events = await query_audit_events(test_app.backend.deps.db);
164
176
  assert_has_event(events, 'token_revoke', 'account_token_revoke RPC');
177
+ assert_event_credential_type(events, 'token_revoke', 'session', 'account_token_revoke RPC');
165
178
  });
166
179
  test('session revoke produces session_revoke event', async () => {
167
180
  const test_app = await create_test_app(build_options(options, get_db()));
@@ -198,6 +211,7 @@ export const describe_audit_completeness_tests = (options) => {
198
211
  assert.ok(res.ok, `account_session_revoke failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
199
212
  const events = await query_audit_events(test_app.backend.deps.db);
200
213
  assert_has_event(events, 'session_revoke', 'account_session_revoke RPC');
214
+ assert_event_credential_type(events, 'session_revoke', 'session', 'account_session_revoke RPC');
201
215
  });
202
216
  test('session revoke-all produces session_revoke_all event', async () => {
203
217
  const test_app = await create_test_app(build_options(options, get_db()));
@@ -211,6 +225,7 @@ export const describe_audit_completeness_tests = (options) => {
211
225
  assert.ok(res.ok, `account_session_revoke_all failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
212
226
  const events = await query_audit_events(test_app.backend.deps.db);
213
227
  assert_has_event(events, 'session_revoke_all', 'account_session_revoke_all RPC');
228
+ assert_event_credential_type(events, 'session_revoke_all', 'session', 'account_session_revoke_all RPC');
214
229
  });
215
230
  test('password change produces password_change event', async () => {
216
231
  const test_app = await create_test_app(build_options(options, get_db()));
@@ -227,6 +242,7 @@ export const describe_audit_completeness_tests = (options) => {
227
242
  assert.strictEqual(res.status, 200);
228
243
  const events = await query_audit_events(test_app.backend.deps.db);
229
244
  assert_has_event(events, 'password_change', 'POST /password');
245
+ assert_event_credential_type(events, 'password_change', 'session', 'POST /password');
230
246
  });
231
247
  });
232
248
  // --- Admin routes ---
package/dist/ui/CLAUDE.md CHANGED
@@ -5,14 +5,16 @@ utilities. Cookie-based SPA auth; prerendered static HTML served by Hono
5
5
  (no SvelteKit SSR for sessions). State classes hold one or more `AsyncSlot`s
6
6
  via composition (one per distinct async operation — e.g. `list` + `create` +
7
7
  `revoke`); per-row write ops use `KeyedAsyncSlot<K, T = void, E = string>`
8
- (supersedes the old `AsyncSlot` + `SvelteSet<id>` pair) so concurrent rows
9
- don't abort each other and failures surface per-row via `slot.error(key)`.
10
- Payload lives as `$state.raw` fields on the class. Shared dependencies flow
11
- through Svelte context, never through props RPC adapters in particular
12
- are provisioned once at the admin shell and read by every `Admin*.svelte`.
8
+ so concurrent rows don't abort each other and failures surface per-row via
9
+ `slot.error(key)`. Payload lives as `$state.raw` fields on the class.
10
+ Shared dependencies flow through Svelte context, never through props
11
+ RPC adapters are provisioned once at the admin shell and read by every
12
+ `Admin*.svelte`.
13
13
 
14
- See ../../docs/usage.md for end-to-end wiring examples (sections "Role grant
15
- offer UI" and "Admin UI"). This file is a reference, not a tutorial.
14
+ For Svelte 5 patterns (runes, inline `$props`, contexts, snippets,
15
+ attachments), see Skill(fuz-stack) svelte-patterns. See ../../docs/usage.md
16
+ for end-to-end wiring examples ("Role grant offer UI", "Admin UI"). This
17
+ file is a reference, not a tutorial.
16
18
 
17
19
  ## Key patterns
18
20
 
@@ -67,15 +69,8 @@ it. Six methods land on the reducer: `role_grant_offer_received` /
67
69
  `_retracted` / `_accepted` / `_declined` / `_supersede` all merge a
68
70
  `{offer}` payload; `role_grant_revoke` is ignored at this layer (role_grant
69
71
  lifecycle lives in auth/role_grants state). The six notification specs and
70
- their payload shapes are defined in `../auth/role_grant_offer_notifications.ts`
71
- (see `../auth/CLAUDE.md` §WS notifications).
72
-
73
- ### Svelte 5 inline `$props` shape
74
-
75
- Always `const {...}: {...} = $props()` — never `interface Props`.
76
- Destructure defaults in the binding list; put the type literal inline.
77
- This matches the user-memory Svelte props rule and the existing file
78
- conventions.
72
+ their payload shapes are defined in `auth/role_grant_offer_notifications.ts`
73
+ (see `auth/CLAUDE.md` §WS notifications).
79
74
 
80
75
  ### Context over props for shared deps
81
76
 
@@ -184,8 +179,8 @@ destructive actions.
184
179
  reason codes with friendly copy: `ERROR_ROLE_GRANT_OFFER_SELF_TARGET`,
185
180
  `ERROR_ROLE_GRANT_OFFER_ROLE_NOT_GRANTABLE`, `ERROR_ROLE_GRANT_OFFER_NOT_AUTHORIZED`,
186
181
  `ERROR_ROLE_GRANT_OFFER_ACTOR_ACCOUNT_MISMATCH`, `ERROR_ROLE_GRANT_OFFER_ACTOR_MISMATCH`
187
- — imported from `../auth/role_grant_offer_action_specs.js` (see
188
- `../auth/CLAUDE.md` for `role_grant_offer_action_specs.ts` +
182
+ — imported from `auth/role_grant_offer_action_specs.js` (see
183
+ `auth/CLAUDE.md` for `role_grant_offer_action_specs.ts` +
189
184
  `role_grant_offer_actions.ts`).
190
185
  - `RoleGrantOfferHistory.svelte` — both-directions history (recipient +
191
186
  grantor, including terminal). Props: `current_actor_id: string | null`
@@ -56,7 +56,7 @@ export type KeyedAsyncSlotOptions<T, E = string> = Omit<AsyncSlotOptions<T, E>,
56
56
  *
57
57
  * @typeParam K - The key type. Map identity is SameValueZero — branded
58
58
  * strings (`Uuid`) work directly. For composite keys, stringify at
59
- * the call site (e.g. `` `${account_id}:${role}` ``).
59
+ * the call site (e.g. "`${account_id}:${role}`").
60
60
  * @typeParam T - The success payload type. Use `void` for write-only
61
61
  * actions whose response isn't worth retaining.
62
62
  * @typeParam E - The shape of per-key `error(key)`. Defaults to
@@ -48,7 +48,7 @@ import { AsyncSlot } from './async_slot.svelte.js';
48
48
  *
49
49
  * @typeParam K - The key type. Map identity is SameValueZero — branded
50
50
  * strings (`Uuid`) work directly. For composite keys, stringify at
51
- * the call site (e.g. `` `${account_id}:${role}` ``).
51
+ * the call site (e.g. "`${account_id}:${role}`").
52
52
  * @typeParam T - The success payload type. Use `void` for write-only
53
53
  * actions whose response isn't worth retaining.
54
54
  * @typeParam E - The shape of per-key `error(key)`. Defaults to
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_app",
3
- "version": "0.61.0",
3
+ "version": "0.63.0",
4
4
  "description": "fullstack app library",
5
5
  "glyph": "🗝",
6
6
  "logo": "logo.svg",