Add initial scopes support
This commit is contained in:
parent
bffda3240a
commit
e81ee78e86
83
src/utils/config/scope.js
Normal file
83
src/utils/config/scope.js
Normal file
@ -0,0 +1,83 @@
|
||||
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;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user