@fuzdev/fuz_app 0.126.0 → 0.127.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 +2 -3
- 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/server/app_server.d.ts +2 -1
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +13 -11
- package/dist/testing/CLAUDE.md +16 -16
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +15 -14
- 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_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/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +4 -3
- package/dist/testing/stubs.d.ts +5 -2
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +19 -4
- 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
package/dist/actions/CLAUDE.md
CHANGED
|
@@ -206,9 +206,8 @@ produces **two** route specs on the same path (GET + POST) that share one
|
|
|
206
206
|
internal dispatcher. The two limiters are required `RateLimiter | null` with
|
|
207
207
|
no default — `null` is the explicit off switch — and the same holds on
|
|
208
208
|
`register_action_ws` / `register_ws_endpoint`, so a hand mount can't run
|
|
209
|
-
unthrottled by omission. `create_app_server` passes its own
|
|
210
|
-
|
|
211
|
-
'disabled_for_testing'`) to every endpoint it mounts. Per-action auth lives inside the dispatcher; the outer routes
|
|
209
|
+
unthrottled by omission. `create_app_server` passes its own to every endpoint
|
|
210
|
+
it mounts (../../../docs/usage.md §Rate limiters). Per-action auth lives inside the dispatcher; the outer routes
|
|
212
211
|
use `auth: {account: 'none', actor: 'none'}` and `transaction: false`.
|
|
213
212
|
|
|
214
213
|
The HTTP RPC dispatcher is a thin shim around `perform_action`
|
package/dist/http/CLAUDE.md
CHANGED
|
@@ -246,12 +246,12 @@ policy invariants.
|
|
|
246
246
|
|
|
247
247
|
### Types
|
|
248
248
|
|
|
249
|
-
- `AppSurface` — JSON-serializable output (`middleware`, `routes`, `rpc_endpoints`, `env`, `events`, `diagnostics`)
|
|
250
|
-
- `AppSurfaceSpec` — the surface bundled with the **source specs** (`surface`, `route_specs`, `middleware_specs`, `rpc_endpoints`). Runtime-only — use for tests and introspection
|
|
249
|
+
- `AppSurface` — JSON-serializable output (`middleware`, `routes`, `rpc_endpoints`, `ws_endpoints`, `env`, `events`, `diagnostics`)
|
|
250
|
+
- `AppSurfaceSpec` — the surface bundled with the **source specs** (`surface`, `route_specs`, `middleware_specs`, `rpc_endpoints`, `ws_endpoints`). Runtime-only — use for tests and introspection
|
|
251
251
|
- `AppSurfaceRoute`, `AppSurfaceMiddleware`, `AppSurfaceEnv`, `AppSurfaceEvent`, `AppSurfaceRpcEndpoint`, `AppSurfaceRpcMethod` — per-entity entries
|
|
252
252
|
- `AppSurfaceDiagnostic` — `{level: 'warning' | 'info'; category; message; source?}`
|
|
253
253
|
- `RpcEndpointSpec` — `{path, actions: Array<RpcAction>}`; fed into `generate_app_surface` so RPC endpoints appear in the surface without coupling to `create_rpc_endpoint`
|
|
254
|
-
- `GenerateAppSurfaceOptions` — `{route_specs, middleware_specs, env_schema?, event_specs?, rpc_endpoints?}`
|
|
254
|
+
- `GenerateAppSurfaceOptions` — `{route_specs, middleware_specs, env_schema?, event_specs?, rpc_endpoints?, ws_endpoints?}`; `ws_endpoints` takes `ResolvedWsEndpointSpec`s (`allowed_origins` filled in by `resolve_ws_endpoints`), so the surface records the patterns the upgrade gate matches
|
|
255
255
|
|
|
256
256
|
`generate_app_surface(options)` emits a `warning` diagnostic for every
|
|
257
257
|
input schema that's not strict (unknown keys silently strip under
|
package/dist/http/surface.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type { RouteAuth } from './auth_shape.js';
|
|
|
14
14
|
import type { RateLimitKey, RouteErrorSchemas } from './error_schemas.js';
|
|
15
15
|
import type { RpcAction } from '../actions/action_rpc.js';
|
|
16
16
|
import type { ActionKind } from '../actions/action_spec.js';
|
|
17
|
-
import type {
|
|
17
|
+
import type { ResolvedWsEndpointSpec } from '../actions/ws_endpoint_spec.js';
|
|
18
18
|
import type { Sensitivity } from '../sensitivity.js';
|
|
19
19
|
/** A route in the generated attack surface (JSON-serializable). */
|
|
20
20
|
export interface AppSurfaceRoute {
|
|
@@ -111,11 +111,12 @@ export interface AppSurfaceWsMethod {
|
|
|
111
111
|
export interface AppSurfaceWsEndpoint {
|
|
112
112
|
path: string;
|
|
113
113
|
/**
|
|
114
|
-
* Upgrade-time origin allowlist
|
|
115
|
-
* regex stringified via
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
114
|
+
* Upgrade-time origin allowlist — the spec's own `allowed_origins`, or the
|
|
115
|
+
* server's when it declares none — one entry per regex, stringified via
|
|
116
|
+
* `RegExp.prototype.toString()` (`'/<source>/<flags>'`). An empty array
|
|
117
|
+
* refuses every request that carries an `Origin`. Reviewers read this as the
|
|
118
|
+
* exact pattern matched at the upgrade gate, not a wildcard approximation.
|
|
119
|
+
* Reconstruct via `new RegExp(source, flags)` if needed.
|
|
119
120
|
*/
|
|
120
121
|
allowed_origins: ReadonlyArray<string>;
|
|
121
122
|
/**
|
|
@@ -161,7 +162,7 @@ export interface AppSurfaceSpec {
|
|
|
161
162
|
route_specs: Array<RouteSpec>;
|
|
162
163
|
middleware_specs: Array<MiddlewareSpec>;
|
|
163
164
|
rpc_endpoints: Array<RpcEndpointSpec>;
|
|
164
|
-
ws_endpoints: Array<
|
|
165
|
+
ws_endpoints: Array<ResolvedWsEndpointSpec>;
|
|
165
166
|
}
|
|
166
167
|
/** An RPC endpoint definition for surface generation. */
|
|
167
168
|
export interface RpcEndpointSpec {
|
|
@@ -179,11 +180,11 @@ export interface GenerateAppSurfaceOptions {
|
|
|
179
180
|
* Mounted WS endpoints (the same array `create_app_server.ws_endpoints`
|
|
180
181
|
* auto-mounts). Each entry's actions surface into
|
|
181
182
|
* `AppSurface.ws_endpoints[i].methods` for attack-surface tests +
|
|
182
|
-
* startup logging. Each
|
|
183
|
-
* `
|
|
184
|
-
*
|
|
183
|
+
* startup logging. Each carries its effective `allowed_origins` —
|
|
184
|
+
* `resolve_ws_endpoints` fills in the server's list where a spec omits
|
|
185
|
+
* it — so the surface records the exact patterns the upgrade gate matches.
|
|
185
186
|
*/
|
|
186
|
-
ws_endpoints?: ReadonlyArray<
|
|
187
|
+
ws_endpoints?: ReadonlyArray<ResolvedWsEndpointSpec>;
|
|
187
188
|
}
|
|
188
189
|
/**
|
|
189
190
|
* Collect error schemas from all middleware that applies to a route path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/surface.ts"],"names":[],"mappings":"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"}
|
package/dist/http/surface.js
CHANGED
|
@@ -8,20 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { z } from 'zod';
|
|
10
10
|
import { schema_to_surface, middleware_applies, merge_error_schemas, is_null_schema, is_strict_object_schema } from './schema_helpers.js';
|
|
11
|
-
/**
|
|
12
|
-
* Stringify a WS endpoint's origin allowlist for the surface. Throws when
|
|
13
|
-
* the spec carries none: the surface records the exact patterns the
|
|
14
|
-
* upgrade gate matches, and an omitted list means the caller never
|
|
15
|
-
* resolved the server default, not any-origin.
|
|
16
|
-
*/
|
|
17
|
-
const to_surface_allowed_origins = (ep) => {
|
|
18
|
-
if (!ep.allowed_origins) {
|
|
19
|
-
throw new Error(`generate_app_surface: ws endpoint ${ep.path} has no allowed_origins — ` +
|
|
20
|
-
"resolve the server's allowed_origins into the spec before surface generation " +
|
|
21
|
-
"(resolve_ws_endpoints, or create_test_app_surface_spec's allowed_origins option)");
|
|
22
|
-
}
|
|
23
|
-
return ep.allowed_origins.map((re) => re.toString());
|
|
24
|
-
};
|
|
25
11
|
// --- Surface generation ---
|
|
26
12
|
/**
|
|
27
13
|
* Collect error schemas from all middleware that applies to a route path.
|
|
@@ -159,7 +145,7 @@ export const generate_app_surface = (options) => {
|
|
|
159
145
|
ws_endpoints: ws_endpoints?.length
|
|
160
146
|
? ws_endpoints.map((ep) => ({
|
|
161
147
|
path: ep.path,
|
|
162
|
-
allowed_origins:
|
|
148
|
+
allowed_origins: ep.allowed_origins.map((re) => re.toString()),
|
|
163
149
|
required_roles: ep.required_roles ?? [],
|
|
164
150
|
// `local_call` specs are frontend-side helpers — registry-only
|
|
165
151
|
// on the backend, never dispatched over WS. Drop them from the
|
package/dist/rate_limiter.d.ts
CHANGED
|
@@ -88,12 +88,30 @@ export declare const default_action_account_rate_limit: RateLimiterOptions;
|
|
|
88
88
|
* A limiter passed explicitly — an instance or `null` — wins over the mode
|
|
89
89
|
* either way, so a rate-limit test enables just the limiter it pins. The
|
|
90
90
|
* disabled mode is loud: `create_app_server` adds a surface warning, which
|
|
91
|
-
* `log_startup_summary` logs at assembly
|
|
91
|
+
* `log_startup_summary` logs at assembly, and the first limiter it leaves
|
|
92
|
+
* `null` prints `RATE_LIMITERS_DISABLED_BANNER` to stderr once per module instance.
|
|
92
93
|
*
|
|
93
94
|
* Twin of the Rust spine's `fuz_auth::RateLimiterMode` (`Enforced` /
|
|
94
95
|
* `DisabledForTesting`).
|
|
95
96
|
*/
|
|
96
97
|
export type RateLimiterMode = 'enforced' | 'disabled_for_testing';
|
|
98
|
+
/**
|
|
99
|
+
* The stderr line a process prints the first time `'disabled_for_testing'`
|
|
100
|
+
* leaves a limiter `null` — the same text as the Rust spine's.
|
|
101
|
+
*/
|
|
102
|
+
export declare const RATE_LIMITERS_DISABLED_BANNER = "!!! RATE LIMITERS DISABLED \u2014 test-only mode. A production server must never print this.";
|
|
103
|
+
/**
|
|
104
|
+
* Print `RATE_LIMITERS_DISABLED_BANNER` with `console.error`, once per module instance.
|
|
105
|
+
*
|
|
106
|
+
* Deliberately on stderr as well as the surface warning, which goes through
|
|
107
|
+
* the server's logger: a deployment that reached this mode is unprotected on
|
|
108
|
+
* every password-bearing route, and that must show in its first lines of
|
|
109
|
+
* output even with the logger silenced. Once per module instance, so a module
|
|
110
|
+
* instance that assembles many in-process servers prints it once, while every spawned test
|
|
111
|
+
* binary prints it at startup — the twin of the Rust spine's
|
|
112
|
+
* `RateLimiterMode::limiter`.
|
|
113
|
+
*/
|
|
114
|
+
export declare const announce_rate_limiters_disabled: () => void;
|
|
97
115
|
/**
|
|
98
116
|
* Result of a rate limit check or record operation.
|
|
99
117
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate_limiter.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/rate_limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAKpC;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,SAAU,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B,EAAE,kBAKzC,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,gCAAgC,EAAE,kBAK9C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,kBAK1C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,EAAE,kBAK/C,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"rate_limiter.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/rate_limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAKpC;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,SAAU,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B,EAAE,kBAKzC,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,gCAAgC,EAAE,kBAK9C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,kBAK1C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,EAAE,kBAK/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,sBAAsB,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,6BAA6B,iGACgD,CAAC;AAI3F;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B,QAAO,IAIlD,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,WAAW;;IACvB,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;gBAOzB,OAAO,EAAE,kBAAkB;IAcvC,8BAA8B;IAC9B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAcD;;;;;;;;;;OAUG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,eAAe;IA2B7D;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,eAAe;IA0B9D;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB;;;;;OAKG;IACH,OAAO,CAAC,GAAG,GAAE,MAAmB,GAAG,IAAI;IAgBvC;;;;OAIG;IACH,OAAO,IAAI,IAAI;CAMf;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,OAAO,CAAC,kBAAkB,CAAC,KAAG,WAE3E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GAAI,GAAG,OAAO,EAAE,aAAa,MAAM,KAAG,QAI7E,CAAC"}
|
package/dist/rate_limiter.js
CHANGED
|
@@ -67,6 +67,29 @@ export const default_action_account_rate_limit = {
|
|
|
67
67
|
cleanup_interval_ms: 5 * 60_000,
|
|
68
68
|
max_keys: DEFAULT_RATE_LIMITER_MAX_KEYS
|
|
69
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* The stderr line a process prints the first time `'disabled_for_testing'`
|
|
72
|
+
* leaves a limiter `null` — the same text as the Rust spine's.
|
|
73
|
+
*/
|
|
74
|
+
export const RATE_LIMITERS_DISABLED_BANNER = '!!! RATE LIMITERS DISABLED — test-only mode. A production server must never print this.';
|
|
75
|
+
let rate_limiters_disabled_announced = false;
|
|
76
|
+
/**
|
|
77
|
+
* Print `RATE_LIMITERS_DISABLED_BANNER` with `console.error`, once per module instance.
|
|
78
|
+
*
|
|
79
|
+
* Deliberately on stderr as well as the surface warning, which goes through
|
|
80
|
+
* the server's logger: a deployment that reached this mode is unprotected on
|
|
81
|
+
* every password-bearing route, and that must show in its first lines of
|
|
82
|
+
* output even with the logger silenced. Once per module instance, so a module
|
|
83
|
+
* instance that assembles many in-process servers prints it once, while every spawned test
|
|
84
|
+
* binary prints it at startup — the twin of the Rust spine's
|
|
85
|
+
* `RateLimiterMode::limiter`.
|
|
86
|
+
*/
|
|
87
|
+
export const announce_rate_limiters_disabled = () => {
|
|
88
|
+
if (rate_limiters_disabled_announced)
|
|
89
|
+
return;
|
|
90
|
+
rate_limiters_disabled_announced = true;
|
|
91
|
+
console.error(RATE_LIMITERS_DISABLED_BANNER);
|
|
92
|
+
};
|
|
70
93
|
/**
|
|
71
94
|
* In-memory sliding window rate limiter.
|
|
72
95
|
*
|
|
@@ -100,7 +100,8 @@ export interface AppServerOptions {
|
|
|
100
100
|
* a default instance for each `*_rate_limiter` option left out,
|
|
101
101
|
* `'disabled_for_testing'` leaves each of them `null`. An explicit option
|
|
102
102
|
* (an instance or `null`) always wins over the mode. The disabled mode adds
|
|
103
|
-
* one surface warning
|
|
103
|
+
* one surface warning, and prints a stderr banner once per module instance
|
|
104
|
+
* (`announce_rate_limiters_disabled`). Never `'disabled_for_testing'` in production — see
|
|
104
105
|
* `RateLimiterMode`.
|
|
105
106
|
*/
|
|
106
107
|
rate_limiters?: RateLimiterMode;
|
|
@@ -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,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAEN,KAAK,cAAc,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAGN,KAAK,WAAW,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACN,WAAW,
|
|
1
|
+
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ 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
16
|
import { BaseServerEnv } from './env.js';
|
|
17
|
-
import { RateLimiter, default_login_ip_rate_limit, default_login_account_rate_limit, default_action_account_rate_limit, default_action_ip_rate_limit } from '../rate_limiter.js';
|
|
17
|
+
import { RateLimiter, announce_rate_limiters_disabled, default_login_ip_rate_limit, 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';
|
|
@@ -103,8 +103,10 @@ export const create_app_server = async (options) => {
|
|
|
103
103
|
const resolve_rate_limiter = (option, defaults) => {
|
|
104
104
|
if (option !== undefined)
|
|
105
105
|
return option;
|
|
106
|
-
if (rate_limiter_mode === 'disabled_for_testing')
|
|
106
|
+
if (rate_limiter_mode === 'disabled_for_testing') {
|
|
107
|
+
announce_rate_limiters_disabled();
|
|
107
108
|
return null;
|
|
109
|
+
}
|
|
108
110
|
const limiter = new RateLimiter({ ...defaults });
|
|
109
111
|
built_rate_limiters.push(limiter);
|
|
110
112
|
return limiter;
|
|
@@ -221,8 +223,10 @@ export const create_app_server = async (options) => {
|
|
|
221
223
|
const resolved_ws_endpoints = resolve_ws_endpoints(typeof options.ws_endpoints === 'function'
|
|
222
224
|
? options.ws_endpoints(context)
|
|
223
225
|
: options.ws_endpoints, options.allowed_origins);
|
|
224
|
-
|
|
226
|
+
// the endpoints to mount and the adapter factory they need — null when none resolve
|
|
227
|
+
let ws_mount = null;
|
|
225
228
|
if (resolved_ws_endpoints?.length) {
|
|
229
|
+
const create_upgrade_websocket = options.create_upgrade_websocket;
|
|
226
230
|
if (create_upgrade_websocket === undefined) {
|
|
227
231
|
throw new Error('create_app_server: ws_endpoints resolved non-empty but create_upgrade_websocket is missing. ' +
|
|
228
232
|
"Pass a factory returning the Hono adapter's upgradeWebSocket helper.");
|
|
@@ -230,6 +234,7 @@ export const create_app_server = async (options) => {
|
|
|
230
234
|
for (const endpoint of resolved_ws_endpoints) {
|
|
231
235
|
assert_endpoint_in_auth_scope('ws_endpoints', endpoint.path);
|
|
232
236
|
}
|
|
237
|
+
ws_mount = { endpoints: resolved_ws_endpoints, create_upgrade_websocket };
|
|
233
238
|
}
|
|
234
239
|
// Surface route (default: enabled)
|
|
235
240
|
if (options.surface_route !== false) {
|
|
@@ -317,12 +322,6 @@ export const create_app_server = async (options) => {
|
|
|
317
322
|
log_startup_summary(surface_spec.surface, log, options.env_values);
|
|
318
323
|
// Hono app assembly
|
|
319
324
|
const app = new Hono();
|
|
320
|
-
// The adapter helper for the WS mount below — built from this app, which
|
|
321
|
-
// Node's `createNodeWebSocket({app})` needs, and only when there is
|
|
322
|
-
// something to mount.
|
|
323
|
-
const upgrade_websocket = resolved_ws_endpoints?.length && create_upgrade_websocket
|
|
324
|
-
? create_upgrade_websocket(app)
|
|
325
|
-
: null;
|
|
326
325
|
// Two-queue side-effect flush. `pending_effects` collects eager
|
|
327
326
|
// fire-and-forget promises (audit emits, api-token usage). `post_commit_effects` collects deferred thunks pushed via
|
|
328
327
|
// `emit_after_commit` (WS notifications, anything that must observe a
|
|
@@ -386,7 +385,10 @@ export const create_app_server = async (options) => {
|
|
|
386
385
|
// adjacent to the consumer routes and ahead of the static fallback —
|
|
387
386
|
// matches the "WS mount is route registration" mental model.
|
|
388
387
|
const mounted_ws_endpoints = {};
|
|
389
|
-
if (
|
|
388
|
+
if (ws_mount) {
|
|
389
|
+
// the adapter helper — built from this app, which Node's
|
|
390
|
+
// `createNodeWebSocket({app})` needs, and only when there is something to mount
|
|
391
|
+
const upgrade_websocket = ws_mount.create_upgrade_websocket(app);
|
|
390
392
|
// Cross-surface collision: `register_ws_endpoint` mounts a `GET path`
|
|
391
393
|
// upgrade route. If a `RouteSpec` already registered `GET path`,
|
|
392
394
|
// Hono's last-wins semantics would silently shadow the consumer's
|
|
@@ -406,7 +408,7 @@ export const create_app_server = async (options) => {
|
|
|
406
408
|
// (even with explicit `auth_guard: false`) cannot opt out. To
|
|
407
409
|
// disable, every spec sharing the transport must pass `auth_guard: false`.
|
|
408
410
|
const guarded_transports = new WeakSet();
|
|
409
|
-
for (const endpoint of
|
|
411
|
+
for (const endpoint of ws_mount.endpoints) {
|
|
410
412
|
if (seen_paths.has(endpoint.path)) {
|
|
411
413
|
throw new Error(`create_app_server: duplicate ws_endpoints path: ${endpoint.path}`);
|
|
412
414
|
}
|
package/dist/testing/CLAUDE.md
CHANGED
|
@@ -37,7 +37,7 @@ time (never runtime), where a throwing guard would break `vite build`.
|
|
|
37
37
|
- `create_stub_audit_sse()` — no-op `AuditLogSse` for surface-test wiring without booting real SSE. `on_audit_event` no-op (nothing is broadcast); `registry` is a fresh `SubscriberRegistry` (live `.count` / `.close_*` for registry-state tests, isolated per call). For real SSE plumbing build via `create_audit_log_sse` against `create_test_app`.
|
|
38
38
|
- `create_stub_api_middleware({include_daemon_token?})` — stub `MiddlewareSpec[]` matching `create_auth_middleware_specs`'s output (origin/session/request_context/bearer_auth, optional daemon_token) for surface generation without booting real auth. See `auth/CLAUDE.md` §Middleware for the real stack.
|
|
39
39
|
- `create_stub_app_server_context(session_options)` — stub `AppServerContext`; rate limiters null, `bootstrap_status.available: false`.
|
|
40
|
-
- `create_test_app_surface_spec(options)` — builds an `AppSurfaceSpec` mirroring `create_app_server`'s route assembly (consumer routes + stub middleware + surface generation). `CreateTestAppSurfaceSpecOptions`: `session_options`, `create_route_specs`, `env_schema?`, `event_specs?`, `rpc_endpoints?`, `ws_endpoints?`, `allowed_origins?`, `transform_middleware?`, `bootstrap?`. Throws, like `create_app_server`, on an endpoint path outside `AUTH_MIDDLEWARE_PATH` (`assert_endpoint_in_auth_scope`). Bootstrap is opt-in (symmetric with `create_app_server` — omit to skip; pass the same value as prod to mount routes at `bootstrap.route_prefix ?? '/api/account'`). Single source of truth for attack-surface tests — track `create_app_server` wiring changes here.
|
|
40
|
+
- `create_test_app_surface_spec(options)` — builds an `AppSurfaceSpec` mirroring `create_app_server`'s route assembly (consumer routes + stub middleware + surface generation). `CreateTestAppSurfaceSpecOptions`: `session_options`, `create_route_specs`, `env_schema?`, `event_specs?`, `rpc_endpoints?`, `ws_endpoints?`, `allowed_origins?`, `transform_middleware?`, `bootstrap?`. Throws, like `create_app_server`, on an endpoint path outside `AUTH_MIDDLEWARE_PATH` (`assert_endpoint_in_auth_scope`). Throws on a `ws_endpoints` spec with no `allowed_origins` of its own when no `allowed_origins` option is given (there is no server list to default from). Bootstrap is opt-in (symmetric with `create_app_server` — omit to skip; pass the same value as prod to mount routes at `bootstrap.route_prefix ?? '/api/account'`). Single source of truth for attack-surface tests — track `create_app_server` wiring changes here.
|
|
41
41
|
|
|
42
42
|
Throwing stubs surface mock escape: a test that accidentally reaches into
|
|
43
43
|
stub territory breaks immediately with a label-scoped error rather than
|
|
@@ -179,9 +179,10 @@ Types:
|
|
|
179
179
|
`create_test_app` hard-codes the test-friendly `AppServerOptions`:
|
|
180
180
|
`allowed_origins: [/^http:\/\/localhost/]`, stub proxy pinned to `127.0.0.1`,
|
|
181
181
|
`env_schema: z.object({})`, `rate_limiters: 'disabled_for_testing'` (every
|
|
182
|
-
rate limiter `null
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
rate limiter `null` — a limiter passed through `app_options` wins over the
|
|
183
|
+
mode, so a rate-limit test enables just the one it pins; the mode's stderr
|
|
184
|
+
banner prints once per module instance — once per test file in an isolated
|
|
185
|
+
vitest project, once per run under `isolate: false`, ../../../docs/usage.md §Rate limiters), static daemon token state (no rotation, keeper already set),
|
|
185
186
|
**`await_pending_effects: true`** (fire-and-forget effects complete before
|
|
186
187
|
the response returns so tests can assert on side effects inline), and silent
|
|
187
188
|
logger. Override via `app_options`. `create_test_app_for_bootstrap` disables
|
|
@@ -551,7 +552,7 @@ Three layers:
|
|
|
551
552
|
|
|
552
553
|
1. **Primitives** — `create_fake_ws()`, `create_fake_hono_context(opts)`, `create_stub_upgrade()`, `MinimalActionEnvironment`, `dispatch_ws_message(on_message, event, ws)`. The fake context sets the keys the production auth middleware sets — `AUTH_SESSION_TOKEN_HASH_KEY` included, as `hash_session_token(auth_session_id)` — because the dispatcher reads the credential through `get_resolved_auth(c)`; a hand-built upgrade context must do the same. `create_stub_upgrade()` stands in for a runtime adapter's `upgradeWebSocket`: it passes a request without `Upgrade: websocket` to `next()`, and records an upgrade request — its real `Context` and the endpoint's events factory — in `upgrades`, answering `200`. So a test can send `app.request('/api/ws', {headers: {upgrade: 'websocket', cookie | authorization, origin, 'x-forwarded-for'}})` through an assembled app's whole middleware chain and build the socket's events from the `Context` that chain produced (`src/test/server/create_app_server_ws_endpoints.dispatch.db.test.ts`); `get_create_events()` still returns the last mounted factory, for a hand-built context.
|
|
553
554
|
2. **Harness** — `create_ws_test_harness({actions, transport?, heartbeat?, log?, on_socket_open?, on_socket_close?})` → `WsTestHarness`. `connect(identity?)` is async and resolves after the connection is admitted and `on_socket_open` completes, so broadcasts sent immediately after `await harness.connect()` reach the client. The harness pre-bakes its `RequestContext` (`TEST_CONTEXT_PRESET_KEY`), which also skips the admission credential re-read — there are no session or token rows behind a harness identity — so tests of the re-read itself drive `register_action_ws` with a real database and no preset (`src/test/actions/register_action_ws.admission.db.test.ts`). The harness threads its own `create_stub_db()` into the dispatcher's `db` slot so handlers declaring `side_effects: true` execute under the same transaction wrap they would in production (the stub's `transaction(fn)` synchronously calls `fn(stub_db)`); domain deps reach handlers via factory closures, the same way HTTP RPC factories already wire them. Audit fan-out runs through whatever `audit` emitter the consumer supplied to its action factory closure (typically `create_test_audit_emitter()` for unit harnesses).
|
|
554
|
-
3. **Round-trip helpers** — predicates + wire-frame types live in `transports/ws_client.ts` (shared with the cross-process `ws_transport.ts` impl): `is_notification(method)`, `is_notification_with<P>(method, match)` (type-guard combinator — narrows `wait_for` return type), `is_response_for(id)`, `JsonrpcNotificationFrame<P>` / `JsonrpcSuccessResponseFrame<R>` / `JsonrpcErrorResponseFrame<D>` (typed wire-frame shapes distinct from the runtime Zod schemas in `http/jsonrpc.ts` — generic over `params` / `result` / `data` so tests narrow without casts).
|
|
555
|
+
3. **Round-trip helpers** — predicates + wire-frame types live in `transports/ws_client.ts` (shared with the cross-process `ws_transport.ts` impl): `is_notification(method)`, `is_notification_with<P>(method, match)` (type-guard combinator — narrows `wait_for` return type), `is_response_for(id)`, `JsonrpcNotificationFrame<P>` / `JsonrpcSuccessResponseFrame<R>` / `JsonrpcErrorResponseFrame<D>` (typed wire-frame shapes distinct from the runtime Zod schemas in `http/jsonrpc.ts` — generic over `params` / `result` / `data` so tests narrow without casts).
|
|
555
556
|
|
|
556
557
|
`WsClient` (in `transports/ws_client.ts`):
|
|
557
558
|
`{send, request<R>, close, messages, wait_for, wait_for_close, close_code, close_reason}`.
|
|
@@ -572,8 +573,6 @@ of undefined`). `wait_for(predicate, timeout_ms?)` checks already-received
|
|
|
572
573
|
messages first, then waits for new arrivals (default 1000ms); drops the
|
|
573
574
|
waiter on timeout so the `waiters` array doesn't grow.
|
|
574
575
|
|
|
575
|
-
`keeper_identity()` — convenience for `{credential_type: 'daemon_token', roles: [ROLE_KEEPER]}`.
|
|
576
|
-
|
|
577
576
|
## Data exposure + rate limiting
|
|
578
577
|
|
|
579
578
|
### `data_exposure.ts` — `describe_data_exposure_tests`
|
|
@@ -1594,12 +1593,15 @@ drift-guarded by `src/test/cross_backend/spine_expected_schema.db.test.ts`
|
|
|
1594
1593
|
|
|
1595
1594
|
### Testing-backdoor credential gate — `cross_backend/testing_backdoor.ts`
|
|
1596
1595
|
|
|
1597
|
-
`describe_testing_backdoor_cross_tests({setup_test, rpc_path?})` —
|
|
1596
|
+
`describe_testing_backdoor_cross_tests({setup_test, rpc_path?, ws?})` —
|
|
1598
1597
|
the negative-credential parity suite for the `_testing_*` backdoor actions.
|
|
1599
|
-
For each
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1598
|
+
For each `_testing_*` action except `_testing_drain_effects` (the three
|
|
1599
|
+
privileged writes plus the three introspection reads) it fires three principals over real HTTP: **anonymous** →
|
|
1600
|
+
401 `unauthenticated`, **session** → 403 `forbidden` `credential_type_required`,
|
|
1601
|
+
**bearer** → 403 `forbidden` `credential_type_required` — and, when `ws`
|
|
1602
|
+
(`{base_url, ws_path, origin?}`) is passed, sends each on a socket opened with
|
|
1603
|
+
the keeper's session cookie, which answers the same `forbidden`
|
|
1604
|
+
`credential_type_required` (a socket is no way around the daemon-token channel) —
|
|
1603
1605
|
proving the daemon-token gate that fences each backdoor action holds end-to-end
|
|
1604
1606
|
on the real dispatcher (the spec-derived `describe_rpc_attack_surface_tests`
|
|
1605
1607
|
never enumerates them because they're off the declared surface). Each method is
|
|
@@ -1731,12 +1733,10 @@ TEST-NET-2 addresses nothing else sends. The backends are started by the
|
|
|
1731
1733
|
backend configs (`ts_spine_*_backend_config`, `rust_spine_stub_backend_config`),
|
|
1732
1734
|
which set `ACTION_RATE_LIMIT_ENABLED_ENV` (`FUZ_ACTION_RATE_LIMIT_ENABLED`) and
|
|
1733
1735
|
`ACTION_RATE_LIMIT_MAX_ATTEMPTS_ENV` (`FUZ_ACTION_RATE_LIMIT_MAX_ATTEMPTS`) from
|
|
1734
|
-
`
|
|
1736
|
+
`spine_surface_constants.ts` — both spine binaries build one IP + one account
|
|
1735
1737
|
limiter (the action defaults' windows, the cap replacing both
|
|
1736
1738
|
`max_attempts`) shared by RPC and WS, and refuse to boot on a cap without the
|
|
1737
|
-
flag. Off,
|
|
1738
|
-
default posture: its auth families charge an always-on per-account limiter at
|
|
1739
|
-
the production cap, its dispatchers none. Runs under the
|
|
1739
|
+
flag. Off, neither spine builds an action limiter. Runs under the
|
|
1740
1740
|
`cross_backend_security` dual-spawn beside the login-security suite. The TS
|
|
1741
1741
|
spine charges every classed action in its dispatcher; the Rust stub charges
|
|
1742
1742
|
`account_token_create` and the other auth-family specs inside their handlers
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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"}
|
|
@@ -256,6 +256,19 @@ export const create_test_app_server = async (options) => {
|
|
|
256
256
|
cleanup: () => backend.close()
|
|
257
257
|
};
|
|
258
258
|
};
|
|
259
|
+
/**
|
|
260
|
+
* The `create_app_server` options both test-app builders share — a fresh
|
|
261
|
+
* object per call, spread ahead of the per-builder options and `app_options`.
|
|
262
|
+
*/
|
|
263
|
+
const test_app_server_base_options = () => ({
|
|
264
|
+
allowed_origins: [/^http:\/\/localhost/],
|
|
265
|
+
proxy: { trusted_proxies: ['127.0.0.1'], get_connection_ip: () => '127.0.0.1' },
|
|
266
|
+
env_schema: z.object({}),
|
|
267
|
+
// every limiter off unless `app_options` passes one — a rate-limit test
|
|
268
|
+
// enables just the limiter it pins
|
|
269
|
+
rate_limiters: 'disabled_for_testing',
|
|
270
|
+
await_pending_effects: true
|
|
271
|
+
});
|
|
259
272
|
/**
|
|
260
273
|
* Create a fully assembled test app with a Hono server, middleware, and routes.
|
|
261
274
|
*
|
|
@@ -283,15 +296,9 @@ export const create_test_app = async (options) => {
|
|
|
283
296
|
keeper_account_id: test_server.account.id
|
|
284
297
|
};
|
|
285
298
|
const result = await create_app_server({
|
|
299
|
+
...test_app_server_base_options(),
|
|
286
300
|
backend: test_server,
|
|
287
301
|
session_options: options.session_options,
|
|
288
|
-
allowed_origins: [/^http:\/\/localhost/],
|
|
289
|
-
proxy: { trusted_proxies: ['127.0.0.1'], get_connection_ip: () => '127.0.0.1' },
|
|
290
|
-
env_schema: z.object({}),
|
|
291
|
-
// every limiter off unless `app_options` passes one — a rate-limit test
|
|
292
|
-
// enables just the limiter it pins
|
|
293
|
-
rate_limiters: 'disabled_for_testing',
|
|
294
|
-
await_pending_effects: true,
|
|
295
302
|
daemon_token_state,
|
|
296
303
|
rpc_endpoints: options.rpc_endpoints,
|
|
297
304
|
bootstrap: options.bootstrap,
|
|
@@ -418,15 +425,9 @@ export const create_test_app_for_bootstrap = async (options) => {
|
|
|
418
425
|
keeper_account_id: null
|
|
419
426
|
};
|
|
420
427
|
const result = await create_app_server({
|
|
428
|
+
...test_app_server_base_options(),
|
|
421
429
|
backend,
|
|
422
430
|
session_options,
|
|
423
|
-
allowed_origins: [/^http:\/\/localhost/],
|
|
424
|
-
proxy: { trusted_proxies: ['127.0.0.1'], get_connection_ip: () => '127.0.0.1' },
|
|
425
|
-
env_schema: z.object({}),
|
|
426
|
-
// every limiter off unless `app_options` passes one — a rate-limit test
|
|
427
|
-
// enables just the limiter it pins
|
|
428
|
-
rate_limiters: 'disabled_for_testing',
|
|
429
|
-
await_pending_effects: true,
|
|
430
431
|
daemon_token_state,
|
|
431
432
|
rpc_endpoints: options.rpc_endpoints,
|
|
432
433
|
bootstrap,
|
|
@@ -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";
|