express-rate-limit 7.3.1 → 7.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/dist/index.cjs CHANGED
@@ -627,6 +627,7 @@ var parseOptions = (passedOptions) => {
627
627
  response.send(message);
628
628
  }
629
629
  },
630
+ passOnStoreError: false,
630
631
  // Allow the default options to be overriden by the options passed to the middleware.
631
632
  ...notUndefinedOptions,
632
633
  // `standardHeaders` is resolved into a draft version above, use that.
@@ -667,7 +668,23 @@ var rateLimit = (passedOptions) => {
667
668
  }
668
669
  const augmentedRequest = request;
669
670
  const key = await config.keyGenerator(request, response);
670
- const { totalHits, resetTime } = await config.store.increment(key);
671
+ let totalHits = 0;
672
+ let resetTime;
673
+ try {
674
+ const incrementResult = await config.store.increment(key);
675
+ totalHits = incrementResult.totalHits;
676
+ resetTime = incrementResult.resetTime;
677
+ } catch (error) {
678
+ if (config.passOnStoreError) {
679
+ console.error(
680
+ "express-rate-limit: error from store, allowing request without rate-limiting.",
681
+ error
682
+ );
683
+ next();
684
+ } else {
685
+ throw error;
686
+ }
687
+ }
671
688
  config.validations.positiveHits(totalHits);
672
689
  config.validations.singleCount(request, config.store, key);
673
690
  const retrieveLimit = typeof config.limit === "function" ? config.limit(request, response) : config.limit;
package/dist/index.d.cts CHANGED
@@ -402,6 +402,10 @@ export type Options = {
402
402
  * be removed from the library in the foreseeable future.
403
403
  */
404
404
  max?: number | ValueDeterminingMiddleware<number>;
405
+ /**
406
+ * If the Store generates an error, allow the request to pass.
407
+ */
408
+ passOnStoreError: boolean;
405
409
  };
406
410
  /**
407
411
  * The extended request object that includes information about the client's
package/dist/index.d.mts CHANGED
@@ -402,6 +402,10 @@ export type Options = {
402
402
  * be removed from the library in the foreseeable future.
403
403
  */
404
404
  max?: number | ValueDeterminingMiddleware<number>;
405
+ /**
406
+ * If the Store generates an error, allow the request to pass.
407
+ */
408
+ passOnStoreError: boolean;
405
409
  };
406
410
  /**
407
411
  * The extended request object that includes information about the client's
package/dist/index.d.ts CHANGED
@@ -402,6 +402,10 @@ export type Options = {
402
402
  * be removed from the library in the foreseeable future.
403
403
  */
404
404
  max?: number | ValueDeterminingMiddleware<number>;
405
+ /**
406
+ * If the Store generates an error, allow the request to pass.
407
+ */
408
+ passOnStoreError: boolean;
405
409
  };
406
410
  /**
407
411
  * The extended request object that includes information about the client's
package/dist/index.mjs CHANGED
@@ -599,6 +599,7 @@ var parseOptions = (passedOptions) => {
599
599
  response.send(message);
600
600
  }
601
601
  },
602
+ passOnStoreError: false,
602
603
  // Allow the default options to be overriden by the options passed to the middleware.
603
604
  ...notUndefinedOptions,
604
605
  // `standardHeaders` is resolved into a draft version above, use that.
@@ -639,7 +640,23 @@ var rateLimit = (passedOptions) => {
639
640
  }
640
641
  const augmentedRequest = request;
641
642
  const key = await config.keyGenerator(request, response);
642
- const { totalHits, resetTime } = await config.store.increment(key);
643
+ let totalHits = 0;
644
+ let resetTime;
645
+ try {
646
+ const incrementResult = await config.store.increment(key);
647
+ totalHits = incrementResult.totalHits;
648
+ resetTime = incrementResult.resetTime;
649
+ } catch (error) {
650
+ if (config.passOnStoreError) {
651
+ console.error(
652
+ "express-rate-limit: error from store, allowing request without rate-limiting.",
653
+ error
654
+ );
655
+ next();
656
+ } else {
657
+ throw error;
658
+ }
659
+ }
643
660
  config.validations.positiveHits(totalHits);
644
661
  config.validations.singleCount(request, config.store, key);
645
662
  const retrieveLimit = typeof config.limit === "function" ? config.limit(request, response) : config.limit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-rate-limit",
3
- "version": "7.3.1",
3
+ "version": "7.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",
package/readme.md CHANGED
@@ -55,6 +55,7 @@ default values.
55
55
  | [`legacyHeaders`] | `boolean` | Enable the `X-Rate-Limit` header. |
56
56
  | [`standardHeaders`] | `'draft-6'` \| `'draft-7'` | Enable the `Ratelimit` header. |
57
57
  | [`store`] | `Store` | Use a custom store to share hit counts across multiple nodes. |
58
+ | [`passOnStoreError`] | `boolean` | Allow (`true`) or block (`false`, default) traffic if the store becomes unavailable. |
58
59
  | [`keyGenerator`] | `function` | Identify users (defaults to IP address). |
59
60
  | [`requestPropertyName`] | `string` | Add rate limit info to the `req` object. |
60
61
  | [`skip`] | `function` | Return `true` to bypass the limiter for the given request. |
@@ -126,6 +127,8 @@ MIT © [Nathan Friedly](http://nfriedly.com/),
126
127
  [`standardHeaders`]:
127
128
  https://express-rate-limit.mintlify.app/reference/configuration#standardheaders
128
129
  [`store`]: https://express-rate-limit.mintlify.app/reference/configuration#store
130
+ [`passOnStoreError`]:
131
+ https://express-rate-limit.mintlify.app/reference/configuration#passOnStoreError
129
132
  [`keyGenerator`]:
130
133
  https://express-rate-limit.mintlify.app/reference/configuration#keygenerator
131
134
  [`requestPropertyName`]: