@fuzdev/fuz_app 0.131.0 → 0.132.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/action_dispatcher.js +0 -1
- package/dist/actions/action_event_data.d.ts +2 -2
- package/dist/actions/action_event_types.d.ts +2 -2
- package/dist/actions/action_rpc.js +0 -1
- package/dist/actions/action_spec.d.ts +19 -19
- package/dist/actions/perform_action.js +0 -1
- package/dist/actions/register_action_ws.js +0 -1
- package/dist/actions/transports_http.d.ts +7 -0
- package/dist/actions/transports_http.d.ts.map +1 -1
- package/dist/actions/transports_http.js +18 -1
- package/dist/auth/CLAUDE.md +1 -1
- package/dist/auth/account_routes.js +1 -1
- package/dist/auth/audit_log_schema.d.ts +5 -5
- package/dist/auth/cell_action_specs.d.ts +3 -3
- package/dist/auth/credential_type_schema.d.ts +1 -1
- package/dist/auth/middleware.d.ts +13 -10
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +14 -10
- package/dist/cli/daemon.js +0 -1
- package/dist/cli/logger.js +0 -1
- package/dist/env/load.js +0 -1
- package/dist/hono_context.d.ts +1 -1
- package/dist/http/CLAUDE.md +2 -1
- package/dist/http/auth_shape.d.ts +6 -6
- package/dist/http/error_schemas.d.ts +12 -2
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +10 -1
- package/dist/http/origin.d.ts +10 -6
- package/dist/http/origin.d.ts.map +1 -1
- package/dist/http/origin.js +10 -6
- package/dist/http/route_spec.d.ts +19 -12
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +33 -6
- package/dist/http/schema_helpers.d.ts +3 -1
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +3 -2
- package/dist/http/simple_request.d.ts +63 -0
- package/dist/http/simple_request.d.ts.map +1 -0
- package/dist/http/simple_request.js +84 -0
- package/dist/http/surface.js +0 -1
- package/dist/realtime/sse.js +0 -1
- package/dist/server/app_server.d.ts +2 -2
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +5 -2
- package/dist/testing/CLAUDE.md +16 -0
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +2 -1
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/attack_surface.js +14 -15
- package/dist/testing/audit_completeness.js +1 -1
- package/dist/testing/cross_backend/action_manifest.d.ts +10 -10
- package/dist/testing/cross_backend/simple_request.d.ts +11 -0
- package/dist/testing/cross_backend/simple_request.d.ts.map +1 -0
- package/dist/testing/cross_backend/simple_request.js +142 -0
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +5 -5
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +40 -11
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +19 -7
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +3 -0
- package/dist/testing/transports/ws_client.js +0 -1
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/auth_state.svelte.js +5 -1
- package/package.json +2 -2
|
@@ -58,6 +58,12 @@ export const ERROR_PAYLOAD_TOO_LARGE = 'payload_too_large';
|
|
|
58
58
|
// --- Origin & bearer token verification ---
|
|
59
59
|
/** Request origin not in allowlist. */
|
|
60
60
|
export const ERROR_FORBIDDEN_ORIGIN = 'forbidden_origin';
|
|
61
|
+
/**
|
|
62
|
+
* A `POST` whose `Content-Type` the route refuses: anything but
|
|
63
|
+
* `application/json` on a JSON route, a CORS-safelisted type or none on a
|
|
64
|
+
* `raw_body` one. See `http/simple_request.ts`.
|
|
65
|
+
*/
|
|
66
|
+
export const ERROR_UNSUPPORTED_CONTENT_TYPE = 'unsupported_content_type';
|
|
61
67
|
/** Bearer token failed validation (missing, malformed, or revoked). */
|
|
62
68
|
export const ERROR_INVALID_TOKEN = 'invalid_token';
|
|
63
69
|
/** Token references a deleted account. */
|
|
@@ -279,7 +285,7 @@ export const AccountVanishedError = z.looseObject({
|
|
|
279
285
|
* - `'both'` — both keys.
|
|
280
286
|
*/
|
|
281
287
|
export const RateLimitKey = z.enum(['ip', 'account', 'both']);
|
|
282
|
-
export const derive_error_schemas = ({ auth, has_input = false, has_params = false, has_query = false, rate_limit }) => {
|
|
288
|
+
export const derive_error_schemas = ({ auth, has_input = false, has_params = false, has_query = false, rate_limit, checks_content_type = false }) => {
|
|
283
289
|
const errors = {};
|
|
284
290
|
const has_validation = has_input || has_params || has_query;
|
|
285
291
|
if (needs_actor(auth)) {
|
|
@@ -320,5 +326,8 @@ export const derive_error_schemas = ({ auth, has_input = false, has_params = fal
|
|
|
320
326
|
if (rate_limit) {
|
|
321
327
|
errors[429] = RateLimitError;
|
|
322
328
|
}
|
|
329
|
+
if (checks_content_type) {
|
|
330
|
+
errors[415] = ApiError;
|
|
331
|
+
}
|
|
323
332
|
return errors;
|
|
324
333
|
};
|
package/dist/http/origin.d.ts
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
* Request source verification middleware for API protection.
|
|
3
3
|
*
|
|
4
4
|
* Verifies requests are coming from expected origins/referers.
|
|
5
|
-
* CSRF protection is
|
|
6
|
-
* (see `auth/session_middleware.ts`)
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* CSRF protection is `SameSite: strict` on session cookies
|
|
6
|
+
* (see `auth/session_middleware.ts`) plus the CORS simple-request refusal
|
|
7
|
+
* (`http/simple_request.ts`) — `SameSite` alone admits same-site pages, which
|
|
8
|
+
* include every other port on the same host. This module provides origin
|
|
9
|
+
* allowlisting for locally-running services — preventing untrusted websites
|
|
10
|
+
* from making requests as the user browses the web — and is the only gate on
|
|
11
|
+
* the WebSocket upgrade, which is never preflighted.
|
|
9
12
|
*
|
|
10
13
|
* @module
|
|
11
14
|
*/
|
|
@@ -30,7 +33,7 @@ export declare const is_browser_context: (c: Context) => boolean;
|
|
|
30
33
|
/**
|
|
31
34
|
* Parses FUZ_ALLOWED_ORIGINS env var into regex matchers for request source verification.
|
|
32
35
|
* Origin allowlisting for locally-running services — not the CSRF layer
|
|
33
|
-
* (that's `SameSite: strict` on session cookies).
|
|
36
|
+
* (that's `SameSite: strict` on session cookies plus `http/simple_request.ts`).
|
|
34
37
|
*
|
|
35
38
|
* Accepts comma-separated patterns with limited wildcards:
|
|
36
39
|
* - Exact origins: `https://api.fuz.dev`
|
|
@@ -56,7 +59,8 @@ export declare const should_allow_origin: (origin: string, allowed_patterns: Rea
|
|
|
56
59
|
/**
|
|
57
60
|
* Middleware that verifies the request source against an allowlist.
|
|
58
61
|
*
|
|
59
|
-
* Origin allowlisting (not the CSRF layer — that's `SameSite: strict` cookies
|
|
62
|
+
* Origin allowlisting (not the CSRF layer — that's `SameSite: strict` cookies
|
|
63
|
+
* plus `http/simple_request.ts`):
|
|
60
64
|
* - Checks the `Origin` header (if present) against the allowlist
|
|
61
65
|
* - Allows requests without an `Origin` header (direct access, curl, etc.)
|
|
62
66
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"origin.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/origin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"origin.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAI7C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,kBAAkB,GAAI,GAAG,OAAO,KAAG,OAC8B,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,GAAG,SAAS,KAAG,KAAK,CAAC,MAAM,CAO5E,CAAC;AAEP;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC/B,QAAQ,MAAM,EACd,kBAAkB,aAAa,CAAC,MAAM,CAAC,KACrC,OAAuD,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,GAChC,kBAAkB,aAAa,CAAC,MAAM,CAAC,KAAG,OAgB1C,CAAC"}
|
package/dist/http/origin.js
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
* Request source verification middleware for API protection.
|
|
3
3
|
*
|
|
4
4
|
* Verifies requests are coming from expected origins/referers.
|
|
5
|
-
* CSRF protection is
|
|
6
|
-
* (see `auth/session_middleware.ts`)
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* CSRF protection is `SameSite: strict` on session cookies
|
|
6
|
+
* (see `auth/session_middleware.ts`) plus the CORS simple-request refusal
|
|
7
|
+
* (`http/simple_request.ts`) — `SameSite` alone admits same-site pages, which
|
|
8
|
+
* include every other port on the same host. This module provides origin
|
|
9
|
+
* allowlisting for locally-running services — preventing untrusted websites
|
|
10
|
+
* from making requests as the user browses the web — and is the only gate on
|
|
11
|
+
* the WebSocket upgrade, which is never preflighted.
|
|
9
12
|
*
|
|
10
13
|
* @module
|
|
11
14
|
*/
|
|
@@ -31,7 +34,7 @@ export const is_browser_context = (c) => c.req.header('Origin') !== undefined ||
|
|
|
31
34
|
/**
|
|
32
35
|
* Parses FUZ_ALLOWED_ORIGINS env var into regex matchers for request source verification.
|
|
33
36
|
* Origin allowlisting for locally-running services — not the CSRF layer
|
|
34
|
-
* (that's `SameSite: strict` on session cookies).
|
|
37
|
+
* (that's `SameSite: strict` on session cookies plus `http/simple_request.ts`).
|
|
35
38
|
*
|
|
36
39
|
* Accepts comma-separated patterns with limited wildcards:
|
|
37
40
|
* - Exact origins: `https://api.fuz.dev`
|
|
@@ -63,7 +66,8 @@ export const should_allow_origin = (origin, allowed_patterns) => allowed_pattern
|
|
|
63
66
|
/**
|
|
64
67
|
* Middleware that verifies the request source against an allowlist.
|
|
65
68
|
*
|
|
66
|
-
* Origin allowlisting (not the CSRF layer — that's `SameSite: strict` cookies
|
|
69
|
+
* Origin allowlisting (not the CSRF layer — that's `SameSite: strict` cookies
|
|
70
|
+
* plus `http/simple_request.ts`):
|
|
67
71
|
* - Checks the `Origin` header (if present) against the allowlist
|
|
68
72
|
* - Allows requests without an `Origin` header (direct access, curl, etc.)
|
|
69
73
|
*
|
|
@@ -51,8 +51,9 @@ export type AuthGuardResolver = (auth: RouteAuth) => AuthGuards;
|
|
|
51
51
|
* and before input validation; resolves the acting actor (when `auth.actor !==
|
|
52
52
|
* 'none'`) from the `acting` selector — `c.var.validated_query.acting` on GETs,
|
|
53
53
|
* read off the raw body on mutations — and sets the request context on the Hono
|
|
54
|
-
* context. Per-route order in `apply_route_specs`:
|
|
55
|
-
* pre-authorization auth (401 + rule-3 scope) →
|
|
54
|
+
* context. Per-route order in `apply_route_specs`: content type (415) →
|
|
55
|
+
* params → query → pre-authorization auth (401 + rule-3 scope) →
|
|
56
|
+
* authorization phase →
|
|
56
57
|
* post-authorization auth (403) → input validation (400) → handler.
|
|
57
58
|
*
|
|
58
59
|
* Returns a `Response` to short-circuit (resolution failure → 400 / 500),
|
|
@@ -138,12 +139,15 @@ export interface RouteSpec {
|
|
|
138
139
|
* overloaded `input: z.null()`, which otherwise can't distinguish "no
|
|
139
140
|
* body" (`GET /health`) from "raw bytes" (a binary upload).
|
|
140
141
|
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* `
|
|
144
|
-
*
|
|
145
|
-
* `
|
|
146
|
-
*
|
|
142
|
+
* A `raw_body` `POST` takes any `Content-Type` a browser can't send
|
|
143
|
+
* cross-origin without a preflight; every other `POST` route requires
|
|
144
|
+
* `application/json`, bodyless or not (415 `unsupported_content_type`
|
|
145
|
+
* otherwise — see `http/simple_request.ts`). The schema-driven round-trip
|
|
146
|
+
* test suite auto-skips `raw_body` routes (it can neither synthesize a
|
|
147
|
+
* meaningful body nor assert a JSON output shape), so consumers don't
|
|
148
|
+
* hand-maintain a `skip_routes` entry per binary route. Also surfaces in
|
|
149
|
+
* `AppSurfaceRoute` so generated docs render "raw" instead of a
|
|
150
|
+
* misleading `null` body.
|
|
147
151
|
*/
|
|
148
152
|
raw_body?: boolean;
|
|
149
153
|
/**
|
|
@@ -228,10 +232,13 @@ export declare const apply_middleware_specs: (app: Hono, specs: Array<Middleware
|
|
|
228
232
|
* validation, wraps with error catch layer (catches `ThrownJsonrpcError`
|
|
229
233
|
* and generic errors), and registers the route.
|
|
230
234
|
*
|
|
231
|
-
* Per-route middleware order:
|
|
232
|
-
* guards (401 + rule-3 scope) →
|
|
233
|
-
* post-authorization auth guards (403) → input
|
|
234
|
-
* handler.
|
|
235
|
+
* Per-route middleware order: content type (415, `POST` only) → params →
|
|
236
|
+
* query → pre-authorization auth guards (401 + rule-3 scope) →
|
|
237
|
+
* authorization phase → post-authorization auth guards (403) → input
|
|
238
|
+
* validation (400) → handler. The content type goes first because it says
|
|
239
|
+
* almost nothing about the route, and a forged request should be refused
|
|
240
|
+
* before any credential is read. Body
|
|
241
|
+
* validation runs behind every authority gate, so a caller
|
|
235
242
|
* any of them refuse never sees route-shape information from a parse
|
|
236
243
|
* failure — a 400 there would confirm the route exists and describe how
|
|
237
244
|
* to call it. Params and query still validate first (they address the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/route_spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAW,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACtE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"route_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/route_spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAW,IAAI,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACtE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAMjB,MAAM,oBAAoB,CAAC;AAU5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAA0C,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEzF;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,UAAU;IAC1B,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC5C,kBAAkB,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,SAAS,KAAK,UAAU,CAAC;AAEhE;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAE7F,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC5B;;;OAGG;IACH,EAAE,EAAE,EAAE,CAAC;IACP;;;;;OAKG;IACH,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;;;;;OAOG;IACH,mBAAmB,EAAE,KAAK,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACvD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE7F;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,mEAAmE;IACnE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxF,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC;AAK5D;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzF,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC;AAK7D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxF,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC;AAmL5D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,KAAK,IAAI,EAAE,OAAO,KAAK,CAAC,cAAc,CAAC,KAAG,IAIhF,CAAC;AAwFF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,iBAAiB,GAC7B,KAAK,IAAI,EACT,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,qBAAqB,iBAAiB,EACtC,KAAK,MAAM,EACX,IAAI,EAAE,EACN,YAAY,oBAAoB,KAC9B,IAsEF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,EAAE,OAAO,KAAK,CAAC,SAAS,CAAC,KAAG,KAAK,CAAC,SAAS,CAK3F,CAAC"}
|
package/dist/http/route_spec.js
CHANGED
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
* @module
|
|
14
14
|
*/
|
|
15
15
|
import { DEV } from 'esm-env';
|
|
16
|
-
import { ERROR_INVALID_JSON_BODY, ERROR_INVALID_REQUEST_BODY, ERROR_INVALID_ROUTE_PARAMS, ERROR_INVALID_QUERY_PARAMS } from './error_schemas.js';
|
|
16
|
+
import { ERROR_INVALID_JSON_BODY, ERROR_INVALID_REQUEST_BODY, ERROR_INVALID_ROUTE_PARAMS, ERROR_INVALID_QUERY_PARAMS, ERROR_UNSUPPORTED_CONTENT_TYPE } from './error_schemas.js';
|
|
17
|
+
import { is_post_content_type_refused } from './simple_request.js';
|
|
17
18
|
import { ThrownJsonrpcError, jsonrpc_error_code_to_http_status, jsonrpc_error_code_to_name, dev_only } from './jsonrpc_errors.js';
|
|
18
19
|
import { is_null_schema, merge_error_schemas } from './schema_helpers.js';
|
|
19
20
|
import { dispatch_with_post_commit_rollback } from './pending_effects.js';
|
|
@@ -27,6 +28,28 @@ export function get_route_params(c, _schema) {
|
|
|
27
28
|
export function get_route_query(c, _schema) {
|
|
28
29
|
return c.get('validated_query');
|
|
29
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Create the content-type check for a route spec: a `POST` whose
|
|
33
|
+
* `Content-Type` the route refuses (`is_post_content_type_refused` — anything
|
|
34
|
+
* but JSON, or for a `raw_body` route anything a browser sends cross-origin
|
|
35
|
+
* without a preflight) gets 415 before anything else on the route runs. The
|
|
36
|
+
* Rust spine's JSON handlers check the same, first thing after the origin.
|
|
37
|
+
*
|
|
38
|
+
* Returns an empty array for other methods, which are never CORS-simple and
|
|
39
|
+
* so always preflighted.
|
|
40
|
+
*/
|
|
41
|
+
const create_content_type_check = (spec) => {
|
|
42
|
+
if (spec.method !== 'POST')
|
|
43
|
+
return [];
|
|
44
|
+
const raw_body = spec.raw_body ?? false;
|
|
45
|
+
const check = async (c, next) => {
|
|
46
|
+
if (is_post_content_type_refused(c.req.header('content-type'), raw_body)) {
|
|
47
|
+
return c.json({ error: ERROR_UNSUPPORTED_CONTENT_TYPE }, 415);
|
|
48
|
+
}
|
|
49
|
+
await next();
|
|
50
|
+
};
|
|
51
|
+
return [check];
|
|
52
|
+
};
|
|
30
53
|
/**
|
|
31
54
|
* Create input validation middleware for a route spec.
|
|
32
55
|
*
|
|
@@ -266,10 +289,13 @@ const build_rest_error_body = (err) => {
|
|
|
266
289
|
* validation, wraps with error catch layer (catches `ThrownJsonrpcError`
|
|
267
290
|
* and generic errors), and registers the route.
|
|
268
291
|
*
|
|
269
|
-
* Per-route middleware order:
|
|
270
|
-
* guards (401 + rule-3 scope) →
|
|
271
|
-
* post-authorization auth guards (403) → input
|
|
272
|
-
* handler.
|
|
292
|
+
* Per-route middleware order: content type (415, `POST` only) → params →
|
|
293
|
+
* query → pre-authorization auth guards (401 + rule-3 scope) →
|
|
294
|
+
* authorization phase → post-authorization auth guards (403) → input
|
|
295
|
+
* validation (400) → handler. The content type goes first because it says
|
|
296
|
+
* almost nothing about the route, and a forged request should be refused
|
|
297
|
+
* before any credential is read. Body
|
|
298
|
+
* validation runs behind every authority gate, so a caller
|
|
273
299
|
* any of them refuse never sees route-shape information from a parse
|
|
274
300
|
* failure — a 400 there would confirm the route exists and describe how
|
|
275
301
|
* to call it. Params and query still validate first (they address the
|
|
@@ -304,6 +330,7 @@ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db, auth
|
|
|
304
330
|
registered.add(route_key);
|
|
305
331
|
assert_route_auth_acting_biconditional(spec.auth, { input: spec.input, query: spec.query }, `Route "${route_key}"`);
|
|
306
332
|
const { pre_authorization: pre_authorization_guards, post_authorization: post_authorization_guards } = resolve_auth_guards(spec.auth);
|
|
333
|
+
const content_type_check = create_content_type_check(spec);
|
|
307
334
|
const params_validation = create_params_validation(spec.params);
|
|
308
335
|
const query_validation = create_query_validation(spec.query);
|
|
309
336
|
const input_validation = create_input_validation(spec.input, spec.method);
|
|
@@ -340,7 +367,7 @@ export const apply_route_specs = (app, specs, resolve_auth_guards, log, db, auth
|
|
|
340
367
|
handler = wrap_output_validation(handler, spec.output, merged_errors, log);
|
|
341
368
|
// Step 3: error catch layer
|
|
342
369
|
handler = wrap_error_catch(handler, log);
|
|
343
|
-
app.on(spec.method, [spec.path], ...params_validation, ...query_validation, ...pre_authorization_guards, ...authorization, ...post_authorization_guards, ...input_validation, handler);
|
|
370
|
+
app.on(spec.method, [spec.path], ...content_type_check, ...params_validation, ...query_validation, ...pre_authorization_guards, ...authorization, ...post_authorization_guards, ...input_validation, handler);
|
|
344
371
|
}
|
|
345
372
|
};
|
|
346
373
|
/**
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import type { RouteAuth } from './auth_shape.js';
|
|
12
|
+
import type { RouteMethod } from './route_spec.js';
|
|
12
13
|
import { type RateLimitKey, type RouteErrorSchemas } from './error_schemas.js';
|
|
13
14
|
/**
|
|
14
15
|
* Check if a schema is exactly `z.null()`.
|
|
@@ -111,11 +112,12 @@ export declare const middleware_applies: (mw_path: string, route_path: string) =
|
|
|
111
112
|
* Merge order: derived -> middleware -> explicit route errors.
|
|
112
113
|
* Later layers override earlier ones for the same status code.
|
|
113
114
|
*
|
|
114
|
-
* @param spec - the route spec (
|
|
115
|
+
* @param spec - the route spec (reads `method`, `auth`, `input`, `params`, `query`, `rate_limit`, `errors`)
|
|
115
116
|
* @param middleware_errors - errors contributed by middleware whose path matches the route
|
|
116
117
|
* @returns merged error schemas, or `null` if empty
|
|
117
118
|
*/
|
|
118
119
|
export declare const merge_error_schemas: (spec: {
|
|
120
|
+
method: RouteMethod;
|
|
119
121
|
auth: RouteAuth;
|
|
120
122
|
input: z.ZodType;
|
|
121
123
|
params?: z.ZodObject;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,GAAI,YAAY,OAAO,KAAG,OAUpD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,CAAC,CAAC,OAAO,EAAE,YAAY,OAAO,KAAG,OACA,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gCAAgC,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EACnE,QAAQ,CAAC,EACT,OAAO,OAAO,KACZ,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAclC,CAAC;AAWF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQrD,CAAC;AAoBF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,
|
|
1
|
+
{"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,GAAI,YAAY,OAAO,KAAG,OAUpD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,CAAC,CAAC,OAAO,EAAE,YAAY,OAAO,KAAG,OACA,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gCAAgC,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EACnE,QAAQ,CAAC,EACT,OAAO,OAAO,KACZ,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAclC,CAAC;AAWF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQrD,CAAC;AAoBF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAWtB,CAAC"}
|
|
@@ -185,7 +185,7 @@ export const middleware_applies = (mw_path, route_path) => {
|
|
|
185
185
|
* Merge order: derived -> middleware -> explicit route errors.
|
|
186
186
|
* Later layers override earlier ones for the same status code.
|
|
187
187
|
*
|
|
188
|
-
* @param spec - the route spec (
|
|
188
|
+
* @param spec - the route spec (reads `method`, `auth`, `input`, `params`, `query`, `rate_limit`, `errors`)
|
|
189
189
|
* @param middleware_errors - errors contributed by middleware whose path matches the route
|
|
190
190
|
* @returns merged error schemas, or `null` if empty
|
|
191
191
|
*/
|
|
@@ -195,7 +195,8 @@ export const merge_error_schemas = (spec, middleware_errors) => {
|
|
|
195
195
|
has_input: !is_null_schema(spec.input),
|
|
196
196
|
has_params: !!spec.params,
|
|
197
197
|
has_query: !!spec.query,
|
|
198
|
-
rate_limit: spec.rate_limit
|
|
198
|
+
rate_limit: spec.rate_limit,
|
|
199
|
+
checks_content_type: spec.method === 'POST'
|
|
199
200
|
});
|
|
200
201
|
const merged = { ...derived, ...middleware_errors, ...spec.errors };
|
|
201
202
|
return Object.keys(merged).length > 0 ? merged : null;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusing CORS simple requests — the cross-origin POSTs a browser sends
|
|
3
|
+
* without asking first.
|
|
4
|
+
*
|
|
5
|
+
* A cross-origin `fetch` or form `POST` skips the CORS preflight when its
|
|
6
|
+
* `Content-Type` is absent or one of the three CORS-safelisted types
|
|
7
|
+
* (`text/plain`, `application/x-www-form-urlencoded`, `multipart/form-data`).
|
|
8
|
+
* The browser sends such a request as-is, with whatever cookies apply — only
|
|
9
|
+
* the response is withheld from the page. Any other content type makes the
|
|
10
|
+
* browser send an `OPTIONS` preflight first, and since fuz_app answers no
|
|
11
|
+
* preflight with CORS headers, the real request is never sent.
|
|
12
|
+
*
|
|
13
|
+
* The session cookie's `SameSite=Strict` doesn't close this on its own:
|
|
14
|
+
* same-site ignores the port, so a page on `http://localhost:8000` is
|
|
15
|
+
* same-site with a server on `http://localhost:4460` and its requests carry
|
|
16
|
+
* the cookie. The origin allowlist (`http/origin.ts`) refuses such a page
|
|
17
|
+
* unless a wildcard (`http://localhost:*`) admits it; this gate refuses it
|
|
18
|
+
* whatever the allowlist says.
|
|
19
|
+
*
|
|
20
|
+
* So every `POST` route carries a content-type check, run first by
|
|
21
|
+
* `apply_route_specs` (`is_post_content_type_refused`, 415
|
|
22
|
+
* `unsupported_content_type`): a JSON route takes only `application/json`,
|
|
23
|
+
* bodyless or not, and a `raw_body` route takes any type that isn't
|
|
24
|
+
* safelisted. Only `POST` needs it: `PUT`, `PATCH`, and `DELETE` are never
|
|
25
|
+
* simple methods, so the browser always preflights them.
|
|
26
|
+
*
|
|
27
|
+
* The check rests on the server answering no preflight. A consumer that adds
|
|
28
|
+
* CORS middleware granting cross-origin requests reopens what this closes.
|
|
29
|
+
*
|
|
30
|
+
* Twin of the Rust spine's `fuz_http::simple_request`: the same predicates,
|
|
31
|
+
* `is_json_content_type` checked in each spine JSON handler and
|
|
32
|
+
* `is_cors_simple_content_type` by the `simple_request_layer` consumers mount
|
|
33
|
+
* over routes with other bodies.
|
|
34
|
+
*
|
|
35
|
+
* @module
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* True when a browser could have sent a `POST` with this `Content-Type`
|
|
39
|
+
* cross-origin without a preflight: none, or a CORS-safelisted one.
|
|
40
|
+
*
|
|
41
|
+
* Matches more than browsers do (a value they'd refuse to call safelisted —
|
|
42
|
+
* one with odd bytes, say — counts as safelisted here), so it only ever
|
|
43
|
+
* refuses too much, never too little.
|
|
44
|
+
*
|
|
45
|
+
* @param content_type - the request's `Content-Type` header, if any
|
|
46
|
+
*/
|
|
47
|
+
export declare const is_cors_simple_content_type: (content_type: string | undefined) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* True when `Content-Type` is `application/json` (any parameters, such as
|
|
50
|
+
* `charset`, allowed).
|
|
51
|
+
*
|
|
52
|
+
* @param content_type - the request's `Content-Type` header, if any
|
|
53
|
+
*/
|
|
54
|
+
export declare const is_json_content_type: (content_type: string | undefined) => boolean;
|
|
55
|
+
/**
|
|
56
|
+
* True when a `POST` route refuses this `Content-Type`: a JSON route anything
|
|
57
|
+
* but `application/json`, a `raw_body` route a CORS-safelisted type or none.
|
|
58
|
+
*
|
|
59
|
+
* @param content_type - the request's `Content-Type` header, if any
|
|
60
|
+
* @param raw_body - the route's `RouteSpec.raw_body`
|
|
61
|
+
*/
|
|
62
|
+
export declare const is_post_content_type_refused: (content_type: string | undefined, raw_body: boolean) => boolean;
|
|
63
|
+
//# sourceMappingURL=simple_request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple_request.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/simple_request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAqBH;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,GAAI,cAAc,MAAM,GAAG,SAAS,KAAG,OAI9E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,GAAG,SAAS,KAAG,OACmB,CAAC;AAE5F;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,cAAc,MAAM,GAAG,SAAS,EAChC,UAAU,OAAO,KACf,OACwF,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusing CORS simple requests — the cross-origin POSTs a browser sends
|
|
3
|
+
* without asking first.
|
|
4
|
+
*
|
|
5
|
+
* A cross-origin `fetch` or form `POST` skips the CORS preflight when its
|
|
6
|
+
* `Content-Type` is absent or one of the three CORS-safelisted types
|
|
7
|
+
* (`text/plain`, `application/x-www-form-urlencoded`, `multipart/form-data`).
|
|
8
|
+
* The browser sends such a request as-is, with whatever cookies apply — only
|
|
9
|
+
* the response is withheld from the page. Any other content type makes the
|
|
10
|
+
* browser send an `OPTIONS` preflight first, and since fuz_app answers no
|
|
11
|
+
* preflight with CORS headers, the real request is never sent.
|
|
12
|
+
*
|
|
13
|
+
* The session cookie's `SameSite=Strict` doesn't close this on its own:
|
|
14
|
+
* same-site ignores the port, so a page on `http://localhost:8000` is
|
|
15
|
+
* same-site with a server on `http://localhost:4460` and its requests carry
|
|
16
|
+
* the cookie. The origin allowlist (`http/origin.ts`) refuses such a page
|
|
17
|
+
* unless a wildcard (`http://localhost:*`) admits it; this gate refuses it
|
|
18
|
+
* whatever the allowlist says.
|
|
19
|
+
*
|
|
20
|
+
* So every `POST` route carries a content-type check, run first by
|
|
21
|
+
* `apply_route_specs` (`is_post_content_type_refused`, 415
|
|
22
|
+
* `unsupported_content_type`): a JSON route takes only `application/json`,
|
|
23
|
+
* bodyless or not, and a `raw_body` route takes any type that isn't
|
|
24
|
+
* safelisted. Only `POST` needs it: `PUT`, `PATCH`, and `DELETE` are never
|
|
25
|
+
* simple methods, so the browser always preflights them.
|
|
26
|
+
*
|
|
27
|
+
* The check rests on the server answering no preflight. A consumer that adds
|
|
28
|
+
* CORS middleware granting cross-origin requests reopens what this closes.
|
|
29
|
+
*
|
|
30
|
+
* Twin of the Rust spine's `fuz_http::simple_request`: the same predicates,
|
|
31
|
+
* `is_json_content_type` checked in each spine JSON handler and
|
|
32
|
+
* `is_cors_simple_content_type` by the `simple_request_layer` consumers mount
|
|
33
|
+
* over routes with other bodies.
|
|
34
|
+
*
|
|
35
|
+
* @module
|
|
36
|
+
*/
|
|
37
|
+
/** The content types a browser sends cross-origin without a preflight. */
|
|
38
|
+
const CORS_SAFELISTED_CONTENT_TYPES = new Set([
|
|
39
|
+
'text/plain',
|
|
40
|
+
'application/x-www-form-urlencoded',
|
|
41
|
+
'multipart/form-data'
|
|
42
|
+
]);
|
|
43
|
+
/** Any character outside visible ASCII and tab — what Rust's `HeaderValue::to_str` refuses. */
|
|
44
|
+
const NON_VISIBLE_ASCII = /[^\t\x20-\x7e]/;
|
|
45
|
+
/**
|
|
46
|
+
* The MIME essence (`type/subtype`, lowercased, parameters dropped) of a
|
|
47
|
+
* `Content-Type` value, or `null` when it holds anything but visible ASCII.
|
|
48
|
+
*/
|
|
49
|
+
const to_content_type_essence = (content_type) => {
|
|
50
|
+
if (NON_VISIBLE_ASCII.test(content_type))
|
|
51
|
+
return null;
|
|
52
|
+
return (content_type.split(';')[0] ?? '').trim().toLowerCase();
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* True when a browser could have sent a `POST` with this `Content-Type`
|
|
56
|
+
* cross-origin without a preflight: none, or a CORS-safelisted one.
|
|
57
|
+
*
|
|
58
|
+
* Matches more than browsers do (a value they'd refuse to call safelisted —
|
|
59
|
+
* one with odd bytes, say — counts as safelisted here), so it only ever
|
|
60
|
+
* refuses too much, never too little.
|
|
61
|
+
*
|
|
62
|
+
* @param content_type - the request's `Content-Type` header, if any
|
|
63
|
+
*/
|
|
64
|
+
export const is_cors_simple_content_type = (content_type) => {
|
|
65
|
+
if (content_type === undefined)
|
|
66
|
+
return true;
|
|
67
|
+
const essence = to_content_type_essence(content_type);
|
|
68
|
+
return essence === null || CORS_SAFELISTED_CONTENT_TYPES.has(essence);
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* True when `Content-Type` is `application/json` (any parameters, such as
|
|
72
|
+
* `charset`, allowed).
|
|
73
|
+
*
|
|
74
|
+
* @param content_type - the request's `Content-Type` header, if any
|
|
75
|
+
*/
|
|
76
|
+
export const is_json_content_type = (content_type) => content_type !== undefined && to_content_type_essence(content_type) === 'application/json';
|
|
77
|
+
/**
|
|
78
|
+
* True when a `POST` route refuses this `Content-Type`: a JSON route anything
|
|
79
|
+
* but `application/json`, a `raw_body` route a CORS-safelisted type or none.
|
|
80
|
+
*
|
|
81
|
+
* @param content_type - the request's `Content-Type` header, if any
|
|
82
|
+
* @param raw_body - the route's `RouteSpec.raw_body`
|
|
83
|
+
*/
|
|
84
|
+
export const is_post_content_type_refused = (content_type, raw_body) => raw_body ? is_cors_simple_content_type(content_type) : !is_json_content_type(content_type);
|
package/dist/http/surface.js
CHANGED
package/dist/realtime/sse.js
CHANGED
|
@@ -63,13 +63,13 @@ export interface BootstrapDisabledOptions {
|
|
|
63
63
|
}
|
|
64
64
|
export interface BootstrapSurfaceOnlyOptions {
|
|
65
65
|
mode: 'surface_only';
|
|
66
|
-
/** Route prefix for surface generation. Default `'/api/account'
|
|
66
|
+
/** Route prefix for surface generation. Default `'/api/account'`; must sit under `/api/`. */
|
|
67
67
|
route_prefix?: string;
|
|
68
68
|
}
|
|
69
69
|
export interface BootstrapLiveOptions {
|
|
70
70
|
mode: 'live';
|
|
71
71
|
token_path: string;
|
|
72
|
-
/** Route prefix for bootstrap routes. Default `'/api/account'
|
|
72
|
+
/** Route prefix for bootstrap routes. Default `'/api/account'`; must sit under `/api/`. */
|
|
73
73
|
route_prefix?: string;
|
|
74
74
|
/**
|
|
75
75
|
* Called after successful bootstrap (account + session created).
|
|
@@ -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;AAGxB,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAIN,KAAK,WAAW,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACN,WAAW,EAMX,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEhF,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAGN,KAAK,eAAe,EACpB,MAAM,6BAA6B,CAAC;AAarC,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAsB,KAAK,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAEzF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,sBAAsB,GACjC,wBAAwB,GAAG,2BAA2B,GAAG,oBAAoB,CAAC;AAE/E,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,EAAE,cAAc,CAAC;IACrB,
|
|
1
|
+
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
import { Hono } from 'hono';
|
|
11
11
|
import { logger } from 'hono/logger';
|
|
12
12
|
import { bodyLimit } from 'hono/body-limit';
|
|
13
|
-
import { z } from 'zod';
|
|
14
13
|
import { session_cookie_options } from '../auth/session_cookie.js';
|
|
15
14
|
import { create_audit_log_sse, create_sse_connection_closer, audit_log_event_specs } from '../realtime/sse_auth_guard.js';
|
|
16
15
|
import { BaseServerEnv } from './env.js';
|
|
@@ -333,7 +332,11 @@ const assemble_app_server = async (options, releases) => {
|
|
|
333
332
|
bootstrap_ip_rate_limiter
|
|
334
333
|
});
|
|
335
334
|
const prefix = options.bootstrap.route_prefix ?? '/api/account';
|
|
336
|
-
|
|
335
|
+
const prefixed = prefix_route_specs(prefix, bootstrap_routes);
|
|
336
|
+
for (const route of prefixed) {
|
|
337
|
+
assert_endpoint_in_auth_scope('bootstrap.route_prefix', route.path);
|
|
338
|
+
}
|
|
339
|
+
factory_routes.push(...prefixed);
|
|
337
340
|
}
|
|
338
341
|
// RPC endpoint auto-mount — resolve specs then append their routes so
|
|
339
342
|
// surface generation and live dispatch share one source of truth.
|
package/dist/testing/CLAUDE.md
CHANGED
|
@@ -1564,6 +1564,22 @@ in-process `auth/origin_parity.db.test.ts` + the cross-process
|
|
|
1564
1564
|
Rust spine returned a plain-text body — now converged to the canonical TS
|
|
1565
1565
|
`{error: "forbidden_origin"}` via `fuz_http::forbidden_origin_response()`.
|
|
1566
1566
|
|
|
1567
|
+
### CORS simple-request parity — `cross_backend/simple_request.ts`
|
|
1568
|
+
|
|
1569
|
+
`describe_simple_request_cross_tests({setup_test, rpc_path?, login_path?, logout_path?})`
|
|
1570
|
+
— a JSON route refuses any `POST` that isn't `application/json` with a flat
|
|
1571
|
+
415 `{error: 'unsupported_content_type'}` before reading a credential or the
|
|
1572
|
+
body: the CORS-safelisted types in any spelling (`text/plain`, `Text/Plain`,
|
|
1573
|
+
form-encoded, multipart) on RPC with a session, untyped RPC (a byte body, so
|
|
1574
|
+
`fetch` adds no type), `application/octet-stream` / `+json` / empty-typed RPC
|
|
1575
|
+
and login, form-encoded login, a forged `text/plain` logout with a session
|
|
1576
|
+
(which must leave the session valid), and an untyped logout with no session
|
|
1577
|
+
(415, not 401); a bodyless JSON logout reaches the auth check (401), and
|
|
1578
|
+
`application/json` with a charset is dispatched. The TS spine checks per route
|
|
1579
|
+
(`apply_route_specs`), the Rust spine in each JSON handler. Runs both legs:
|
|
1580
|
+
the in-process `auth/simple_request_parity.db.test.ts` and the cross-process
|
|
1581
|
+
`simple_request.cross.test.ts`.
|
|
1582
|
+
|
|
1567
1583
|
### Query-string shape parity — `cross_backend/query_shape.ts`
|
|
1568
1584
|
|
|
1569
1585
|
`describe_query_shape_cross_tests({setup_test, capabilities, rpc_path?})` —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAYvE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,
|
|
1
|
+
{"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAYvE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAm5BF,CAAC"}
|
|
@@ -595,7 +595,8 @@ export const describe_standard_admin_integration_tests = (options) => {
|
|
|
595
595
|
headers: {
|
|
596
596
|
host: 'localhost',
|
|
597
597
|
origin: 'http://localhost:5173',
|
|
598
|
-
cookie: `${cookie_name}=${user_two_cookie}
|
|
598
|
+
cookie: `${cookie_name}=${user_two_cookie}`,
|
|
599
|
+
'content-type': 'application/json'
|
|
599
600
|
}
|
|
600
601
|
});
|
|
601
602
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,EAQN,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAsDpF,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,sBAAsB,KAAG,
|
|
1
|
+
{"version":3,"file":"attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,EAQN,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAsDpF,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,sBAAsB,KAAG,IA6J3E,CAAC;AAIF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uCAAuC,GACnD,UAAU,2BAA2B,GAAG,IAAI,GAAG,SAAS,KACtD,2BAA2B,GAAG,IAWhC,CAAC;AAEF,0DAA0D;AAC1D,MAAM,WAAW,4BAA4B;IAC5C,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,iIAAiI;IACjI,uBAAuB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,eAAe,CAAC,EAAE,4BAA4B,CAAC;IAC/C;;;;;;;;;;;OAWG;IACH,sBAAsB,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC5D;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sCAAsC,GAClD,SAAS,4BAA4B,KACnC,IA4EF,CAAC"}
|