mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-25 13:44:09 -08:00
Merge pull request #1827 from theS1LV3R/master
feat: get client ip from x-forwarded-for header if available
This commit is contained in:
commit
6e29feffd3
|
@ -254,7 +254,9 @@ let needSetup = false;
|
||||||
// ***************************
|
// ***************************
|
||||||
|
|
||||||
socket.on("loginByToken", async (token, callback) => {
|
socket.on("loginByToken", async (token, callback) => {
|
||||||
log.info("auth", `Login by token. IP=${getClientIp(socket)}`);
|
const clientIP = await server.getClientIP(socket);
|
||||||
|
|
||||||
|
log.info("auth", `Login by token. IP=${clientIP}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let decoded = jwt.verify(token, jwtSecret);
|
let decoded = jwt.verify(token, jwtSecret);
|
||||||
|
@ -270,14 +272,14 @@ let needSetup = false;
|
||||||
afterLogin(socket, user);
|
afterLogin(socket, user);
|
||||||
log.debug("auth", "afterLogin ok");
|
log.debug("auth", "afterLogin ok");
|
||||||
|
|
||||||
log.info("auth", `Successfully logged in user ${decoded.username}. IP=${getClientIp(socket)}`);
|
log.info("auth", `Successfully logged in user ${decoded.username}. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: true,
|
ok: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
log.info("auth", `Inactive or deleted user ${decoded.username}. IP=${getClientIp(socket)}`);
|
log.info("auth", `Inactive or deleted user ${decoded.username}. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: false,
|
ok: false,
|
||||||
|
@ -286,7 +288,7 @@ let needSetup = false;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
log.error("auth", `Invalid token. IP=${getClientIp(socket)}`);
|
log.error("auth", `Invalid token. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: false,
|
ok: false,
|
||||||
|
@ -297,7 +299,9 @@ let needSetup = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("login", async (data, callback) => {
|
socket.on("login", async (data, callback) => {
|
||||||
log.info("auth", `Login by username + password. IP=${getClientIp(socket)}`);
|
const clientIP = await server.getClientIP(socket);
|
||||||
|
|
||||||
|
log.info("auth", `Login by username + password. IP=${clientIP}`);
|
||||||
|
|
||||||
// Checking
|
// Checking
|
||||||
if (typeof callback !== "function") {
|
if (typeof callback !== "function") {
|
||||||
|
@ -310,7 +314,7 @@ let needSetup = false;
|
||||||
|
|
||||||
// Login Rate Limit
|
// Login Rate Limit
|
||||||
if (! await loginRateLimiter.pass(callback)) {
|
if (! await loginRateLimiter.pass(callback)) {
|
||||||
log.info("auth", `Too many failed requests for user ${data.username}. IP=${getClientIp(socket)}`);
|
log.info("auth", `Too many failed requests for user ${data.username}. IP=${clientIP}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +324,7 @@ let needSetup = false;
|
||||||
if (user.twofa_status === 0) {
|
if (user.twofa_status === 0) {
|
||||||
afterLogin(socket, user);
|
afterLogin(socket, user);
|
||||||
|
|
||||||
log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`);
|
log.info("auth", `Successfully logged in user ${data.username}. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: true,
|
ok: true,
|
||||||
|
@ -332,7 +336,7 @@ let needSetup = false;
|
||||||
|
|
||||||
if (user.twofa_status === 1 && !data.token) {
|
if (user.twofa_status === 1 && !data.token) {
|
||||||
|
|
||||||
log.info("auth", `2FA token required for user ${data.username}. IP=${getClientIp(socket)}`);
|
log.info("auth", `2FA token required for user ${data.username}. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
tokenRequired: true,
|
tokenRequired: true,
|
||||||
|
@ -350,7 +354,7 @@ let needSetup = false;
|
||||||
socket.userID,
|
socket.userID,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`);
|
log.info("auth", `Successfully logged in user ${data.username}. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: true,
|
ok: true,
|
||||||
|
@ -360,7 +364,7 @@ let needSetup = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
log.warn("auth", `Invalid token provided for user ${data.username}. IP=${getClientIp(socket)}`);
|
log.warn("auth", `Invalid token provided for user ${data.username}. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: false,
|
ok: false,
|
||||||
|
@ -370,7 +374,7 @@ let needSetup = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
log.warn("auth", `Incorrect username or password for user ${data.username}. IP=${getClientIp(socket)}`);
|
log.warn("auth", `Incorrect username or password for user ${data.username}. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: false,
|
ok: false,
|
||||||
|
@ -442,6 +446,8 @@ let needSetup = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("save2FA", async (currentPassword, callback) => {
|
socket.on("save2FA", async (currentPassword, callback) => {
|
||||||
|
const clientIP = await server.getClientIP(socket);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (! await twoFaRateLimiter.pass(callback)) {
|
if (! await twoFaRateLimiter.pass(callback)) {
|
||||||
return;
|
return;
|
||||||
|
@ -454,7 +460,7 @@ let needSetup = false;
|
||||||
socket.userID,
|
socket.userID,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
log.info("auth", `Saved 2FA token. IP=${getClientIp(socket)}`);
|
log.info("auth", `Saved 2FA token. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: true,
|
ok: true,
|
||||||
|
@ -462,7 +468,7 @@ let needSetup = false;
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
log.error("auth", `Error changing 2FA token. IP=${getClientIp(socket)}`);
|
log.error("auth", `Error changing 2FA token. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: false,
|
ok: false,
|
||||||
|
@ -472,6 +478,8 @@ let needSetup = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("disable2FA", async (currentPassword, callback) => {
|
socket.on("disable2FA", async (currentPassword, callback) => {
|
||||||
|
const clientIP = await server.getClientIP(socket);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (! await twoFaRateLimiter.pass(callback)) {
|
if (! await twoFaRateLimiter.pass(callback)) {
|
||||||
return;
|
return;
|
||||||
|
@ -481,7 +489,7 @@ let needSetup = false;
|
||||||
await doubleCheckPassword(socket, currentPassword);
|
await doubleCheckPassword(socket, currentPassword);
|
||||||
await TwoFA.disable2FA(socket.userID);
|
await TwoFA.disable2FA(socket.userID);
|
||||||
|
|
||||||
log.info("auth", `Disabled 2FA token. IP=${getClientIp(socket)}`);
|
log.info("auth", `Disabled 2FA token. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: true,
|
ok: true,
|
||||||
|
@ -489,7 +497,7 @@ let needSetup = false;
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
log.error("auth", `Error disabling 2FA token. IP=${getClientIp(socket)}`);
|
log.error("auth", `Error disabling 2FA token. IP=${clientIP}`);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
ok: false,
|
ok: false,
|
||||||
|
@ -1684,10 +1692,6 @@ async function shutdownFunction(signal) {
|
||||||
await cloudflaredStop();
|
await cloudflaredStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getClientIp(socket) {
|
|
||||||
return socket.client.conn.remoteAddress.replace(/^.*:/, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Final function called before application exits */
|
/** Final function called before application exits */
|
||||||
function finalFunction() {
|
function finalFunction() {
|
||||||
log.info("server", "Graceful shutdown successful!");
|
log.info("server", "Graceful shutdown successful!");
|
||||||
|
|
|
@ -8,6 +8,7 @@ const { log } = require("../src/util");
|
||||||
const Database = require("./database");
|
const Database = require("./database");
|
||||||
const util = require("util");
|
const util = require("util");
|
||||||
const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent");
|
const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent");
|
||||||
|
const { Settings } = require("./settings");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue.
|
* `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue.
|
||||||
|
@ -128,6 +129,18 @@ class UptimeKumaServer {
|
||||||
|
|
||||||
errorLogStream.end();
|
errorLogStream.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getClientIP(socket) {
|
||||||
|
const clientIP = socket.client.conn.remoteAddress.replace(/^.*:/, "");
|
||||||
|
|
||||||
|
if (await Settings.get("trustProxy")) {
|
||||||
|
return socket.client.conn.request.headers["x-forwarded-for"]
|
||||||
|
|| socket.client.conn.request.headers["x-real-ip"]
|
||||||
|
|| clientIP;
|
||||||
|
} else {
|
||||||
|
return clientIP;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -289,6 +289,7 @@ exports.postgresQuery = function (connectionString, query) {
|
||||||
* Retrieve value of setting based on key
|
* Retrieve value of setting based on key
|
||||||
* @param {string} key Key of setting to retrieve
|
* @param {string} key Key of setting to retrieve
|
||||||
* @returns {Promise<any>} Value
|
* @returns {Promise<any>} Value
|
||||||
|
* @deprecated Use await Settings.get(key)
|
||||||
*/
|
*/
|
||||||
exports.setting = async function (key) {
|
exports.setting = async function (key) {
|
||||||
return await Settings.get(key);
|
return await Settings.get(key);
|
||||||
|
|
Loading…
Reference in a new issue