@daloyjs/core 0.16.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/adapters/bun.d.ts.map +1 -1
- package/dist/adapters/bun.js +38 -7
- package/dist/adapters/bun.js.map +1 -1
- package/dist/adapters/node.d.ts.map +1 -1
- package/dist/adapters/node.js +29 -7
- package/dist/adapters/node.js.map +1 -1
- package/dist/app.d.ts +412 -3
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +895 -29
- package/dist/app.js.map +1 -1
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +218 -1
- package/dist/cli.js.map +1 -1
- package/dist/combine.d.ts +97 -0
- package/dist/combine.d.ts.map +1 -0
- package/dist/combine.js +247 -0
- package/dist/combine.js.map +1 -0
- package/dist/compression.d.ts +127 -0
- package/dist/compression.d.ts.map +1 -0
- package/dist/compression.js +368 -0
- package/dist/compression.js.map +1 -0
- package/dist/config.d.ts +97 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +132 -0
- package/dist/config.js.map +1 -0
- package/dist/conn-info.d.ts +121 -0
- package/dist/conn-info.d.ts.map +1 -0
- package/dist/conn-info.js +145 -0
- package/dist/conn-info.js.map +1 -0
- package/dist/cookie.d.ts +112 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/cookie.js +185 -0
- package/dist/cookie.js.map +1 -0
- package/dist/dependency.d.ts +47 -0
- package/dist/dependency.d.ts.map +1 -0
- package/dist/dependency.js +68 -0
- package/dist/dependency.js.map +1 -0
- package/dist/etag.d.ts +48 -0
- package/dist/etag.d.ts.map +1 -0
- package/dist/etag.js +117 -0
- package/dist/etag.js.map +1 -0
- package/dist/index.d.ts +41 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -5
- package/dist/index.js.map +1 -1
- package/dist/ip-restriction.d.ts +75 -0
- package/dist/ip-restriction.d.ts.map +1 -0
- package/dist/ip-restriction.js +203 -0
- package/dist/ip-restriction.js.map +1 -0
- package/dist/jwk.d.ts +82 -0
- package/dist/jwk.d.ts.map +1 -0
- package/dist/jwk.js +269 -0
- package/dist/jwk.js.map +1 -0
- package/dist/jwt.d.ts +103 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +437 -0
- package/dist/jwt.js.map +1 -0
- package/dist/load-shedding.d.ts +73 -0
- package/dist/load-shedding.d.ts.map +1 -0
- package/dist/load-shedding.js +171 -0
- package/dist/load-shedding.js.map +1 -0
- package/dist/middleware.d.ts +205 -2
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +399 -78
- package/dist/middleware.js.map +1 -1
- package/dist/multipart.d.ts +17 -0
- package/dist/multipart.d.ts.map +1 -1
- package/dist/multipart.js +117 -1
- package/dist/multipart.js.map +1 -1
- package/dist/openapi.d.ts +8 -0
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +18 -1
- package/dist/openapi.js.map +1 -1
- package/dist/security-schemes.d.ts +21 -5
- package/dist/security-schemes.d.ts.map +1 -1
- package/dist/security-schemes.js +32 -5
- package/dist/security-schemes.js.map +1 -1
- package/dist/security.d.ts +32 -0
- package/dist/security.d.ts.map +1 -1
- package/dist/security.js +79 -0
- package/dist/security.js.map +1 -1
- package/dist/session.d.ts +43 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +130 -87
- package/dist/session.js.map +1 -1
- package/dist/subdomains.d.ts +97 -0
- package/dist/subdomains.d.ts.map +1 -0
- package/dist/subdomains.js +157 -0
- package/dist/subdomains.js.map +1 -0
- package/dist/time-claims.d.ts +72 -0
- package/dist/time-claims.d.ts.map +1 -0
- package/dist/time-claims.js +88 -0
- package/dist/time-claims.js.map +1 -0
- package/dist/types.d.ts +50 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/websocket.d.ts +51 -34
- package/dist/websocket.d.ts.map +1 -1
- package/dist/websocket.js +162 -2
- package/dist/websocket.js.map +1 -1
- package/package.json +30 -3
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 4 leftover: `loadShedding()` primitive.
|
|
3
|
+
*
|
|
4
|
+
* Lightweight Node-process pressure monitor that returns `Hooks` for
|
|
5
|
+
* `app.use(...)`. When any of the configured thresholds is exceeded,
|
|
6
|
+
* every incoming request is short-circuited with `503 Service Unavailable`
|
|
7
|
+
* carrying a `Retry-After` header. First-party answer to
|
|
8
|
+
* `@fastify/under-pressure`. Defaults are off for heap/RSS thresholds
|
|
9
|
+
* (deployment-specific) and conservative for everything else (event-loop
|
|
10
|
+
* delay at 1 s, event-loop utilization at 0.98). The monitor samples at
|
|
11
|
+
* `sampleIntervalMs` (default 1 s). Graceful no-op on runtimes without
|
|
12
|
+
* `node:perf_hooks` (Workers / Edge / Fastly Compute).
|
|
13
|
+
*
|
|
14
|
+
* @since 0.20.0
|
|
15
|
+
*/
|
|
16
|
+
import { HttpError } from "./errors.js";
|
|
17
|
+
async function tryLoadPerfHooks() {
|
|
18
|
+
try {
|
|
19
|
+
return (await import("node:perf_hooks"));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build a Hooks bundle that refuses requests with `503` when the configured
|
|
27
|
+
* process-pressure thresholds are exceeded.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { App, loadShedding } from "@daloyjs/core";
|
|
32
|
+
*
|
|
33
|
+
* const app = new App();
|
|
34
|
+
* app.use(loadShedding({
|
|
35
|
+
* maxEventLoopDelayMs: 500,
|
|
36
|
+
* maxHeapUsedBytes: 1.5 * 1024 ** 3,
|
|
37
|
+
* retryAfterSeconds: 5,
|
|
38
|
+
* }));
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function loadShedding(opts = {}) {
|
|
42
|
+
const maxDelay = opts.maxEventLoopDelayMs ?? 1000;
|
|
43
|
+
const maxHeap = opts.maxHeapUsedBytes;
|
|
44
|
+
const maxRss = opts.maxRssBytes;
|
|
45
|
+
const maxELU = opts.maxEventLoopUtilization ?? 0.98;
|
|
46
|
+
const sampleMs = Math.max(100, opts.sampleIntervalMs ?? 1000);
|
|
47
|
+
const retryAfter = opts.retryAfterSeconds ?? 10;
|
|
48
|
+
const healthCheckMs = Math.max(100, opts.healthCheckIntervalMs ?? sampleMs);
|
|
49
|
+
const snapshot = {
|
|
50
|
+
eventLoopDelayMs: 0,
|
|
51
|
+
heapUsedBytes: 0,
|
|
52
|
+
rssBytes: 0,
|
|
53
|
+
eventLoopUtilization: 0,
|
|
54
|
+
};
|
|
55
|
+
let perf;
|
|
56
|
+
let histogram;
|
|
57
|
+
let lastELU;
|
|
58
|
+
let lastSample = 0;
|
|
59
|
+
let lastHealth = 0;
|
|
60
|
+
let perfPromise;
|
|
61
|
+
let timer;
|
|
62
|
+
let stopped = false;
|
|
63
|
+
const procRef = typeof process !== "undefined" ? process : undefined;
|
|
64
|
+
const ensurePerf = () => {
|
|
65
|
+
if (perfPromise)
|
|
66
|
+
return perfPromise;
|
|
67
|
+
perfPromise = (async () => {
|
|
68
|
+
perf = await tryLoadPerfHooks();
|
|
69
|
+
if (perf?.monitorEventLoopDelay && maxDelay > 0) {
|
|
70
|
+
histogram = perf.monitorEventLoopDelay({ resolution: 20 });
|
|
71
|
+
histogram.enable();
|
|
72
|
+
// Make sure the histogram does not pin the event loop alive.
|
|
73
|
+
const unref = histogram.unref;
|
|
74
|
+
if (typeof unref === "function")
|
|
75
|
+
unref.call(histogram);
|
|
76
|
+
}
|
|
77
|
+
if (perf?.performance?.eventLoopUtilization) {
|
|
78
|
+
lastELU = perf.performance.eventLoopUtilization();
|
|
79
|
+
}
|
|
80
|
+
})();
|
|
81
|
+
return perfPromise;
|
|
82
|
+
};
|
|
83
|
+
const refreshSnapshot = () => {
|
|
84
|
+
if (histogram) {
|
|
85
|
+
// mean is in nanoseconds; convert to ms.
|
|
86
|
+
snapshot.eventLoopDelayMs = histogram.mean / 1e6;
|
|
87
|
+
histogram.reset();
|
|
88
|
+
}
|
|
89
|
+
if (perf?.performance?.eventLoopUtilization && lastELU) {
|
|
90
|
+
const next = perf.performance.eventLoopUtilization(lastELU);
|
|
91
|
+
snapshot.eventLoopUtilization = next.utilization;
|
|
92
|
+
lastELU = perf.performance.eventLoopUtilization();
|
|
93
|
+
}
|
|
94
|
+
if (procRef?.memoryUsage) {
|
|
95
|
+
const mem = procRef.memoryUsage();
|
|
96
|
+
snapshot.heapUsedBytes = mem.heapUsed;
|
|
97
|
+
snapshot.rssBytes = mem.rss;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const reasonFor = () => {
|
|
101
|
+
if (maxDelay > 0 && snapshot.eventLoopDelayMs > maxDelay) {
|
|
102
|
+
return `event-loop delay ${snapshot.eventLoopDelayMs.toFixed(0)}ms > ${maxDelay}ms`;
|
|
103
|
+
}
|
|
104
|
+
if (maxHeap !== undefined && snapshot.heapUsedBytes > maxHeap) {
|
|
105
|
+
return `heap used ${snapshot.heapUsedBytes} > ${maxHeap}`;
|
|
106
|
+
}
|
|
107
|
+
if (maxRss !== undefined && snapshot.rssBytes > maxRss) {
|
|
108
|
+
return `rss ${snapshot.rssBytes} > ${maxRss}`;
|
|
109
|
+
}
|
|
110
|
+
if (maxELU > 0 && snapshot.eventLoopUtilization > maxELU) {
|
|
111
|
+
return `event-loop utilization ${snapshot.eventLoopUtilization.toFixed(3)} > ${maxELU}`;
|
|
112
|
+
}
|
|
113
|
+
if (snapshot.reason)
|
|
114
|
+
return snapshot.reason;
|
|
115
|
+
return undefined;
|
|
116
|
+
};
|
|
117
|
+
const startTimer = () => {
|
|
118
|
+
if (timer || stopped)
|
|
119
|
+
return;
|
|
120
|
+
if (typeof setInterval !== "function")
|
|
121
|
+
return;
|
|
122
|
+
timer = setInterval(() => {
|
|
123
|
+
refreshSnapshot();
|
|
124
|
+
}, sampleMs);
|
|
125
|
+
const unref = timer.unref;
|
|
126
|
+
if (typeof unref === "function")
|
|
127
|
+
unref.call(timer);
|
|
128
|
+
};
|
|
129
|
+
const maybeSample = async () => {
|
|
130
|
+
await ensurePerf();
|
|
131
|
+
const now = Date.now();
|
|
132
|
+
if (now - lastSample >= sampleMs) {
|
|
133
|
+
lastSample = now;
|
|
134
|
+
refreshSnapshot();
|
|
135
|
+
startTimer();
|
|
136
|
+
}
|
|
137
|
+
if (opts.healthCheck && now - lastHealth >= healthCheckMs) {
|
|
138
|
+
lastHealth = now;
|
|
139
|
+
try {
|
|
140
|
+
const reason = await opts.healthCheck();
|
|
141
|
+
snapshot.reason = reason || undefined;
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
snapshot.reason =
|
|
145
|
+
err instanceof Error ? `healthCheck threw: ${err.message}` : "healthCheck threw";
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
return {
|
|
150
|
+
async beforeHandle() {
|
|
151
|
+
await maybeSample();
|
|
152
|
+
const reason = reasonFor();
|
|
153
|
+
if (!reason)
|
|
154
|
+
return undefined;
|
|
155
|
+
throw new HttpError(503, {
|
|
156
|
+
type: "https://daloyjs.dev/errors/load-shed",
|
|
157
|
+
title: "Service Unavailable",
|
|
158
|
+
detail: `Load shedding: ${reason}`,
|
|
159
|
+
}, { "retry-after": String(retryAfter) });
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Read-only accessor for tests + observability plugins that want to know
|
|
165
|
+
* what the latest pressure sample looked like. Returns `undefined` if the
|
|
166
|
+
* given hooks object was not produced by {@link loadShedding}.
|
|
167
|
+
*
|
|
168
|
+
* @internal
|
|
169
|
+
*/
|
|
170
|
+
export const LOAD_SHEDDING_MARKER = Symbol.for("daloyjs.loadShedding");
|
|
171
|
+
//# sourceMappingURL=load-shedding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-shedding.js","sourceRoot":"","sources":["../src/load-shedding.ts"],"names":[],"mappings":"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"}
|
package/dist/middleware.d.ts
CHANGED
|
@@ -64,6 +64,15 @@ export interface CspDirectivesOptions {
|
|
|
64
64
|
trustedTypes?: boolean | {
|
|
65
65
|
policies?: string[];
|
|
66
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* When set, append `report-to <group>` to the generated CSP header so
|
|
69
|
+
* browsers POST violation reports to the named Reporting API endpoint.
|
|
70
|
+
* Pair with {@link SecureHeadersOptions.reportingEndpoints} (or
|
|
71
|
+
* {@link App.cspReportRoute}) to register the receiver. Wave 4 leftover.
|
|
72
|
+
*
|
|
73
|
+
* @since 0.20.0
|
|
74
|
+
*/
|
|
75
|
+
reportTo?: string;
|
|
67
76
|
}
|
|
68
77
|
export interface SecureHeadersOptions {
|
|
69
78
|
contentSecurityPolicy?: string | false | CspDirectivesOptions;
|
|
@@ -79,6 +88,27 @@ export interface SecureHeadersOptions {
|
|
|
79
88
|
crossOriginResourcePolicy?: string | false;
|
|
80
89
|
noSniff?: boolean;
|
|
81
90
|
xssProtection?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Reporting API endpoint declarations rendered as the
|
|
93
|
+
* `Reporting-Endpoints` response header (modern browsers) plus a
|
|
94
|
+
* legacy `Report-To` JSON header for older Chromium versions. Keys are
|
|
95
|
+
* group names; values are absolute URLs that accept POSTed reports.
|
|
96
|
+
* Pair with {@link CspDirectivesOptions.reportTo} (or pass
|
|
97
|
+
* `reportTo: "csp-endpoint"` here as a shortcut) to direct CSP
|
|
98
|
+
* violation reports there. Wave 4 leftover.
|
|
99
|
+
*
|
|
100
|
+
* @since 0.20.0
|
|
101
|
+
*/
|
|
102
|
+
reportingEndpoints?: Record<string, string>;
|
|
103
|
+
/**
|
|
104
|
+
* Shortcut: when set and {@link SecureHeadersOptions.contentSecurityPolicy}
|
|
105
|
+
* is a directives object, append `report-to <reportTo>` to the CSP
|
|
106
|
+
* header so violation reports land at the matching
|
|
107
|
+
* `reportingEndpoints` URL.
|
|
108
|
+
*
|
|
109
|
+
* @since 0.20.0
|
|
110
|
+
*/
|
|
111
|
+
reportTo?: string;
|
|
82
112
|
}
|
|
83
113
|
/**
|
|
84
114
|
* Apply a Helmet-equivalent baseline of secure response headers:
|
|
@@ -140,6 +170,30 @@ export declare const CORS_HOOK_MARKER: unique symbol;
|
|
|
140
170
|
* @since 0.16.0
|
|
141
171
|
*/
|
|
142
172
|
export declare const CORS_ORIGIN_ALLOW_MARKER: unique symbol;
|
|
173
|
+
/**
|
|
174
|
+
* Marker stamped on the `Hooks` object returned by {@link cors} when the
|
|
175
|
+
* configured `origin` permits the wildcard `"*"`. Used by the Wave 3
|
|
176
|
+
* boot-time refuse-to-boot guard: a wildcard CORS origin in production is
|
|
177
|
+
* almost always a misconfiguration, so `App` constructed with
|
|
178
|
+
* `secureDefaults: true` (the 0.16+ default) and resolved to
|
|
179
|
+
* `production` throws at `app.use(cors({ origin: "*" }))` time rather than
|
|
180
|
+
* silently exposing every state-changing endpoint cross-origin.
|
|
181
|
+
*
|
|
182
|
+
* @since 0.17.0
|
|
183
|
+
*/
|
|
184
|
+
export declare const CORS_WILDCARD_ORIGIN_MARKER: unique symbol;
|
|
185
|
+
/**
|
|
186
|
+
* Marker stamped on the `Hooks` object returned by {@link csrf}. Used by
|
|
187
|
+
* the Wave 3 boot-time refuse-to-boot guard: when `session()` is registered
|
|
188
|
+
* on a `secureDefaults: true` App that also exposes any state-changing
|
|
189
|
+
* route, the framework requires a matching `csrf()` hook somewhere in the
|
|
190
|
+
* hook chain so an attacker cannot forge a cross-site request that mutates
|
|
191
|
+
* the authenticated session. Third-party CSRF helpers can opt into the
|
|
192
|
+
* guard by stamping the same marker on their returned hooks.
|
|
193
|
+
*
|
|
194
|
+
* @since 0.17.0
|
|
195
|
+
*/
|
|
196
|
+
export declare const CSRF_HOOK_MARKER: unique symbol;
|
|
143
197
|
export type CorsOriginAllow = (origin: string) => boolean;
|
|
144
198
|
export interface CorsOptions {
|
|
145
199
|
origin: string | string[] | ((origin: string) => boolean);
|
|
@@ -195,7 +249,23 @@ export interface RateLimitOptions {
|
|
|
195
249
|
trustProxyHeaders?: boolean;
|
|
196
250
|
/** When true, set Retry-After header on 429. Default: true. */
|
|
197
251
|
retryAfter?: boolean;
|
|
252
|
+
/**
|
|
253
|
+
* Share a single bucket across every `rateLimit()` call that declares the
|
|
254
|
+
* same `groupId`. Use this to enforce one combined limit across related
|
|
255
|
+
* routes (e.g. `/login`, `/login/otp`, and `/password-reset` all spend
|
|
256
|
+
* from the same per-IP "auth" bucket). Without `groupId`, each
|
|
257
|
+
* `rateLimit()` call gets its own independent in-memory store.
|
|
258
|
+
*
|
|
259
|
+
* Cooperation is only meaningful for the default in-memory store; when
|
|
260
|
+
* an explicit `store` is supplied the developer is responsible for
|
|
261
|
+
* keying it. The framework prepends the `groupId` to the derived key so
|
|
262
|
+
* two groups never collide in a shared store either.
|
|
263
|
+
*
|
|
264
|
+
* @since 0.19.0
|
|
265
|
+
*/
|
|
266
|
+
groupId?: string;
|
|
198
267
|
}
|
|
268
|
+
export declare function _resetSharedRateLimitStoresForTests(): void;
|
|
199
269
|
/**
|
|
200
270
|
* Fixed-window rate limiter. Throws {@link TooManyRequestsError} (mapped to
|
|
201
271
|
* `429`) when a key exceeds `max` requests inside `windowMs`. Adds
|
|
@@ -229,6 +299,40 @@ export interface RateLimitOptions {
|
|
|
229
299
|
* @since 0.1.0
|
|
230
300
|
*/
|
|
231
301
|
export declare function rateLimit(opts: RateLimitOptions): Hooks;
|
|
302
|
+
export interface LoginThrottleOptions {
|
|
303
|
+
/** Fixed-window length in ms. Default: 15 minutes. */
|
|
304
|
+
windowMs?: number;
|
|
305
|
+
/** Maximum attempts before returning 429. Default: 5. */
|
|
306
|
+
max?: number;
|
|
307
|
+
/** Shared bucket id. Default: `"login"`. */
|
|
308
|
+
groupId?: string;
|
|
309
|
+
/** Derive the caller key. Defaults to trusted proxy headers only when enabled. */
|
|
310
|
+
keyGenerator?: (ctx: BaseContext<any, any>) => string;
|
|
311
|
+
/** Shared store for the hard limit. Uses rateLimit()'s in-memory group bucket by default. */
|
|
312
|
+
store?: RateLimitStore;
|
|
313
|
+
/** Trust x-forwarded-for / x-real-ip when deriving the default key. Default: false. */
|
|
314
|
+
trustProxyHeaders?: boolean;
|
|
315
|
+
/** When true, set Retry-After header on 429. Default: true. */
|
|
316
|
+
retryAfter?: boolean;
|
|
317
|
+
/** Start slowing responses after this many attempts in the same window. Default: 2. */
|
|
318
|
+
delayAfter?: number;
|
|
319
|
+
/** Added delay per attempt beyond delayAfter, in ms. Default: 250. */
|
|
320
|
+
delayMs?: number;
|
|
321
|
+
/** Maximum slowdown delay in ms. Default: 2000. */
|
|
322
|
+
maxDelayMs?: number;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Login throttle preset for `/login`, `/login/otp`, password reset, and
|
|
326
|
+
* adjacent credential-entry routes. It combines a shared `rateLimit({ groupId })`
|
|
327
|
+
* bucket with a small progressive slowdown before the hard 429 kicks in.
|
|
328
|
+
*
|
|
329
|
+
* Mount the same `loginThrottle()` instance (or multiple instances with the
|
|
330
|
+
* same `groupId`) across related routes so an attacker cannot bypass the limit
|
|
331
|
+
* by rotating between password, OTP, and reset endpoints.
|
|
332
|
+
*
|
|
333
|
+
* @since 0.23.0
|
|
334
|
+
*/
|
|
335
|
+
export declare function loginThrottle(opts?: LoginThrottleOptions): Hooks;
|
|
232
336
|
/**
|
|
233
337
|
* Stamp a `Server-Timing` header (or your chosen header) on every response
|
|
234
338
|
* with the handler's wall-clock duration in milliseconds. Browsers display
|
|
@@ -270,10 +374,63 @@ export declare function timing(headerName?: string): Hooks;
|
|
|
270
374
|
* @returns A {@link Hooks} bundle ready for `app.use(...)`.
|
|
271
375
|
* @since 0.1.0
|
|
272
376
|
*/
|
|
273
|
-
|
|
377
|
+
/**
|
|
378
|
+
* Per-request revalidation hook for {@link bearerAuth}. Runs after `validate`
|
|
379
|
+
* has accepted the raw token, and is the integration point for
|
|
380
|
+
* **revocation lists**, **token-version counters** ("user changed password
|
|
381
|
+
* since this token was issued"), and "this token was issued before the
|
|
382
|
+
* tenant was disabled" checks. Returning `false` rejects the request with
|
|
383
|
+
* `403`; returning `true` or `undefined` accepts.
|
|
384
|
+
*
|
|
385
|
+
* @since 0.22.0
|
|
386
|
+
*/
|
|
387
|
+
export type BearerAuthVerifyHook<TCredentials = string> = (credentials: TCredentials, ctx: BaseContext<any, any>) => boolean | void | Promise<boolean | void>;
|
|
388
|
+
export interface BearerAuthOptions {
|
|
389
|
+
/** Cheap, stateless token check (signature / format). */
|
|
274
390
|
validate: (token: string) => boolean | Promise<boolean>;
|
|
391
|
+
/** WWW-Authenticate realm. Default: `"api"`. */
|
|
275
392
|
realm?: string;
|
|
276
|
-
|
|
393
|
+
/**
|
|
394
|
+
* Optional per-request revalidation hook (Wave 5). Called after `validate`
|
|
395
|
+
* accepts the token. Returning `false` rejects the request with `403`;
|
|
396
|
+
* returning `true` or `undefined` accepts. Use for revocation lists,
|
|
397
|
+
* token-version counters, etc.
|
|
398
|
+
*
|
|
399
|
+
* @since 0.22.0
|
|
400
|
+
*/
|
|
401
|
+
verify?: BearerAuthVerifyHook<string>;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Minimal Bearer-token authentication middleware. Rejects requests with no
|
|
405
|
+
* `Authorization: Bearer ...` header with `401` (and a `WWW-Authenticate`
|
|
406
|
+
* challenge), and requests whose token fails `validate(token)` (or the
|
|
407
|
+
* optional per-request `verify(token, ctx)` revalidation hook) with `403`.
|
|
408
|
+
*
|
|
409
|
+
* The `validate` callback is the integration point with whatever JWT
|
|
410
|
+
* verifier, opaque-token introspector, or in-memory test stub you use. The
|
|
411
|
+
* optional `verify` hook (Wave 5) is the integration point for revocation
|
|
412
|
+
* lists, token-version counters, and other per-request invalidation checks
|
|
413
|
+
* that `validate` cannot answer statelessly.
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```ts
|
|
417
|
+
* import { bearerAuth } from "@daloyjs/core";
|
|
418
|
+
* import { jwtVerify } from "jose";
|
|
419
|
+
*
|
|
420
|
+
* app.use(bearerAuth({
|
|
421
|
+
* realm: "books-api",
|
|
422
|
+
* validate: async (token) => {
|
|
423
|
+
* try { await jwtVerify(token, jwks); return true; } catch { return false; }
|
|
424
|
+
* },
|
|
425
|
+
* verify: async (token, _ctx) => !(await revoked.has(hash(token))),
|
|
426
|
+
* }));
|
|
427
|
+
* ```
|
|
428
|
+
*
|
|
429
|
+
* @param opts - Token validator, optional revalidation hook, and realm.
|
|
430
|
+
* @returns A {@link Hooks} bundle ready for `app.use(...)`.
|
|
431
|
+
* @since 0.1.0
|
|
432
|
+
*/
|
|
433
|
+
export declare function bearerAuth(opts: BearerAuthOptions): Hooks;
|
|
277
434
|
/**
|
|
278
435
|
* Cookie attributes for the CSRF token cookie. The token cookie must be
|
|
279
436
|
* **readable by client-side JavaScript** (so the SPA can mirror it into a
|
|
@@ -383,6 +540,18 @@ export interface BasicAuthOptions {
|
|
|
383
540
|
* without invoking `verify`.
|
|
384
541
|
*/
|
|
385
542
|
maxCredentialBytes?: number;
|
|
543
|
+
/**
|
|
544
|
+
* Typed-context callback fired after `verify` accepts the credentials and
|
|
545
|
+
* after the framework has stamped `ctx.state.user`. Use this to decorate
|
|
546
|
+
* `ctx.state` with extra fields (typed via `AppState`) so handlers do not
|
|
547
|
+
* re-parse the `Authorization` header in every route.
|
|
548
|
+
*
|
|
549
|
+
* @since 0.22.0
|
|
550
|
+
*/
|
|
551
|
+
onAuthSuccess?: (creds: {
|
|
552
|
+
username: string;
|
|
553
|
+
password: string;
|
|
554
|
+
}, ctx: BaseContext<any, any>) => void | Promise<void>;
|
|
386
555
|
}
|
|
387
556
|
/**
|
|
388
557
|
* HTTP Basic Authentication middleware (RFC 7617).
|
|
@@ -412,5 +581,39 @@ export interface BasicAuthOptions {
|
|
|
412
581
|
* @since 0.12.0
|
|
413
582
|
*/
|
|
414
583
|
export declare function basicAuth(opts: BasicAuthOptions): Hooks;
|
|
584
|
+
/**
|
|
585
|
+
* Marker stamped on the per-request `state` bag so multiple `requireScopes()`
|
|
586
|
+
* hooks in the same chain aggregate their required scopes into one combined
|
|
587
|
+
* `WWW-Authenticate: Bearer scope="..."` challenge instead of each emitting a
|
|
588
|
+
* separate `401` with only its own scopes.
|
|
589
|
+
*
|
|
590
|
+
* @since 0.21.0
|
|
591
|
+
*/
|
|
592
|
+
export declare const REQUIRE_SCOPES_AGGREGATE_KEY: "__daloyRequiredScopes";
|
|
593
|
+
export declare const REQUIRE_SCOPES_HOOK_MARKER: unique symbol;
|
|
594
|
+
/**
|
|
595
|
+
* Declarative scope-check middleware for OAuth2-style bearer credentials.
|
|
596
|
+
* Reads the typed `ctx.state.user.scopes` written by the upstream auth
|
|
597
|
+
* helper (`bearerAuth`, `jwt`, …) and refuses the request with `401` (no
|
|
598
|
+
* credentials) or `403` (valid credentials but insufficient scopes).
|
|
599
|
+
*
|
|
600
|
+
* Multiple `requireScopes()` hooks in the same chain aggregate their required
|
|
601
|
+
* scopes into one combined `WWW-Authenticate: Bearer scope="a b c"` challenge
|
|
602
|
+
* via {@link REQUIRE_SCOPES_AGGREGATE_KEY} on `ctx.state`.
|
|
603
|
+
*
|
|
604
|
+
* @example
|
|
605
|
+
* ```ts
|
|
606
|
+
* app.route({
|
|
607
|
+
* method: "POST",
|
|
608
|
+
* path: "/items",
|
|
609
|
+
* hooks: { ...bearerAuth({ validate }), ...requireScopes(["items:write"]) },
|
|
610
|
+
* responses: { 200: { description: "ok" } },
|
|
611
|
+
* handler: () => ({ status: 200 as const, body: { ok: true } }),
|
|
612
|
+
* });
|
|
613
|
+
* ```
|
|
614
|
+
*
|
|
615
|
+
* @since 0.21.0
|
|
616
|
+
*/
|
|
617
|
+
export declare function requireScopes(scopes: readonly string[]): Hooks;
|
|
415
618
|
export { timingSafeEqual };
|
|
416
619
|
//# sourceMappingURL=middleware.d.ts.map
|
package/dist/middleware.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
|