express-rate-limit 7.4.1 → 7.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +76 -6
- package/dist/index.d.cts +17 -1
- package/dist/index.d.mts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.mjs +76 -6
- package/package.json +3 -3
- package/readme.md +22 -19
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,9 @@ __export(source_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(source_exports);
|
|
28
28
|
|
|
29
29
|
// source/headers.ts
|
|
30
|
+
var import_node_buffer = require("buffer");
|
|
31
|
+
var import_node_crypto = require("crypto");
|
|
32
|
+
var SUPPORTED_DRAFT_VERSIONS = ["draft-6", "draft-7", "draft-8"];
|
|
30
33
|
var getResetSeconds = (resetTime, windowMs) => {
|
|
31
34
|
let resetSeconds = void 0;
|
|
32
35
|
if (resetTime) {
|
|
@@ -37,6 +40,12 @@ var getResetSeconds = (resetTime, windowMs) => {
|
|
|
37
40
|
}
|
|
38
41
|
return resetSeconds;
|
|
39
42
|
};
|
|
43
|
+
var getPartitionKey = (key) => {
|
|
44
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
45
|
+
hash.update(key);
|
|
46
|
+
const partitionKey = hash.digest("hex").slice(0, 12);
|
|
47
|
+
return import_node_buffer.Buffer.from(partitionKey).toString("base64");
|
|
48
|
+
};
|
|
40
49
|
var setLegacyHeaders = (response, info) => {
|
|
41
50
|
if (response.headersSent)
|
|
42
51
|
return;
|
|
@@ -72,6 +81,17 @@ var setDraft7Headers = (response, info, windowMs) => {
|
|
|
72
81
|
`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`
|
|
73
82
|
);
|
|
74
83
|
};
|
|
84
|
+
var setDraft8Headers = (response, info, windowMs, name, key) => {
|
|
85
|
+
if (response.headersSent)
|
|
86
|
+
return;
|
|
87
|
+
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
88
|
+
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
89
|
+
const partitionKey = getPartitionKey(key);
|
|
90
|
+
const policy = `q=${info.limit}; w=${windowSeconds}; pk=:${partitionKey}:`;
|
|
91
|
+
const header = `r=${info.remaining}; t=${resetSeconds}`;
|
|
92
|
+
response.append("RateLimit-Policy", `"${name}"; ${policy}`);
|
|
93
|
+
response.append("RateLimit", `"${name}"; ${header}`);
|
|
94
|
+
};
|
|
75
95
|
var setRetryAfterHeader = (response, info, windowMs) => {
|
|
76
96
|
if (response.headersSent)
|
|
77
97
|
return;
|
|
@@ -274,6 +294,22 @@ var validations = {
|
|
|
274
294
|
);
|
|
275
295
|
}
|
|
276
296
|
},
|
|
297
|
+
/**
|
|
298
|
+
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
|
299
|
+
*
|
|
300
|
+
* @param version {any | undefined} - The version passed by the user.
|
|
301
|
+
*
|
|
302
|
+
* @returns {void}
|
|
303
|
+
*/
|
|
304
|
+
headersDraftVersion(version) {
|
|
305
|
+
if (typeof version !== "string" || !SUPPORTED_DRAFT_VERSIONS.includes(version)) {
|
|
306
|
+
const versionString = SUPPORTED_DRAFT_VERSIONS.join(", ");
|
|
307
|
+
throw new ValidationError(
|
|
308
|
+
"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",
|
|
309
|
+
`standardHeaders: only the following versions of the IETF draft specification are supported: ${versionString}.`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
},
|
|
277
313
|
/**
|
|
278
314
|
* Warns the user when the selected headers option requires a reset time but
|
|
279
315
|
* the store does not provide one.
|
|
@@ -606,6 +642,24 @@ var parseOptions = (passedOptions) => {
|
|
|
606
642
|
message: "Too many requests, please try again later.",
|
|
607
643
|
statusCode: 429,
|
|
608
644
|
legacyHeaders: passedOptions.headers ?? true,
|
|
645
|
+
identifier(request, _response) {
|
|
646
|
+
let duration = "";
|
|
647
|
+
const property = config.requestPropertyName;
|
|
648
|
+
const { limit } = request[property];
|
|
649
|
+
const seconds = config.windowMs / 1e3;
|
|
650
|
+
const minutes = config.windowMs / (1e3 * 60);
|
|
651
|
+
const hours = config.windowMs / (1e3 * 60 * 60);
|
|
652
|
+
const days = config.windowMs / (1e3 * 60 * 60 * 24);
|
|
653
|
+
if (seconds < 60)
|
|
654
|
+
duration = `${seconds}sec`;
|
|
655
|
+
else if (minutes < 60)
|
|
656
|
+
duration = `${minutes}min`;
|
|
657
|
+
else if (hours < 24)
|
|
658
|
+
duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
|
659
|
+
else
|
|
660
|
+
duration = `${days}day${days > 1 ? "s" : ""}`;
|
|
661
|
+
return `${limit}-in-${duration}`;
|
|
662
|
+
},
|
|
609
663
|
requestPropertyName: "rateLimit",
|
|
610
664
|
skipFailedRequests: false,
|
|
611
665
|
skipSuccessfulRequests: false,
|
|
@@ -628,7 +682,7 @@ var parseOptions = (passedOptions) => {
|
|
|
628
682
|
}
|
|
629
683
|
},
|
|
630
684
|
passOnStoreError: false,
|
|
631
|
-
// Allow the default options to be overriden by the
|
|
685
|
+
// Allow the default options to be overriden by the passed options.
|
|
632
686
|
...notUndefinedOptions,
|
|
633
687
|
// `standardHeaders` is resolved into a draft version above, use that.
|
|
634
688
|
standardHeaders,
|
|
@@ -706,11 +760,27 @@ var rateLimit = (passedOptions) => {
|
|
|
706
760
|
setLegacyHeaders(response, info);
|
|
707
761
|
}
|
|
708
762
|
if (config.standardHeaders && !response.headersSent) {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
763
|
+
switch (config.standardHeaders) {
|
|
764
|
+
case "draft-6": {
|
|
765
|
+
setDraft6Headers(response, info, config.windowMs);
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
case "draft-7": {
|
|
769
|
+
config.validations.headersResetTime(info.resetTime);
|
|
770
|
+
setDraft7Headers(response, info, config.windowMs);
|
|
771
|
+
break;
|
|
772
|
+
}
|
|
773
|
+
case "draft-8": {
|
|
774
|
+
const retrieveName = typeof config.identifier === "function" ? config.identifier(request, response) : config.identifier;
|
|
775
|
+
const name = await retrieveName;
|
|
776
|
+
config.validations.headersResetTime(info.resetTime);
|
|
777
|
+
setDraft8Headers(response, info, config.windowMs, name, key);
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
default: {
|
|
781
|
+
config.validations.headersDraftVersion(config.standardHeaders);
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
714
784
|
}
|
|
715
785
|
}
|
|
716
786
|
if (config.skipFailedRequests || config.skipSuccessfulRequests) {
|
package/dist/index.d.cts
CHANGED
|
@@ -86,6 +86,14 @@ declare const validations: {
|
|
|
86
86
|
* @returns {void}
|
|
87
87
|
*/
|
|
88
88
|
onLimitReached(onLimitReached?: any): void;
|
|
89
|
+
/**
|
|
90
|
+
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
|
91
|
+
*
|
|
92
|
+
* @param version {any | undefined} - The version passed by the user.
|
|
93
|
+
*
|
|
94
|
+
* @returns {void}
|
|
95
|
+
*/
|
|
96
|
+
headersDraftVersion(version?: any): void;
|
|
89
97
|
/**
|
|
90
98
|
* Warns the user when the selected headers option requires a reset time but
|
|
91
99
|
* the store does not provide one.
|
|
@@ -111,6 +119,7 @@ declare const validations: {
|
|
|
111
119
|
creationStack(store: Store): void;
|
|
112
120
|
};
|
|
113
121
|
export type Validations = typeof validations;
|
|
122
|
+
declare const SUPPORTED_DRAFT_VERSIONS: string[];
|
|
114
123
|
/**
|
|
115
124
|
* Callback that fires when a client's hit counter is incremented.
|
|
116
125
|
*
|
|
@@ -271,7 +280,7 @@ export type Store = {
|
|
|
271
280
|
*/
|
|
272
281
|
prefix?: string;
|
|
273
282
|
};
|
|
274
|
-
export type DraftHeadersVersion =
|
|
283
|
+
export type DraftHeadersVersion = (typeof SUPPORTED_DRAFT_VERSIONS)[number];
|
|
275
284
|
/**
|
|
276
285
|
* Validate configuration object for enabling or disabling specific validations.
|
|
277
286
|
*
|
|
@@ -326,6 +335,13 @@ export type Options = {
|
|
|
326
335
|
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
|
327
336
|
*/
|
|
328
337
|
standardHeaders: boolean | DraftHeadersVersion;
|
|
338
|
+
/**
|
|
339
|
+
* The name used to identify the quota policy in the `RateLimit` headers as per
|
|
340
|
+
* the 8th draft of the IETF specification.
|
|
341
|
+
*
|
|
342
|
+
* Defaults to `{limit}-in-{window}`.
|
|
343
|
+
*/
|
|
344
|
+
identifier: string | ValueDeterminingMiddleware<string>;
|
|
329
345
|
/**
|
|
330
346
|
* The name of the property on the request object to store the rate limit info.
|
|
331
347
|
*
|
package/dist/index.d.mts
CHANGED
|
@@ -86,6 +86,14 @@ declare const validations: {
|
|
|
86
86
|
* @returns {void}
|
|
87
87
|
*/
|
|
88
88
|
onLimitReached(onLimitReached?: any): void;
|
|
89
|
+
/**
|
|
90
|
+
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
|
91
|
+
*
|
|
92
|
+
* @param version {any | undefined} - The version passed by the user.
|
|
93
|
+
*
|
|
94
|
+
* @returns {void}
|
|
95
|
+
*/
|
|
96
|
+
headersDraftVersion(version?: any): void;
|
|
89
97
|
/**
|
|
90
98
|
* Warns the user when the selected headers option requires a reset time but
|
|
91
99
|
* the store does not provide one.
|
|
@@ -111,6 +119,7 @@ declare const validations: {
|
|
|
111
119
|
creationStack(store: Store): void;
|
|
112
120
|
};
|
|
113
121
|
export type Validations = typeof validations;
|
|
122
|
+
declare const SUPPORTED_DRAFT_VERSIONS: string[];
|
|
114
123
|
/**
|
|
115
124
|
* Callback that fires when a client's hit counter is incremented.
|
|
116
125
|
*
|
|
@@ -271,7 +280,7 @@ export type Store = {
|
|
|
271
280
|
*/
|
|
272
281
|
prefix?: string;
|
|
273
282
|
};
|
|
274
|
-
export type DraftHeadersVersion =
|
|
283
|
+
export type DraftHeadersVersion = (typeof SUPPORTED_DRAFT_VERSIONS)[number];
|
|
275
284
|
/**
|
|
276
285
|
* Validate configuration object for enabling or disabling specific validations.
|
|
277
286
|
*
|
|
@@ -326,6 +335,13 @@ export type Options = {
|
|
|
326
335
|
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
|
327
336
|
*/
|
|
328
337
|
standardHeaders: boolean | DraftHeadersVersion;
|
|
338
|
+
/**
|
|
339
|
+
* The name used to identify the quota policy in the `RateLimit` headers as per
|
|
340
|
+
* the 8th draft of the IETF specification.
|
|
341
|
+
*
|
|
342
|
+
* Defaults to `{limit}-in-{window}`.
|
|
343
|
+
*/
|
|
344
|
+
identifier: string | ValueDeterminingMiddleware<string>;
|
|
329
345
|
/**
|
|
330
346
|
* The name of the property on the request object to store the rate limit info.
|
|
331
347
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -86,6 +86,14 @@ declare const validations: {
|
|
|
86
86
|
* @returns {void}
|
|
87
87
|
*/
|
|
88
88
|
onLimitReached(onLimitReached?: any): void;
|
|
89
|
+
/**
|
|
90
|
+
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
|
91
|
+
*
|
|
92
|
+
* @param version {any | undefined} - The version passed by the user.
|
|
93
|
+
*
|
|
94
|
+
* @returns {void}
|
|
95
|
+
*/
|
|
96
|
+
headersDraftVersion(version?: any): void;
|
|
89
97
|
/**
|
|
90
98
|
* Warns the user when the selected headers option requires a reset time but
|
|
91
99
|
* the store does not provide one.
|
|
@@ -111,6 +119,7 @@ declare const validations: {
|
|
|
111
119
|
creationStack(store: Store): void;
|
|
112
120
|
};
|
|
113
121
|
export type Validations = typeof validations;
|
|
122
|
+
declare const SUPPORTED_DRAFT_VERSIONS: string[];
|
|
114
123
|
/**
|
|
115
124
|
* Callback that fires when a client's hit counter is incremented.
|
|
116
125
|
*
|
|
@@ -271,7 +280,7 @@ export type Store = {
|
|
|
271
280
|
*/
|
|
272
281
|
prefix?: string;
|
|
273
282
|
};
|
|
274
|
-
export type DraftHeadersVersion =
|
|
283
|
+
export type DraftHeadersVersion = (typeof SUPPORTED_DRAFT_VERSIONS)[number];
|
|
275
284
|
/**
|
|
276
285
|
* Validate configuration object for enabling or disabling specific validations.
|
|
277
286
|
*
|
|
@@ -326,6 +335,13 @@ export type Options = {
|
|
|
326
335
|
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
|
327
336
|
*/
|
|
328
337
|
standardHeaders: boolean | DraftHeadersVersion;
|
|
338
|
+
/**
|
|
339
|
+
* The name used to identify the quota policy in the `RateLimit` headers as per
|
|
340
|
+
* the 8th draft of the IETF specification.
|
|
341
|
+
*
|
|
342
|
+
* Defaults to `{limit}-in-{window}`.
|
|
343
|
+
*/
|
|
344
|
+
identifier: string | ValueDeterminingMiddleware<string>;
|
|
329
345
|
/**
|
|
330
346
|
* The name of the property on the request object to store the rate limit info.
|
|
331
347
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// source/headers.ts
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
var SUPPORTED_DRAFT_VERSIONS = ["draft-6", "draft-7", "draft-8"];
|
|
2
5
|
var getResetSeconds = (resetTime, windowMs) => {
|
|
3
6
|
let resetSeconds = void 0;
|
|
4
7
|
if (resetTime) {
|
|
@@ -9,6 +12,12 @@ var getResetSeconds = (resetTime, windowMs) => {
|
|
|
9
12
|
}
|
|
10
13
|
return resetSeconds;
|
|
11
14
|
};
|
|
15
|
+
var getPartitionKey = (key) => {
|
|
16
|
+
const hash = createHash("sha256");
|
|
17
|
+
hash.update(key);
|
|
18
|
+
const partitionKey = hash.digest("hex").slice(0, 12);
|
|
19
|
+
return Buffer.from(partitionKey).toString("base64");
|
|
20
|
+
};
|
|
12
21
|
var setLegacyHeaders = (response, info) => {
|
|
13
22
|
if (response.headersSent)
|
|
14
23
|
return;
|
|
@@ -44,6 +53,17 @@ var setDraft7Headers = (response, info, windowMs) => {
|
|
|
44
53
|
`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`
|
|
45
54
|
);
|
|
46
55
|
};
|
|
56
|
+
var setDraft8Headers = (response, info, windowMs, name, key) => {
|
|
57
|
+
if (response.headersSent)
|
|
58
|
+
return;
|
|
59
|
+
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
60
|
+
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
61
|
+
const partitionKey = getPartitionKey(key);
|
|
62
|
+
const policy = `q=${info.limit}; w=${windowSeconds}; pk=:${partitionKey}:`;
|
|
63
|
+
const header = `r=${info.remaining}; t=${resetSeconds}`;
|
|
64
|
+
response.append("RateLimit-Policy", `"${name}"; ${policy}`);
|
|
65
|
+
response.append("RateLimit", `"${name}"; ${header}`);
|
|
66
|
+
};
|
|
47
67
|
var setRetryAfterHeader = (response, info, windowMs) => {
|
|
48
68
|
if (response.headersSent)
|
|
49
69
|
return;
|
|
@@ -246,6 +266,22 @@ var validations = {
|
|
|
246
266
|
);
|
|
247
267
|
}
|
|
248
268
|
},
|
|
269
|
+
/**
|
|
270
|
+
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
|
271
|
+
*
|
|
272
|
+
* @param version {any | undefined} - The version passed by the user.
|
|
273
|
+
*
|
|
274
|
+
* @returns {void}
|
|
275
|
+
*/
|
|
276
|
+
headersDraftVersion(version) {
|
|
277
|
+
if (typeof version !== "string" || !SUPPORTED_DRAFT_VERSIONS.includes(version)) {
|
|
278
|
+
const versionString = SUPPORTED_DRAFT_VERSIONS.join(", ");
|
|
279
|
+
throw new ValidationError(
|
|
280
|
+
"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",
|
|
281
|
+
`standardHeaders: only the following versions of the IETF draft specification are supported: ${versionString}.`
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
},
|
|
249
285
|
/**
|
|
250
286
|
* Warns the user when the selected headers option requires a reset time but
|
|
251
287
|
* the store does not provide one.
|
|
@@ -578,6 +614,24 @@ var parseOptions = (passedOptions) => {
|
|
|
578
614
|
message: "Too many requests, please try again later.",
|
|
579
615
|
statusCode: 429,
|
|
580
616
|
legacyHeaders: passedOptions.headers ?? true,
|
|
617
|
+
identifier(request, _response) {
|
|
618
|
+
let duration = "";
|
|
619
|
+
const property = config.requestPropertyName;
|
|
620
|
+
const { limit } = request[property];
|
|
621
|
+
const seconds = config.windowMs / 1e3;
|
|
622
|
+
const minutes = config.windowMs / (1e3 * 60);
|
|
623
|
+
const hours = config.windowMs / (1e3 * 60 * 60);
|
|
624
|
+
const days = config.windowMs / (1e3 * 60 * 60 * 24);
|
|
625
|
+
if (seconds < 60)
|
|
626
|
+
duration = `${seconds}sec`;
|
|
627
|
+
else if (minutes < 60)
|
|
628
|
+
duration = `${minutes}min`;
|
|
629
|
+
else if (hours < 24)
|
|
630
|
+
duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
|
631
|
+
else
|
|
632
|
+
duration = `${days}day${days > 1 ? "s" : ""}`;
|
|
633
|
+
return `${limit}-in-${duration}`;
|
|
634
|
+
},
|
|
581
635
|
requestPropertyName: "rateLimit",
|
|
582
636
|
skipFailedRequests: false,
|
|
583
637
|
skipSuccessfulRequests: false,
|
|
@@ -600,7 +654,7 @@ var parseOptions = (passedOptions) => {
|
|
|
600
654
|
}
|
|
601
655
|
},
|
|
602
656
|
passOnStoreError: false,
|
|
603
|
-
// Allow the default options to be overriden by the
|
|
657
|
+
// Allow the default options to be overriden by the passed options.
|
|
604
658
|
...notUndefinedOptions,
|
|
605
659
|
// `standardHeaders` is resolved into a draft version above, use that.
|
|
606
660
|
standardHeaders,
|
|
@@ -678,11 +732,27 @@ var rateLimit = (passedOptions) => {
|
|
|
678
732
|
setLegacyHeaders(response, info);
|
|
679
733
|
}
|
|
680
734
|
if (config.standardHeaders && !response.headersSent) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
735
|
+
switch (config.standardHeaders) {
|
|
736
|
+
case "draft-6": {
|
|
737
|
+
setDraft6Headers(response, info, config.windowMs);
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
case "draft-7": {
|
|
741
|
+
config.validations.headersResetTime(info.resetTime);
|
|
742
|
+
setDraft7Headers(response, info, config.windowMs);
|
|
743
|
+
break;
|
|
744
|
+
}
|
|
745
|
+
case "draft-8": {
|
|
746
|
+
const retrieveName = typeof config.identifier === "function" ? config.identifier(request, response) : config.identifier;
|
|
747
|
+
const name = await retrieveName;
|
|
748
|
+
config.validations.headersResetTime(info.resetTime);
|
|
749
|
+
setDraft8Headers(response, info, config.windowMs, name, key);
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
default: {
|
|
753
|
+
config.validations.headersDraftVersion(config.standardHeaders);
|
|
754
|
+
break;
|
|
755
|
+
}
|
|
686
756
|
}
|
|
687
757
|
}
|
|
688
758
|
if (config.skipFailedRequests || config.skipSuccessfulRequests) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"description": "Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Nathan Friedly",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"prepare": "run-s compile && husky install config/husky"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"express": "4 || 5 || ^5.0.0-beta.1"
|
|
77
|
+
"express": "^4.11 || 5 || ^5.0.0-beta.1"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@express-rate-limit/prettier": "1.1.1",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"del-cli": "5.1.0",
|
|
88
88
|
"dts-bundle-generator": "8.0.1",
|
|
89
89
|
"esbuild": "0.19.5",
|
|
90
|
-
"express": "4.21.
|
|
90
|
+
"express": "4.21.1",
|
|
91
91
|
"husky": "8.0.3",
|
|
92
92
|
"jest": "29.7.0",
|
|
93
93
|
"lint-staged": "15.0.2",
|
package/readme.md
CHANGED
|
@@ -26,7 +26,7 @@ import { rateLimit } from 'express-rate-limit'
|
|
|
26
26
|
const limiter = rateLimit({
|
|
27
27
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
28
28
|
limit: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes).
|
|
29
|
-
standardHeaders: 'draft-
|
|
29
|
+
standardHeaders: 'draft-8', // draft-6: `RateLimit-*` headers; draft-7 & draft-8: combined `RateLimit` header
|
|
30
30
|
legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
|
|
31
31
|
// store: ... , // Redis, Memcached, etc. See below.
|
|
32
32
|
})
|
|
@@ -45,24 +45,25 @@ The rate limiter comes with a built-in memory store, and supports a variety of
|
|
|
45
45
|
All function options may be async. Click the name for additional info and
|
|
46
46
|
default values.
|
|
47
47
|
|
|
48
|
-
| Option | Type
|
|
49
|
-
| -------------------------- |
|
|
50
|
-
| [`windowMs`] | `number`
|
|
51
|
-
| [`limit`] | `number` \| `function`
|
|
52
|
-
| [`message`] | `string` \| `json` \| `function`
|
|
53
|
-
| [`statusCode`] | `number`
|
|
54
|
-
| [`handler`] | `function`
|
|
55
|
-
| [`legacyHeaders`] | `boolean`
|
|
56
|
-
| [`standardHeaders`] | `'draft-6'` \| `'draft-7'`
|
|
57
|
-
| [`
|
|
58
|
-
| [`
|
|
59
|
-
| [`
|
|
60
|
-
| [`
|
|
61
|
-
| [`
|
|
62
|
-
| [`
|
|
63
|
-
| [`
|
|
64
|
-
| [`
|
|
65
|
-
| [`
|
|
48
|
+
| Option | Type | Remarks |
|
|
49
|
+
| -------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
50
|
+
| [`windowMs`] | `number` | How long to remember requests for, in milliseconds. |
|
|
51
|
+
| [`limit`] | `number` \| `function` | How many requests to allow. |
|
|
52
|
+
| [`message`] | `string` \| `json` \| `function` | Response to return after limit is reached. |
|
|
53
|
+
| [`statusCode`] | `number` | HTTP status code after limit is reached (default is 429). |
|
|
54
|
+
| [`handler`] | `function` | Function to run after limit is reached (overrides `message` and `statusCode` settings, if set). |
|
|
55
|
+
| [`legacyHeaders`] | `boolean` | Enable the `X-Rate-Limit` header. |
|
|
56
|
+
| [`standardHeaders`] | `'draft-6'` \| `'draft-7'` \| `'draft-8'` | Enable the `Ratelimit` header. |
|
|
57
|
+
| [`identifier`] | `string` \| `function` | Name associated with the quota policy enforced by this rate limiter. |
|
|
58
|
+
| [`store`] | `Store` | Use a custom store to share hit counts across multiple nodes. |
|
|
59
|
+
| [`passOnStoreError`] | `boolean` | Allow (`true`) or block (`false`, default) traffic if the store becomes unavailable. |
|
|
60
|
+
| [`keyGenerator`] | `function` | Identify users (defaults to IP address). |
|
|
61
|
+
| [`requestPropertyName`] | `string` | Add rate limit info to the `req` object. |
|
|
62
|
+
| [`skip`] | `function` | Return `true` to bypass the limiter for the given request. |
|
|
63
|
+
| [`skipSuccessfulRequests`] | `boolean` | Uncount 1xx/2xx/3xx responses. |
|
|
64
|
+
| [`skipFailedRequests`] | `boolean` | Uncount 4xx/5xx responses. |
|
|
65
|
+
| [`requestWasSuccessful`] | `function` | Used by `skipSuccessfulRequests` and `skipFailedRequests`. |
|
|
66
|
+
| [`validate`] | `boolean` \| `object` | Enable or disable built-in validation checks. |
|
|
66
67
|
|
|
67
68
|
## Thank You
|
|
68
69
|
|
|
@@ -126,6 +127,8 @@ MIT © [Nathan Friedly](http://nfriedly.com/),
|
|
|
126
127
|
https://express-rate-limit.mintlify.app/reference/configuration#legacyheaders
|
|
127
128
|
[`standardHeaders`]:
|
|
128
129
|
https://express-rate-limit.mintlify.app/reference/configuration#standardheaders
|
|
130
|
+
[`identifier`]:
|
|
131
|
+
https://express-rate-limit.mintlify.app/reference/configuration#identifier
|
|
129
132
|
[`store`]: https://express-rate-limit.mintlify.app/reference/configuration#store
|
|
130
133
|
[`passOnStoreError`]:
|
|
131
134
|
https://express-rate-limit.mintlify.app/reference/configuration#passOnStoreError
|