diff options
Diffstat (limited to 'server/rate-limiter.js')
-rw-r--r-- | server/rate-limiter.js | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/server/rate-limiter.js b/server/rate-limiter.js new file mode 100644 index 0000000..3c269b6 --- /dev/null +++ b/server/rate-limiter.js @@ -0,0 +1,75 @@ +const { RateLimiter } = require("limiter"); +const { log } = require("../src/util"); + +class KumaRateLimiter { + /** + * @param {object} config Rate limiter configuration object + */ + constructor(config) { + this.errorMessage = config.errorMessage; + this.rateLimiter = new RateLimiter(config); + } + + /** + * Callback for pass + * @callback passCB + * @param {object} err Too many requests + */ + + /** + * Should the request be passed through + * @param {passCB} callback Callback function to call with decision + * @param {number} num Number of tokens to remove + * @returns {Promise<boolean>} Should the request be allowed? + */ + async pass(callback, num = 1) { + const remainingRequests = await this.removeTokens(num); + log.info("rate-limit", "remaining requests: " + remainingRequests); + if (remainingRequests < 0) { + if (callback) { + callback({ + ok: false, + msg: this.errorMessage, + }); + } + return false; + } + return true; + } + + /** + * Remove a given number of tokens + * @param {number} num Number of tokens to remove + * @returns {Promise<number>} Number of remaining tokens + */ + async removeTokens(num = 1) { + return await this.rateLimiter.removeTokens(num); + } +} + +const loginRateLimiter = new KumaRateLimiter({ + tokensPerInterval: 20, + interval: "minute", + fireImmediately: true, + errorMessage: "Too frequently, try again later." +}); + +const apiRateLimiter = new KumaRateLimiter({ + tokensPerInterval: 60, + interval: "minute", + fireImmediately: true, + errorMessage: "Too frequently, try again later." +}); + +const twoFaRateLimiter = new KumaRateLimiter({ + tokensPerInterval: 30, + interval: "minute", + fireImmediately: true, + errorMessage: "Too frequently, try again later." +}); + +module.exports = { + loginRateLimiter, + apiRateLimiter, + twoFaRateLimiter, +}; |