diff --git a/server/shared/request/mw.js b/server/shared/request/mw.js index fd49538f1..ba093ed51 100644 --- a/server/shared/request/mw.js +++ b/server/shared/request/mw.js @@ -4,16 +4,23 @@ const rateLimit = require('express-rate-limit'); const Tapster = require('@extensionengine/tapster'); const { provider, ...options } = require('../../../config/server').store; -const DEFAULT_WINDOW_MS = 15 * 60 * 1000; // every 15 minutes +const DEFAULT_STORE_NAMESPACE = 'default-request-limiter'; +const DEFAULT_WINDOW_MINUTES = 5; +const DEFAULT_WINDOW_MS = DEFAULT_WINDOW_MINUTES * 60 * 1000; // Store must be implemented using the following interface: // https://github.com/nfriedly/express-rate-limit/blob/master/README.md#store class Store { - constructor() { + /** + * @param {string} namespace namespace for the keys that need to be stored + * @param {number} windowMs ttl in milliseconds + */ + constructor(namespace, windowMs) { this.cache = new Tapster({ ...options[provider], store: provider, - namespace: 'request-limiter' + namespace, + ttl: windowMs / 1000 // Tapster expects input in seconds }); } @@ -37,14 +44,22 @@ class Store { } } -const defaultStore = new Store(); +const defaultStore = new Store(DEFAULT_STORE_NAMESPACE, DEFAULT_WINDOW_MS); + +function requestLimiter({ max = 10, namespace, windowMs, ...opts } = {}) { + let store; + // If namespace and windowMs are not provided, use the default store + if (!namespace && !windowMs) { + store = defaultStore; + windowMs = DEFAULT_WINDOW_MS; + } else if (namespace && windowMs) { + store = new Store(namespace, windowMs); + } else { + throw new Error(` + namespace and windowMs are required to create a custom store. + Omit both for default store with ${DEFAULT_WINDOW_MINUTES}min window.`); + } -function requestLimiter({ - max = 10, - windowMs = DEFAULT_WINDOW_MS, - store = defaultStore, - ...opts -} = {}) { return rateLimit({ max, windowMs, store, ...opts }); } diff --git a/server/user/mw.js b/server/user/mw.js index 9c9dc3fff..a17a97797 100644 --- a/server/user/mw.js +++ b/server/user/mw.js @@ -6,6 +6,7 @@ const { requestLimiter } = require('../shared/request/mw'); const ONE_HOUR_IN_MS = 60 * 60 * 1000; const loginRequestLimiter = requestLimiter({ + namespace: 'login-request-limiter', windowMs: ONE_HOUR_IN_MS, keyGenerator: req => req.userKey });