express-rate-limit 6.2.0 → 6.4.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 +26 -0
- package/dist/index.cjs +37 -30
- package/dist/index.d.ts +3 -5
- package/dist/index.mjs +29 -17
- package/package.json +24 -24
package/changelog.md
CHANGED
|
@@ -6,6 +6,32 @@ 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.4.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.3.0)
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Adds Express 5 (`5.0.0-beta.1`) as a supported peer dependency (#304)
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- Tests are now run on Node 12, 14, 16 and 18 on CI (#305)
|
|
18
|
+
- Updated all development dependencies (#306)
|
|
19
|
+
|
|
20
|
+
## [6.3.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.3.0)
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Changes the build target to es2019 so that ESBuild outputs code that can run
|
|
25
|
+
with Node 12.
|
|
26
|
+
- Changes the minimum required Node version to 12.9.0.
|
|
27
|
+
|
|
28
|
+
## [6.2.1](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.2.1)
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Use the default value for an option when `undefined` is passed to the rate
|
|
33
|
+
limiter.
|
|
34
|
+
|
|
9
35
|
## [6.2.0](https://github.com/nfriedly/express-rate-limit/releases/tag/v6.2.0)
|
|
10
36
|
|
|
11
37
|
### Added
|
package/dist/index.cjs
CHANGED
|
@@ -2,24 +2,19 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
6
5
|
var __export = (target, all) => {
|
|
7
6
|
for (var name in all)
|
|
8
7
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
8
|
};
|
|
10
|
-
var
|
|
11
|
-
if (
|
|
12
|
-
for (let key of __getOwnPropNames(
|
|
13
|
-
if (!__hasOwnProp.call(
|
|
14
|
-
__defProp(
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
14
|
}
|
|
16
|
-
return
|
|
15
|
+
return to;
|
|
17
16
|
};
|
|
18
|
-
var __toCommonJS =
|
|
19
|
-
return (module2, temp) => {
|
|
20
|
-
return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
|
|
21
|
-
};
|
|
22
|
-
})(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
18
|
|
|
24
19
|
// source/index.ts
|
|
25
20
|
var source_exports = {};
|
|
@@ -28,6 +23,7 @@ __export(source_exports, {
|
|
|
28
23
|
default: () => lib_default,
|
|
29
24
|
rateLimit: () => lib_default
|
|
30
25
|
});
|
|
26
|
+
module.exports = __toCommonJS(source_exports);
|
|
31
27
|
|
|
32
28
|
// source/memory-store.ts
|
|
33
29
|
var calculateNextResetTime = (windowMs) => {
|
|
@@ -48,7 +44,8 @@ var MemoryStore = class {
|
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
async increment(key) {
|
|
51
|
-
|
|
47
|
+
var _a;
|
|
48
|
+
const totalHits = ((_a = this.hits[key]) != null ? _a : 0) + 1;
|
|
52
49
|
this.hits[key] = totalHits;
|
|
53
50
|
return {
|
|
54
51
|
totalHits,
|
|
@@ -88,50 +85,51 @@ var promisifyStore = (passedStore) => {
|
|
|
88
85
|
});
|
|
89
86
|
}
|
|
90
87
|
async decrement(key) {
|
|
91
|
-
return
|
|
88
|
+
return legacyStore.decrement(key);
|
|
92
89
|
}
|
|
93
90
|
async resetKey(key) {
|
|
94
|
-
return
|
|
91
|
+
return legacyStore.resetKey(key);
|
|
95
92
|
}
|
|
96
93
|
async resetAll() {
|
|
97
94
|
if (typeof legacyStore.resetAll === "function")
|
|
98
|
-
return
|
|
95
|
+
return legacyStore.resetAll();
|
|
99
96
|
}
|
|
100
97
|
}
|
|
101
98
|
return new PromisifiedStore();
|
|
102
99
|
};
|
|
103
100
|
var parseOptions = (passedOptions) => {
|
|
104
|
-
|
|
101
|
+
var _a, _b, _c;
|
|
102
|
+
const notUndefinedOptions = omitUndefinedOptions(passedOptions);
|
|
103
|
+
const config = {
|
|
105
104
|
windowMs: 60 * 1e3,
|
|
106
|
-
store: new MemoryStore(),
|
|
107
105
|
max: 5,
|
|
108
106
|
message: "Too many requests, please try again later.",
|
|
109
107
|
statusCode: 429,
|
|
110
|
-
legacyHeaders: passedOptions.headers
|
|
111
|
-
standardHeaders: passedOptions.draft_polli_ratelimit_headers
|
|
108
|
+
legacyHeaders: (_a = passedOptions.headers) != null ? _a : true,
|
|
109
|
+
standardHeaders: (_b = passedOptions.draft_polli_ratelimit_headers) != null ? _b : false,
|
|
112
110
|
requestPropertyName: "rateLimit",
|
|
113
111
|
skipFailedRequests: false,
|
|
114
112
|
skipSuccessfulRequests: false,
|
|
115
113
|
requestWasSuccessful: (_request, response) => response.statusCode < 400,
|
|
116
114
|
skip: (_request, _response) => false,
|
|
117
|
-
keyGenerator
|
|
115
|
+
keyGenerator(request, _response) {
|
|
118
116
|
if (!request.ip) {
|
|
119
117
|
console.error("WARN | `express-rate-limit` | `request.ip` is undefined. You can avoid this by providing a custom `keyGenerator` function, but it may be indicative of a larger issue.");
|
|
120
118
|
}
|
|
121
119
|
return request.ip;
|
|
122
120
|
},
|
|
123
|
-
handler
|
|
124
|
-
response.status(
|
|
121
|
+
handler(_request, response, _next, _optionsUsed) {
|
|
122
|
+
response.status(config.statusCode).send(config.message);
|
|
125
123
|
},
|
|
126
|
-
onLimitReached
|
|
124
|
+
onLimitReached(_request, _response, _optionsUsed) {
|
|
127
125
|
},
|
|
128
|
-
...
|
|
126
|
+
...notUndefinedOptions,
|
|
127
|
+
store: promisifyStore((_c = notUndefinedOptions.store) != null ? _c : new MemoryStore())
|
|
129
128
|
};
|
|
130
|
-
if (typeof
|
|
129
|
+
if (typeof config.store.increment !== "function" || typeof config.store.decrement !== "function" || typeof config.store.resetKey !== "function" || typeof config.store.resetAll !== "undefined" && typeof config.store.resetAll !== "function" || typeof config.store.init !== "undefined" && typeof config.store.init !== "function") {
|
|
131
130
|
throw new TypeError("An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.");
|
|
132
131
|
}
|
|
133
|
-
|
|
134
|
-
return options;
|
|
132
|
+
return config;
|
|
135
133
|
};
|
|
136
134
|
var handleAsyncErrors = (fn) => async (request, response, next) => {
|
|
137
135
|
try {
|
|
@@ -141,7 +139,7 @@ var handleAsyncErrors = (fn) => async (request, response, next) => {
|
|
|
141
139
|
}
|
|
142
140
|
};
|
|
143
141
|
var rateLimit = (passedOptions) => {
|
|
144
|
-
const options = parseOptions(passedOptions
|
|
142
|
+
const options = parseOptions(passedOptions != null ? passedOptions : {});
|
|
145
143
|
if (typeof options.store.init === "function")
|
|
146
144
|
options.store.init(options);
|
|
147
145
|
const middleware = handleAsyncErrors(async (request, response, next) => {
|
|
@@ -220,6 +218,15 @@ var rateLimit = (passedOptions) => {
|
|
|
220
218
|
middleware.resetKey = options.store.resetKey.bind(options.store);
|
|
221
219
|
return middleware;
|
|
222
220
|
};
|
|
221
|
+
var omitUndefinedOptions = (passedOptions) => {
|
|
222
|
+
const omittedOptions = {};
|
|
223
|
+
for (const k of Object.keys(passedOptions)) {
|
|
224
|
+
const key = k;
|
|
225
|
+
if (passedOptions[key] !== void 0) {
|
|
226
|
+
omittedOptions[key] = passedOptions[key];
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return omittedOptions;
|
|
230
|
+
};
|
|
223
231
|
var lib_default = rateLimit;
|
|
224
|
-
module.exports = __toCommonJS(source_exports);
|
|
225
232
|
module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated by dts-bundle-generator v6.
|
|
1
|
+
// Generated by dts-bundle-generator v6.8.0
|
|
2
2
|
|
|
3
3
|
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
|
4
4
|
|
|
@@ -233,7 +233,7 @@ export interface Options {
|
|
|
233
233
|
*
|
|
234
234
|
* By default, the built-in `MemoryStore` will be used.
|
|
235
235
|
*/
|
|
236
|
-
store: Store;
|
|
236
|
+
store: Store | LegacyStore;
|
|
237
237
|
/**
|
|
238
238
|
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
|
239
239
|
* of requests.
|
|
@@ -276,9 +276,7 @@ export interface RateLimitInfo {
|
|
|
276
276
|
*
|
|
277
277
|
* @public
|
|
278
278
|
*/
|
|
279
|
-
export declare const rateLimit: (passedOptions?:
|
|
280
|
-
store?: LegacyStore | Store | undefined;
|
|
281
|
-
}) | undefined) => RateLimitRequestHandler;
|
|
279
|
+
export declare const rateLimit: (passedOptions?: Partial<Options> | undefined) => RateLimitRequestHandler;
|
|
282
280
|
/**
|
|
283
281
|
* A `Store` that stores the hit count for each client in memory.
|
|
284
282
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -17,7 +17,8 @@ var MemoryStore = class {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
async increment(key) {
|
|
20
|
-
|
|
20
|
+
var _a;
|
|
21
|
+
const totalHits = ((_a = this.hits[key]) != null ? _a : 0) + 1;
|
|
21
22
|
this.hits[key] = totalHits;
|
|
22
23
|
return {
|
|
23
24
|
totalHits,
|
|
@@ -57,50 +58,51 @@ var promisifyStore = (passedStore) => {
|
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
async decrement(key) {
|
|
60
|
-
return
|
|
61
|
+
return legacyStore.decrement(key);
|
|
61
62
|
}
|
|
62
63
|
async resetKey(key) {
|
|
63
|
-
return
|
|
64
|
+
return legacyStore.resetKey(key);
|
|
64
65
|
}
|
|
65
66
|
async resetAll() {
|
|
66
67
|
if (typeof legacyStore.resetAll === "function")
|
|
67
|
-
return
|
|
68
|
+
return legacyStore.resetAll();
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
return new PromisifiedStore();
|
|
71
72
|
};
|
|
72
73
|
var parseOptions = (passedOptions) => {
|
|
73
|
-
|
|
74
|
+
var _a, _b, _c;
|
|
75
|
+
const notUndefinedOptions = omitUndefinedOptions(passedOptions);
|
|
76
|
+
const config = {
|
|
74
77
|
windowMs: 60 * 1e3,
|
|
75
|
-
store: new MemoryStore(),
|
|
76
78
|
max: 5,
|
|
77
79
|
message: "Too many requests, please try again later.",
|
|
78
80
|
statusCode: 429,
|
|
79
|
-
legacyHeaders: passedOptions.headers
|
|
80
|
-
standardHeaders: passedOptions.draft_polli_ratelimit_headers
|
|
81
|
+
legacyHeaders: (_a = passedOptions.headers) != null ? _a : true,
|
|
82
|
+
standardHeaders: (_b = passedOptions.draft_polli_ratelimit_headers) != null ? _b : false,
|
|
81
83
|
requestPropertyName: "rateLimit",
|
|
82
84
|
skipFailedRequests: false,
|
|
83
85
|
skipSuccessfulRequests: false,
|
|
84
86
|
requestWasSuccessful: (_request, response) => response.statusCode < 400,
|
|
85
87
|
skip: (_request, _response) => false,
|
|
86
|
-
keyGenerator
|
|
88
|
+
keyGenerator(request, _response) {
|
|
87
89
|
if (!request.ip) {
|
|
88
90
|
console.error("WARN | `express-rate-limit` | `request.ip` is undefined. You can avoid this by providing a custom `keyGenerator` function, but it may be indicative of a larger issue.");
|
|
89
91
|
}
|
|
90
92
|
return request.ip;
|
|
91
93
|
},
|
|
92
|
-
handler
|
|
93
|
-
response.status(
|
|
94
|
+
handler(_request, response, _next, _optionsUsed) {
|
|
95
|
+
response.status(config.statusCode).send(config.message);
|
|
94
96
|
},
|
|
95
|
-
onLimitReached
|
|
97
|
+
onLimitReached(_request, _response, _optionsUsed) {
|
|
96
98
|
},
|
|
97
|
-
...
|
|
99
|
+
...notUndefinedOptions,
|
|
100
|
+
store: promisifyStore((_c = notUndefinedOptions.store) != null ? _c : new MemoryStore())
|
|
98
101
|
};
|
|
99
|
-
if (typeof
|
|
102
|
+
if (typeof config.store.increment !== "function" || typeof config.store.decrement !== "function" || typeof config.store.resetKey !== "function" || typeof config.store.resetAll !== "undefined" && typeof config.store.resetAll !== "function" || typeof config.store.init !== "undefined" && typeof config.store.init !== "function") {
|
|
100
103
|
throw new TypeError("An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.");
|
|
101
104
|
}
|
|
102
|
-
|
|
103
|
-
return options;
|
|
105
|
+
return config;
|
|
104
106
|
};
|
|
105
107
|
var handleAsyncErrors = (fn) => async (request, response, next) => {
|
|
106
108
|
try {
|
|
@@ -110,7 +112,7 @@ var handleAsyncErrors = (fn) => async (request, response, next) => {
|
|
|
110
112
|
}
|
|
111
113
|
};
|
|
112
114
|
var rateLimit = (passedOptions) => {
|
|
113
|
-
const options = parseOptions(passedOptions
|
|
115
|
+
const options = parseOptions(passedOptions != null ? passedOptions : {});
|
|
114
116
|
if (typeof options.store.init === "function")
|
|
115
117
|
options.store.init(options);
|
|
116
118
|
const middleware = handleAsyncErrors(async (request, response, next) => {
|
|
@@ -189,6 +191,16 @@ var rateLimit = (passedOptions) => {
|
|
|
189
191
|
middleware.resetKey = options.store.resetKey.bind(options.store);
|
|
190
192
|
return middleware;
|
|
191
193
|
};
|
|
194
|
+
var omitUndefinedOptions = (passedOptions) => {
|
|
195
|
+
const omittedOptions = {};
|
|
196
|
+
for (const k of Object.keys(passedOptions)) {
|
|
197
|
+
const key = k;
|
|
198
|
+
if (passedOptions[key] !== void 0) {
|
|
199
|
+
omittedOptions[key] = passedOptions[key];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return omittedOptions;
|
|
203
|
+
};
|
|
192
204
|
var lib_default = rateLimit;
|
|
193
205
|
export {
|
|
194
206
|
MemoryStore,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.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",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"changelog.md"
|
|
47
47
|
],
|
|
48
48
|
"engines": {
|
|
49
|
-
"node": ">=
|
|
49
|
+
"node": ">= 12.9.0"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"clean": "del-cli dist/ coverage/ *.log *.tmp *.bak *.tgz",
|
|
53
|
-
"build:cjs": "esbuild --bundle --format=cjs --outfile=dist/index.cjs --footer:js=\"module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;\" source/index.ts",
|
|
54
|
-
"build:esm": "esbuild --bundle --format=esm --outfile=dist/index.mjs source/index.ts",
|
|
53
|
+
"build:cjs": "esbuild --bundle --target=es2019 --format=cjs --outfile=dist/index.cjs --footer:js=\"module.exports = rateLimit; module.exports.default = rateLimit; module.exports.rateLimit = rateLimit; module.exports.MemoryStore = MemoryStore;\" source/index.ts",
|
|
54
|
+
"build:esm": "esbuild --bundle --target=es2019 --format=esm --outfile=dist/index.mjs source/index.ts",
|
|
55
55
|
"build:types": "dts-bundle-generator --out-file=dist/index.d.ts source/index.ts",
|
|
56
56
|
"compile": "run-s clean build:*",
|
|
57
57
|
"lint:code": "xo --ignore test/external/",
|
|
@@ -67,28 +67,28 @@
|
|
|
67
67
|
"prepare": "run-s compile && husky install config/husky"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"express": "^4"
|
|
70
|
+
"express": "^4 || ^5"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@jest/globals": "
|
|
74
|
-
"@types/express": "
|
|
75
|
-
"@types/jest": "
|
|
76
|
-
"@types/node": "
|
|
77
|
-
"@types/supertest": "
|
|
78
|
-
"cross-env": "
|
|
79
|
-
"del-cli": "
|
|
80
|
-
"dts-bundle-generator": "
|
|
81
|
-
"esbuild": "
|
|
82
|
-
"express": "
|
|
83
|
-
"husky": "
|
|
84
|
-
"jest": "
|
|
85
|
-
"lint-staged": "
|
|
86
|
-
"npm-run-all": "
|
|
87
|
-
"supertest": "
|
|
88
|
-
"ts-jest": "
|
|
89
|
-
"ts-node": "
|
|
90
|
-
"typescript": "
|
|
91
|
-
"xo": "
|
|
73
|
+
"@jest/globals": "27.4.6",
|
|
74
|
+
"@types/express": "4.17.13",
|
|
75
|
+
"@types/jest": "27.4.1",
|
|
76
|
+
"@types/node": "16.11.27",
|
|
77
|
+
"@types/supertest": "2.0.12",
|
|
78
|
+
"cross-env": "7.0.3",
|
|
79
|
+
"del-cli": "4.0.1",
|
|
80
|
+
"dts-bundle-generator": "6.8.0",
|
|
81
|
+
"esbuild": "0.14.38",
|
|
82
|
+
"express": "4.17.3",
|
|
83
|
+
"husky": "7.0.4",
|
|
84
|
+
"jest": "27.5.1",
|
|
85
|
+
"lint-staged": "12.4.0",
|
|
86
|
+
"npm-run-all": "4.1.5",
|
|
87
|
+
"supertest": "6.2.2",
|
|
88
|
+
"ts-jest": "27.1.4",
|
|
89
|
+
"ts-node": "10.7.0",
|
|
90
|
+
"typescript": "4.6.3",
|
|
91
|
+
"xo": "0.48.0"
|
|
92
92
|
},
|
|
93
93
|
"xo": {
|
|
94
94
|
"prettier": true,
|