mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-10-29 15:25:01 -04: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." } | ||||
|             } | ||||
|           }, | ||||
|           "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": { | ||||
|             "type": "array", | ||||
|             "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 (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
 | ||||
|             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': | ||||
|                 { | ||||
|                     if (common.validateArray(command.nodeids, 1) == false) break; // Check nodeid's
 | ||||
|                     if (typeof command.type != 'number') break; // Check command type
 | ||||
|                     if (typeof command.runAsUser != 'number') { command.runAsUser = 0; } // Check runAsUser
 | ||||
|                     if (typeof command.presetcmd != 'number') { | ||||
|                         if (typeof command.type != 'number') break; // Check command type
 | ||||
|                         if (typeof command.runAsUser != 'number') { command.runAsUser = 0; } // Check runAsUser
 | ||||
|                     } | ||||
| 
 | ||||
|                     const processRunCommand = function (command) { | ||||
|                         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
 | ||||
|                         var file = parent.getServerFilePath(user, domain, command.cmdpath); | ||||
|                         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": [ | ||||
|         { | ||||
|           "name": "CompanyUrl", | ||||
|  | ||||
| @ -138,7 +138,10 @@ | ||||
|         <span id="deskPreConfigShortcutContextMenu2"></span> | ||||
|         <div class="cmtext" onclick="cmdeskpreconfigtypeaction(-1,event)">Customize...</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="cxclose" class="cmtext" onclick="pluginTabClose(event)">Close Tab</div> | ||||
| @ -703,7 +706,7 @@ | ||||
|                             <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()" /> | ||||
|                             <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=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> | ||||
| @ -2373,11 +2376,24 @@ | ||||
|                         } | ||||
|                     } | ||||
|                     if (serverinfo.preConfiguredRemoteInput) { | ||||
|                         // Setup the pre-configured keyboard remote input strings | ||||
|                         var x = ''; | ||||
|                         for (var i in serverinfo.preConfiguredRemoteInput) { x += '<div class="cmtext" onclick="cmdeskpreconfigtypeaction(' + i + ',event)">' + EscapeHtml(serverinfo.preConfiguredRemoteInput[i].name) + '</div>'; } | ||||
|                         if (x != '') { x += '<hr />'; } | ||||
|                         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; | ||||
|                 } | ||||
|                 case 'userinfo': { | ||||
| @ -6265,6 +6281,10 @@ | ||||
|             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) { | ||||
|             files.sendText({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: [ file.n ], rec: false }); | ||||
|             p13folderup(999); | ||||
| @ -6300,6 +6320,7 @@ | ||||
|             QV('deskPlayerContextMenu', false); | ||||
|             QV('deskKeyShortcutContextMenu', false); | ||||
|             QV('deskPreConfigShortcutContextMenu', false); | ||||
|             QV('deskPreConfigScriptContextMenu', false); | ||||
|             QV('expandAllContextMenu', false); | ||||
|             //QV('pluginTabContextMenu', false); | ||||
|             contextelement = null; | ||||
| @ -6951,6 +6972,10 @@ | ||||
|             if (!currentNode || currentNode._id != node._id || refresh == true) { | ||||
|                 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 | ||||
|                 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); | ||||
| @ -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() />'; } | ||||
|                 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) + '") />'; | ||||
|                 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 ((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() />';  } | ||||
| @ -17899,6 +17924,7 @@ | ||||
|         } | ||||
|         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 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. | ||||
|         // So we do that for all browsers except FireFox | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user