Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

express-rate-limit

Package Overview
Dependencies
Maintainers
1
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-rate-limit - npm Package Compare versions

Comparing version 2.2.0 to 2.3.0

lib/memory-store.js

58

lib/express-rate-limit.js
'use strict';
var defaults = require('defaults');
var MemoryStore = require('./memory-store');

@@ -31,2 +32,12 @@ function RateLimit(options) {

// store to use for persisting rate limit data
options.store = options.store || new MemoryStore(options.windowMs);
// ensure that the store has the incr method
if (typeof options.store.incr !== 'function' || typeof options.store.resetKey !== 'function') {
throw new Error('The store is not valid.');
}
if (options.global) {

@@ -37,42 +48,27 @@ throw new Error('The global option was removed from express-rate-limit v2.');

// this is shared by all endpoints that use this instance
var hits = {};
function rateLimit(req, res, next) {
var key = options.keyGenerator(req, res);
if (hits[key]) {
hits[key]++;
} else {
hits[key] = 1;
}
options.store.incr(key, function(err, current) {
if (err) {
return next(err);
}
if (options.max && hits[key] > options.max) {
return options.handler(req,res, next);
}
if (options.max && current > options.max) {
return options.handler(req,res, next);
}
if (options.delayAfter && options.delayMs && hits[key] > options.delayAfter) {
var delay = (hits[key] - options.delayAfter) * options.delayMs;
setTimeout(next, delay);
} else {
next();
}
if (options.delayAfter && options.delayMs && current > options.delayAfter) {
var delay = (current - options.delayAfter) * options.delayMs;
setTimeout(next, delay);
} else {
next();
}
});
}
function resetAll() {
hits = {};
}
rateLimit.resetKey = options.store.resetKey.bind(options.store);
// simply reset ALL hits every windowMs
setInterval(resetAll, options.windowMs);
// export an API to allow hits from one or all IPs to be reset
function resetKey(key) {
delete hits[key];
}
rateLimit.resetKey = resetKey;
// Backward compatibility function
rateLimit.resetIp = resetKey;
rateLimit.resetIp = rateLimit.resetKey;

@@ -79,0 +75,0 @@ return rateLimit;

{
"name": "express-rate-limit",
"version": "2.2.0",
"version": "2.3.0",
"description": "Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.",

@@ -46,3 +46,3 @@ "homepage": "https://github.com/nfriedly/express-rate-limit",

"jshint-stylish": "^2.1.0",
"load-grunt-tasks": "^3.4.0",
"load-grunt-tasks": "^3.5.0",
"supertest": "^1.1.0",

@@ -49,0 +49,0 @@ "time-grunt": "^1.3.0"

@@ -10,3 +10,3 @@ # Express Rate Limit

Note: this module does not share state with other processes/servers.
Note: this module does not share state with other processes/servers by default.
If you need a more robust solution, I recommend checking out [strict-rate-limiter](https://www.npmjs.com/package/strict-rate-limiter) or [express-brute](https://www.npmjs.com/package/express-brute), both are excellent pieces of software.

@@ -111,3 +111,37 @@

```
* **store**: The storage to use when persisting rate limit attempts. By default, the [MemoryStore](lib/memory-store.js) is used. It must implement the following in order to function:
```js
function SomeStore() {
/**
* Increments the value in the underlying store for the given key.
* @method function
* @param {string} key - The key to use as the unique identifier passed
* down from RateLimit.
* @param {Store~incrCallback} cb - The callback issued when the underlying
* store is finished.
*/
this.incr = function(key, cb) {
// ...
};
/**
* This callback is called by the underlying store when an answer to the
* increment is available.
* @callback Store~incrCallback
* @param {?object} err - The error from the underlying store, or null if no
* error occurred.
* @param {number} value - The current value of the counter
*/
/**
* Resets a value with the given key.
* @method function
* @param {[type]} key - The key to reset
*/
this.resetKey = function(key) {
// ...
};
};
```
The `delayAfter` and `delayMs` options were written for human-facing pages such as login and password reset forms.

@@ -114,0 +148,0 @@ For public APIs, setting these to `0` (disabled) and relying on only `windowMs` and `max` for rate-limiting usually makes the most sense.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc