express-rate-limit 7.5.0 → 7.5.1
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 +35 -50
- package/dist/index.d.cts +5 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.mjs +32 -47
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -18,18 +18,22 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// source/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
23
|
MemoryStore: () => MemoryStore,
|
|
24
24
|
default: () => lib_default,
|
|
25
25
|
rateLimit: () => lib_default
|
|
26
26
|
});
|
|
27
|
-
module.exports = __toCommonJS(
|
|
27
|
+
module.exports = __toCommonJS(index_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 = [
|
|
30
|
+
var import_node_buffer = require("node:buffer");
|
|
31
|
+
var import_node_crypto = require("node:crypto");
|
|
32
|
+
var SUPPORTED_DRAFT_VERSIONS = [
|
|
33
|
+
"draft-6",
|
|
34
|
+
"draft-7",
|
|
35
|
+
"draft-8"
|
|
36
|
+
];
|
|
33
37
|
var getResetSeconds = (resetTime, windowMs) => {
|
|
34
38
|
let resetSeconds = void 0;
|
|
35
39
|
if (resetTime) {
|
|
@@ -47,8 +51,7 @@ var getPartitionKey = (key) => {
|
|
|
47
51
|
return import_node_buffer.Buffer.from(partitionKey).toString("base64");
|
|
48
52
|
};
|
|
49
53
|
var setLegacyHeaders = (response, info) => {
|
|
50
|
-
if (response.headersSent)
|
|
51
|
-
return;
|
|
54
|
+
if (response.headersSent) return;
|
|
52
55
|
response.setHeader("X-RateLimit-Limit", info.limit.toString());
|
|
53
56
|
response.setHeader("X-RateLimit-Remaining", info.remaining.toString());
|
|
54
57
|
if (info.resetTime instanceof Date) {
|
|
@@ -60,8 +63,7 @@ var setLegacyHeaders = (response, info) => {
|
|
|
60
63
|
}
|
|
61
64
|
};
|
|
62
65
|
var setDraft6Headers = (response, info, windowMs) => {
|
|
63
|
-
if (response.headersSent)
|
|
64
|
-
return;
|
|
66
|
+
if (response.headersSent) return;
|
|
65
67
|
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
66
68
|
const resetSeconds = getResetSeconds(info.resetTime);
|
|
67
69
|
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
|
@@ -71,8 +73,7 @@ var setDraft6Headers = (response, info, windowMs) => {
|
|
|
71
73
|
response.setHeader("RateLimit-Reset", resetSeconds.toString());
|
|
72
74
|
};
|
|
73
75
|
var setDraft7Headers = (response, info, windowMs) => {
|
|
74
|
-
if (response.headersSent)
|
|
75
|
-
return;
|
|
76
|
+
if (response.headersSent) return;
|
|
76
77
|
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
77
78
|
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
78
79
|
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
|
@@ -82,8 +83,7 @@ var setDraft7Headers = (response, info, windowMs) => {
|
|
|
82
83
|
);
|
|
83
84
|
};
|
|
84
85
|
var setDraft8Headers = (response, info, windowMs, name, key) => {
|
|
85
|
-
if (response.headersSent)
|
|
86
|
-
return;
|
|
86
|
+
if (response.headersSent) return;
|
|
87
87
|
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
88
88
|
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
89
89
|
const partitionKey = getPartitionKey(key);
|
|
@@ -93,14 +93,13 @@ var setDraft8Headers = (response, info, windowMs, name, key) => {
|
|
|
93
93
|
response.append("RateLimit", `"${name}"; ${header}`);
|
|
94
94
|
};
|
|
95
95
|
var setRetryAfterHeader = (response, info, windowMs) => {
|
|
96
|
-
if (response.headersSent)
|
|
97
|
-
return;
|
|
96
|
+
if (response.headersSent) return;
|
|
98
97
|
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
99
98
|
response.setHeader("Retry-After", resetSeconds.toString());
|
|
100
99
|
};
|
|
101
100
|
|
|
102
101
|
// source/validations.ts
|
|
103
|
-
var import_node_net = require("net");
|
|
102
|
+
var import_node_net = require("node:net");
|
|
104
103
|
var ValidationError = class extends Error {
|
|
105
104
|
/**
|
|
106
105
|
* The code must be a string, in snake case and all capital, that starts with
|
|
@@ -128,8 +127,7 @@ var validations = {
|
|
|
128
127
|
},
|
|
129
128
|
// Should be EnabledValidations type, but that's a circular reference
|
|
130
129
|
disable() {
|
|
131
|
-
for (const k of Object.keys(this.enabled))
|
|
132
|
-
this.enabled[k] = false;
|
|
130
|
+
for (const k of Object.keys(this.enabled)) this.enabled[k] = false;
|
|
133
131
|
},
|
|
134
132
|
/**
|
|
135
133
|
* Checks whether the IP address is valid, and that it does not have a port
|
|
@@ -302,7 +300,8 @@ var validations = {
|
|
|
302
300
|
* @returns {void}
|
|
303
301
|
*/
|
|
304
302
|
headersDraftVersion(version) {
|
|
305
|
-
if (typeof version !== "string" ||
|
|
303
|
+
if (typeof version !== "string" || // @ts-expect-error This is fine. If version is not in the array, it will just return false.
|
|
304
|
+
!SUPPORTED_DRAFT_VERSIONS.includes(version)) {
|
|
306
305
|
const versionString = SUPPORTED_DRAFT_VERSIONS.join(", ");
|
|
307
306
|
throw new ValidationError(
|
|
308
307
|
"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",
|
|
@@ -400,10 +399,8 @@ var getValidations = (_enabled) => {
|
|
|
400
399
|
args
|
|
401
400
|
);
|
|
402
401
|
} catch (error) {
|
|
403
|
-
if (error instanceof ChangeWarning)
|
|
404
|
-
|
|
405
|
-
else
|
|
406
|
-
console.error(error);
|
|
402
|
+
if (error instanceof ChangeWarning) console.warn(error);
|
|
403
|
+
else console.error(error);
|
|
407
404
|
}
|
|
408
405
|
};
|
|
409
406
|
}
|
|
@@ -438,13 +435,11 @@ var MemoryStore = class {
|
|
|
438
435
|
*/
|
|
439
436
|
init(options) {
|
|
440
437
|
this.windowMs = options.windowMs;
|
|
441
|
-
if (this.interval)
|
|
442
|
-
clearInterval(this.interval);
|
|
438
|
+
if (this.interval) clearInterval(this.interval);
|
|
443
439
|
this.interval = setInterval(() => {
|
|
444
440
|
this.clearExpired();
|
|
445
441
|
}, this.windowMs);
|
|
446
|
-
if (this.interval.unref)
|
|
447
|
-
this.interval.unref();
|
|
442
|
+
if (this.interval.unref) this.interval.unref();
|
|
448
443
|
}
|
|
449
444
|
/**
|
|
450
445
|
* Method to fetch a client's hit count and reset time.
|
|
@@ -485,8 +480,7 @@ var MemoryStore = class {
|
|
|
485
480
|
*/
|
|
486
481
|
async decrement(key) {
|
|
487
482
|
const client = this.getClient(key);
|
|
488
|
-
if (client.totalHits > 0)
|
|
489
|
-
client.totalHits--;
|
|
483
|
+
if (client.totalHits > 0) client.totalHits--;
|
|
490
484
|
}
|
|
491
485
|
/**
|
|
492
486
|
* Method to reset a client's hit counter.
|
|
@@ -544,8 +538,7 @@ var MemoryStore = class {
|
|
|
544
538
|
* @returns {Client} - The requested client.
|
|
545
539
|
*/
|
|
546
540
|
getClient(key) {
|
|
547
|
-
if (this.current.has(key))
|
|
548
|
-
return this.current.get(key);
|
|
541
|
+
if (this.current.has(key)) return this.current.get(key);
|
|
549
542
|
let client;
|
|
550
543
|
if (this.previous.has(key)) {
|
|
551
544
|
client = this.previous.get(key);
|
|
@@ -585,8 +578,7 @@ var promisifyStore = (passedStore) => {
|
|
|
585
578
|
legacyStore.incr(
|
|
586
579
|
key,
|
|
587
580
|
(error, totalHits, resetTime) => {
|
|
588
|
-
if (error)
|
|
589
|
-
reject(error);
|
|
581
|
+
if (error) reject(error);
|
|
590
582
|
resolve({ totalHits, resetTime });
|
|
591
583
|
}
|
|
592
584
|
);
|
|
@@ -633,8 +625,7 @@ var parseOptions = (passedOptions) => {
|
|
|
633
625
|
);
|
|
634
626
|
validations2.onLimitReached(notUndefinedOptions.onLimitReached);
|
|
635
627
|
let standardHeaders = notUndefinedOptions.standardHeaders ?? false;
|
|
636
|
-
if (standardHeaders === true)
|
|
637
|
-
standardHeaders = "draft-6";
|
|
628
|
+
if (standardHeaders === true) standardHeaders = "draft-6";
|
|
638
629
|
const config = {
|
|
639
630
|
windowMs: 60 * 1e3,
|
|
640
631
|
limit: passedOptions.max ?? 5,
|
|
@@ -650,14 +641,10 @@ var parseOptions = (passedOptions) => {
|
|
|
650
641
|
const minutes = config.windowMs / (1e3 * 60);
|
|
651
642
|
const hours = config.windowMs / (1e3 * 60 * 60);
|
|
652
643
|
const days = config.windowMs / (1e3 * 60 * 60 * 24);
|
|
653
|
-
if (seconds < 60)
|
|
654
|
-
|
|
655
|
-
else if (
|
|
656
|
-
|
|
657
|
-
else if (hours < 24)
|
|
658
|
-
duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
|
659
|
-
else
|
|
660
|
-
duration = `${days}day${days > 1 ? "s" : ""}`;
|
|
644
|
+
if (seconds < 60) duration = `${seconds}sec`;
|
|
645
|
+
else if (minutes < 60) duration = `${minutes}min`;
|
|
646
|
+
else if (hours < 24) duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
|
647
|
+
else duration = `${days}day${days > 1 ? "s" : ""}`;
|
|
661
648
|
return `${limit}-in-${duration}`;
|
|
662
649
|
},
|
|
663
650
|
requestPropertyName: "rateLimit",
|
|
@@ -682,12 +669,12 @@ var parseOptions = (passedOptions) => {
|
|
|
682
669
|
}
|
|
683
670
|
},
|
|
684
671
|
passOnStoreError: false,
|
|
685
|
-
// Allow the default options to be
|
|
672
|
+
// Allow the default options to be overridden by the passed options.
|
|
686
673
|
...notUndefinedOptions,
|
|
687
674
|
// `standardHeaders` is resolved into a draft version above, use that.
|
|
688
675
|
standardHeaders,
|
|
689
676
|
// Note that this field is declared after the user's options are spread in,
|
|
690
|
-
// so that this field doesn't get
|
|
677
|
+
// so that this field doesn't get overridden with an un-promisified store!
|
|
691
678
|
store: promisifyStore(notUndefinedOptions.store ?? new MemoryStore()),
|
|
692
679
|
// Print an error to the console if a few known misconfigurations are detected.
|
|
693
680
|
validations: validations2
|
|
@@ -711,8 +698,7 @@ var rateLimit = (passedOptions) => {
|
|
|
711
698
|
const options = getOptionsFromConfig(config);
|
|
712
699
|
config.validations.creationStack(config.store);
|
|
713
700
|
config.validations.unsharedStore(config.store);
|
|
714
|
-
if (typeof config.store.init === "function")
|
|
715
|
-
config.store.init(options);
|
|
701
|
+
if (typeof config.store.init === "function") config.store.init(options);
|
|
716
702
|
const middleware = handleAsyncErrors(
|
|
717
703
|
async (request, response, next) => {
|
|
718
704
|
const skip = await config.skip(request, response);
|
|
@@ -797,8 +783,7 @@ var rateLimit = (passedOptions) => {
|
|
|
797
783
|
await decrementKey();
|
|
798
784
|
});
|
|
799
785
|
response.on("close", async () => {
|
|
800
|
-
if (!response.writableEnded)
|
|
801
|
-
await decrementKey();
|
|
786
|
+
if (!response.writableEnded) await decrementKey();
|
|
802
787
|
});
|
|
803
788
|
response.on("error", async () => {
|
|
804
789
|
await decrementKey();
|
package/dist/index.d.cts
CHANGED
|
@@ -119,7 +119,11 @@ declare const validations: {
|
|
|
119
119
|
creationStack(store: Store): void;
|
|
120
120
|
};
|
|
121
121
|
export type Validations = typeof validations;
|
|
122
|
-
declare const SUPPORTED_DRAFT_VERSIONS:
|
|
122
|
+
declare const SUPPORTED_DRAFT_VERSIONS: readonly [
|
|
123
|
+
"draft-6",
|
|
124
|
+
"draft-7",
|
|
125
|
+
"draft-8"
|
|
126
|
+
];
|
|
123
127
|
/**
|
|
124
128
|
* Callback that fires when a client's hit counter is incremented.
|
|
125
129
|
*
|
package/dist/index.d.mts
CHANGED
|
@@ -119,7 +119,11 @@ declare const validations: {
|
|
|
119
119
|
creationStack(store: Store): void;
|
|
120
120
|
};
|
|
121
121
|
export type Validations = typeof validations;
|
|
122
|
-
declare const SUPPORTED_DRAFT_VERSIONS:
|
|
122
|
+
declare const SUPPORTED_DRAFT_VERSIONS: readonly [
|
|
123
|
+
"draft-6",
|
|
124
|
+
"draft-7",
|
|
125
|
+
"draft-8"
|
|
126
|
+
];
|
|
123
127
|
/**
|
|
124
128
|
* Callback that fires when a client's hit counter is incremented.
|
|
125
129
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -119,7 +119,11 @@ declare const validations: {
|
|
|
119
119
|
creationStack(store: Store): void;
|
|
120
120
|
};
|
|
121
121
|
export type Validations = typeof validations;
|
|
122
|
-
declare const SUPPORTED_DRAFT_VERSIONS:
|
|
122
|
+
declare const SUPPORTED_DRAFT_VERSIONS: readonly [
|
|
123
|
+
"draft-6",
|
|
124
|
+
"draft-7",
|
|
125
|
+
"draft-8"
|
|
126
|
+
];
|
|
123
127
|
/**
|
|
124
128
|
* Callback that fires when a client's hit counter is incremented.
|
|
125
129
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// source/headers.ts
|
|
2
|
-
import { Buffer } from "buffer";
|
|
3
|
-
import { createHash } from "crypto";
|
|
4
|
-
var SUPPORTED_DRAFT_VERSIONS = [
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
var SUPPORTED_DRAFT_VERSIONS = [
|
|
5
|
+
"draft-6",
|
|
6
|
+
"draft-7",
|
|
7
|
+
"draft-8"
|
|
8
|
+
];
|
|
5
9
|
var getResetSeconds = (resetTime, windowMs) => {
|
|
6
10
|
let resetSeconds = void 0;
|
|
7
11
|
if (resetTime) {
|
|
@@ -19,8 +23,7 @@ var getPartitionKey = (key) => {
|
|
|
19
23
|
return Buffer.from(partitionKey).toString("base64");
|
|
20
24
|
};
|
|
21
25
|
var setLegacyHeaders = (response, info) => {
|
|
22
|
-
if (response.headersSent)
|
|
23
|
-
return;
|
|
26
|
+
if (response.headersSent) return;
|
|
24
27
|
response.setHeader("X-RateLimit-Limit", info.limit.toString());
|
|
25
28
|
response.setHeader("X-RateLimit-Remaining", info.remaining.toString());
|
|
26
29
|
if (info.resetTime instanceof Date) {
|
|
@@ -32,8 +35,7 @@ var setLegacyHeaders = (response, info) => {
|
|
|
32
35
|
}
|
|
33
36
|
};
|
|
34
37
|
var setDraft6Headers = (response, info, windowMs) => {
|
|
35
|
-
if (response.headersSent)
|
|
36
|
-
return;
|
|
38
|
+
if (response.headersSent) return;
|
|
37
39
|
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
38
40
|
const resetSeconds = getResetSeconds(info.resetTime);
|
|
39
41
|
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
|
@@ -43,8 +45,7 @@ var setDraft6Headers = (response, info, windowMs) => {
|
|
|
43
45
|
response.setHeader("RateLimit-Reset", resetSeconds.toString());
|
|
44
46
|
};
|
|
45
47
|
var setDraft7Headers = (response, info, windowMs) => {
|
|
46
|
-
if (response.headersSent)
|
|
47
|
-
return;
|
|
48
|
+
if (response.headersSent) return;
|
|
48
49
|
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
49
50
|
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
50
51
|
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
|
@@ -54,8 +55,7 @@ var setDraft7Headers = (response, info, windowMs) => {
|
|
|
54
55
|
);
|
|
55
56
|
};
|
|
56
57
|
var setDraft8Headers = (response, info, windowMs, name, key) => {
|
|
57
|
-
if (response.headersSent)
|
|
58
|
-
return;
|
|
58
|
+
if (response.headersSent) return;
|
|
59
59
|
const windowSeconds = Math.ceil(windowMs / 1e3);
|
|
60
60
|
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
61
61
|
const partitionKey = getPartitionKey(key);
|
|
@@ -65,14 +65,13 @@ var setDraft8Headers = (response, info, windowMs, name, key) => {
|
|
|
65
65
|
response.append("RateLimit", `"${name}"; ${header}`);
|
|
66
66
|
};
|
|
67
67
|
var setRetryAfterHeader = (response, info, windowMs) => {
|
|
68
|
-
if (response.headersSent)
|
|
69
|
-
return;
|
|
68
|
+
if (response.headersSent) return;
|
|
70
69
|
const resetSeconds = getResetSeconds(info.resetTime, windowMs);
|
|
71
70
|
response.setHeader("Retry-After", resetSeconds.toString());
|
|
72
71
|
};
|
|
73
72
|
|
|
74
73
|
// source/validations.ts
|
|
75
|
-
import { isIP } from "net";
|
|
74
|
+
import { isIP } from "node:net";
|
|
76
75
|
var ValidationError = class extends Error {
|
|
77
76
|
/**
|
|
78
77
|
* The code must be a string, in snake case and all capital, that starts with
|
|
@@ -100,8 +99,7 @@ var validations = {
|
|
|
100
99
|
},
|
|
101
100
|
// Should be EnabledValidations type, but that's a circular reference
|
|
102
101
|
disable() {
|
|
103
|
-
for (const k of Object.keys(this.enabled))
|
|
104
|
-
this.enabled[k] = false;
|
|
102
|
+
for (const k of Object.keys(this.enabled)) this.enabled[k] = false;
|
|
105
103
|
},
|
|
106
104
|
/**
|
|
107
105
|
* Checks whether the IP address is valid, and that it does not have a port
|
|
@@ -274,7 +272,8 @@ var validations = {
|
|
|
274
272
|
* @returns {void}
|
|
275
273
|
*/
|
|
276
274
|
headersDraftVersion(version) {
|
|
277
|
-
if (typeof version !== "string" ||
|
|
275
|
+
if (typeof version !== "string" || // @ts-expect-error This is fine. If version is not in the array, it will just return false.
|
|
276
|
+
!SUPPORTED_DRAFT_VERSIONS.includes(version)) {
|
|
278
277
|
const versionString = SUPPORTED_DRAFT_VERSIONS.join(", ");
|
|
279
278
|
throw new ValidationError(
|
|
280
279
|
"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",
|
|
@@ -372,10 +371,8 @@ var getValidations = (_enabled) => {
|
|
|
372
371
|
args
|
|
373
372
|
);
|
|
374
373
|
} catch (error) {
|
|
375
|
-
if (error instanceof ChangeWarning)
|
|
376
|
-
|
|
377
|
-
else
|
|
378
|
-
console.error(error);
|
|
374
|
+
if (error instanceof ChangeWarning) console.warn(error);
|
|
375
|
+
else console.error(error);
|
|
379
376
|
}
|
|
380
377
|
};
|
|
381
378
|
}
|
|
@@ -410,13 +407,11 @@ var MemoryStore = class {
|
|
|
410
407
|
*/
|
|
411
408
|
init(options) {
|
|
412
409
|
this.windowMs = options.windowMs;
|
|
413
|
-
if (this.interval)
|
|
414
|
-
clearInterval(this.interval);
|
|
410
|
+
if (this.interval) clearInterval(this.interval);
|
|
415
411
|
this.interval = setInterval(() => {
|
|
416
412
|
this.clearExpired();
|
|
417
413
|
}, this.windowMs);
|
|
418
|
-
if (this.interval.unref)
|
|
419
|
-
this.interval.unref();
|
|
414
|
+
if (this.interval.unref) this.interval.unref();
|
|
420
415
|
}
|
|
421
416
|
/**
|
|
422
417
|
* Method to fetch a client's hit count and reset time.
|
|
@@ -457,8 +452,7 @@ var MemoryStore = class {
|
|
|
457
452
|
*/
|
|
458
453
|
async decrement(key) {
|
|
459
454
|
const client = this.getClient(key);
|
|
460
|
-
if (client.totalHits > 0)
|
|
461
|
-
client.totalHits--;
|
|
455
|
+
if (client.totalHits > 0) client.totalHits--;
|
|
462
456
|
}
|
|
463
457
|
/**
|
|
464
458
|
* Method to reset a client's hit counter.
|
|
@@ -516,8 +510,7 @@ var MemoryStore = class {
|
|
|
516
510
|
* @returns {Client} - The requested client.
|
|
517
511
|
*/
|
|
518
512
|
getClient(key) {
|
|
519
|
-
if (this.current.has(key))
|
|
520
|
-
return this.current.get(key);
|
|
513
|
+
if (this.current.has(key)) return this.current.get(key);
|
|
521
514
|
let client;
|
|
522
515
|
if (this.previous.has(key)) {
|
|
523
516
|
client = this.previous.get(key);
|
|
@@ -557,8 +550,7 @@ var promisifyStore = (passedStore) => {
|
|
|
557
550
|
legacyStore.incr(
|
|
558
551
|
key,
|
|
559
552
|
(error, totalHits, resetTime) => {
|
|
560
|
-
if (error)
|
|
561
|
-
reject(error);
|
|
553
|
+
if (error) reject(error);
|
|
562
554
|
resolve({ totalHits, resetTime });
|
|
563
555
|
}
|
|
564
556
|
);
|
|
@@ -605,8 +597,7 @@ var parseOptions = (passedOptions) => {
|
|
|
605
597
|
);
|
|
606
598
|
validations2.onLimitReached(notUndefinedOptions.onLimitReached);
|
|
607
599
|
let standardHeaders = notUndefinedOptions.standardHeaders ?? false;
|
|
608
|
-
if (standardHeaders === true)
|
|
609
|
-
standardHeaders = "draft-6";
|
|
600
|
+
if (standardHeaders === true) standardHeaders = "draft-6";
|
|
610
601
|
const config = {
|
|
611
602
|
windowMs: 60 * 1e3,
|
|
612
603
|
limit: passedOptions.max ?? 5,
|
|
@@ -622,14 +613,10 @@ var parseOptions = (passedOptions) => {
|
|
|
622
613
|
const minutes = config.windowMs / (1e3 * 60);
|
|
623
614
|
const hours = config.windowMs / (1e3 * 60 * 60);
|
|
624
615
|
const days = config.windowMs / (1e3 * 60 * 60 * 24);
|
|
625
|
-
if (seconds < 60)
|
|
626
|
-
|
|
627
|
-
else if (
|
|
628
|
-
|
|
629
|
-
else if (hours < 24)
|
|
630
|
-
duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
|
631
|
-
else
|
|
632
|
-
duration = `${days}day${days > 1 ? "s" : ""}`;
|
|
616
|
+
if (seconds < 60) duration = `${seconds}sec`;
|
|
617
|
+
else if (minutes < 60) duration = `${minutes}min`;
|
|
618
|
+
else if (hours < 24) duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
|
619
|
+
else duration = `${days}day${days > 1 ? "s" : ""}`;
|
|
633
620
|
return `${limit}-in-${duration}`;
|
|
634
621
|
},
|
|
635
622
|
requestPropertyName: "rateLimit",
|
|
@@ -654,12 +641,12 @@ var parseOptions = (passedOptions) => {
|
|
|
654
641
|
}
|
|
655
642
|
},
|
|
656
643
|
passOnStoreError: false,
|
|
657
|
-
// Allow the default options to be
|
|
644
|
+
// Allow the default options to be overridden by the passed options.
|
|
658
645
|
...notUndefinedOptions,
|
|
659
646
|
// `standardHeaders` is resolved into a draft version above, use that.
|
|
660
647
|
standardHeaders,
|
|
661
648
|
// Note that this field is declared after the user's options are spread in,
|
|
662
|
-
// so that this field doesn't get
|
|
649
|
+
// so that this field doesn't get overridden with an un-promisified store!
|
|
663
650
|
store: promisifyStore(notUndefinedOptions.store ?? new MemoryStore()),
|
|
664
651
|
// Print an error to the console if a few known misconfigurations are detected.
|
|
665
652
|
validations: validations2
|
|
@@ -683,8 +670,7 @@ var rateLimit = (passedOptions) => {
|
|
|
683
670
|
const options = getOptionsFromConfig(config);
|
|
684
671
|
config.validations.creationStack(config.store);
|
|
685
672
|
config.validations.unsharedStore(config.store);
|
|
686
|
-
if (typeof config.store.init === "function")
|
|
687
|
-
config.store.init(options);
|
|
673
|
+
if (typeof config.store.init === "function") config.store.init(options);
|
|
688
674
|
const middleware = handleAsyncErrors(
|
|
689
675
|
async (request, response, next) => {
|
|
690
676
|
const skip = await config.skip(request, response);
|
|
@@ -769,8 +755,7 @@ var rateLimit = (passedOptions) => {
|
|
|
769
755
|
await decrementKey();
|
|
770
756
|
});
|
|
771
757
|
response.on("close", async () => {
|
|
772
|
-
if (!response.writableEnded)
|
|
773
|
-
await decrementKey();
|
|
758
|
+
if (!response.writableEnded) await decrementKey();
|
|
774
759
|
});
|
|
775
760
|
response.on("error", async () => {
|
|
776
761
|
await decrementKey();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "7.5.
|
|
3
|
+
"version": "7.5.1",
|
|
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": "
|
|
77
|
+
"express": ">= 4.11"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@express-rate-limit/prettier": "1.1.1",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"@types/supertest": "2.0.15",
|
|
87
87
|
"del-cli": "5.1.0",
|
|
88
88
|
"dts-bundle-generator": "8.0.1",
|
|
89
|
-
"esbuild": "0.
|
|
89
|
+
"esbuild": "0.25.0",
|
|
90
90
|
"express": "4.21.1",
|
|
91
91
|
"husky": "8.0.3",
|
|
92
92
|
"jest": "29.7.0",
|