@fuzdev/fuz_app 0.58.0 → 0.60.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 (107) hide show
  1. package/dist/actions/CLAUDE.md +13 -8
  2. package/dist/actions/action_codegen.d.ts +1 -1
  3. package/dist/actions/action_codegen.js +2 -2
  4. package/dist/actions/action_event_helpers.d.ts +3 -3
  5. package/dist/actions/action_event_helpers.js +8 -8
  6. package/dist/actions/action_event_types.d.ts +3 -3
  7. package/dist/actions/action_event_types.js +3 -3
  8. package/dist/actions/transports_ws_auth_guard.d.ts +2 -2
  9. package/dist/actions/transports_ws_auth_guard.js +3 -3
  10. package/dist/auth/CLAUDE.md +215 -45
  11. package/dist/auth/account_action_specs.d.ts +9 -0
  12. package/dist/auth/account_action_specs.d.ts.map +1 -1
  13. package/dist/auth/account_action_specs.js +9 -0
  14. package/dist/auth/actor_lookup_action_specs.d.ts +127 -0
  15. package/dist/auth/actor_lookup_action_specs.d.ts.map +1 -0
  16. package/dist/auth/actor_lookup_action_specs.js +93 -0
  17. package/dist/auth/actor_lookup_actions.d.ts +19 -0
  18. package/dist/auth/actor_lookup_actions.d.ts.map +1 -0
  19. package/dist/auth/actor_lookup_actions.js +32 -0
  20. package/dist/auth/actor_lookup_queries.d.ts +44 -0
  21. package/dist/auth/actor_lookup_queries.d.ts.map +1 -0
  22. package/dist/auth/actor_lookup_queries.js +42 -0
  23. package/dist/auth/actor_search_action_specs.d.ts +166 -0
  24. package/dist/auth/actor_search_action_specs.d.ts.map +1 -0
  25. package/dist/auth/actor_search_action_specs.js +139 -0
  26. package/dist/auth/actor_search_actions.d.ts +31 -0
  27. package/dist/auth/actor_search_actions.d.ts.map +1 -0
  28. package/dist/auth/actor_search_actions.js +61 -0
  29. package/dist/auth/actor_search_queries.d.ts +75 -0
  30. package/dist/auth/actor_search_queries.d.ts.map +1 -0
  31. package/dist/auth/actor_search_queries.js +91 -0
  32. package/dist/auth/admin_action_specs.d.ts +35 -0
  33. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  34. package/dist/auth/admin_action_specs.js +35 -0
  35. package/dist/auth/admin_actions.js +2 -2
  36. package/dist/auth/all_action_spec_registries.d.ts +55 -0
  37. package/dist/auth/all_action_spec_registries.d.ts.map +1 -0
  38. package/dist/auth/all_action_spec_registries.js +59 -0
  39. package/dist/auth/audit_emitter.d.ts +1 -1
  40. package/dist/auth/audit_emitter.js +2 -2
  41. package/dist/auth/audit_log_queries.d.ts +1 -1
  42. package/dist/auth/audit_log_queries.js +3 -3
  43. package/dist/auth/audit_log_routes.d.ts +1 -1
  44. package/dist/auth/audit_log_routes.js +1 -1
  45. package/dist/auth/audit_log_schema.d.ts +5 -5
  46. package/dist/auth/audit_log_schema.js +7 -7
  47. package/dist/auth/auth_ddl.d.ts +7 -0
  48. package/dist/auth/auth_ddl.d.ts.map +1 -1
  49. package/dist/auth/auth_ddl.js +8 -0
  50. package/dist/auth/credential_type_schema.d.ts +1 -1
  51. package/dist/auth/credential_type_schema.js +3 -3
  52. package/dist/auth/grant_path_schema.d.ts +1 -1
  53. package/dist/auth/grant_path_schema.js +3 -3
  54. package/dist/auth/migrations.d.ts +4 -4
  55. package/dist/auth/migrations.d.ts.map +1 -1
  56. package/dist/auth/migrations.js +7 -6
  57. package/dist/auth/role_grant_offer_action_specs.d.ts +17 -0
  58. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
  59. package/dist/auth/role_grant_offer_action_specs.js +17 -0
  60. package/dist/auth/role_grant_offer_actions.js +2 -2
  61. package/dist/auth/role_grant_offer_notifications.d.ts +2 -2
  62. package/dist/auth/role_grant_offer_notifications.js +2 -2
  63. package/dist/auth/role_grant_queries.d.ts +21 -0
  64. package/dist/auth/role_grant_queries.d.ts.map +1 -1
  65. package/dist/auth/role_grant_queries.js +31 -0
  66. package/dist/auth/role_schema.d.ts +2 -2
  67. package/dist/auth/role_schema.js +3 -3
  68. package/dist/auth/self_service_role_action_specs.d.ts +8 -0
  69. package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
  70. package/dist/auth/self_service_role_action_specs.js +8 -0
  71. package/dist/auth/self_service_role_actions.d.ts +1 -1
  72. package/dist/auth/self_service_role_actions.js +2 -2
  73. package/dist/auth/session_cookie.d.ts +1 -1
  74. package/dist/auth/session_cookie.js +1 -1
  75. package/dist/auth/session_middleware.d.ts +1 -1
  76. package/dist/auth/session_middleware.js +5 -5
  77. package/dist/rate_limiter.d.ts +5 -5
  78. package/dist/rate_limiter.js +6 -6
  79. package/dist/realtime/sse_auth_guard.d.ts +3 -3
  80. package/dist/realtime/sse_auth_guard.js +4 -4
  81. package/dist/server/app_backend.d.ts +3 -3
  82. package/dist/server/app_backend.js +4 -4
  83. package/dist/server/app_server.d.ts +1 -1
  84. package/dist/server/app_server.js +10 -10
  85. package/dist/testing/CLAUDE.md +22 -12
  86. package/dist/testing/admin_integration.js +4 -4
  87. package/dist/testing/app_server.d.ts +1 -1
  88. package/dist/testing/app_server.js +2 -2
  89. package/dist/testing/attack_surface.d.ts +4 -4
  90. package/dist/testing/attack_surface.js +6 -6
  91. package/dist/testing/audit_completeness.js +4 -4
  92. package/dist/testing/data_exposure.d.ts +2 -2
  93. package/dist/testing/data_exposure.js +7 -7
  94. package/dist/testing/db.d.ts +8 -8
  95. package/dist/testing/db.js +11 -11
  96. package/dist/testing/integration.js +4 -4
  97. package/dist/testing/integration_helpers.d.ts +6 -6
  98. package/dist/testing/integration_helpers.js +7 -7
  99. package/dist/testing/rate_limiting.js +4 -4
  100. package/dist/testing/round_trip.js +2 -2
  101. package/dist/testing/rpc_round_trip.js +2 -2
  102. package/dist/testing/schema_generators.d.ts.map +1 -1
  103. package/dist/testing/schema_generators.js +23 -2
  104. package/dist/testing/sse_round_trip.js +2 -2
  105. package/dist/testing/surface_invariants.d.ts +4 -4
  106. package/dist/testing/surface_invariants.js +5 -5
  107. package/package.json +1 -1
@@ -18,7 +18,7 @@ export declare const get_session_cookie: <T>(c: Context, options: SessionOptions
18
18
  * `options.max_age` is the single source of truth for cookie lifetime: it
19
19
  * drives both the embedded `expires_at` (via `create_session_cookie_value`)
20
20
  * and the cookie's HTTP `Max-Age` attribute set here. Falls back to
21
- * `SESSION_COOKIE_OPTIONS.maxAge` (= `SESSION_AGE_MAX`) when unset.
21
+ * `session_cookie_options.maxAge` (= `SESSION_AGE_MAX`) when unset.
22
22
  * `options.cookie_options` cannot carry `maxAge` (omitted in the type) so
23
23
  * the two values can't drift.
24
24
  */
@@ -5,7 +5,7 @@
5
5
  * @module
6
6
  */
7
7
  import { getCookie, setCookie, deleteCookie } from 'hono/cookie';
8
- import { SESSION_COOKIE_OPTIONS, process_session_cookie, create_session_cookie_value, } from './session_cookie.js';
8
+ import { session_cookie_options, process_session_cookie, create_session_cookie_value, } from './session_cookie.js';
9
9
  import { generate_session_token, hash_session_token, AUTH_SESSION_LIFETIME_MS, query_create_session, query_session_enforce_limit, } from './session_queries.js';
10
10
  /**
11
11
  * Read the session cookie value from a request.
@@ -19,15 +19,15 @@ export const get_session_cookie = (c, options) => {
19
19
  * `options.max_age` is the single source of truth for cookie lifetime: it
20
20
  * drives both the embedded `expires_at` (via `create_session_cookie_value`)
21
21
  * and the cookie's HTTP `Max-Age` attribute set here. Falls back to
22
- * `SESSION_COOKIE_OPTIONS.maxAge` (= `SESSION_AGE_MAX`) when unset.
22
+ * `session_cookie_options.maxAge` (= `SESSION_AGE_MAX`) when unset.
23
23
  * `options.cookie_options` cannot carry `maxAge` (omitted in the type) so
24
24
  * the two values can't drift.
25
25
  */
26
26
  export const set_session_cookie = (c, value, options) => {
27
27
  const cookie_options = {
28
- ...SESSION_COOKIE_OPTIONS,
28
+ ...session_cookie_options,
29
29
  ...options.cookie_options,
30
- maxAge: options.max_age ?? SESSION_COOKIE_OPTIONS.maxAge,
30
+ maxAge: options.max_age ?? session_cookie_options.maxAge,
31
31
  };
32
32
  setCookie(c, options.cookie_name, value, cookie_options);
33
33
  };
@@ -36,7 +36,7 @@ export const set_session_cookie = (c, value, options) => {
36
36
  */
37
37
  export const clear_session_cookie = (c, options) => {
38
38
  const cookie_options = {
39
- ...SESSION_COOKIE_OPTIONS,
39
+ ...session_cookie_options,
40
40
  ...options.cookie_options,
41
41
  };
42
42
  deleteCookie(c, options.cookie_name, cookie_options);
@@ -43,9 +43,9 @@ export interface RateLimiterOptions {
43
43
  max_keys?: number | null;
44
44
  }
45
45
  /** Default options for per-IP login rate limiting: 5 attempts per 15 minutes. */
46
- export declare const DEFAULT_LOGIN_IP_RATE_LIMIT: RateLimiterOptions;
46
+ export declare const default_login_ip_rate_limit: RateLimiterOptions;
47
47
  /** Default options for per-account login rate limiting: 10 attempts per 30 minutes. */
48
- export declare const DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT: RateLimiterOptions;
48
+ export declare const default_login_account_rate_limit: RateLimiterOptions;
49
49
  /**
50
50
  * Default options for per-IP action-dispatcher rate limiting: 600 attempts
51
51
  * per 15 minutes. Shared by the HTTP RPC and WebSocket action dispatchers
@@ -53,7 +53,7 @@ export declare const DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT: RateLimiterOptions;
53
53
  * scripts and egregious oracle probes, but well above human or normal
54
54
  * automation pace. Tighten downstream for stricter deployments.
55
55
  */
56
- export declare const DEFAULT_ACTION_IP_RATE_LIMIT: RateLimiterOptions;
56
+ export declare const default_action_ip_rate_limit: RateLimiterOptions;
57
57
  /**
58
58
  * Default options for per-actor action-dispatcher rate limiting: 1200
59
59
  * attempts per 15 minutes. Shared by the HTTP RPC and WebSocket action
@@ -61,7 +61,7 @@ export declare const DEFAULT_ACTION_IP_RATE_LIMIT: RateLimiterOptions;
61
61
  * admin workflow; an oracle probing 10k addresses still finishes in
62
62
  * ~2 hours, slow enough to surface in audit. Tighten downstream.
63
63
  */
64
- export declare const DEFAULT_ACTION_ACCOUNT_RATE_LIMIT: RateLimiterOptions;
64
+ export declare const default_action_account_rate_limit: RateLimiterOptions;
65
65
  /**
66
66
  * Result of a rate limit check or record operation.
67
67
  */
@@ -139,7 +139,7 @@ export declare class RateLimiter {
139
139
  /**
140
140
  * Create a `RateLimiter` with sensible defaults for per-IP login protection.
141
141
  *
142
- * @param options - override individual options; unset fields use `DEFAULT_LOGIN_IP_RATE_LIMIT`
142
+ * @param options - override individual options; unset fields use `default_login_ip_rate_limit`
143
143
  */
144
144
  export declare const create_rate_limiter: (options?: Partial<RateLimiterOptions>) => RateLimiter;
145
145
  /**
@@ -17,14 +17,14 @@ import { ERROR_RATE_LIMIT_EXCEEDED } from './http/error_schemas.js';
17
17
  */
18
18
  export const DEFAULT_RATE_LIMITER_MAX_KEYS = 100_000;
19
19
  /** Default options for per-IP login rate limiting: 5 attempts per 15 minutes. */
20
- export const DEFAULT_LOGIN_IP_RATE_LIMIT = {
20
+ export const default_login_ip_rate_limit = {
21
21
  max_attempts: 5,
22
22
  window_ms: 15 * 60_000,
23
23
  cleanup_interval_ms: 5 * 60_000,
24
24
  max_keys: DEFAULT_RATE_LIMITER_MAX_KEYS,
25
25
  };
26
26
  /** Default options for per-account login rate limiting: 10 attempts per 30 minutes. */
27
- export const DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT = {
27
+ export const default_login_account_rate_limit = {
28
28
  max_attempts: 10,
29
29
  window_ms: 30 * 60_000,
30
30
  cleanup_interval_ms: 5 * 60_000,
@@ -37,7 +37,7 @@ export const DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT = {
37
37
  * scripts and egregious oracle probes, but well above human or normal
38
38
  * automation pace. Tighten downstream for stricter deployments.
39
39
  */
40
- export const DEFAULT_ACTION_IP_RATE_LIMIT = {
40
+ export const default_action_ip_rate_limit = {
41
41
  max_attempts: 600,
42
42
  window_ms: 15 * 60_000,
43
43
  cleanup_interval_ms: 5 * 60_000,
@@ -50,7 +50,7 @@ export const DEFAULT_ACTION_IP_RATE_LIMIT = {
50
50
  * admin workflow; an oracle probing 10k addresses still finishes in
51
51
  * ~2 hours, slow enough to surface in audit. Tighten downstream.
52
52
  */
53
- export const DEFAULT_ACTION_ACCOUNT_RATE_LIMIT = {
53
+ export const default_action_account_rate_limit = {
54
54
  max_attempts: 1200,
55
55
  window_ms: 15 * 60_000,
56
56
  cleanup_interval_ms: 5 * 60_000,
@@ -203,10 +203,10 @@ export class RateLimiter {
203
203
  /**
204
204
  * Create a `RateLimiter` with sensible defaults for per-IP login protection.
205
205
  *
206
- * @param options - override individual options; unset fields use `DEFAULT_LOGIN_IP_RATE_LIMIT`
206
+ * @param options - override individual options; unset fields use `default_login_ip_rate_limit`
207
207
  */
208
208
  export const create_rate_limiter = (options) => {
209
- return new RateLimiter({ ...DEFAULT_LOGIN_IP_RATE_LIMIT, ...options });
209
+ return new RateLimiter({ ...default_login_ip_rate_limit, ...options });
210
210
  };
211
211
  /**
212
212
  * Build a 429 rate-limit-exceeded JSON response with `Retry-After` header.
@@ -27,7 +27,7 @@ export declare const AUDIT_LOG_CHANNEL = "audit_log";
27
27
  * (matched by the blake3 session hash in `event.metadata.session_id`) — closing
28
28
  * all of a user's streams for a single-session revoke would be over-aggressive.
29
29
  */
30
- export declare const DISCONNECT_EVENT_TYPES: ReadonlySet<string>;
30
+ export declare const disconnect_event_types: ReadonlySet<string>;
31
31
  /**
32
32
  * Create an audit event handler that closes SSE streams on auth changes.
33
33
  *
@@ -69,7 +69,7 @@ export interface AuditLogSse {
69
69
  * One spec per `AUDIT_EVENT_TYPES` entry, all sharing the `AuditLogEventJson` params schema.
70
70
  * Pass to `create_app_server`'s `event_specs` for surface generation and DEV validation.
71
71
  */
72
- export declare const AUDIT_LOG_EVENT_SPECS: Array<EventSpec>;
72
+ export declare const audit_log_event_specs: Array<EventSpec>;
73
73
  /**
74
74
  * Default max concurrent SSE subscribers per session scope for the audit log.
75
75
  *
@@ -102,7 +102,7 @@ export declare const AUDIT_LOG_SSE_MAX_PER_SCOPE = 10;
102
102
  * create_audit_log_route_specs({stream: audit_sse});
103
103
  *
104
104
  * // In create_app_server options:
105
- * event_specs: AUDIT_LOG_EVENT_SPECS,
105
+ * event_specs: audit_log_event_specs,
106
106
  * ```
107
107
  */
108
108
  export declare const create_audit_log_sse: (options: {
@@ -25,7 +25,7 @@ export const AUDIT_LOG_CHANNEL = 'audit_log';
25
25
  * (matched by the blake3 session hash in `event.metadata.session_id`) — closing
26
26
  * all of a user's streams for a single-session revoke would be over-aggressive.
27
27
  */
28
- export const DISCONNECT_EVENT_TYPES = new Set([
28
+ export const disconnect_event_types = new Set([
29
29
  'role_grant_revoke', // role revoked — user lost access
30
30
  'session_revoke', // single session revoked — close only that stream
31
31
  'session_revoke_all', // all sessions invalidated — user should be kicked
@@ -51,7 +51,7 @@ export const DISCONNECT_EVENT_TYPES = new Set([
51
51
  */
52
52
  export const create_sse_auth_guard = (registry, required_role, log) => {
53
53
  return (event) => {
54
- if (!DISCONNECT_EVENT_TYPES.has(event.event_type))
54
+ if (!disconnect_event_types.has(event.event_type))
55
55
  return;
56
56
  // Only act on successful revocations. Failed attempts carry
57
57
  // attacker-controlled identifiers (e.g., session_revoke with outcome=failure
@@ -98,7 +98,7 @@ export const create_sse_auth_guard = (registry, required_role, log) => {
98
98
  * One spec per `AUDIT_EVENT_TYPES` entry, all sharing the `AuditLogEventJson` params schema.
99
99
  * Pass to `create_app_server`'s `event_specs` for surface generation and DEV validation.
100
100
  */
101
- export const AUDIT_LOG_EVENT_SPECS = AUDIT_EVENT_TYPES.map((event_type) => ({
101
+ export const audit_log_event_specs = AUDIT_EVENT_TYPES.map((event_type) => ({
102
102
  method: event_type,
103
103
  params: AuditLogEventJson,
104
104
  description: `Audit log: ${event_type.replaceAll('_', ' ')}`,
@@ -136,7 +136,7 @@ export const AUDIT_LOG_SSE_MAX_PER_SCOPE = 10;
136
136
  * create_audit_log_route_specs({stream: audit_sse});
137
137
  *
138
138
  * // In create_app_server options:
139
- * event_specs: AUDIT_LOG_EVENT_SPECS,
139
+ * event_specs: audit_log_event_specs,
140
140
  * ```
141
141
  */
142
142
  export const create_audit_log_sse = (options) => {
@@ -66,7 +66,7 @@ export interface CreateAppBackendOptions {
66
66
  * Audit-log config for consumer event-type extensions. Built once at
67
67
  * startup via `create_audit_log_config({extra_events})` and captured
68
68
  * inside `AppDeps.audit` so consumer handlers cannot silently fall
69
- * back to the builtin config. Omit to use `BUILTIN_AUDIT_LOG_CONFIG`
69
+ * back to the builtin config. Omit to use `builtin_audit_log_config`
70
70
  * (no extra events).
71
71
  */
72
72
  audit_log_config?: AuditLogConfig;
@@ -76,7 +76,7 @@ export interface CreateAppBackendOptions {
76
76
  * (`namespace`, `name`, `sequence`); order is append-only so forward-only
77
77
  * guarantees hold per-namespace.
78
78
  *
79
- * Names in `RESERVED_MIGRATION_NAMESPACES` (currently `['fuz_auth']`) are
79
+ * Names in `reserved_migration_namespaces` (currently `['fuz_auth']`) are
80
80
  * rejected at startup. Omit for no extra namespaces. This is the only
81
81
  * place to splice consumer migrations — DB init belongs to the backend
82
82
  * lifecycle, not server assembly.
@@ -92,7 +92,7 @@ export interface CreateAppBackendOptions {
92
92
  *
93
93
  * @param options - keyring, password deps, optional database URL, and optional `migration_namespaces`
94
94
  * @returns app backend with deps, database metadata, and combined migration results
95
- * @throws Error if `migration_namespaces` contains a namespace in `RESERVED_MIGRATION_NAMESPACES`
95
+ * @throws Error if `migration_namespaces` contains a namespace in `reserved_migration_namespaces`
96
96
  */
97
97
  export declare const create_app_backend: (options: CreateAppBackendOptions) => Promise<AppBackend>;
98
98
  //# sourceMappingURL=app_backend.d.ts.map
@@ -13,7 +13,7 @@
13
13
  import { Logger } from '@fuzdev/fuz_util/log.js';
14
14
  import { create_audit_emitter } from '../auth/audit_emitter.js';
15
15
  import { run_migrations } from '../db/migrate.js';
16
- import { AUTH_MIGRATION_NS, RESERVED_MIGRATION_NAMESPACES } from '../auth/migrations.js';
16
+ import { auth_migration_ns, reserved_migration_namespaces } from '../auth/migrations.js';
17
17
  import { create_db } from '../db/create_db.js';
18
18
  /**
19
19
  * Initialize the backend: database + auth migrations + deps.
@@ -24,7 +24,7 @@ import { create_db } from '../db/create_db.js';
24
24
  *
25
25
  * @param options - keyring, password deps, optional database URL, and optional `migration_namespaces`
26
26
  * @returns app backend with deps, database metadata, and combined migration results
27
- * @throws Error if `migration_namespaces` contains a namespace in `RESERVED_MIGRATION_NAMESPACES`
27
+ * @throws Error if `migration_namespaces` contains a namespace in `reserved_migration_namespaces`
28
28
  */
29
29
  export const create_app_backend = async (options) => {
30
30
  const { database_url, keyring, password, stat, read_text_file, delete_file } = options;
@@ -32,13 +32,13 @@ export const create_app_backend = async (options) => {
32
32
  const { db, close, db_type, db_name } = await create_db(database_url);
33
33
  if (options.migration_namespaces?.length) {
34
34
  for (const ns of options.migration_namespaces) {
35
- if (RESERVED_MIGRATION_NAMESPACES.includes(ns.namespace)) {
35
+ if (reserved_migration_namespaces.includes(ns.namespace)) {
36
36
  throw new Error(`Migration namespace "${ns.namespace}" is reserved by fuz_app — choose a different namespace`);
37
37
  }
38
38
  }
39
39
  }
40
40
  const migration_results = await run_migrations(db, [
41
- AUTH_MIGRATION_NS,
41
+ auth_migration_ns,
42
42
  ...(options.migration_namespaces ?? []),
43
43
  ]);
44
44
  const audit = create_audit_emitter({
@@ -136,7 +136,7 @@ export interface AppServerOptions {
136
136
  * When truthy, creates an `AuditLogSse` instance internally, appends the SSE
137
137
  * listener to `backend.deps.audit.on_event_chain` (composing with the
138
138
  * consumer's `on_audit_event` callback rather than rebuilding `AppDeps`), and
139
- * auto-includes `AUDIT_LOG_EVENT_SPECS` in the surface. The result is exposed
139
+ * auto-includes `audit_log_event_specs` in the surface. The result is exposed
140
140
  * on `AppServerContext` (for route factories) and `AppServer` (for the caller).
141
141
  *
142
142
  * Pass `true` for defaults (admin role), or `{role: 'custom'}` for a custom role.
@@ -11,10 +11,10 @@ import { Hono } from 'hono';
11
11
  import { logger } from 'hono/logger';
12
12
  import { bodyLimit } from 'hono/body-limit';
13
13
  import { z } from 'zod';
14
- import { SESSION_COOKIE_OPTIONS, } from '../auth/session_cookie.js';
15
- import { create_audit_log_sse, AUDIT_LOG_EVENT_SPECS, } from '../realtime/sse_auth_guard.js';
14
+ import { session_cookie_options, } from '../auth/session_cookie.js';
15
+ import { create_audit_log_sse, audit_log_event_specs, } from '../realtime/sse_auth_guard.js';
16
16
  import { query_app_settings_load } from '../auth/app_settings_queries.js';
17
- import { create_rate_limiter, DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT, DEFAULT_ACTION_ACCOUNT_RATE_LIMIT, DEFAULT_ACTION_IP_RATE_LIMIT, } from '../rate_limiter.js';
17
+ import { create_rate_limiter, default_login_account_rate_limit, default_action_account_rate_limit, default_action_ip_rate_limit, } from '../rate_limiter.js';
18
18
  // Side-effect import: augments Hono's ContextVariableMap so consumers
19
19
  // that import app_server get type-safe c.get('auth_session_id') etc.
20
20
  import '../hono_context.js';
@@ -53,19 +53,19 @@ export const create_app_server = async (options) => {
53
53
  // Rate limiter defaults (undefined = default, null = disable)
54
54
  const ip_rate_limiter = options.ip_rate_limiter === undefined ? create_rate_limiter() : options.ip_rate_limiter;
55
55
  const login_account_rate_limiter = options.login_account_rate_limiter === undefined
56
- ? create_rate_limiter(DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT)
56
+ ? create_rate_limiter(default_login_account_rate_limit)
57
57
  : options.login_account_rate_limiter;
58
58
  const signup_account_rate_limiter = options.signup_account_rate_limiter === undefined
59
- ? create_rate_limiter(DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT)
59
+ ? create_rate_limiter(default_login_account_rate_limit)
60
60
  : options.signup_account_rate_limiter;
61
61
  const bearer_ip_rate_limiter = options.bearer_ip_rate_limiter === undefined
62
62
  ? create_rate_limiter()
63
63
  : options.bearer_ip_rate_limiter;
64
64
  const action_ip_rate_limiter = options.action_ip_rate_limiter === undefined
65
- ? create_rate_limiter(DEFAULT_ACTION_IP_RATE_LIMIT)
65
+ ? create_rate_limiter(default_action_ip_rate_limit)
66
66
  : options.action_ip_rate_limiter;
67
67
  const action_account_rate_limiter = options.action_account_rate_limiter === undefined
68
- ? create_rate_limiter(DEFAULT_ACTION_ACCOUNT_RATE_LIMIT)
68
+ ? create_rate_limiter(default_action_account_rate_limit)
69
69
  : options.action_account_rate_limiter;
70
70
  // Factory-managed audit SSE — appends a listener to the bound emitter's
71
71
  // chain so SSE fan-out runs alongside the consumer's `on_audit_event`
@@ -156,7 +156,7 @@ export const create_app_server = async (options) => {
156
156
  : middleware_specs;
157
157
  const all_event_specs = [
158
158
  ...(options.event_specs ?? []),
159
- ...(audit_sse ? AUDIT_LOG_EVENT_SPECS : []),
159
+ ...(audit_sse ? audit_log_event_specs : []),
160
160
  ];
161
161
  const surface_spec = create_app_surface_spec({
162
162
  middleware_specs: surface_middleware,
@@ -176,11 +176,11 @@ export const create_app_server = async (options) => {
176
176
  message: 'Session cookie secure=false — cookies sent over HTTP',
177
177
  });
178
178
  }
179
- if (cookie_opts.sameSite && cookie_opts.sameSite !== SESSION_COOKIE_OPTIONS.sameSite) {
179
+ if (cookie_opts.sameSite && cookie_opts.sameSite !== session_cookie_options.sameSite) {
180
180
  config_diagnostics.push({
181
181
  level: 'warning',
182
182
  category: 'security',
183
- message: `Session cookie sameSite='${cookie_opts.sameSite}' — weakened from default '${SESSION_COOKIE_OPTIONS.sameSite}'`,
183
+ message: `Session cookie sameSite='${cookie_opts.sameSite}' — weakened from default '${session_cookie_options.sameSite}'`,
184
184
  });
185
185
  }
186
186
  if (cookie_opts.httpOnly === false) {
@@ -91,7 +91,7 @@ from `app_server.ts` instead.
91
91
  ## Database — `db.ts`
92
92
 
93
93
  Factory builders for parameterized DB tests. Consumer projects pass their
94
- `init_schema` callback (which calls `run_migrations(db, [AUTH_MIGRATION_NS, ...app_migrations])`);
94
+ `init_schema` callback (which calls `run_migrations(db, [auth_migration_ns, ...app_migrations])`);
95
95
  factories accept any migration namespace set.
96
96
 
97
97
  | Helper | Role |
@@ -101,10 +101,10 @@ factories accept any migration namespace set.
101
101
  | `reset_pglite(db)` | `DROP SCHEMA public CASCADE` + recreate. Reuses a live PGlite instance. |
102
102
  | `create_pglite_factory(init_schema)` | In-memory; no external deps; `skip: false`. See WASM caching below. |
103
103
  | `create_pg_factory(init_schema, test_url?)` | PostgreSQL; `skip: true` when `test_url` is missing; drops `schema_version` before `init_schema` so migrations re-evaluate against actual tables (prevents stale tracker rows from skipping migrations when DDL changes between test sessions); pool is reused + cleaned up across `create()` calls. |
104
- | `AUTH_TRUNCATE_TABLES` | `['invite', 'api_token', 'auth_session', 'role_grant', 'role_grant_offer', 'actor', 'account']` in FK-safe order. Excludes `audit_log` — unit DB tests don't need to truncate it. |
105
- | `AUTH_INTEGRATION_TRUNCATE_TABLES` | `AUTH_TRUNCATE_TABLES + ['audit_log']` — for integration suites that exercise the audit path. |
106
- | `AUTH_DROP_TABLES` | Full set from `AUTH_MIGRATIONS` in drop order; call `drop_auth_schema(db)` at the top of `init_schema` on persistent pg databases that may hold stale DDL from previous fuz_app versions. |
107
- | `drop_auth_schema(db)` | `DROP TABLE IF EXISTS <table> CASCADE` for every entry in `AUTH_DROP_TABLES` plus `schema_version`. Safe on fresh DBs. |
104
+ | `auth_truncate_tables` | `['invite', 'api_token', 'auth_session', 'role_grant', 'role_grant_offer', 'actor', 'account']` in FK-safe order. Excludes `audit_log` — unit DB tests don't need to truncate it. |
105
+ | `auth_integration_truncate_tables` | `auth_truncate_tables + ['audit_log']` — for integration suites that exercise the audit path. |
106
+ | `auth_drop_tables` | Full set from `auth_migrations` in drop order; call `drop_auth_schema(db)` at the top of `init_schema` on persistent pg databases that may hold stale DDL from previous fuz_app versions. |
107
+ | `drop_auth_schema(db)` | `DROP TABLE IF EXISTS <table> CASCADE` for every entry in `auth_drop_tables` plus `schema_version`. Safe on fresh DBs. |
108
108
  | `create_describe_db(factories, truncate_tables)` | Returns `describe_db(name, fn)` that runs `fn(get_db)` once per factory, inside a `describe` block with shared `beforeAll(create)` + `beforeEach(TRUNCATE)` + `afterAll(close)`. Skipped factories use `describe.skip`. |
109
109
  | `log_db_factory_status(factories)` | Console summary of enabled / skipped factories. |
110
110
 
@@ -234,13 +234,13 @@ Tightness audit:
234
234
  classifies every route × status combination as `'literal' | 'enum' | 'generic'`.
235
235
  - `assert_error_schema_tightness(surface, options?)` — fails routes below a
236
236
  threshold (`min_specificity`, default `'enum'`) with `allowlist` + `ignore_statuses` escape hatches.
237
- - `FUZ_APP_STOCK_ROUTE_TIGHTNESS_ALLOWLIST` — currently empty. Every
237
+ - `fuz_app_stock_route_tightness_allowlist` — currently empty. Every
238
238
  fuz_app-shipped route (account login/password/bootstrap/signup, db
239
239
  health/tables/:name/tables/:name/rows/:id) has been tightened in place to
240
240
  `z.enum([...])` / `z.literal(...)` against every emit-site code. Kept as a
241
241
  forward-compatibility hook for future stock routes that need an interim
242
242
  exemption; paths assume the standard `/api/account` + `/api/db` prefixes.
243
- - `DEFAULT_ERROR_SCHEMA_TIGHTNESS` — `{ignore_statuses: [401, 403, 429], allowlist: FUZ_APP_STOCK_ROUTE_TIGHTNESS_ALLOWLIST}`.
243
+ - `default_error_schema_tightness` — `{ignore_statuses: [401, 403, 429], allowlist: fuz_app_stock_route_tightness_allowlist}`.
244
244
  Applied by `describe_standard_attack_surface_tests` when
245
245
  `error_schema_tightness` is omitted; pass an override config or `null` to
246
246
  opt out.
@@ -323,8 +323,8 @@ Walks Zod schemas to generate valid values for adversarial/round-trip tests.
323
323
  | `check_error_response_fields(body)` | Returns the list of fields outside `KNOWN_SAFE_ERROR_FIELDS` (`error`, `issues`, `required_roles`, `required_credential_types`, `retry_after`, `has_references`, `ok`). |
324
324
  | `assert_no_error_info_leakage(body, context)` | Rejects field-name patterns (`stack`, `trace`, `sql`, …) + value patterns (`node_modules`, stack-like `at …`, `.ts:NN`). |
325
325
  | `assert_rate_limit_retry_after_header(response, body)` | `Retry-After` numeric header equals `Math.ceil(body.retry_after)`. |
326
- | `SENSITIVE_FIELD_BLOCKLIST` | `['password_hash', 'token_hash']` — never in any response body. |
327
- | `ADMIN_ONLY_FIELD_BLOCKLIST` | `['updated_by', 'created_by']` — never in non-admin response bodies. |
326
+ | `sensitive_field_blocklist` | `['password_hash', 'token_hash']` — never in any response body. |
327
+ | `admin_only_field_blocklist` | `['updated_by', 'created_by']` — never in non-admin response bodies. |
328
328
  | `collect_json_keys_recursive(value)` | Deep walk; returns `Set<string>` of every key at every nesting depth. |
329
329
  | `assert_no_sensitive_fields_in_json(body, blocklist, context)` | Rejects any key in the blocklist at any depth. |
330
330
  | `pick_auth_headers(spec, test_app, authed_account, admin_account)` | `RouteAuth` → appropriate test credentials; role `admin` uses `admin_account`, other roles use bootstrapped keeper, `keeper` uses daemon token. |
@@ -337,7 +337,7 @@ Single-call bundle of 5 top-level groups (10 named tests + every
337
337
  adversarial case per route):
338
338
 
339
339
  1. **attack surface snapshot** — `matches committed snapshot`, `is deterministic`.
340
- 2. **attack surface structure** — `only expected public routes`, `full middleware stack on API routes`, `surface invariants`, `security policy`, `error schema tightness` (logs counts and asserts against `DEFAULT_ERROR_SCHEMA_TIGHTNESS` by default; pass an override config or `null` via `error_schema_tightness`).
340
+ 2. **attack surface structure** — `only expected public routes`, `full middleware stack on API routes`, `surface invariants`, `security policy`, `error schema tightness` (logs counts and asserts against `default_error_schema_tightness` by default; pass an override config or `null` via `error_schema_tightness`).
341
341
  3. **adversarial HTTP auth enforcement** — `unauthenticated → 401`, `wrong role → 403` × roles, `authenticated without role → 403`, `keeper routes reject session credential → 403`, `correct auth passes guard`.
342
342
  4. **adversarial input validation** — delegated to `describe_adversarial_input`.
343
343
  5. **adversarial 404 response validation** — delegated to `describe_adversarial_404`.
@@ -511,8 +511,8 @@ new arrivals (default 1000ms); drops the waiter on timeout so the
511
511
  Six tests in two top-level groups:
512
512
 
513
513
  1. **schema-level** (3 tests, no DB) — walks JSON Schema representations:
514
- - `no sensitive fields in any output schema` — `SENSITIVE_FIELD_BLOCKLIST`
515
- - `no admin-only fields in non-admin output schemas` — `ADMIN_ONLY_FIELD_BLOCKLIST`
514
+ - `no sensitive fields in any output schema` — `sensitive_field_blocklist`
515
+ - `no admin-only fields in non-admin output schemas` — `admin_only_field_blocklist`
516
516
  - `no sensitive fields in any error schema`
517
517
  2. **runtime** (3 tests, DB-backed via `create_test_app`):
518
518
  - `unauthenticated error responses contain no sensitive fields`
@@ -699,6 +699,16 @@ deps — no DB needed.
699
699
 
700
700
  Options: `{build: () => AppSurfaceSpec, roles: Array<string>}`.
701
701
 
702
+ **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.
711
+
702
712
  ## Cross-cutting conventions
703
713
 
704
714
  - **`assert` from vitest, not `expect`.** Project-wide convention
@@ -28,9 +28,9 @@ import './assert_dev_env.js';
28
28
  import { describe, test, assert, afterAll } from 'vitest';
29
29
  import { ROLE_KEEPER, ROLE_ADMIN } from '../auth/role_schema.js';
30
30
  import { GRANT_PATH_ADMIN } from '../auth/grant_path_schema.js';
31
- import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
31
+ import { auth_migration_ns } from '../auth/migrations.js';
32
32
  import { create_test_app } from './app_server.js';
33
- import { create_pglite_factory, create_describe_db, AUTH_INTEGRATION_TRUNCATE_TABLES, } from './db.js';
33
+ import { create_pglite_factory, create_describe_db, auth_integration_truncate_tables, } from './db.js';
34
34
  import { find_auth_route } from './integration_helpers.js';
35
35
  import { run_migrations } from '../db/migrate.js';
36
36
  import { ErrorCoverageCollector, assert_error_coverage, DEFAULT_INTEGRATION_ERROR_COVERAGE, } from './error_coverage.js';
@@ -88,10 +88,10 @@ export const describe_standard_admin_integration_tests = (options) => {
88
88
  const rpc_endpoints_for_setup = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
89
89
  const rpc_path = require_rpc_endpoint_path(rpc_endpoints_for_setup);
90
90
  const init_schema = async (db) => {
91
- await run_migrations(db, [AUTH_MIGRATION_NS]);
91
+ await run_migrations(db, [auth_migration_ns]);
92
92
  };
93
93
  const factories = options.db_factories ?? [create_pglite_factory(init_schema)];
94
- const describe_db = create_describe_db(factories, AUTH_INTEGRATION_TRUNCATE_TABLES);
94
+ const describe_db = create_describe_db(factories, auth_integration_truncate_tables);
95
95
  describe_db('standard_admin_integration', (get_db) => {
96
96
  const { cookie_name } = options.session_options;
97
97
  const { role_specs } = options.roles;
@@ -120,7 +120,7 @@ export interface TestAppServerOptions {
120
120
  *
121
121
  * Use when the consumer registers extra event types via
122
122
  * `create_audit_log_config({extra_events})` — without this, emits for
123
- * those events fall back to `BUILTIN_AUDIT_LOG_CONFIG` and log
123
+ * those events fall back to `builtin_audit_log_config` and log
124
124
  * "unknown event_type" warnings.
125
125
  */
126
126
  audit_log_config?: AuditLogConfig;
@@ -10,7 +10,7 @@ import { generate_session_token, hash_session_token, AUTH_SESSION_LIFETIME_MS, q
10
10
  import { query_create_api_token } from '../auth/api_token_queries.js';
11
11
  import { create_session_cookie_value } from '../auth/session_cookie.js';
12
12
  import { run_migrations } from '../db/migrate.js';
13
- import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
13
+ import { auth_migration_ns } from '../auth/migrations.js';
14
14
  import { create_audit_emitter } from '../auth/audit_emitter.js';
15
15
  import { create_app_server, } from '../server/app_server.js';
16
16
  import { generate_daemon_token, DAEMON_TOKEN_HEADER, } from '../auth/daemon_token.js';
@@ -33,7 +33,7 @@ export const TEST_COOKIE_SECRET = 'a'.repeat(64);
33
33
  // Shares the WASM instance cache from test_db.ts, avoiding redundant cold starts
34
34
  // within the same vitest worker thread. Schema is reset on each create() call.
35
35
  const fallback_pglite_factory = create_pglite_factory(async (db) => {
36
- await run_migrations(db, [AUTH_MIGRATION_NS]);
36
+ await run_migrations(db, [auth_migration_ns]);
37
37
  });
38
38
  /**
39
39
  * Bootstrap a test account with credentials.
@@ -20,7 +20,7 @@ export interface AdversarialTestOptions {
20
20
  export declare const describe_adversarial_auth: (options: AdversarialTestOptions) => void;
21
21
  /**
22
22
  * Merge a consumer's `error_schema_tightness` option with
23
- * `DEFAULT_ERROR_SCHEMA_TIGHTNESS` so `allowlist` and `ignore_statuses` are
23
+ * `default_error_schema_tightness` so `allowlist` and `ignore_statuses` are
24
24
  * additive rather than replacing.
25
25
  *
26
26
  * - `undefined` → return the default as-is.
@@ -52,9 +52,9 @@ export interface StandardAttackSurfaceOptions {
52
52
  security_policy?: SurfaceSecurityPolicyOptions;
53
53
  /**
54
54
  * Error schema tightness assertion config. Defaults to
55
- * `DEFAULT_ERROR_SCHEMA_TIGHTNESS` (ignores 401/403/429,
55
+ * `default_error_schema_tightness` (ignores 401/403/429,
56
56
  * `min_specificity: 'enum'`, allowlist seeded with
57
- * `FUZ_APP_STOCK_ROUTE_TIGHTNESS_ALLOWLIST`).
57
+ * `fuz_app_stock_route_tightness_allowlist`).
58
58
  *
59
59
  * Consumer-supplied `allowlist` and `ignore_statuses` are **additive** —
60
60
  * the suite merges them underneath the stock defaults, so project-specific
@@ -74,7 +74,7 @@ export interface StandardAttackSurfaceOptions {
74
74
  * 4. Middleware stack — every API route has the full middleware chain
75
75
  * 5. Surface invariants — structural assertions (error schemas, descriptions, duplicates, consistency)
76
76
  * 6. Security policy — rate limiting on sensitive routes, no unexpected public mutations, method conventions
77
- * 7. Error schema tightness — informational log of generic vs specific error schemas, plus assertion against `DEFAULT_ERROR_SCHEMA_TIGHTNESS` by default (opt out with `error_schema_tightness: null`)
77
+ * 7. Error schema tightness — informational log of generic vs specific error schemas, plus assertion against `default_error_schema_tightness` by default (opt out with `error_schema_tightness: null`)
78
78
  * 8. Adversarial auth — unauthenticated/wrong-role/correct-auth enforcement
79
79
  * 9. Adversarial input — input body and params validation
80
80
  * 10. Adversarial 404 — stub 404 handlers, validate response bodies against declared schemas
@@ -15,7 +15,7 @@ import './assert_dev_env.js';
15
15
  * @module
16
16
  */
17
17
  import { test, assert, describe } from 'vitest';
18
- import { assert_surface_invariants, assert_surface_security_policy, audit_error_schema_tightness, assert_error_schema_tightness, DEFAULT_ERROR_SCHEMA_TIGHTNESS, FUZ_APP_STOCK_ROUTE_TIGHTNESS_ALLOWLIST, } from './surface_invariants.js';
18
+ import { assert_surface_invariants, assert_surface_security_policy, audit_error_schema_tightness, assert_error_schema_tightness, default_error_schema_tightness, fuz_app_stock_route_tightness_allowlist, } from './surface_invariants.js';
19
19
  import { describe_adversarial_input } from './adversarial_input.js';
20
20
  import { describe_adversarial_404 } from './adversarial_404.js';
21
21
  import { create_test_app_from_specs, create_test_request_context, create_auth_test_apps, select_auth_app, resolve_test_path, } from './auth_apps.js';
@@ -164,7 +164,7 @@ export const describe_adversarial_auth = (options) => {
164
164
  // --- Standard attack surface test suite ---
165
165
  /**
166
166
  * Merge a consumer's `error_schema_tightness` option with
167
- * `DEFAULT_ERROR_SCHEMA_TIGHTNESS` so `allowlist` and `ignore_statuses` are
167
+ * `default_error_schema_tightness` so `allowlist` and `ignore_statuses` are
168
168
  * additive rather than replacing.
169
169
  *
170
170
  * - `undefined` → return the default as-is.
@@ -181,11 +181,11 @@ export const resolve_standard_error_schema_tightness = (consumer) => {
181
181
  if (consumer === null)
182
182
  return null;
183
183
  return {
184
- ...DEFAULT_ERROR_SCHEMA_TIGHTNESS,
184
+ ...default_error_schema_tightness,
185
185
  ...consumer,
186
- allowlist: [...FUZ_APP_STOCK_ROUTE_TIGHTNESS_ALLOWLIST, ...(consumer?.allowlist ?? [])],
186
+ allowlist: [...fuz_app_stock_route_tightness_allowlist, ...(consumer?.allowlist ?? [])],
187
187
  ignore_statuses: [
188
- ...(DEFAULT_ERROR_SCHEMA_TIGHTNESS.ignore_statuses ?? []),
188
+ ...(default_error_schema_tightness.ignore_statuses ?? []),
189
189
  ...(consumer?.ignore_statuses ?? []),
190
190
  ],
191
191
  };
@@ -200,7 +200,7 @@ export const resolve_standard_error_schema_tightness = (consumer) => {
200
200
  * 4. Middleware stack — every API route has the full middleware chain
201
201
  * 5. Surface invariants — structural assertions (error schemas, descriptions, duplicates, consistency)
202
202
  * 6. Security policy — rate limiting on sensitive routes, no unexpected public mutations, method conventions
203
- * 7. Error schema tightness — informational log of generic vs specific error schemas, plus assertion against `DEFAULT_ERROR_SCHEMA_TIGHTNESS` by default (opt out with `error_schema_tightness: null`)
203
+ * 7. Error schema tightness — informational log of generic vs specific error schemas, plus assertion against `default_error_schema_tightness` by default (opt out with `error_schema_tightness: null`)
204
204
  * 8. Adversarial auth — unauthenticated/wrong-role/correct-auth enforcement
205
205
  * 9. Adversarial input — input body and params validation
206
206
  * 10. Adversarial 404 — stub 404 handlers, validate response bodies against declared schemas
@@ -15,9 +15,9 @@ import './assert_dev_env.js';
15
15
  import { describe, test, assert } from 'vitest';
16
16
  import { ROLE_KEEPER, ROLE_ADMIN } from '../auth/role_schema.js';
17
17
  import { AUDIT_EVENT_TYPES } from '../auth/audit_log_schema.js';
18
- import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
18
+ import { auth_migration_ns } from '../auth/migrations.js';
19
19
  import { create_test_app, } from './app_server.js';
20
- import { create_pglite_factory, create_describe_db, AUTH_INTEGRATION_TRUNCATE_TABLES, } from './db.js';
20
+ import { create_pglite_factory, create_describe_db, auth_integration_truncate_tables, } from './db.js';
21
21
  import { find_auth_route } from './integration_helpers.js';
22
22
  import { run_migrations } from '../db/migrate.js';
23
23
  import { query_accept_offer } from '../auth/role_grant_offer_queries.js';
@@ -75,10 +75,10 @@ export const describe_audit_completeness_tests = (options) => {
75
75
  const rpc_endpoints_for_setup = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
76
76
  const rpc_path = require_rpc_endpoint_path(rpc_endpoints_for_setup);
77
77
  const init_schema = async (db) => {
78
- await run_migrations(db, [AUTH_MIGRATION_NS]);
78
+ await run_migrations(db, [auth_migration_ns]);
79
79
  };
80
80
  const factories = options.db_factories ?? [create_pglite_factory(init_schema)];
81
- const describe_db = create_describe_db(factories, AUTH_INTEGRATION_TRUNCATE_TABLES);
81
+ const describe_db = create_describe_db(factories, auth_integration_truncate_tables);
82
82
  describe_db('audit_log_completeness', (get_db) => {
83
83
  // --- Account routes ---
84
84
  describe('account mutation audit events', () => {
@@ -27,9 +27,9 @@ export interface DataExposureTestOptions {
27
27
  session_options: SessionOptions<string>;
28
28
  /** Route spec factory for runtime tests. */
29
29
  create_route_specs: (ctx: AppServerContext) => Array<RouteSpec>;
30
- /** Fields that must never appear in any response. Default: `SENSITIVE_FIELD_BLOCKLIST`. */
30
+ /** Fields that must never appear in any response. Default: `sensitive_field_blocklist`. */
31
31
  sensitive_fields?: ReadonlyArray<string>;
32
- /** Fields that must not appear in non-admin responses. Default: `ADMIN_ONLY_FIELD_BLOCKLIST`. */
32
+ /** Fields that must not appear in non-admin responses. Default: `admin_only_field_blocklist`. */
33
33
  admin_only_fields?: ReadonlyArray<string>;
34
34
  /** Optional overrides for `AppServerOptions`. */
35
35
  app_options?: Partial<Omit<AppServerOptions, 'backend' | 'session_options' | 'create_route_specs'>>;