express-rate-limit 6.0.2 → 6.1.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 +39 -0
- package/dist/index.cjs +3 -5
- package/dist/index.d.ts +29 -16
- package/dist/index.mjs +2 -4
- package/package.json +17 -17
- package/readme.md +44 -21
- package/tsconfig.json +5 -7
package/changelog.md
CHANGED
|
@@ -6,6 +6,45 @@ 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.1.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.1.0)
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added a named export `rateLimit` in case the default import does not work.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Added a named export `default`, so Typescript CommonJS developers can
|
|
18
|
+
default-import the library (`import rateLimit from 'express-rate-limit'`).
|
|
19
|
+
|
|
20
|
+
## [6.0.5](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.0.5)
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Use named imports for ExpressJS types so users do not need to enable the
|
|
25
|
+
`esModuleInterop` flag in their Typescript compiler configuration.
|
|
26
|
+
|
|
27
|
+
## [6.0.4](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.0.4)
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Upload the built package as a `.tgz` to GitHub releases.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Add ` main` and `module` fields to `package.json`. This helps tools such as
|
|
36
|
+
ESLint that do not yet support the `exports` field.
|
|
37
|
+
- Bumped the minimum node.js version in `package-lock.json` to match
|
|
38
|
+
`package.json`
|
|
39
|
+
|
|
40
|
+
## [6.0.3](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.0.3)
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- Bumped minimum Node version from 12.9 to 14.5 in `package.json` because the
|
|
45
|
+
transpiled output uses the nullish coalescing operator (`??`), which
|
|
46
|
+
[isn't supported in node.js prior to 14.x](https://node.green/#ES2020-features--nullish-coalescing-operator-----).
|
|
47
|
+
|
|
9
48
|
## [6.0.2](https://github.com/nfriedly/express-rate-limit/releases/v6.0.2)
|
|
10
49
|
|
|
11
50
|
### Fixed
|
package/dist/index.cjs
CHANGED
|
@@ -24,7 +24,8 @@ var __toCommonJS = /* @__PURE__ */ ((cache) => {
|
|
|
24
24
|
// source/index.ts
|
|
25
25
|
var source_exports = {};
|
|
26
26
|
__export(source_exports, {
|
|
27
|
-
default: () =>
|
|
27
|
+
default: () => lib_default,
|
|
28
|
+
rateLimit: () => lib_default
|
|
28
29
|
});
|
|
29
30
|
|
|
30
31
|
// source/memory-store.ts
|
|
@@ -219,8 +220,5 @@ var rateLimit = (passedOptions) => {
|
|
|
219
220
|
return middleware;
|
|
220
221
|
};
|
|
221
222
|
var lib_default = rateLimit;
|
|
222
|
-
|
|
223
|
-
// source/index.ts
|
|
224
|
-
var source_default = lib_default;
|
|
225
223
|
module.exports = __toCommonJS(source_exports);
|
|
226
|
-
module.exports = rateLimit;
|
|
224
|
+
module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// Generated by dts-bundle-generator v6.
|
|
1
|
+
// Generated by dts-bundle-generator v6.4.0
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Callback that fires when a client's hit counter is incremented.
|
|
@@ -14,32 +14,32 @@ export declare type IncrementCallback = (error: Error | undefined, totalHits: nu
|
|
|
14
14
|
* Method (in the form of middleware) to generate/retrieve a value based on the
|
|
15
15
|
* incoming request
|
|
16
16
|
*
|
|
17
|
-
* @param request {
|
|
18
|
-
* @param response {
|
|
17
|
+
* @param request {Request} - The Express request object
|
|
18
|
+
* @param response {Response} - The Express response object
|
|
19
19
|
*
|
|
20
20
|
* @returns {T} - The value needed
|
|
21
21
|
*/
|
|
22
|
-
export declare type ValueDeterminingMiddleware<T> = (request:
|
|
22
|
+
export declare type ValueDeterminingMiddleware<T> = (request: Request, response: Response) => T | Promise<T>;
|
|
23
23
|
/**
|
|
24
24
|
* Express request handler that sends back a response when a client is
|
|
25
25
|
* rate-limited.
|
|
26
26
|
*
|
|
27
|
-
* @param request {
|
|
28
|
-
* @param response {
|
|
29
|
-
* @param next {
|
|
27
|
+
* @param request {Request} - The Express request object
|
|
28
|
+
* @param response {Response} - The Express response object
|
|
29
|
+
* @param next {NextFunction} - The Express `next` function, can be called to skip responding
|
|
30
30
|
* @param optionsUsed {Options} - The options used to set up the middleware
|
|
31
31
|
*/
|
|
32
|
-
export declare type RateLimitExceededEventHandler = (request:
|
|
32
|
+
export declare type RateLimitExceededEventHandler = (request: Request, response: Response, next: NextFunction, optionsUsed: Options) => void;
|
|
33
33
|
/**
|
|
34
34
|
* Event callback that is triggered on a client's first request that exceeds the limit
|
|
35
35
|
* but not for subsequent requests. May be used for logging, etc. Should *not*
|
|
36
36
|
* send a response.
|
|
37
37
|
*
|
|
38
|
-
* @param request {
|
|
39
|
-
* @param response {
|
|
38
|
+
* @param request {Request} - The Express request object
|
|
39
|
+
* @param response {Response} - The Express response object
|
|
40
40
|
* @param optionsUsed {Options} - The options used to set up the middleware
|
|
41
41
|
*/
|
|
42
|
-
export declare type RateLimitReachedEventHandler = (request:
|
|
42
|
+
export declare type RateLimitReachedEventHandler = (request: Request, response: Response, optionsUsed: Options) => void;
|
|
43
43
|
/**
|
|
44
44
|
* Data returned from the `Store` when a client's hit counter is incremented.
|
|
45
45
|
*
|
|
@@ -53,7 +53,7 @@ export declare type IncrementResponse = {
|
|
|
53
53
|
/**
|
|
54
54
|
* A modified Express request handler with the rate limit functions.
|
|
55
55
|
*/
|
|
56
|
-
export declare type RateLimitRequestHandler =
|
|
56
|
+
export declare type RateLimitRequestHandler = RequestHandler & {
|
|
57
57
|
/**
|
|
58
58
|
* Method to reset a client's hit counter.
|
|
59
59
|
*
|
|
@@ -227,7 +227,7 @@ export interface Options {
|
|
|
227
227
|
* The extended request object that includes information about the client's
|
|
228
228
|
* rate limit.
|
|
229
229
|
*/
|
|
230
|
-
export declare type AugmentedRequest =
|
|
230
|
+
export declare type AugmentedRequest = Request & {
|
|
231
231
|
[key: string]: RateLimitInfo;
|
|
232
232
|
};
|
|
233
233
|
/**
|
|
@@ -240,9 +240,22 @@ export interface RateLimitInfo {
|
|
|
240
240
|
readonly remaining: number;
|
|
241
241
|
readonly resetTime: Date | undefined;
|
|
242
242
|
}
|
|
243
|
-
|
|
243
|
+
/**
|
|
244
|
+
*
|
|
245
|
+
* Create an instance of IP rate-limiting middleware for Express.
|
|
246
|
+
*
|
|
247
|
+
* @param passedOptions {Options} - Options to configure the rate limiter
|
|
248
|
+
*
|
|
249
|
+
* @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration
|
|
250
|
+
*
|
|
251
|
+
* @public
|
|
252
|
+
*/
|
|
253
|
+
export declare const rateLimit: (passedOptions?: (Omit<Partial<Options>, "store"> & {
|
|
244
254
|
store?: LegacyStore | Store | undefined;
|
|
245
255
|
}) | undefined) => RateLimitRequestHandler;
|
|
246
|
-
|
|
256
|
+
|
|
257
|
+
export {
|
|
258
|
+
rateLimit as default,
|
|
259
|
+
};
|
|
247
260
|
|
|
248
261
|
export {};
|
package/dist/index.mjs
CHANGED
|
@@ -190,9 +190,7 @@ var rateLimit = (passedOptions) => {
|
|
|
190
190
|
return middleware;
|
|
191
191
|
};
|
|
192
192
|
var lib_default = rateLimit;
|
|
193
|
-
|
|
194
|
-
// source/index.ts
|
|
195
|
-
var source_default = lib_default;
|
|
196
193
|
export {
|
|
197
|
-
|
|
194
|
+
lib_default as default,
|
|
195
|
+
lib_default as rateLimit
|
|
198
196
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.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",
|
|
@@ -28,13 +28,15 @@
|
|
|
28
28
|
"attack"
|
|
29
29
|
],
|
|
30
30
|
"type": "module",
|
|
31
|
-
"types": "./dist/index.d.ts",
|
|
32
31
|
"exports": {
|
|
33
32
|
".": {
|
|
34
33
|
"import": "./dist/index.mjs",
|
|
35
34
|
"require": "./dist/index.cjs"
|
|
36
35
|
}
|
|
37
36
|
},
|
|
37
|
+
"main": "./dist/index.cjs",
|
|
38
|
+
"module": "./dist/index.mjs",
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
38
40
|
"files": [
|
|
39
41
|
"dist/",
|
|
40
42
|
"tsconfig.json",
|
|
@@ -44,12 +46,12 @@
|
|
|
44
46
|
"changelog.md"
|
|
45
47
|
],
|
|
46
48
|
"engines": {
|
|
47
|
-
"node": ">=
|
|
49
|
+
"node": ">= 14.5.0"
|
|
48
50
|
},
|
|
49
51
|
"scripts": {
|
|
50
52
|
"clean": "del-cli dist/ coverage/ *.log *.tmp *.bak *.tgz",
|
|
51
|
-
"build:cjs": "esbuild
|
|
52
|
-
"build:esm": "esbuild
|
|
53
|
+
"build:cjs": "esbuild --bundle --format=cjs --outfile=dist/index.cjs --footer:js=\"module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit;\" source/index.ts",
|
|
54
|
+
"build:esm": "esbuild --bundle --format=esm --outfile=dist/index.mjs source/index.ts",
|
|
53
55
|
"build:types": "dts-bundle-generator --out-file=dist/index.d.ts source/index.ts",
|
|
54
56
|
"compile": "run-s clean build:*",
|
|
55
57
|
"lint:code": "xo --ignore test/external/",
|
|
@@ -60,7 +62,7 @@
|
|
|
60
62
|
"autofix": "run-s autofix:*",
|
|
61
63
|
"test:lib": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
|
|
62
64
|
"test:ext": "cd test/external/ && bash run-all-tests",
|
|
63
|
-
"test": "
|
|
65
|
+
"test": "run-s lint test:*",
|
|
64
66
|
"pre-commit": "lint-staged",
|
|
65
67
|
"prepare": "run-s compile && husky install config/husky"
|
|
66
68
|
},
|
|
@@ -68,21 +70,21 @@
|
|
|
68
70
|
"express": "^4"
|
|
69
71
|
},
|
|
70
72
|
"devDependencies": {
|
|
71
|
-
"@jest/globals": "^27.4.
|
|
73
|
+
"@jest/globals": "^27.4.6",
|
|
72
74
|
"@types/express": "^4.17.13",
|
|
73
|
-
"@types/jest": "^27.0
|
|
74
|
-
"@types/node": "^16.11.
|
|
75
|
+
"@types/jest": "^27.4.0",
|
|
76
|
+
"@types/node": "^16.11.19",
|
|
75
77
|
"@types/supertest": "^2.0.11",
|
|
76
78
|
"cross-env": "^7.0.3",
|
|
77
79
|
"del-cli": "^4.0.1",
|
|
78
|
-
"dts-bundle-generator": "^6.
|
|
79
|
-
"esbuild": "^0.14.
|
|
80
|
+
"dts-bundle-generator": "^6.4.0",
|
|
81
|
+
"esbuild": "^0.14.11",
|
|
80
82
|
"express": "^4.17.1",
|
|
81
83
|
"husky": "^7.0.4",
|
|
82
|
-
"jest": "^27.4.
|
|
83
|
-
"lint-staged": "^12.1.
|
|
84
|
+
"jest": "^27.4.7",
|
|
85
|
+
"lint-staged": "^12.1.7",
|
|
84
86
|
"npm-run-all": "^4.1.5",
|
|
85
|
-
"supertest": "^6.1
|
|
87
|
+
"supertest": "^6.2.1",
|
|
86
88
|
"ts-jest": "^27.1.1",
|
|
87
89
|
"ts-node": "^10.4.0",
|
|
88
90
|
"typescript": "^4.5.2",
|
|
@@ -97,9 +99,7 @@
|
|
|
97
99
|
"@typescript-eslint/consistent-indexed-object-style": [
|
|
98
100
|
"error",
|
|
99
101
|
"index-signature"
|
|
100
|
-
]
|
|
101
|
-
"import/no-named-as-default-member": 0,
|
|
102
|
-
"import/no-cycle": 0
|
|
102
|
+
]
|
|
103
103
|
}
|
|
104
104
|
},
|
|
105
105
|
"prettier": {
|
package/readme.md
CHANGED
|
@@ -12,7 +12,7 @@ public APIs and/or endpoints such as password reset. Plays nice with
|
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
-
### Alternate Rate
|
|
15
|
+
### Alternate Rate Limiters
|
|
16
16
|
|
|
17
17
|
> This module does not share state with other processes/servers by default. If
|
|
18
18
|
> you need a more robust solution, I recommend using an external store. See the
|
|
@@ -26,7 +26,7 @@ software and may be more appropriate for some situations:
|
|
|
26
26
|
- [express-brute](https://www.npmjs.com/package/express-brute)
|
|
27
27
|
- [rate-limiter](https://www.npmjs.com/package/express-limiter)
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Installation
|
|
30
30
|
|
|
31
31
|
From the npm registry:
|
|
32
32
|
|
|
@@ -51,14 +51,21 @@ Replace `{version}` with the version of the package that you want to your, e.g.:
|
|
|
51
51
|
|
|
52
52
|
## Usage
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
### Importing
|
|
55
|
+
|
|
56
|
+
This library is provided in ESM as well as CJS forms, and works with both
|
|
57
|
+
Javascript and Typescript projects.
|
|
58
|
+
|
|
59
|
+
**This package requires you to use Node 14 or above.**
|
|
60
|
+
|
|
61
|
+
Import it in a CommonJS project (`type: commonjs` or no `type` field in
|
|
62
|
+
`package.json`) as follows:
|
|
56
63
|
|
|
57
64
|
```ts
|
|
58
65
|
const rateLimit = require('express-rate-limit')
|
|
59
66
|
```
|
|
60
67
|
|
|
61
|
-
|
|
68
|
+
Import it in a ESM project (`type: module` in `package.json`) as follows:
|
|
62
69
|
|
|
63
70
|
```ts
|
|
64
71
|
import rateLimit from 'express-rate-limit'
|
|
@@ -72,10 +79,6 @@ requests:
|
|
|
72
79
|
```ts
|
|
73
80
|
import rateLimit from 'express-rate-limit'
|
|
74
81
|
|
|
75
|
-
// Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
|
|
76
|
-
// see https://expressjs.com/en/guide/behind-proxies.html
|
|
77
|
-
// app.set('trust proxy', 1);
|
|
78
|
-
|
|
79
82
|
const limiter = rateLimit({
|
|
80
83
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
81
84
|
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
|
@@ -94,10 +97,6 @@ requests:
|
|
|
94
97
|
```ts
|
|
95
98
|
import rateLimit from 'express-rate-limit'
|
|
96
99
|
|
|
97
|
-
// Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
|
|
98
|
-
// see https://expressjs.com/en/guide/behind-proxies.html
|
|
99
|
-
// app.set('trust proxy', 1);
|
|
100
|
-
|
|
101
100
|
const apiLimiter = rateLimit({
|
|
102
101
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
103
102
|
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
|
@@ -114,10 +113,6 @@ To create multiple instances to apply different rules to different endpoints:
|
|
|
114
113
|
```ts
|
|
115
114
|
import rateLimit from 'express-rate-limit'
|
|
116
115
|
|
|
117
|
-
// Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
|
|
118
|
-
// see https://expressjs.com/en/guide/behind-proxies.html
|
|
119
|
-
// app.set('trust proxy', 1);
|
|
120
|
-
|
|
121
116
|
const apiLimiter = rateLimit({
|
|
122
117
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
123
118
|
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
|
@@ -147,10 +142,6 @@ To use a custom store:
|
|
|
147
142
|
import rateLimit from 'express-rate-limit'
|
|
148
143
|
import MemoryStore from 'express-rate-limit/memory-store.js'
|
|
149
144
|
|
|
150
|
-
// Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
|
|
151
|
-
// see https://expressjs.com/en/guide/behind-proxies.html
|
|
152
|
-
// app.set('trust proxy', 1);
|
|
153
|
-
|
|
154
145
|
const apiLimiter = rateLimit({
|
|
155
146
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
156
147
|
max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
|
|
@@ -166,6 +157,38 @@ app.use('/api', apiLimiter)
|
|
|
166
157
|
> prefixes, when using multiple instances. The default built-in memory store is
|
|
167
158
|
> an exception to this rule.
|
|
168
159
|
|
|
160
|
+
### Troubleshooting Proxy Issues
|
|
161
|
+
|
|
162
|
+
If you are behind a proxy/load balancer (usually the case with most hosting
|
|
163
|
+
services, e.g. Heroku, Bluemix, AWS ELB, Nginx, Cloudflare, Akamai, Fastly,
|
|
164
|
+
Firebase Hosting, Rackspace LB, Riverbed Stingray, etc.), the IP address of the
|
|
165
|
+
request might be the IP of the load balancer/reverse proxy (making the rate
|
|
166
|
+
limiter effectively a global one and blocking all requests once the limit is
|
|
167
|
+
reached) or `undefined`. To solve this issue, add the following line to your
|
|
168
|
+
code (right after you create the express application):
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
app.set('trust proxy', numberOfProxies)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Where `numberOfProxies` is the number of proxies between the user and the
|
|
175
|
+
server. To find the correct number, create a test endpoint that returns the
|
|
176
|
+
client IP:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
app.set('trust proxy', 1)
|
|
180
|
+
app.get('/ip', (request, response) => response.send(request.ip))
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Go to `/ip` and see the IP address returned in the response. If it matches your
|
|
184
|
+
IP address (which you can get by going to http://ip.nfriedly.com/ or
|
|
185
|
+
https://api.ipify.org/), then the number of proxies is correct and the rate
|
|
186
|
+
limiter should now work correctly. If not, then keep increasing the number until
|
|
187
|
+
it does.
|
|
188
|
+
|
|
189
|
+
For more information about the `trust proxy` setting, take a look at the
|
|
190
|
+
[official Express documentation](https://expressjs.com/en/guide/behind-proxies.html).
|
|
191
|
+
|
|
169
192
|
## Request API
|
|
170
193
|
|
|
171
194
|
A `request.rateLimit` property is added to all requests with the `limit`,
|
package/tsconfig.json
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
+
"include": ["source/"],
|
|
3
|
+
"exclude": ["node_modules/"],
|
|
2
4
|
"compilerOptions": {
|
|
3
5
|
"declaration": true,
|
|
4
|
-
|
|
5
6
|
"strict": true,
|
|
6
7
|
"noUnusedLocals": true,
|
|
7
8
|
"noImplicitReturns": true,
|
|
8
9
|
"noFallthroughCasesInSwitch": true,
|
|
9
|
-
|
|
10
|
-
"moduleResolution": "node"
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
"include": ["./source/**/*.ts"],
|
|
14
|
-
"exclude": ["./node_modules"]
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"moduleResolution": "node"
|
|
12
|
+
}
|
|
15
13
|
}
|