mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-30 03:16:12 +03:00
Added support for pre-defined scripts.
This commit is contained in:
parent
d171d2af82
commit
f6c3883735
@ -383,6 +383,39 @@
|
|||||||
"expire": { "type": "number", "description": "When set, limits the self-created guest sharing link to this number of minutes." }
|
"expire": { "type": "number", "description": "When set, limits the self-created guest sharing link to this number of minutes." }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"PreconfiguredScripts": {
|
||||||
|
"type": "array",
|
||||||
|
"default": null,
|
||||||
|
"description": "When set, your can try click the run button to run on of these scripts on the remote device.",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [ "name", "type" ],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"description": "Name of the script.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"description": "The type of script.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "bat", "ps1", "sh", "agent" ]
|
||||||
|
},
|
||||||
|
"runas": {
|
||||||
|
"description": "How to run this script, does not appy to agent scripts.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["agent", "userfirst", "user"]
|
||||||
|
},
|
||||||
|
"cmd": {
|
||||||
|
"description": "The command or \\r\\n seperated commands to run, if set do not use the file key.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"description": "The script file path and name, if set do not use the cmd key. This file path starts in meshcentral-data.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"preConfiguredRemoteInput": {
|
"preConfiguredRemoteInput": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"default": null,
|
"default": null,
|
||||||
|
52
meshuser.js
52
meshuser.js
@ -593,6 +593,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
if ((typeof domain.terminal.linuxshell == 'string') && (domain.terminal.linuxshell != 'any')) { serverinfo.linuxshell = domain.terminal.linuxshell; }
|
if ((typeof domain.terminal.linuxshell == 'string') && (domain.terminal.linuxshell != 'any')) { serverinfo.linuxshell = domain.terminal.linuxshell; }
|
||||||
}
|
}
|
||||||
if (Array.isArray(domain.preconfiguredremoteinput)) { serverinfo.preConfiguredRemoteInput = domain.preconfiguredremoteinput; }
|
if (Array.isArray(domain.preconfiguredremoteinput)) { serverinfo.preConfiguredRemoteInput = domain.preconfiguredremoteinput; }
|
||||||
|
if (Array.isArray(domain.preconfiguredscripts)) {
|
||||||
|
const r = [];
|
||||||
|
for (var i in domain.preconfiguredscripts) {
|
||||||
|
const types = ['', 'bat', 'ps1', 'sh', 'agent']; // 1 = Windows Command, 2 = Windows PowerShell, 3 = Linux, 4 = Agent
|
||||||
|
const script = domain.preconfiguredscripts[i];
|
||||||
|
if ((typeof script.name == 'string') && (script.name.length <= 32) && (typeof script.type == 'string') && ((typeof script.file == 'string') || (typeof script.cmd == 'string'))) {
|
||||||
|
const s = { name: script.name, type: types.indexOf(script.type.toLowerCase()) };
|
||||||
|
if (s.type > 0) { r.push(s); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serverinfo.preConfiguredScripts = r;
|
||||||
|
}
|
||||||
|
|
||||||
// Send server information
|
// Send server information
|
||||||
try { ws.send(JSON.stringify({ action: 'serverinfo', serverinfo: serverinfo })); } catch (ex) { }
|
try { ws.send(JSON.stringify({ action: 'serverinfo', serverinfo: serverinfo })); } catch (ex) { }
|
||||||
@ -2783,8 +2795,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
case 'runcommands':
|
case 'runcommands':
|
||||||
{
|
{
|
||||||
if (common.validateArray(command.nodeids, 1) == false) break; // Check nodeid's
|
if (common.validateArray(command.nodeids, 1) == false) break; // Check nodeid's
|
||||||
if (typeof command.type != 'number') break; // Check command type
|
if (typeof command.presetcmd != 'number') {
|
||||||
if (typeof command.runAsUser != 'number') { command.runAsUser = 0; } // Check runAsUser
|
if (typeof command.type != 'number') break; // Check command type
|
||||||
|
if (typeof command.runAsUser != 'number') { command.runAsUser = 0; } // Check runAsUser
|
||||||
|
}
|
||||||
|
|
||||||
const processRunCommand = function (command) {
|
const processRunCommand = function (command) {
|
||||||
for (i in command.nodeids) {
|
for (i in command.nodeids) {
|
||||||
@ -2873,7 +2887,39 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof command.cmdpath == 'string') {
|
if (typeof command.presetcmd == 'number') {
|
||||||
|
// If a pre-set command is used, load the command
|
||||||
|
if (Array.isArray(domain.preconfiguredscripts) == false) return;
|
||||||
|
const script = domain.preconfiguredscripts[command.presetcmd];
|
||||||
|
if (script == null) return;
|
||||||
|
delete command.presetcmd;
|
||||||
|
|
||||||
|
// Decode script type
|
||||||
|
const types = ['', 'bat', 'ps1', 'sh', 'agent']; // 1 = Windows Command, 2 = Windows PowerShell, 3 = Linux, 4 = Agent
|
||||||
|
if (typeof script.type == 'string') { const stype = types.indexOf(script.type.toLowerCase()); if (stype > 0) { command.type = stype; } }
|
||||||
|
if (command.type == null) return;
|
||||||
|
|
||||||
|
// Decode script runas
|
||||||
|
if (command.type != 4) {
|
||||||
|
const runAsModes = ['agent', 'userfirst', 'user']; // 0 = AsAgent, 1 = UserFirst, 2 = UserOnly
|
||||||
|
if (typeof script.runas == 'string') { const srunas = runAsModes.indexOf(script.runas.toLowerCase()); if (srunas >= 0) { command.runAsUser = srunas; } }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof script.file == 'string') {
|
||||||
|
// The pre-defined script commands are in a file, load it
|
||||||
|
const scriptPath = parent.common.joinPath(parent.parent.datapath, script.file);
|
||||||
|
fs.readFile(scriptPath, function (err, data) {
|
||||||
|
// If loaded correctly, run loaded commands
|
||||||
|
if ((err != null) || (data == null) || (data.length == 0) || (data.length > 65535)) return;
|
||||||
|
command.cmds = data.toString();
|
||||||
|
processRunCommand(command);
|
||||||
|
});
|
||||||
|
} else if (typeof script.cmd == 'string') {
|
||||||
|
// The pre-defined script commands are right in the config.json, use that
|
||||||
|
command.cmds = script.cmd;
|
||||||
|
processRunCommand(command);
|
||||||
|
}
|
||||||
|
} else if (typeof command.cmdpath == 'string') {
|
||||||
// If a server command path is used, load the script from the path
|
// If a server command path is used, load the script from the path
|
||||||
var file = parent.getServerFilePath(user, domain, command.cmdpath);
|
var file = parent.getServerFilePath(user, domain, command.cmdpath);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
|
@ -243,6 +243,31 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"PreconfiguredScripts": [
|
||||||
|
{
|
||||||
|
"name": "Run NotePad as user",
|
||||||
|
"file": "scripts/notepad.bat",
|
||||||
|
"type": "bat",
|
||||||
|
"runas": "user"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Run NotePad as agent",
|
||||||
|
"cmd": "notepad.exe",
|
||||||
|
"type": "bat",
|
||||||
|
"runas": "agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Run echo",
|
||||||
|
"cmd": "echo \"hello world\"",
|
||||||
|
"type": "sh",
|
||||||
|
"runas": "agent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Agent Update",
|
||||||
|
"cmd": "agentupdate",
|
||||||
|
"type": "agent"
|
||||||
|
}
|
||||||
|
],
|
||||||
"PreconfiguredRemoteInput": [
|
"PreconfiguredRemoteInput": [
|
||||||
{
|
{
|
||||||
"name": "CompanyUrl",
|
"name": "CompanyUrl",
|
||||||
|
@ -138,7 +138,10 @@
|
|||||||
<span id="deskPreConfigShortcutContextMenu2"></span>
|
<span id="deskPreConfigShortcutContextMenu2"></span>
|
||||||
<div class="cmtext" onclick="cmdeskpreconfigtypeaction(-1,event)">Customize...</div>
|
<div class="cmtext" onclick="cmdeskpreconfigtypeaction(-1,event)">Customize...</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="deskPreConfigScriptContextMenu" class="contextMenu noselect" style="display:none;min-width:0px;max-height:calc(80% - 50px);overflow-y:auto">
|
||||||
|
<span id="deskPreConfigScriptContextMenu1"></span>
|
||||||
|
<span id="deskPreConfigScriptContextMenu2"></span>
|
||||||
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div id="pluginTabContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
|
<div id="pluginTabContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
|
||||||
<div id="cxclose" class="cmtext" onclick="pluginTabClose(event)">Close Tab</div>
|
<div id="cxclose" class="cmtext" onclick="pluginTabClose(event)">Close Tab</div>
|
||||||
@ -703,7 +706,7 @@
|
|||||||
<span id="DeskTimer" style="line-height:22px" title="Session time"></span>
|
<span id="DeskTimer" style="line-height:22px" title="Session time"></span>
|
||||||
<input id=DeskToolsButton type=button value=Tools title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()" />
|
<input id=DeskToolsButton type=button value=Tools title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()" />
|
||||||
<span> </span>
|
<span> </span>
|
||||||
<span id=DeskRunButton class="deskarea" title="Run a script on this computer"><img class="desktopButtons" src='images/icon-play.png' onclick=runDeviceCmd() height=16 width=16 style=padding-top:2px /></span>
|
<span id=DeskRunButton cmenu="deskPreConfigScriptContextMenu" class="deskarea" title="Run a script on this computer"><img class="desktopButtons" src='images/icon-play.png' onclick=runDeviceCmd() height=16 width=16 style=padding-top:2px /></span>
|
||||||
<span id=DeskChatButton class="deskarea" title="Open chat window to this computer"><img class="desktopButtons" src='images/icon-chat.png' onclick=deviceChat(event) height=16 width=16 style=padding-top:2px /></span>
|
<span id=DeskChatButton class="deskarea" title="Open chat window to this computer"><img class="desktopButtons" src='images/icon-chat.png' onclick=deviceChat(event) height=16 width=16 style=padding-top:2px /></span>
|
||||||
<span id=DeskNotifyButton title="Display a notification on the remote computer"><img class="desktopButtons" src='images/icon-notify.png' onclick=deviceToastFunction() height=16 width=16 style=padding-top:2px /></span>
|
<span id=DeskNotifyButton title="Display a notification on the remote computer"><img class="desktopButtons" src='images/icon-notify.png' onclick=deviceToastFunction() height=16 width=16 style=padding-top:2px /></span>
|
||||||
<span id=DeskLockButton title="Lock the remote computer"><img src='images/icon-lock.png' class="desktopButtons" onclick=deviceLockFunction() height=16 width=16 /></span>
|
<span id=DeskLockButton title="Lock the remote computer"><img src='images/icon-lock.png' class="desktopButtons" onclick=deviceLockFunction() height=16 width=16 /></span>
|
||||||
@ -2373,11 +2376,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (serverinfo.preConfiguredRemoteInput) {
|
if (serverinfo.preConfiguredRemoteInput) {
|
||||||
|
// Setup the pre-configured keyboard remote input strings
|
||||||
var x = '';
|
var x = '';
|
||||||
for (var i in serverinfo.preConfiguredRemoteInput) { x += '<div class="cmtext" onclick="cmdeskpreconfigtypeaction(' + i + ',event)">' + EscapeHtml(serverinfo.preConfiguredRemoteInput[i].name) + '</div>'; }
|
for (var i in serverinfo.preConfiguredRemoteInput) { x += '<div class="cmtext" onclick="cmdeskpreconfigtypeaction(' + i + ',event)">' + EscapeHtml(serverinfo.preConfiguredRemoteInput[i].name) + '</div>'; }
|
||||||
if (x != '') { x += '<hr />'; }
|
if (x != '') { x += '<hr />'; }
|
||||||
QH('deskPreConfigShortcutContextMenu1', x);
|
QH('deskPreConfigShortcutContextMenu1', x);
|
||||||
}
|
}
|
||||||
|
if (serverinfo.preConfiguredScripts) {
|
||||||
|
// Setup the pre-configured scripts
|
||||||
|
var x = '', y = '';
|
||||||
|
for (var i in serverinfo.preConfiguredScripts) {
|
||||||
|
var s = serverinfo.preConfiguredScripts[i];
|
||||||
|
var z = '<div class="cmtext" onclick="cmdeskpreconfigscriptaction(' + i + ',event)">' + EscapeHtml(serverinfo.preConfiguredScripts[i].name) + '</div>';
|
||||||
|
if (s.type != 3) { x += z; }
|
||||||
|
if (s.type >= 3) { y += z; }
|
||||||
|
}
|
||||||
|
QH('deskPreConfigScriptContextMenu1', x); // Windows devices
|
||||||
|
QH('deskPreConfigScriptContextMenu2', y); // Other devices
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'userinfo': {
|
case 'userinfo': {
|
||||||
@ -6265,6 +6281,10 @@
|
|||||||
else { showDeskTypeEx(deskKeyboardStrings[action - 1000].v); } // Type user pre-configured input string
|
else { showDeskTypeEx(deskKeyboardStrings[action - 1000].v); } // Type user pre-configured input string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cmdeskpreconfigscriptaction(action) {
|
||||||
|
meshserver.send({ action: 'runcommands', nodeids: [ currentNode._id ], presetcmd: action });
|
||||||
|
}
|
||||||
|
|
||||||
function p13deletefileCm(b, file) {
|
function p13deletefileCm(b, file) {
|
||||||
files.sendText({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: [ file.n ], rec: false });
|
files.sendText({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: [ file.n ], rec: false });
|
||||||
p13folderup(999);
|
p13folderup(999);
|
||||||
@ -6300,6 +6320,7 @@
|
|||||||
QV('deskPlayerContextMenu', false);
|
QV('deskPlayerContextMenu', false);
|
||||||
QV('deskKeyShortcutContextMenu', false);
|
QV('deskKeyShortcutContextMenu', false);
|
||||||
QV('deskPreConfigShortcutContextMenu', false);
|
QV('deskPreConfigShortcutContextMenu', false);
|
||||||
|
QV('deskPreConfigScriptContextMenu', false);
|
||||||
QV('expandAllContextMenu', false);
|
QV('expandAllContextMenu', false);
|
||||||
//QV('pluginTabContextMenu', false);
|
//QV('pluginTabContextMenu', false);
|
||||||
contextelement = null;
|
contextelement = null;
|
||||||
@ -6951,6 +6972,10 @@
|
|||||||
if (!currentNode || currentNode._id != node._id || refresh == true) {
|
if (!currentNode || currentNode._id != node._id || refresh == true) {
|
||||||
currentNode = node;
|
currentNode = node;
|
||||||
|
|
||||||
|
// Pre defined scripts
|
||||||
|
QV('deskPreConfigScriptContextMenu1', (currentNode.mtype == 2) && isWindowsNode(currentNode)); // Windows devices
|
||||||
|
QV('deskPreConfigScriptContextMenu2', (currentNode.mtype == 2) && !isWindowsNode(currentNode)); // Other devices
|
||||||
|
|
||||||
// Device Notification
|
// Device Notification
|
||||||
QV('p10deviceNotify', (currentNode.sessions != null) && ((currentNode.sessions.kvm != null) || (currentNode.sessions.terminal != null) || (currentNode.sessions.files != null) || (currentNode.sessions.tcp != null) || (currentNode.sessions.udp != null)));
|
QV('p10deviceNotify', (currentNode.sessions != null) && ((currentNode.sessions.kvm != null) || (currentNode.sessions.terminal != null) || (currentNode.sessions.files != null) || (currentNode.sessions.tcp != null) || (currentNode.sessions.udp != null)));
|
||||||
QV('p10deviceStar', stars[currentNode._id] == 1);
|
QV('p10deviceStar', stars[currentNode._id] == 1);
|
||||||
@ -7221,7 +7246,7 @@
|
|||||||
if (((meshrights & (4 + 8 + 64 + 262144)) != 0) && (node.mtype < 3) && ((node.agent == null) || (node.agent.id != 34))) { x += '<input type=button value="' + "Actions" + '" title="' + "Perform power actions on the device" + '" onclick=deviceActionFunction() />'; }
|
if (((meshrights & (4 + 8 + 64 + 262144)) != 0) && (node.mtype < 3) && ((node.agent == null) || (node.agent.id != 34))) { x += '<input type=button value="' + "Actions" + '" title="' + "Perform power actions on the device" + '" onclick=deviceActionFunction() />'; }
|
||||||
x += '<input type=button value="' + "Notes" + '" title="' + "View notes about this device" + '" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponentEx(node._id) + '") />';
|
x += '<input type=button value="' + "Notes" + '" title="' + "View notes about this device" + '" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponentEx(node._id) + '") />';
|
||||||
x += '<input type=button value="' + "Log Event" + '" title="' + "Write an event for this device" + '" onclick=writeDeviceEvent("' + encodeURIComponentEx(node._id) + '") />';
|
x += '<input type=button value="' + "Log Event" + '" title="' + "Write an event for this device" + '" onclick=writeDeviceEvent("' + encodeURIComponentEx(node._id) + '") />';
|
||||||
if ((node.mtype == 2) && (connectivity & 1) && ((meshrights & 131072) != 0)) { x += '<input type=button value="' + "Run" + '" title="' + "Run commands on this device" + '" onclick=runDeviceCmd("' + encodeURIComponentEx(node._id) + '") />'; }
|
if ((node.mtype == 2) && (connectivity & 1) && ((meshrights & 131072) != 0)) { x += '<input type=button cmenu=deskPreConfigScriptContextMenu value="' + "Run" + '" title="' + "Run commands on this device" + '" onclick=runDeviceCmd("' + encodeURIComponentEx(node._id) + '") />'; }
|
||||||
if (node.mtype != 4) {
|
if (node.mtype != 4) {
|
||||||
if ((meshrights & 8) && ((connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0)))) { x += '<input type=button value="' + "Message" + '" title="' + "Display a text message on the remote device" + '" onclick=deviceMessageFunction() />'; }
|
if ((meshrights & 8) && ((connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0)))) { x += '<input type=button value="' + "Message" + '" title="' + "Display a text message on the remote device" + '" onclick=deviceMessageFunction() />'; }
|
||||||
//if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="' + "Display a text message of the remote device" + '" onclick=deviceToastFunction() />'; }
|
//if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="' + "Display a text message of the remote device" + '" onclick=deviceToastFunction() />'; }
|
||||||
@ -17899,6 +17924,7 @@
|
|||||||
}
|
}
|
||||||
function round(value, precision) { var multiplier = Math.pow(10, precision || 0); return Math.round(value * multiplier) / multiplier; }
|
function round(value, precision) { var multiplier = Math.pow(10, precision || 0); return Math.round(value * multiplier) / multiplier; }
|
||||||
function safeNewWindow(url, target) { var newWindow = window.open(url, target, 'noopener,noreferrer'); if (newWindow) { newWindow.opener = null; } }
|
function safeNewWindow(url, target) { var newWindow = window.open(url, target, 'noopener,noreferrer'); if (newWindow) { newWindow.opener = null; } }
|
||||||
|
function isWindowsNode(node) { if ((node.mtype != 2) || (node.agent == null) || (node.agent.id == null)) return false; return ([1,2,3,4,21,22,34].indexOf(node.agent.id) >= 0); }
|
||||||
|
|
||||||
// Webkit seems to have a problem with "download" tag causing "network error", but openning the download in a hidden frame fixes it.
|
// Webkit seems to have a problem with "download" tag causing "network error", but openning the download in a hidden frame fixes it.
|
||||||
// So we do that for all browsers except FireFox
|
// So we do that for all browsers except FireFox
|
||||||
|
Loading…
Reference in New Issue
Block a user