mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-22 12:52:50 +03:00
Added file context menu for device files.
This commit is contained in:
parent
ff9d87dddf
commit
0be2a1026f
@ -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;
|
||||
};
|
||||
|
34
mcrec.js
34
mcrec.js
@ -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;
|
@ -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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
@ -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.
|
||||
|
12
meshrelay.js
12
meshrelay.js
@ -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); }
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.4.9-d",
|
||||
"version": "0.4.9-e",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -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
@ -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 + '\'> <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 + '\'> <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
|
||||
|
Loading…
Reference in New Issue
Block a user