uptime-kuma/server/rate-limiter.js
Matthew Nickson b8720b46c3
Switched to using Authorization header
Prometheus doesn't support using custom headers for exporters, however
it does support using the Authorisation header with basic auth. As
such, we switched from using X-API-Key to Authorization with the basic
scheme and an empty username field.

Also added a rate limit for API endpoints of 60 requests in a minute

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-02-15 21:53:49 +00:00

75 lines
1.9 KiB
JavaScript

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
* @param {number} [num=1] Number of tokens to remove
* @returns {Promise<boolean>}
*/
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=1] Number of tokens to remove
* @returns {Promise<number>}
*/
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,
};