Added file context menu for device files.

This commit is contained in:
Ylian Saint-Hilaire 2020-02-14 11:20:06 -08:00
parent cc64467df7
commit c6bd8c3a19
9 changed files with 2208 additions and 1695 deletions

View File

@ -803,7 +803,7 @@ module.exports.CertificateOperations = function (parent) {
accelerator.accid = acceleratorCreateCount;
accelerator.on('message', function (message) {
acceleratorMessage++;
this.x.func(this.x.tag, message);
if (this.x.func) { this.x.func(this.x.tag, message); }
delete this.x;
if (pendingAccelerator.length > 0) { this.send(this.x = pendingAccelerator.shift()); } else { freeAccelerators.push(this); }
});
@ -850,5 +850,24 @@ module.exports.CertificateOperations = function (parent) {
}
};
// Perform any general operation
obj.acceleratorPerformOperation = function (operation, data, tag, func) {
if (acceleratorTotalCount <= 1) {
// No accelerators available
program.processMessage({ action: operation, data: data, tag: tag, func: func });
} else {
var acc = obj.getAccelerator();
if (acc == null) {
// Add to pending accelerator workload
acceleratorPerformSignaturePushFuncCall++;
pendingAccelerator.push({ action: operation, data: data, tag: tag, func: func });
} else {
// Send to accelerator now
acceleratorPerformSignatureRunFuncCall++;
acc.send(acc.x = { action: operation, data: data, tag: tag, func: func });
}
}
};
return obj;
};

View File

@ -12,24 +12,24 @@ var path = require('path');
var worker = null;
const NodeJSVer = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
var directRun = (require.main === module);
function log() { if (directRun) { console.log(...arguments); } else { if (worker != null) { worker.parentPort.postMessage({ msg: arguments[0] }); } } }
function log() { if (directRun) { console.log(...arguments); } /*else { if (worker != null) { worker.parentPort.postMessage({ msg: arguments[0] }); } } */ }
if (directRun && (NodeJSVer >= 12)) { const xworker = require('worker_threads'); try { if (xworker.isMainThread == false) { worker = xworker; } } catch (ex) { log(ex); } }
function start() { startEx(process.argv); }
if (directRun) { setup(); }
function setup() { InstallModules(['image-size'], start); }
function start() { startEx(process.argv); }
function startEx(argv) {
var state = { recFileName: null, recFile: null, recFileSize: 0, recFilePtr: 0 };
var infile = null;
if (argv.length > 2) { infile = argv[2]; } else {
log('MeshCentral Session Recodings Processor');
log('This tool will index a .mcrec file so that the player can seek thru the file.');
log('');
log(' Usage: node mcrec [file]');
return;
if (argv.length > 2) { indexFile(argv[2]); } else {
log("MeshCentral Session Recodings Processor");
log("This tool will index a .mcrec file so that the player can seek thru the file.");
log("");
log(" Usage: node mcrec [file]");
}
}
function indexFile(infile) {
var state = { recFileName: null, recFile: null, recFileSize: 0, recFilePtr: 0 };
if (fs.existsSync(infile) == false) { log("Missing file: " + infile); return; }
state.recFileName = infile;
state.recFileSize = fs.statSync(infile).size;
@ -64,7 +64,16 @@ function createIndex(state, ptr) {
}
function processBlock(state, block) {
if (block == null) { writeIndex(state, function () { log("Done."); }); return; }
if (block == null) {
// We are done, close this file.
writeIndex(state, function () {
fs.close(state.recFile, function () {
for (var i in state) { delete state[i]; } // Clear the state.
log("Done.");
});
});
return;
}
var elapseMilliSeconds = 0;
if (state.startTime != null) { elapseMilliSeconds = (block.time - state.startTime); }
var flagBinary = (block.flags & 1) != 0;
@ -310,4 +319,5 @@ function InstallModule(modulename, func, tag1, tag2) {
}
// Export table
module.exports.startEx = startEx;
module.exports.startEx = startEx;
module.exports.indexFile = indexFile;

View File

@ -21,7 +21,10 @@ var certStore = null;
process.on('disconnect', function () { process.exit(); });
// Handle parent messages
process.on('message', function (message) {
process.on('message', function (message) { module.exports.processMessage(message); });
// Process an incoming message
module.exports.processMessage = function(message) {
switch (message.action) {
case 'sign': {
if (typeof message.key == 'number') { message.key = certStore[message.key].key; }
@ -36,9 +39,14 @@ process.on('message', function (message) {
certStore = message.certs;
break;
}
case 'indexMcRec': {
//console.log('indexMcRec', message.data);
require(require('path').join(__dirname, 'mcrec.js')).indexFile(message.data);
break;
}
default: {
console.log('Unknown accelerator action: ' + message.action + '.');
break;
}
}
});
}

View File

@ -2333,12 +2333,14 @@ function mainStart() {
var ldap = false;
var allsspi = true;
var yubikey = false;
var recordingIndex = false;
var domainCount = 0;
if (require('os').platform() == 'win32') { for (var i in config.domains) { domainCount++; if (config.domains[i].auth == 'sspi') { sspi = true; } else { allsspi = false; } } } else { allsspi = false; }
if (domainCount == 0) { allsspi = false; }
for (var i in config.domains) {
if (config.domains[i].yubikey != null) { yubikey = true; }
if (config.domains[i].auth == 'ldap') { ldap = true; }
if ((config.domains[i].sessionrecording != null) && (config.domains[i].sessionrecording.index == true)) { recordingIndex = true; }
}
// Get the current node version
@ -2348,6 +2350,7 @@ function mainStart() {
var modules = ['ws', 'cbor', 'nedb', 'https', 'yauzl', 'xmldom', 'ipcheck', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'cookie-session', 'express-handlebars'];
if (require('os').platform() == 'win32') { modules.push('node-windows'); if (sspi == true) { modules.push('node-sspi'); } } // Add Windows modules
if (ldap == true) { modules.push('ldapauth-fork'); }
if (recordingIndex == true) { modules.push('image-size'); } // Need to get the remote desktop JPEG sizes to index the recodring file.
if (config.letsencrypt != null) { if ((nodeVersion < 10) || (require('crypto').generateKeyPair == null)) { addServerWarning("Let's Encrypt support requires Node v10.12 or higher.", !args.launch); } else { modules.push('greenlock'); } } // Add Greenlock Module
if (config.settings.mqtt != null) { modules.push('aedes'); } // Add MQTT Modules
if (config.settings.mysql != null) { modules.push('mysql'); } // Add MySQL, official driver.

View File

@ -228,7 +228,7 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
if (xdevicename2 != null) { metadata.devicename = xdevicename2; }
var firstBlock = JSON.stringify(metadata);
recordingEntry(fd, 1, ((obj.req.query.browser) ? 2 : 0), firstBlock, function () {
try { relayinfo.peer1.ws.logfile = ws.logfile = { fd: fd, lock: false }; } catch (ex) {
try { relayinfo.peer1.ws.logfile = ws.logfile = { fd: fd, lock: false, filename: recFullFilename }; } catch (ex) {
try { ws.send('c'); } catch (ex) { } // Send connect to both peers, 'cr' indicates the session is being recorded.
try { relayinfo.peer1.ws.send('c'); } catch (ex) { }
return;
@ -331,7 +331,15 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
var peer = (relayinfo.peer1 == obj) ? relayinfo.peer2 : relayinfo.peer1;
// Close the recording file
if (ws.logfile != null) { recordingEntry(ws.logfile.fd, 3, 0, 'MeshCentralMCREC', function (fd, tag) { parent.parent.fs.close(fd); tag.ws.logfile = null; tag.pws.logfile = null; }, { ws: ws, pws: peer.ws }); }
if (ws.logfile != null) {
recordingEntry(ws.logfile.fd, 3, 0, 'MeshCentralMCREC', function (fd, tag) {
parent.parent.fs.close(fd);
tag.ws.logfile = null;
tag.pws.logfile = null;
// Now that the recording file is closed, check if we need to index this file.
if (domain.sessionrecording.index == true) { parent.parent.certificateOperations.acceleratorPerformOperation('indexMcRec', tag.logfile.filename); }
}, { ws: ws, pws: peer.ws, logfile: ws.logfile });
}
// Disconnect the peer
try { if (peer.relaySessionCounted) { parent.relaySessionCount--; delete peer.relaySessionCounted; } } catch (ex) { console.log(ex); }

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.4.9-d",
"version": "0.4.9-e",
"keywords": [
"Remote Management",
"Intel AMT",

View File

@ -121,6 +121,7 @@
"_agentConfig": [ "webSocketMaskOverride=1" ],
"_SessionRecording": {
"_filepath": "C:\\temp",
"_index": true,
"__protocols__": "Is an array: 1 = Terminal, 2 = Desktop, 5 = Files, 100 = Intel AMT WSMAN, 101 = Intel AMT Redirection",
"protocols": [ 1, 2, 101 ]
}

File diff suppressed because it is too large Load Diff

View File

@ -72,6 +72,11 @@
<div id="altPortContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
<div id="cxaltport" class="cmtext" onclick="cmaltportaction(1,event)"><b>Alternate Port</b></div>
</div>
<div id="filesContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
<div id="cxfilerename" class="cmtext" onclick="cmfilesaction(1,event)"><b>Rename</b></div>
<div id="cxfileedit" class="cmtext" onclick="cmfilesaction(2,event)"><b>Edit</b></div>
<div id="cxfiledelete" class="cmtext" onclick="cmfilesaction(3,event)"><b>Delete</b></div>
</div>
<!--
<div id="pluginTabContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
<div id="cxclose" class="cmtext" onclick="pluginTabClose(event)">Close Tab</div>
@ -4000,6 +4005,12 @@
var scrollLeft = (window.pageXOffset !== null) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
var scrollTop = (window.pageYOffset !== null) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
var elem = document.elementFromPoint(event.pageX - scrollLeft, event.pageY - scrollTop);
//console.log('handleContextMenu', scrollLeft, scrollTop, elem, elem.parentElement, elem.parentElement.parentElement);
// Look for a file entry element
var fileElement = null, elx = elem;
while (elx && elx != null && elx.id != 'fileEntry') { elx = elx.parentElement; }
if (elx && (elx.id == 'fileEntry')) { fileElement = elx; }
if (elem && elem != null && elem.id == 'rdpClickOnceLink' && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
contextelement = elem;
@ -4013,6 +4024,10 @@
contextelement = elem;
var contextmenudiv = document.getElementById('termShellContextMenuLinux');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
} else if (fileElement && currentNode) {
contextelement = fileElement;
var contextmenudiv = document.getElementById('filesContextMenu');
showContextMenuDiv(contextmenudiv, event.pageX, event.pageY);
} else if (elem && elem != null && elem.id == 'MxMESH') {
contextelement = elem;
var contextmenudiv = document.getElementById('meshContextMenu');
@ -4113,6 +4128,28 @@
Q('d10rdpport').focus();
}
function cmfilesaction(action) {
if (xxdialogMode) return;
var filetreexx = p13sort_files(p13filetree.dir);
var file = filetreexx[parseInt(contextelement.attributes.fileindex.nodeValue)];
if (action == 1) { // Rename the file
setDialogMode(2, "Rename", 3, p13renamefileEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="' + file.n + '" />', { action: 'rename', path: p13filetreelocation.join('/'), oldname: file.n});
focusTextBox('p13renameinput');
p13fileNameCheck();
} else if (action == 2) { // Edit the file
if (file.s <= 204800) {
p13downloadfile(encodeURIComponent(p13filetreelocation.join('/') + '/' + file.n), encodeURIComponent(file.n), file.s, 'viewer');
} else { messagebox("File Editor", "Only files less than 200k can be edited."); }
} else if (action == 3) { // Delete the file
setDialogMode(2, "Delete", 3, p13deletefileCm, "Delete item?", file);
}
}
function p13deletefileCm(b, file) {
files.sendText({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: [ file.n ], rec: false });
p13folderup(999);
}
/*
function pluginTabClose() {
var pluginTab = contextelement;
@ -4131,6 +4168,7 @@
QV('termShellContextMenu', false);
QV('termShellContextMenuLinux', false);
QV('altPortContextMenu', false);
QV('filesContextMenu', false);
//QV('pluginTabContextMenu', false);
contextelement = null;
}
@ -6811,7 +6849,7 @@
} else {
var link = shortname;
if (f.s > 0) { link = '<a hrf=# rel=\"noreferrer noopener\" target=\"_blank\" style=cursor:pointer onclick=\"return p13downloadfile(\'' + encodeURIComponent(newlinkpath + '/' + name) + '\',\'' + encodeURIComponent(name) + '\',' + f.s + ')\">' + shortname + '</a>'; }
h = '<div class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'>&nbsp;<span class=fsize>' + fdatestr + '</span><span style=float:right>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
h = '<div id=fileEntry fileIndex=' + i + ' class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'>&nbsp;<span class=fsize>' + fdatestr + '</span><span style=float:right>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
}
if (f.t < 3) { html1 += h; } else { html2 += h; }
@ -7023,7 +7061,7 @@
QS('dialog').width = 'auto';
QS('dialog').bottom = '80px';
QS('dialog').top = QS('dialog').left = QS('dialog').right = '100px';
Q('d4editorarea').value = EscapeHtml(downloadFile.data);
Q('d4editorarea').value = downloadFile.data;
downloadFile = null;
} else {
// Save the file to disk