mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-17 11:44:38 -05:00
add login rate limiter
This commit is contained in:
parent
8a481a1be0
commit
b77b33e790
@ -1,8 +1,9 @@
|
|||||||
const basicAuth = require("express-basic-auth")
|
const basicAuth = require("express-basic-auth");
|
||||||
const passwordHash = require("./password-hash");
|
const passwordHash = require("./password-hash");
|
||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
const { setting } = require("./util-server");
|
const { setting } = require("./util-server");
|
||||||
const { debug } = require("../src/util");
|
const { debug } = require("../src/util");
|
||||||
|
const { loginRateLimiter } = require("./rate-limiter");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -13,7 +14,7 @@ const { debug } = require("../src/util");
|
|||||||
exports.login = async function (username, password) {
|
exports.login = async function (username, password) {
|
||||||
let user = await R.findOne("user", " username = ? AND active = 1 ", [
|
let user = await R.findOne("user", " username = ? AND active = 1 ", [
|
||||||
username,
|
username,
|
||||||
])
|
]);
|
||||||
|
|
||||||
if (user && passwordHash.verify(password, user.password)) {
|
if (user && passwordHash.verify(password, user.password)) {
|
||||||
// Upgrade the hash to bcrypt
|
// Upgrade the hash to bcrypt
|
||||||
@ -27,21 +28,30 @@ exports.login = async function (username, password) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
};
|
||||||
|
|
||||||
function myAuthorizer(username, password, callback) {
|
function myAuthorizer(username, password, callback) {
|
||||||
|
|
||||||
setting("disableAuth").then((result) => {
|
setting("disableAuth").then((result) => {
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
callback(null, true)
|
callback(null, true);
|
||||||
} else {
|
} else {
|
||||||
exports.login(username, password).then((user) => {
|
// Login Rate Limit
|
||||||
callback(null, user != null)
|
loginRateLimiter.pass(null, 0).then((pass) => {
|
||||||
})
|
if (pass) {
|
||||||
}
|
exports.login(username, password).then((user) => {
|
||||||
})
|
callback(null, user != null);
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
loginRateLimiter.removeTokens(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(null, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.basicAuth = basicAuth({
|
exports.basicAuth = basicAuth({
|
||||||
|
39
server/rate-limiter.js
Normal file
39
server/rate-limiter.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
const { RateLimiter } = require("limiter");
|
||||||
|
const { debug } = require("../src/util");
|
||||||
|
|
||||||
|
class KumaRateLimiter {
|
||||||
|
constructor(config) {
|
||||||
|
this.errorMessage = config.errorMessage;
|
||||||
|
this.rateLimiter = new RateLimiter(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
async pass(callback, num = 1) {
|
||||||
|
const remainingRequests = await this.removeTokens(num);
|
||||||
|
debug("Rate Limit (remainingRequests):" + remainingRequests);
|
||||||
|
if (remainingRequests < 0) {
|
||||||
|
if (callback) {
|
||||||
|
callback({
|
||||||
|
ok: false,
|
||||||
|
msg: this.errorMessage,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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."
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
loginRateLimiter
|
||||||
|
};
|
@ -52,6 +52,7 @@ const Database = require("./database");
|
|||||||
|
|
||||||
debug("Importing Background Jobs");
|
debug("Importing Background Jobs");
|
||||||
const { initBackgroundJobs } = require("./jobs");
|
const { initBackgroundJobs } = require("./jobs");
|
||||||
|
const { loginRateLimiter } = require("./rate-limiter");
|
||||||
|
|
||||||
const { basicAuth } = require("./auth");
|
const { basicAuth } = require("./auth");
|
||||||
const { login } = require("./auth");
|
const { login } = require("./auth");
|
||||||
@ -281,6 +282,11 @@ exports.entryPage = "dashboard";
|
|||||||
socket.on("login", async (data, callback) => {
|
socket.on("login", async (data, callback) => {
|
||||||
console.log("Login");
|
console.log("Login");
|
||||||
|
|
||||||
|
// Login Rate Limit
|
||||||
|
if (! await loginRateLimiter.pass(callback)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let user = await login(data.username, data.password);
|
let user = await login(data.username, data.password);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
Loading…
Reference in New Issue
Block a user