@fuzdev/fuz_app 0.128.0 → 0.129.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/register_action_ws.d.ts +0 -1
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/auth/CLAUDE.md +1 -1
- package/dist/auth/actor_lookup_action_specs.d.ts +2 -2
- package/dist/auth/actor_lookup_action_specs.js +2 -2
- package/dist/auth/audit_emitter.d.ts +14 -7
- package/dist/auth/audit_emitter.d.ts.map +1 -1
- package/dist/auth/audit_emitter.js +6 -8
- package/dist/auth/bearer_auth.d.ts +3 -2
- package/dist/auth/bearer_auth.d.ts.map +1 -1
- package/dist/auth/bearer_auth.js +3 -2
- package/dist/auth/request_context.d.ts +1 -1
- package/dist/auth/request_context.js +1 -1
- package/dist/auth/token_scope.d.ts +4 -2
- package/dist/auth/token_scope.d.ts.map +1 -1
- package/dist/auth/token_scope.js +10 -2
- package/dist/http/CLAUDE.md +3 -4
- package/dist/http/auth_shape.d.ts +3 -2
- package/dist/http/auth_shape.d.ts.map +1 -1
- package/dist/http/auth_shape.js +3 -2
- package/dist/http/common_routes.d.ts +1 -14
- package/dist/http/common_routes.d.ts.map +1 -1
- package/dist/http/common_routes.js +1 -19
- package/dist/http/ip_canonical.d.ts +1 -1
- package/dist/http/ip_canonical.js +1 -1
- package/dist/realtime/sse_auth_guard.d.ts +3 -1
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
- package/dist/realtime/sse_auth_guard.js +3 -1
- package/dist/server/app_server.d.ts +118 -7
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +136 -91
- package/dist/server/surface_route.d.ts +32 -0
- package/dist/server/surface_route.d.ts.map +1 -0
- package/dist/server/surface_route.js +46 -0
- package/dist/testing/CLAUDE.md +17 -12
- package/dist/testing/app_server.d.ts +39 -4
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +84 -68
- package/dist/testing/audit_completeness.js +1 -1
- package/dist/testing/audit_drift_guard.d.ts +1 -1
- package/dist/testing/cross_backend/default_spine_surface.d.ts +2 -2
- package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_spine_surface.js +5 -2
- package/dist/testing/cross_backend/identity_parity.js +1 -1
- package/dist/testing/cross_backend/in_process_setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/in_process_setup.js +4 -1
- package/dist/testing/cross_backend/method_coverage.d.ts +1 -1
- package/dist/testing/cross_backend/method_coverage.d.ts.map +1 -1
- package/dist/testing/cross_backend/method_coverage.js +2 -2
- package/dist/testing/cross_backend/peer_ping_ws.d.ts +1 -1
- package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +1 -1
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/setup.d.ts +4 -4
- package/dist/testing/cross_backend/setup.js +1 -1
- package/dist/testing/cross_backend/sse_round_trip.d.ts +1 -1
- package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +24 -14
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +40 -32
- package/dist/testing/cross_backend/testing_server_bun.d.ts +1 -1
- package/dist/testing/cross_backend/testing_server_bun.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_server_bun.js +80 -64
- package/dist/testing/cross_backend/testing_server_core.d.ts +10 -4
- package/dist/testing/cross_backend/testing_server_core.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_server_deno.d.ts +1 -1
- package/dist/testing/cross_backend/testing_server_deno.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_server_deno.js +1 -1
- package/dist/testing/cross_backend/testing_server_node.d.ts +1 -1
- package/dist/testing/cross_backend/testing_server_node.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_server_node.js +2 -2
- package/dist/testing/cross_backend/ws_round_trip.d.ts +1 -1
- package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_round_trip.js +11 -9
- package/dist/testing/stubs.d.ts +45 -7
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +60 -31
- package/dist/testing/ws_round_trip.d.ts +1 -3
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/ui/AdminSurface.svelte +3 -1
- package/dist/ui/AdminSurface.svelte.d.ts.map +1 -1
- package/dist/ui/CLAUDE.md +3 -1
- package/dist/ui/async_slot.svelte.d.ts +4 -4
- package/dist/ui/async_slot.svelte.js +4 -4
- package/dist/ui/keyed_async_slot.svelte.d.ts +4 -4
- package/dist/ui/keyed_async_slot.svelte.js +3 -3
- package/package.json +1 -1
|
@@ -95,7 +95,6 @@ import type { Db } from '../db/db.js';
|
|
|
95
95
|
import { type Action } from './action_types.js';
|
|
96
96
|
import type { RealtimeCloser } from './connection_closer.js';
|
|
97
97
|
import { BackendWebsocketTransport, type ConnectionIdentity } from './transports_ws_backend.js';
|
|
98
|
-
export type { Action };
|
|
99
98
|
/** Default inactivity window before the server closes a silent socket. */
|
|
100
99
|
export declare const DEFAULT_SERVER_HEARTBEAT_TIMEOUT = 60000;
|
|
101
100
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAE3D,OAAO,EAAU,KAAK,MAAM,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAWnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAmBtD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAa7D,OAAO,EAAE,yBAAyB,EAAE,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAIhG,
|
|
1
|
+
{"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/CLAUDE.md
CHANGED
|
@@ -124,7 +124,7 @@ upstream in `auth/signup_routes.ts` via `query_invite_find_unclaimed_match_for_u
|
|
|
124
124
|
its registered listeners + optional `AuditLogConfig`. Its methods:
|
|
125
125
|
|
|
126
126
|
- `emit(ctx, input)` — fire-and-forget pool write, pushes to `ctx.pending_effects`; a success row's listener fan-out goes on `ctx.post_commit_effects`
|
|
127
|
-
- `emit_role_grant_target(ctx, auth, input)` — lifts `actor_id` / `account_id` / `ip` boilerplate for role-grant-shape events
|
|
127
|
+
- `emit_role_grant_target(ctx, auth, input)` — lifts `actor_id` / `account_id` / `ip` boilerplate for role-grant-shape events; `input` is an `AuditEmitRoleGrantInput`
|
|
128
128
|
- `emit_pool(input)` — awaitable pool write for code paths without a request context (ad-hoc maintenance scripts; not for success audits paired with a mutation — those write in-tx and `notify` post-commit). Writes, then notifies, whatever the outcome
|
|
129
129
|
- `notify(event)` — fan out an already-written row to listeners (used by in-tx audit batches like `query_accept_offer.audit_events`)
|
|
130
130
|
- `add_listener(listener)` — listener registration, returning a remover for that registration (idempotent; the same function registered twice is two registrations, each with its own remover). Twin of Rust `fuz_auth` `AuditEmitter::add_listener` in firing order and snapshot-at-notify
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Account-grain — only that the caller is signed in matters, not which
|
|
13
13
|
* actor is calling, so resolution skips the actor phase. The auth gate
|
|
14
14
|
* + per-account rate limit (default 1200/15min) + the
|
|
15
|
-
*
|
|
15
|
+
* per-call cap (`ACTOR_LOOKUP_IDS_MAX`) bound the batched
|
|
16
16
|
* username-enumeration surface that the `cell_list` ↔ `actor_lookup`
|
|
17
17
|
* pair would otherwise present.
|
|
18
18
|
*
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* ids), bounded by:
|
|
39
39
|
*
|
|
40
40
|
* 1. rate-limit (per-account, see above),
|
|
41
|
-
* 2.
|
|
41
|
+
* 2. `ACTOR_LOOKUP_IDS_MAX` cap per call,
|
|
42
42
|
* 3. actor-uuid intractability (122-bit random),
|
|
43
43
|
* 4. hard-deleted actors are indistinguishable from never-existed (no
|
|
44
44
|
* tombstone oracle — see `auth/actor_lookup_queries.ts`).
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Account-grain — only that the caller is signed in matters, not which
|
|
13
13
|
* actor is calling, so resolution skips the actor phase. The auth gate
|
|
14
14
|
* + per-account rate limit (default 1200/15min) + the
|
|
15
|
-
*
|
|
15
|
+
* per-call cap (`ACTOR_LOOKUP_IDS_MAX`) bound the batched
|
|
16
16
|
* username-enumeration surface that the `cell_list` ↔ `actor_lookup`
|
|
17
17
|
* pair would otherwise present.
|
|
18
18
|
*
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* ids), bounded by:
|
|
39
39
|
*
|
|
40
40
|
* 1. rate-limit (per-account, see above),
|
|
41
|
-
* 2.
|
|
41
|
+
* 2. `ACTOR_LOOKUP_IDS_MAX` cap per call,
|
|
42
42
|
* 3. actor-uuid intractability (122-bit random),
|
|
43
43
|
* 4. hard-deleted actors are indistinguishable from never-existed (no
|
|
44
44
|
* tombstone oracle — see `auth/actor_lookup_queries.ts`).
|
|
@@ -102,6 +102,19 @@ export interface AuditEmitRoleGrantContext extends AuditEmitterContext {
|
|
|
102
102
|
/** Resolved client IP from the trusted-proxy middleware — `'unknown'` if not resolved. */
|
|
103
103
|
client_ip: string;
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Input to `AuditEmitter.emit_role_grant_target` — the event fields that
|
|
107
|
+
* vary per call site; `actor_id`, `account_id`, and `ip` are lifted from
|
|
108
|
+
* the auth and request contexts.
|
|
109
|
+
*/
|
|
110
|
+
export interface AuditEmitRoleGrantInput<T extends string> {
|
|
111
|
+
event_type: T;
|
|
112
|
+
target_account_id: Uuid | null;
|
|
113
|
+
target_actor_id: Uuid | null;
|
|
114
|
+
metadata: AuditLogInput<T>['metadata'];
|
|
115
|
+
/** Default `'success'`, as for `emit`. */
|
|
116
|
+
outcome?: 'success' | 'failure';
|
|
117
|
+
}
|
|
105
118
|
/**
|
|
106
119
|
* Bound audit-emit capability. Built once at backend assembly via
|
|
107
120
|
* `create_audit_emitter`; lives on `AppDeps.audit` so factories never see
|
|
@@ -137,13 +150,7 @@ export interface AuditEmitter {
|
|
|
137
150
|
* Reach for the lower-level `emit` only when the event is non-role-grant
|
|
138
151
|
* shape (e.g. `app_settings_update`, bootstrap, signup).
|
|
139
152
|
*/
|
|
140
|
-
emit_role_grant_target<T extends string>(ctx: AuditEmitRoleGrantContext, auth: RequestActorContext, input:
|
|
141
|
-
event_type: T;
|
|
142
|
-
target_account_id: Uuid | null;
|
|
143
|
-
target_actor_id: Uuid | null;
|
|
144
|
-
metadata: AuditLogInput<T>['metadata'];
|
|
145
|
-
outcome?: 'success' | 'failure';
|
|
146
|
-
}): void;
|
|
153
|
+
emit_role_grant_target<T extends string>(ctx: AuditEmitRoleGrantContext, auth: RequestActorContext, input: AuditEmitRoleGrantInput<T>): void;
|
|
147
154
|
/**
|
|
148
155
|
* Awaitable pool write for code paths without a request context.
|
|
149
156
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit_emitter.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IAClE,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACrE,0FAA0F;IAC1F,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"audit_emitter.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_emitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -187,16 +187,14 @@ export const create_audit_emitter = (options) => {
|
|
|
187
187
|
};
|
|
188
188
|
const listener_count = () => listeners.length;
|
|
189
189
|
// Freeze the slot layout so consumers cannot hot-patch `emit` /
|
|
190
|
-
// `emit_role_grant_target` / `emit_pool` / `notify` after construction
|
|
191
|
-
//
|
|
192
|
-
// and only happened to work because the four slots were writable —
|
|
190
|
+
// `emit_role_grant_target` / `emit_pool` / `notify` after construction —
|
|
191
|
+
// a patched `emit` would miss role-grant-shape emits anyway, since
|
|
193
192
|
// `emit_role_grant_target` calls the closed-over inner `emit`, not
|
|
194
|
-
// `this.emit
|
|
195
|
-
//
|
|
196
|
-
// is captured by the closure before the freeze. The listener list stays
|
|
193
|
+
// `this.emit`. Tests that need instrumentation pass `emit_decorator` so the
|
|
194
|
+
// wrap is captured by the closure before the freeze. The listener list stays
|
|
197
195
|
// closure-private; it changes only through `add_listener` and the remover
|
|
198
|
-
// it returns (`create_app_server` registers its SSE + WS listeners
|
|
199
|
-
//
|
|
196
|
+
// it returns (`create_app_server` registers its SSE + WS listeners after
|
|
197
|
+
// the emitter is built, by design, and removes them on close).
|
|
200
198
|
return Object.freeze({
|
|
201
199
|
emit,
|
|
202
200
|
emit_role_grant_target,
|
|
@@ -28,8 +28,9 @@ import type { QueryDeps } from '../db/query_deps.js';
|
|
|
28
28
|
* (`invalid_token`, `account_not_found`) that could aid enumeration attacks,
|
|
29
29
|
* and ensures public actions are not blocked by bad credentials.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* Discards bearer tokens when an `Origin` or `Referer` header is present —
|
|
32
|
+
* `next()` with no identity, as for a bad token — so browsers must use cookie
|
|
33
|
+
* auth, reducing attack surface.
|
|
33
34
|
* Auth scheme matching is case-insensitive per RFC 7235.
|
|
34
35
|
* On success, sets `c.var.auth_account_id`, `CREDENTIAL_TYPE_KEY = 'api_token'`,
|
|
35
36
|
* and `AUTH_API_TOKEN_ID_KEY`. Skips when an account is already authenticated
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bearer_auth.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bearer_auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAUtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD
|
|
1
|
+
{"version":3,"file":"bearer_auth.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bearer_auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAUtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,6BAA6B,GAAI,MAAM,SAAS,EAAE,KAAK,MAAM,KAAG,iBAuE5E,CAAC"}
|
package/dist/auth/bearer_auth.js
CHANGED
|
@@ -31,8 +31,9 @@ import { is_browser_context } from '../http/origin.js';
|
|
|
31
31
|
* (`invalid_token`, `account_not_found`) that could aid enumeration attacks,
|
|
32
32
|
* and ensures public actions are not blocked by bad credentials.
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* Discards bearer tokens when an `Origin` or `Referer` header is present —
|
|
35
|
+
* `next()` with no identity, as for a bad token — so browsers must use cookie
|
|
36
|
+
* auth, reducing attack surface.
|
|
36
37
|
* Auth scheme matching is case-insensitive per RFC 7235.
|
|
37
38
|
* On success, sets `c.var.auth_account_id`, `CREDENTIAL_TYPE_KEY = 'api_token'`,
|
|
38
39
|
* and `AUTH_API_TOKEN_ID_KEY`. Skips when an account is already authenticated
|
|
@@ -251,7 +251,7 @@ export declare const create_request_context_middleware: (deps: QueryDeps, sessio
|
|
|
251
251
|
* across route-spec declarations and direct calls alike, and the twin of the
|
|
252
252
|
* Rust signature. It needs no parse: the surface arm's identifier is pure label,
|
|
253
253
|
* since rule 3 never asks *which* surface. And it is deliberately not narrowed
|
|
254
|
-
* to the spine's
|
|
254
|
+
* to the spine's own — the name decides nothing, so there is nothing for a
|
|
255
255
|
* closed set to protect, while a consumer surface would have nothing to pass.
|
|
256
256
|
* fuz_app's own uses are pinned two ways by the surface census: the exact call
|
|
257
257
|
* site, and the scan asserting every `'surface:<name>'` literal in `src/lib`
|
|
@@ -281,7 +281,7 @@ const token_scope_denial = (c, capability) => {
|
|
|
281
281
|
* across route-spec declarations and direct calls alike, and the twin of the
|
|
282
282
|
* Rust signature. It needs no parse: the surface arm's identifier is pure label,
|
|
283
283
|
* since rule 3 never asks *which* surface. And it is deliberately not narrowed
|
|
284
|
-
* to the spine's
|
|
284
|
+
* to the spine's own — the name decides nothing, so there is nothing for a
|
|
285
285
|
* closed set to protect, while a consumer surface would have nothing to pass.
|
|
286
286
|
* fuz_app's own uses are pinned two ways by the surface census: the exact call
|
|
287
287
|
* site, and the scan asserting every `'surface:<name>'` literal in `src/lib`
|
|
@@ -106,7 +106,9 @@ export declare const token_scope_admits_method: (scope: TokenScope, method: stri
|
|
|
106
106
|
export declare const token_scope_admits_non_rpc: (scope: TokenScope) => boolean;
|
|
107
107
|
/**
|
|
108
108
|
* The non-RPC surfaces the **spine itself** mounts (rule 3). Twin of the Rust
|
|
109
|
-
* `TokenSurface` enum, name for name
|
|
109
|
+
* `TokenSurface` enum, name for name, except `app_surface` — the opt-in
|
|
110
|
+
* `GET /api/surface` explorer (`server/surface_route.ts`), which only the TS
|
|
111
|
+
* spine serves.
|
|
110
112
|
*
|
|
111
113
|
* Not a registry a consumer registers into. `RouteAuth.required_scope` accepts
|
|
112
114
|
* any well-formed `surface:<name>` (see `parse_token_scope_capability`), so a
|
|
@@ -120,7 +122,7 @@ export declare const token_scope_admits_non_rpc: (scope: TokenScope) => boolean;
|
|
|
120
122
|
* refused, in the `required_scope` a denial reports. That is the same field
|
|
121
123
|
* whose `rpc:<method>` arm has always carried arbitrary consumer method names.
|
|
122
124
|
*/
|
|
123
|
-
export declare const TOKEN_SURFACES: readonly ["db_admin", "fact_bare", "audit_stream", "ws_upgrade"];
|
|
125
|
+
export declare const TOKEN_SURFACES: readonly ["db_admin", "fact_bare", "audit_stream", "ws_upgrade", "app_surface"];
|
|
124
126
|
export type TokenSurface = (typeof TOKEN_SURFACES)[number];
|
|
125
127
|
/**
|
|
126
128
|
* Is `value` one of the surfaces the spine mounts?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token_scope.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/token_scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAW,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU;;;;;;;;;4BAYrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;;;4BAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,QAAO,UAGlC,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,mBAAmB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,KAAG,UAI3D,CAAC;AAEH,qDAAqD;AACrD,eAAO,MAAM,sBAAsB,GAAI,OAAO,eAAe,KAAG,UACgB,CAAC;AAEjF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,UAAU,EAAE,QAAQ,MAAM,KAAG,OACtB,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,UAAU,KAAG,OAAgC,CAAC;AAEhG
|
|
1
|
+
{"version":3,"file":"token_scope.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/token_scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAW,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU;;;;;;;;;4BAYrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;;;4BAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,QAAO,UAGlC,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,mBAAmB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,KAAG,UAI3D,CAAC;AAEH,qDAAqD;AACrD,eAAO,MAAM,sBAAsB,GAAI,OAAO,eAAe,KAAG,UACgB,CAAC;AAEjF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,UAAU,EAAE,QAAQ,MAAM,KAAG,OACtB,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,UAAU,KAAG,OAAgC,CAAC;AAEhG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,iFAMjB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,KAAK,IAAI,YACA,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,QAAgC,CAAC;AAQtE;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GAAI,QAAQ,MAAM,KAAG,MAC3B,CAAC;AAErC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAC/B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,4BAA4B,GAAI,OAAO,MAAM,KAAG,oBAAoB,GAAG,IAUnF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,GACzC,OAAO,UAAU,EACjB,YAAY,oBAAoB,KAC9B,OAGkC,CAAC;AAEtC;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GACnC,YAAY,MAAM,KAChB;IAAE,KAAK,EAAE,sBAAsB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAGxD,CAAC;AAEH,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,GAAI,OAAO,UAAU,KAAG,MAGrD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,UAAU,GAAG,IAU5D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,UAAU,KAAG,MAQzD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,UAAU,GAAG,IAQtE,CAAC"}
|
package/dist/auth/token_scope.js
CHANGED
|
@@ -112,7 +112,9 @@ export const token_scope_admits_method = (scope, method) => scope.kind === 'full
|
|
|
112
112
|
export const token_scope_admits_non_rpc = (scope) => scope.kind === 'full';
|
|
113
113
|
/**
|
|
114
114
|
* The non-RPC surfaces the **spine itself** mounts (rule 3). Twin of the Rust
|
|
115
|
-
* `TokenSurface` enum, name for name
|
|
115
|
+
* `TokenSurface` enum, name for name, except `app_surface` — the opt-in
|
|
116
|
+
* `GET /api/surface` explorer (`server/surface_route.ts`), which only the TS
|
|
117
|
+
* spine serves.
|
|
116
118
|
*
|
|
117
119
|
* Not a registry a consumer registers into. `RouteAuth.required_scope` accepts
|
|
118
120
|
* any well-formed `surface:<name>` (see `parse_token_scope_capability`), so a
|
|
@@ -126,7 +128,13 @@ export const token_scope_admits_non_rpc = (scope) => scope.kind === 'full';
|
|
|
126
128
|
* refused, in the `required_scope` a denial reports. That is the same field
|
|
127
129
|
* whose `rpc:<method>` arm has always carried arbitrary consumer method names.
|
|
128
130
|
*/
|
|
129
|
-
export const TOKEN_SURFACES = [
|
|
131
|
+
export const TOKEN_SURFACES = [
|
|
132
|
+
'db_admin',
|
|
133
|
+
'fact_bare',
|
|
134
|
+
'audit_stream',
|
|
135
|
+
'ws_upgrade',
|
|
136
|
+
'app_surface'
|
|
137
|
+
];
|
|
130
138
|
/**
|
|
131
139
|
* Is `value` one of the surfaces the spine mounts?
|
|
132
140
|
*
|
package/dist/http/CLAUDE.md
CHANGED
|
@@ -28,7 +28,7 @@ effects, see ../../../docs/architecture.md.
|
|
|
28
28
|
- `http/jsonrpc.ts` — JSON-RPC 2.0 envelope schemas (MCP superset), `JsonrpcErrorCode`, `_meta`.
|
|
29
29
|
- `http/jsonrpc_errors.ts` — `ThrownJsonrpcError`, `jsonrpc_errors` throwers, HTTP-status mappings.
|
|
30
30
|
- `http/jsonrpc_helpers.ts` — message builders, type guards, input/result normalizers.
|
|
31
|
-
- `http/common_routes.ts` — health check + readiness probe (`/ready` schema-drift deploy gate) + authenticated server-status
|
|
31
|
+
- `http/common_routes.ts` — health check + readiness probe (`/ready` schema-drift deploy gate) + authenticated server-status route specs (the surface explorer route lives in `server/surface_route.ts`).
|
|
32
32
|
- `http/db_routes.ts` — allowlist-gated keeper-only table browser route specs (`public` schema, minus the `NON_BROWSABLE_TABLES` credential floor).
|
|
33
33
|
- `http/pending_effects.ts` — `emit_after_commit` + `dispatch_with_post_commit_rollback` (the shared rollback-discard wrapper both dispatch sites use) + `flush_pending_effects` + `flush_post_commit_effects` + `EmitAfterCommitContext`.
|
|
34
34
|
|
|
@@ -484,13 +484,12 @@ at send time.
|
|
|
484
484
|
|
|
485
485
|
## Common Routes
|
|
486
486
|
|
|
487
|
-
`http/common_routes.ts` exposes
|
|
487
|
+
`http/common_routes.ts` exposes three generic route-spec factories with no
|
|
488
488
|
auth-domain dependencies:
|
|
489
489
|
|
|
490
490
|
- `create_health_route_spec()` — `GET /health`, public, returns `{status: 'ok'}`. Infrastructure endpoint for uptime monitors
|
|
491
|
-
- `create_ready_route_spec({expected, log})` — `GET /ready`, public, the deploy gate. Introspects the live DB's columns (`db/schema_ready.ts`) and compares against the committed `expected` column map: `200 {ready: true}` on match, else `503 {error: 'schema_drift' | 'db_unreachable'}`. Detailed drift logs server-side only (minimal body — no schema leak, mirrors why `/api/surface` is
|
|
491
|
+
- `create_ready_route_spec({expected, log})` — `GET /ready`, public, the deploy gate. Introspects the live DB's columns (`db/schema_ready.ts`) and compares against the committed `expected` column map: `200 {ready: true}` on match, else `503 {error: 'schema_drift' | 'db_unreachable'}`. Detailed drift logs server-side only (minimal body — no schema leak, mirrors why `/api/surface` is admin-only). Throws at assembly on an empty `expected` (fail-loud). Opt-in like `/health`; pair with `load_expected_schema(url)` — loads + URL-caches a consumer's committed `expected_schema.json` and throws on an empty map
|
|
492
492
|
- `create_server_status_route_spec({version, get_uptime_ms})` — `GET /api/server/status`, authenticated, returns `{version, uptime_ms}`
|
|
493
|
-
- `create_surface_route_spec({surface})` — `GET /api/surface`, authenticated, serves the `AppSurface` JSON. Authenticated because surface data reveals API structure (schemas, auth, routes)
|
|
494
493
|
|
|
495
494
|
Auth-aware variants (account status, bootstrap status) live in `auth/` —
|
|
496
495
|
`http/common_routes.ts` stays generic.
|
|
@@ -141,8 +141,9 @@ export declare const RouteAuth: z.ZodObject<{
|
|
|
141
141
|
*
|
|
142
142
|
* - `surface:<name>` — a non-RPC surface, refused to every narrowed token
|
|
143
143
|
* whatever its method list says (token scoping's rule that a narrowed
|
|
144
|
-
* token is RPC-only). `surface:audit_stream
|
|
145
|
-
* the spine's; a consumer names
|
|
144
|
+
* token is RPC-only). `surface:audit_stream`, `surface:fact_bare`, and
|
|
145
|
+
* `surface:app_surface` are the spine's route-spec ones; a consumer names
|
|
146
|
+
* its own without registering it.
|
|
146
147
|
* - `rpc:<method>` — one action method, refused unless the token lists it.
|
|
147
148
|
* What a route bridged from an `ActionSpec` declares: it carries the
|
|
148
149
|
* method's identity but never reaches the dispatcher's per-method gate.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth_shape.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/auth_shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,6DAGtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAGtD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa;;;;EAA2C,CAAC;AACtE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;IAMpB
|
|
1
|
+
{"version":3,"file":"auth_shape.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/auth_shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,6DAGtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAGtD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa;;;;EAA2C,CAAC;AACtE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;IAMpB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;;kBAyCF,CAAC;AACJ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAUlD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OACA,CAAC;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAG,OAAgC,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,KAAG,OAAkC,CAAC;AAEnF,wEAAwE;AACxE,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,KAAG,OAA+B,CAAC;AAE/E,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,GAAI,MAAM,SAAS,KAAG,OAC3B,CAAC;AAEjC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OACQ,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,SAAS,KAAG,OACwB,CAAC;AAYvF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAIhE,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sCAAsC,GAClD,MAAM,SAAS,EACf,OAAO,WAAW,EAClB,SAAS,MAAM,KACb,IAmBF,CAAC"}
|
package/dist/http/auth_shape.js
CHANGED
|
@@ -135,8 +135,9 @@ export const RouteAuth = z
|
|
|
135
135
|
*
|
|
136
136
|
* - `surface:<name>` — a non-RPC surface, refused to every narrowed token
|
|
137
137
|
* whatever its method list says (token scoping's rule that a narrowed
|
|
138
|
-
* token is RPC-only). `surface:audit_stream
|
|
139
|
-
* the spine's; a consumer names
|
|
138
|
+
* token is RPC-only). `surface:audit_stream`, `surface:fact_bare`, and
|
|
139
|
+
* `surface:app_surface` are the spine's route-spec ones; a consumer names
|
|
140
|
+
* its own without registering it.
|
|
140
141
|
* - `rpc:<method>` — one action method, refused unless the token lists it.
|
|
141
142
|
* What a route bridged from an `ActionSpec` declares: it carries the
|
|
142
143
|
* method's identity but never reaches the dispatcher's per-method gate.
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Logger } from '@fuzdev/fuz_util/log.ts';
|
|
10
10
|
import type { RouteSpec } from './route_spec.js';
|
|
11
|
-
import type { AppSurface } from './surface.js';
|
|
12
11
|
import { type ExpectedSchema } from '../db/schema_ready.js';
|
|
13
12
|
/**
|
|
14
13
|
* Create a public health check route spec.
|
|
@@ -57,7 +56,7 @@ export interface ReadyRouteOptions {
|
|
|
57
56
|
* else `503 {error}` (`schema_drift` when columns are missing, `db_unreachable`
|
|
58
57
|
* when the introspection query throws). The detailed drift goes to the server
|
|
59
58
|
* log only — the public body stays a minimal code so the endpoint doesn't leak
|
|
60
|
-
* schema structure (mirrors why `/api/surface` is
|
|
59
|
+
* schema structure (mirrors why `/api/surface` is admin-only). A deploy poll
|
|
61
60
|
* treats `503` as a failed release and rolls back, turning a silent
|
|
62
61
|
* schema-drift auth outage into a loud blocked deploy. See `db/schema_ready.ts`
|
|
63
62
|
* for the column-presence rationale and `auth/migrations.ts` for the
|
|
@@ -78,16 +77,4 @@ export interface ServerStatusOptions {
|
|
|
78
77
|
* this requires authentication.
|
|
79
78
|
*/
|
|
80
79
|
export declare const create_server_status_route_spec: (options: ServerStatusOptions) => RouteSpec;
|
|
81
|
-
/** Options for the surface explorer route. */
|
|
82
|
-
export interface SurfaceRouteOptions {
|
|
83
|
-
/** The generated app surface to serve. */
|
|
84
|
-
surface: AppSurface;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Create an authenticated route spec that serves the `AppSurface` as JSON.
|
|
88
|
-
*
|
|
89
|
-
* Surface data reveals API structure (routes, auth, schemas), so this
|
|
90
|
-
* requires authentication like the server status route.
|
|
91
|
-
*/
|
|
92
|
-
export declare const create_surface_route_spec: (options: SurfaceRouteOptions) => RouteSpec;
|
|
93
80
|
//# sourceMappingURL=common_routes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/common_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"common_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/common_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,uBAAuB,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QAAO,SAQ1C,CAAC;AAKH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,GAAG,GAAG,MAAM,KAAG,cAkBxD,CAAC;AAEF,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IACjC;;;;OAIG;IACH,QAAQ,EAAE,cAAc,CAAC;IACzB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,GAAI,SAAS,iBAAiB,KAAG,SAoCpE,CAAC;AAEF,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IACnC,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,aAAa,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,GAAI,SAAS,mBAAmB,KAAG,SAQ7E,CAAC"}
|
|
@@ -71,7 +71,7 @@ export const load_expected_schema = (url) => {
|
|
|
71
71
|
* else `503 {error}` (`schema_drift` when columns are missing, `db_unreachable`
|
|
72
72
|
* when the introspection query throws). The detailed drift goes to the server
|
|
73
73
|
* log only — the public body stays a minimal code so the endpoint doesn't leak
|
|
74
|
-
* schema structure (mirrors why `/api/surface` is
|
|
74
|
+
* schema structure (mirrors why `/api/surface` is admin-only). A deploy poll
|
|
75
75
|
* treats `503` as a failed release and rolls back, turning a silent
|
|
76
76
|
* schema-drift auth outage into a loud blocked deploy. See `db/schema_ready.ts`
|
|
77
77
|
* for the column-presence rationale and `auth/migrations.ts` for the
|
|
@@ -129,21 +129,3 @@ export const create_server_status_route_spec = (options) => ({
|
|
|
129
129
|
input: z.null(),
|
|
130
130
|
output: z.looseObject({ version: z.string(), uptime_ms: z.number() })
|
|
131
131
|
});
|
|
132
|
-
/**
|
|
133
|
-
* Create an authenticated route spec that serves the `AppSurface` as JSON.
|
|
134
|
-
*
|
|
135
|
-
* Surface data reveals API structure (routes, auth, schemas), so this
|
|
136
|
-
* requires authentication like the server status route.
|
|
137
|
-
*/
|
|
138
|
-
export const create_surface_route_spec = (options) => ({
|
|
139
|
-
method: 'GET',
|
|
140
|
-
path: '/api/surface',
|
|
141
|
-
auth: { account: 'required', actor: 'none' },
|
|
142
|
-
handler: (c) => c.json(options.surface),
|
|
143
|
-
description: 'Application surface (routes, middleware, schemas)',
|
|
144
|
-
input: z.null(),
|
|
145
|
-
output: z.looseObject({
|
|
146
|
-
routes: z.array(z.looseObject({})),
|
|
147
|
-
middleware: z.array(z.looseObject({}))
|
|
148
|
-
})
|
|
149
|
-
});
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* IPv6 forms (`::ffff:127.0.0.1` vs `0:0:0:0:0:ffff:7f00:1` vs the
|
|
13
13
|
* bare `127.0.0.1`) — three keys for one address.
|
|
14
14
|
*
|
|
15
|
-
* Canonicalization runs through
|
|
15
|
+
* Canonicalization runs through `canonicalize_ip` which:
|
|
16
16
|
*
|
|
17
17
|
* 1. Lowercases and char-set filters (`IP_LITERAL_CHARS`) — non-IP
|
|
18
18
|
* strings (`'unknown'`, `'attacker:controlled'`, `'::1\n'`) pass
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* IPv6 forms (`::ffff:127.0.0.1` vs `0:0:0:0:0:ffff:7f00:1` vs the
|
|
13
13
|
* bare `127.0.0.1`) — three keys for one address.
|
|
14
14
|
*
|
|
15
|
-
* Canonicalization runs through
|
|
15
|
+
* Canonicalization runs through `canonicalize_ip` which:
|
|
16
16
|
*
|
|
17
17
|
* 1. Lowercases and char-set filters (`IP_LITERAL_CHARS`) — non-IP
|
|
18
18
|
* strings (`'unknown'`, `'attacker:controlled'`, `'::1\n'`) pass
|
|
@@ -118,7 +118,9 @@ export declare const AUDIT_LOG_SSE_MAX_PER_SCOPE = 10;
|
|
|
118
118
|
* connection closer.
|
|
119
119
|
*
|
|
120
120
|
* Combines `SubscriberRegistry`, `create_sse_auth_guard`, and the broadcast
|
|
121
|
-
* call into a single object, and adds the registry to `connection_closer
|
|
121
|
+
* call into a single object, and adds the registry to `connection_closer` for
|
|
122
|
+
* good — the remover `add` returns is dropped, so a caller that must take the
|
|
123
|
+
* registry out again passes `null` and adds it itself.
|
|
122
124
|
* The result satisfies `AuditLogRouteOptions['stream']`
|
|
123
125
|
* and provides the `on_audit_event` listener for the audit emitter.
|
|
124
126
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse_auth_guard.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/realtime/sse_auth_guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAIN,KAAK,aAAa,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE3D,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,GAAI,CAAC,EAC7C,UAAU,kBAAkB,CAAC,CAAC,CAAC,KAC7B,gBAKD,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EACtC,UAAU,kBAAkB,CAAC,CAAC,CAAC,EAC/B,eAAe,MAAM,GAAG,IAAI,EAC5B,KAAK,MAAM,KACT,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CA4DjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC9C,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,yJAAyJ;IACzJ,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,SAAS,CAOlD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C
|
|
1
|
+
{"version":3,"file":"sse_auth_guard.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/realtime/sse_auth_guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAIN,KAAK,aAAa,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE3D,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,GAAI,CAAC,EAC7C,UAAU,kBAAkB,CAAC,CAAC,CAAC,KAC7B,gBAKD,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EACtC,UAAU,kBAAkB,CAAC,CAAC,CAAC,EAC/B,eAAe,MAAM,GAAG,IAAI,EAC5B,KAAK,MAAM,KACT,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CA4DjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC9C,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,yJAAyJ;IACzJ,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,SAAS,CAOlD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS;IAC7C,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;OASG;IACH,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,KAAG,WAgBH,CAAC"}
|
|
@@ -164,7 +164,9 @@ export const AUDIT_LOG_SSE_MAX_PER_SCOPE = 10;
|
|
|
164
164
|
* connection closer.
|
|
165
165
|
*
|
|
166
166
|
* Combines `SubscriberRegistry`, `create_sse_auth_guard`, and the broadcast
|
|
167
|
-
* call into a single object, and adds the registry to `connection_closer
|
|
167
|
+
* call into a single object, and adds the registry to `connection_closer` for
|
|
168
|
+
* good — the remover `add` returns is dropped, so a caller that must take the
|
|
169
|
+
* registry out again passes `null` and adds it itself.
|
|
168
170
|
* The result satisfies `AuditLogRouteOptions['stream']`
|
|
169
171
|
* and provides the `on_audit_event` listener for the audit emitter.
|
|
170
172
|
*
|
|
@@ -10,18 +10,18 @@
|
|
|
10
10
|
import { Hono, type Context } from 'hono';
|
|
11
11
|
import type { UpgradeWebSocket } from 'hono/ws';
|
|
12
12
|
import { z } from 'zod';
|
|
13
|
-
import { type SessionOptions } from '../auth/session_cookie.js';
|
|
13
|
+
import { type SessionOptions, type SessionCookieOptions } from '../auth/session_cookie.js';
|
|
14
14
|
import type { BootstrapAccountSuccess } from '../auth/bootstrap_account.js';
|
|
15
15
|
import type { EventSpec } from '../realtime/sse.js';
|
|
16
16
|
import { type AuditLogSse } from '../realtime/sse_auth_guard.js';
|
|
17
|
-
import { RateLimiter, type RateLimiterMode } from '../rate_limiter.js';
|
|
17
|
+
import { RateLimiter, type RateLimiterMode, type RateLimiterOptions } from '../rate_limiter.js';
|
|
18
18
|
import type { DaemonTokenState } from '../auth/daemon_token.js';
|
|
19
19
|
import type { MigrationResult } from '../db/migrate.js';
|
|
20
20
|
import type { AppBackend } from './app_backend.js';
|
|
21
21
|
import type { AppServerContext } from './app_server_context.js';
|
|
22
22
|
import '../hono_context.js';
|
|
23
23
|
import { type ServeStaticFactory } from './static.js';
|
|
24
|
-
import { type AppSurfaceSpec, type RpcEndpointSpec } from '../http/surface.js';
|
|
24
|
+
import { type AppSurfaceSpec, type AppSurfaceDiagnostic, type RpcEndpointSpec } from '../http/surface.js';
|
|
25
25
|
import { type RouteSpec } from '../http/route_spec.js';
|
|
26
26
|
import type { MiddlewareSpec } from '../http/middleware_spec.js';
|
|
27
27
|
import { type BootstrapStatus } from '../auth/bootstrap_routes.js';
|
|
@@ -186,10 +186,19 @@ export interface AppServerOptions {
|
|
|
186
186
|
/** Bootstrap options. Omit to skip bootstrap status check and routes. */
|
|
187
187
|
bootstrap?: BootstrapServerOptions;
|
|
188
188
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
189
|
+
* Mount `GET /api/surface`, which serves this server's generated
|
|
190
|
+
* `AppSurface` (every route, its auth, and its schemas) to an admin UI such
|
|
191
|
+
* as `AdminSurface.svelte`. Off by default — the Rust spine serves no such
|
|
192
|
+
* route, and a map of the API is nothing to publish unasked.
|
|
193
|
+
*
|
|
194
|
+
* When mounted the route is admin-only (`roles: ['admin']`, so it takes the
|
|
195
|
+
* `?acting=` selector) and a rule-3 token surface
|
|
196
|
+
* (`required_scope: 'surface:app_surface'`): a narrowed API token is refused
|
|
197
|
+
* it whatever its method list says. See `server/surface_route.ts`.
|
|
198
|
+
*
|
|
199
|
+
* @default false
|
|
191
200
|
*/
|
|
192
|
-
surface_route?:
|
|
201
|
+
surface_route?: boolean;
|
|
193
202
|
/**
|
|
194
203
|
* Build route specs from the initialized backend.
|
|
195
204
|
* Called after all middleware is ready.
|
|
@@ -469,6 +478,106 @@ export declare const require_audit_sse: (source: {
|
|
|
469
478
|
}) => AuditLogSse;
|
|
470
479
|
/** Default maximum request body size: 1 MiB. */
|
|
471
480
|
export declare const DEFAULT_MAX_BODY_SIZE: number;
|
|
481
|
+
/**
|
|
482
|
+
* Each `AppServerOptions` rate-limiter field, with the defaults an omitted one
|
|
483
|
+
* is built from under `rate_limiters: 'enforced'` and the name its
|
|
484
|
+
* explicitly-null diagnostic uses. Insertion order is the order limiters are
|
|
485
|
+
* built and their diagnostics are listed.
|
|
486
|
+
*/
|
|
487
|
+
declare const rate_limiter_slots: {
|
|
488
|
+
readonly login_ip_rate_limiter: {
|
|
489
|
+
readonly label: "login IP";
|
|
490
|
+
readonly defaults: RateLimiterOptions;
|
|
491
|
+
};
|
|
492
|
+
readonly signup_ip_rate_limiter: {
|
|
493
|
+
readonly label: "signup IP";
|
|
494
|
+
readonly defaults: RateLimiterOptions;
|
|
495
|
+
};
|
|
496
|
+
readonly bootstrap_ip_rate_limiter: {
|
|
497
|
+
readonly label: "bootstrap IP";
|
|
498
|
+
readonly defaults: RateLimiterOptions;
|
|
499
|
+
};
|
|
500
|
+
readonly login_account_rate_limiter: {
|
|
501
|
+
readonly label: "login account";
|
|
502
|
+
readonly defaults: RateLimiterOptions;
|
|
503
|
+
};
|
|
504
|
+
readonly signup_account_rate_limiter: {
|
|
505
|
+
readonly label: "signup account";
|
|
506
|
+
readonly defaults: RateLimiterOptions;
|
|
507
|
+
};
|
|
508
|
+
readonly action_ip_rate_limiter: {
|
|
509
|
+
readonly label: "action IP";
|
|
510
|
+
readonly defaults: RateLimiterOptions;
|
|
511
|
+
};
|
|
512
|
+
readonly action_account_rate_limiter: {
|
|
513
|
+
readonly label: "action account";
|
|
514
|
+
readonly defaults: RateLimiterOptions;
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
/**
|
|
518
|
+
* Name of an `AppServerOptions` rate-limiter field — also the
|
|
519
|
+
* `AppServerContext` field its resolved limiter lands on.
|
|
520
|
+
*
|
|
521
|
+
* @internal
|
|
522
|
+
*/
|
|
523
|
+
export type AppServerRateLimiterKey = keyof typeof rate_limiter_slots;
|
|
524
|
+
/**
|
|
525
|
+
* Every `AppServerOptions` rate-limiter field, in build order.
|
|
526
|
+
*
|
|
527
|
+
* @internal
|
|
528
|
+
*/
|
|
529
|
+
export declare const APP_SERVER_RATE_LIMITER_KEYS: ReadonlyArray<AppServerRateLimiterKey>;
|
|
530
|
+
/**
|
|
531
|
+
* The rate limiters `create_app_server` resolved from its options.
|
|
532
|
+
*
|
|
533
|
+
* @internal
|
|
534
|
+
*/
|
|
535
|
+
export interface ResolvedRateLimiters {
|
|
536
|
+
/** The `rate_limiters` mode, defaulted to `'enforced'`. */
|
|
537
|
+
mode: RateLimiterMode;
|
|
538
|
+
/** Each limiter by option name — `null` when off. */
|
|
539
|
+
limiters: Record<AppServerRateLimiterKey, RateLimiter | null>;
|
|
540
|
+
/**
|
|
541
|
+
* The limiters built here for omitted options, in build order — the
|
|
542
|
+
* server's to dispose. Never one passed in, which its caller owns.
|
|
543
|
+
*/
|
|
544
|
+
built: Array<RateLimiter>;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Resolve each rate-limiter option: an explicit option (instance or `null`)
|
|
548
|
+
* wins; an omitted one is a default instance under `'enforced'` and `null`
|
|
549
|
+
* under `'disabled_for_testing'`, which also announces the mode on stderr
|
|
550
|
+
* (`announce_rate_limiters_disabled`). One instance per surface — see
|
|
551
|
+
* `AppServerOptions.login_ip_rate_limiter` for why these are not a single
|
|
552
|
+
* shared bucket.
|
|
553
|
+
*
|
|
554
|
+
* @param options - the rate-limiter fields and `rate_limiters` mode of `AppServerOptions`
|
|
555
|
+
* @internal
|
|
556
|
+
*/
|
|
557
|
+
export declare const resolve_rate_limiters: (options: Pick<AppServerOptions, AppServerRateLimiterKey | "rate_limiters">) => ResolvedRateLimiters;
|
|
558
|
+
/**
|
|
559
|
+
* Inputs to `collect_config_diagnostics`.
|
|
560
|
+
*
|
|
561
|
+
* @internal
|
|
562
|
+
*/
|
|
563
|
+
export interface ConfigDiagnosticsInput {
|
|
564
|
+
/** The session cookie overrides, from `AppServerOptions.session_options`. */
|
|
565
|
+
cookie_options: Partial<SessionCookieOptions> | undefined;
|
|
566
|
+
/** The `rate_limiters` mode, defaulted. */
|
|
567
|
+
rate_limiter_mode: RateLimiterMode;
|
|
568
|
+
/** The resolved limiters, from `resolve_rate_limiters`. */
|
|
569
|
+
rate_limiters: Record<AppServerRateLimiterKey, RateLimiter | null>;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* The config-level diagnostics `create_app_server` appends to the surface's
|
|
573
|
+
* spec-level ones: a weakened session cookie, and an open rate-limited
|
|
574
|
+
* surface — one warning for `'disabled_for_testing'`, otherwise one per
|
|
575
|
+
* explicitly-null limiter, so a deployment that disables login's limiter but
|
|
576
|
+
* keeps signup's reads differently from one that disables both.
|
|
577
|
+
*
|
|
578
|
+
* @internal
|
|
579
|
+
*/
|
|
580
|
+
export declare const collect_config_diagnostics: (input: ConfigDiagnosticsInput) => Array<AppSurfaceDiagnostic>;
|
|
472
581
|
/**
|
|
473
582
|
* Create a fully assembled Hono app with auth, middleware, and routes.
|
|
474
583
|
*
|
|
@@ -503,8 +612,10 @@ export declare const DEFAULT_MAX_BODY_SIZE: number;
|
|
|
503
612
|
* live connection on the backend's closer, runs the same releases, and
|
|
504
613
|
* closes the database (`AppServer.close`).
|
|
505
614
|
*
|
|
506
|
-
* @returns assembled Hono app
|
|
615
|
+
* @returns the assembled Hono app with its surface, bootstrap status, migration results,
|
|
616
|
+
* audit SSE, mounted WS transports, and `close`
|
|
507
617
|
* @throws Error from any assembly step, after releasing what assembly acquired
|
|
508
618
|
*/
|
|
509
619
|
export declare const create_app_server: (options: AppServerOptions) => Promise<AppServer>;
|
|
620
|
+
export {};
|
|
510
621
|
//# sourceMappingURL=app_server.d.ts.map
|