55 lines
1.2 KiB
JavaScript
55 lines
1.2 KiB
JavaScript
function parseAllowedOrigins(value = "") {
|
|
return String(value)
|
|
.split(",")
|
|
.map((origin) => origin.trim())
|
|
.filter(Boolean);
|
|
}
|
|
|
|
function parseIpv4(hostname) {
|
|
const parts = hostname.split(".");
|
|
if (parts.length !== 4) return null;
|
|
|
|
const octets = parts.map((part) => {
|
|
if (!/^\d{1,3}$/.test(part)) return null;
|
|
|
|
const value = Number(part);
|
|
return value >= 0 && value <= 255 ? value : null;
|
|
});
|
|
|
|
return octets.some((octet) => octet === null) ? null : octets;
|
|
}
|
|
|
|
function isPrivateLanHostname(hostname) {
|
|
const octets = parseIpv4(hostname);
|
|
if (!octets) return false;
|
|
|
|
const [first, second] = octets;
|
|
return (
|
|
first === 10 ||
|
|
(first === 172 && second >= 16 && second <= 31) ||
|
|
(first === 192 && second === 168)
|
|
);
|
|
}
|
|
|
|
function isAllowedCorsOrigin(origin, allowedOrigins = []) {
|
|
if (!origin) return true;
|
|
if (allowedOrigins.includes(origin)) return true;
|
|
|
|
try {
|
|
const url = new URL(origin);
|
|
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
return false;
|
|
}
|
|
|
|
return isPrivateLanHostname(url.hostname);
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
isAllowedCorsOrigin,
|
|
isPrivateLanHostname,
|
|
parseAllowedOrigins,
|
|
};
|