Improved events and reports.
Ylian Saint-Hilaire committed
Sep 12, 2021 at 13:03 UTC
663d1fb7223d483e93003b5a914787add360841b
3 files changed
+55
-13
meshdesktopmultiplex.js
+41
-3
@@ -186,11 +186,12 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
186
if (obj.viewers == null) return;
187
if (peer == obj.agent) {
188
//console.log('removePeer-agent', obj.nodeid);
189
+ // Agent has disconnected, disconnect everyone.
190
+ if (obj.viewers != null) { for (var i in obj.viewers) { obj.viewers[i].close(); } }
191
+
192
// Clean up the agent
193
obj.agent = null;
194
192
- // Agent has disconnected, disconnect everyone.
193
- if (obj.viewers != null) { for (var i in obj.viewers) { obj.viewers[i].close(); } }
195
dispose();
196
return true;
197
} else {
@@ -211,9 +212,46 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
212
213
// Log leaving the multiplex session
214
if (obj.startTime != null) { // Used to check if the agent has connected. If not, don't log this event since the session never really started.
215
+ // In this code, we want to compute the share of in/out traffic that belongs to this viewer. It includes all of the viewers in/out traffic + all or a portion of the agents in/out traffic.
216
+ // The agent traffic needs to get divided out between the viewers fairly. For the time that multiple viewers are present, the agent traffic is divided between the viewers.
217
+
218
+ // Compute traffic to and from the browser
219
+ var inTraffc, outTraffc;
220
+ try { inTraffc = peer.ws._socket.bytesRead; } catch (ex) { }
221
+ try { outTraffc = peer.ws._socket.bytesWritten; } catch (ex) { }
222
+
223
+ // Add any previous agent traffic accounting
224
+ if (peer.agentInTraffic) { inTraffc += peer.agentInTraffic; }
225
+ if (peer.outTraffc) { inTraffc += peer.agentOutTraffic; }
226
+
227
+ // Compute traffic to and from the agent
228
+ if (obj.agent != null) {
229
+ // Get unaccounted bytes from/to the agent
230
+ var agentInTraffc, agentOutTraffc, agentInTraffc2, agentOutTraffc2;
231
+ try { agentInTraffc = agentInTraffc2 = obj.agent.ws._socket.bytesRead; } catch (ex) { }
232
+ try { agentOutTraffc = agentOutTraffc2 = obj.agent.ws._socket.bytesWritten; } catch (ex) { }
233
+ if (obj.agent.accountedBytesRead) { agentInTraffc -= obj.agent.accountedBytesRead; }
234
+ if (obj.agent.accountedBytesWritten) { agentOutTraffc -= obj.agent.accountedBytesWritten; }
235
+ obj.agent.accountedBytesRead = agentInTraffc2;
236
+ obj.agent.accountedBytesWritten = agentOutTraffc2;
237
+
238
+ // Devide up the agent traffic amoung the viewers
239
+ var viewerPartIn = Math.floor(agentInTraffc / (obj.viewers.length + 1));
240
+ var viewerPartOut = Math.floor(agentOutTraffc / (obj.viewers.length + 1));
241
+
242
+ // Add the portion to this viewer and all other viewer
243
+ inTraffc += viewerPartIn;
244
+ outTraffc += viewerPartOut;
245
+ for (var i in obj.viewers) {
246
+ if (obj.viewers[i].agentInTraffic) { obj.viewers[i].agentInTraffic += viewerPartIn; } else { obj.viewers[i].agentInTraffic = viewerPartIn; }
247
+ if (obj.viewers[i].agentOutTraffic) { obj.viewers[i].agentOutTraffic += viewerPartOut; } else { obj.viewers[i].agentOutTraffic = viewerPartOut; }
248
+ }
249
+ }
250
+
251
//var event = { etype: 'relay', action: 'relaylog', domain: domain.id, nodeid: obj.nodeid, userid: peer.user._id, username: peer.user.name, msgid: 5, msg: "Left the desktop multiplex session", protocol: 2 };
252
const sessionSeconds = Math.floor((Date.now() - peer.startTime) / 1000);
216
- var event = { etype: 'relay', action: 'relaylog', domain: domain.id, nodeid: obj.nodeid, userid: peer.user._id, username: peer.user.name, msgid: 122, msgArgs: [sessionSeconds], msg: "Left the desktop multiplex session after " + sessionSeconds + " second(s).", protocol: 2 };
253
+ var event = { etype: 'relay', action: 'relaylog', domain: domain.id, nodeid: obj.nodeid, userid: peer.user._id, username: peer.user.name, msgid: 122, msgArgs: [sessionSeconds], msg: "Left the desktop multiplex session after " + sessionSeconds + " second(s).", protocol: 2, bytesin: inTraffc, bytesout: outTraffc };
254
+ if (peer.guestName) { event.guestname = peer.guestName; }
255
parent.parent.DispatchEvent(['*', obj.nodeid, peer.user._id, obj.meshid], obj, event);
256
}
257
meshuser.js
+10
-7
@@ -4694,8 +4694,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4694
expireTime = command.end * 1000;
4695
}
4696
4697
- //var cookie = { a: 5, p: command.p, uid: user._id, gn: command.guestname, nid: node._id, cf: command.consent, pid: publicid };
4698
- var cookie = { a: 6, pid: publicid };
4697
+ //var cookie = { a: 5, p: command.p, uid: user._id, gn: command.guestname, nid: node._id, cf: command.consent, pid: publicid }; // Old style sharing cookie
4698
+ var cookie = { a: 6, pid: publicid }; // New style sharing cookie
4699
if ((startTime != null) && (expireTime != null)) { command.start = startTime; command.expire = cookie.e = expireTime; }
4700
const inviteCookie = parent.parent.encodeCookie(cookie, parent.parent.invitationLinkEncryptionKey);
4701
if (inviteCookie == null) { if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'createDeviceShareLink', responseid: command.responseid, result: 'Unable to generate shareing cookie' })); } catch (ex) { } } return; }
@@ -5475,20 +5475,23 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5475
// Columns
5476
if (command.groupBy == 1) {
5477
data.groupFormat = 'user';
5478
- data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5478
+ data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5479
} else if (command.groupBy == 2) {
5480
data.groupFormat = 'node';
5481
- data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'userid', title: "user", format: 'user' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5481
+ data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'userid', title: "user", format: 'user' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5482
} else if (command.groupBy == 3) {
5483
- data.columns = [{ id: 'time', title: "time", format: 'time' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'userid', title: "user", format: 'user' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5483
+ data.columns = [{ id: 'time', title: "time", format: 'time' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'userid', title: "user", format: 'user' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5484
}
5485
5486
- // Add traffic colums
5486
+ // Add traffic columns
5487
if (command.showTraffic) {
5488
data.columns.push({ id: 'bytesin', title: "bytesin", format: 'bytes', align: 'center', sumBy: 'protocol' });
5489
data.columns.push({ id: 'bytesout', title: "bytesout", format: 'bytes', align: 'center', sumBy: 'protocol' });
5490
}
5491
5492
+ // Remote guest column is not needed
5493
+ if (!command.showGuestName) { data.columns.splice(2, 1); }
5494
+
5495
// Rows
5496
for (var i in docs) {
5497
// If MySQL or MariaDB query, we can't filter on MsgID, so we have to do it here.
@@ -5506,7 +5509,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5509
if (command.showTraffic) { entry.bytesin = docs[i].bytesin; entry.bytesout = docs[i].bytesout; }
5510
5511
// Add guest name if present
5509
- if (docs[i].nodeid.guestname != null) { entry.guestname = docs[i].nodeid.guestname; }
5512
+ if (docs[i].guestname != null) { entry.guestname = docs[i].guestname; }
5513
5514
// Session length
5515
if (((docs[i].msgid >= 10) && (docs[i].msgid <= 12)) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[3] == 'number')) { entry.length = docs[i].msgArgs[3]; }
views/default.handlebars
+4
-3
@@ -14951,6 +14951,7 @@
14951
14952
x += '<div id=d2showTrafficDiv style=display:none>';
14953
x += addHtmlValue("", '<div style=width:250px><label><input type=checkbox id=d2showTraffic ' + ((settings.showTraffic) ? 'checked' : '') + '>' + "Show Traffic" + '</label><div>');
14954
+ x += addHtmlValue("", '<div style=width:250px><label><input type=checkbox id=d2showGuestName ' + ((settings.showGuestName) ? 'checked' : '') + '>' + "Show Guest Name" + '</label><div>');
14955
x += '</div>';
14956
14957
setDialogMode(2, "Generate Report", 3, generateReportDialogEx, x);
@@ -14981,12 +14982,12 @@
14982
try { tz = Intl.DateTimeFormat().resolvedOptions().timeZone; } catch (ex) {}
14983
var devGroup = decodeURIComponent(Q('d2groupId').value);
14984
if (devGroup == 0) { devGroup = null; }
14984
- putstore('_ReportSettings', JSON.stringify({ type: parseInt(Q('d2reportType').value), groupBy: parseInt(Q('d2groupBy').value), timeRange: parseInt(Q('d2timeRange').value), devGroup: devGroup, showTraffic: Q('d2showTraffic').checked }));
14985
- meshserver.send({ action: 'report', type: parseInt(Q('d2reportType').value), groupBy: parseInt(Q('d2groupBy').value), start: start, end: end, tz: tz, tf: new Date().getTimezoneOffset(), l: getLang(), devGroup: devGroup, showTraffic: Q('d2showTraffic').checked });
14985
+ putstore('_ReportSettings', JSON.stringify({ type: parseInt(Q('d2reportType').value), groupBy: parseInt(Q('d2groupBy').value), timeRange: parseInt(Q('d2timeRange').value), devGroup: devGroup, showTraffic: Q('d2showTraffic').checked, showGuestName: Q('d2showGuestName').checked }));
14986
+ meshserver.send({ action: 'report', type: parseInt(Q('d2reportType').value), groupBy: parseInt(Q('d2groupBy').value), start: start, end: end, tz: tz, tf: new Date().getTimezoneOffset(), l: getLang(), devGroup: devGroup, showTraffic: Q('d2showTraffic').checked, showGuestName: Q('d2showGuestName').checked });
14987
}
14988
14989
function renderReport(r) {
14989
- var colTranslation = { time: "Time", device: "Device", session: "Session", user: "User", length: "Length", bytesin: "Bytes In", bytesout: "Bytes Out" }
14990
+ var colTranslation = { time: "Time", device: "Device", session: "Session", user: "User", guest: "Guest", length: "Length", bytesin: "Bytes In", bytesout: "Bytes Out" }
14991
var x = '<table style=width:100%>', firstItem;
14992
var sumByCol = null; // Indicate by what colum we sum by
14993
var sumByValues = []; // Indicate by what values we sum by