ingenium 0.0.1 → 0.0.2
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 +1 -1
- package/dist/index.cjs +268 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +105 -9
- package/dist/index.d.ts +105 -9
- package/dist/index.js +268 -44
- package/dist/index.js.map +1 -1
- package/package.json +23 -8
- package/src/app.ts +7 -1
- package/src/body/multipart.ts +9 -1
- package/src/cors/middleware.ts +58 -3
- package/src/cors/types.ts +6 -3
- package/src/csrf/middleware.ts +98 -13
- package/src/csrf/types.ts +22 -1
- package/src/idempotency/middleware.ts +78 -5
- package/src/index.ts +1 -1
- package/src/jwt/middleware.ts +74 -3
- package/src/jwt/types.ts +12 -0
- package/src/jwt/verify.ts +75 -11
- package/src/problem/serialize.ts +18 -2
- package/src/proxy/trust.ts +22 -0
- package/src/session/middleware.ts +36 -3
- package/src/session/types.ts +14 -1
- package/src/static/middleware.ts +43 -8
- package/src/ws/index.ts +2 -0
- package/src/ws/middleware.ts +70 -0
- package/src/ws/types.ts +37 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Buffer as Buffer$1 } from 'node:buffer';
|
|
2
2
|
import * as node_http from 'node:http';
|
|
3
|
-
import { IncomingHttpHeaders, Server as Server$1 } from 'node:http';
|
|
3
|
+
import { IncomingHttpHeaders, IncomingMessage, Server as Server$1 } from 'node:http';
|
|
4
4
|
import { Readable } from 'node:stream';
|
|
5
5
|
import { KeyObject } from 'node:crypto';
|
|
6
6
|
import { WebSocket as WebSocket$1 } from 'ws';
|
|
@@ -2202,7 +2202,9 @@ type CorsOriginFn = (origin: string, ctx: IngeniumContext) => boolean | string |
|
|
|
2202
2202
|
/**
|
|
2203
2203
|
* Spec for the `origin` option.
|
|
2204
2204
|
*
|
|
2205
|
-
* - `boolean` — `true` reflects any request `Origin
|
|
2205
|
+
* - `boolean` — `true` reflects any request `Origin` (but never the literal
|
|
2206
|
+
* `"null"`, and rejected at construction when `credentials: true`); `false`
|
|
2207
|
+
* disables CORS.
|
|
2206
2208
|
* - `'*'` — wildcard: `Access-Control-Allow-Origin: *`.
|
|
2207
2209
|
* - any other `string` — exact match against the request's `Origin`.
|
|
2208
2210
|
* - `string[]` — allowlist; matched exactly.
|
|
@@ -2234,8 +2236,9 @@ interface CorsOptions {
|
|
|
2234
2236
|
exposedHeaders?: string[];
|
|
2235
2237
|
/**
|
|
2236
2238
|
* If `true`, sets `Access-Control-Allow-Credentials: true`.
|
|
2237
|
-
* Incompatible with `origin: '*'` —
|
|
2238
|
-
*
|
|
2239
|
+
* Incompatible with `origin: '*'` and `origin: true` — both throw at
|
|
2240
|
+
* construction time, because reflecting credentials to an unrestricted set of
|
|
2241
|
+
* origins lets any site read authenticated responses. Default: `false`.
|
|
2239
2242
|
*/
|
|
2240
2243
|
credentials?: boolean;
|
|
2241
2244
|
/**
|
|
@@ -2498,7 +2501,12 @@ interface CsrfCookieOptions {
|
|
|
2498
2501
|
domain?: string;
|
|
2499
2502
|
/** SameSite policy. Default `'lax'`. */
|
|
2500
2503
|
sameSite?: 'lax' | 'strict' | 'none';
|
|
2501
|
-
/**
|
|
2504
|
+
/**
|
|
2505
|
+
* Mark cookie Secure. **Default `true`** so the CSRF cookie is never sent
|
|
2506
|
+
* over plaintext HTTP where a network attacker could read it and forge the
|
|
2507
|
+
* double-submit header. Override to `false` only for local HTTP development;
|
|
2508
|
+
* doing so emits a dev-mode warning.
|
|
2509
|
+
*/
|
|
2502
2510
|
secure?: boolean;
|
|
2503
2511
|
/**
|
|
2504
2512
|
* Mark cookie HttpOnly. **Default `false`** — clients must read the cookie
|
|
@@ -2521,6 +2529,22 @@ interface CsrfOptions {
|
|
|
2521
2529
|
storage?: CsrfStorage;
|
|
2522
2530
|
/** Cookie options when `storage === 'cookie'`. */
|
|
2523
2531
|
cookie?: CsrfCookieOptions;
|
|
2532
|
+
/**
|
|
2533
|
+
* Bind a cookie-mode token to a per-session/per-user identifier (e.g. a
|
|
2534
|
+
* session id or authenticated user id derived from `ctx`).
|
|
2535
|
+
*
|
|
2536
|
+
* Without binding, a signed double-submit token is only proven to have been
|
|
2537
|
+
* minted by *this server* — any token the server ever issued is globally
|
|
2538
|
+
* valid for any user, so a leaked or shared token defeats the protection.
|
|
2539
|
+
* When this returns a stable value, the token is HMAC'd over
|
|
2540
|
+
* `raw + '.' + binding` and the binding is re-verified on unsafe requests,
|
|
2541
|
+
* so a token minted for one session cannot be replayed against another.
|
|
2542
|
+
*
|
|
2543
|
+
* Returning `undefined` (e.g. before login) falls back to plain
|
|
2544
|
+
* double-submit and emits a dev-mode warning. Has no effect in session
|
|
2545
|
+
* storage mode, where the session id already authenticates the binding.
|
|
2546
|
+
*/
|
|
2547
|
+
sessionBinding?: (ctx: IngeniumContext) => string | undefined;
|
|
2524
2548
|
/** Methods that bypass validation. Default `['GET', 'HEAD', 'OPTIONS', 'TRACE']`. */
|
|
2525
2549
|
ignoreMethods?: readonly string[];
|
|
2526
2550
|
/**
|
|
@@ -2773,6 +2797,8 @@ type JwtVerifyError = {
|
|
|
2773
2797
|
error: 'bad_signature';
|
|
2774
2798
|
} | {
|
|
2775
2799
|
error: 'expired';
|
|
2800
|
+
} | {
|
|
2801
|
+
error: 'missing_exp';
|
|
2776
2802
|
} | {
|
|
2777
2803
|
error: 'not_yet_valid';
|
|
2778
2804
|
} | {
|
|
@@ -2832,6 +2858,17 @@ interface JwtOptions<T = Record<string, unknown>> {
|
|
|
2832
2858
|
maxAgeSeconds?: number;
|
|
2833
2859
|
/** Leeway for `nbf` / `exp` checks, in seconds. Default `5`. */
|
|
2834
2860
|
clockSkewSeconds?: number;
|
|
2861
|
+
/**
|
|
2862
|
+
* Require a numeric `exp` claim. Default `true`.
|
|
2863
|
+
*
|
|
2864
|
+
* Why default-on: a token that omits `exp` (or carries a non-numeric one)
|
|
2865
|
+
* would otherwise verify forever — a stolen token never stops working. We
|
|
2866
|
+
* refuse those by default and only relax it for callers who deliberately
|
|
2867
|
+
* issue non-expiring tokens (set this to `false`). Either way a present
|
|
2868
|
+
* `exp`/`nbf`/`iat` that is not a finite number is treated as malformed, not
|
|
2869
|
+
* silently skipped.
|
|
2870
|
+
*/
|
|
2871
|
+
requireExp?: boolean;
|
|
2835
2872
|
/**
|
|
2836
2873
|
* If `true` (default), missing tokens raise `IngeniumUnauthorizedError`.
|
|
2837
2874
|
* If `false`, missing tokens just call `next()` with no `ctx.jwt`.
|
|
@@ -2861,6 +2898,17 @@ interface JwtOptions<T = Record<string, unknown>> {
|
|
|
2861
2898
|
_payload?: T;
|
|
2862
2899
|
}
|
|
2863
2900
|
|
|
2901
|
+
/**
|
|
2902
|
+
* 500 — the configured algorithm allowlist and the supplied key material are
|
|
2903
|
+
* from different families (an HMAC alg paired with an asymmetric PEM / public
|
|
2904
|
+
* key, or vice versa). Allowing this is the canonical algorithm-confusion
|
|
2905
|
+
* footgun: an attacker forges `HS256` tokens using the server's *public* key
|
|
2906
|
+
* as the HMAC secret. We refuse the configuration at construction time so the
|
|
2907
|
+
* mistake surfaces at boot, not as a silent auth bypass.
|
|
2908
|
+
*/
|
|
2909
|
+
declare class IngeniumJwtKeyAlgMismatchError extends IngeniumError {
|
|
2910
|
+
constructor(message: string);
|
|
2911
|
+
}
|
|
2864
2912
|
/**
|
|
2865
2913
|
* Bearer-token JWT verification middleware.
|
|
2866
2914
|
*
|
|
@@ -3496,6 +3544,11 @@ interface VerifyOptions {
|
|
|
3496
3544
|
issuer?: string | readonly string[];
|
|
3497
3545
|
maxAgeSeconds?: number;
|
|
3498
3546
|
clockSkewSeconds?: number;
|
|
3547
|
+
/**
|
|
3548
|
+
* Require a finite numeric `exp`. Default `true` — a token without an
|
|
3549
|
+
* expiry would otherwise verify forever (see middleware `requireExp`).
|
|
3550
|
+
*/
|
|
3551
|
+
requireExp?: boolean;
|
|
3499
3552
|
/** Override "now" for deterministic tests. Returns seconds since epoch. */
|
|
3500
3553
|
nowSeconds?: () => number;
|
|
3501
3554
|
}
|
|
@@ -3658,7 +3711,20 @@ interface SessionCookieOptions {
|
|
|
3658
3711
|
httpOnly?: boolean;
|
|
3659
3712
|
/** Cookie `SameSite` attribute. @default 'lax' */
|
|
3660
3713
|
sameSite?: 'lax' | 'strict' | 'none';
|
|
3661
|
-
/**
|
|
3714
|
+
/**
|
|
3715
|
+
* Cookie `Secure` attribute.
|
|
3716
|
+
*
|
|
3717
|
+
* When left undefined, {@link sessionMiddleware} resolves it safely: ON in
|
|
3718
|
+
* production (`NODE_ENV==='production'`) so the cookie cannot ride plaintext
|
|
3719
|
+
* HTTP, OFF in dev so `http://localhost` keeps working. Set `false`
|
|
3720
|
+
* explicitly to opt out in production (emits a dev warning), or `true` to
|
|
3721
|
+
* force it on in every environment.
|
|
3722
|
+
*
|
|
3723
|
+
* Note: the raw {@link serializeCookie} helper still treats `undefined` as
|
|
3724
|
+
* off — only the middleware applies the environment-aware default.
|
|
3725
|
+
*
|
|
3726
|
+
* @default undefined (production → Secure, dev → not Secure)
|
|
3727
|
+
*/
|
|
3662
3728
|
secure?: boolean;
|
|
3663
3729
|
}
|
|
3664
3730
|
/** Options accepted by {@link sessionMiddleware}. */
|
|
@@ -3762,8 +3828,10 @@ interface SessionStore {
|
|
|
3762
3828
|
* - HMAC-SHA-256 over the session id, base64url-encoded; verified with
|
|
3763
3829
|
* `timingSafeEqual`.
|
|
3764
3830
|
* - 144-bit (18-byte) random ids.
|
|
3765
|
-
* - Defaults: `HttpOnly`, `SameSite=Lax`, `Path=/`.
|
|
3766
|
-
*
|
|
3831
|
+
* - Defaults: `HttpOnly`, `SameSite=Lax`, `Path=/`. `Secure` defaults ON in
|
|
3832
|
+
* production (`NODE_ENV==='production'`) and OFF in dev so http://localhost
|
|
3833
|
+
* keeps working; set `cookie.secure: false` to force it off in production
|
|
3834
|
+
* (a dev warning fires), or `true` to force it on everywhere.
|
|
3767
3835
|
* - Tampered or unknown cookies silently issue a fresh session — never an
|
|
3768
3836
|
* error response, since this is an attacker-influenced surface.
|
|
3769
3837
|
*/
|
|
@@ -3810,12 +3878,40 @@ type WebSocket = WebSocket$1;
|
|
|
3810
3878
|
* are not meaningful for WS handlers (the upgrade has already happened).
|
|
3811
3879
|
*/
|
|
3812
3880
|
type WebSocketHandler = (socket: WebSocket$1, ctx: IngeniumContext) => void | Promise<void>;
|
|
3881
|
+
/**
|
|
3882
|
+
* Custom Origin verifier. Receives the request's `Origin` header (or
|
|
3883
|
+
* `undefined` when absent, e.g. a non-browser client) plus the raw upgrade
|
|
3884
|
+
* request. Return `true` to allow the upgrade, `false` to reject it with a
|
|
3885
|
+
* `403` handshake.
|
|
3886
|
+
*/
|
|
3887
|
+
type WebSocketOriginVerifier = (origin: string | undefined, req: IncomingMessage) => boolean;
|
|
3888
|
+
/**
|
|
3889
|
+
* Origin allowlist policy for a WebSocket upgrade. WS handlers run OUTSIDE the
|
|
3890
|
+
* normal middleware pipeline, so the only built-in defense against
|
|
3891
|
+
* Cross-Site WebSocket Hijacking (CSWSH) is this option — browsers attach the
|
|
3892
|
+
* victim's cookies to cross-origin upgrades, so without an Origin check any
|
|
3893
|
+
* external page can open an authenticated socket.
|
|
3894
|
+
*
|
|
3895
|
+
* - `true` — same-origin only: the `Origin` host must equal the request `Host`.
|
|
3896
|
+
* - `string` / `string[]` — exact `Origin` allowlist (compared verbatim).
|
|
3897
|
+
* - function — custom predicate (see {@link WebSocketOriginVerifier}).
|
|
3898
|
+
*
|
|
3899
|
+
* Omitting the option preserves backward compatibility (no enforcement) but
|
|
3900
|
+
* emits a one-time dev warning, because the safe default for a browser-facing
|
|
3901
|
+
* socket is to restrict origins.
|
|
3902
|
+
*/
|
|
3903
|
+
type WebSocketOriginOption = boolean | string | string[] | WebSocketOriginVerifier;
|
|
3813
3904
|
/** Per-handler options forwarded to `WebSocketServer({ noServer: true, ... })`. */
|
|
3814
3905
|
interface WebSocketHandlerOptions {
|
|
3815
3906
|
/** Max payload size (bytes) for incoming frames. */
|
|
3816
3907
|
maxPayload?: number;
|
|
3817
3908
|
/** Enable permessage-deflate. Defaults to false (matches `ws` default). */
|
|
3818
3909
|
perMessageDeflate?: boolean;
|
|
3910
|
+
/**
|
|
3911
|
+
* Origin allowlist for the upgrade handshake — the built-in CSWSH defense.
|
|
3912
|
+
* See {@link WebSocketOriginOption} for semantics and why it matters.
|
|
3913
|
+
*/
|
|
3914
|
+
origin?: WebSocketOriginOption;
|
|
3819
3915
|
}
|
|
3820
3916
|
/** Bag passed to integrators (advanced). */
|
|
3821
3917
|
interface WsIntegrator {
|
|
@@ -4259,4 +4355,4 @@ declare const ingenium: IngeniumFactory & {
|
|
|
4259
4355
|
openapiHandler: typeof openapiHandler;
|
|
4260
4356
|
};
|
|
4261
4357
|
|
|
4262
|
-
export { type ApiKeyLogger, type ApiKeyOptions, type ApiKeyValidator, type CachedResponse, type CloseOptions, type ComposedHandler, type CookieGetOptions, type CookieSetOptions, type CorsOptions, type CorsOrigin, type CorsOriginFn, type CronHandler, type CronMatch, type CronOptions, CronRegistry, type CsrfCookieOptions, type CsrfOptions, type CsrfStorage, type CsrfValueReader, type Decorator, DecoratorRegistry, type EagerDecorator, type EnableWebSocketsOptions, type ExtractParams, type FailedJob, type FormatHandlers, type FormattableCtx, type ForwardedInfo, type GenerateOpenApiOptions, HTTP_METHODS, type HeaderBag, type Hooks, HooksRegistry, Http2Adapter, type Http2AdapterOptions, Http2cAdapter, type HttpMethod, IdempotencyMemoryStore, type IdempotencyOptions, type IdempotencyStore, IngeniumApp, type IngeniumAppOptions, IngeniumBadRequestError, IngeniumBody, IngeniumContext, IngeniumContextPool, type IngeniumCookies, IngeniumCronJob, IngeniumCsrfError, IngeniumError, type IngeniumErrorHandler, IngeniumHaltError, type IngeniumHandler, IngeniumHeaderInjectionError, IngeniumMethodNotAllowedError, type IngeniumMiddleware, IngeniumNotFoundError, IngeniumPayloadTooLargeError, type IngeniumPlugin, type IngeniumQuery, IngeniumQueue, IngeniumTimeoutError, IngeniumUnauthorizedError, IngeniumUnserializableError, IngeniumValidationError, type InjectRequest, type InjectResponse, type JobHandle, type JsonEtagCtx, type JsonEtagOptions, type JwtAlgorithm, type JwtHeader, type JwtKey, type JwtLogger, type JwtOptions, type JwtSecret, type JwtSecretResolver, type JwtTokenReader, type JwtVerified, type LazyDecorator, type ListeningServer, type MatchMiss, type MatchResult, MemoryQueueStore, type MultipartFile, type MultipartOptions, type MultipartResult, type NegotiableCtx, NodeAdapter, type OnComposeHook, type OnErrorHook, type OnRequestHook, type OnResponseHook, type OnRouteHook, type Components as OpenApiComponents, type Info as OpenApiInfo, type Response as OpenApiResponse, type Schema as OpenApiSchema, type SecurityRequirement as OpenApiSecurityRequirement, type SecurityScheme as OpenApiSecurityScheme, type Server as OpenApiServer, type OpenApiSpec, type Tag as OpenApiTag, type Operation, type Parameter, type ParseSchema, type ParsedAccept, type PathItem, type PluginTarget, type ProblemDetails, type ProblemDetailsOptions, type QueueOptions, QueueRegistry, type QueueStore, type QueueWorker, MemoryStore$1 as RateLimitMemoryStore, type RateLimitOptions, type RateLimitStore, type RegisteredQueue, type RegistrationEvent, type RequestBody, type ResponseBody, type RetryPolicy, RouteBuilder, type RouteDescriptor, type RouteOptions, Router, RouterTrie, type SafeJsonStringifyOptions, type SafeParseSchema, ScopedApp, type Session, type SessionCookieOptions, MemoryStore as SessionMemoryStore, type SessionOptions, type SessionStore, type ShutdownOptions, type SseEvent, type SseStream, type StandardFailureResult, type StandardIssue, type StandardPathSegment, type StandardResult, type StandardSchemaV1, type StandardSchemaV1Props, type StandardSuccessResult, type StaticOptions, type Transport, type TransportHooks, TrieNode, type TrustProxy, type WebSocket, type WebSocketHandler, type WebSocketHandlerOptions, type WsIntegrator, WsNodeAdapter, type WsRegistrar, _resetDefaultApp, accepts, acceptsCharsets, acceptsEncodings, acceptsLanguages, after, apiKeyMiddleware, before, clearJwksCache, compose, composeWithHandler, computeEtag, corsMiddleware as cors_, createWebSocketRegistrar, csrfMiddleware, ingenium as default, defaultApp, del as delete, enableWebSockets, expandShorthand, fetchJwks, formatResponse, generateOpenApi, get, gracefulShutdown, head, idempotencyMiddleware, ingenium, isFresh, isStandardSchema, jwtMiddleware, listen, nextFireFrom, onError, openapiHandler, options, parseAcceptHeader, parseCronSpec, patch, peerHasWs, post, problemDetailsMiddleware, put, rateLimit, resolveForwarded, respondJsonWithEtag, safeJsonStringify, selectBest, sessionMiddleware, sortByPreference, sse, startKeepAlive, staticMiddleware as static_, toProblemDetails, use, verifyJwt };
|
|
4358
|
+
export { type ApiKeyLogger, type ApiKeyOptions, type ApiKeyValidator, type CachedResponse, type CloseOptions, type ComposedHandler, type CookieGetOptions, type CookieSetOptions, type CorsOptions, type CorsOrigin, type CorsOriginFn, type CronHandler, type CronMatch, type CronOptions, CronRegistry, type CsrfCookieOptions, type CsrfOptions, type CsrfStorage, type CsrfValueReader, type Decorator, DecoratorRegistry, type EagerDecorator, type EnableWebSocketsOptions, type ExtractParams, type FailedJob, type FormatHandlers, type FormattableCtx, type ForwardedInfo, type GenerateOpenApiOptions, HTTP_METHODS, type HeaderBag, type Hooks, HooksRegistry, Http2Adapter, type Http2AdapterOptions, Http2cAdapter, type HttpMethod, IdempotencyMemoryStore, type IdempotencyOptions, type IdempotencyStore, IngeniumApp, type IngeniumAppOptions, IngeniumBadRequestError, IngeniumBody, IngeniumContext, IngeniumContextPool, type IngeniumCookies, IngeniumCronJob, IngeniumCsrfError, IngeniumError, type IngeniumErrorHandler, IngeniumHaltError, type IngeniumHandler, IngeniumHeaderInjectionError, IngeniumJwtKeyAlgMismatchError, IngeniumMethodNotAllowedError, type IngeniumMiddleware, IngeniumNotFoundError, IngeniumPayloadTooLargeError, type IngeniumPlugin, type IngeniumQuery, IngeniumQueue, IngeniumTimeoutError, IngeniumUnauthorizedError, IngeniumUnserializableError, IngeniumValidationError, type InjectRequest, type InjectResponse, type JobHandle, type JsonEtagCtx, type JsonEtagOptions, type JwtAlgorithm, type JwtHeader, type JwtKey, type JwtLogger, type JwtOptions, type JwtSecret, type JwtSecretResolver, type JwtTokenReader, type JwtVerified, type LazyDecorator, type ListeningServer, type MatchMiss, type MatchResult, MemoryQueueStore, type MultipartFile, type MultipartOptions, type MultipartResult, type NegotiableCtx, NodeAdapter, type OnComposeHook, type OnErrorHook, type OnRequestHook, type OnResponseHook, type OnRouteHook, type Components as OpenApiComponents, type Info as OpenApiInfo, type Response as OpenApiResponse, type Schema as OpenApiSchema, type SecurityRequirement as OpenApiSecurityRequirement, type SecurityScheme as OpenApiSecurityScheme, type Server as OpenApiServer, type OpenApiSpec, type Tag as OpenApiTag, type Operation, type Parameter, type ParseSchema, type ParsedAccept, type PathItem, type PluginTarget, type ProblemDetails, type ProblemDetailsOptions, type QueueOptions, QueueRegistry, type QueueStore, type QueueWorker, MemoryStore$1 as RateLimitMemoryStore, type RateLimitOptions, type RateLimitStore, type RegisteredQueue, type RegistrationEvent, type RequestBody, type ResponseBody, type RetryPolicy, RouteBuilder, type RouteDescriptor, type RouteOptions, Router, RouterTrie, type SafeJsonStringifyOptions, type SafeParseSchema, ScopedApp, type Session, type SessionCookieOptions, MemoryStore as SessionMemoryStore, type SessionOptions, type SessionStore, type ShutdownOptions, type SseEvent, type SseStream, type StandardFailureResult, type StandardIssue, type StandardPathSegment, type StandardResult, type StandardSchemaV1, type StandardSchemaV1Props, type StandardSuccessResult, type StaticOptions, type Transport, type TransportHooks, TrieNode, type TrustProxy, type WebSocket, type WebSocketHandler, type WebSocketHandlerOptions, type WsIntegrator, WsNodeAdapter, type WsRegistrar, _resetDefaultApp, accepts, acceptsCharsets, acceptsEncodings, acceptsLanguages, after, apiKeyMiddleware, before, clearJwksCache, compose, composeWithHandler, computeEtag, corsMiddleware as cors_, createWebSocketRegistrar, csrfMiddleware, ingenium as default, defaultApp, del as delete, enableWebSockets, expandShorthand, fetchJwks, formatResponse, generateOpenApi, get, gracefulShutdown, head, idempotencyMiddleware, ingenium, isFresh, isStandardSchema, jwtMiddleware, listen, nextFireFrom, onError, openapiHandler, options, parseAcceptHeader, parseCronSpec, patch, peerHasWs, post, problemDetailsMiddleware, put, rateLimit, resolveForwarded, respondJsonWithEtag, safeJsonStringify, selectBest, sessionMiddleware, sortByPreference, sse, startKeepAlive, staticMiddleware as static_, toProblemDetails, use, verifyJwt };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Buffer as Buffer$1 } from 'node:buffer';
|
|
2
2
|
import * as node_http from 'node:http';
|
|
3
|
-
import { IncomingHttpHeaders, Server as Server$1 } from 'node:http';
|
|
3
|
+
import { IncomingHttpHeaders, IncomingMessage, Server as Server$1 } from 'node:http';
|
|
4
4
|
import { Readable } from 'node:stream';
|
|
5
5
|
import { KeyObject } from 'node:crypto';
|
|
6
6
|
import { WebSocket as WebSocket$1 } from 'ws';
|
|
@@ -2202,7 +2202,9 @@ type CorsOriginFn = (origin: string, ctx: IngeniumContext) => boolean | string |
|
|
|
2202
2202
|
/**
|
|
2203
2203
|
* Spec for the `origin` option.
|
|
2204
2204
|
*
|
|
2205
|
-
* - `boolean` — `true` reflects any request `Origin
|
|
2205
|
+
* - `boolean` — `true` reflects any request `Origin` (but never the literal
|
|
2206
|
+
* `"null"`, and rejected at construction when `credentials: true`); `false`
|
|
2207
|
+
* disables CORS.
|
|
2206
2208
|
* - `'*'` — wildcard: `Access-Control-Allow-Origin: *`.
|
|
2207
2209
|
* - any other `string` — exact match against the request's `Origin`.
|
|
2208
2210
|
* - `string[]` — allowlist; matched exactly.
|
|
@@ -2234,8 +2236,9 @@ interface CorsOptions {
|
|
|
2234
2236
|
exposedHeaders?: string[];
|
|
2235
2237
|
/**
|
|
2236
2238
|
* If `true`, sets `Access-Control-Allow-Credentials: true`.
|
|
2237
|
-
* Incompatible with `origin: '*'` —
|
|
2238
|
-
*
|
|
2239
|
+
* Incompatible with `origin: '*'` and `origin: true` — both throw at
|
|
2240
|
+
* construction time, because reflecting credentials to an unrestricted set of
|
|
2241
|
+
* origins lets any site read authenticated responses. Default: `false`.
|
|
2239
2242
|
*/
|
|
2240
2243
|
credentials?: boolean;
|
|
2241
2244
|
/**
|
|
@@ -2498,7 +2501,12 @@ interface CsrfCookieOptions {
|
|
|
2498
2501
|
domain?: string;
|
|
2499
2502
|
/** SameSite policy. Default `'lax'`. */
|
|
2500
2503
|
sameSite?: 'lax' | 'strict' | 'none';
|
|
2501
|
-
/**
|
|
2504
|
+
/**
|
|
2505
|
+
* Mark cookie Secure. **Default `true`** so the CSRF cookie is never sent
|
|
2506
|
+
* over plaintext HTTP where a network attacker could read it and forge the
|
|
2507
|
+
* double-submit header. Override to `false` only for local HTTP development;
|
|
2508
|
+
* doing so emits a dev-mode warning.
|
|
2509
|
+
*/
|
|
2502
2510
|
secure?: boolean;
|
|
2503
2511
|
/**
|
|
2504
2512
|
* Mark cookie HttpOnly. **Default `false`** — clients must read the cookie
|
|
@@ -2521,6 +2529,22 @@ interface CsrfOptions {
|
|
|
2521
2529
|
storage?: CsrfStorage;
|
|
2522
2530
|
/** Cookie options when `storage === 'cookie'`. */
|
|
2523
2531
|
cookie?: CsrfCookieOptions;
|
|
2532
|
+
/**
|
|
2533
|
+
* Bind a cookie-mode token to a per-session/per-user identifier (e.g. a
|
|
2534
|
+
* session id or authenticated user id derived from `ctx`).
|
|
2535
|
+
*
|
|
2536
|
+
* Without binding, a signed double-submit token is only proven to have been
|
|
2537
|
+
* minted by *this server* — any token the server ever issued is globally
|
|
2538
|
+
* valid for any user, so a leaked or shared token defeats the protection.
|
|
2539
|
+
* When this returns a stable value, the token is HMAC'd over
|
|
2540
|
+
* `raw + '.' + binding` and the binding is re-verified on unsafe requests,
|
|
2541
|
+
* so a token minted for one session cannot be replayed against another.
|
|
2542
|
+
*
|
|
2543
|
+
* Returning `undefined` (e.g. before login) falls back to plain
|
|
2544
|
+
* double-submit and emits a dev-mode warning. Has no effect in session
|
|
2545
|
+
* storage mode, where the session id already authenticates the binding.
|
|
2546
|
+
*/
|
|
2547
|
+
sessionBinding?: (ctx: IngeniumContext) => string | undefined;
|
|
2524
2548
|
/** Methods that bypass validation. Default `['GET', 'HEAD', 'OPTIONS', 'TRACE']`. */
|
|
2525
2549
|
ignoreMethods?: readonly string[];
|
|
2526
2550
|
/**
|
|
@@ -2773,6 +2797,8 @@ type JwtVerifyError = {
|
|
|
2773
2797
|
error: 'bad_signature';
|
|
2774
2798
|
} | {
|
|
2775
2799
|
error: 'expired';
|
|
2800
|
+
} | {
|
|
2801
|
+
error: 'missing_exp';
|
|
2776
2802
|
} | {
|
|
2777
2803
|
error: 'not_yet_valid';
|
|
2778
2804
|
} | {
|
|
@@ -2832,6 +2858,17 @@ interface JwtOptions<T = Record<string, unknown>> {
|
|
|
2832
2858
|
maxAgeSeconds?: number;
|
|
2833
2859
|
/** Leeway for `nbf` / `exp` checks, in seconds. Default `5`. */
|
|
2834
2860
|
clockSkewSeconds?: number;
|
|
2861
|
+
/**
|
|
2862
|
+
* Require a numeric `exp` claim. Default `true`.
|
|
2863
|
+
*
|
|
2864
|
+
* Why default-on: a token that omits `exp` (or carries a non-numeric one)
|
|
2865
|
+
* would otherwise verify forever — a stolen token never stops working. We
|
|
2866
|
+
* refuse those by default and only relax it for callers who deliberately
|
|
2867
|
+
* issue non-expiring tokens (set this to `false`). Either way a present
|
|
2868
|
+
* `exp`/`nbf`/`iat` that is not a finite number is treated as malformed, not
|
|
2869
|
+
* silently skipped.
|
|
2870
|
+
*/
|
|
2871
|
+
requireExp?: boolean;
|
|
2835
2872
|
/**
|
|
2836
2873
|
* If `true` (default), missing tokens raise `IngeniumUnauthorizedError`.
|
|
2837
2874
|
* If `false`, missing tokens just call `next()` with no `ctx.jwt`.
|
|
@@ -2861,6 +2898,17 @@ interface JwtOptions<T = Record<string, unknown>> {
|
|
|
2861
2898
|
_payload?: T;
|
|
2862
2899
|
}
|
|
2863
2900
|
|
|
2901
|
+
/**
|
|
2902
|
+
* 500 — the configured algorithm allowlist and the supplied key material are
|
|
2903
|
+
* from different families (an HMAC alg paired with an asymmetric PEM / public
|
|
2904
|
+
* key, or vice versa). Allowing this is the canonical algorithm-confusion
|
|
2905
|
+
* footgun: an attacker forges `HS256` tokens using the server's *public* key
|
|
2906
|
+
* as the HMAC secret. We refuse the configuration at construction time so the
|
|
2907
|
+
* mistake surfaces at boot, not as a silent auth bypass.
|
|
2908
|
+
*/
|
|
2909
|
+
declare class IngeniumJwtKeyAlgMismatchError extends IngeniumError {
|
|
2910
|
+
constructor(message: string);
|
|
2911
|
+
}
|
|
2864
2912
|
/**
|
|
2865
2913
|
* Bearer-token JWT verification middleware.
|
|
2866
2914
|
*
|
|
@@ -3496,6 +3544,11 @@ interface VerifyOptions {
|
|
|
3496
3544
|
issuer?: string | readonly string[];
|
|
3497
3545
|
maxAgeSeconds?: number;
|
|
3498
3546
|
clockSkewSeconds?: number;
|
|
3547
|
+
/**
|
|
3548
|
+
* Require a finite numeric `exp`. Default `true` — a token without an
|
|
3549
|
+
* expiry would otherwise verify forever (see middleware `requireExp`).
|
|
3550
|
+
*/
|
|
3551
|
+
requireExp?: boolean;
|
|
3499
3552
|
/** Override "now" for deterministic tests. Returns seconds since epoch. */
|
|
3500
3553
|
nowSeconds?: () => number;
|
|
3501
3554
|
}
|
|
@@ -3658,7 +3711,20 @@ interface SessionCookieOptions {
|
|
|
3658
3711
|
httpOnly?: boolean;
|
|
3659
3712
|
/** Cookie `SameSite` attribute. @default 'lax' */
|
|
3660
3713
|
sameSite?: 'lax' | 'strict' | 'none';
|
|
3661
|
-
/**
|
|
3714
|
+
/**
|
|
3715
|
+
* Cookie `Secure` attribute.
|
|
3716
|
+
*
|
|
3717
|
+
* When left undefined, {@link sessionMiddleware} resolves it safely: ON in
|
|
3718
|
+
* production (`NODE_ENV==='production'`) so the cookie cannot ride plaintext
|
|
3719
|
+
* HTTP, OFF in dev so `http://localhost` keeps working. Set `false`
|
|
3720
|
+
* explicitly to opt out in production (emits a dev warning), or `true` to
|
|
3721
|
+
* force it on in every environment.
|
|
3722
|
+
*
|
|
3723
|
+
* Note: the raw {@link serializeCookie} helper still treats `undefined` as
|
|
3724
|
+
* off — only the middleware applies the environment-aware default.
|
|
3725
|
+
*
|
|
3726
|
+
* @default undefined (production → Secure, dev → not Secure)
|
|
3727
|
+
*/
|
|
3662
3728
|
secure?: boolean;
|
|
3663
3729
|
}
|
|
3664
3730
|
/** Options accepted by {@link sessionMiddleware}. */
|
|
@@ -3762,8 +3828,10 @@ interface SessionStore {
|
|
|
3762
3828
|
* - HMAC-SHA-256 over the session id, base64url-encoded; verified with
|
|
3763
3829
|
* `timingSafeEqual`.
|
|
3764
3830
|
* - 144-bit (18-byte) random ids.
|
|
3765
|
-
* - Defaults: `HttpOnly`, `SameSite=Lax`, `Path=/`.
|
|
3766
|
-
*
|
|
3831
|
+
* - Defaults: `HttpOnly`, `SameSite=Lax`, `Path=/`. `Secure` defaults ON in
|
|
3832
|
+
* production (`NODE_ENV==='production'`) and OFF in dev so http://localhost
|
|
3833
|
+
* keeps working; set `cookie.secure: false` to force it off in production
|
|
3834
|
+
* (a dev warning fires), or `true` to force it on everywhere.
|
|
3767
3835
|
* - Tampered or unknown cookies silently issue a fresh session — never an
|
|
3768
3836
|
* error response, since this is an attacker-influenced surface.
|
|
3769
3837
|
*/
|
|
@@ -3810,12 +3878,40 @@ type WebSocket = WebSocket$1;
|
|
|
3810
3878
|
* are not meaningful for WS handlers (the upgrade has already happened).
|
|
3811
3879
|
*/
|
|
3812
3880
|
type WebSocketHandler = (socket: WebSocket$1, ctx: IngeniumContext) => void | Promise<void>;
|
|
3881
|
+
/**
|
|
3882
|
+
* Custom Origin verifier. Receives the request's `Origin` header (or
|
|
3883
|
+
* `undefined` when absent, e.g. a non-browser client) plus the raw upgrade
|
|
3884
|
+
* request. Return `true` to allow the upgrade, `false` to reject it with a
|
|
3885
|
+
* `403` handshake.
|
|
3886
|
+
*/
|
|
3887
|
+
type WebSocketOriginVerifier = (origin: string | undefined, req: IncomingMessage) => boolean;
|
|
3888
|
+
/**
|
|
3889
|
+
* Origin allowlist policy for a WebSocket upgrade. WS handlers run OUTSIDE the
|
|
3890
|
+
* normal middleware pipeline, so the only built-in defense against
|
|
3891
|
+
* Cross-Site WebSocket Hijacking (CSWSH) is this option — browsers attach the
|
|
3892
|
+
* victim's cookies to cross-origin upgrades, so without an Origin check any
|
|
3893
|
+
* external page can open an authenticated socket.
|
|
3894
|
+
*
|
|
3895
|
+
* - `true` — same-origin only: the `Origin` host must equal the request `Host`.
|
|
3896
|
+
* - `string` / `string[]` — exact `Origin` allowlist (compared verbatim).
|
|
3897
|
+
* - function — custom predicate (see {@link WebSocketOriginVerifier}).
|
|
3898
|
+
*
|
|
3899
|
+
* Omitting the option preserves backward compatibility (no enforcement) but
|
|
3900
|
+
* emits a one-time dev warning, because the safe default for a browser-facing
|
|
3901
|
+
* socket is to restrict origins.
|
|
3902
|
+
*/
|
|
3903
|
+
type WebSocketOriginOption = boolean | string | string[] | WebSocketOriginVerifier;
|
|
3813
3904
|
/** Per-handler options forwarded to `WebSocketServer({ noServer: true, ... })`. */
|
|
3814
3905
|
interface WebSocketHandlerOptions {
|
|
3815
3906
|
/** Max payload size (bytes) for incoming frames. */
|
|
3816
3907
|
maxPayload?: number;
|
|
3817
3908
|
/** Enable permessage-deflate. Defaults to false (matches `ws` default). */
|
|
3818
3909
|
perMessageDeflate?: boolean;
|
|
3910
|
+
/**
|
|
3911
|
+
* Origin allowlist for the upgrade handshake — the built-in CSWSH defense.
|
|
3912
|
+
* See {@link WebSocketOriginOption} for semantics and why it matters.
|
|
3913
|
+
*/
|
|
3914
|
+
origin?: WebSocketOriginOption;
|
|
3819
3915
|
}
|
|
3820
3916
|
/** Bag passed to integrators (advanced). */
|
|
3821
3917
|
interface WsIntegrator {
|
|
@@ -4259,4 +4355,4 @@ declare const ingenium: IngeniumFactory & {
|
|
|
4259
4355
|
openapiHandler: typeof openapiHandler;
|
|
4260
4356
|
};
|
|
4261
4357
|
|
|
4262
|
-
export { type ApiKeyLogger, type ApiKeyOptions, type ApiKeyValidator, type CachedResponse, type CloseOptions, type ComposedHandler, type CookieGetOptions, type CookieSetOptions, type CorsOptions, type CorsOrigin, type CorsOriginFn, type CronHandler, type CronMatch, type CronOptions, CronRegistry, type CsrfCookieOptions, type CsrfOptions, type CsrfStorage, type CsrfValueReader, type Decorator, DecoratorRegistry, type EagerDecorator, type EnableWebSocketsOptions, type ExtractParams, type FailedJob, type FormatHandlers, type FormattableCtx, type ForwardedInfo, type GenerateOpenApiOptions, HTTP_METHODS, type HeaderBag, type Hooks, HooksRegistry, Http2Adapter, type Http2AdapterOptions, Http2cAdapter, type HttpMethod, IdempotencyMemoryStore, type IdempotencyOptions, type IdempotencyStore, IngeniumApp, type IngeniumAppOptions, IngeniumBadRequestError, IngeniumBody, IngeniumContext, IngeniumContextPool, type IngeniumCookies, IngeniumCronJob, IngeniumCsrfError, IngeniumError, type IngeniumErrorHandler, IngeniumHaltError, type IngeniumHandler, IngeniumHeaderInjectionError, IngeniumMethodNotAllowedError, type IngeniumMiddleware, IngeniumNotFoundError, IngeniumPayloadTooLargeError, type IngeniumPlugin, type IngeniumQuery, IngeniumQueue, IngeniumTimeoutError, IngeniumUnauthorizedError, IngeniumUnserializableError, IngeniumValidationError, type InjectRequest, type InjectResponse, type JobHandle, type JsonEtagCtx, type JsonEtagOptions, type JwtAlgorithm, type JwtHeader, type JwtKey, type JwtLogger, type JwtOptions, type JwtSecret, type JwtSecretResolver, type JwtTokenReader, type JwtVerified, type LazyDecorator, type ListeningServer, type MatchMiss, type MatchResult, MemoryQueueStore, type MultipartFile, type MultipartOptions, type MultipartResult, type NegotiableCtx, NodeAdapter, type OnComposeHook, type OnErrorHook, type OnRequestHook, type OnResponseHook, type OnRouteHook, type Components as OpenApiComponents, type Info as OpenApiInfo, type Response as OpenApiResponse, type Schema as OpenApiSchema, type SecurityRequirement as OpenApiSecurityRequirement, type SecurityScheme as OpenApiSecurityScheme, type Server as OpenApiServer, type OpenApiSpec, type Tag as OpenApiTag, type Operation, type Parameter, type ParseSchema, type ParsedAccept, type PathItem, type PluginTarget, type ProblemDetails, type ProblemDetailsOptions, type QueueOptions, QueueRegistry, type QueueStore, type QueueWorker, MemoryStore$1 as RateLimitMemoryStore, type RateLimitOptions, type RateLimitStore, type RegisteredQueue, type RegistrationEvent, type RequestBody, type ResponseBody, type RetryPolicy, RouteBuilder, type RouteDescriptor, type RouteOptions, Router, RouterTrie, type SafeJsonStringifyOptions, type SafeParseSchema, ScopedApp, type Session, type SessionCookieOptions, MemoryStore as SessionMemoryStore, type SessionOptions, type SessionStore, type ShutdownOptions, type SseEvent, type SseStream, type StandardFailureResult, type StandardIssue, type StandardPathSegment, type StandardResult, type StandardSchemaV1, type StandardSchemaV1Props, type StandardSuccessResult, type StaticOptions, type Transport, type TransportHooks, TrieNode, type TrustProxy, type WebSocket, type WebSocketHandler, type WebSocketHandlerOptions, type WsIntegrator, WsNodeAdapter, type WsRegistrar, _resetDefaultApp, accepts, acceptsCharsets, acceptsEncodings, acceptsLanguages, after, apiKeyMiddleware, before, clearJwksCache, compose, composeWithHandler, computeEtag, corsMiddleware as cors_, createWebSocketRegistrar, csrfMiddleware, ingenium as default, defaultApp, del as delete, enableWebSockets, expandShorthand, fetchJwks, formatResponse, generateOpenApi, get, gracefulShutdown, head, idempotencyMiddleware, ingenium, isFresh, isStandardSchema, jwtMiddleware, listen, nextFireFrom, onError, openapiHandler, options, parseAcceptHeader, parseCronSpec, patch, peerHasWs, post, problemDetailsMiddleware, put, rateLimit, resolveForwarded, respondJsonWithEtag, safeJsonStringify, selectBest, sessionMiddleware, sortByPreference, sse, startKeepAlive, staticMiddleware as static_, toProblemDetails, use, verifyJwt };
|
|
4358
|
+
export { type ApiKeyLogger, type ApiKeyOptions, type ApiKeyValidator, type CachedResponse, type CloseOptions, type ComposedHandler, type CookieGetOptions, type CookieSetOptions, type CorsOptions, type CorsOrigin, type CorsOriginFn, type CronHandler, type CronMatch, type CronOptions, CronRegistry, type CsrfCookieOptions, type CsrfOptions, type CsrfStorage, type CsrfValueReader, type Decorator, DecoratorRegistry, type EagerDecorator, type EnableWebSocketsOptions, type ExtractParams, type FailedJob, type FormatHandlers, type FormattableCtx, type ForwardedInfo, type GenerateOpenApiOptions, HTTP_METHODS, type HeaderBag, type Hooks, HooksRegistry, Http2Adapter, type Http2AdapterOptions, Http2cAdapter, type HttpMethod, IdempotencyMemoryStore, type IdempotencyOptions, type IdempotencyStore, IngeniumApp, type IngeniumAppOptions, IngeniumBadRequestError, IngeniumBody, IngeniumContext, IngeniumContextPool, type IngeniumCookies, IngeniumCronJob, IngeniumCsrfError, IngeniumError, type IngeniumErrorHandler, IngeniumHaltError, type IngeniumHandler, IngeniumHeaderInjectionError, IngeniumJwtKeyAlgMismatchError, IngeniumMethodNotAllowedError, type IngeniumMiddleware, IngeniumNotFoundError, IngeniumPayloadTooLargeError, type IngeniumPlugin, type IngeniumQuery, IngeniumQueue, IngeniumTimeoutError, IngeniumUnauthorizedError, IngeniumUnserializableError, IngeniumValidationError, type InjectRequest, type InjectResponse, type JobHandle, type JsonEtagCtx, type JsonEtagOptions, type JwtAlgorithm, type JwtHeader, type JwtKey, type JwtLogger, type JwtOptions, type JwtSecret, type JwtSecretResolver, type JwtTokenReader, type JwtVerified, type LazyDecorator, type ListeningServer, type MatchMiss, type MatchResult, MemoryQueueStore, type MultipartFile, type MultipartOptions, type MultipartResult, type NegotiableCtx, NodeAdapter, type OnComposeHook, type OnErrorHook, type OnRequestHook, type OnResponseHook, type OnRouteHook, type Components as OpenApiComponents, type Info as OpenApiInfo, type Response as OpenApiResponse, type Schema as OpenApiSchema, type SecurityRequirement as OpenApiSecurityRequirement, type SecurityScheme as OpenApiSecurityScheme, type Server as OpenApiServer, type OpenApiSpec, type Tag as OpenApiTag, type Operation, type Parameter, type ParseSchema, type ParsedAccept, type PathItem, type PluginTarget, type ProblemDetails, type ProblemDetailsOptions, type QueueOptions, QueueRegistry, type QueueStore, type QueueWorker, MemoryStore$1 as RateLimitMemoryStore, type RateLimitOptions, type RateLimitStore, type RegisteredQueue, type RegistrationEvent, type RequestBody, type ResponseBody, type RetryPolicy, RouteBuilder, type RouteDescriptor, type RouteOptions, Router, RouterTrie, type SafeJsonStringifyOptions, type SafeParseSchema, ScopedApp, type Session, type SessionCookieOptions, MemoryStore as SessionMemoryStore, type SessionOptions, type SessionStore, type ShutdownOptions, type SseEvent, type SseStream, type StandardFailureResult, type StandardIssue, type StandardPathSegment, type StandardResult, type StandardSchemaV1, type StandardSchemaV1Props, type StandardSuccessResult, type StaticOptions, type Transport, type TransportHooks, TrieNode, type TrustProxy, type WebSocket, type WebSocketHandler, type WebSocketHandlerOptions, type WsIntegrator, WsNodeAdapter, type WsRegistrar, _resetDefaultApp, accepts, acceptsCharsets, acceptsEncodings, acceptsLanguages, after, apiKeyMiddleware, before, clearJwksCache, compose, composeWithHandler, computeEtag, corsMiddleware as cors_, createWebSocketRegistrar, csrfMiddleware, ingenium as default, defaultApp, del as delete, enableWebSockets, expandShorthand, fetchJwks, formatResponse, generateOpenApi, get, gracefulShutdown, head, idempotencyMiddleware, ingenium, isFresh, isStandardSchema, jwtMiddleware, listen, nextFireFrom, onError, openapiHandler, options, parseAcceptHeader, parseCronSpec, patch, peerHasWs, post, problemDetailsMiddleware, put, rateLimit, resolveForwarded, respondJsonWithEtag, safeJsonStringify, selectBest, sessionMiddleware, sortByPreference, sse, startKeepAlive, staticMiddleware as static_, toProblemDetails, use, verifyJwt };
|