@fuzdev/fuz_app 0.126.0 → 0.128.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/CLAUDE.md +37 -21
- package/dist/actions/connection_closer.d.ts +16 -4
- package/dist/actions/connection_closer.d.ts.map +1 -1
- package/dist/actions/connection_closer.js +20 -4
- package/dist/actions/register_action_ws.d.ts +10 -2
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +6 -3
- package/dist/actions/register_ws_endpoint.d.ts +3 -1
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +3 -1
- package/dist/auth/CLAUDE.md +13 -9
- package/dist/auth/audit_emitter.d.ts +59 -12
- package/dist/auth/audit_emitter.d.ts.map +1 -1
- package/dist/auth/audit_emitter.js +53 -15
- package/dist/auth/middleware.d.ts +30 -0
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +59 -0
- package/dist/http/CLAUDE.md +3 -3
- package/dist/http/surface.d.ts +12 -11
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +1 -15
- package/dist/rate_limiter.d.ts +19 -1
- package/dist/rate_limiter.d.ts.map +1 -1
- package/dist/rate_limiter.js +23 -0
- package/dist/realtime/sse_auth_guard.d.ts +3 -1
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
- package/dist/server/app_server.d.ts +41 -13
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +105 -50
- package/dist/testing/CLAUDE.md +51 -38
- package/dist/testing/app_server.d.ts +1 -1
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +15 -14
- package/dist/testing/attack_surface.d.ts +1 -1
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/audit_drift_guard.d.ts +4 -2
- package/dist/testing/audit_drift_guard.d.ts.map +1 -1
- package/dist/testing/audit_drift_guard.js +14 -4
- package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
- package/dist/testing/cross_backend/account_lifecycle.js +1 -2
- package/dist/testing/cross_backend/capabilities.d.ts +3 -1
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.d.ts +3 -34
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +1 -31
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts +1 -1
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +3 -3
- package/dist/testing/cross_backend/spine_surface_constants.d.ts +43 -3
- package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
- package/dist/testing/cross_backend/spine_surface_constants.js +43 -3
- package/dist/testing/cross_backend/testing_backdoor.d.ts +15 -1
- package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_backdoor.js +49 -5
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +27 -18
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +30 -19
- package/dist/testing/cross_backend/testing_server_core.d.ts +11 -11
- package/dist/testing/cross_backend/testing_server_core.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_server_core.js +2 -2
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +0 -2
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/ts_spine_backend_config.js +2 -4
- package/dist/testing/cross_backend/ws_action_rate_limit.d.ts +1 -1
- package/dist/testing/cross_backend/ws_action_rate_limit.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_round_trip.d.ts +2 -1
- package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_round_trip.js +40 -4
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +4 -3
- package/dist/testing/stubs.d.ts +26 -6
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +56 -16
- package/dist/testing/ws_round_trip.d.ts +7 -31
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +0 -38
- package/package.json +1 -1
|
@@ -44,8 +44,10 @@ export const install_audit_drift_guard = () => {
|
|
|
44
44
|
* forward from the input envelope. Tests asserting on role-grant-shape
|
|
45
45
|
* emissions read out of the same homogeneous `calls` array.
|
|
46
46
|
* `notify` is a no-op; `add_listener` records into a local array that
|
|
47
|
-
* `listener_count` reports
|
|
48
|
-
*
|
|
47
|
+
* `listener_count` reports, and returns a remover with the production
|
|
48
|
+
* semantics (per registration, idempotent) — registered listeners never fire,
|
|
49
|
+
* since this emitter captures `emit` shapes, not fan-out. `drain_inflight` resolves at once:
|
|
50
|
+
* a recorded call writes nothing, so nothing is ever in flight.
|
|
49
51
|
*
|
|
50
52
|
* `emit` AND `emit_pool` both append to `calls`, so a test reads either
|
|
51
53
|
* entry point's writes off the same array.
|
|
@@ -65,6 +67,7 @@ export const install_audit_drift_guard = () => {
|
|
|
65
67
|
*/
|
|
66
68
|
export const create_recording_audit_emitter = (calls_ref) => {
|
|
67
69
|
const calls = calls_ref ?? [];
|
|
70
|
+
// one entry per registration, as `create_audit_emitter` keeps them
|
|
68
71
|
const listeners = [];
|
|
69
72
|
const emitter = {
|
|
70
73
|
emit: (_ctx, input) => {
|
|
@@ -88,9 +91,16 @@ export const create_recording_audit_emitter = (calls_ref) => {
|
|
|
88
91
|
},
|
|
89
92
|
notify: () => undefined,
|
|
90
93
|
add_listener: (listener) => {
|
|
91
|
-
|
|
94
|
+
const entry = { listener };
|
|
95
|
+
listeners.push(entry);
|
|
96
|
+
return () => {
|
|
97
|
+
const index = listeners.indexOf(entry);
|
|
98
|
+
if (index !== -1)
|
|
99
|
+
listeners.splice(index, 1);
|
|
100
|
+
};
|
|
92
101
|
},
|
|
93
|
-
listener_count: () => listeners.length
|
|
102
|
+
listener_count: () => listeners.length,
|
|
103
|
+
drain_inflight: () => Promise.resolve()
|
|
94
104
|
};
|
|
95
105
|
return { emitter, calls };
|
|
96
106
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account_lifecycle.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/account_lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAsC9B,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,YAAY,CAAC;AAG1E;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,GAAG,uCAAuC,CAAC;AAEvF,eAAO,MAAM,sCAAsC,GAClD,SAAS,gCAAgC,KACvC,
|
|
1
|
+
{"version":3,"file":"account_lifecycle.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/account_lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAsC9B,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,YAAY,CAAC;AAG1E;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,GAAG,uCAAuC,CAAC;AAEvF,eAAO,MAAM,sCAAsC,GAClD,SAAS,gCAAgC,KACvC,IAoUF,CAAC"}
|
|
@@ -88,8 +88,7 @@ export const describe_account_lifecycle_cross_tests = (options) => {
|
|
|
88
88
|
const del = await cross_rpc_call(t, rpc_path, 'account_delete', { account_id: fixture.account.id }, fixture.create_session_headers());
|
|
89
89
|
assert.strictEqual(error_reason(del), ERROR_CANNOT_DELETE_KEEPER);
|
|
90
90
|
// Deterministic barrier before reading: await in-flight
|
|
91
|
-
// fire-and-forget audit writes
|
|
92
|
-
// satisfied-by-construction on the TS spine via await_pending_effects).
|
|
91
|
+
// fire-and-forget audit writes on either spine.
|
|
93
92
|
const td = fixture.fresh_transport({ origin: null });
|
|
94
93
|
const drained = await cross_rpc_call(td, rpc_path, '_testing_drain_effects', undefined, fixture.create_daemon_token_headers());
|
|
95
94
|
assert.ok(drained.ok, `_testing_drain_effects failed: ${JSON.stringify(drained.error)}`);
|
|
@@ -183,7 +183,9 @@ export interface BackendCapabilities {
|
|
|
183
183
|
* (`account_session_revoke_all` among them), so a socket can revoke the
|
|
184
184
|
* session it is running on. Gates the self-revocation case in
|
|
185
185
|
* `describe_cross_process_ws_tests`: the socket reads the reply to its
|
|
186
|
-
* request, then is closed with `WS_CLOSE_SESSION_REVOKED`.
|
|
186
|
+
* request, then is closed with `WS_CLOSE_SESSION_REVOKED`. Also gates that
|
|
187
|
+
* suite's WS-mutation audit case (with `rpc_path`; it calls
|
|
188
|
+
* `_testing_drain_effects`).
|
|
187
189
|
*
|
|
188
190
|
* `true` on fuz_app's own spine presets — the TS spine binary mounts its
|
|
189
191
|
* full action set on `/api/ws`, and the Rust `testing_spine_stub` serves
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4C9B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,kCAAkC,EAAE,OAAO,CAAC;IACrD;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4C9B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,kCAAkC,EAAE,OAAO,CAAC;IACrD;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;IAC3C;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,EAAE,mBAsBpC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,iBAInC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,EAAE,IAAI,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAG,IAMrF,CAAC"}
|
|
@@ -2,8 +2,8 @@ import '../assert_dev_env.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Family-shared `BackendConfig` builders for cross-process test backends.
|
|
4
4
|
*
|
|
5
|
-
* Two consumer-facing factories —
|
|
6
|
-
* and
|
|
5
|
+
* Two consumer-facing factories — `make_default_ts_backend_config`
|
|
6
|
+
* and `make_default_rust_backend_config` — own the common shape
|
|
7
7
|
* for the JS-runtime (Deno/Node on V8) and Rust families respectively.
|
|
8
8
|
* Per-backend factories in consumer projects compose a small
|
|
9
9
|
* declaration against one of these and add consumer-specific env vars
|
|
@@ -35,38 +35,7 @@ import '../assert_dev_env.js';
|
|
|
35
35
|
import type { BackendBootstrapConfig, BackendConfig } from './backend_config.js';
|
|
36
36
|
import type { BackendCapabilities, BackendShapeNotes } from './capabilities.js';
|
|
37
37
|
import { type TestBackendPaths } from './build_test_backend_paths.js';
|
|
38
|
-
/**
|
|
39
|
-
* Env var both spine binaries read to enable their login rate limiters
|
|
40
|
-
* (`'true'` on / unset off). The cross-language contract for the login-security
|
|
41
|
-
* cross project: the TS binary reads it via `runtime.env_get` (a test-only flag,
|
|
42
|
-
* not in `BaseServerEnv`); the Rust `testing_spine_stub` reads it via
|
|
43
|
-
* `std::env::var` — so one backend-config option drives both impls. Shared home
|
|
44
|
-
* here because both `ts_spine_backend_config` and `rust_spine_stub_backend_config`
|
|
45
|
-
* already import this module. (The spawned TS binary re-declares the literal
|
|
46
|
-
* locally — it can't import this module, which transitively pulls `vitest` —
|
|
47
|
-
* mirroring how `testing_spine_server_node.ts` re-declares `TS_SPINE_DIR_ENV`.)
|
|
48
|
-
*/
|
|
49
|
-
export declare const LOGIN_RATE_LIMIT_ENABLED_ENV = "FUZ_LOGIN_RATE_LIMIT_ENABLED";
|
|
50
|
-
/**
|
|
51
|
-
* Env var both spine binaries read to enable their action rate limiters
|
|
52
|
-
* (`'true'` on / unset off) — one per-IP and one per-account limiter, shared by
|
|
53
|
-
* the RPC and WS endpoints (and, on the Rust stub, the auth-family handlers
|
|
54
|
-
* that charge in-handler). The cross-language contract for the action
|
|
55
|
-
* rate-limit cross suite (`ws_action_rate_limit.ts`); same delivery as
|
|
56
|
-
* `LOGIN_RATE_LIMIT_ENABLED_ENV`. Off, the TS spine builds no action limiter
|
|
57
|
-
* and the Rust stub keeps its default posture (only its auth families charge,
|
|
58
|
-
* against an always-on per-account limiter at the production cap).
|
|
59
|
-
*/
|
|
60
|
-
export declare const ACTION_RATE_LIMIT_ENABLED_ENV = "FUZ_ACTION_RATE_LIMIT_ENABLED";
|
|
61
|
-
/**
|
|
62
|
-
* Env var replacing both action limiters' `max_attempts` (a positive integer;
|
|
63
|
-
* the windows stay `default_action_ip_rate_limit`'s /
|
|
64
|
-
* `default_action_account_rate_limit`'s). Both spine binaries refuse to boot
|
|
65
|
-
* when it is set without `ACTION_RATE_LIMIT_ENABLED_ENV` or is not a positive
|
|
66
|
-
* integer, so a suite never asserts a throttle the backend didn't build.
|
|
67
|
-
*/
|
|
68
|
-
export declare const ACTION_RATE_LIMIT_MAX_ATTEMPTS_ENV = "FUZ_ACTION_RATE_LIMIT_MAX_ATTEMPTS";
|
|
69
|
-
/** Options for {@link action_rate_limit_env}. */
|
|
38
|
+
/** Options for `action_rate_limit_env`. */
|
|
70
39
|
export interface ActionRateLimitEnvOptions {
|
|
71
40
|
readonly enable_action_rate_limit?: boolean;
|
|
72
41
|
readonly action_rate_limit_max_attempts?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default_backend_configs.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_backend_configs.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAA4B,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"default_backend_configs.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_backend_configs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,37 +1,7 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
2
|
import { build_test_backend_paths } from './build_test_backend_paths.js';
|
|
3
3
|
import { default_test_bootstrap_token, default_test_cookie_keys, default_test_keeper_password, default_test_keeper_username } from './default_secrets.js';
|
|
4
|
-
|
|
5
|
-
* Env var both spine binaries read to enable their login rate limiters
|
|
6
|
-
* (`'true'` on / unset off). The cross-language contract for the login-security
|
|
7
|
-
* cross project: the TS binary reads it via `runtime.env_get` (a test-only flag,
|
|
8
|
-
* not in `BaseServerEnv`); the Rust `testing_spine_stub` reads it via
|
|
9
|
-
* `std::env::var` — so one backend-config option drives both impls. Shared home
|
|
10
|
-
* here because both `ts_spine_backend_config` and `rust_spine_stub_backend_config`
|
|
11
|
-
* already import this module. (The spawned TS binary re-declares the literal
|
|
12
|
-
* locally — it can't import this module, which transitively pulls `vitest` —
|
|
13
|
-
* mirroring how `testing_spine_server_node.ts` re-declares `TS_SPINE_DIR_ENV`.)
|
|
14
|
-
*/
|
|
15
|
-
export const LOGIN_RATE_LIMIT_ENABLED_ENV = 'FUZ_LOGIN_RATE_LIMIT_ENABLED';
|
|
16
|
-
/**
|
|
17
|
-
* Env var both spine binaries read to enable their action rate limiters
|
|
18
|
-
* (`'true'` on / unset off) — one per-IP and one per-account limiter, shared by
|
|
19
|
-
* the RPC and WS endpoints (and, on the Rust stub, the auth-family handlers
|
|
20
|
-
* that charge in-handler). The cross-language contract for the action
|
|
21
|
-
* rate-limit cross suite (`ws_action_rate_limit.ts`); same delivery as
|
|
22
|
-
* `LOGIN_RATE_LIMIT_ENABLED_ENV`. Off, the TS spine builds no action limiter
|
|
23
|
-
* and the Rust stub keeps its default posture (only its auth families charge,
|
|
24
|
-
* against an always-on per-account limiter at the production cap).
|
|
25
|
-
*/
|
|
26
|
-
export const ACTION_RATE_LIMIT_ENABLED_ENV = 'FUZ_ACTION_RATE_LIMIT_ENABLED';
|
|
27
|
-
/**
|
|
28
|
-
* Env var replacing both action limiters' `max_attempts` (a positive integer;
|
|
29
|
-
* the windows stay `default_action_ip_rate_limit`'s /
|
|
30
|
-
* `default_action_account_rate_limit`'s). Both spine binaries refuse to boot
|
|
31
|
-
* when it is set without `ACTION_RATE_LIMIT_ENABLED_ENV` or is not a positive
|
|
32
|
-
* integer, so a suite never asserts a throttle the backend didn't build.
|
|
33
|
-
*/
|
|
34
|
-
export const ACTION_RATE_LIMIT_MAX_ATTEMPTS_ENV = 'FUZ_ACTION_RATE_LIMIT_MAX_ATTEMPTS';
|
|
4
|
+
import { ACTION_RATE_LIMIT_ENABLED_ENV, ACTION_RATE_LIMIT_MAX_ATTEMPTS_ENV } from './spine_surface_constants.js';
|
|
35
5
|
/**
|
|
36
6
|
* The `extra_env` entries carrying the action rate-limit toggles, shared by the
|
|
37
7
|
* TS and Rust backend configs so one option pair drives both impls.
|
|
@@ -13,7 +13,7 @@ export declare const RUST_SPINE_STUB_DATABASE_URL_ENV = "FUZ_TESTING_RUST_SPINE_
|
|
|
13
13
|
/**
|
|
14
14
|
* Env var the stub reads for the absolute path of the committed
|
|
15
15
|
* `expected_schema.json` its `/ready` gate introspects against. Pointed at the
|
|
16
|
-
* **same** fixture the TS spine reads (
|
|
16
|
+
* **same** fixture the TS spine reads (`SPINE_EXPECTED_SCHEMA_URL`) —
|
|
17
17
|
* column-presence is engine-portable, so one file is the cross-impl contract.
|
|
18
18
|
*/
|
|
19
19
|
export declare const RUST_SPINE_STUB_EXPECTED_SCHEMA_PATH_ENV = "FUZ_RUST_SPINE_STUB_EXPECTED_SCHEMA_PATH";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rust_spine_stub_backend_config.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/rust_spine_stub_backend_config.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA0C9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"rust_spine_stub_backend_config.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/rust_spine_stub_backend_config.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA0C9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAYzD,uGAAuG;AACvG,eAAO,MAAM,uBAAuB,oCAAoC,CAAC;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,6CAA6C,CAAC;AAE3F;;;;;GAKG;AACH,eAAO,MAAM,wCAAwC,6CAA6C,CAAC;AAqBnG,kGAAkG;AAClG,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD,0FAA0F;AAC1F,eAAO,MAAM,oCAAoC,sDACG,CAAC;AAErD,MAAM,WAAW,6BAA6B;IAC7C,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,8BAA8B,CAAC,EAAE,MAAM,CAAC;CACjD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,GAC1C,UAAS,6BAAkC,KACzC,aAmDF,CAAC"}
|
|
@@ -38,8 +38,8 @@ import '../assert_dev_env.js';
|
|
|
38
38
|
*/
|
|
39
39
|
import { fileURLToPath } from 'node:url';
|
|
40
40
|
import { build_test_backend_paths } from './build_test_backend_paths.js';
|
|
41
|
-
import { SPINE_EXPECTED_SCHEMA_URL } from './spine_surface_constants.js';
|
|
42
|
-
import {
|
|
41
|
+
import { LOGIN_RATE_LIMIT_ENABLED_ENV, SPINE_EXPECTED_SCHEMA_URL } from './spine_surface_constants.js';
|
|
42
|
+
import { action_rate_limit_env, make_default_rust_backend_config, rust_default_capabilities } from './default_backend_configs.js';
|
|
43
43
|
/** Env var naming the prebuilt `testing_spine_stub` binary. Required when `binary_path` is omitted. */
|
|
44
44
|
export const RUST_SPINE_STUB_BIN_ENV = 'FUZ_TESTING_RUST_SPINE_STUB_BIN';
|
|
45
45
|
/**
|
|
@@ -53,7 +53,7 @@ export const RUST_SPINE_STUB_DATABASE_URL_ENV = 'FUZ_TESTING_RUST_SPINE_STUB_DAT
|
|
|
53
53
|
/**
|
|
54
54
|
* Env var the stub reads for the absolute path of the committed
|
|
55
55
|
* `expected_schema.json` its `/ready` gate introspects against. Pointed at the
|
|
56
|
-
* **same** fixture the TS spine reads (
|
|
56
|
+
* **same** fixture the TS spine reads (`SPINE_EXPECTED_SCHEMA_URL`) —
|
|
57
57
|
* column-presence is engine-portable, so one file is the cross-impl contract.
|
|
58
58
|
*/
|
|
59
59
|
export const RUST_SPINE_STUB_EXPECTED_SCHEMA_PATH_ENV = 'FUZ_RUST_SPINE_STUB_EXPECTED_SCHEMA_PATH';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
2
|
/**
|
|
3
|
-
* Pure spine-surface
|
|
4
|
-
*
|
|
3
|
+
* Pure spine-surface constants — wire paths, roles, the fixture URL, and the
|
|
4
|
+
* env-var names the backend configs set for the spawned spine binaries. A
|
|
5
|
+
* hono-free leaf split out of `default_spine_surface.ts`.
|
|
5
6
|
*
|
|
6
7
|
* Cross-process suite modules (which drive a separately-spawned backend binary
|
|
7
8
|
* over HTTP) need only the wire path / role / fixture-URL, not the in-process
|
|
@@ -10,7 +11,13 @@ import '../assert_dev_env.js';
|
|
|
10
11
|
* `session_middleware` → `hono/cookie` — onto a backend-spawning consumer with
|
|
11
12
|
* no `hono` peer installed (a Rust-only spine consumer). Keeping these constants
|
|
12
13
|
* on this handler-free leaf lets such a consumer import the path without the
|
|
13
|
-
* peer. `default_spine_surface.ts`
|
|
14
|
+
* peer. `default_spine_surface.ts` imports the ones it uses from here.
|
|
15
|
+
*
|
|
16
|
+
* The env-var names live here so both sides of each contract share one
|
|
17
|
+
* constant: the backend configs that set them (`default_backend_configs.ts`,
|
|
18
|
+
* `ts_spine_backend_config.ts`, `rust_spine_stub_backend_config.ts`) and the
|
|
19
|
+
* spawned TS spine binary that reads them, which imports this leaf rather than
|
|
20
|
+
* the config builders.
|
|
14
21
|
*
|
|
15
22
|
* @module
|
|
16
23
|
*/
|
|
@@ -56,4 +63,37 @@ export declare const SPINE_PARTICIPANT_ROLE = "participant";
|
|
|
56
63
|
* engine-portable, so one fixture is the cross-impl contract.
|
|
57
64
|
*/
|
|
58
65
|
export declare const SPINE_EXPECTED_SCHEMA_URL: URL;
|
|
66
|
+
/**
|
|
67
|
+
* Env var both spine binaries read to enable their login rate limiters
|
|
68
|
+
* (`'true'` on / unset off). The cross-language contract for the login-security
|
|
69
|
+
* cross project: the TS binary reads it via `runtime.env_get` (a test-only flag,
|
|
70
|
+
* not in `BaseServerEnv`); the Rust `testing_spine_stub` reads it via
|
|
71
|
+
* `std::env::var` — so one backend-config option drives both impls
|
|
72
|
+
* (`ts_spine_backend_config` and `rust_spine_stub_backend_config` set it).
|
|
73
|
+
*/
|
|
74
|
+
export declare const LOGIN_RATE_LIMIT_ENABLED_ENV = "FUZ_LOGIN_RATE_LIMIT_ENABLED";
|
|
75
|
+
/**
|
|
76
|
+
* Env var both spine binaries read to enable their action rate limiters
|
|
77
|
+
* (`'true'` on / unset off) — one per-IP and one per-account limiter, shared by
|
|
78
|
+
* the RPC and WS endpoints (and, on the Rust stub, the auth-family handlers
|
|
79
|
+
* that charge in-handler). The cross-language contract for the action
|
|
80
|
+
* rate-limit cross suite (`ws_action_rate_limit.ts`); same delivery as
|
|
81
|
+
* `LOGIN_RATE_LIMIT_ENABLED_ENV`. Off, neither spine builds an action
|
|
82
|
+
* limiter.
|
|
83
|
+
*/
|
|
84
|
+
export declare const ACTION_RATE_LIMIT_ENABLED_ENV = "FUZ_ACTION_RATE_LIMIT_ENABLED";
|
|
85
|
+
/**
|
|
86
|
+
* Env var replacing both action limiters' `max_attempts` (a positive integer;
|
|
87
|
+
* the windows stay `default_action_ip_rate_limit`'s /
|
|
88
|
+
* `default_action_account_rate_limit`'s). Both spine binaries refuse to boot
|
|
89
|
+
* when it is set without `ACTION_RATE_LIMIT_ENABLED_ENV` or is not a positive
|
|
90
|
+
* integer, so a suite never asserts a throttle the backend didn't build.
|
|
91
|
+
*/
|
|
92
|
+
export declare const ACTION_RATE_LIMIT_MAX_ATTEMPTS_ENV = "FUZ_ACTION_RATE_LIMIT_MAX_ATTEMPTS";
|
|
93
|
+
/**
|
|
94
|
+
* Env var naming the TS spine backend's root dir, set by
|
|
95
|
+
* `ts_spine_backend_config`; the spawned binary writes its daemon token to
|
|
96
|
+
* `{dir}/run/daemon_token`, which must match `bootstrap.daemon_token_path`.
|
|
97
|
+
*/
|
|
98
|
+
export declare const TS_SPINE_DIR_ENV = "FUZ_TESTING_TS_SPINE_DIR";
|
|
59
99
|
//# sourceMappingURL=spine_surface_constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spine_surface_constants.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/spine_surface_constants.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B
|
|
1
|
+
{"version":3,"file":"spine_surface_constants.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/spine_surface_constants.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,iEAAiE;AACjE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,GAAwD,CAAC;AAEjG;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAE3E;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,uCAAuC,CAAC;AAEvF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,6BAA6B,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
2
|
/**
|
|
3
|
-
* Pure spine-surface
|
|
4
|
-
*
|
|
3
|
+
* Pure spine-surface constants — wire paths, roles, the fixture URL, and the
|
|
4
|
+
* env-var names the backend configs set for the spawned spine binaries. A
|
|
5
|
+
* hono-free leaf split out of `default_spine_surface.ts`.
|
|
5
6
|
*
|
|
6
7
|
* Cross-process suite modules (which drive a separately-spawned backend binary
|
|
7
8
|
* over HTTP) need only the wire path / role / fixture-URL, not the in-process
|
|
@@ -10,7 +11,13 @@ import '../assert_dev_env.js';
|
|
|
10
11
|
* `session_middleware` → `hono/cookie` — onto a backend-spawning consumer with
|
|
11
12
|
* no `hono` peer installed (a Rust-only spine consumer). Keeping these constants
|
|
12
13
|
* on this handler-free leaf lets such a consumer import the path without the
|
|
13
|
-
* peer. `default_spine_surface.ts`
|
|
14
|
+
* peer. `default_spine_surface.ts` imports the ones it uses from here.
|
|
15
|
+
*
|
|
16
|
+
* The env-var names live here so both sides of each contract share one
|
|
17
|
+
* constant: the backend configs that set them (`default_backend_configs.ts`,
|
|
18
|
+
* `ts_spine_backend_config.ts`, `rust_spine_stub_backend_config.ts`) and the
|
|
19
|
+
* spawned TS spine binary that reads them, which imports this leaf rather than
|
|
20
|
+
* the config builders.
|
|
14
21
|
*
|
|
15
22
|
* @module
|
|
16
23
|
*/
|
|
@@ -56,3 +63,36 @@ export const SPINE_PARTICIPANT_ROLE = 'participant';
|
|
|
56
63
|
* engine-portable, so one fixture is the cross-impl contract.
|
|
57
64
|
*/
|
|
58
65
|
export const SPINE_EXPECTED_SCHEMA_URL = new URL('./expected_schema.json', import.meta.url);
|
|
66
|
+
/**
|
|
67
|
+
* Env var both spine binaries read to enable their login rate limiters
|
|
68
|
+
* (`'true'` on / unset off). The cross-language contract for the login-security
|
|
69
|
+
* cross project: the TS binary reads it via `runtime.env_get` (a test-only flag,
|
|
70
|
+
* not in `BaseServerEnv`); the Rust `testing_spine_stub` reads it via
|
|
71
|
+
* `std::env::var` — so one backend-config option drives both impls
|
|
72
|
+
* (`ts_spine_backend_config` and `rust_spine_stub_backend_config` set it).
|
|
73
|
+
*/
|
|
74
|
+
export const LOGIN_RATE_LIMIT_ENABLED_ENV = 'FUZ_LOGIN_RATE_LIMIT_ENABLED';
|
|
75
|
+
/**
|
|
76
|
+
* Env var both spine binaries read to enable their action rate limiters
|
|
77
|
+
* (`'true'` on / unset off) — one per-IP and one per-account limiter, shared by
|
|
78
|
+
* the RPC and WS endpoints (and, on the Rust stub, the auth-family handlers
|
|
79
|
+
* that charge in-handler). The cross-language contract for the action
|
|
80
|
+
* rate-limit cross suite (`ws_action_rate_limit.ts`); same delivery as
|
|
81
|
+
* `LOGIN_RATE_LIMIT_ENABLED_ENV`. Off, neither spine builds an action
|
|
82
|
+
* limiter.
|
|
83
|
+
*/
|
|
84
|
+
export const ACTION_RATE_LIMIT_ENABLED_ENV = 'FUZ_ACTION_RATE_LIMIT_ENABLED';
|
|
85
|
+
/**
|
|
86
|
+
* Env var replacing both action limiters' `max_attempts` (a positive integer;
|
|
87
|
+
* the windows stay `default_action_ip_rate_limit`'s /
|
|
88
|
+
* `default_action_account_rate_limit`'s). Both spine binaries refuse to boot
|
|
89
|
+
* when it is set without `ACTION_RATE_LIMIT_ENABLED_ENV` or is not a positive
|
|
90
|
+
* integer, so a suite never asserts a throttle the backend didn't build.
|
|
91
|
+
*/
|
|
92
|
+
export const ACTION_RATE_LIMIT_MAX_ATTEMPTS_ENV = 'FUZ_ACTION_RATE_LIMIT_MAX_ATTEMPTS';
|
|
93
|
+
/**
|
|
94
|
+
* Env var naming the TS spine backend's root dir, set by
|
|
95
|
+
* `ts_spine_backend_config`; the spawned binary writes its daemon token to
|
|
96
|
+
* `{dir}/run/daemon_token`, which must match `bootstrap.daemon_token_path`.
|
|
97
|
+
*/
|
|
98
|
+
export const TS_SPINE_DIR_ENV = 'FUZ_TESTING_TS_SPINE_DIR';
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
2
|
import type { RpcPathCrossSuiteOptions } from './setup.js';
|
|
3
3
|
/** Options for the testing-backdoor negative-credential suite. */
|
|
4
|
-
export
|
|
4
|
+
export interface TestingBackdoorCrossTestOptions extends RpcPathCrossSuiteOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Where the backend's WebSocket endpoint is, for the session-socket cases.
|
|
7
|
+
* Pass it when the backend serves the `_testing_*` actions on its WS
|
|
8
|
+
* endpoint too; omitted, those cases are skipped.
|
|
9
|
+
*/
|
|
10
|
+
readonly ws?: {
|
|
11
|
+
/** Base URL the backend is reachable at (e.g. `http://localhost:1178`). */
|
|
12
|
+
readonly base_url: string;
|
|
13
|
+
/** WebSocket endpoint path on the backend (e.g. `/api/ws`). */
|
|
14
|
+
readonly ws_path: string;
|
|
15
|
+
/** Origin for the upgrade. Defaults to `base_url`. */
|
|
16
|
+
readonly origin?: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
5
19
|
export declare const describe_testing_backdoor_cross_tests: (options: TestingBackdoorCrossTestOptions) => void;
|
|
6
20
|
//# sourceMappingURL=testing_backdoor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing_backdoor.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_backdoor.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"testing_backdoor.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_backdoor.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA2E9B,OAAO,KAAK,EAAE,wBAAwB,EAAe,MAAM,YAAY,CAAC;AA0ExE,kEAAkE;AAClE,MAAM,WAAW,+BAAgC,SAAQ,wBAAwB;IAChF;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE;QACb,2EAA2E;QAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,+DAA+D;QAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,sDAAsD;QACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACF;AAED,eAAO,MAAM,qCAAqC,GACjD,SAAS,+BAA+B,KACtC,IAyEF,CAAC"}
|
|
@@ -29,6 +29,14 @@ import '../assert_dev_env.js';
|
|
|
29
29
|
* `credential_type_required` — same ceiling; an api token cannot reach
|
|
30
30
|
* keeper operations.
|
|
31
31
|
*
|
|
32
|
+
* Over WebSocket (when `ws` is supplied), the same methods sent on a socket
|
|
33
|
+
* opened with the keeper's **session** cookie answer the same `forbidden`
|
|
34
|
+
* error with `credential_type_required`: the upgrade admits a session, but
|
|
35
|
+
* each message runs the same per-action gates as HTTP RPC, so a socket is no
|
|
36
|
+
* way around the daemon-token channel. Anonymous and bearer have no WS case —
|
|
37
|
+
* an anonymous upgrade is refused before any message, and the upgrade client
|
|
38
|
+
* threads cookies.
|
|
39
|
+
*
|
|
32
40
|
* Each method is sent with **valid** params so each case varies only the
|
|
33
41
|
* credential. (Validation runs after the gates — the order is 401 → authz →
|
|
34
42
|
* 403 → 429 → 400 — so the shapes are belt-and-suspenders here rather than load-
|
|
@@ -45,7 +53,9 @@ import '../assert_dev_env.js';
|
|
|
45
53
|
* binary, not the in-process app — like the ws/sse suites. Wire from a
|
|
46
54
|
* `*.cross.test.ts`. Requires the standard `_testing_*` actions mounted (the
|
|
47
55
|
* same precondition `default_cross_process_setup` already imposes for its
|
|
48
|
-
* per-test `_testing_reset`); ungated, since every cross
|
|
56
|
+
* per-test `_testing_reset`); the HTTP cases are ungated, since every cross
|
|
57
|
+
* backend mounts them, and the WS cases run when `ws` is passed — for a
|
|
58
|
+
* backend that also serves them on its WS endpoint.
|
|
49
59
|
*
|
|
50
60
|
* `$lib`-free by contract (relative specifiers only), like the sibling
|
|
51
61
|
* cross-backend suites.
|
|
@@ -54,7 +64,11 @@ import '../assert_dev_env.js';
|
|
|
54
64
|
*/
|
|
55
65
|
import { describe, test, assert } from 'vitest';
|
|
56
66
|
import { ERROR_CREDENTIAL_TYPE_REQUIRED } from '../../http/error_schemas.js';
|
|
67
|
+
import { JSONRPC_ERROR_CODES } from '../../http/jsonrpc_errors.js';
|
|
57
68
|
import { rpc_call } from '../rpc_helpers.js';
|
|
69
|
+
import { create_admitted_ws_transport } from '../transports/ws_transport.js';
|
|
70
|
+
import { is_response_for } from '../transports/ws_client.js';
|
|
71
|
+
import { test_if } from './capabilities.js';
|
|
58
72
|
import { SPINE_RPC_PATH } from './spine_surface_constants.js';
|
|
59
73
|
/** A well-formed UUID that never names a real row. */
|
|
60
74
|
const NIL_UUID = '00000000-0000-0000-0000-000000000000';
|
|
@@ -81,18 +95,21 @@ const principals = [
|
|
|
81
95
|
{
|
|
82
96
|
name: 'anonymous',
|
|
83
97
|
status: 401,
|
|
98
|
+
code: JSONRPC_ERROR_CODES.unauthenticated,
|
|
84
99
|
// Fresh jar so the keeper cookie (cross-process) can't leak in.
|
|
85
100
|
resolve: (f) => ({ transport: f.fresh_transport(), headers: {} })
|
|
86
101
|
},
|
|
87
102
|
{
|
|
88
103
|
name: 'session',
|
|
89
104
|
status: 403,
|
|
105
|
+
code: JSONRPC_ERROR_CODES.forbidden,
|
|
90
106
|
reason: ERROR_CREDENTIAL_TYPE_REQUIRED,
|
|
91
107
|
resolve: (f) => ({ transport: f.transport, headers: f.create_session_headers() })
|
|
92
108
|
},
|
|
93
109
|
{
|
|
94
110
|
name: 'bearer',
|
|
95
111
|
status: 403,
|
|
112
|
+
code: JSONRPC_ERROR_CODES.forbidden,
|
|
96
113
|
reason: ERROR_CREDENTIAL_TYPE_REQUIRED,
|
|
97
114
|
// Bearer is discarded in a browser context, so suppress Origin (empty
|
|
98
115
|
// jar + no Origin) — the credential must actually resolve so the refusal
|
|
@@ -105,7 +122,7 @@ const principals = [
|
|
|
105
122
|
}
|
|
106
123
|
];
|
|
107
124
|
export const describe_testing_backdoor_cross_tests = (options) => {
|
|
108
|
-
const { setup_test } = options;
|
|
125
|
+
const { setup_test, ws } = options;
|
|
109
126
|
const rpc_path = options.rpc_path ?? SPINE_RPC_PATH;
|
|
110
127
|
describe('testing backdoor credential gate parity', () => {
|
|
111
128
|
for (const { method, params } of backdoor_methods) {
|
|
@@ -125,12 +142,39 @@ export const describe_testing_backdoor_cross_tests = (options) => {
|
|
|
125
142
|
assert.ok(!res.ok, `${label}: expected denial (${principal.status}) but the call succeeded`);
|
|
126
143
|
assert.strictEqual(res.status, principal.status, `${label}: status`);
|
|
127
144
|
// `!res.ok` narrows `res` to the error variant for `res.error`.
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
145
|
+
if (!res.ok) {
|
|
146
|
+
assert.strictEqual(res.error.code, principal.code, `${label}: error.code`);
|
|
147
|
+
if (principal.reason !== undefined) {
|
|
148
|
+
const reason = res.error.data?.reason;
|
|
149
|
+
assert.strictEqual(reason, principal.reason, `${label}: error.data.reason`);
|
|
150
|
+
}
|
|
131
151
|
}
|
|
132
152
|
});
|
|
133
153
|
}
|
|
134
154
|
}
|
|
155
|
+
for (const { method, params } of backdoor_methods) {
|
|
156
|
+
test_if(ws !== undefined, `${method} over a session socket → forbidden ${ERROR_CREDENTIAL_TYPE_REQUIRED}`, async () => {
|
|
157
|
+
const fixture = await setup_test();
|
|
158
|
+
const client = await create_admitted_ws_transport({
|
|
159
|
+
base_url: ws.base_url,
|
|
160
|
+
ws_path: ws.ws_path,
|
|
161
|
+
cookies: fixture.transport.cookies(),
|
|
162
|
+
origin: ws.origin
|
|
163
|
+
});
|
|
164
|
+
try {
|
|
165
|
+
const id = `backdoor_${method}`;
|
|
166
|
+
await client.send({ jsonrpc: '2.0', id, method, params });
|
|
167
|
+
const frame = await client.wait_for(is_response_for(id));
|
|
168
|
+
const label = `${method} session socket`;
|
|
169
|
+
assert.ok(frame.error, `${label}: expected a credential_type_required error but the call succeeded`);
|
|
170
|
+
assert.strictEqual(frame.error.code, JSONRPC_ERROR_CODES.forbidden, `${label}: code`);
|
|
171
|
+
const reason = frame.error.data?.reason;
|
|
172
|
+
assert.strictEqual(reason, ERROR_CREDENTIAL_TYPE_REQUIRED, `${label}: error.data.reason`);
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
await client.close();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
135
179
|
});
|
|
136
180
|
};
|
|
@@ -71,6 +71,7 @@ import '../assert_dev_env.js';
|
|
|
71
71
|
import { z } from 'zod';
|
|
72
72
|
import { type RpcAction } from '../../actions/action_rpc.js';
|
|
73
73
|
import type { AppDeps } from '../../auth/deps.js';
|
|
74
|
+
import type { AuditEmitter } from '../../auth/audit_emitter.js';
|
|
74
75
|
import type { SessionOptions } from '../../auth/session_cookie.js';
|
|
75
76
|
import type { DaemonTokenState } from '../../auth/daemon_token.js';
|
|
76
77
|
import type { Db } from '../../db/db.js';
|
|
@@ -162,16 +163,21 @@ export declare const testing_reset_action_spec: {
|
|
|
162
163
|
* the cross-backend conformance suite uses in place of a poll/sleep before
|
|
163
164
|
* asserting on audit rows.
|
|
164
165
|
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
166
|
+
* The handler awaits `AuditEmitter.drain_inflight`, which waits until no
|
|
167
|
+
* tracked `emit` write is outstanding — so the binary's emitter must be built
|
|
168
|
+
* with `track_inflight: true`, or the drain resolves at once and is no barrier.
|
|
169
|
+
* Tracking is what makes it a barrier whatever the transport: an **HTTP**
|
|
170
|
+
* mutation on a binary running `await_pending_effects: true` has its writes
|
|
171
|
+
* settled by the time it responds, but a **WS** mutation is answered before
|
|
172
|
+
* its effects flush (reply-then-close for a self-revocation), so its audit
|
|
173
|
+
* write can still be in flight when the caller reads the reply. The Rust
|
|
174
|
+
* spine does the same await in `AuditEmitter::drain_inflight`, over an
|
|
175
|
+
* emitter built with `new_with_inflight_tracking`.
|
|
176
|
+
*
|
|
177
|
+
* Covered: every `emit` that ran before the drain was dispatched, and any
|
|
178
|
+
* started while it waits. A write that starts after the drain resolves is
|
|
179
|
+
* not — nor are eager writes outside `emit` (session touch, token usage),
|
|
180
|
+
* which only the dispatching transport's own flush awaits.
|
|
175
181
|
*
|
|
176
182
|
* `auth` gates on the daemon-token credential, matching `_testing_reset`.
|
|
177
183
|
*/
|
|
@@ -243,13 +249,15 @@ export declare const testing_mint_session_action_spec: {
|
|
|
243
249
|
readonly description: string;
|
|
244
250
|
};
|
|
245
251
|
/**
|
|
246
|
-
* Build the standalone `_testing_drain_effects` action
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
* suite asserts on audit rows (the spine binary bundles it via
|
|
252
|
+
* Build the standalone `_testing_drain_effects` action over `audit` — the
|
|
253
|
+
* emitter the backend's handlers emit through (`deps.audit`), built with
|
|
254
|
+
* `track_inflight: true` (see the spec doc). Mount it on any test endpoint
|
|
255
|
+
* whose suite asserts on audit rows (the spine binary bundles it via
|
|
250
256
|
* `create_testing_actions`; in-process suites mount it directly).
|
|
257
|
+
*
|
|
258
|
+
* @param audit - the backend's emitter, whose in-flight writes the action awaits
|
|
251
259
|
*/
|
|
252
|
-
export declare const create_testing_drain_effects_action: () => RpcAction;
|
|
260
|
+
export declare const create_testing_drain_effects_action: (audit: AuditEmitter) => RpcAction;
|
|
253
261
|
/**
|
|
254
262
|
* `_testing_put_fact` — seed an **embedded** fact (`fact.bytes`) for the
|
|
255
263
|
* cross-process fact-serving suite, which drives over real HTTP and has no
|
|
@@ -475,9 +483,10 @@ export interface CreateTestingActionsOptions {
|
|
|
475
483
|
/**
|
|
476
484
|
* Build the testing RPC actions for a test binary's registry.
|
|
477
485
|
*
|
|
478
|
-
* Returns `
|
|
479
|
-
*
|
|
480
|
-
*
|
|
486
|
+
* Returns the bundled `_testing_*` actions (module doc). The test binary
|
|
487
|
+
* calls this at server-assembly time and registers the result on its
|
|
488
|
+
* dispatcher. `_testing_drain_effects` drains `deps.audit`, so the binary's
|
|
489
|
+
* `audit_factory` builds the emitter with `track_inflight: true`.
|
|
481
490
|
*
|
|
482
491
|
* The reset action's table-wipe list mirrors
|
|
483
492
|
* `auth_integration_truncate_tables` from `testing/db.ts` — the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing_reset_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_reset_actions.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAKzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAqCzC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;QAiBpC;;;;;;;;WAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWyC,CAAC;AAE/C
|
|
1
|
+
{"version":3,"file":"testing_reset_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_reset_actions.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAKzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAqCzC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;QAiBpC;;;;;;;;WAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWyC,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;CAWA,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;CAwBC,CAAC;AAE/C;;;;;;;;GAQG;AACH,eAAO,MAAM,mCAAmC,GAAI,OAAO,YAAY,KAAG,SAIvE,CAAC;AAEJ;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;CAeK,CAAC;AAE/C;;;;;;;;;GASG;AACH,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWF,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,QAAO,SAGvD,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;CAYJ,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,uCAAuC,QAAO,SAGzD,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAaF,CAAC;AAyB/C,eAAO,MAAM,qCAAqC,GACjD,SAAS,aAAa,CAAC,SAAS,CAAC,KAC/B,SAMF,CAAC;AAEF,4CAA4C;AAC5C,MAAM,WAAW,2BAA2B;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;IAC9C;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxD;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,OAAO,EACb,SAAS,2BAA2B,KAClC,KAAK,CAAC,SAAS,CAsIjB,CAAC;AAEF,0FAA0F;AAC1F,eAAO,MAAM,0BAA0B,UAAmC,CAAC"}
|