@orkestrel/middleware 0.0.18 → 0.0.20
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/README.md +20 -15
- package/dist/src/core/index.cjs +393 -312
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +497 -328
- package/dist/src/core/index.d.ts +497 -328
- package/dist/src/core/index.js +391 -311
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +486 -422
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +316 -232
- package/dist/src/server/index.d.ts +316 -232
- package/dist/src/server/index.js +478 -417
- package/dist/src/server/index.js.map +1 -1
- package/package.json +21 -23
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CookieOptions } from '@orkestrel/server';
|
|
3
|
-
import { Encoding } from '@orkestrel/server';
|
|
4
|
-
import { Guard } from '@orkestrel/contract';
|
|
1
|
+
import type { Connection } from '@orkestrel/server';
|
|
2
|
+
import type { CookieOptions } from '@orkestrel/server';
|
|
3
|
+
import type { Encoding } from '@orkestrel/server';
|
|
4
|
+
import type { Guard } from '@orkestrel/contract';
|
|
5
5
|
import { JSONShape } from '@orkestrel/contract';
|
|
6
|
-
import { MiddlewareContext } from '@orkestrel/server';
|
|
7
|
-
import { MiddlewareHandler } from '@orkestrel/server';
|
|
6
|
+
import type { MiddlewareContext } from '@orkestrel/server';
|
|
7
|
+
import type { MiddlewareHandler } from '@orkestrel/server';
|
|
8
8
|
import { NumberShape } from '@orkestrel/contract';
|
|
9
9
|
import { StringShape } from '@orkestrel/contract';
|
|
10
|
-
import { TableInterface } from '@orkestrel/database';
|
|
11
|
-
import { TokenSecret } from '@orkestrel/server';
|
|
10
|
+
import type { TableInterface } from '@orkestrel/database';
|
|
11
|
+
import type { TokenSecret } from '@orkestrel/server';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Configures `createBearer` — bearer-token authentication.
|
|
15
15
|
*
|
|
16
|
-
* @param options - See fields below
|
|
17
16
|
* @remarks
|
|
18
17
|
* - `secret` — the {@link TokenSecret} `verifyToken` checks the extracted
|
|
19
18
|
* token against (rotation-aware).
|
|
20
19
|
* - `header` — the header the token is read from; defaults to
|
|
21
20
|
* {@link DEFAULT_BEARER_HEADER}.
|
|
22
|
-
* - `scheme` — the scheme prefix stripped before verification
|
|
23
|
-
* insensitive); defaults to {@link DEFAULT_BEARER_SCHEME}. An empty
|
|
24
|
-
* means the whole header value is the raw token.
|
|
21
|
+
* - `scheme` — the scheme prefix stripped before verification
|
|
22
|
+
* (case-insensitive); defaults to {@link DEFAULT_BEARER_SCHEME}. An empty
|
|
23
|
+
* string means the whole header value is the raw token.
|
|
25
24
|
*/
|
|
26
25
|
export declare interface BearerOptions {
|
|
27
26
|
readonly secret: TokenSecret;
|
|
@@ -30,7 +29,7 @@ export declare interface BearerOptions {
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
|
-
*
|
|
32
|
+
* Describes the bearer-authentication state slice `createBearer` stashes on
|
|
34
33
|
* `context.state` once a token verifies.
|
|
35
34
|
*
|
|
36
35
|
* @remarks
|
|
@@ -43,7 +42,7 @@ export declare interface BearerState {
|
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
/**
|
|
46
|
-
*
|
|
45
|
+
* Describes the body state slice `createBody` stashes.
|
|
47
46
|
*
|
|
48
47
|
* @remarks
|
|
49
48
|
* `body` holds the same defined value the cached `context.body()` resolved
|
|
@@ -55,9 +54,8 @@ export declare interface BodyState {
|
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
/**
|
|
58
|
-
*
|
|
57
|
+
* Configures `createBoundary` — the outermost error-rendering battery.
|
|
59
58
|
*
|
|
60
|
-
* @param options - See fields below
|
|
61
59
|
* @remarks
|
|
62
60
|
* - `expose` — when `true`, a non-`HTTPError` throw's `error.message` is
|
|
63
61
|
* surfaced in the 500 body instead of a generic message. Defaults to
|
|
@@ -71,22 +69,22 @@ export declare interface BoundaryOptions {
|
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
72
|
+
* Builds the {@link Client} slice `createForwarded` stashes, from the
|
|
73
|
+
* resolved client IP — a leaf shaping helper.
|
|
76
74
|
*
|
|
77
75
|
* @param ip - The resolved client IP, if any
|
|
78
|
-
* @returns The {@link
|
|
76
|
+
* @returns The {@link Client} slice value
|
|
79
77
|
*
|
|
80
78
|
* @example
|
|
81
79
|
* ```ts
|
|
82
|
-
*
|
|
80
|
+
* buildClient('203.0.113.7') // { ip: '203.0.113.7' }
|
|
83
81
|
* ```
|
|
84
82
|
*/
|
|
85
|
-
export declare function
|
|
83
|
+
export declare function buildClient(ip: string | undefined): Client_2;
|
|
86
84
|
|
|
87
85
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
86
|
+
* Builds the draft `RateLimit` structured header field — emitted only when
|
|
87
|
+
* `createLimiter`'s `policy` option is `true`.
|
|
90
88
|
*
|
|
91
89
|
* @param remaining - The requests still admitted this window
|
|
92
90
|
* @param resetAt - The window reset instant (same clock unit as `now`)
|
|
@@ -101,8 +99,8 @@ export declare function buildClientInfo(ip: string | undefined): ClientInfo;
|
|
|
101
99
|
export declare function buildRateLimitField(remaining: number, resetAt: number, now: number): string;
|
|
102
100
|
|
|
103
101
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
102
|
+
* Builds the draft `RateLimit-Policy` structured header field — emitted only
|
|
103
|
+
* when `createLimiter`'s `policy` option is `true`.
|
|
106
104
|
*
|
|
107
105
|
* @param max - The window's admitted request count
|
|
108
106
|
* @param window - The window length in milliseconds
|
|
@@ -116,8 +114,8 @@ export declare function buildRateLimitField(remaining: number, resetAt: number,
|
|
|
116
114
|
export declare function buildRateLimitPolicyField(max: number, window: number): string;
|
|
117
115
|
|
|
118
116
|
/**
|
|
119
|
-
*
|
|
120
|
-
* floored at a minimum of `1
|
|
117
|
+
* Builds the `Retry-After` header value — whole seconds until a window reset,
|
|
118
|
+
* floored at a minimum of `1`.
|
|
121
119
|
*
|
|
122
120
|
* @param resetAt - The window reset instant (same clock unit as `now`)
|
|
123
121
|
* @param now - The current instant
|
|
@@ -131,26 +129,27 @@ export declare function buildRateLimitPolicyField(max: number, window: number):
|
|
|
131
129
|
export declare function buildRetryAfter(resetAt: number, now: number): string;
|
|
132
130
|
|
|
133
131
|
/**
|
|
134
|
-
*
|
|
132
|
+
* Describes the resolved client connection facts `createForwarded` stashes.
|
|
135
133
|
*
|
|
136
134
|
* @remarks
|
|
137
135
|
* `ip` is the first untrusted address walking `X-Forwarded-For` /
|
|
138
136
|
* `Forwarded` right-to-left past the configured trusted hops, falling back
|
|
139
137
|
* to the socket peer when no proxy hop qualifies.
|
|
140
138
|
*/
|
|
141
|
-
|
|
139
|
+
declare interface Client_2 {
|
|
142
140
|
readonly ip?: string;
|
|
143
141
|
}
|
|
142
|
+
export { Client_2 as Client }
|
|
144
143
|
|
|
145
144
|
/**
|
|
146
|
-
*
|
|
145
|
+
* Describes the client-facts state slice `createForwarded` stashes.
|
|
147
146
|
*/
|
|
148
147
|
export declare interface ClientState {
|
|
149
|
-
readonly client?:
|
|
148
|
+
readonly client?: Client_2;
|
|
150
149
|
}
|
|
151
150
|
|
|
152
151
|
/**
|
|
153
|
-
*
|
|
152
|
+
* Compresses bytes with the host-independent `CompressionStream` primitive.
|
|
154
153
|
*
|
|
155
154
|
* @param bytes - The uncompressed response bytes
|
|
156
155
|
* @param encoding - The negotiated actionable coding
|
|
@@ -166,14 +165,13 @@ export declare interface ClientState {
|
|
|
166
165
|
export declare function compressBytes(bytes: Uint8Array<ArrayBuffer>, encoding: Exclude<Encoding, 'identity'>): Promise<Uint8Array<ArrayBuffer>>;
|
|
167
166
|
|
|
168
167
|
/**
|
|
169
|
-
*
|
|
168
|
+
* Configures `createCompression` — response-body compression.
|
|
170
169
|
*
|
|
171
|
-
* @param options - See fields below
|
|
172
170
|
* @remarks
|
|
173
171
|
* - `threshold` — the minimum buffered body size (bytes) worth compressing;
|
|
174
172
|
* defaults to {@link DEFAULT_COMPRESSION_THRESHOLD}.
|
|
175
173
|
* - `encodings` — the codings offered, in preference order, intersected at
|
|
176
|
-
*
|
|
174
|
+
* construction with what the runtime's `CompressionStream` actually
|
|
177
175
|
* supports; defaults to {@link DEFAULT_COMPRESSION_ENCODINGS}.
|
|
178
176
|
* - `filter` — an optional per-response opt-out predicate (the BREACH
|
|
179
177
|
* posture escape hatch); a response the predicate declines is never
|
|
@@ -186,7 +184,7 @@ export declare interface CompressionOptions {
|
|
|
186
184
|
}
|
|
187
185
|
|
|
188
186
|
/**
|
|
189
|
-
*
|
|
187
|
+
* Runs the shared negotiate → skip → threshold → compress → header-set skeleton
|
|
190
188
|
* both faces' `createCompression` batteries compose — response-body
|
|
191
189
|
* compression over a caller-supplied set of feature-detected codings.
|
|
192
190
|
*
|
|
@@ -196,17 +194,17 @@ export declare interface CompressionOptions {
|
|
|
196
194
|
* even when a later skip declines to compress) → `negotiateEncoding` over
|
|
197
195
|
* `options.encodings` → {@link isCompressionNegotiated} → `isCompressibleType`
|
|
198
196
|
* on `Content-Type` → a fast skip when the response already carries a
|
|
199
|
-
* numeric `Content-Length`
|
|
200
|
-
* body known too small to be worth compressing) → buffer
|
|
197
|
+
* numeric `Content-Length` below `options.threshold` (avoids buffering a
|
|
198
|
+
* body known too small to be worth compressing) → buffer through
|
|
201
199
|
* `response.arrayBuffer()` → a threshold passthrough when the buffered size
|
|
202
200
|
* is still below `options.threshold` → `options.compress` → set
|
|
203
|
-
* `Content-Encoding` and a fresh `Content-Length`
|
|
201
|
+
* `Content-Encoding` and a fresh `Content-Length` through {@link rebuildResponse}.
|
|
204
202
|
* Returns `response` unchanged (aside from the `Vary` stamp) on any skip.
|
|
205
203
|
*
|
|
206
204
|
* @param request - The inbound `Request` (read for `Accept-Encoding`)
|
|
207
205
|
* @param context - The `MiddlewareContext` (read for `context.method`)
|
|
208
206
|
* @param response - The downstream `Response` to consider compressing
|
|
209
|
-
* @param options -
|
|
207
|
+
* @param options - See {@link CompressResponseOptions}
|
|
210
208
|
* @returns The original `response` when skipped, or a new compressed `Response`
|
|
211
209
|
*
|
|
212
210
|
* @example
|
|
@@ -218,27 +216,42 @@ export declare interface CompressionOptions {
|
|
|
218
216
|
* })
|
|
219
217
|
* ```
|
|
220
218
|
*/
|
|
221
|
-
export declare function compressResponse(request: Request, context: MiddlewareContext<unknown>, response: Response, options:
|
|
219
|
+
export declare function compressResponse(request: Request, context: MiddlewareContext<unknown>, response: Response, options: CompressResponseOptions): Promise<Response>;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Describes the already-resolved settings `compressResponse` runs its shared
|
|
223
|
+
* negotiate → skip → threshold → compress skeleton against — the shape each
|
|
224
|
+
* face's `createCompression` builds from its own option bag.
|
|
225
|
+
*
|
|
226
|
+
* @remarks
|
|
227
|
+
* - `threshold` — the minimum body size (bytes) worth compressing.
|
|
228
|
+
* - `filter` — the per-response opt-out predicate; absent allows every
|
|
229
|
+
* response.
|
|
230
|
+
* - `encodings` — the codings offered, in preference order, already narrowed
|
|
231
|
+
* to what this face can actually produce.
|
|
232
|
+
* - `compress` — the runtime's compression primitive for one negotiated
|
|
233
|
+
* coding.
|
|
234
|
+
*/
|
|
235
|
+
export declare interface CompressResponseOptions {
|
|
222
236
|
readonly threshold: number;
|
|
223
237
|
readonly filter?: (request: Request, response: Response) => boolean;
|
|
224
238
|
readonly encodings: readonly Encoding[];
|
|
225
239
|
readonly compress: (bytes: Uint8Array<ArrayBuffer>, encoding: Exclude<Encoding, 'identity'>) => Promise<Uint8Array<ArrayBuffer>>;
|
|
226
|
-
}
|
|
240
|
+
}
|
|
227
241
|
|
|
228
242
|
/**
|
|
229
|
-
*
|
|
243
|
+
* Describes the connection-facts state slice `createLimiter`'s default key derivation
|
|
230
244
|
* falls back to when neither {@link BearerState} nor {@link ClientState} is
|
|
231
245
|
* present — the raw socket peer surfaced on `context.state` by the server's
|
|
232
246
|
* `state` option.
|
|
233
247
|
*/
|
|
234
248
|
export declare interface ConnectionState {
|
|
235
|
-
readonly connection?:
|
|
249
|
+
readonly connection?: Connection;
|
|
236
250
|
}
|
|
237
251
|
|
|
238
252
|
/**
|
|
239
|
-
*
|
|
253
|
+
* Configures `createCookieTransport` — the signed-cookie {@link SessionTransportInterface}.
|
|
240
254
|
*
|
|
241
|
-
* @param options - See fields below
|
|
242
255
|
* @remarks
|
|
243
256
|
* - `name` — the cookie name; defaults to {@link DEFAULT_SESSION_COOKIE}.
|
|
244
257
|
* - `secret` — the {@link TokenSecret} the session id is signed with (`signToken`).
|
|
@@ -252,9 +265,8 @@ export declare interface CookieTransportOptions {
|
|
|
252
265
|
}
|
|
253
266
|
|
|
254
267
|
/**
|
|
255
|
-
*
|
|
268
|
+
* Configures `createCors` — Cross-Origin Resource Sharing.
|
|
256
269
|
*
|
|
257
|
-
* @param options - See fields below
|
|
258
270
|
* @remarks
|
|
259
271
|
* - `origin` — the allowed origin(s): `'*'` (default), a single origin
|
|
260
272
|
* string, or an allow-list `readonly string[]` (reflects the request
|
|
@@ -270,7 +282,8 @@ export declare interface CorsOptions {
|
|
|
270
282
|
}
|
|
271
283
|
|
|
272
284
|
/**
|
|
273
|
-
*
|
|
285
|
+
* Creates the bearer-token authentication battery — reads the token from its header and
|
|
286
|
+
* verifies it with `verifyToken`.
|
|
274
287
|
*
|
|
275
288
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link BearerState}
|
|
276
289
|
* @param options - See {@link BearerOptions}
|
|
@@ -286,7 +299,7 @@ export declare interface CorsOptions {
|
|
|
286
299
|
export declare function createBearer<TState extends BearerState>(options: BearerOptions): MiddlewareHandler<TState>;
|
|
287
300
|
|
|
288
301
|
/**
|
|
289
|
-
*
|
|
302
|
+
* Creates the body-driving battery — eagerly awaits the cached `context.body()` so
|
|
290
303
|
* its throws (or a malformed-JSON `undefined`) surface before the handler
|
|
291
304
|
* runs, and stashes the resolved value onto {@link BodyState.body}.
|
|
292
305
|
*
|
|
@@ -297,9 +310,8 @@ export declare function createBearer<TState extends BearerState>(options: Bearer
|
|
|
297
310
|
* @remarks
|
|
298
311
|
* The shipped `MiddlewareContext.body()` is a parameterless, server-owned
|
|
299
312
|
* cache (`ServerOptions.limit` governs its size cap) — this battery carries
|
|
300
|
-
* no `limit`/`decompression` options
|
|
301
|
-
*
|
|
302
|
-
* stashed from the SAME awaited call the 400 check reads — `context.body()`
|
|
313
|
+
* no `limit`/`decompression` options. `state.body` is
|
|
314
|
+
* stashed from the same awaited call the 400 check reads — `context.body()`
|
|
303
315
|
* is never invoked twice.
|
|
304
316
|
*
|
|
305
317
|
* @example
|
|
@@ -310,7 +322,7 @@ export declare function createBearer<TState extends BearerState>(options: Bearer
|
|
|
310
322
|
export declare function createBody<TState extends BodyState = BodyState>(): MiddlewareHandler<TState>;
|
|
311
323
|
|
|
312
324
|
/**
|
|
313
|
-
*
|
|
325
|
+
* Creates the outermost error-rendering battery — catches a downstream throw and
|
|
314
326
|
* renders it as a `Response`.
|
|
315
327
|
*
|
|
316
328
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
@@ -318,15 +330,26 @@ export declare function createBody<TState extends BodyState = BodyState>(): Midd
|
|
|
318
330
|
* @returns A `MiddlewareHandler<TState>`
|
|
319
331
|
* @throws {TypeError} When `options.expose` or `options.report` is malformed
|
|
320
332
|
*
|
|
321
|
-
* @example
|
|
333
|
+
* @example Mount a battery
|
|
322
334
|
* ```ts
|
|
335
|
+
* import { createBoundary, createSecurity } from '@orkestrel/middleware'
|
|
336
|
+
* import type { IdentifierState } from '@orkestrel/middleware'
|
|
337
|
+
* import { compose } from '@orkestrel/server'
|
|
338
|
+
*
|
|
339
|
+
* interface State extends IdentifierState {}
|
|
340
|
+
*
|
|
323
341
|
* const boundary = createBoundary({ expose: false })
|
|
342
|
+
* const security = createSecurity({ hsts: true })
|
|
343
|
+
*
|
|
344
|
+
* const handle = compose<State>([boundary, security], async (_request, context) => {
|
|
345
|
+
* return Response.json({ identifier: context.state.identifier })
|
|
346
|
+
* })
|
|
324
347
|
* ```
|
|
325
348
|
*/
|
|
326
349
|
export declare function createBoundary<TState>(options?: BoundaryOptions): MiddlewareHandler<TState>;
|
|
327
350
|
|
|
328
351
|
/**
|
|
329
|
-
*
|
|
352
|
+
* Creates the response-body compression battery — negotiates and compresses a buffered response
|
|
330
353
|
* body over the runtime's feature-detected `CompressionStream` codings.
|
|
331
354
|
*
|
|
332
355
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
@@ -342,11 +365,11 @@ export declare function createBoundary<TState>(options?: BoundaryOptions): Middl
|
|
|
342
365
|
export declare function createCompression<TState>(options?: CompressionOptions): MiddlewareHandler<TState>;
|
|
343
366
|
|
|
344
367
|
/**
|
|
345
|
-
*
|
|
368
|
+
* Creates a signed-cookie {@link SessionTransportInterface} — the session id travels as
|
|
346
369
|
* a `signToken`-signed cookie value.
|
|
347
370
|
*
|
|
348
371
|
* @param options - See {@link CookieTransportOptions}
|
|
349
|
-
* @returns A {@link
|
|
372
|
+
* @returns A {@link SessionTransportInterface}
|
|
350
373
|
* @throws {TypeError} When `options.secret` or `options.name` is malformed
|
|
351
374
|
*
|
|
352
375
|
* @example
|
|
@@ -354,10 +377,11 @@ export declare function createCompression<TState>(options?: CompressionOptions):
|
|
|
354
377
|
* const transport = createCookieTransport({ secret: 'shh' })
|
|
355
378
|
* ```
|
|
356
379
|
*/
|
|
357
|
-
export declare function createCookieTransport(options: CookieTransportOptions):
|
|
380
|
+
export declare function createCookieTransport(options: CookieTransportOptions): SessionTransportInterface;
|
|
358
381
|
|
|
359
382
|
/**
|
|
360
|
-
* Cross-Origin Resource Sharing battery
|
|
383
|
+
* Creates the Cross-Origin Resource Sharing battery — answers a preflight itself, and
|
|
384
|
+
* reflects an allow-listed origin or serves the configured wildcard.
|
|
361
385
|
*
|
|
362
386
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
363
387
|
* @param options - See {@link CorsOptions}
|
|
@@ -372,7 +396,7 @@ export declare function createCookieTransport(options: CookieTransportOptions):
|
|
|
372
396
|
export declare function createCors<TState>(options?: CorsOptions): MiddlewareHandler<TState>;
|
|
373
397
|
|
|
374
398
|
/**
|
|
375
|
-
*
|
|
399
|
+
* Creates the session-bound double-submit CSRF protection battery.
|
|
376
400
|
*
|
|
377
401
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link CSRFState}, {@link SessionState}, and {@link ConnectionState}
|
|
378
402
|
* @param options - See {@link CSRFOptions}
|
|
@@ -388,33 +412,33 @@ export declare function createCors<TState>(options?: CorsOptions): MiddlewareHan
|
|
|
388
412
|
export declare function createCSRF<TState extends CSRFState & SessionState & ConnectionState>(options: CSRFOptions): MiddlewareHandler<TState>;
|
|
389
413
|
|
|
390
414
|
/**
|
|
391
|
-
*
|
|
415
|
+
* Creates a {@link DatabaseSessionStore} as a {@link SessionStoreInterface} —
|
|
392
416
|
* the durable counterpart to `createMemorySessionStore`, over a caller-opened
|
|
393
417
|
* `@orkestrel/database` table (declare it with {@link sessionColumns}).
|
|
394
418
|
*
|
|
395
|
-
* @typeParam S - The session
|
|
419
|
+
* @typeParam S - The session entity type
|
|
396
420
|
* @param table - The backing `TableInterface<SessionRow>`
|
|
397
|
-
* @param
|
|
398
|
-
* @param options -
|
|
421
|
+
* @param guard - A {@link Guard} narrowing a restored snapshot to `S`
|
|
422
|
+
* @param options - See {@link SessionLimits}
|
|
399
423
|
* @returns A {@link SessionStoreInterface}
|
|
424
|
+
* @throws {TypeError} When `options.ttl` or `options.lifetime` is malformed
|
|
400
425
|
*
|
|
401
426
|
* @remarks
|
|
402
427
|
* This factory only wraps `new DatabaseSessionStore(...)` — it never opens a
|
|
403
428
|
* database or driver itself; the caller owns that lifecycle and passes in an
|
|
404
|
-
* already-open table.
|
|
429
|
+
* already-open table. It supplies {@link createRestoredSession} as the store's
|
|
430
|
+
* snapshot rebuild step, which is why the store imports nothing from this
|
|
431
|
+
* file.
|
|
405
432
|
*
|
|
406
433
|
* @example
|
|
407
434
|
* ```ts
|
|
408
435
|
* const store = createDatabaseSessionStore(db.table('sessions'), isSession, { ttl: 60_000 })
|
|
409
436
|
* ```
|
|
410
437
|
*/
|
|
411
|
-
export declare function createDatabaseSessionStore<S extends SessionInterface = Session>(table: TableInterface<SessionRow>,
|
|
412
|
-
readonly ttl?: number;
|
|
413
|
-
readonly lifetime?: number;
|
|
414
|
-
}): SessionStoreInterface<S>;
|
|
438
|
+
export declare function createDatabaseSessionStore<S extends SessionInterface = Session>(table: TableInterface<SessionRow>, guard: Guard<S>, options?: SessionLimits): SessionStoreInterface<S>;
|
|
415
439
|
|
|
416
440
|
/**
|
|
417
|
-
*
|
|
441
|
+
* Creates the application-level per-request deadline battery.
|
|
418
442
|
*
|
|
419
443
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
420
444
|
* @param options - See {@link DeadlineOptions}
|
|
@@ -422,9 +446,9 @@ export declare function createDatabaseSessionStore<S extends SessionInterface =
|
|
|
422
446
|
* @throws {TypeError} When `options.ms` or `options.status` is malformed
|
|
423
447
|
*
|
|
424
448
|
* @remarks
|
|
425
|
-
*
|
|
449
|
+
* Mount this battery outside `createBody` in the chain — it reconstructs the inbound
|
|
426
450
|
* `Request` (to link its `signal` to the deadline `signal`), which throws if
|
|
427
|
-
* the body was already consumed upstream (
|
|
451
|
+
* the body was already consumed upstream (for example by `createBody`'s cached read).
|
|
428
452
|
*
|
|
429
453
|
* @example
|
|
430
454
|
* ```ts
|
|
@@ -434,7 +458,7 @@ export declare function createDatabaseSessionStore<S extends SessionInterface =
|
|
|
434
458
|
export declare function createDeadline<TState>(options: DeadlineOptions): MiddlewareHandler<TState>;
|
|
435
459
|
|
|
436
460
|
/**
|
|
437
|
-
*
|
|
461
|
+
* Creates the dynamic response `ETag` + conditional GET battery (RFC 7232).
|
|
438
462
|
*
|
|
439
463
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
440
464
|
* @param options - See {@link ETagOptions}
|
|
@@ -449,7 +473,8 @@ export declare function createDeadline<TState>(options: DeadlineOptions): Middle
|
|
|
449
473
|
export declare function createETag<TState>(options?: ETagOptions): MiddlewareHandler<TState>;
|
|
450
474
|
|
|
451
475
|
/**
|
|
452
|
-
*
|
|
476
|
+
* Creates the trusted-proxy client-IP resolver battery — walks `X-Forwarded-For` past
|
|
477
|
+
* the hops its options declare trusted.
|
|
453
478
|
*
|
|
454
479
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link ClientState} and {@link ConnectionState}
|
|
455
480
|
* @param options - See {@link ForwardedOptions}
|
|
@@ -464,11 +489,11 @@ export declare function createETag<TState>(options?: ETagOptions): MiddlewareHan
|
|
|
464
489
|
export declare function createForwarded<TState extends ClientState & ConnectionState>(options: ForwardedOptions): MiddlewareHandler<TState>;
|
|
465
490
|
|
|
466
491
|
/**
|
|
467
|
-
*
|
|
492
|
+
* Creates a bare-header {@link SessionTransportInterface} — the session id travels
|
|
468
493
|
* verbatim in a request/response header.
|
|
469
494
|
*
|
|
470
495
|
* @param options - See {@link HeaderTransportOptions}
|
|
471
|
-
* @returns A {@link
|
|
496
|
+
* @returns A {@link SessionTransportInterface}
|
|
472
497
|
* @throws {TypeError} When `options.header` is malformed
|
|
473
498
|
*
|
|
474
499
|
* @example
|
|
@@ -476,10 +501,11 @@ export declare function createForwarded<TState extends ClientState & ConnectionS
|
|
|
476
501
|
* const transport = createHeaderTransport()
|
|
477
502
|
* ```
|
|
478
503
|
*/
|
|
479
|
-
export declare function createHeaderTransport(options?: HeaderTransportOptions):
|
|
504
|
+
export declare function createHeaderTransport(options?: HeaderTransportOptions): SessionTransportInterface;
|
|
480
505
|
|
|
481
506
|
/**
|
|
482
|
-
*
|
|
507
|
+
* Creates the fixed-window rate-limiting battery — checks a key's budget before
|
|
508
|
+
* consuming it, so one window admits exactly `max` requests.
|
|
483
509
|
*
|
|
484
510
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link BearerState}, {@link ClientState}, and {@link ConnectionState}
|
|
485
511
|
* @param options - See {@link LimiterOptions}
|
|
@@ -494,28 +520,43 @@ export declare function createHeaderTransport(options?: HeaderTransportOptions):
|
|
|
494
520
|
export declare function createLimiter<TState extends BearerState & ClientState & ConnectionState>(options: LimiterOptions<TState>): MiddlewareHandler<TState>;
|
|
495
521
|
|
|
496
522
|
/**
|
|
497
|
-
*
|
|
523
|
+
* Creates the default in-process {@link SessionStoreInterface} — a `Map`-backed
|
|
498
524
|
* store enforcing an idle timeout and an absolute lifetime.
|
|
499
525
|
*
|
|
500
|
-
* @typeParam S - The session
|
|
526
|
+
* @typeParam S - The session entity type
|
|
501
527
|
* @param options - See {@link MemorySessionStoreOptions}
|
|
502
528
|
* @returns A {@link SessionStoreInterface}
|
|
503
529
|
* @throws {TypeError} When `options.ttl` or `options.lifetime` is malformed
|
|
504
530
|
*
|
|
505
531
|
* @remarks
|
|
506
|
-
* The {@link
|
|
507
|
-
*
|
|
508
|
-
* factory — the name `createSession` belongs to the battery, not this class.
|
|
532
|
+
* The store holds whatever {@link SessionInterface} entity `createSession`'s
|
|
533
|
+
* `create` option produced, keyed by that entity's own `id`.
|
|
509
534
|
*
|
|
510
535
|
* @example
|
|
511
536
|
* ```ts
|
|
512
537
|
* const store = createMemorySessionStore({ ttl: 60_000 })
|
|
513
538
|
* ```
|
|
514
539
|
*/
|
|
515
|
-
export declare function createMemorySessionStore<S>(options?: MemorySessionStoreOptions): SessionStoreInterface<S>;
|
|
540
|
+
export declare function createMemorySessionStore<S extends SessionInterface>(options?: MemorySessionStoreOptions): SessionStoreInterface<S>;
|
|
516
541
|
|
|
517
542
|
/**
|
|
518
|
-
*
|
|
543
|
+
* Rebuilds a {@link Session} from an untrusted snapshot value — the inverse of
|
|
544
|
+
* `snapshotSession` and a durable store's `get` deserialization step.
|
|
545
|
+
*
|
|
546
|
+
* @param value - The candidate snapshot, of unknown shape
|
|
547
|
+
* @returns A rebuilt {@link Session}, or `undefined` when `value` is malformed
|
|
548
|
+
*
|
|
549
|
+
* @example
|
|
550
|
+
* ```ts
|
|
551
|
+
* createRestoredSession({ id: 'abc', state: { userId: 'u_1' } }) // Session { id: 'abc' }
|
|
552
|
+
* createRestoredSession({ id: 1 }) // undefined
|
|
553
|
+
* ```
|
|
554
|
+
*/
|
|
555
|
+
export declare function createRestoredSession(value: unknown): Session | undefined;
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Creates the security-headers + request-identifier battery — sets each documented
|
|
559
|
+
* header default, and mints or echoes a request identifier.
|
|
519
560
|
*
|
|
520
561
|
* @typeParam TState - The consumer's opaque per-request state type, must carry {@link IdentifierState}
|
|
521
562
|
* @param options - See {@link SecurityOptions}
|
|
@@ -530,7 +571,7 @@ export declare function createMemorySessionStore<S>(options?: MemorySessionStore
|
|
|
530
571
|
export declare function createSecurity<TState extends IdentifierState>(options?: SecurityOptions): MiddlewareHandler<TState>;
|
|
531
572
|
|
|
532
573
|
/**
|
|
533
|
-
*
|
|
574
|
+
* Creates the generic session battery — resolves, mints, and persists a session
|
|
534
575
|
* across the request, with a mid-handler `regenerate`/`destroy` control handle.
|
|
535
576
|
*
|
|
536
577
|
* @typeParam S - The session entity type the store persists (must implement {@link SessionInterface})
|
|
@@ -538,7 +579,7 @@ export declare function createSecurity<TState extends IdentifierState>(options?:
|
|
|
538
579
|
* @param options - See {@link SessionOptions}
|
|
539
580
|
* @returns A `MiddlewareHandler<TState>`
|
|
540
581
|
* @throws {TypeError} When any option is malformed
|
|
541
|
-
* @throws {HTTPError} `404` when `
|
|
582
|
+
* @throws {HTTPError} `404` when `required` is set and no session resolves or mints
|
|
542
583
|
*
|
|
543
584
|
* @example
|
|
544
585
|
* ```ts
|
|
@@ -548,7 +589,7 @@ export declare function createSecurity<TState extends IdentifierState>(options?:
|
|
|
548
589
|
export declare function createSession<S extends SessionInterface = SessionInterface, TState extends SessionState & ConnectionState = SessionState & ConnectionState>(options: SessionOptions<S, TState>): MiddlewareHandler<TState>;
|
|
549
590
|
|
|
550
591
|
/**
|
|
551
|
-
*
|
|
592
|
+
* Creates the access-log/timing seam — records one {@link TelemetryEntry} per request
|
|
552
593
|
* after the response settles.
|
|
553
594
|
*
|
|
554
595
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
@@ -564,9 +605,8 @@ export declare function createSession<S extends SessionInterface = SessionInterf
|
|
|
564
605
|
export declare function createTelemetry<TState>(options: TelemetryOptions): MiddlewareHandler<TState>;
|
|
565
606
|
|
|
566
607
|
/**
|
|
567
|
-
*
|
|
608
|
+
* Configures `createCSRF` — session-bound double-submit CSRF protection.
|
|
568
609
|
*
|
|
569
|
-
* @param options - See fields below
|
|
570
610
|
* @remarks
|
|
571
611
|
* - `secret` — the {@link TokenSecret} the CSRF token is signed with.
|
|
572
612
|
* - `cookie` — the signed-cookie name; defaults to {@link DEFAULT_CSRF_COOKIE}.
|
|
@@ -587,7 +627,7 @@ export declare interface CSRFOptions {
|
|
|
587
627
|
}
|
|
588
628
|
|
|
589
629
|
/**
|
|
590
|
-
*
|
|
630
|
+
* Describes the CSRF state slice `createCSRF` stashes — the raw token a safe-method
|
|
591
631
|
* response exposes for a subsequent mutating request to submit back.
|
|
592
632
|
*/
|
|
593
633
|
export declare interface CSRFState {
|
|
@@ -595,26 +635,28 @@ export declare interface CSRFState {
|
|
|
595
635
|
}
|
|
596
636
|
|
|
597
637
|
/**
|
|
598
|
-
*
|
|
638
|
+
* Implements a durable {@link SessionStoreInterface} over an `@orkestrel/database`
|
|
599
639
|
* table — the same idle-timeout + absolute-lifetime contract as
|
|
600
640
|
* {@link MemorySessionStore}, backed by a caller-supplied `TableInterface`
|
|
601
641
|
* instead of an in-process `Map`.
|
|
602
642
|
*
|
|
603
|
-
* @typeParam S - The session
|
|
643
|
+
* @typeParam S - The stored session entity type
|
|
604
644
|
*
|
|
605
645
|
* @remarks
|
|
606
646
|
* `get` reads the row, evicts (removes the row) once `sessionExpired`
|
|
607
|
-
* reports either threshold elapsed, then rebuilds the session
|
|
608
|
-
*
|
|
609
|
-
* caller's
|
|
610
|
-
*
|
|
647
|
+
* reports either threshold elapsed, then rebuilds the session through the
|
|
648
|
+
* `restore` step it was constructed with — a malformed snapshot or one that
|
|
649
|
+
* fails the caller's guard resolves `undefined` rather than throwing.
|
|
650
|
+
* `createDatabaseSessionStore` supplies `createRestoredSession` as that step,
|
|
651
|
+
* so a caller reaching the factory never states it. A live read
|
|
652
|
+
* touches `seen`. `set` preserves an existing row's `created` across a
|
|
611
653
|
* re-`set` of the same id (stamped once at the first `set`), mirroring
|
|
612
654
|
* {@link MemorySessionStore}. `delete` of an absent id is a no-op (the
|
|
613
655
|
* table's `remove` contract).
|
|
614
656
|
*
|
|
615
|
-
* A malformed-snapshot or failed-guard `undefined`
|
|
657
|
+
* A malformed-snapshot or failed-guard `undefined` leaves the row in place —
|
|
616
658
|
* unlike the expired path, which removes it. This is deliberate: a
|
|
617
|
-
* caller-contextual
|
|
659
|
+
* caller-contextual guard may reject a session that is still perfectly
|
|
618
660
|
* valid for another flow reading the same table (a differently-shaped `S`,
|
|
619
661
|
* a stricter guard mid-rollout), so `get` never destroys data on a guard
|
|
620
662
|
* miss. A row that no caller's guard ever accepts again self-heals once its
|
|
@@ -622,28 +664,26 @@ export declare interface CSRFState {
|
|
|
622
664
|
*
|
|
623
665
|
* @example
|
|
624
666
|
* ```ts
|
|
625
|
-
* const store = new DatabaseSessionStore(table, isSession, {
|
|
626
|
-
*
|
|
667
|
+
* const store = new DatabaseSessionStore(table, isSession, createRestoredSession, {
|
|
668
|
+
* ttl: 60_000,
|
|
669
|
+
* })
|
|
670
|
+
* await store.set(new Session('abc'), Date.now())
|
|
627
671
|
* ```
|
|
628
672
|
*/
|
|
629
673
|
export declare class DatabaseSessionStore<S extends SessionInterface = Session> implements SessionStoreInterface<S> {
|
|
630
674
|
#private;
|
|
631
|
-
constructor(table: TableInterface<SessionRow>,
|
|
632
|
-
readonly ttl?: number;
|
|
633
|
-
readonly lifetime?: number;
|
|
634
|
-
});
|
|
675
|
+
constructor(table: TableInterface<SessionRow>, guard: Guard<S>, restore: SessionRestoreFunction, options?: SessionLimits);
|
|
635
676
|
get(id: string, now: number): Promise<S | undefined>;
|
|
636
|
-
set(
|
|
677
|
+
set(session: S, now: number): Promise<void>;
|
|
637
678
|
delete(id: string): Promise<void>;
|
|
638
679
|
}
|
|
639
680
|
|
|
640
681
|
/**
|
|
641
|
-
*
|
|
682
|
+
* Configures `createDeadline` — the application-level per-request deadline.
|
|
642
683
|
*
|
|
643
|
-
* @param options - See fields below
|
|
644
684
|
* @remarks
|
|
645
|
-
* - `ms` — the deadline in milliseconds, armed
|
|
646
|
-
* linked to the request's `signal`
|
|
685
|
+
* - `ms` — the deadline in milliseconds, armed through `@orkestrel/timeout` and
|
|
686
|
+
* linked to the request's `signal` through `@orkestrel/abort`'s `linkSignal`.
|
|
647
687
|
* - `status` — the response status returned when the deadline fires before
|
|
648
688
|
* the downstream chain settles; defaults to {@link DEFAULT_DEADLINE_STATUS}.
|
|
649
689
|
*/
|
|
@@ -652,22 +692,22 @@ export declare interface DeadlineOptions {
|
|
|
652
692
|
readonly status?: number;
|
|
653
693
|
}
|
|
654
694
|
|
|
655
|
-
/**
|
|
695
|
+
/** Names `'authorization'`, the default header `createBearer` reads the token from. */
|
|
656
696
|
export declare const DEFAULT_BEARER_HEADER = "authorization";
|
|
657
697
|
|
|
658
|
-
/**
|
|
698
|
+
/** Names `'Bearer'`, the default scheme prefix `createBearer` strips before verification. */
|
|
659
699
|
export declare const DEFAULT_BEARER_SCHEME = "Bearer";
|
|
660
700
|
|
|
661
|
-
/**
|
|
701
|
+
/** Holds `'?1'`, the default `Origin-Agent-Cluster` value `createSecurity` sets. */
|
|
662
702
|
export declare const DEFAULT_CLUSTER = "?1";
|
|
663
703
|
|
|
664
|
-
/**
|
|
704
|
+
/** Holds `'require-corp'`, the value `createSecurity` sets for `Cross-Origin-Embedder-Policy` when `coep: true`. */
|
|
665
705
|
export declare const DEFAULT_COEP = "require-corp";
|
|
666
706
|
|
|
667
707
|
/**
|
|
668
|
-
*
|
|
669
|
-
* intersected at construction with what the runtime's
|
|
670
|
-
* actually supports.
|
|
708
|
+
* Lists `['gzip', 'deflate']`, the default content-codings `createCompression` offers in
|
|
709
|
+
* preference order — intersected at construction with what the runtime's
|
|
710
|
+
* `CompressionStream` actually supports.
|
|
671
711
|
*
|
|
672
712
|
* @remarks
|
|
673
713
|
* The shipped `@orkestrel/server` peer's {@link Encoding} union is
|
|
@@ -678,76 +718,76 @@ export declare const DEFAULT_COEP = "require-corp";
|
|
|
678
718
|
*/
|
|
679
719
|
export declare const DEFAULT_COMPRESSION_ENCODINGS: readonly Encoding[];
|
|
680
720
|
|
|
681
|
-
/**
|
|
721
|
+
/** Holds `1024`, the default minimum buffered body size in bytes `createCompression` will compress. */
|
|
682
722
|
export declare const DEFAULT_COMPRESSION_THRESHOLD = 1024;
|
|
683
723
|
|
|
684
|
-
/**
|
|
724
|
+
/** Holds `'same-origin'`, the default `Cross-Origin-Opener-Policy` value `createSecurity` sets. */
|
|
685
725
|
export declare const DEFAULT_COOP = "same-origin";
|
|
686
726
|
|
|
687
|
-
/**
|
|
727
|
+
/** Holds `'same-origin'`, the default `Cross-Origin-Resource-Policy` value `createSecurity` sets. */
|
|
688
728
|
export declare const DEFAULT_CORP = "same-origin";
|
|
689
729
|
|
|
690
|
-
/**
|
|
730
|
+
/** Lists the default headers `createCors` advertises on a preflight response. */
|
|
691
731
|
export declare const DEFAULT_CORS_HEADERS: readonly string[];
|
|
692
732
|
|
|
693
|
-
/**
|
|
733
|
+
/** Lists the default methods `createCors` advertises on a preflight response. */
|
|
694
734
|
export declare const DEFAULT_CORS_METHODS: readonly string[];
|
|
695
735
|
|
|
696
736
|
/**
|
|
697
|
-
*
|
|
698
|
-
* `
|
|
737
|
+
* Holds `"default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'; form-action 'self'"`,
|
|
738
|
+
* the default `Content-Security-Policy` value `createSecurity` sets — a custom
|
|
739
|
+
* `csp` option replaces this wholesale, never merges.
|
|
699
740
|
*/
|
|
700
741
|
export declare const DEFAULT_CSP = "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'; form-action 'self'";
|
|
701
742
|
|
|
702
|
-
/**
|
|
743
|
+
/** Names `'csrf'`, the default signed cookie `createCSRF` writes the CSRF token under. */
|
|
703
744
|
export declare const DEFAULT_CSRF_COOKIE = "csrf";
|
|
704
745
|
|
|
705
|
-
/**
|
|
746
|
+
/** Names `'_csrf'`, the default body field `createCSRF` falls back to reading a mutating request's submitted token from. */
|
|
706
747
|
export declare const DEFAULT_CSRF_FIELD = "_csrf";
|
|
707
748
|
|
|
708
|
-
/**
|
|
749
|
+
/** Names `'x-csrf-token'`, the default header `createCSRF` reads a mutating request's submitted token from. */
|
|
709
750
|
export declare const DEFAULT_CSRF_HEADER = "x-csrf-token";
|
|
710
751
|
|
|
711
|
-
/**
|
|
752
|
+
/** Lists `['GET', 'HEAD', 'OPTIONS']`, the default methods `createCSRF` treats as safe (mint instead of verify). */
|
|
712
753
|
export declare const DEFAULT_CSRF_SAFE_METHODS: readonly string[];
|
|
713
754
|
|
|
714
|
-
/**
|
|
755
|
+
/** Holds `503`, the default response status `createDeadline` returns when its deadline fires first. */
|
|
715
756
|
export declare const DEFAULT_DEADLINE_STATUS = 503;
|
|
716
757
|
|
|
717
|
-
/**
|
|
758
|
+
/** Holds `'DENY'`, the default `X-Frame-Options` value `createSecurity` sets. */
|
|
718
759
|
export declare const DEFAULT_FRAME_OPTIONS = "DENY";
|
|
719
760
|
|
|
720
|
-
/**
|
|
761
|
+
/** Holds `'max-age=31536000; includeSubDomains'`, the value `createSecurity` sets for `Strict-Transport-Security` when `hsts: true`. */
|
|
721
762
|
export declare const DEFAULT_HSTS = "max-age=31536000; includeSubDomains";
|
|
722
763
|
|
|
723
|
-
/**
|
|
764
|
+
/** Names `'x-request-id'`, the default header `createSecurity` mints or echoes a request identifier into. */
|
|
724
765
|
export declare const DEFAULT_IDENTIFIER_HEADER = "x-request-id";
|
|
725
766
|
|
|
726
|
-
/**
|
|
767
|
+
/** Holds `10_000`, the default maximum number of distinct rate-limit keys `createLimiter` tracks before LRU eviction. */
|
|
727
768
|
export declare const DEFAULT_LIMITER_CAPACITY = 10000;
|
|
728
769
|
|
|
729
|
-
/**
|
|
770
|
+
/** Holds `'rate limit exceeded'`, the default 429 body message `createLimiter` sends when a key is over budget. */
|
|
730
771
|
export declare const DEFAULT_LIMITER_MESSAGE = "rate limit exceeded";
|
|
731
772
|
|
|
732
|
-
/**
|
|
773
|
+
/** Holds `'camera=(), microphone=(), geolocation=()'`, the default `Permissions-Policy` value `createSecurity` sets. */
|
|
733
774
|
export declare const DEFAULT_PERMISSIONS_POLICY = "camera=(), microphone=(), geolocation=()";
|
|
734
775
|
|
|
735
|
-
/**
|
|
776
|
+
/** Holds `'strict-origin-when-cross-origin'`, the default `Referrer-Policy` value `createSecurity` sets. */
|
|
736
777
|
export declare const DEFAULT_REFERRER_POLICY = "strict-origin-when-cross-origin";
|
|
737
778
|
|
|
738
|
-
/**
|
|
779
|
+
/** Holds `10_000`, the default maximum number of distinct session ids `createMemorySessionStore` tracks before LRU (by last write) eviction. */
|
|
739
780
|
export declare const DEFAULT_SESSION_CAPACITY = 10000;
|
|
740
781
|
|
|
741
|
-
/**
|
|
782
|
+
/** Names `'session'`, the default cookie `createCookieTransport` writes the signed session id under. */
|
|
742
783
|
export declare const DEFAULT_SESSION_COOKIE = "session";
|
|
743
784
|
|
|
744
|
-
/**
|
|
785
|
+
/** Names `'session-id'`, the default header `createHeaderTransport` carries the session id in. */
|
|
745
786
|
export declare const DEFAULT_SESSION_HEADER = "session-id";
|
|
746
787
|
|
|
747
788
|
/**
|
|
748
|
-
* Feature-
|
|
749
|
-
* actually supports — `createCompression`'s construction-time intersection
|
|
750
|
-
* (ruling J).
|
|
789
|
+
* Feature-detects which of `candidates` the runtime's `CompressionStream`
|
|
790
|
+
* actually supports — `createCompression`'s construction-time intersection.
|
|
751
791
|
*
|
|
752
792
|
* @remarks
|
|
753
793
|
* Probes each candidate with `new CompressionStream(candidate)` inside a
|
|
@@ -766,7 +806,7 @@ export declare const DEFAULT_SESSION_HEADER = "session-id";
|
|
|
766
806
|
export declare function detectEncodings(candidates: readonly Encoding[]): readonly Encoding[];
|
|
767
807
|
|
|
768
808
|
/**
|
|
769
|
-
*
|
|
809
|
+
* Compares two strings in constant time — `createCSRF`'s double-submit token
|
|
770
810
|
* comparison, avoiding a timing oracle on the submitted-vs-cookie match.
|
|
771
811
|
*
|
|
772
812
|
* @remarks
|
|
@@ -778,7 +818,7 @@ export declare function detectEncodings(candidates: readonly Encoding[]): readon
|
|
|
778
818
|
*
|
|
779
819
|
* @param a - The first string
|
|
780
820
|
* @param b - The second string
|
|
781
|
-
* @returns
|
|
821
|
+
* @returns True if `a` and `b` are exactly equal; false otherwise
|
|
782
822
|
*
|
|
783
823
|
* @example
|
|
784
824
|
* ```ts
|
|
@@ -789,9 +829,8 @@ export declare function detectEncodings(candidates: readonly Encoding[]): readon
|
|
|
789
829
|
export declare function equalsConstantTime(a: string, b: string): boolean;
|
|
790
830
|
|
|
791
831
|
/**
|
|
792
|
-
*
|
|
832
|
+
* Configures `createETag` — dynamic response ETag + conditional GET.
|
|
793
833
|
*
|
|
794
|
-
* @param options - See fields below
|
|
795
834
|
* @remarks
|
|
796
835
|
* - `weak` — mint a weak `W/"…"` ETag (default `true`) or a strong `"…"` one
|
|
797
836
|
* (`false`).
|
|
@@ -801,8 +840,8 @@ export declare interface ETagOptions {
|
|
|
801
840
|
}
|
|
802
841
|
|
|
803
842
|
/**
|
|
804
|
-
*
|
|
805
|
-
*
|
|
843
|
+
* Scopes a battery to every pathname outside a set of exact ones — on that set it
|
|
844
|
+
* steps aside through `next()`.
|
|
806
845
|
*
|
|
807
846
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
808
847
|
* @param paths - One pathname, or a set of pathnames, matched exactly against `context.url.pathname`
|
|
@@ -817,12 +856,11 @@ export declare interface ETagOptions {
|
|
|
817
856
|
export declare function except<TState>(paths: string | readonly string[], handler: MiddlewareHandler<TState>): MiddlewareHandler<TState>;
|
|
818
857
|
|
|
819
858
|
/**
|
|
820
|
-
*
|
|
859
|
+
* Configures `createForwarded` — the trusted-proxy client-IP resolver.
|
|
821
860
|
*
|
|
822
|
-
* @param options - See fields below
|
|
823
861
|
* @remarks
|
|
824
|
-
* Construction requires
|
|
825
|
-
*
|
|
862
|
+
* Construction requires either `proxies` or `trusted`, never both and never
|
|
863
|
+
* neither (a `TypeError` guards each):
|
|
826
864
|
* - `proxies` — trust exactly this many hops from the right of
|
|
827
865
|
* `X-Forwarded-For` / `Forwarded`.
|
|
828
866
|
* - `trusted` — trust every hop matching one of these CIDR entries.
|
|
@@ -834,9 +872,8 @@ export declare type ForwardedOptions = {
|
|
|
834
872
|
};
|
|
835
873
|
|
|
836
874
|
/**
|
|
837
|
-
*
|
|
875
|
+
* Configures `createHeaderTransport` — the bare-header {@link SessionTransportInterface}.
|
|
838
876
|
*
|
|
839
|
-
* @param options - See fields below
|
|
840
877
|
* @remarks
|
|
841
878
|
* - `header` — the header carrying the session id; defaults to
|
|
842
879
|
* {@link DEFAULT_SESSION_HEADER}.
|
|
@@ -846,7 +883,7 @@ export declare interface HeaderTransportOptions {
|
|
|
846
883
|
}
|
|
847
884
|
|
|
848
885
|
/**
|
|
849
|
-
*
|
|
886
|
+
* Describes the request-identifier state slice `createSecurity` stashes when its
|
|
850
887
|
* `identifier` option is enabled.
|
|
851
888
|
*/
|
|
852
889
|
export declare interface IdentifierState {
|
|
@@ -854,21 +891,22 @@ export declare interface IdentifierState {
|
|
|
854
891
|
}
|
|
855
892
|
|
|
856
893
|
/**
|
|
857
|
-
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
894
|
+
* Checks whether a response must skip the compression and ETag buffering pipeline
|
|
895
|
+
* — the shared cheap-skip predicate both batteries apply before ever touching
|
|
896
|
+
* `response.arrayBuffer()`, true for a `HEAD` request, a `204`/`304` or
|
|
897
|
+
* otherwise bodyless response, an `event-stream` response, and a response
|
|
898
|
+
* already carrying the header the caller is about to set.
|
|
860
899
|
*
|
|
861
900
|
* @remarks
|
|
862
|
-
*
|
|
863
|
-
*
|
|
864
|
-
*
|
|
865
|
-
*
|
|
866
|
-
* ETag battery).
|
|
901
|
+
* Buffering an `event-stream` response would hang the connection, so SSE skips
|
|
902
|
+
* whatever its size. `skipHeader` is the header whose presence already answers
|
|
903
|
+
* the question — `Content-Encoding` for compression, `ETag` for the ETag
|
|
904
|
+
* battery.
|
|
867
905
|
*
|
|
868
906
|
* @param method - The request's HTTP method
|
|
869
907
|
* @param response - The candidate response
|
|
870
908
|
* @param skipHeader - The response header whose presence means "already handled"
|
|
871
|
-
* @returns
|
|
909
|
+
* @returns True if the response must be left untouched; false otherwise
|
|
872
910
|
*
|
|
873
911
|
* @example
|
|
874
912
|
* ```ts
|
|
@@ -878,11 +916,11 @@ export declare interface IdentifierState {
|
|
|
878
916
|
export declare function isBufferingIneligible(method: string, response: Response, skipHeader: string): boolean;
|
|
879
917
|
|
|
880
918
|
/**
|
|
881
|
-
*
|
|
882
|
-
* `createCompression`'s negotiation-eligibility half of
|
|
919
|
+
* Checks whether a negotiated `Accept-Encoding` outcome is worth acting on —
|
|
920
|
+
* `createCompression`'s negotiation-eligibility half of the skip list.
|
|
883
921
|
*
|
|
884
922
|
* @param encoding - The negotiated coding, or `undefined` when negotiation failed
|
|
885
|
-
* @returns
|
|
923
|
+
* @returns True if `encoding` names an actionable, non-`identity` coding; false otherwise
|
|
886
924
|
*
|
|
887
925
|
* @example
|
|
888
926
|
* ```ts
|
|
@@ -893,12 +931,12 @@ export declare function isBufferingIneligible(method: string, response: Response
|
|
|
893
931
|
export declare function isCompressionNegotiated(encoding: Encoding | undefined): encoding is Exclude<Encoding, 'identity'>;
|
|
894
932
|
|
|
895
933
|
/**
|
|
896
|
-
*
|
|
897
|
-
* structural guard
|
|
934
|
+
* Determines whether a value implements {@link MultipartBody} — a total
|
|
935
|
+
* structural guard: `files` keyed by field name to arrays of
|
|
898
936
|
* {@link MultipartFile}, and a `fields` string record.
|
|
899
937
|
*
|
|
900
938
|
* @param value - The candidate value
|
|
901
|
-
* @returns
|
|
939
|
+
* @returns True if `value` is shaped like a {@link MultipartBody}; false otherwise
|
|
902
940
|
*
|
|
903
941
|
* @example
|
|
904
942
|
* ```ts
|
|
@@ -908,21 +946,34 @@ export declare function isCompressionNegotiated(encoding: Encoding | undefined):
|
|
|
908
946
|
export declare function isMultipartBody(value: unknown): value is MultipartBody;
|
|
909
947
|
|
|
910
948
|
/**
|
|
911
|
-
*
|
|
912
|
-
* total structural guard
|
|
949
|
+
* Determines whether a value is one staged {@link MultipartFile} record — a
|
|
950
|
+
* total structural guard checking every required field's shape.
|
|
913
951
|
*
|
|
914
952
|
* @param value - The candidate value
|
|
915
|
-
* @returns
|
|
953
|
+
* @returns True if `value` is shaped like a {@link MultipartFile}; false otherwise
|
|
954
|
+
*
|
|
955
|
+
* @example
|
|
956
|
+
* ```ts
|
|
957
|
+
* isMultipartFile({
|
|
958
|
+
* field: 'avatar',
|
|
959
|
+
* name: 'a.png',
|
|
960
|
+
* size: 3,
|
|
961
|
+
* mime: 'image/png',
|
|
962
|
+
* validated: true,
|
|
963
|
+
* status: 'staged',
|
|
964
|
+
* path: '/tmp/a',
|
|
965
|
+
* }) // true
|
|
966
|
+
* ```
|
|
916
967
|
*/
|
|
917
968
|
export declare function isMultipartFile(value: unknown): value is MultipartFile;
|
|
918
969
|
|
|
919
970
|
/**
|
|
920
|
-
*
|
|
971
|
+
* Determines whether a request is a CORS preflight — an `OPTIONS` request
|
|
921
972
|
* carrying an `Access-Control-Request-Method` header.
|
|
922
973
|
*
|
|
923
974
|
* @param method - The request's HTTP method
|
|
924
975
|
* @param headers - The request's `Headers`
|
|
925
|
-
* @returns
|
|
976
|
+
* @returns True if the request is a CORS preflight `createCors` must answer; false otherwise
|
|
926
977
|
*
|
|
927
978
|
* @example
|
|
928
979
|
* ```ts
|
|
@@ -932,29 +983,29 @@ export declare function isMultipartFile(value: unknown): value is MultipartFile;
|
|
|
932
983
|
export declare function isPreflight(method: string, headers: Headers): boolean;
|
|
933
984
|
|
|
934
985
|
/**
|
|
935
|
-
*
|
|
936
|
-
* structural guard
|
|
937
|
-
* — accepts a plain object, a
|
|
938
|
-
* (a real `Session`),
|
|
939
|
-
* instance
|
|
986
|
+
* Determines whether a value implements {@link SessionInterface} — a total
|
|
987
|
+
* structural guard: an `id` string, a `state` `Map`, and the `set`, `delete`,
|
|
988
|
+
* and `clear` mutators. Prototype-agnostic — accepts a plain object, a
|
|
989
|
+
* null-prototype object, and a class instance (a real `Session`), because a
|
|
990
|
+
* restored or stored session is routinely a class instance rather than a literal.
|
|
940
991
|
*
|
|
941
992
|
* @param value - The candidate value
|
|
942
|
-
* @returns
|
|
993
|
+
* @returns True if `value` is shaped like a {@link SessionInterface}; false otherwise
|
|
943
994
|
*
|
|
944
995
|
* @example
|
|
945
996
|
* ```ts
|
|
946
|
-
* isSession({ id: 'a', data: new Map() }) // true
|
|
947
997
|
* isSession(new Session('a')) // true
|
|
998
|
+
* isSession({ id: 'a', state: new Map() }) // false — the mutators are missing
|
|
948
999
|
* ```
|
|
949
1000
|
*/
|
|
950
1001
|
export declare function isSession(value: unknown): value is SessionInterface;
|
|
951
1002
|
|
|
952
1003
|
/**
|
|
953
|
-
*
|
|
954
|
-
* total structural guard
|
|
1004
|
+
* Determines whether a value implements {@link SessionControlInterface} — a
|
|
1005
|
+
* total structural guard: callable `regenerate` and `destroy`.
|
|
955
1006
|
*
|
|
956
1007
|
* @param value - The candidate value
|
|
957
|
-
* @returns
|
|
1008
|
+
* @returns True if `value` is shaped like a {@link SessionControlInterface}; false otherwise
|
|
958
1009
|
*
|
|
959
1010
|
* @example
|
|
960
1011
|
* ```ts
|
|
@@ -964,15 +1015,14 @@ export declare function isSession(value: unknown): value is SessionInterface;
|
|
|
964
1015
|
export declare function isSessionControl(value: unknown): value is SessionControlInterface;
|
|
965
1016
|
|
|
966
1017
|
/**
|
|
967
|
-
*
|
|
1018
|
+
* Configures `createLimiter` — fixed-window rate limiting.
|
|
968
1019
|
*
|
|
969
1020
|
* @typeParam TState - The consumer's opaque per-request state type `key` reads
|
|
970
|
-
* @param options - See fields below
|
|
971
1021
|
* @remarks
|
|
972
1022
|
* - `max` — the number of requests admitted per key per `window`.
|
|
973
1023
|
* - `window` — the window length in milliseconds.
|
|
974
1024
|
* - `capacity` — the maximum number of distinct keys tracked before the
|
|
975
|
-
* least-recently-used key is evicted (true LRU — every access, not
|
|
1025
|
+
* least-recently-used key is evicted (true LRU — every access, not only
|
|
976
1026
|
* insertion, refreshes recency); defaults to {@link DEFAULT_LIMITER_CAPACITY}.
|
|
977
1027
|
* - `key` — derives the bucket key from the request; defaults to the
|
|
978
1028
|
* bearer-token-then-client-IP idiom (see the battery's guide).
|
|
@@ -997,7 +1047,7 @@ export declare interface LimiterOptions<TState = unknown> {
|
|
|
997
1047
|
}
|
|
998
1048
|
|
|
999
1049
|
/**
|
|
1000
|
-
*
|
|
1050
|
+
* Checks whether a candidate address is a bare (non-CIDR) trusted-hop match — an
|
|
1001
1051
|
* exact string match, or a simple prefix-CIDR match for IPv4 (`/8`–`/32`).
|
|
1002
1052
|
* An IPv6 entry matches by exact string only — there is no IPv6 CIDR
|
|
1003
1053
|
* support.
|
|
@@ -1009,14 +1059,14 @@ export declare interface LimiterOptions<TState = unknown> {
|
|
|
1009
1059
|
* never claims full CIDR generality beyond IPv4.
|
|
1010
1060
|
*
|
|
1011
1061
|
* @remarks
|
|
1012
|
-
* An IPv6 `trusted` roster entry is compared as an
|
|
1062
|
+
* An IPv6 `trusted` roster entry is compared as an exact string — it must be
|
|
1013
1063
|
* supplied in canonical form (no zero-compression normalization, no case
|
|
1014
1064
|
* folding) by the caller; this function performs no IPv6 normalization of
|
|
1015
1065
|
* its own.
|
|
1016
1066
|
*
|
|
1017
1067
|
* @param address - The candidate hop address
|
|
1018
1068
|
* @param entry - One `trusted` roster entry — an exact address or an IPv4 CIDR
|
|
1019
|
-
* @returns
|
|
1069
|
+
* @returns True if `address` is covered by `entry`; false otherwise
|
|
1020
1070
|
*
|
|
1021
1071
|
* @example
|
|
1022
1072
|
* ```ts
|
|
@@ -1027,18 +1077,18 @@ export declare interface LimiterOptions<TState = unknown> {
|
|
|
1027
1077
|
export declare function matchesTrustedEntry(address: string, entry: string): boolean;
|
|
1028
1078
|
|
|
1029
1079
|
/**
|
|
1030
|
-
*
|
|
1080
|
+
* Implements the default in-process {@link SessionStoreInterface} — a `Map`-backed store
|
|
1031
1081
|
* enforcing both an idle timeout and an absolute lifetime, with lazy
|
|
1032
1082
|
* (read-time) eviction, a bounded capacity, and no background timers.
|
|
1033
1083
|
*
|
|
1034
|
-
* @typeParam S - The session
|
|
1084
|
+
* @typeParam S - The stored session entity type
|
|
1035
1085
|
*
|
|
1036
1086
|
* @remarks
|
|
1037
|
-
* `get` evicts a session whose idle time (`now -
|
|
1038
|
-
* absolute lifetime (`now -
|
|
1039
|
-
* lifetime check fires
|
|
1040
|
-
* `
|
|
1041
|
-
* later re-`set` of the same id. A live read touches `
|
|
1087
|
+
* `get` evicts a session whose idle time (`now - seen >= ttl`) or
|
|
1088
|
+
* absolute lifetime (`now - created >= lifetime`) has elapsed — the
|
|
1089
|
+
* lifetime check fires even if the session was continuously touched, because
|
|
1090
|
+
* `created` is stamped once at the first `set` and preserved across every
|
|
1091
|
+
* later re-`set` of the same id. A live read touches `seen`. `delete` of
|
|
1042
1092
|
* an absent id is a no-op.
|
|
1043
1093
|
*
|
|
1044
1094
|
* Capacity is enforced as least-recently-used **by last write**: `set`
|
|
@@ -1053,21 +1103,20 @@ export declare function matchesTrustedEntry(address: string, entry: string): boo
|
|
|
1053
1103
|
* @example
|
|
1054
1104
|
* ```ts
|
|
1055
1105
|
* const store = new MemorySessionStore({ ttl: 60_000, lifetime: 3_600_000 })
|
|
1056
|
-
* await store.set('abc',
|
|
1106
|
+
* await store.set(new Session('abc'), Date.now())
|
|
1057
1107
|
* ```
|
|
1058
1108
|
*/
|
|
1059
|
-
export declare class MemorySessionStore<S> implements SessionStoreInterface<S> {
|
|
1109
|
+
export declare class MemorySessionStore<S extends SessionInterface> implements SessionStoreInterface<S> {
|
|
1060
1110
|
#private;
|
|
1061
1111
|
constructor(options?: MemorySessionStoreOptions);
|
|
1062
1112
|
get(id: string, now: number): Promise<S | undefined>;
|
|
1063
|
-
set(
|
|
1113
|
+
set(session: S, now: number): Promise<void>;
|
|
1064
1114
|
delete(id: string): Promise<void>;
|
|
1065
1115
|
}
|
|
1066
1116
|
|
|
1067
1117
|
/**
|
|
1068
|
-
*
|
|
1118
|
+
* Configures `createMemorySessionStore` — the default in-process {@link SessionStoreInterface}.
|
|
1069
1119
|
*
|
|
1070
|
-
* @param options - See fields below
|
|
1071
1120
|
* @remarks
|
|
1072
1121
|
* - `ttl` — the idle timeout in milliseconds (lazy eviction on `get`).
|
|
1073
1122
|
* - `lifetime` — the absolute lifetime in milliseconds from first `set`
|
|
@@ -1081,15 +1130,13 @@ export declare class MemorySessionStore<S> implements SessionStoreInterface<S> {
|
|
|
1081
1130
|
* sink only — it must never call back into the store (no re-entrant
|
|
1082
1131
|
* `get`/`set`); mutations during eviction are unsupported.
|
|
1083
1132
|
*/
|
|
1084
|
-
export declare interface MemorySessionStoreOptions {
|
|
1085
|
-
readonly ttl?: number;
|
|
1086
|
-
readonly lifetime?: number;
|
|
1133
|
+
export declare interface MemorySessionStoreOptions extends SessionLimits {
|
|
1087
1134
|
readonly capacity?: number;
|
|
1088
1135
|
readonly evict?: (id: string) => void;
|
|
1089
1136
|
}
|
|
1090
1137
|
|
|
1091
1138
|
/**
|
|
1092
|
-
*
|
|
1139
|
+
* Describes the parsed multipart request body `createMultipart` stashes — files keyed
|
|
1093
1140
|
* by their field name, plus every plain text field.
|
|
1094
1141
|
*/
|
|
1095
1142
|
export declare interface MultipartBody {
|
|
@@ -1098,7 +1145,7 @@ export declare interface MultipartBody {
|
|
|
1098
1145
|
}
|
|
1099
1146
|
|
|
1100
1147
|
/**
|
|
1101
|
-
*
|
|
1148
|
+
* Represents one staged multipart upload's public record — the shape the node-face
|
|
1102
1149
|
* `createMultipart` battery (`@orkestrel/middleware/server`) produces per
|
|
1103
1150
|
* uploaded file.
|
|
1104
1151
|
*
|
|
@@ -1106,7 +1153,7 @@ export declare interface MultipartBody {
|
|
|
1106
1153
|
* Declared here rather than in the node-bound server surface so the
|
|
1107
1154
|
* fetch/string-pure {@link MultipartState} slice — referenced by any
|
|
1108
1155
|
* environment narrowing `context.state` — never depends on the node face.
|
|
1109
|
-
* The server's concrete `
|
|
1156
|
+
* The server's concrete `UploadedFile` is structurally compatible
|
|
1110
1157
|
* with this shape.
|
|
1111
1158
|
*/
|
|
1112
1159
|
export declare interface MultipartFile {
|
|
@@ -1120,7 +1167,7 @@ export declare interface MultipartFile {
|
|
|
1120
1167
|
}
|
|
1121
1168
|
|
|
1122
1169
|
/**
|
|
1123
|
-
*
|
|
1170
|
+
* Describes the multipart state slice `createMultipart` stashes.
|
|
1124
1171
|
*
|
|
1125
1172
|
* @remarks
|
|
1126
1173
|
* Present only once `createMultipart` has fully parsed a multipart request.
|
|
@@ -1133,8 +1180,8 @@ export declare interface MultipartState {
|
|
|
1133
1180
|
}
|
|
1134
1181
|
|
|
1135
1182
|
/**
|
|
1136
|
-
*
|
|
1137
|
-
* steps aside
|
|
1183
|
+
* Scopes a battery to a set of exact pathnames and nowhere else — outside that set
|
|
1184
|
+
* it steps aside through `next()`.
|
|
1138
1185
|
*
|
|
1139
1186
|
* @typeParam TState - The consumer's opaque per-request state type
|
|
1140
1187
|
* @param paths - One pathname, or a set of pathnames, matched exactly against `context.url.pathname`
|
|
@@ -1149,7 +1196,7 @@ export declare interface MultipartState {
|
|
|
1149
1196
|
export declare function only<TState>(paths: string | readonly string[], handler: MiddlewareHandler<TState>): MiddlewareHandler<TState>;
|
|
1150
1197
|
|
|
1151
1198
|
/**
|
|
1152
|
-
*
|
|
1199
|
+
* Rebuilds a `Response` around a replacement body while preserving its
|
|
1153
1200
|
* status/statusText — the buffered-response reconstruction shared by the
|
|
1154
1201
|
* compression and ETag batteries after they have consumed
|
|
1155
1202
|
* `response.arrayBuffer()`.
|
|
@@ -1168,13 +1215,13 @@ export declare function only<TState>(paths: string | readonly string[], handler:
|
|
|
1168
1215
|
export declare function rebuildResponse(body: ConstructorParameters<typeof Response>[0], response: Response, headers?: ConstructorParameters<typeof Headers>[0]): Response;
|
|
1169
1216
|
|
|
1170
1217
|
/**
|
|
1171
|
-
*
|
|
1218
|
+
* Walks `X-Forwarded-For` right-to-left and resolves the first untrusted hop
|
|
1172
1219
|
* address — `createForwarded`'s core algorithm.
|
|
1173
1220
|
*
|
|
1174
1221
|
* @remarks
|
|
1175
1222
|
* Parses `X-Forwarded-For` only. With `proxies` set, trusts exactly that
|
|
1176
1223
|
* many hops counted from the right (the closest to this server) and returns
|
|
1177
|
-
* the next one left of them; with `trusted` set, trusts every
|
|
1224
|
+
* the next one left of them; with `trusted` set, trusts every consecutive
|
|
1178
1225
|
* hop from the right that matches one of the roster
|
|
1179
1226
|
* ({@link matchesTrustedEntry}) and returns the first hop that does not. If
|
|
1180
1227
|
* the rightmost hop (the immediate sender) does not match the roster, the
|
|
@@ -1184,7 +1231,7 @@ export declare function rebuildResponse(body: ConstructorParameters<typeof Respo
|
|
|
1184
1231
|
* socket peer).
|
|
1185
1232
|
*
|
|
1186
1233
|
* @param header - The raw `X-Forwarded-For` header value (comma-separated hops), if present
|
|
1187
|
-
* @param trust -
|
|
1234
|
+
* @param trust - The {@link ForwardedOptions} form in force — a trusted hop count or a `trusted` CIDR/exact roster
|
|
1188
1235
|
* @returns The first untrusted hop address, or `undefined` when none qualifies
|
|
1189
1236
|
*
|
|
1190
1237
|
* @example
|
|
@@ -1192,21 +1239,17 @@ export declare function rebuildResponse(body: ConstructorParameters<typeof Respo
|
|
|
1192
1239
|
* resolveForwardedFor('203.0.113.7, 10.0.0.1', { proxies: 1 }) // '203.0.113.7'
|
|
1193
1240
|
* ```
|
|
1194
1241
|
*/
|
|
1195
|
-
export declare function resolveForwardedFor(header: string | undefined, trust:
|
|
1196
|
-
readonly proxies: number;
|
|
1197
|
-
} | {
|
|
1198
|
-
readonly trusted: readonly string[];
|
|
1199
|
-
}): string | undefined;
|
|
1242
|
+
export declare function resolveForwardedFor(header: string | undefined, trust: ForwardedOptions): string | undefined;
|
|
1200
1243
|
|
|
1201
1244
|
/**
|
|
1202
|
-
*
|
|
1245
|
+
* Derives `createLimiter`'s default rate-limit bucket key from a request's
|
|
1203
1246
|
* resolved identity facts.
|
|
1204
1247
|
*
|
|
1205
1248
|
* @remarks
|
|
1206
1249
|
* Prefers a verified bearer token ({@link BearerState.token}) as
|
|
1207
1250
|
* `token:<value>`; else a resolved client IP ({@link ClientState.client.ip},
|
|
1208
1251
|
* set when `createForwarded` is mounted) or the raw socket peer
|
|
1209
|
-
* ({@link ConnectionState.connection.ip}) collapsed
|
|
1252
|
+
* ({@link ConnectionState.connection.ip}) collapsed through `computeClientKey`
|
|
1210
1253
|
* (IPv6 to its `/64` network) as `ip:<key>`; else the literal `ip:unknown`.
|
|
1211
1254
|
* Never reads `X-Forwarded-For` itself — that trust decision belongs solely
|
|
1212
1255
|
* to `createForwarded`.
|
|
@@ -1223,8 +1266,8 @@ export declare function resolveForwardedFor(header: string | undefined, trust: {
|
|
|
1223
1266
|
export declare function resolveKey(state: BearerState & ClientState & ConnectionState): string;
|
|
1224
1267
|
|
|
1225
1268
|
/**
|
|
1226
|
-
*
|
|
1227
|
-
* (default
|
|
1269
|
+
* Resolves an opt-in, value-bearing security header — `string | boolean`
|
|
1270
|
+
* (off by default, `true` uses the secure default), the shape `createSecurity`'s
|
|
1228
1271
|
* `coep`/`hsts` options use, distinct from the plain value-or-`false` shape
|
|
1229
1272
|
* `resolveSecurityHeader` (the peer substrate) handles.
|
|
1230
1273
|
*
|
|
@@ -1241,22 +1284,7 @@ export declare function resolveKey(state: BearerState & ClientState & Connection
|
|
|
1241
1284
|
export declare function resolveOptInHeader(value: string | boolean | undefined, fallback: string): string | undefined;
|
|
1242
1285
|
|
|
1243
1286
|
/**
|
|
1244
|
-
*
|
|
1245
|
-
* {@link snapshotSession}) — a durable store's `get` deserialization step.
|
|
1246
|
-
*
|
|
1247
|
-
* @param value - The candidate snapshot, of unknown shape
|
|
1248
|
-
* @returns A rebuilt `Session`, or `undefined` when `value` is malformed
|
|
1249
|
-
*
|
|
1250
|
-
* @example
|
|
1251
|
-
* ```ts
|
|
1252
|
-
* restoreSession({ id: 'abc', data: { userId: 'u_1' } }) // Session { id: 'abc', data: Map }
|
|
1253
|
-
* restoreSession({ id: 1 }) // undefined
|
|
1254
|
-
* ```
|
|
1255
|
-
*/
|
|
1256
|
-
export declare function restoreSession(value: unknown): Session | undefined;
|
|
1257
|
-
|
|
1258
|
-
/**
|
|
1259
|
-
* `createSecurity`'s `identifier` sub-option — request-id minting/echo
|
|
1287
|
+
* Describes `createSecurity`'s `identifier` sub-option — request-id minting/echo
|
|
1260
1288
|
* policy, or `false` to disable the feature entirely.
|
|
1261
1289
|
*
|
|
1262
1290
|
* @remarks
|
|
@@ -1269,9 +1297,8 @@ export declare type SecurityIdentifierOptions = {
|
|
|
1269
1297
|
} | false;
|
|
1270
1298
|
|
|
1271
1299
|
/**
|
|
1272
|
-
*
|
|
1300
|
+
* Configures `createSecurity` — the security-headers + request-id battery.
|
|
1273
1301
|
*
|
|
1274
|
-
* @param options - See fields below
|
|
1275
1302
|
* @remarks
|
|
1276
1303
|
* Every header option is `string | false` (a custom value replaces the
|
|
1277
1304
|
* default wholesale, `false` omits the header) unless noted; unset uses the
|
|
@@ -1284,11 +1311,11 @@ export declare type SecurityIdentifierOptions = {
|
|
|
1284
1311
|
* - `coop` — `Cross-Origin-Opener-Policy`; default {@link DEFAULT_COOP}.
|
|
1285
1312
|
* - `corp` — `Cross-Origin-Resource-Policy`; default {@link DEFAULT_CORP}.
|
|
1286
1313
|
* - `cluster` — `Origin-Agent-Cluster`; default {@link DEFAULT_CLUSTER}.
|
|
1287
|
-
* - `coep` — `Cross-Origin-Embedder-Policy`; `string | boolean`,
|
|
1314
|
+
* - `coep` — `Cross-Origin-Embedder-Policy`; `string | boolean`, off by
|
|
1288
1315
|
* default (opt-in, breaks cross-origin subresources); `true` → {@link DEFAULT_COEP}.
|
|
1289
|
-
* - `hsts` — `Strict-Transport-Security`; `string | boolean`,
|
|
1316
|
+
* - `hsts` — `Strict-Transport-Security`; `string | boolean`, off by default
|
|
1290
1317
|
* (opt-in, destructive if misconfigured); `true` → {@link DEFAULT_HSTS}.
|
|
1291
|
-
* - `identifier` — {@link SecurityIdentifierOptions};
|
|
1318
|
+
* - `identifier` — {@link SecurityIdentifierOptions}; on by default (mints
|
|
1292
1319
|
* and stashes {@link IdentifierState}).
|
|
1293
1320
|
*/
|
|
1294
1321
|
export declare interface SecurityOptions {
|
|
@@ -1305,35 +1332,41 @@ export declare interface SecurityOptions {
|
|
|
1305
1332
|
}
|
|
1306
1333
|
|
|
1307
1334
|
/**
|
|
1308
|
-
*
|
|
1309
|
-
* value
|
|
1310
|
-
*
|
|
1311
|
-
*
|
|
1335
|
+
* Represents a server-managed session's default entity — the `create` option's default
|
|
1336
|
+
* value for `createSession`. It ships without a bare `create*` factory of its
|
|
1337
|
+
* own, because the name `createSession` belongs to the battery;
|
|
1338
|
+
* `createRestoredSession` rebuilds one from a stored snapshot.
|
|
1312
1339
|
*
|
|
1313
1340
|
* @remarks
|
|
1314
|
-
* `
|
|
1315
|
-
*
|
|
1341
|
+
* `state` is a `ReadonlyMap` view over the entity's own `Map`: TypeScript
|
|
1342
|
+
* refuses a write through it, and `set`, `delete`, and `clear` are the write
|
|
1343
|
+
* path. `createSession` persists the state to the configured store on the way
|
|
1344
|
+
* out.
|
|
1316
1345
|
*
|
|
1317
1346
|
* @example
|
|
1318
1347
|
* ```ts
|
|
1319
1348
|
* const session = new Session('abc123')
|
|
1320
|
-
* session.
|
|
1349
|
+
* session.set('userId', 'u_1')
|
|
1321
1350
|
* ```
|
|
1322
1351
|
*/
|
|
1323
1352
|
export declare class Session implements SessionInterface {
|
|
1324
|
-
|
|
1325
|
-
readonly data: Map<string, unknown>;
|
|
1353
|
+
#private;
|
|
1326
1354
|
constructor(id: string);
|
|
1355
|
+
get id(): string;
|
|
1356
|
+
get state(): ReadonlyMap<string, unknown>;
|
|
1357
|
+
set(key: string, value: unknown): void;
|
|
1358
|
+
delete(key: string): boolean;
|
|
1359
|
+
clear(): void;
|
|
1327
1360
|
}
|
|
1328
1361
|
|
|
1329
1362
|
/**
|
|
1330
|
-
*
|
|
1331
|
-
* {@link import('./types.js').SessionRow} table
|
|
1363
|
+
* Holds the `@orkestrel/database` column shape for a
|
|
1364
|
+
* {@link import('./types.js').SessionRow} table. Pass it as-is to
|
|
1332
1365
|
* `createDatabase({ tables: { sessions: sessionColumns } })` so an app
|
|
1333
1366
|
* declaring a durable session table never hand-writes the shape.
|
|
1334
1367
|
*
|
|
1335
1368
|
* @remarks
|
|
1336
|
-
* `
|
|
1369
|
+
* `seen`/`created` are `integerShape({ min: 0 })` — the table validates
|
|
1337
1370
|
* them as integers, so
|
|
1338
1371
|
* {@link import('./stores/DatabaseSessionStore.js').DatabaseSessionStore}'s
|
|
1339
1372
|
* `now` clock must yield integer milliseconds (`Date.now()`, the implicit
|
|
@@ -1349,76 +1382,130 @@ export declare class Session implements SessionInterface {
|
|
|
1349
1382
|
export declare const sessionColumns: {
|
|
1350
1383
|
id: StringShape;
|
|
1351
1384
|
session: JSONShape;
|
|
1352
|
-
|
|
1353
|
-
|
|
1385
|
+
seen: NumberShape;
|
|
1386
|
+
created: NumberShape;
|
|
1354
1387
|
};
|
|
1355
1388
|
|
|
1356
1389
|
/**
|
|
1357
|
-
*
|
|
1390
|
+
* Describes the mid-handler control handle `createSession` stashes alongside the
|
|
1358
1391
|
* session itself — the OWASP anti-fixation / logout primitives.
|
|
1359
1392
|
*
|
|
1360
1393
|
* @remarks
|
|
1361
|
-
* `regenerate` and `destroy` record intent
|
|
1394
|
+
* `regenerate` and `destroy` record intent synchronously when called; the
|
|
1362
1395
|
* store I/O and transport write happen after the handler's `next()` returns
|
|
1363
1396
|
* (`destroy` supersedes a prior `regenerate`). `regenerate` mints a new id,
|
|
1364
|
-
* carries the session's `
|
|
1397
|
+
* carries the session's `state` over, and invalidates the old id.
|
|
1365
1398
|
*/
|
|
1366
1399
|
export declare interface SessionControlInterface {
|
|
1400
|
+
/** Mints a fresh id, carries the session's `state` over, and invalidates the old id. */
|
|
1367
1401
|
regenerate(): void;
|
|
1402
|
+
/** Ends the session — deletes it from the store and clears its transport. */
|
|
1368
1403
|
destroy(): void;
|
|
1369
1404
|
}
|
|
1370
1405
|
|
|
1371
1406
|
/**
|
|
1372
|
-
*
|
|
1407
|
+
* Describes the per-session instants a store stamps and `sessionExpired` measures
|
|
1408
|
+
* against.
|
|
1409
|
+
*
|
|
1410
|
+
* @remarks
|
|
1411
|
+
* - `seen` — the instant of the most recent live read or write.
|
|
1412
|
+
* - `created` — the instant of the first `set`, preserved across every
|
|
1413
|
+
* later re-`set` of the same id.
|
|
1414
|
+
*/
|
|
1415
|
+
export declare interface SessionCursors {
|
|
1416
|
+
readonly seen: number;
|
|
1417
|
+
readonly created: number;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
/**
|
|
1421
|
+
* Represents one in-process session entry — the payload {@link MemorySessionStore} holds
|
|
1422
|
+
* against an id, alongside the same cursors a persisted row carries.
|
|
1423
|
+
*
|
|
1424
|
+
* @typeParam S - The stored session entity type
|
|
1425
|
+
*/
|
|
1426
|
+
export declare interface SessionEntry<S extends SessionInterface> extends SessionCursors {
|
|
1427
|
+
readonly session: S;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
/**
|
|
1431
|
+
* Checks whether a session has aged past its idle timeout or absolute lifetime as
|
|
1373
1432
|
* of `now` — the pure expiry predicate `MemorySessionStore` delegates to.
|
|
1374
1433
|
*
|
|
1375
|
-
* @param cursors -
|
|
1434
|
+
* @param cursors - See {@link SessionCursors}
|
|
1376
1435
|
* @param now - The current instant (same clock unit as `cursors`)
|
|
1377
|
-
* @param limits -
|
|
1378
|
-
* @returns
|
|
1436
|
+
* @param limits - See {@link SessionLimits}
|
|
1437
|
+
* @returns True if either configured threshold has elapsed; false otherwise
|
|
1379
1438
|
*
|
|
1380
1439
|
* @example
|
|
1381
1440
|
* ```ts
|
|
1382
|
-
* sessionExpired({
|
|
1441
|
+
* sessionExpired({ seen: 0, created: 0 }, 1_000, { ttl: 500 }) // true
|
|
1383
1442
|
* ```
|
|
1384
1443
|
*/
|
|
1385
|
-
export declare function sessionExpired(cursors:
|
|
1386
|
-
readonly lastSeen: number;
|
|
1387
|
-
readonly createdAt: number;
|
|
1388
|
-
}, now: number, limits: {
|
|
1389
|
-
readonly ttl?: number;
|
|
1390
|
-
readonly lifetime?: number;
|
|
1391
|
-
}): boolean;
|
|
1444
|
+
export declare function sessionExpired(cursors: SessionCursors, now: number, limits: SessionLimits): boolean;
|
|
1392
1445
|
|
|
1393
1446
|
/**
|
|
1394
|
-
*
|
|
1447
|
+
* Represents a server-managed session's public surface — an id, its live state, and the
|
|
1448
|
+
* mutators that write it.
|
|
1395
1449
|
*
|
|
1396
1450
|
* @remarks
|
|
1397
|
-
* `
|
|
1398
|
-
*
|
|
1451
|
+
* `state` is a `ReadonlyMap` view a handler reads directly: TypeScript
|
|
1452
|
+
* refuses a write through it, and `set`, `delete`, and `clear` are the write
|
|
1453
|
+
* path. `createSession` persists the state to the configured
|
|
1454
|
+
* {@link SessionStoreInterface} on the way out. `clear` empties the state
|
|
1455
|
+
* without ending the session — `SessionControlInterface.destroy` does that.
|
|
1399
1456
|
*/
|
|
1400
1457
|
export declare interface SessionInterface {
|
|
1401
1458
|
readonly id: string;
|
|
1402
|
-
readonly
|
|
1459
|
+
readonly state: ReadonlyMap<string, unknown>;
|
|
1460
|
+
/**
|
|
1461
|
+
* Writes one key's value into the session's state.
|
|
1462
|
+
*
|
|
1463
|
+
* @param key - The state key to write
|
|
1464
|
+
* @param value - The value to store under `key`
|
|
1465
|
+
*/
|
|
1466
|
+
set(key: string, value: unknown): void;
|
|
1467
|
+
/**
|
|
1468
|
+
* Removes one key from the session's state.
|
|
1469
|
+
*
|
|
1470
|
+
* @param key - The state key to remove
|
|
1471
|
+
* @returns True when the session held `key`; false otherwise
|
|
1472
|
+
*/
|
|
1473
|
+
delete(key: string): boolean;
|
|
1474
|
+
/** Empties the state, leaving the session and its id alive. */
|
|
1475
|
+
clear(): void;
|
|
1403
1476
|
}
|
|
1404
1477
|
|
|
1405
1478
|
/**
|
|
1406
|
-
*
|
|
1479
|
+
* Describes the idle and absolute-lifetime thresholds a session store enforces —
|
|
1480
|
+
* `sessionExpired`'s limits argument and both shipped stores' construction
|
|
1481
|
+
* options.
|
|
1407
1482
|
*
|
|
1408
|
-
* @
|
|
1483
|
+
* @remarks
|
|
1484
|
+
* - `ttl` — the idle timeout in milliseconds; absent means no idle expiry.
|
|
1485
|
+
* - `lifetime` — the absolute lifetime in milliseconds from the first `set`;
|
|
1486
|
+
* absent means no absolute expiry.
|
|
1487
|
+
*/
|
|
1488
|
+
export declare interface SessionLimits {
|
|
1489
|
+
readonly ttl?: number | undefined;
|
|
1490
|
+
readonly lifetime?: number | undefined;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
/**
|
|
1494
|
+
* Configures `createSession` — the generic session battery.
|
|
1495
|
+
*
|
|
1496
|
+
* @typeParam S - The session entity type `create` produces
|
|
1409
1497
|
* @typeParam TState - The consumer's opaque per-request state type `mint` reads
|
|
1410
|
-
* @param options - See fields below
|
|
1411
1498
|
* @remarks
|
|
1412
|
-
* - `transport` — the {@link
|
|
1499
|
+
* - `transport` — the {@link SessionTransportInterface} (`createCookieTransport(...)`,
|
|
1413
1500
|
* `createHeaderTransport(...)`, or a custom one).
|
|
1414
1501
|
* - `store` — the {@link SessionStoreInterface}; defaults to
|
|
1415
1502
|
* `createMemorySessionStore({ ttl, lifetime, capacity, evict })`.
|
|
1416
1503
|
* - `ttl` — the idle timeout in milliseconds.
|
|
1417
1504
|
* - `lifetime` — the absolute session lifetime in milliseconds from mint.
|
|
1418
|
-
* - `capacity` — the maximum number of distinct session ids the
|
|
1505
|
+
* - `capacity` — the maximum number of distinct session ids the default
|
|
1419
1506
|
* memory store tracks before LRU eviction; ignored when `store` is
|
|
1420
1507
|
* provided. Defaults to {@link DEFAULT_SESSION_CAPACITY}.
|
|
1421
|
-
* - `evict` — invoked with a session id evicted by the
|
|
1508
|
+
* - `evict` — invoked with a session id evicted by the default memory
|
|
1422
1509
|
* store's own policy; ignored when `store` is provided. It is a
|
|
1423
1510
|
* notification sink only — it must never call back into the store
|
|
1424
1511
|
* (no re-entrant `get`/`set`); mutations during eviction are unsupported.
|
|
@@ -1426,14 +1513,12 @@ export declare interface SessionInterface {
|
|
|
1426
1513
|
* defaults to `new Session(id)`.
|
|
1427
1514
|
* - `mint` — decides whether to auto-mint a session when none resolves;
|
|
1428
1515
|
* defaults to always minting (auto-session).
|
|
1429
|
-
* - `
|
|
1516
|
+
* - `required` — when `true`, a request that resolves no session and does not
|
|
1430
1517
|
* mint one renders a 404 instead of proceeding sessionless. Defaults to `false`.
|
|
1431
|
-
* - `ends` — when `true`, a `DELETE` request carrying a valid session id
|
|
1432
|
-
* deletes the session and short-circuits with `204`. Defaults to `false`.
|
|
1433
1518
|
* - `clock` — the injected time source fed to the store; defaults to `Date.now`.
|
|
1434
1519
|
*/
|
|
1435
|
-
export declare interface SessionOptions<S, TState = unknown> {
|
|
1436
|
-
readonly transport:
|
|
1520
|
+
export declare interface SessionOptions<S extends SessionInterface, TState = unknown> {
|
|
1521
|
+
readonly transport: SessionTransportInterface;
|
|
1437
1522
|
readonly store?: SessionStoreInterface<S>;
|
|
1438
1523
|
readonly ttl?: number;
|
|
1439
1524
|
readonly lifetime?: number;
|
|
@@ -1441,25 +1526,47 @@ export declare interface SessionOptions<S, TState = unknown> {
|
|
|
1441
1526
|
readonly evict?: (id: string) => void;
|
|
1442
1527
|
readonly create?: (id: string) => S;
|
|
1443
1528
|
readonly mint?: (context: MiddlewareContext<TState>) => boolean | Promise<boolean>;
|
|
1444
|
-
readonly
|
|
1445
|
-
readonly ends?: boolean;
|
|
1529
|
+
readonly required?: boolean;
|
|
1446
1530
|
readonly clock?: () => number;
|
|
1447
1531
|
}
|
|
1448
1532
|
|
|
1449
1533
|
/**
|
|
1450
|
-
*
|
|
1534
|
+
* Rebuilds a session entity from an untrusted stored snapshot, or resolves `undefined` when the value is malformed.
|
|
1535
|
+
*
|
|
1536
|
+
* @remarks
|
|
1537
|
+
* The step {@link DatabaseSessionStore} is constructed with, and the seam a
|
|
1538
|
+
* consumer implements to restore its own session entity from a persisted row.
|
|
1539
|
+
* `createDatabaseSessionStore` supplies `createRestoredSession` as that step.
|
|
1540
|
+
*/
|
|
1541
|
+
export declare type SessionRestoreFunction = (value: unknown) => SessionInterface | undefined;
|
|
1542
|
+
|
|
1543
|
+
/**
|
|
1544
|
+
* Represents one persisted session row — an opaque snapshot column plus the store-owned
|
|
1451
1545
|
* idle/absolute-lifetime cursors, the shape a {@link DatabaseSessionStore}'s
|
|
1452
1546
|
* backing table holds.
|
|
1453
1547
|
*/
|
|
1454
|
-
export declare interface SessionRow {
|
|
1548
|
+
export declare interface SessionRow extends SessionCursors {
|
|
1455
1549
|
readonly id: string;
|
|
1456
1550
|
readonly session: unknown;
|
|
1457
|
-
readonly lastSeen: number;
|
|
1458
|
-
readonly createdAt: number;
|
|
1459
1551
|
}
|
|
1460
1552
|
|
|
1461
1553
|
/**
|
|
1462
|
-
*
|
|
1554
|
+
* Represents a session's serializable projection — the value `snapshotSession` produces
|
|
1555
|
+
* and a durable store's `set` writes.
|
|
1556
|
+
*
|
|
1557
|
+
* @remarks
|
|
1558
|
+
* `state` is the wire member a persisted row carries, built on a
|
|
1559
|
+
* null-prototype record so a session key literally named `__proto__`
|
|
1560
|
+
* round-trips as an own enumerable property. It holds the same entries the
|
|
1561
|
+
* entity's own `state` view publishes.
|
|
1562
|
+
*/
|
|
1563
|
+
export declare interface SessionSnapshot {
|
|
1564
|
+
readonly id: string;
|
|
1565
|
+
readonly state: Readonly<Record<string, unknown>>;
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
/**
|
|
1569
|
+
* Describes the session state slice `createSession` stashes.
|
|
1463
1570
|
*
|
|
1464
1571
|
* @remarks
|
|
1465
1572
|
* `session` is present whenever a request resolves or mints a session;
|
|
@@ -1471,68 +1578,112 @@ export declare interface SessionState {
|
|
|
1471
1578
|
}
|
|
1472
1579
|
|
|
1473
1580
|
/**
|
|
1474
|
-
*
|
|
1475
|
-
* implements — a point-access store
|
|
1581
|
+
* Describes the pluggable session persistence seam `createSession`'s `store` option
|
|
1582
|
+
* implements — a point-access store keyed by session id.
|
|
1476
1583
|
*
|
|
1477
|
-
* @typeParam S - The session
|
|
1584
|
+
* @typeParam S - The stored session entity type
|
|
1478
1585
|
* @remarks
|
|
1479
1586
|
* Every primitive is async and takes a trailing `now` clock reading (the
|
|
1480
1587
|
* same seam `createSession`'s `clock` option feeds) so a store can apply its
|
|
1481
1588
|
* own idle/absolute expiry against the caller's injected time rather than
|
|
1482
|
-
* its own wall clock. `
|
|
1483
|
-
|
|
1484
|
-
|
|
1589
|
+
* its own wall clock. `set` reads the id from the session it is handed —
|
|
1590
|
+
* a stored value carries its own id, so no separate id is passed. `delete` of
|
|
1591
|
+
* an absent id is a no-op, never throws.
|
|
1592
|
+
*
|
|
1593
|
+
* `get` must resolve a value satisfying {@link isSession} — an `id` string,
|
|
1594
|
+
* a `state` `Map` view, and the mutators — or `undefined`. `createSession`
|
|
1595
|
+
* dereferences the resolved value's `id` and `state` without re-checking
|
|
1596
|
+
* them, so a store that resolves an off-shape value corrupts the battery's
|
|
1597
|
+
* own state rather than being refused at the seam. The shipped
|
|
1598
|
+
* `DatabaseSessionStore` enforces this with the caller-supplied guard it is
|
|
1599
|
+
* constructed with.
|
|
1600
|
+
*/
|
|
1601
|
+
export declare interface SessionStoreInterface<S extends SessionInterface> {
|
|
1602
|
+
/**
|
|
1603
|
+
* Reads a session by id, applying the idle and absolute expiry against `now`.
|
|
1604
|
+
*
|
|
1605
|
+
* @param id - The session id to read
|
|
1606
|
+
* @param now - The caller's clock reading the expiry is measured against
|
|
1607
|
+
* @returns The stored session, or `undefined` when it is absent or expired
|
|
1608
|
+
*/
|
|
1485
1609
|
get(id: string, now: number): Promise<S | undefined>;
|
|
1486
|
-
|
|
1610
|
+
/**
|
|
1611
|
+
* Persists a session under its own `id`, refreshing its idle window.
|
|
1612
|
+
*
|
|
1613
|
+
* @param session - The session to persist, keyed by its own `id`
|
|
1614
|
+
* @param now - The caller's clock reading stamped as the session's `seen`
|
|
1615
|
+
* @returns A promise that resolves once the session is stored
|
|
1616
|
+
*/
|
|
1617
|
+
set(session: S, now: number): Promise<void>;
|
|
1618
|
+
/**
|
|
1619
|
+
* Removes a session by id — a no-op on an absent id, never throws.
|
|
1620
|
+
*
|
|
1621
|
+
* @param id - The session id to remove
|
|
1622
|
+
* @returns A promise that resolves once the id is absent from the store
|
|
1623
|
+
*/
|
|
1487
1624
|
delete(id: string): Promise<void>;
|
|
1488
1625
|
}
|
|
1489
1626
|
|
|
1490
1627
|
/**
|
|
1491
|
-
*
|
|
1628
|
+
* Describes the transport seam `createSession`'s `transport` option implements — how a
|
|
1492
1629
|
* session id travels to and from the client (a signed cookie, a header, …).
|
|
1493
1630
|
*
|
|
1494
1631
|
* @remarks
|
|
1495
1632
|
* `read` is total (a malformed/tampered credential resolves `undefined`,
|
|
1496
|
-
* never throws). `write` and `clear` mutate the
|
|
1633
|
+
* never throws). `write` and `clear` mutate the returned `Response` on the
|
|
1497
1634
|
* way out — the returning onion makes "before send" automatic. `write` is
|
|
1498
1635
|
* called only when a session is freshly minted or regenerated; `clear` is
|
|
1499
1636
|
* called on `destroy()`. `write`'s `encrypted` flag is the request's resolved
|
|
1500
1637
|
* transport security (derived from `context.url.protocol`) so a cookie
|
|
1501
|
-
* transport can resolve its own `Secure` attribute
|
|
1638
|
+
* transport can resolve its own `Secure` attribute through `resolveSecure`
|
|
1502
1639
|
* without re-deriving connection facts itself.
|
|
1503
1640
|
*/
|
|
1504
|
-
export declare interface
|
|
1641
|
+
export declare interface SessionTransportInterface {
|
|
1642
|
+
/**
|
|
1643
|
+
* Reads the incoming session id from the request — `undefined` on any failure.
|
|
1644
|
+
*
|
|
1645
|
+
* @param request - The inbound request the credential travels on
|
|
1646
|
+
* @returns The session id, or `undefined` when none is present or readable
|
|
1647
|
+
*/
|
|
1505
1648
|
read(request: Request): string | undefined | Promise<string | undefined>;
|
|
1649
|
+
/**
|
|
1650
|
+
* Writes a freshly minted or regenerated session id onto the response, together with
|
|
1651
|
+
* the request's encrypted-transport fact.
|
|
1652
|
+
*
|
|
1653
|
+
* @param response - The outgoing response the credential is written onto
|
|
1654
|
+
* @param id - The session id carried to the client
|
|
1655
|
+
* @param encrypted - Whether the request arrived over an encrypted transport
|
|
1656
|
+
* @returns Nothing, or a promise that resolves once the credential is written
|
|
1657
|
+
*/
|
|
1506
1658
|
write(response: Response, id: string, encrypted: boolean): void | Promise<void>;
|
|
1659
|
+
/** Clears the transport's credential on `destroy()`. */
|
|
1507
1660
|
clear(response: Response): void;
|
|
1508
1661
|
}
|
|
1509
1662
|
|
|
1510
1663
|
/**
|
|
1511
|
-
*
|
|
1664
|
+
* Snapshots a session's `state` into a plain, serializable record — the
|
|
1512
1665
|
* projection a durable store's `set` writes to disk.
|
|
1513
1666
|
*
|
|
1514
1667
|
* @param session - The session to snapshot
|
|
1515
|
-
* @returns A plain-object copy of
|
|
1668
|
+
* @returns A {@link SessionSnapshot} whose `state` is a plain-object copy of
|
|
1669
|
+
* `session.state`, keyed alongside `session.id`
|
|
1516
1670
|
*
|
|
1517
1671
|
* @remarks
|
|
1518
|
-
* `
|
|
1672
|
+
* `state` is built on a null-prototype object (`Object.create(null)`), never
|
|
1519
1673
|
* a `{}` literal — a session key literally named `__proto__` must round-trip
|
|
1520
|
-
* as an
|
|
1674
|
+
* as an own enumerable property instead of hitting `Object.prototype`'s
|
|
1521
1675
|
* `__proto__` accessor (which would silently drop the entry and risk
|
|
1522
1676
|
* polluting the shared prototype).
|
|
1523
1677
|
*
|
|
1524
1678
|
* @example
|
|
1525
1679
|
* ```ts
|
|
1526
|
-
* snapshotSession(session) // { id: 'abc',
|
|
1680
|
+
* snapshotSession(session) // { id: 'abc', state: { userId: 'u_1' } }
|
|
1527
1681
|
* ```
|
|
1528
1682
|
*/
|
|
1529
|
-
export declare function snapshotSession(session: SessionInterface):
|
|
1530
|
-
readonly id: string;
|
|
1531
|
-
readonly data: Record<string, unknown>;
|
|
1532
|
-
};
|
|
1683
|
+
export declare function snapshotSession(session: SessionInterface): SessionSnapshot;
|
|
1533
1684
|
|
|
1534
1685
|
/**
|
|
1535
|
-
*
|
|
1686
|
+
* Represents one access-log-style entry `createTelemetry` records after a response
|
|
1536
1687
|
* settles — the access-log/timing seam's payload shape.
|
|
1537
1688
|
*
|
|
1538
1689
|
* @remarks
|
|
@@ -1551,9 +1702,8 @@ export declare interface TelemetryEntry {
|
|
|
1551
1702
|
}
|
|
1552
1703
|
|
|
1553
1704
|
/**
|
|
1554
|
-
*
|
|
1705
|
+
* Configures `createTelemetry` — the request timing/access-log seam.
|
|
1555
1706
|
*
|
|
1556
|
-
* @param options - See fields below
|
|
1557
1707
|
* @remarks
|
|
1558
1708
|
* - `record` — invoked once per request with the settled {@link
|
|
1559
1709
|
* TelemetryEntry}; its own throw is swallowed so a broken sink can never
|
|
@@ -1564,17 +1714,36 @@ export declare interface TelemetryOptions {
|
|
|
1564
1714
|
}
|
|
1565
1715
|
|
|
1566
1716
|
/**
|
|
1567
|
-
*
|
|
1568
|
-
*
|
|
1717
|
+
* Copies every entry of one session's `state` into another — the regenerate
|
|
1718
|
+
* state-carry `createSession`'s `control.regenerate()` applies.
|
|
1719
|
+
*
|
|
1720
|
+
* @param from - The source session whose `state` is copied
|
|
1721
|
+
* @param to - The destination session the entries are written into, through
|
|
1722
|
+
* its own `set` mutator
|
|
1723
|
+
*
|
|
1724
|
+
* @example
|
|
1725
|
+
* ```ts
|
|
1726
|
+
* transferSessionState(oldSession, newSession)
|
|
1727
|
+
* ```
|
|
1728
|
+
*/
|
|
1729
|
+
export declare function transferSessionState(from: SessionInterface, to: SessionInterface): void;
|
|
1730
|
+
|
|
1731
|
+
/**
|
|
1732
|
+
* Validates a store's idle and absolute-lifetime thresholds, throwing when
|
|
1733
|
+
* either is present and malformed — the shared construction gate
|
|
1734
|
+
* {@link MemorySessionStore} and {@link DatabaseSessionStore} both apply, so
|
|
1735
|
+
* one malformed `ttl` is refused identically by whichever store receives it.
|
|
1569
1736
|
*
|
|
1570
|
-
* @param
|
|
1571
|
-
* @
|
|
1737
|
+
* @param limits - See {@link SessionLimits}
|
|
1738
|
+
* @returns Nothing; a successful return means both thresholds are usable
|
|
1739
|
+
* @throws {TypeError} Thrown when `ttl` or `lifetime` is present and is not a
|
|
1740
|
+
* positive finite number
|
|
1572
1741
|
*
|
|
1573
1742
|
* @example
|
|
1574
1743
|
* ```ts
|
|
1575
|
-
*
|
|
1744
|
+
* validateSessionLimits({ ttl: 60_000 }) // returns; the thresholds are usable
|
|
1576
1745
|
* ```
|
|
1577
1746
|
*/
|
|
1578
|
-
export declare function
|
|
1747
|
+
export declare function validateSessionLimits(limits: SessionLimits | undefined): void;
|
|
1579
1748
|
|
|
1580
1749
|
export { }
|