Introduce ESLint and Prettier
This commit is contained in:
1 parent
9c943d0bbf
commit
e494bdca8a
26 files changed
+1585
-1594
No files matched your search
+199
-136
@@ -29,8 +29,7 @@ const auth = require("./auth");
|
||||
const cache = require("./cache");
|
||||
|
||||
function udpConReq(address, un, key, callback) {
|
||||
if (!address)
|
||||
return false;
|
||||
if (!address) return false;
|
||||
|
||||
let [host, port] = address.split(":", 2);
|
||||
|
||||
@@ -38,18 +37,22 @@ function udpConReq(address, un, key, callback) {
|
||||
port = 80;
|
||||
} else {
|
||||
port = parseInt(port);
|
||||
if (isNaN(port))
|
||||
return false;
|
||||
if (isNaN(port)) return false;
|
||||
}
|
||||
|
||||
const ts = Math.trunc(Date.now() / 1000);
|
||||
const id = Math.trunc(Math.random() * 4294967295);
|
||||
const cn = crypto.randomBytes(8).toString("hex");
|
||||
const sig = crypto.createHmac("sha1", key).update(`${ts}${id}${un}${cn}`).digest("hex");
|
||||
const sig = crypto
|
||||
.createHmac("sha1", key)
|
||||
.update(`${ts}${id}${un}${cn}`)
|
||||
.digest("hex");
|
||||
const uri = `http://${address}?ts=${ts}&id=${id}&un=${un}&cn=${cn}&sig=${sig}`;
|
||||
const message = Buffer.from(`GET ${uri} HTTP/1.1\r\nHost: ${address}\r\n\r\n`);
|
||||
const message = Buffer.from(
|
||||
`GET ${uri} HTTP/1.1\r\nHost: ${address}\r\n\r\n`
|
||||
);
|
||||
|
||||
const client = dgram.createSocket({type: "udp4", reuseAddr: true});
|
||||
const client = dgram.createSocket({ type: "udp4", reuseAddr: true });
|
||||
const UDP_CONNECTION_REQUEST_PORT = config.get("UDP_CONNECTION_REQUEST_PORT");
|
||||
|
||||
if (UDP_CONNECTION_REQUEST_PORT)
|
||||
@@ -59,10 +62,10 @@ function udpConReq(address, un, key, callback) {
|
||||
// are allowed to bind to the same address and port. The STUN server needs
|
||||
// to open its UDP port with the SO_REUSEADDR option, allowing the NBI to
|
||||
// also bind to the same port.
|
||||
client.bind({port: UDP_CONNECTION_REQUEST_PORT, exclusive: true});
|
||||
client.bind({ port: UDP_CONNECTION_REQUEST_PORT, exclusive: true });
|
||||
|
||||
let count = 3;
|
||||
const func = (err) => {
|
||||
const func = err => {
|
||||
if (err || --count <= 0) {
|
||||
client.close();
|
||||
return callback(err);
|
||||
@@ -73,11 +76,18 @@ function udpConReq(address, un, key, callback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function httpConReq(url, username, password, allowBasicAuth, timeout, callback) {
|
||||
function httpConReq(
|
||||
url,
|
||||
username,
|
||||
password,
|
||||
allowBasicAuth,
|
||||
timeout,
|
||||
callback
|
||||
) {
|
||||
const options = URL.parse(url);
|
||||
if (options.protocol !== "http:")
|
||||
return callback(new Error("Invalid connection request URL or protocol"));
|
||||
options.agent = new http.Agent({maxSockets: 1});
|
||||
options.agent = new http.Agent({ maxSockets: 1 });
|
||||
|
||||
function statusToError(statusCode) {
|
||||
switch (statusCode) {
|
||||
@@ -93,70 +103,96 @@ function httpConReq(url, username, password, allowBasicAuth, timeout, callback)
|
||||
}
|
||||
}
|
||||
|
||||
const request = http.get(options, (res) => {
|
||||
if (res.statusCode === 401 && res.headers["www-authenticate"]) {
|
||||
const authHeader = auth.parseAuthHeader(res.headers["www-authenticate"]);
|
||||
if (authHeader.method === "Basic") {
|
||||
if (!allowBasicAuth) {
|
||||
request.abort();
|
||||
return callback(new Error("Basic HTTP authentication not allowed"));
|
||||
}
|
||||
options.headers = {
|
||||
"Authorization": auth.basic(username || "", password || "")
|
||||
};
|
||||
} else if (authHeader.method === "Digest") {
|
||||
options.headers = {
|
||||
"Authorization": auth.digest(username || "", password || "", options.path, "GET", null, authHeader)
|
||||
};
|
||||
}
|
||||
|
||||
const request = http.get(options, (res) => {
|
||||
if (res.statusCode === 0) {
|
||||
// Workaround for some devices unexpectedly closing the connection
|
||||
request = http.get(options, (res) => {
|
||||
callback(statusToError(res.statusCode));
|
||||
res.resume();
|
||||
}).on("error", () => {
|
||||
const request = http
|
||||
.get(options, response => {
|
||||
if (response.statusCode === 401 && response.headers["www-authenticate"]) {
|
||||
const authHeader = auth.parseAuthHeader(
|
||||
response.headers["www-authenticate"]
|
||||
);
|
||||
if (authHeader.method === "Basic") {
|
||||
if (!allowBasicAuth) {
|
||||
request.abort();
|
||||
return callback(new Error("Basic HTTP authentication not allowed"));
|
||||
}
|
||||
options.headers = {
|
||||
Authorization: auth.basic(username || "", password || "")
|
||||
};
|
||||
} else if (authHeader.method === "Digest") {
|
||||
options.headers = {
|
||||
Authorization: auth.digest(
|
||||
username || "",
|
||||
password || "",
|
||||
options.path,
|
||||
"GET",
|
||||
null,
|
||||
authHeader
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
const req = http
|
||||
.get(options, res => {
|
||||
if (res.statusCode === 0) {
|
||||
// Workaround for some devices unexpectedly closing the connection
|
||||
let req2;
|
||||
req2 = http
|
||||
.get(options, res2 => {
|
||||
callback(statusToError(res2.statusCode));
|
||||
res2.resume();
|
||||
})
|
||||
.on("error", () => {
|
||||
req2.abort();
|
||||
callback(statusToError(0));
|
||||
})
|
||||
.on("socket", socket => {
|
||||
socket.setTimeout(timeout);
|
||||
socket.on("timeout", () => {
|
||||
req2.abort();
|
||||
});
|
||||
});
|
||||
req2();
|
||||
} else {
|
||||
callback(statusToError(res.statusCode));
|
||||
}
|
||||
res.resume();
|
||||
})
|
||||
.on("error", () => {
|
||||
req.abort();
|
||||
callback(statusToError(0));
|
||||
}).on("socket", (socket) => {
|
||||
})
|
||||
.on("socket", socket => {
|
||||
socket.setTimeout(timeout);
|
||||
socket.on("timeout", () => {
|
||||
request.abort();
|
||||
req.abort();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
callback(statusToError(res.statusCode));
|
||||
}
|
||||
res.resume();
|
||||
}).on("error", () => {
|
||||
request.abort();
|
||||
callback(statusToError(0));
|
||||
}).on("socket", (socket) => {
|
||||
socket.setTimeout(timeout);
|
||||
socket.on("timeout", () => {
|
||||
request.abort();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
callback(statusToError(res.statusCode));
|
||||
}
|
||||
// No listener for data so emit resume
|
||||
res.resume();
|
||||
}).on("error", (err) => {
|
||||
request.abort();
|
||||
callback(statusToError(0));
|
||||
}).on("socket", (socket) => {
|
||||
socket.setTimeout(timeout);
|
||||
socket.on("timeout", () => {
|
||||
} else {
|
||||
callback(statusToError(response.statusCode));
|
||||
}
|
||||
// No listener for data so emit resume
|
||||
response.resume();
|
||||
})
|
||||
.on("error", () => {
|
||||
request.abort();
|
||||
callback(statusToError(0));
|
||||
})
|
||||
.on("socket", socket => {
|
||||
socket.setTimeout(timeout);
|
||||
socket.on("timeout", () => {
|
||||
request.abort();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function connectionRequest(deviceId, callback) {
|
||||
const CONNECTION_REQUEST_TIMEOUT = config.get("CONNECTION_REQUEST_TIMEOUT", deviceId);
|
||||
const CONNECTION_REQUEST_ALLOW_BASIC_AUTH = config.get("CONNECTION_REQUEST_ALLOW_BASIC_AUTH", deviceId);
|
||||
const CONNECTION_REQUEST_TIMEOUT = config.get(
|
||||
"CONNECTION_REQUEST_TIMEOUT",
|
||||
deviceId
|
||||
);
|
||||
const CONNECTION_REQUEST_ALLOW_BASIC_AUTH = config.get(
|
||||
"CONNECTION_REQUEST_ALLOW_BASIC_AUTH",
|
||||
deviceId
|
||||
);
|
||||
const proj = {
|
||||
"Device.ManagementServer.ConnectionRequestURL._value": 1,
|
||||
"Device.ManagementServer.UDPConnectionRequestAddress._value": 1,
|
||||
@@ -168,46 +204,74 @@ function connectionRequest(deviceId, callback) {
|
||||
"InternetGatewayDevice.ManagementServer.ConnectionRequestPassword._value": 1
|
||||
};
|
||||
|
||||
db.devicesCollection.findOne({_id: deviceId}, proj, (err, device) => {
|
||||
if (err)
|
||||
return callback(err);
|
||||
db.devicesCollection.findOne({ _id: deviceId }, proj, (err, device) => {
|
||||
if (err) return callback(err);
|
||||
|
||||
let managementServer, connectionRequestUrl, udpConnectionRequestAddress, username, password;
|
||||
if (device.Device) // TR-181 data model
|
||||
let managementServer,
|
||||
connectionRequestUrl,
|
||||
udpConnectionRequestAddress,
|
||||
username,
|
||||
password;
|
||||
if (device.Device)
|
||||
// TR-181 data model
|
||||
managementServer = device.Device.ManagementServer;
|
||||
else // TR-098 data model
|
||||
managementServer = device.InternetGatewayDevice.ManagementServer;
|
||||
// TR-098 data model
|
||||
else managementServer = device.InternetGatewayDevice.ManagementServer;
|
||||
|
||||
connectionRequestUrl = managementServer.ConnectionRequestURL._value;
|
||||
if (managementServer.UDPConnectionRequestAddress)
|
||||
udpConnectionRequestAddress = managementServer.UDPConnectionRequestAddress._value;
|
||||
if (managementServer.UDPConnectionRequestAddress) {
|
||||
udpConnectionRequestAddress =
|
||||
managementServer.UDPConnectionRequestAddress._value;
|
||||
}
|
||||
if (managementServer.ConnectionRequestUsername)
|
||||
username = managementServer.ConnectionRequestUsername._value;
|
||||
if (managementServer.ConnectionRequestPassword)
|
||||
password = managementServer.ConnectionRequestPassword._value;
|
||||
|
||||
const conReq = () => {
|
||||
const udpSent = udpConReq(udpConnectionRequestAddress, username, password, (err) => {
|
||||
if (err)
|
||||
throw err;
|
||||
});
|
||||
const udpSent = udpConReq(
|
||||
udpConnectionRequestAddress,
|
||||
username,
|
||||
password,
|
||||
err => {
|
||||
if (err) throw err;
|
||||
}
|
||||
);
|
||||
|
||||
httpConReq(connectionRequestUrl, username, password, CONNECTION_REQUEST_ALLOW_BASIC_AUTH, CONNECTION_REQUEST_TIMEOUT, (err) => {
|
||||
if (udpSent)
|
||||
return callback();
|
||||
callback(err);
|
||||
});
|
||||
httpConReq(
|
||||
connectionRequestUrl,
|
||||
username,
|
||||
password,
|
||||
CONNECTION_REQUEST_ALLOW_BASIC_AUTH,
|
||||
CONNECTION_REQUEST_TIMEOUT,
|
||||
err => {
|
||||
if (udpSent) return callback();
|
||||
callback(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (config.auth && config.auth.connectionRequest) {
|
||||
// Callback is optional for backward compatibility
|
||||
if (config.auth.connectionRequest.length > 4)
|
||||
return config.auth.connectionRequest(deviceId, connectionRequestUrl, username, password, (u, p) => {
|
||||
username = u;
|
||||
password = p;
|
||||
conReq();
|
||||
});
|
||||
[username, password] = config.auth.connectionRequest(deviceId, connectionRequestUrl, username, password);
|
||||
if (config.auth.connectionRequest.length > 4) {
|
||||
return config.auth.connectionRequest(
|
||||
deviceId,
|
||||
connectionRequestUrl,
|
||||
username,
|
||||
password,
|
||||
(u, p) => {
|
||||
username = u;
|
||||
password = p;
|
||||
conReq();
|
||||
}
|
||||
);
|
||||
}
|
||||
[username, password] = config.auth.connectionRequest(
|
||||
deviceId,
|
||||
connectionRequestUrl,
|
||||
username,
|
||||
password
|
||||
);
|
||||
}
|
||||
conReq();
|
||||
});
|
||||
@@ -215,23 +279,18 @@ function connectionRequest(deviceId, callback) {
|
||||
|
||||
function watchTask(deviceId, taskId, timeout, callback) {
|
||||
setTimeout(() => {
|
||||
db.tasksCollection.findOne({_id: taskId}, {_id: 1}, (err, task) => {
|
||||
if (err)
|
||||
return callback(err);
|
||||
db.tasksCollection.findOne({ _id: taskId }, { _id: 1 }, (err, task) => {
|
||||
if (err) return callback(err);
|
||||
|
||||
if (!task)
|
||||
return callback(null, "completed");
|
||||
if (!task) return callback(null, "completed");
|
||||
|
||||
const q = {_id: `${deviceId}:task_${taskId}`};
|
||||
db.faultsCollection.findOne(q, {_id: 1}, (err, fault) => {
|
||||
if (err)
|
||||
return callback(err);
|
||||
const q = { _id: `${deviceId}:task_${taskId}` };
|
||||
db.faultsCollection.findOne(q, { _id: 1 }, (err, fault) => {
|
||||
if (err) return callback(err);
|
||||
|
||||
if (fault)
|
||||
return callback(null, "fault");
|
||||
if (fault) return callback(null, "fault");
|
||||
|
||||
if ((timeout -= 500) <= 0)
|
||||
return callback(null, "timeout");
|
||||
if ((timeout -= 500) <= 0) return callback(null, "timeout");
|
||||
|
||||
watchTask(deviceId, taskId, timeout, callback);
|
||||
});
|
||||
@@ -244,53 +303,57 @@ function sanitizeTask(task, callback) {
|
||||
if (task.expiry) {
|
||||
if (common.typeOf(task.expiry) === common.DATE_TYPE || isNaN(task.expiry))
|
||||
task.expiry = new Date(task.expiry);
|
||||
else
|
||||
task.expiry = new Date(task.timestamp.getTime() + +task.expiry * 1000);
|
||||
else task.expiry = new Date(task.timestamp.getTime() + +task.expiry * 1000);
|
||||
}
|
||||
|
||||
callback(task);
|
||||
}
|
||||
|
||||
function insertTasks(tasks, callback) {
|
||||
if (tasks && common.typeOf(tasks) !== common.ARRAY_TYPE)
|
||||
tasks = [tasks];
|
||||
else if (!tasks || tasks.length === 0)
|
||||
return callback(null, tasks || []);
|
||||
if (tasks && common.typeOf(tasks) !== common.ARRAY_TYPE) tasks = [tasks];
|
||||
else if (!tasks || tasks.length === 0) return callback(null, tasks || []);
|
||||
|
||||
let counter = tasks.length;
|
||||
for (let task of tasks)
|
||||
sanitizeTask(task, (t) => {
|
||||
if (t.uniqueKey)
|
||||
db.tasksCollection.remove({device: t.device, uniqueKey: t.uniqueKey}, () => {});
|
||||
for (let task of tasks) {
|
||||
sanitizeTask(task, t => {
|
||||
if (t.uniqueKey) {
|
||||
db.tasksCollection.remove(
|
||||
{ device: t.device, uniqueKey: t.uniqueKey },
|
||||
() => {}
|
||||
);
|
||||
}
|
||||
|
||||
if (--counter === 0)
|
||||
db.tasksCollection.insert(tasks, callback);
|
||||
if (--counter === 0) db.tasksCollection.insert(tasks, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deleteDevice(deviceId, callback) {
|
||||
db.tasksCollection.remove({"device": deviceId}, (err) => {
|
||||
if (err)
|
||||
return callback(err);
|
||||
db.devicesCollection.remove({"_id": deviceId}, (err) => {
|
||||
if (err)
|
||||
return callback(err);
|
||||
db.faultsCollection.remove({
|
||||
"_id": {
|
||||
"$regex": `^${common.escapeRegExp(deviceId)}\\:`
|
||||
}
|
||||
}, (err) => {
|
||||
if (err)
|
||||
return callback(err);
|
||||
db.operationsCollection.remove({
|
||||
"_id": {
|
||||
"$regex": `^${common.escapeRegExp(deviceId)}\\:`
|
||||
db.tasksCollection.remove({ device: deviceId }, err => {
|
||||
if (err) return callback(err);
|
||||
db.devicesCollection.remove({ _id: deviceId }, err => {
|
||||
if (err) return callback(err);
|
||||
db.faultsCollection.remove(
|
||||
{
|
||||
_id: {
|
||||
$regex: `^${common.escapeRegExp(deviceId)}\\:`
|
||||
}
|
||||
}, (err) => {
|
||||
if (err)
|
||||
return callback(err);
|
||||
cache.del(`${deviceId}_tasks_faults_operations`, callback);
|
||||
});
|
||||
});
|
||||
},
|
||||
err => {
|
||||
if (err) return callback(err);
|
||||
db.operationsCollection.remove(
|
||||
{
|
||||
_id: {
|
||||
$regex: `^${common.escapeRegExp(deviceId)}\\:`
|
||||
}
|
||||
},
|
||||
err => {
|
||||
if (err) return callback(err);
|
||||
cache.del(`${deviceId}_tasks_faults_operations`, callback);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user