zero-ui/backend/services/member.js

196 lines
4.8 KiB
JavaScript

const _ = require("lodash");
const axios = require("axios");
const api = require("../utils/controller-api");
const db = require("../utils/db");
const getZTAddress = require("../utils/zt-address");
let ZT_ADDRESS = null;
getZTAddress().then(function (address) {
ZT_ADDRESS = address;
});
async function getPeer(mid) {
try {
const peer = await api.get("peer/" + mid);
return peer.data;
} catch (err) {
return;
}
}
async function getMemberAdditionalData(data) {
// DB BUG INITIALIZATION MIGRATION
const network = db.get("networks").find({ id: data.nwid });
network.defaults({ members: [] }).get("members").write();
// END MIGRATION SECTION
const member = db
.get("networks")
.find({ id: data.nwid })
.get("members")
.find({ id: data.id });
const additionalData = member.get("additionalConfig").value() || {};
const lastOnline = member.get("lastOnline").value() || 0;
const peer = await getPeer(data.id);
let peerData = {};
if (peer && !_.isEmpty(peer)) {
peerData.latency = peer.latency;
if (peer.latency !== -1) peerData.online = 1;
if (peer.latency == -1) peerData.online = 2;
peerData.clientVersion = peer.version;
if (peer.paths.length > 0) {
let path = peer.paths.filter((p) => {
let ret = p.active && !p.expired;
if (typeof p.preferred !== "undefined") {
ret = ret && p.preferred;
}
return ret;
});
if (path.length > 0) {
peerData.lastOnline = path[0].lastReceive;
peerData.physicalAddress = path[0].address.split("/")[0];
peerData.physicalPort = path[0].address.split("/")[1];
}
}
} else {
peerData.online = 0;
}
delete data.lastAuthorizedCredential;
delete data.lastAuthorizedCredentialType;
delete data.objtype;
delete data.remoteTraceLevel;
delete data.remoteTraceTarget;
return {
id: data.nwid + "-" + data.id,
clock: new Date().getTime(),
networkId: data.nwid,
nodeId: data.id,
controllerId: ZT_ADDRESS,
// @ts-ignore
lastOnline: lastOnline,
...additionalData,
...peerData,
config: data,
};
}
async function filterDeleted(nwid, mid) {
const member = db
.get("networks")
.find({ id: nwid })
.get("members")
.find({ id: mid });
let deleted = member.get("deleted").value() || false;
if (!deleted) return mid;
else return;
}
exports.getMembersData = getMembersData;
async function getMembersData(nwid, mids) {
const prefix = "/controller/network/" + nwid + "/member/";
const filtered = (
await Promise.all(mids.map(async (mid) => await filterDeleted(nwid, mid)))
).filter((item) => item !== undefined);
const links = filtered.map((mid) => prefix + mid);
const multipleRes = await axios
.all(links.map((l) => api.get(l)))
.then(
axios.spread(function (...res) {
return res;
})
)
.catch(function (err) {
return [];
});
let data = Promise.all(
multipleRes.map((el) => {
return getMemberAdditionalData(el.data);
})
);
return data;
}
exports.updateMemberAdditionalData = updateMemberAdditionalData;
async function updateMemberAdditionalData(nwid, mid, data) {
if (data.config && data.config.authorized) {
db.get("networks")
.filter({ id: nwid })
.map("members")
.first()
.filter({ id: mid })
.first()
.set("deleted", false)
.write();
}
let additionalData = {};
if (data.hasOwnProperty("name")) {
additionalData.name = data.name;
}
if (data.hasOwnProperty("description")) {
additionalData.description = data.description;
}
if (additionalData) {
const member = db
.get("networks")
.filter({ id: nwid })
.map("members")
.first()
.filter({ id: mid });
if (member.value().length) {
member
.map("additionalConfig")
.map((additionalConfig) => _.assign(additionalConfig, additionalData))
.write();
} else {
additionalData = { name: "", description: "" };
if (data.hasOwnProperty("name")) {
additionalData.name = data.name;
}
if (data.hasOwnProperty("description")) {
additionalData.description = data.description;
}
db.get("networks")
.filter({ id: nwid })
.map("members")
.first()
.push({ id: mid, additionalConfig: additionalData })
.write();
}
}
}
exports.deleteMemberAdditionalData = deleteMemberAdditionalData;
async function deleteMemberAdditionalData(nwid, mid) {
// ZT controller bug
/* db.get("networks")
.find({ id: nwid })
.get("members")
.remove({ id: mid })
.write();
*/
await updateMemberAdditionalData(nwid, mid, {});
db.get("networks")
.filter({ id: nwid })
.map("members")
.first()
.filter({ id: mid })
.first()
.set("deleted", true)
.write();
}