express-rate-limit 5.1.1 → 5.1.3
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/lib/express-rate-limit.js +12 -12
- package/lib/memory-store.js +4 -5
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -115,7 +115,7 @@ Defaults to `5`. Set to `0` to disable.
|
|
|
115
115
|
|
|
116
116
|
### windowMs
|
|
117
117
|
|
|
118
|
-
Timeframe for which requests are checked/
|
|
118
|
+
Timeframe for which requests are checked/remembered. Also used in the Retry-After header when the limit is reached.
|
|
119
119
|
|
|
120
120
|
Note: with non-default stores, you may need to configure this value twice, once here and once on the store. In some cases the units also differ (e.g. seconds vs miliseconds)
|
|
121
121
|
|
|
@@ -13,16 +13,16 @@ function RateLimit(options) {
|
|
|
13
13
|
skipFailedRequests: false, // Do not count failed requests (status >= 400)
|
|
14
14
|
skipSuccessfulRequests: false, // Do not count successful requests (status < 400)
|
|
15
15
|
// allows to create custom keys (by default user IP is used)
|
|
16
|
-
keyGenerator: function(req /*, res*/) {
|
|
16
|
+
keyGenerator: function (req /*, res*/) {
|
|
17
17
|
return req.ip;
|
|
18
18
|
},
|
|
19
|
-
skip: function(/*req, res*/) {
|
|
19
|
+
skip: function (/*req, res*/) {
|
|
20
20
|
return false;
|
|
21
21
|
},
|
|
22
|
-
handler: function(req, res /*, next*/) {
|
|
22
|
+
handler: function (req, res /*, next*/) {
|
|
23
23
|
res.status(options.statusCode).send(options.message);
|
|
24
24
|
},
|
|
25
|
-
onLimitReached: function(/*req, res, optionsUsed*/) {}
|
|
25
|
+
onLimitReached: function (/*req, res, optionsUsed*/) {},
|
|
26
26
|
},
|
|
27
27
|
options
|
|
28
28
|
);
|
|
@@ -40,7 +40,7 @@ function RateLimit(options) {
|
|
|
40
40
|
throw new Error("The store is not valid.");
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
["global", "delayMs", "delayAfter"].forEach(key => {
|
|
43
|
+
["global", "delayMs", "delayAfter"].forEach((key) => {
|
|
44
44
|
// note: this doesn't trigger if delayMs or delayAfter are set to 0, because that essentially disables them
|
|
45
45
|
if (options[key]) {
|
|
46
46
|
throw new Error(
|
|
@@ -56,7 +56,7 @@ function RateLimit(options) {
|
|
|
56
56
|
|
|
57
57
|
const key = options.keyGenerator(req, res);
|
|
58
58
|
|
|
59
|
-
options.store.incr(key, function(err, current, resetTime) {
|
|
59
|
+
options.store.incr(key, function (err, current, resetTime) {
|
|
60
60
|
if (err) {
|
|
61
61
|
return next(err);
|
|
62
62
|
}
|
|
@@ -65,13 +65,12 @@ function RateLimit(options) {
|
|
|
65
65
|
typeof options.max === "function" ? options.max(req, res) : options.max;
|
|
66
66
|
|
|
67
67
|
Promise.resolve(maxResult)
|
|
68
|
-
.
|
|
69
|
-
.then(max => {
|
|
68
|
+
.then((max) => {
|
|
70
69
|
req.rateLimit = {
|
|
71
70
|
limit: max,
|
|
72
71
|
current: current,
|
|
73
72
|
remaining: Math.max(max - current, 0),
|
|
74
|
-
resetTime: resetTime
|
|
73
|
+
resetTime: resetTime,
|
|
75
74
|
};
|
|
76
75
|
|
|
77
76
|
if (options.headers && !res.headersSent) {
|
|
@@ -107,7 +106,7 @@ function RateLimit(options) {
|
|
|
107
106
|
};
|
|
108
107
|
|
|
109
108
|
if (options.skipFailedRequests) {
|
|
110
|
-
res.on("finish", function() {
|
|
109
|
+
res.on("finish", function () {
|
|
111
110
|
if (res.statusCode >= 400) {
|
|
112
111
|
decrementKey();
|
|
113
112
|
}
|
|
@@ -123,7 +122,7 @@ function RateLimit(options) {
|
|
|
123
122
|
}
|
|
124
123
|
|
|
125
124
|
if (options.skipSuccessfulRequests) {
|
|
126
|
-
res.on("finish", function() {
|
|
125
|
+
res.on("finish", function () {
|
|
127
126
|
if (res.statusCode < 400) {
|
|
128
127
|
options.store.decrement(key);
|
|
129
128
|
}
|
|
@@ -143,7 +142,8 @@ function RateLimit(options) {
|
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
next();
|
|
146
|
-
})
|
|
145
|
+
})
|
|
146
|
+
.catch(next);
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
|
package/lib/memory-store.js
CHANGED
|
@@ -10,7 +10,7 @@ function MemoryStore(windowMs) {
|
|
|
10
10
|
let hits = {};
|
|
11
11
|
let resetTime = calculateNextResetTime(windowMs);
|
|
12
12
|
|
|
13
|
-
this.incr = function(key, cb) {
|
|
13
|
+
this.incr = function (key, cb) {
|
|
14
14
|
if (hits[key]) {
|
|
15
15
|
hits[key]++;
|
|
16
16
|
} else {
|
|
@@ -20,22 +20,21 @@ function MemoryStore(windowMs) {
|
|
|
20
20
|
cb(null, hits[key], resetTime);
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
this.decrement = function(key) {
|
|
23
|
+
this.decrement = function (key) {
|
|
24
24
|
if (hits[key]) {
|
|
25
25
|
hits[key]--;
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
// export an API to allow hits all IPs to be reset
|
|
30
|
-
this.resetAll = function() {
|
|
30
|
+
this.resetAll = function () {
|
|
31
31
|
hits = {};
|
|
32
32
|
resetTime = calculateNextResetTime(windowMs);
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
// export an API to allow hits from one IP to be reset
|
|
36
|
-
this.resetKey = function(key) {
|
|
36
|
+
this.resetKey = function (key) {
|
|
37
37
|
delete hits[key];
|
|
38
|
-
delete resetTime[key];
|
|
39
38
|
};
|
|
40
39
|
|
|
41
40
|
// simply reset ALL hits every windowMs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.3",
|
|
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
|
"homepage": "https://github.com/nfriedly/express-rate-limit",
|
|
6
6
|
"author": {
|
|
@@ -34,17 +34,19 @@
|
|
|
34
34
|
"dependencies": {},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"eslint": "^6.8.0",
|
|
37
|
-
"eslint-config-prettier": "^6.10.
|
|
37
|
+
"eslint-config-prettier": "^6.10.1",
|
|
38
38
|
"eslint-plugin-prettier": "^3.1.2",
|
|
39
39
|
"express": "^4.17.1",
|
|
40
40
|
"husky": "^4.2.3",
|
|
41
|
-
"mocha": "^7.
|
|
42
|
-
"prettier": "^
|
|
41
|
+
"mocha": "^7.1.1",
|
|
42
|
+
"prettier": "^2.0.4",
|
|
43
43
|
"pretty-quick": "^2.0.1",
|
|
44
44
|
"supertest": "^4.0.2"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
|
-
"
|
|
47
|
+
"lint": "eslint .",
|
|
48
|
+
"autofix": "npm run lint -- --fix",
|
|
49
|
+
"test": "npm run lint && mocha",
|
|
48
50
|
"precommit": "pretty-quick --staged"
|
|
49
51
|
}
|
|
50
52
|
}
|