express-rate-limit 5.2.2 → 5.3.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 +17 -6
- package/lib/express-rate-limit.js +13 -5
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Express Rate Limit
|
|
2
2
|
|
|
3
|
-
[](https://david-dm.org/nfriedly/express-rate-limit)
|
|
3
|
+
[](https://github.com/nfriedly/express-rate-limit/actions)
|
|
4
|
+
[](https://npmjs.org/package/express-rate-limit "View this project on NPM")
|
|
6
5
|
[](https://www.npmjs.com/package/express-rate-limit)
|
|
7
6
|
|
|
8
7
|
|
|
@@ -10,12 +9,11 @@ Basic rate-limiting middleware for Express. Use to limit repeated requests to pu
|
|
|
10
9
|
|
|
11
10
|
Plays nice with [express-slow-down](https://www.npmjs.com/package/express-slow-down).
|
|
12
11
|
|
|
13
|
-
Note: this module does not share state with other processes/servers by default.
|
|
14
|
-
If you need a more robust solution, I recommend using an external store:
|
|
12
|
+
Note: this module does not share state with other processes/servers by default. It also buckets all requests to an internal clock rather than starting a new timer for each end-user. It's fine for abuse-prevention but might not produce the desired effect when attempting to strictly enforce API rate-limits or similar. If you need a more robust solution, I recommend using an external store:
|
|
15
13
|
|
|
16
14
|
### Stores
|
|
17
15
|
|
|
18
|
-
- Memory Store _(default, built-in)_ - stores hits in-memory in the Node.js process. Does not share state with other servers or processes.
|
|
16
|
+
- Memory Store _(default, built-in)_ - stores hits in-memory in the Node.js process. Does not share state with other servers or processes, and does not start a separate timer for each end user.
|
|
19
17
|
- [Redis Store](https://npmjs.com/package/rate-limit-redis)
|
|
20
18
|
- [Memcached Store](https://npmjs.org/package/rate-limit-memcached)
|
|
21
19
|
- [Mongo Store](https://www.npmjs.com/package/rate-limit-mongo)
|
|
@@ -188,6 +186,19 @@ function (req, res, options) {
|
|
|
188
186
|
}
|
|
189
187
|
```
|
|
190
188
|
|
|
189
|
+
### requestWasSuccessful
|
|
190
|
+
|
|
191
|
+
Function that is called when `skipFailedRequests` and/or `skipSuccessfulRequests` are set to `true`.
|
|
192
|
+
May be overridden if, for example, a service sends out a 200 status code on errors.
|
|
193
|
+
|
|
194
|
+
Defaults to
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
function (req, res) {
|
|
198
|
+
return res.statusCode < 400;
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
191
202
|
### skipFailedRequests
|
|
192
203
|
|
|
193
204
|
When set to `true`, failed requests won't be counted. Request considered failed when:
|
|
@@ -10,8 +10,12 @@ function RateLimit(options) {
|
|
|
10
10
|
statusCode: 429, // 429 status = Too Many Requests (RFC 6585)
|
|
11
11
|
headers: true, //Send custom rate limit header with limit and remaining
|
|
12
12
|
draft_polli_ratelimit_headers: false, //Support for the new RateLimit standardization headers
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
// ability to manually decide if request was successful. Used when `skipSuccessfulRequests` and/or `skipFailedRequests` are set to `true`
|
|
14
|
+
requestWasSuccessful: function (req, res) {
|
|
15
|
+
return res.statusCode < 400;
|
|
16
|
+
},
|
|
17
|
+
skipFailedRequests: false, // Do not count failed requests
|
|
18
|
+
skipSuccessfulRequests: false, // Do not count successful requests
|
|
15
19
|
// allows to create custom keys (by default user IP is used)
|
|
16
20
|
keyGenerator: function (req /*, res*/) {
|
|
17
21
|
return req.ip;
|
|
@@ -82,7 +86,7 @@ function RateLimit(options) {
|
|
|
82
86
|
res.setHeader("X-RateLimit-Remaining", req.rateLimit.remaining);
|
|
83
87
|
if (resetTime instanceof Date) {
|
|
84
88
|
// if we have a resetTime, also provide the current date to help avoid issues with incorrect clocks
|
|
85
|
-
res.setHeader("Date", new Date().
|
|
89
|
+
res.setHeader("Date", new Date().toUTCString());
|
|
86
90
|
res.setHeader(
|
|
87
91
|
"X-RateLimit-Reset",
|
|
88
92
|
Math.ceil(resetTime.getTime() / 1000)
|
|
@@ -114,7 +118,7 @@ function RateLimit(options) {
|
|
|
114
118
|
|
|
115
119
|
if (options.skipFailedRequests) {
|
|
116
120
|
res.on("finish", function () {
|
|
117
|
-
if (
|
|
121
|
+
if (!options.requestWasSuccessful(req, res)) {
|
|
118
122
|
decrementKey();
|
|
119
123
|
}
|
|
120
124
|
});
|
|
@@ -130,7 +134,7 @@ function RateLimit(options) {
|
|
|
130
134
|
|
|
131
135
|
if (options.skipSuccessfulRequests) {
|
|
132
136
|
res.on("finish", function () {
|
|
133
|
-
if (
|
|
137
|
+
if (options.requestWasSuccessful(req, res)) {
|
|
134
138
|
options.store.decrement(key);
|
|
135
139
|
}
|
|
136
140
|
});
|
|
@@ -152,9 +156,13 @@ function RateLimit(options) {
|
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
next();
|
|
159
|
+
|
|
160
|
+
return null;
|
|
155
161
|
})
|
|
156
162
|
.catch(next);
|
|
157
163
|
});
|
|
164
|
+
|
|
165
|
+
return null;
|
|
158
166
|
})
|
|
159
167
|
.catch(next);
|
|
160
168
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.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
|
"homepage": "https://github.com/nfriedly/express-rate-limit",
|
|
6
6
|
"author": {
|
|
@@ -31,17 +31,18 @@
|
|
|
31
31
|
"brute-force",
|
|
32
32
|
"attack"
|
|
33
33
|
],
|
|
34
|
-
"dependencies": {},
|
|
35
34
|
"devDependencies": {
|
|
36
|
-
"
|
|
37
|
-
"eslint
|
|
38
|
-
"eslint-
|
|
35
|
+
"bluebird": "^3.7.2",
|
|
36
|
+
"eslint": "^7.19.0",
|
|
37
|
+
"eslint-config-prettier": "^7.2.0",
|
|
38
|
+
"eslint-plugin-prettier": "^3.3.1",
|
|
39
39
|
"express": "^4.17.1",
|
|
40
|
-
"husky": "^4.
|
|
41
|
-
"mocha": "^
|
|
42
|
-
"prettier": "^2.
|
|
43
|
-
"pretty-quick": "^
|
|
44
|
-
"
|
|
40
|
+
"husky": "^4.3.8",
|
|
41
|
+
"mocha": "^8.2.1",
|
|
42
|
+
"prettier": "^2.2.1",
|
|
43
|
+
"pretty-quick": "^3.1.0",
|
|
44
|
+
"sinon": "^9.2.4",
|
|
45
|
+
"supertest": "^6.1.3"
|
|
45
46
|
},
|
|
46
47
|
"scripts": {
|
|
47
48
|
"lint": "eslint .",
|