Added selective session recording.

Ylian Saint-Hilaire committed Sep 29, 2020 at 15:02 UTC 7b71c0488fb8287f13883f9b77747f6778f4416b
6 files changed +25 -1
meshcentral-config-schema.json
+1
@@ -309,6 +309,7 @@
309 "type": "object",
310 "additionalProperties": false,
311 "properties": {
312 + "onlySelectedDeviceGroups": { "type": "boolean", "default": false, "description": "When enabled, only device groups with the session recording feature turned on will be recorded. When false, all devices are recorded." },
313 "filepath": { "type": "string" },
314 "index": { "type": "boolean", "default": false },
315 "maxRecordings": { "type": "integer" },
meshdesktopmultiplex.js
+7
@@ -683,6 +683,13 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
683 function recordingSetup(domain, func) {
684 // Setup session recording
685 if ((domain.sessionrecording == true || ((typeof domain.sessionrecording == 'object') && ((domain.sessionrecording.protocols == null) || (domain.sessionrecording.protocols.indexOf(2) >= 0))))) {
686 +
687 + // Check again to make sure we need to start recording
688 + if (domain.sessionrecording.onlyselecteddevicegroups === true) {
689 + var mesh = parent.meshes[obj.meshid];
690 + if ((mesh.flags == null) || ((mesh.flags & 4) == 0)) { func(false); return; } // Do not record the session
691 + }
692 +
693 var now = new Date(Date.now());
694 var recFilename = 'desktopSession' + ((domain.id == '') ? '' : '-') + domain.id + '-' + now.getUTCFullYear() + '-' + parent.common.zeroPad(now.getUTCMonth(), 2) + '-' + parent.common.zeroPad(now.getUTCDate(), 2) + '-' + parent.common.zeroPad(now.getUTCHours(), 2) + '-' + parent.common.zeroPad(now.getUTCMinutes(), 2) + '-' + parent.common.zeroPad(now.getUTCSeconds(), 2) + '-' + obj.nodeid.split('/')[2] + '.mcrec'
695 var recFullFilename = null;
meshrelay.js
+12 -1
@@ -232,7 +232,18 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
232 parent.db.Get(obj.req.query.nodeid, function (err, nodes) {
233 var xusername = '', xdevicename = '', xdevicename2 = null, node = null;
234 if ((nodes != null) && (nodes.length == 1)) { node = nodes[0]; xdevicename2 = node.name; xdevicename = '-' + parent.common.makeFilename(node.name); }
235 -
235 +
236 + // Check again if we need to do recording
237 + if (domain.sessionrecording.onlyselecteddevicegroups === true) {
238 + var mesh = parent.meshes[node.meshid];
239 + if ((mesh.flags == null) || ((mesh.flags & 4) == 0)) {
240 + // Do not record the session, just send session start
241 + try { ws.send('c'); } catch (ex) { } // Send connect to both peers
242 + try { relayinfo.peer1.ws.send('c'); } catch (ex) { }
243 + return;
244 + }
245 + }
246 +
247 // Get the username and make it acceptable as a filename
248 if (sessionUser._id) { xusername = '-' + parent.common.makeFilename(sessionUser._id.split('/')[2]); }
249
meshuser.js
+1
@@ -421,6 +421,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
421 serverinfo.maxGuestSessionSharingTime = (typeof domain.maxguestsessionsharingtime == 'number') ? domain.maxguestsessionsharingtime : 60;
422 serverinfo.languages = parent.renderLanguages;
423 serverinfo.tlshash = Buffer.from(parent.webCertificateHashs[domain.id], 'binary').toString('hex').toUpperCase(); // SHA384 of server HTTPS certificate
424 + if ((domain.sessionrecording) && (domain.sessionrecording.onlyselecteddevicegroups === true)) { serverinfo.devGroupSessionRecording = 1; } // Allow enabling of session recording
425 if ((parent.parent.config.domains[domain.id].amtacmactivation != null) && (parent.parent.config.domains[domain.id].amtacmactivation.acmmatch != null)) {
426 var matchingDomains = [];
427 for (var i in parent.parent.config.domains[domain.id].amtacmactivation.acmmatch) {
sample-config-advanced.json
+1
@@ -226,6 +226,7 @@
226 },
227 "_agentConfig": [ "webSocketMaskOverride=1", "coreDumpEnabled=1" ],
228 "_sessionRecording": {
229 + "_onlySelectedDeviceGroups": true,
230 "_filepath": "C:\\temp",
231 "_index": true,
232 "_maxRecordings": 10,
views/default.handlebars
+3
@@ -9321,6 +9321,7 @@
9321 if (currentMesh.flags) {
9322 if (currentMesh.flags & 1) { meshFeatures.push("Auto-Remove"); }
9323 if (currentMesh.flags & 2) { meshFeatures.push("Hostname Sync"); }
9324 + if ((serverinfo.devGroupSessionRecording == 1) && (currentMesh.flags & 4)) { meshFeatures.push("Record Sessions"); }
9325 }
9326 meshFeatures = meshFeatures.join(', ');
9327 if (meshFeatures == '') { meshFeatures = '<i>' + "None" + '</i>'; }
@@ -9620,6 +9621,7 @@
9621 var flags = (currentMesh.flags)?currentMesh.flags:0;
9622 var x = '<div><label><input type=checkbox id=d20flag1 ' + ((flags & 1) ? 'checked' : '') + '>' + "Remove device on disconnect" + '</label><br></div>';
9623 x += '<div><label><input type=checkbox id=d20flag2 ' + ((flags & 2) ? 'checked' : '') + '>' + "Sync server device name to hostname" + '</label><br></div>';
9624 + if (serverinfo.devGroupSessionRecording == 1) { x += '<div><label><input type=checkbox id=d20flag4 ' + ((flags & 4) ? 'checked' : '') + '>' + "Record sessions" + '</label><br></div>'; }
9625 setDialogMode(2, "Edit Device Group Features", 3, p20editmeshfeaturesEx, x);
9626 }
9627
@@ -9627,6 +9629,7 @@
9629 var flags = 0;
9630 if (Q('d20flag1').checked) { flags += 1; }
9631 if (Q('d20flag2').checked) { flags += 2; }
9632 + if (serverinfo.devGroupSessionRecording == 1) { if (Q('d20flag4').checked) { flags += 4; } }
9633 meshserver.send({ action: 'editmesh', meshid: currentMesh._id, flags: flags });
9634 }
9635