mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Added support for pre-defined scripts.
This commit is contained in:
		
							parent
							
								
									d171d2af82
								
							
						
					
					
						commit
						f6c3883735
					
				
					 4 changed files with 136 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue