express-rate-limit 6.4.0 → 6.6.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/changelog.md +8 -0
- package/dist/index.cjs +14 -8
- package/dist/index.d.ts +18 -3
- package/dist/index.mjs +13 -8
- package/package.json +16 -15
- package/readme.md +23 -3
package/changelog.md
CHANGED
|
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to
|
|
7
7
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [6.5.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.5.0)
|
|
10
|
+
|
|
11
|
+
## Changed
|
|
12
|
+
|
|
13
|
+
- The message option can now be a (sync/asynx) function that returns a value
|
|
14
|
+
(#311)
|
|
15
|
+
- Updated all dependencies
|
|
16
|
+
|
|
9
17
|
## [6.4.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.3.0)
|
|
10
18
|
|
|
11
19
|
### Added
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -36,12 +37,11 @@ var MemoryStore = class {
|
|
|
36
37
|
this.windowMs = options.windowMs;
|
|
37
38
|
this.resetTime = calculateNextResetTime(this.windowMs);
|
|
38
39
|
this.hits = {};
|
|
39
|
-
|
|
40
|
+
this.interval = setInterval(async () => {
|
|
40
41
|
await this.resetAll();
|
|
41
42
|
}, this.windowMs);
|
|
42
|
-
if (interval.unref)
|
|
43
|
-
interval.unref();
|
|
44
|
-
}
|
|
43
|
+
if (this.interval.unref)
|
|
44
|
+
this.interval.unref();
|
|
45
45
|
}
|
|
46
46
|
async increment(key) {
|
|
47
47
|
var _a;
|
|
@@ -54,9 +54,8 @@ var MemoryStore = class {
|
|
|
54
54
|
}
|
|
55
55
|
async decrement(key) {
|
|
56
56
|
const current = this.hits[key];
|
|
57
|
-
if (current)
|
|
57
|
+
if (current)
|
|
58
58
|
this.hits[key] = current - 1;
|
|
59
|
-
}
|
|
60
59
|
}
|
|
61
60
|
async resetKey(key) {
|
|
62
61
|
delete this.hits[key];
|
|
@@ -65,6 +64,9 @@ var MemoryStore = class {
|
|
|
65
64
|
this.hits = {};
|
|
66
65
|
this.resetTime = calculateNextResetTime(this.windowMs);
|
|
67
66
|
}
|
|
67
|
+
shutdown() {
|
|
68
|
+
clearInterval(this.interval);
|
|
69
|
+
}
|
|
68
70
|
};
|
|
69
71
|
|
|
70
72
|
// source/lib.ts
|
|
@@ -118,8 +120,12 @@ var parseOptions = (passedOptions) => {
|
|
|
118
120
|
}
|
|
119
121
|
return request.ip;
|
|
120
122
|
},
|
|
121
|
-
handler(
|
|
122
|
-
response.status(config.statusCode)
|
|
123
|
+
async handler(request, response, _next, _optionsUsed) {
|
|
124
|
+
response.status(config.statusCode);
|
|
125
|
+
const message = typeof config.message === "function" ? await config.message(request, response) : config.message;
|
|
126
|
+
if (!response.writableEnded) {
|
|
127
|
+
response.send(message != null ? message : "Too many requests, please try again later.");
|
|
128
|
+
}
|
|
123
129
|
},
|
|
124
130
|
onLimitReached(_request, _response, _optionsUsed) {
|
|
125
131
|
},
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated by dts-bundle-generator v6.
|
|
1
|
+
// Generated by dts-bundle-generator v6.12.0
|
|
2
2
|
|
|
3
3
|
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
|
4
4
|
|
|
@@ -126,6 +126,10 @@ export interface Store {
|
|
|
126
126
|
* Method to reset everyone's hit counter.
|
|
127
127
|
*/
|
|
128
128
|
resetAll?: () => Promise<void> | void;
|
|
129
|
+
/**
|
|
130
|
+
* Method to shutdown the store, stop timers, and release all resources.
|
|
131
|
+
*/
|
|
132
|
+
shutdown?: () => Promise<void> | void;
|
|
129
133
|
}
|
|
130
134
|
/**
|
|
131
135
|
* The configuration options for the rate limiter.
|
|
@@ -152,7 +156,7 @@ export interface Options {
|
|
|
152
156
|
*
|
|
153
157
|
* Defaults to `'Too many requests, please try again later.'`
|
|
154
158
|
*/
|
|
155
|
-
readonly message: any
|
|
159
|
+
readonly message: any | ValueDeterminingMiddleware<any>;
|
|
156
160
|
/**
|
|
157
161
|
* The HTTP status code to send back when a client is rate limited.
|
|
158
162
|
*
|
|
@@ -276,7 +280,7 @@ export interface RateLimitInfo {
|
|
|
276
280
|
*
|
|
277
281
|
* @public
|
|
278
282
|
*/
|
|
279
|
-
export declare const rateLimit: (passedOptions?: Partial<Options>
|
|
283
|
+
export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
|
|
280
284
|
/**
|
|
281
285
|
* A `Store` that stores the hit count for each client in memory.
|
|
282
286
|
*
|
|
@@ -297,6 +301,10 @@ export declare class MemoryStore implements Store {
|
|
|
297
301
|
* The time at which all hit counts will be reset.
|
|
298
302
|
*/
|
|
299
303
|
resetTime: Date;
|
|
304
|
+
/**
|
|
305
|
+
* Reference to the active timer.
|
|
306
|
+
*/
|
|
307
|
+
interval?: NodeJS.Timer;
|
|
300
308
|
/**
|
|
301
309
|
* Method that initializes the store.
|
|
302
310
|
*
|
|
@@ -335,6 +343,13 @@ export declare class MemoryStore implements Store {
|
|
|
335
343
|
* @public
|
|
336
344
|
*/
|
|
337
345
|
resetAll(): Promise<void>;
|
|
346
|
+
/**
|
|
347
|
+
* Method to stop the timer (if currently running) and prevent any memory
|
|
348
|
+
* leaks.
|
|
349
|
+
*
|
|
350
|
+
* @public
|
|
351
|
+
*/
|
|
352
|
+
shutdown(): void;
|
|
338
353
|
}
|
|
339
354
|
|
|
340
355
|
export {
|
package/dist/index.mjs
CHANGED
|
@@ -9,12 +9,11 @@ var MemoryStore = class {
|
|
|
9
9
|
this.windowMs = options.windowMs;
|
|
10
10
|
this.resetTime = calculateNextResetTime(this.windowMs);
|
|
11
11
|
this.hits = {};
|
|
12
|
-
|
|
12
|
+
this.interval = setInterval(async () => {
|
|
13
13
|
await this.resetAll();
|
|
14
14
|
}, this.windowMs);
|
|
15
|
-
if (interval.unref)
|
|
16
|
-
interval.unref();
|
|
17
|
-
}
|
|
15
|
+
if (this.interval.unref)
|
|
16
|
+
this.interval.unref();
|
|
18
17
|
}
|
|
19
18
|
async increment(key) {
|
|
20
19
|
var _a;
|
|
@@ -27,9 +26,8 @@ var MemoryStore = class {
|
|
|
27
26
|
}
|
|
28
27
|
async decrement(key) {
|
|
29
28
|
const current = this.hits[key];
|
|
30
|
-
if (current)
|
|
29
|
+
if (current)
|
|
31
30
|
this.hits[key] = current - 1;
|
|
32
|
-
}
|
|
33
31
|
}
|
|
34
32
|
async resetKey(key) {
|
|
35
33
|
delete this.hits[key];
|
|
@@ -38,6 +36,9 @@ var MemoryStore = class {
|
|
|
38
36
|
this.hits = {};
|
|
39
37
|
this.resetTime = calculateNextResetTime(this.windowMs);
|
|
40
38
|
}
|
|
39
|
+
shutdown() {
|
|
40
|
+
clearInterval(this.interval);
|
|
41
|
+
}
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
// source/lib.ts
|
|
@@ -91,8 +92,12 @@ var parseOptions = (passedOptions) => {
|
|
|
91
92
|
}
|
|
92
93
|
return request.ip;
|
|
93
94
|
},
|
|
94
|
-
handler(
|
|
95
|
-
response.status(config.statusCode)
|
|
95
|
+
async handler(request, response, _next, _optionsUsed) {
|
|
96
|
+
response.status(config.statusCode);
|
|
97
|
+
const message = typeof config.message === "function" ? await config.message(request, response) : config.message;
|
|
98
|
+
if (!response.writableEnded) {
|
|
99
|
+
response.send(message != null ? message : "Too many requests, please try again later.");
|
|
100
|
+
}
|
|
96
101
|
},
|
|
97
102
|
onLimitReached(_request, _response, _optionsUsed) {
|
|
98
103
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.6.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",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"type": "module",
|
|
31
31
|
"exports": {
|
|
32
32
|
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
33
34
|
"import": "./dist/index.mjs",
|
|
34
35
|
"require": "./dist/index.cjs"
|
|
35
36
|
}
|
|
@@ -70,25 +71,25 @@
|
|
|
70
71
|
"express": "^4 || ^5"
|
|
71
72
|
},
|
|
72
73
|
"devDependencies": {
|
|
73
|
-
"@jest/globals": "
|
|
74
|
+
"@jest/globals": "28.1.3",
|
|
74
75
|
"@types/express": "4.17.13",
|
|
75
|
-
"@types/jest": "
|
|
76
|
-
"@types/node": "
|
|
76
|
+
"@types/jest": "28.1.6",
|
|
77
|
+
"@types/node": "18.0.6",
|
|
77
78
|
"@types/supertest": "2.0.12",
|
|
78
79
|
"cross-env": "7.0.3",
|
|
79
80
|
"del-cli": "4.0.1",
|
|
80
|
-
"dts-bundle-generator": "6.
|
|
81
|
-
"esbuild": "0.14.
|
|
82
|
-
"express": "4.
|
|
83
|
-
"husky": "
|
|
84
|
-
"jest": "
|
|
85
|
-
"lint-staged": "
|
|
81
|
+
"dts-bundle-generator": "6.12.0",
|
|
82
|
+
"esbuild": "0.14.49",
|
|
83
|
+
"express": "4.18.1",
|
|
84
|
+
"husky": "8.0.1",
|
|
85
|
+
"jest": "28.1.3",
|
|
86
|
+
"lint-staged": "13.0.3",
|
|
86
87
|
"npm-run-all": "4.1.5",
|
|
87
|
-
"supertest": "6.2.
|
|
88
|
-
"ts-jest": "
|
|
89
|
-
"ts-node": "10.
|
|
90
|
-
"typescript": "4.
|
|
91
|
-
"xo": "0.
|
|
88
|
+
"supertest": "6.2.4",
|
|
89
|
+
"ts-jest": "28.0.7",
|
|
90
|
+
"ts-node": "10.9.1",
|
|
91
|
+
"typescript": "4.7.4",
|
|
92
|
+
"xo": "0.49.0"
|
|
92
93
|
},
|
|
93
94
|
"xo": {
|
|
94
95
|
"prettier": true,
|
package/readme.md
CHANGED
|
@@ -239,11 +239,30 @@ const limiter = rateLimit({
|
|
|
239
239
|
The response body to send back when a client is rate limited.
|
|
240
240
|
|
|
241
241
|
May be a `string`, JSON object, or any other value that Express's
|
|
242
|
-
[response.send](https://expressjs.com/en/4x/api.html#
|
|
243
|
-
supports.
|
|
242
|
+
[`response.send`](https://expressjs.com/en/4x/api.html#res.send) method
|
|
243
|
+
supports. It can also be a (sync/async) function that accepts the Express
|
|
244
|
+
request and response objects and then returns a `string`, JSON object or any
|
|
245
|
+
other value the Express `response.send` function accepts.
|
|
244
246
|
|
|
245
247
|
Defaults to `'Too many requests, please try again later.'`
|
|
246
248
|
|
|
249
|
+
An example of using a function:
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
const isPremium = async (user) => {
|
|
253
|
+
// ...
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const limiter = rateLimit({
|
|
257
|
+
// ...
|
|
258
|
+
message: async (request, response) => {
|
|
259
|
+
if (await isPremium(request.user))
|
|
260
|
+
return 'You can only make 10 requests every hour.'
|
|
261
|
+
else return 'You can only make 5 requests every hour.'
|
|
262
|
+
},
|
|
263
|
+
})
|
|
264
|
+
```
|
|
265
|
+
|
|
247
266
|
### `statusCode`
|
|
248
267
|
|
|
249
268
|
> `number`
|
|
@@ -348,7 +367,8 @@ const limiter = rateLimit({
|
|
|
348
367
|
Express request handler that sends back a response when a client is
|
|
349
368
|
rate-limited.
|
|
350
369
|
|
|
351
|
-
By default, sends back the `statusCode` and `message` set via the options
|
|
370
|
+
By default, sends back the `statusCode` and `message` set via the `options`,
|
|
371
|
+
similar to this:
|
|
352
372
|
|
|
353
373
|
```ts
|
|
354
374
|
const limiter = rateLimit({
|