Support Forwarded header
This commit is contained in:
1 parent
e80109de93
commit
603f5c79ac
10 files changed
+239
-34
No files matched your search
+2
-1
@@ -77,7 +77,8 @@ const externals = [
|
|||||||
"yaml",
|
"yaml",
|
||||||
"codemirror",
|
"codemirror",
|
||||||
"codemirror/mode/javascript/javascript",
|
"codemirror/mode/javascript/javascript",
|
||||||
"codemirror/mode/yaml/yaml"
|
"codemirror/mode/yaml/yaml",
|
||||||
|
"ipaddr.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
function rmDirSync(dirPath): void {
|
function rmDirSync(dirPath): void {
|
||||||
|
|||||||
@@ -164,12 +164,13 @@ FS_ACCESS_LOG_FILE
|
|||||||
|
|
||||||
Default: unset
|
Default: unset
|
||||||
|
|
||||||
FS_HOSTNAME
|
FS_URL_PREFIX
|
||||||
The hostname to use when generating the file URL for TR-069 Download
|
The URL prefix (e.g. 'https://example.com:7657/') to use when generating the
|
||||||
requests. Set this if the hostname where genieacs-fs is listening differs
|
file URL for TR-069 Download requests. Set this if genieacs-fs and
|
||||||
from the hostname in the ACS URL.
|
genieacs-cwmp are behind a proxy or running on different servers.
|
||||||
|
|
||||||
Default: the hostname from the ACS URL
|
Default: auto generated based on the hostname from the ACS URL, FS_PORT
|
||||||
|
config, and whether or not SSL is enabled for genieacs-fs.
|
||||||
|
|
||||||
UI_WORKER_PROCESSES
|
UI_WORKER_PROCESSES
|
||||||
The number of worker processes to spawn for genieacs-ui. A value of 0 means
|
The number of worker processes to spawn for genieacs-ui. A value of 0 means
|
||||||
|
|||||||
+15
-2
@@ -32,7 +32,7 @@ while (!existsSync(`${ROOT_DIR}/package.json`)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For compatibility with v1.1
|
// For compatibility with v1.1
|
||||||
let configDir, cwmpSsl, nbiSsl, fsSsl, uiSsl;
|
let configDir, cwmpSsl, nbiSsl, fsSsl, uiSsl, fsHostname;
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
EXT_DIR: { type: "path", default: resolve(ROOT_DIR, "config/ext") },
|
EXT_DIR: { type: "path", default: resolve(ROOT_DIR, "config/ext") },
|
||||||
@@ -62,7 +62,7 @@ const options = {
|
|||||||
FS_INTERFACE: { type: "string", default: "0.0.0.0" },
|
FS_INTERFACE: { type: "string", default: "0.0.0.0" },
|
||||||
FS_SSL_CERT: { type: "string", default: "" },
|
FS_SSL_CERT: { type: "string", default: "" },
|
||||||
FS_SSL_KEY: { type: "string", default: "" },
|
FS_SSL_KEY: { type: "string", default: "" },
|
||||||
FS_HOSTNAME: { type: "string", default: "" },
|
FS_URL_PREFIX: { type: "string", default: "" },
|
||||||
FS_LOG_FILE: { type: "path", default: "" },
|
FS_LOG_FILE: { type: "path", default: "" },
|
||||||
FS_ACCESS_LOG_FILE: { type: "path", default: "" },
|
FS_ACCESS_LOG_FILE: { type: "path", default: "" },
|
||||||
|
|
||||||
@@ -76,6 +76,7 @@ const options = {
|
|||||||
UI_JWT_SECRET: { type: "string", default: "" },
|
UI_JWT_SECRET: { type: "string", default: "" },
|
||||||
|
|
||||||
UDP_CONNECTION_REQUEST_PORT: { type: "int", default: 0 },
|
UDP_CONNECTION_REQUEST_PORT: { type: "int", default: 0 },
|
||||||
|
FORWARDED_HEADER: { type: "string", default: "" },
|
||||||
|
|
||||||
DOWNLOAD_TIMEOUT: { type: "int", default: 3600 },
|
DOWNLOAD_TIMEOUT: { type: "int", default: 3600 },
|
||||||
EXT_TIMEOUT: { type: "int", default: 3000 },
|
EXT_TIMEOUT: { type: "int", default: 3000 },
|
||||||
@@ -143,6 +144,9 @@ function setConfig(name, value, commandLineArgument = false): boolean {
|
|||||||
.trim();
|
.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name === "FS_HOSTNAME" || name === "fs-hostname")
|
||||||
|
fsHostname = fsHostname || String(value).trim();
|
||||||
|
|
||||||
// For compatibility with v1.0
|
// For compatibility with v1.0
|
||||||
if (name === "PRESETS_CACHE_DURATION" || name === "presets-cache-duration")
|
if (name === "PRESETS_CACHE_DURATION" || name === "presets-cache-duration")
|
||||||
setConfig("MAX_CACHE_TTL", value);
|
setConfig("MAX_CACHE_TTL", value);
|
||||||
@@ -260,6 +264,15 @@ if (["true", "1"].includes(uiSsl)) {
|
|||||||
setConfig("UI_SSL_KEY", `${d}/cwmp.key`);
|
setConfig("UI_SSL_KEY", `${d}/cwmp.key`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fsHostname) {
|
||||||
|
const FS_PORT = allConfig["FS_PORT"] || 7567;
|
||||||
|
const FS_SSL = !!allConfig["FS_SSL_CERT"];
|
||||||
|
setConfig(
|
||||||
|
"FS_URL_PREFIX",
|
||||||
|
(FS_SSL ? "https" : "http") + `://${fsHostname}:${FS_PORT}/`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
for (const [k, v] of Object.entries(options))
|
for (const [k, v] of Object.entries(options))
|
||||||
if (v["default"] != null) setConfig(k, v["default"]);
|
if (v["default"] != null) setConfig(k, v["default"]);
|
||||||
|
|||||||
+19
-19
@@ -48,10 +48,10 @@ import {
|
|||||||
import { IncomingMessage, ServerResponse } from "http";
|
import { IncomingMessage, ServerResponse } from "http";
|
||||||
import { Readable } from "stream";
|
import { Readable } from "stream";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
import { TLSSocket } from "tls";
|
|
||||||
import { decode, encodingExists } from "iconv-lite";
|
import { decode, encodingExists } from "iconv-lite";
|
||||||
import { parseXmlDeclaration } from "./xml-parser";
|
import { parseXmlDeclaration } from "./xml-parser";
|
||||||
import * as debug from "./debug";
|
import * as debug from "./debug";
|
||||||
|
import { getRequestOrigin } from "./forwarded";
|
||||||
|
|
||||||
const gzipPromisified = promisify(zlib.gzip);
|
const gzipPromisified = promisify(zlib.gzip);
|
||||||
const deflatePromisified = promisify(zlib.deflate);
|
const deflatePromisified = promisify(zlib.deflate);
|
||||||
@@ -770,18 +770,18 @@ async function sendAcsRequest(
|
|||||||
const downloadRequest = acsRequest as SetAcsRequest;
|
const downloadRequest = acsRequest as SetAcsRequest;
|
||||||
downloadRequest.fileSize = 0;
|
downloadRequest.fileSize = 0;
|
||||||
if (!downloadRequest.url) {
|
if (!downloadRequest.url) {
|
||||||
const FS_PORT = config.get("FS_PORT");
|
let prefix = "" + config.get("FS_URL_PREFIX");
|
||||||
const FS_SSL = config.get("FS_SSL_CERT");
|
|
||||||
let hostname = config.get("FS_HOSTNAME");
|
if (!prefix) {
|
||||||
if (!hostname) {
|
const FS_PORT = +config.get("FS_PORT");
|
||||||
if (sessionContext.httpRequest.headers["host"])
|
const ssl = !!config.get("FS_SSL_CERT");
|
||||||
hostname = sessionContext.httpRequest.headers["host"].split(":")[0];
|
const origin = getRequestOrigin(sessionContext.httpRequest);
|
||||||
else hostname = sessionContext.httpRequest.connection.localAddress;
|
let hostname = origin.localAddress;
|
||||||
|
if (origin.host) [hostname] = origin.host.split(":", 1);
|
||||||
|
prefix = (ssl ? "https" : "http") + `://${hostname}:${FS_PORT}/`;
|
||||||
}
|
}
|
||||||
downloadRequest.url = FS_SSL ? "https://" : "http://";
|
|
||||||
downloadRequest.url += hostname;
|
downloadRequest.url = prefix + encodeURI(downloadRequest.fileName);
|
||||||
if (FS_PORT !== 80) downloadRequest.url += ":" + FS_PORT;
|
|
||||||
downloadRequest.url += "/" + encodeURI(downloadRequest.fileName);
|
|
||||||
|
|
||||||
const files = localCache.getFiles(sessionContext.cacheSnapshot);
|
const files = localCache.getFiles(sessionContext.cacheSnapshot);
|
||||||
if (files[downloadRequest.fileName])
|
if (files[downloadRequest.fileName])
|
||||||
@@ -974,7 +974,7 @@ async function responseUnauthorized(
|
|||||||
|
|
||||||
resHeaders["Connection"] = "close";
|
resHeaders["Connection"] = "close";
|
||||||
} else {
|
} else {
|
||||||
if (sessionContext.httpRequest.socket instanceof TLSSocket) {
|
if (getRequestOrigin(sessionContext.httpRequest).encrypted) {
|
||||||
resHeaders["WWW-Authenticate"] = `Basic realm="${REALM}"`;
|
resHeaders["WWW-Authenticate"] = `Basic realm="${REALM}"`;
|
||||||
} else {
|
} else {
|
||||||
const nonce = crypto.randomBytes(16).toString("hex");
|
const nonce = crypto.randomBytes(16).toString("hex");
|
||||||
@@ -1347,12 +1347,12 @@ async function listenerAsync(
|
|||||||
cacheSnapshot,
|
cacheSnapshot,
|
||||||
"cwmp.debug",
|
"cwmp.debug",
|
||||||
{
|
{
|
||||||
remoteAddress: httpResponse.connection.remoteAddress
|
remoteAddress: getRequestOrigin(httpRequest).remoteAddress
|
||||||
},
|
},
|
||||||
Date.now(),
|
Date.now(),
|
||||||
e => {
|
e => {
|
||||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
||||||
return httpResponse.connection.remoteAddress;
|
return getRequestOrigin(httpRequest).remoteAddress;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1395,12 +1395,12 @@ async function listenerAsync(
|
|||||||
cacheSnapshot,
|
cacheSnapshot,
|
||||||
"cwmp.debug",
|
"cwmp.debug",
|
||||||
{
|
{
|
||||||
remoteAddress: httpResponse.connection.remoteAddress
|
remoteAddress: getRequestOrigin(httpRequest).remoteAddress
|
||||||
},
|
},
|
||||||
Date.now(),
|
Date.now(),
|
||||||
e => {
|
e => {
|
||||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
||||||
return httpResponse.connection.remoteAddress;
|
return getRequestOrigin(httpRequest).remoteAddress;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1429,12 +1429,12 @@ async function listenerAsync(
|
|||||||
cacheSnapshot,
|
cacheSnapshot,
|
||||||
"cwmp.debug",
|
"cwmp.debug",
|
||||||
{
|
{
|
||||||
remoteAddress: httpResponse.connection.remoteAddress
|
remoteAddress: getRequestOrigin(httpRequest).remoteAddress
|
||||||
},
|
},
|
||||||
Date.now(),
|
Date.now(),
|
||||||
e => {
|
e => {
|
||||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
|
||||||
return httpResponse.connection.remoteAddress;
|
return getRequestOrigin(httpRequest).remoteAddress;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2013-2019 GenieACS Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GenieACS.
|
||||||
|
*
|
||||||
|
* GenieACS is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GenieACS is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with GenieACS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { IncomingMessage } from "http";
|
||||||
|
import { TLSSocket } from "tls";
|
||||||
|
import { parseCIDR, parse, IPv6, IPv4 } from "ipaddr.js";
|
||||||
|
import * as config from "./config";
|
||||||
|
|
||||||
|
interface RequestOrigin {
|
||||||
|
localAddress: string;
|
||||||
|
localPort: number;
|
||||||
|
remoteAddress: string;
|
||||||
|
remotePort: number;
|
||||||
|
host: string;
|
||||||
|
encrypted: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FORWARDED_HEADER = "" + config.get("FORWARDED_HEADER");
|
||||||
|
const cache = new WeakMap<IncomingMessage, RequestOrigin>();
|
||||||
|
const cidrs: [IPv4 | IPv6, number][] = [];
|
||||||
|
|
||||||
|
for (const str of FORWARDED_HEADER.split(",").map(s => s.trim())) {
|
||||||
|
try {
|
||||||
|
cidrs.push(parseCIDR(str));
|
||||||
|
} catch (err) {
|
||||||
|
// Not a valid CIDR format, try parsing as IP
|
||||||
|
try {
|
||||||
|
const ip = parse(str);
|
||||||
|
cidrs.push([ip, ip.toByteArray().length * 8]);
|
||||||
|
} catch (err) {
|
||||||
|
// Not a valid IP either, ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseForwardedHeader(str: string): { [name: string]: string } {
|
||||||
|
str = str.toLowerCase();
|
||||||
|
const res: { [name: string]: string } = {};
|
||||||
|
let keyIdx = 0;
|
||||||
|
let valueIdx = -1;
|
||||||
|
let key: string;
|
||||||
|
for (let i = 0; i < str.length; ++i) {
|
||||||
|
const char = str.charCodeAt(i);
|
||||||
|
if (char === 61 /* = */) {
|
||||||
|
if (keyIdx >= 0) {
|
||||||
|
key = str.slice(keyIdx, i).trim();
|
||||||
|
keyIdx = -1;
|
||||||
|
valueIdx = i + 1;
|
||||||
|
}
|
||||||
|
} else if (char === 59 /* ; */) {
|
||||||
|
if (valueIdx >= 0) res[key] = str.slice(valueIdx, i).trim();
|
||||||
|
valueIdx = -1;
|
||||||
|
keyIdx = i + 1;
|
||||||
|
} else if (char === 44 /* , */) {
|
||||||
|
if (valueIdx >= 0) res[key] = str.slice(valueIdx, i).trim();
|
||||||
|
return res;
|
||||||
|
} else if (char === 34 /* " */) {
|
||||||
|
if (valueIdx >= 0) {
|
||||||
|
const quoteIdx = i;
|
||||||
|
if (!str.slice(valueIdx, quoteIdx).trim()) {
|
||||||
|
for (i = i + 1; i < str.length; ++i) {
|
||||||
|
const c = str.charCodeAt(i);
|
||||||
|
if (c === 92 /* \ */) ++i;
|
||||||
|
if (c === 34 /* " */) {
|
||||||
|
res[key] = JSON.parse(str.slice(quoteIdx, i + 1).trim());
|
||||||
|
valueIdx = -1;
|
||||||
|
keyIdx = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueIdx >= 0) res[key] = str.slice(valueIdx).trim();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRequestOrigin(request: IncomingMessage): RequestOrigin {
|
||||||
|
let origin = cache.get(request);
|
||||||
|
if (!origin) {
|
||||||
|
const soc = request.socket;
|
||||||
|
origin = {
|
||||||
|
localAddress: soc.localAddress,
|
||||||
|
localPort: soc.localPort,
|
||||||
|
remoteAddress: soc.remoteAddress,
|
||||||
|
remotePort: soc.remotePort,
|
||||||
|
host: request.headers["host"],
|
||||||
|
encrypted: !!(request.socket as TLSSocket).encrypted
|
||||||
|
};
|
||||||
|
|
||||||
|
// const header = request.headers["forwarded"];
|
||||||
|
const header = 'For="[2001:db8:cafe::17]:4711";proto_=https';
|
||||||
|
if (header) {
|
||||||
|
const ip = parse(soc.remoteAddress) as IPv4;
|
||||||
|
if (cidrs.some(cidr => ip.match(cidr as [IPv4, number]))) {
|
||||||
|
const parsed = parseForwardedHeader(header);
|
||||||
|
|
||||||
|
if (parsed["proto"] === "https") {
|
||||||
|
origin.encrypted = true;
|
||||||
|
origin.localPort = 443;
|
||||||
|
} else if (parsed["proto"] === "http") {
|
||||||
|
origin.encrypted = false;
|
||||||
|
origin.localPort = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsed["host"]) {
|
||||||
|
origin.host = parsed["host"];
|
||||||
|
const [, port] = parsed["host"].split(":", 2);
|
||||||
|
origin.localPort = +port || origin.localPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsed["for"]) {
|
||||||
|
if (parsed["for"].startsWith("[")) {
|
||||||
|
const i = parsed["for"].lastIndexOf("]");
|
||||||
|
if (i >= 0) {
|
||||||
|
origin.remoteAddress = parsed["for"].slice(1, i);
|
||||||
|
origin.remotePort =
|
||||||
|
parseInt(parsed["for"].slice(i + 2)) || origin.remotePort;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const i = parsed["for"].lastIndexOf(":");
|
||||||
|
if (i >= 0) {
|
||||||
|
origin.remoteAddress = parsed["for"].slice(0, i);
|
||||||
|
origin.remotePort =
|
||||||
|
parseInt(parsed["for"].slice(i + 1)) || origin.remotePort;
|
||||||
|
} else {
|
||||||
|
origin.remoteAddress = parsed["for"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsed["by"]) {
|
||||||
|
if (parsed["by"].startsWith("[")) {
|
||||||
|
const i = parsed["by"].lastIndexOf("]");
|
||||||
|
if (i >= 0) {
|
||||||
|
origin.localAddress = parsed["by"].slice(1, i);
|
||||||
|
origin.localPort =
|
||||||
|
parseInt(parsed["by"].slice(i + 2)) || origin.localPort;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const i = parsed["by"].lastIndexOf(":");
|
||||||
|
if (i >= 0) {
|
||||||
|
origin.localAddress = parsed["by"].slice(0, i);
|
||||||
|
origin.localPort =
|
||||||
|
parseInt(parsed["by"].slice(i + 1)) || origin.localPort;
|
||||||
|
} else {
|
||||||
|
origin.localAddress = parsed["by"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.set(request, origin);
|
||||||
|
}
|
||||||
|
return origin;
|
||||||
|
}
|
||||||
@@ -19,11 +19,16 @@
|
|||||||
|
|
||||||
import * as url from "url";
|
import * as url from "url";
|
||||||
import * as querystring from "querystring";
|
import * as querystring from "querystring";
|
||||||
|
import { IncomingMessage, ServerResponse } from "http";
|
||||||
import { GridFSBucket } from "mongodb";
|
import { GridFSBucket } from "mongodb";
|
||||||
import * as db from "./db";
|
import * as db from "./db";
|
||||||
import * as logger from "./logger";
|
import * as logger from "./logger";
|
||||||
|
import { getRequestOrigin } from "./forwarded";
|
||||||
|
|
||||||
export function listener(request, response): void {
|
export function listener(
|
||||||
|
request: IncomingMessage,
|
||||||
|
response: ServerResponse
|
||||||
|
): void {
|
||||||
const urlParts = url.parse(request.url, true);
|
const urlParts = url.parse(request.url, true);
|
||||||
if (request.method === "GET") {
|
if (request.method === "GET") {
|
||||||
const filename = querystring.unescape(urlParts.pathname.substring(1));
|
const filename = querystring.unescape(urlParts.pathname.substring(1));
|
||||||
@@ -31,7 +36,7 @@ export function listener(request, response): void {
|
|||||||
const log = {
|
const log = {
|
||||||
message: "Fetch file",
|
message: "Fetch file",
|
||||||
filename: filename,
|
filename: filename,
|
||||||
remoteAddress: request.connection.remoteAddress
|
remoteAddress: getRequestOrigin(request).remoteAddress
|
||||||
};
|
};
|
||||||
|
|
||||||
db.filesCollection.findOne({ _id: filename }, (err, file) => {
|
db.filesCollection.findOne({ _id: filename }, (err, file) => {
|
||||||
|
|||||||
+5
-3
@@ -21,6 +21,7 @@ import * as fs from "fs";
|
|||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
|
|
||||||
import * as config from "./config";
|
import * as config from "./config";
|
||||||
|
import { getRequestOrigin } from "./forwarded";
|
||||||
|
|
||||||
const REOPEN_EVERY = 60000;
|
const REOPEN_EVERY = 60000;
|
||||||
|
|
||||||
@@ -149,8 +150,9 @@ export function close(): void {
|
|||||||
export function flatten(details): {} {
|
export function flatten(details): {} {
|
||||||
if (details.sessionContext) {
|
if (details.sessionContext) {
|
||||||
details.deviceId = details.sessionContext.deviceId;
|
details.deviceId = details.sessionContext.deviceId;
|
||||||
details.remoteAddress =
|
details.remoteAddress = getRequestOrigin(
|
||||||
details.sessionContext.httpRequest.connection.remoteAddress;
|
details.sessionContext.httpRequest
|
||||||
|
).remoteAddress;
|
||||||
delete details.sessionContext;
|
delete details.sessionContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +200,7 @@ export function flatten(details): {} {
|
|||||||
|
|
||||||
// For genieacs-ui
|
// For genieacs-ui
|
||||||
if (details.context) {
|
if (details.context) {
|
||||||
details.remoteAddress = details.context.request.ip;
|
details.remoteAddress = getRequestOrigin(details.context.req).remoteAddress;
|
||||||
if (details.context.state.user)
|
if (details.context.state.user)
|
||||||
details.user = details.context.state.user.username;
|
details.user = details.context.state.user.username;
|
||||||
delete details.context;
|
delete details.context;
|
||||||
|
|||||||
+3
-2
@@ -50,6 +50,7 @@ import {
|
|||||||
ScriptResult,
|
ScriptResult,
|
||||||
Expression
|
Expression
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
import { getRequestOrigin } from "./forwarded";
|
||||||
|
|
||||||
const VALID_PARAM_TYPES = new Set([
|
const VALID_PARAM_TYPES = new Set([
|
||||||
"xsd:int",
|
"xsd:int",
|
||||||
@@ -119,7 +120,7 @@ export function configContextCallback(
|
|||||||
else if (name === "productClass") name = "DeviceID.ProductClass";
|
else if (name === "productClass") name = "DeviceID.ProductClass";
|
||||||
else if (name === "oui") name = "DeviceID.OUI";
|
else if (name === "oui") name = "DeviceID.OUI";
|
||||||
else if (name === "remoteAddress")
|
else if (name === "remoteAddress")
|
||||||
return sessionContext.httpRequest.connection.remoteAddress;
|
return getRequestOrigin(sessionContext.httpRequest).remoteAddress;
|
||||||
|
|
||||||
const deviceData = sessionContext.deviceData;
|
const deviceData = sessionContext.deviceData;
|
||||||
const paths = deviceData.paths;
|
const paths = deviceData.paths;
|
||||||
@@ -130,7 +131,7 @@ export function configContextCallback(
|
|||||||
}
|
}
|
||||||
} else if (exp[0] === "FUNC") {
|
} else if (exp[0] === "FUNC") {
|
||||||
if (exp[1] === "REMOTE_ADDRESS")
|
if (exp[1] === "REMOTE_ADDRESS")
|
||||||
return sessionContext.httpRequest.connection.remoteAddress;
|
return getRequestOrigin(sessionContext.httpRequest).remoteAddress;
|
||||||
}
|
}
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+5
@@ -4525,6 +4525,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ipaddr.js": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||||
|
},
|
||||||
"irregular-plurals": {
|
"irregular-plurals": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"iconv-lite": "^0.5.0",
|
"iconv-lite": "^0.5.0",
|
||||||
|
"ipaddr.js": "^1.9.1",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"koa": "^2.7.0",
|
"koa": "^2.7.0",
|
||||||
"koa-bodyparser": "^4.2.1",
|
"koa-bodyparser": "^4.2.1",
|
||||||
|
|||||||
Reference in new issue
Block a user