83 lines
2.8 KiB
JavaScript
83 lines
2.8 KiB
JavaScript
import { getSettings } from "utils/config/config";
|
|
|
|
function checkIPRange(ip, ipSpace) {
|
|
// Check if the given IP is in the ipSpace address space using
|
|
// CIDR notation. If ipSpace is a plain IPv4 we just compare them.
|
|
const ipSpaceParts = ipSpace.split("/");
|
|
if (ipSpaceParts.length === 1) {
|
|
if (ip === ipSpace) {
|
|
return true;
|
|
}
|
|
} else if (ipSpaceParts.length === 2) {
|
|
const ipParts = ip.split(".");
|
|
const ipNum = parseInt(ipParts[0], 10) * 256 * 256 * 256 + parseInt(ipParts[1], 10) * 256 * 256 + parseInt(ipParts[2], 10) * 256 + parseInt(ipParts[3], 10);
|
|
const ipSpaceNum = parseInt(ipSpaceParts[0].split(".")[0], 10) * 256 * 256 * 256 + parseInt(ipSpaceParts[0].split(".")[1], 10) * 256 * 256 + parseInt(ipSpaceParts[0].split(".")[2], 10) * 256 + parseInt(ipSpaceParts[0].split(".")[3], 10);
|
|
const mask = 32 - parseInt(ipSpaceParts[1], 10);
|
|
// eslint-disable-next-line no-bitwise
|
|
const maskNum = 0xffffffff << mask;
|
|
// eslint-disable-next-line no-bitwise
|
|
if ((ipNum & maskNum) === (ipSpaceNum & maskNum)) {
|
|
return true;
|
|
}
|
|
} else {
|
|
console.error("Invalid ipSpace: ", ipSpace);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function isRequestProxied(req) {
|
|
const settings = getSettings();
|
|
// Check if trustedproxies is set
|
|
const trustedProxies = settings?.trustedproxies;
|
|
|
|
// If trustedproxies is set, check if the client IP
|
|
// is in the trustedproxies address space using CIDR notation.
|
|
if (trustedProxies) {
|
|
// Get the connection IP and strip IPv6 from the hybrid IPv4-IPv6 socket
|
|
const ip = req.connection.remoteAddress.replace(/^.*:/, '');
|
|
|
|
for (let i = 0; i < trustedProxies.length; i += 1) {
|
|
const proxy = trustedProxies[i].trim();
|
|
const inRange = checkIPRange(ip, proxy);
|
|
if (inRange) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
export function getClientIP(req) {
|
|
// Check if the request is proxied
|
|
const proxied = isRequestProxied(req);
|
|
// If the request is proxied, get the forwarded IP address
|
|
// from the X-Real-IP header
|
|
const forwarded = req.headers["x-real-ip"];
|
|
// If not get the connection IP address
|
|
const ip = req.connection.remoteAddress.replace(/^.*:/, '');
|
|
|
|
// Conditionally return the forwarded IP address or the connection IP address
|
|
return proxied ? (forwarded || ip) : ip;
|
|
}
|
|
|
|
export function isInLocalScope(req) {
|
|
const settings = getSettings();
|
|
// Check if localscope is set
|
|
const localScope = settings?.localscope;
|
|
|
|
// If localscope is set, check if the client IP
|
|
// is in the localscope address space using CIDR notation.
|
|
if (localScope) {
|
|
const ip = getClientIP(req);
|
|
|
|
for (let i = 0; i < localScope.length; i += 1) {
|
|
const localIP = localScope[i].trim();
|
|
const inRange = checkIPRange(ip, localIP)
|
|
if (inRange) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|