@fuzdev/fuz_app 0.118.0 → 0.119.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/CLAUDE.md +301 -73
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +16 -1
- package/dist/actions/connection_closer.d.ts +136 -51
- package/dist/actions/connection_closer.d.ts.map +1 -1
- package/dist/actions/connection_closer.js +133 -34
- package/dist/actions/register_action_ws.d.ts +176 -24
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +581 -241
- package/dist/actions/register_ws_endpoint.d.ts +1 -0
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +1 -0
- package/dist/actions/socket.svelte.d.ts +43 -9
- package/dist/actions/socket.svelte.d.ts.map +1 -1
- package/dist/actions/socket.svelte.js +59 -8
- package/dist/actions/transports.d.ts +55 -1
- package/dist/actions/transports.d.ts.map +1 -1
- package/dist/actions/transports.js +55 -1
- package/dist/actions/transports_ws_auth_guard.d.ts +53 -67
- package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
- package/dist/actions/transports_ws_auth_guard.js +87 -111
- package/dist/actions/transports_ws_backend.d.ts +212 -30
- package/dist/actions/transports_ws_backend.d.ts.map +1 -1
- package/dist/actions/transports_ws_backend.js +327 -70
- package/dist/actions/ws_endpoint_spec.d.ts +26 -13
- package/dist/actions/ws_endpoint_spec.d.ts.map +1 -1
- package/dist/auth/CLAUDE.md +113 -32
- package/dist/auth/account_actions.d.ts +12 -18
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +47 -33
- package/dist/auth/account_routes.d.ts +5 -11
- package/dist/auth/account_routes.d.ts.map +1 -1
- package/dist/auth/account_routes.js +40 -36
- package/dist/auth/account_schema.d.ts +27 -0
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +22 -0
- package/dist/auth/admin_actions.d.ts +8 -17
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +33 -21
- package/dist/auth/api_token_queries.d.ts +23 -2
- package/dist/auth/api_token_queries.d.ts.map +1 -1
- package/dist/auth/api_token_queries.js +39 -3
- package/dist/auth/audit_emitter.d.ts +61 -38
- package/dist/auth/audit_emitter.d.ts.map +1 -1
- package/dist/auth/audit_emitter.js +57 -14
- package/dist/auth/audit_log_route_schema.js +7 -7
- package/dist/auth/audit_log_routes.d.ts +31 -6
- package/dist/auth/audit_log_routes.d.ts.map +1 -1
- package/dist/auth/audit_log_routes.js +85 -11
- package/dist/auth/audit_log_schema.d.ts +48 -0
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +58 -0
- package/dist/auth/cleanup.d.ts +203 -28
- package/dist/auth/cleanup.d.ts.map +1 -1
- package/dist/auth/cleanup.js +222 -26
- package/dist/auth/deps.d.ts +28 -0
- package/dist/auth/deps.d.ts.map +1 -1
- package/dist/auth/resolved_auth.d.ts +105 -0
- package/dist/auth/resolved_auth.d.ts.map +1 -0
- package/dist/auth/resolved_auth.js +124 -0
- package/dist/auth/session_middleware.d.ts +8 -1
- package/dist/auth/session_middleware.d.ts.map +1 -1
- package/dist/auth/session_middleware.js +9 -3
- package/dist/auth/session_queries.d.ts +31 -6
- package/dist/auth/session_queries.d.ts.map +1 -1
- package/dist/auth/session_queries.js +31 -6
- package/dist/auth/standard_rpc_actions.d.ts +9 -9
- package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
- package/dist/auth/standard_rpc_actions.js +3 -3
- package/dist/db/CLAUDE.md +7 -1
- package/dist/db/status.d.ts +58 -1
- package/dist/db/status.d.ts.map +1 -1
- package/dist/db/status.js +205 -77
- package/dist/http/CLAUDE.md +7 -3
- package/dist/http/db_routes.d.ts +6 -2
- package/dist/http/db_routes.d.ts.map +1 -1
- package/dist/http/db_routes.js +2 -2
- package/dist/periodic.d.ts +80 -0
- package/dist/periodic.d.ts.map +1 -0
- package/dist/periodic.js +122 -0
- package/dist/realtime/sse_auth_guard.d.ts +79 -49
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
- package/dist/realtime/sse_auth_guard.js +103 -73
- package/dist/realtime/subscriber_registry.d.ts +119 -8
- package/dist/realtime/subscriber_registry.d.ts.map +1 -1
- package/dist/realtime/subscriber_registry.js +184 -25
- package/dist/server/app_backend.d.ts +12 -1
- package/dist/server/app_backend.d.ts.map +1 -1
- package/dist/server/app_backend.js +5 -2
- package/dist/server/app_server.d.ts +55 -15
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +41 -13
- package/dist/testing/CLAUDE.md +140 -48
- package/dist/testing/app_server.d.ts +2 -2
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +11 -2
- package/dist/testing/audit_drift_guard.d.ts +1 -48
- package/dist/testing/audit_drift_guard.d.ts.map +1 -1
- package/dist/testing/audit_drift_guard.js +0 -42
- package/dist/testing/connection_closer_helpers.d.ts +9 -22
- package/dist/testing/connection_closer_helpers.d.ts.map +1 -1
- package/dist/testing/connection_closer_helpers.js +11 -17
- package/dist/testing/cross_backend/capabilities.d.ts +67 -13
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +27 -12
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +21 -0
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.js +13 -4
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +4 -1
- package/dist/testing/cross_backend/session_cap.d.ts +13 -0
- package/dist/testing/cross_backend/session_cap.d.ts.map +1 -1
- package/dist/testing/cross_backend/session_cap.js +55 -19
- package/dist/testing/cross_backend/sse_round_trip.d.ts +10 -2
- package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/sse_round_trip.js +93 -26
- package/dist/testing/cross_backend/testing_server_bun.js +4 -4
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/ts_spine_backend_config.js +10 -2
- package/dist/testing/cross_backend/ws_connection_cap.d.ts +35 -0
- package/dist/testing/cross_backend/ws_connection_cap.d.ts.map +1 -0
- package/dist/testing/cross_backend/ws_connection_cap.js +131 -0
- package/dist/testing/cross_backend/ws_round_trip.d.ts +2 -1
- package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_round_trip.js +156 -19
- package/dist/testing/sse_round_trip.d.ts +6 -4
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/stubs.d.ts +1 -1
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +6 -4
- package/dist/testing/transports/sse_transport.d.ts +1 -1
- package/dist/testing/transports/ws_client.d.ts +7 -0
- package/dist/testing/transports/ws_client.d.ts.map +1 -1
- package/dist/testing/transports/ws_raw_client.d.ts +51 -0
- package/dist/testing/transports/ws_raw_client.d.ts.map +1 -0
- package/dist/testing/transports/ws_raw_client.js +156 -0
- package/dist/testing/transports/ws_transport.d.ts +28 -0
- package/dist/testing/transports/ws_transport.d.ts.map +1 -1
- package/dist/testing/transports/ws_transport.js +45 -1
- package/dist/testing/ws_round_trip.d.ts +8 -3
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +19 -4
- package/dist/ui/AdminAccounts.svelte +4 -3
- package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
- package/dist/ui/AdminOverview.svelte +3 -1
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
- package/dist/ui/CLAUDE.md +22 -6
- package/dist/ui/admin_accounts_state.svelte.d.ts +15 -1
- package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
- package/dist/ui/admin_accounts_state.svelte.js +16 -0
- package/dist/ui/auth_state.svelte.d.ts +25 -1
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/auth_state.svelte.js +28 -1
- package/package.json +1 -1
|
@@ -24,6 +24,64 @@
|
|
|
24
24
|
* runs inside `perform_action` on every message via the same gates HTTP
|
|
25
25
|
* RPC uses.
|
|
26
26
|
*
|
|
27
|
+
* ## Admission: the revocation race
|
|
28
|
+
*
|
|
29
|
+
* The auth middleware resolves the credential before the handshake, and the
|
|
30
|
+
* socket exists only once `onOpen` fires. Every revocation (session revoke,
|
|
31
|
+
* logout, password change, token revoke, account delete) closes the sockets
|
|
32
|
+
* *registered* under what it revoked, so one landing in that gap would close
|
|
33
|
+
* nothing, and the socket would then be admitted on the dead credential and
|
|
34
|
+
* keep it: per-message dispatch re-authorizes the *actor*, never the session
|
|
35
|
+
* or token — and its admission could evict a live socket of the same account
|
|
36
|
+
* past the cap.
|
|
37
|
+
*
|
|
38
|
+
* `onOpen` closes the gap in three steps: register the connection **pending**
|
|
39
|
+
* (`BackendWebsocketTransport.register_pending` — closeable by every
|
|
40
|
+
* revocation, inert otherwise), re-read the credential
|
|
41
|
+
* (`revalidate_resolved_auth`), then `BackendWebsocketTransport.admit`. A
|
|
42
|
+
* revocation whose close ran after the registration found the pending entry,
|
|
43
|
+
* so `admit` refuses; one that committed before the re-read is seen by it. The
|
|
44
|
+
* cap is enforced only by `admit`, so a refused upgrade evicts nothing, and
|
|
45
|
+
* pending registrations never count toward it.
|
|
46
|
+
*
|
|
47
|
+
* That argument needs every revocation to close only after its commit —
|
|
48
|
+
* otherwise a close could miss the registration while the re-read still sees
|
|
49
|
+
* the credential alive. Every one does: the revocation handlers queue their
|
|
50
|
+
* close behind the commit (`queue_connection_close`), and the audit emitter
|
|
51
|
+
* announces a success row to the listeners behind it too. So no interleaving
|
|
52
|
+
* admits a revoked credential; `docs/security.md` §Connection Admission says
|
|
53
|
+
* what that rests on.
|
|
54
|
+
*
|
|
55
|
+
* A refused upgrade is closed with `WS_CLOSE_SESSION_REVOKED` (4001, the
|
|
56
|
+
* reason a revoked socket gets), or `WS_CLOSE_INTERNAL_ERROR` (1011) when the
|
|
57
|
+
* re-read itself failed — fail closed, never admitted unchecked. The handshake
|
|
58
|
+
* has already answered `101`, so a refusal can only be a close frame.
|
|
59
|
+
*
|
|
60
|
+
* Frames that arrive before admission are queued, not dispatched: nothing runs
|
|
61
|
+
* on a credential that has not been re-read. They dispatch in arrival order
|
|
62
|
+
* once the socket is admitted and `on_socket_open` has completed, and are
|
|
63
|
+
* dropped unread on a refusal. The queue holds at most
|
|
64
|
+
* `MAX_PRE_ADMISSION_FRAMES` frames and
|
|
65
|
+
* `PRE_ADMISSION_QUEUE_BYTES_FACTOR` × `max_message_bytes` bytes; past either
|
|
66
|
+
* the socket is closed.
|
|
67
|
+
*
|
|
68
|
+
* The upgrade's role gate is *not* re-read: a role revocation closes no
|
|
69
|
+
* WebSocket in the first place (per-message dispatch re-reads role grants).
|
|
70
|
+
*
|
|
71
|
+
* ## A server-closed socket dispatches nothing
|
|
72
|
+
*
|
|
73
|
+
* A runtime adapter can keep delivering inbound frames after the server calls
|
|
74
|
+
* `ws.close(…)`, until the close handshake completes (`@hono/node-ws` does —
|
|
75
|
+
* up to the `ws` close timeout when the client withholds its close frame).
|
|
76
|
+
* So every server-side close — revocation, cap eviction, heartbeat timeout,
|
|
77
|
+
* an oversized message, a refused admission — removes the connection from the
|
|
78
|
+
* transport and aborts the socket's signal *at close time*, and `onMessage`
|
|
79
|
+
* drops any frame on a socket that has ended. A connection the transport no
|
|
80
|
+
* longer holds though nothing closed its socket (a bare `remove_connection`)
|
|
81
|
+
* is ended on its next frame (`BackendWebsocketTransport.is_registered`), with
|
|
82
|
+
* `WS_CLOSE_INTERNAL_ERROR` — it must not linger as a socket that reads
|
|
83
|
+
* everything and answers nothing.
|
|
84
|
+
*
|
|
27
85
|
* @module
|
|
28
86
|
*/
|
|
29
87
|
import type { Hono } from 'hono';
|
|
@@ -33,22 +91,65 @@ import type { Uuid } from '@fuzdev/fuz_util/id.ts';
|
|
|
33
91
|
import type { RateLimiter } from '../rate_limiter.js';
|
|
34
92
|
import type { Db } from '../db/db.js';
|
|
35
93
|
import { type Action } from './action_types.js';
|
|
94
|
+
import type { RealtimeCloser } from './connection_closer.js';
|
|
36
95
|
import { BackendWebsocketTransport, type ConnectionIdentity } from './transports_ws_backend.js';
|
|
37
96
|
export type { Action };
|
|
38
97
|
/** Default inactivity window before the server closes a silent socket. */
|
|
39
98
|
export declare const DEFAULT_SERVER_HEARTBEAT_TIMEOUT = 60000;
|
|
99
|
+
/**
|
|
100
|
+
* Max inbound frames one socket may have queued while it is still opening —
|
|
101
|
+
* between the handshake and the end of the credential re-check plus
|
|
102
|
+
* `on_socket_open`. One more closes the socket with
|
|
103
|
+
* `WS_CLOSE_POLICY_VIOLATION`.
|
|
104
|
+
*
|
|
105
|
+
* Frames sent before the socket is open wait rather than dispatch (nothing
|
|
106
|
+
* runs on a credential that has not been re-read), and a runtime adapter hands
|
|
107
|
+
* them over with no backpressure, so the wait needs a bound. This is the count
|
|
108
|
+
* half; `PRE_ADMISSION_QUEUE_BYTES_FACTOR` is the byte half.
|
|
109
|
+
*
|
|
110
|
+
* Sized so a client flushing its durable queue on reopen never meets it at the
|
|
111
|
+
* default `DEFAULT_QUEUE_MAX_SIZE` (`actions/socket.svelte.ts`). A consumer
|
|
112
|
+
* that raises the client's queue above this cap makes a full flush overflow
|
|
113
|
+
* it: the socket closes with `WS_CLOSE_POLICY_VIOLATION`, the flushed requests
|
|
114
|
+
* fail, and the client reconnects.
|
|
115
|
+
*/
|
|
116
|
+
export declare const MAX_PRE_ADMISSION_FRAMES = 256;
|
|
117
|
+
/**
|
|
118
|
+
* The byte budget of one socket's pre-admission queue, as a multiple of the
|
|
119
|
+
* endpoint's `max_message_bytes`: the frames queued while the socket is still
|
|
120
|
+
* opening may total at most this many maximum-size messages. The frame that
|
|
121
|
+
* would pass it closes the socket with `WS_CLOSE_POLICY_VIOLATION`.
|
|
122
|
+
*
|
|
123
|
+
* The count cap alone (`MAX_PRE_ADMISSION_FRAMES`) would let each pending
|
|
124
|
+
* socket hold that many full-size messages, and pending sockets are not
|
|
125
|
+
* capped per account — a registration that is never admitted must not be able
|
|
126
|
+
* to pin that much memory. Small requests, which is what a client flushes on
|
|
127
|
+
* reopen, meet the count cap long before this one.
|
|
128
|
+
*
|
|
129
|
+
* A client whose queued requests total more than this budget and flushes
|
|
130
|
+
* them all on reopen overflows it: the socket closes, the flushed requests
|
|
131
|
+
* fail, and the client reconnects.
|
|
132
|
+
*/
|
|
133
|
+
export declare const PRE_ADMISSION_QUEUE_BYTES_FACTOR = 4;
|
|
134
|
+
/**
|
|
135
|
+
* The close reason sent with `WS_CLOSE_POLICY_VIOLATION` when a socket
|
|
136
|
+
* overflows its pre-admission queue, by count or by bytes.
|
|
137
|
+
*/
|
|
138
|
+
export declare const WS_CLOSE_PRE_ADMISSION_OVERFLOW_REASON = "too much sent before the socket opened";
|
|
40
139
|
/**
|
|
41
140
|
* Context passed to the `on_socket_open` hook.
|
|
42
141
|
*
|
|
43
|
-
* Fires
|
|
44
|
-
* `connection_id` is valid
|
|
45
|
-
*
|
|
46
|
-
*
|
|
142
|
+
* Fires once the connection is **admitted** — registered in the transport and
|
|
143
|
+
* its credential re-checked (so `connection_id` is valid, and broadcasts reach
|
|
144
|
+
* it) — and before any client message dispatches. A socket refused at
|
|
145
|
+
* admission never reaches it. Consumers use this to bootstrap per-socket
|
|
146
|
+
* domain state — e.g. spawning a per-account unit and pushing an initial state
|
|
147
|
+
* snapshot.
|
|
47
148
|
*/
|
|
48
149
|
export interface SocketOpenContext {
|
|
49
150
|
/** The raw WebSocket context — exposed for edge cases; prefer `notify` for sends. */
|
|
50
151
|
ws: WSContext;
|
|
51
|
-
/** Connection id assigned by `BackendWebsocketTransport.
|
|
152
|
+
/** Connection id assigned by `BackendWebsocketTransport.register_pending`. */
|
|
52
153
|
connection_id: Uuid;
|
|
53
154
|
/** Auth identity registered for this connection. */
|
|
54
155
|
identity: ConnectionIdentity;
|
|
@@ -57,23 +158,36 @@ export interface SocketOpenContext {
|
|
|
57
158
|
* on per-message handler contexts — same socket-scoped semantics.
|
|
58
159
|
*/
|
|
59
160
|
notify: (method: string, params: unknown) => void;
|
|
60
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* Fires when this socket ends — the client closed it, or the server did
|
|
163
|
+
* (revocation, cap eviction, heartbeat timeout), at the moment the server
|
|
164
|
+
* closes rather than when the close handshake lands. Threaded through to
|
|
165
|
+
* every handler's `ctx.signal`.
|
|
166
|
+
*/
|
|
61
167
|
signal: AbortSignal;
|
|
62
168
|
}
|
|
63
169
|
/**
|
|
64
170
|
* Context passed to the `on_socket_close` hook.
|
|
65
171
|
*
|
|
66
|
-
* Fires
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* (
|
|
172
|
+
* Fires after the transport has removed the connection — `connection_id` and
|
|
173
|
+
* `identity` are the values captured at open, so consumer cleanup reads them
|
|
174
|
+
* from here, not from the transport. Fires for both client-initiated closes
|
|
175
|
+
* (Hono onClose) and server-initiated closes — a revocation, the per-account
|
|
176
|
+
* connection cap's eviction, and a heartbeat timeout all call `ws.close()`,
|
|
177
|
+
* which triggers Hono's onClose. Fires only for a socket that was admitted: one
|
|
178
|
+
* refused at admission never ran `on_socket_open`, so it has no close hook
|
|
179
|
+
* either.
|
|
70
180
|
*/
|
|
71
181
|
export interface SocketCloseContext {
|
|
72
|
-
/**
|
|
182
|
+
/**
|
|
183
|
+
* The WebSocket context the close event carried. Not necessarily the object
|
|
184
|
+
* `on_socket_open` received — an adapter may build one per event — so key
|
|
185
|
+
* per-socket state on `connection_id`.
|
|
186
|
+
*/
|
|
73
187
|
ws: WSContext;
|
|
74
188
|
/** Connection id captured at open time. */
|
|
75
189
|
connection_id: Uuid;
|
|
76
|
-
/** Auth identity captured at open time —
|
|
190
|
+
/** Auth identity captured at open time — the transport no longer holds it. */
|
|
77
191
|
identity: ConnectionIdentity;
|
|
78
192
|
}
|
|
79
193
|
export interface ServerHeartbeatOptions {
|
|
@@ -119,6 +233,27 @@ export interface RegisterActionWsOptions {
|
|
|
119
233
|
* handle for `create_ws_auth_guard` and `send_to`/`broadcast`.
|
|
120
234
|
*/
|
|
121
235
|
transport?: BackendWebsocketTransport;
|
|
236
|
+
/**
|
|
237
|
+
* The backend's closer — `deps.connection_closer`. This endpoint's
|
|
238
|
+
* transport is added to it, so every revocation handler's close reaches
|
|
239
|
+
* the sockets opened here. Required so it can't be forgotten: left out of
|
|
240
|
+
* the closer, a transport's sockets close only through the audit listener,
|
|
241
|
+
* which a failed audit write or a session / token cap eviction never
|
|
242
|
+
* reaches. Pass `null` only when no revocation has to reach this transport
|
|
243
|
+
* (a harness driving the dispatcher directly), or when the transport was
|
|
244
|
+
* added by hand.
|
|
245
|
+
*/
|
|
246
|
+
connection_closer: RealtimeCloser | null;
|
|
247
|
+
/**
|
|
248
|
+
* Per-account connection cap for the transport this call creates — see
|
|
249
|
+
* `BackendWebsocketTransportOptions.max_connections_per_account`
|
|
250
|
+
* (evict-oldest, closing with `WS_CLOSE_CONNECTION_LIMIT`; `null`
|
|
251
|
+
* disables). Rejected alongside `transport`: a supplied transport carries
|
|
252
|
+
* its own cap, set where it was constructed.
|
|
253
|
+
*
|
|
254
|
+
* @default DEFAULT_MAX_CONNECTIONS_PER_ACCOUNT
|
|
255
|
+
*/
|
|
256
|
+
max_connections_per_account?: number | null;
|
|
122
257
|
/**
|
|
123
258
|
* Server-side heartbeat policy. Default-on (receive-silence detection,
|
|
124
259
|
* 60s timeout). `false` disables the timer entirely — only do this if
|
|
@@ -144,17 +279,24 @@ export interface RegisterActionWsOptions {
|
|
|
144
279
|
/** Optional logger; defaults to `[ws]` namespace. */
|
|
145
280
|
log?: LoggerType;
|
|
146
281
|
/**
|
|
147
|
-
* Called once per socket, after the
|
|
148
|
-
* Awaited before any
|
|
149
|
-
*
|
|
150
|
-
*
|
|
282
|
+
* Called once per socket, after the connection is admitted (module doc,
|
|
283
|
+
* "Admission"). Awaited before any inbound frame is dispatched — every
|
|
284
|
+
* frame the client sends meanwhile waits in arrival order, replies to
|
|
285
|
+
* server-initiated requests included: a hook that awaits
|
|
286
|
+
* `transport.request_connection` on its own connection gets no reply until
|
|
287
|
+
* it returns, so start such a request without awaiting it. Throwing logs an
|
|
288
|
+
* error and closes the socket with an `internal_error` frame and
|
|
289
|
+
* `WS_CLOSE_INTERNAL_ERROR` — a failing bootstrap should not leave a
|
|
290
|
+
* partially-initialized socket alive.
|
|
151
291
|
*/
|
|
152
292
|
on_socket_open?: (ctx: SocketOpenContext) => void | Promise<void>;
|
|
153
293
|
/**
|
|
154
|
-
* Called once per socket on close, *
|
|
155
|
-
* connection
|
|
156
|
-
*
|
|
157
|
-
*
|
|
294
|
+
* Called once per admitted socket on close, *after* the transport has
|
|
295
|
+
* removed the connection — a slow hook never holds a dead entry that
|
|
296
|
+
* broadcasts still target and the per-account cap still counts. Receives
|
|
297
|
+
* `connection_id` and `identity` captured at open time, the same whether the
|
|
298
|
+
* close came from the client, a revocation, or a connection-cap eviction.
|
|
299
|
+
* Errors are logged and swallowed.
|
|
158
300
|
*/
|
|
159
301
|
on_socket_close?: (ctx: SocketCloseContext) => void | Promise<void>;
|
|
160
302
|
/**
|
|
@@ -193,14 +335,24 @@ export interface RegisterActionWsResult {
|
|
|
193
335
|
* wrap iff `spec.side_effects: true`) → DEV output validation.
|
|
194
336
|
* - Authorization phase runs **per message** — role_grant changes during a
|
|
195
337
|
* connection lifetime are picked up on the next message without any
|
|
196
|
-
* in-place refresh. Authentication invalidation closes the socket
|
|
197
|
-
* `create_ws_auth_guard
|
|
338
|
+
* in-place refresh. Authentication invalidation closes the socket: the
|
|
339
|
+
* revocation handlers through `connection_closer`, and `create_ws_auth_guard`
|
|
340
|
+
* on the audit row.
|
|
341
|
+
* - Admission re-reads the credential once, after the handshake: a socket
|
|
342
|
+
* whose session or token was revoked while it was upgrading closes with
|
|
343
|
+
* `WS_CLOSE_SESSION_REVOKED`, and one whose re-check failed with
|
|
344
|
+
* `WS_CLOSE_INTERNAL_ERROR`. Frames sent before admission wait for it.
|
|
345
|
+
* - A socket the server has closed dispatches nothing more, whether or not
|
|
346
|
+
* its client answers the close.
|
|
198
347
|
*
|
|
199
348
|
* @returns the transport (supplied or freshly created) — retain it to wire
|
|
200
349
|
* `create_ws_auth_guard` or broadcast on audit events.
|
|
201
350
|
* @mutates options.app - registers a `GET path` route via `upgradeWebSocket`
|
|
202
|
-
* @mutates options.transport -
|
|
203
|
-
*
|
|
351
|
+
* @mutates options.transport - per socket, registers, admits, and removes a
|
|
352
|
+
* connection via `register_pending` / `admit` / `remove_connection`
|
|
353
|
+
* @mutates options.connection_closer - adds the endpoint's transport
|
|
354
|
+
* @throws Error when `max_connections_per_account` is passed alongside
|
|
355
|
+
* `transport`, or is neither `null` nor a positive integer
|
|
204
356
|
*/
|
|
205
357
|
export declare const register_action_ws: (options: RegisterActionWsOptions) => RegisterActionWsResult;
|
|
206
358
|
//# sourceMappingURL=register_action_ws.d.ts.map
|
|
@@ -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
|
|
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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"}
|