mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Added multi-agent upload feature.
This commit is contained in:
		
							parent
							
								
									b1e369aee0
								
							
						
					
					
						commit
						c24c8821fe
					
				
					 6 changed files with 1862 additions and 1681 deletions
				
			
		| 
						 | 
					@ -43,6 +43,8 @@ var MESHRIGHT_NODESKTOP = 65536;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createMeshCore(agent) {
 | 
					function createMeshCore(agent) {
 | 
				
			||||||
    var obj = {};
 | 
					    var obj = {};
 | 
				
			||||||
 | 
					    var agentFileHttpRequests = {}; // Currently active agent HTTPS GET requests from the server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (process.platform == 'win32' && require('user-sessions').isRoot()) {
 | 
					    if (process.platform == 'win32' && require('user-sessions').isRoot()) {
 | 
				
			||||||
        // Check the Agent Uninstall MetaData for correctness, as the installer may have written an incorrect value
 | 
					        // Check the Agent Uninstall MetaData for correctness, as the installer may have written an incorrect value
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
| 
						 | 
					@ -1140,6 +1142,33 @@ function createMeshCore(agent) {
 | 
				
			||||||
                case 'meshToolInfo':
 | 
					                case 'meshToolInfo':
 | 
				
			||||||
                    if (data.pipe == true) { delete data.pipe; delete data.action; data.cmd = 'meshToolInfo'; broadcastToRegisteredApps(data); }
 | 
					                    if (data.pipe == true) { delete data.pipe; delete data.action; data.cmd = 'meshToolInfo'; broadcastToRegisteredApps(data); }
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 'wget': // Server uses this command to tell the agent to download a file using HTTPS/GET and place it in a given path. This is used for one-to-many file uploads.
 | 
				
			||||||
 | 
					                    if ((data.overwrite !== true) && fs.existsSync(data.path)) break; // Don't overwrite an existing file.
 | 
				
			||||||
 | 
					                    data.url = 'http' + getServerTargetUrlEx('*/').substring(2);
 | 
				
			||||||
 | 
					                    var agentFileHttpOptions = http.parseUri(data.url);
 | 
				
			||||||
 | 
					                    agentFileHttpOptions.path = data.urlpath;
 | 
				
			||||||
 | 
					                    agentFileHttpOptions.rejectUnauthorized = 0; // TODO: Check TLS cert
 | 
				
			||||||
 | 
					                    if (agentFileHttpOptions == null) break;
 | 
				
			||||||
 | 
					                    var agentFileHttpRequest = http.request(agentFileHttpOptions,
 | 
				
			||||||
 | 
					                        function (response) {
 | 
				
			||||||
 | 
					                            response.xparent = this;
 | 
				
			||||||
 | 
					                            try {
 | 
				
			||||||
 | 
					                                response.xfile = fs.createWriteStream(this.xpath, { flags: 'wbN' })
 | 
				
			||||||
 | 
					                                response.pipe(response.xfile);
 | 
				
			||||||
 | 
					                                response.end = function () { delete agentFileHttpRequests[this.xparent.xurlpath]; delete this.xparent; }
 | 
				
			||||||
 | 
					                            } catch (ex) {
 | 
				
			||||||
 | 
					                                delete agentFileHttpRequests[this.xurlpath];
 | 
				
			||||||
 | 
					                                delete response.xparent;
 | 
				
			||||||
 | 
					                                return;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                    agentFileHttpRequest.on('error', function (ex) { delete agentFileHttpRequests[this.xurlpath]; });
 | 
				
			||||||
 | 
					                    agentFileHttpRequest.end();
 | 
				
			||||||
 | 
					                    agentFileHttpRequest.xurlpath = data.urlpath;
 | 
				
			||||||
 | 
					                    agentFileHttpRequest.xpath = data.path;
 | 
				
			||||||
 | 
					                    agentFileHttpRequests[data.urlpath] = agentFileHttpRequest;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    // Unknown action, ignore it.
 | 
					                    // Unknown action, ignore it.
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,13 @@ function CreateMeshCentralServer(config, args) {
 | 
				
			||||||
        if (obj.fs.existsSync(obj.path.join(__dirname, '../meshcentral-web/emails'))) { obj.webEmailsOverridePath = obj.path.join(__dirname, '../meshcentral-web/emails'); }
 | 
					        if (obj.fs.existsSync(obj.path.join(__dirname, '../meshcentral-web/emails'))) { obj.webEmailsOverridePath = obj.path.join(__dirname, '../meshcentral-web/emails'); }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Clean up any temporary files
 | 
				
			||||||
 | 
					    var removeTime = new Date(Date.now()).getTime() - (30 * 60 * 1000); // 30 minutes
 | 
				
			||||||
 | 
					    var dir = obj.fs.readdir(obj.path.join(obj.filespath, 'tmp'), function (err, files) {
 | 
				
			||||||
 | 
					        if (err != null) return;
 | 
				
			||||||
 | 
					        for (var i in files) { try { const filepath = obj.path.join(obj.filespath, 'tmp', files[i]); if (obj.fs.statSync(filepath).mtime.getTime() < removeTime) { obj.fs.unlink(filepath, function () { }); } } catch (ex) { } }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Look to see if data and/or file path is specified
 | 
					    // Look to see if data and/or file path is specified
 | 
				
			||||||
    if (obj.config.settings && (typeof obj.config.settings.datapath == 'string')) { obj.datapath = obj.config.settings.datapath; }
 | 
					    if (obj.config.settings && (typeof obj.config.settings.datapath == 'string')) { obj.datapath = obj.config.settings.datapath; }
 | 
				
			||||||
    if (obj.config.settings && (typeof obj.config.settings.filespath == 'string')) { obj.filespath = obj.config.settings.filespath; }
 | 
					    if (obj.config.settings && (typeof obj.config.settings.filespath == 'string')) { obj.filespath = obj.config.settings.filespath; }
 | 
				
			||||||
| 
						 | 
					@ -1550,6 +1557,13 @@ function CreateMeshCentralServer(config, args) {
 | 
				
			||||||
        // Perform database maintenance
 | 
					        // Perform database maintenance
 | 
				
			||||||
        obj.db.maintenance();
 | 
					        obj.db.maintenance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Clean up any temporary files
 | 
				
			||||||
 | 
					        var removeTime = new Date(Date.now()).getTime() - (30 * 60 * 1000); // 30 minutes
 | 
				
			||||||
 | 
					        var dir = obj.fs.readdir(obj.path.join(obj.filespath, 'tmp'), function (err, files) {
 | 
				
			||||||
 | 
					            if (err != null) return;
 | 
				
			||||||
 | 
					            for (var i in files) { try { const filepath = obj.path.join(obj.filespath, 'tmp', files[i]); if (obj.fs.statSync(filepath).mtime.getTime() < removeTime) { obj.fs.unlink(filepath, function () { }); } } catch (ex) { } }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Check for self-update that targets a specific version
 | 
					        // Check for self-update that targets a specific version
 | 
				
			||||||
        if ((typeof obj.args.selfupdate == 'string') && (getCurrentVerion() === obj.args.selfupdate)) { obj.args.selfupdate = false; }
 | 
					        if ((typeof obj.args.selfupdate == 'string') && (getCurrentVerion() === obj.args.selfupdate)) { obj.args.selfupdate = false; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								public/scripts/amt-wsman-0.2.0-min.js
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								public/scripts/amt-wsman-0.2.0-min.js
									
										
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -4440,6 +4440,7 @@
 | 
				
			||||||
                if ((rights & 131072) && ((added & 16) == 0)) { added |= 16; addedOptions += '<option value=106>' + "Run commands" + '</option>'; }
 | 
					                if ((rights & 131072) && ((added & 16) == 0)) { added |= 16; addedOptions += '<option value=106>' + "Run commands" + '</option>'; }
 | 
				
			||||||
                if ((rights & 16384) && ((added & 32) == 0)) { added |= 32; addedOptions += '<option value=108>' + "Device notification" + '</option>'; }
 | 
					                if ((rights & 16384) && ((added & 32) == 0)) { added |= 32; addedOptions += '<option value=108>' + "Device notification" + '</option>'; }
 | 
				
			||||||
                if ((rights & 4) && ((added & 64) == 0)) { added |= 64; addedOptions += '<option value=107>' + "Edit tags" + '</option>'; }
 | 
					                if ((rights & 4) && ((added & 64) == 0)) { added |= 64; addedOptions += '<option value=107>' + "Edit tags" + '</option>'; }
 | 
				
			||||||
 | 
					                if ((rights & 8) && ((added & 256) == 0)) { added |= 256; addedOptions += '<option value=109>' + "Upload files" + '</option>'; }
 | 
				
			||||||
                if ((rights & 32768) && ((added & 128) == 0)) { added |= 128; addedOptions += '<option value=101>' + "Delete devices" + '</option>'; }
 | 
					                if ((rights & 32768) && ((added & 128) == 0)) { added |= 128; addedOptions += '<option value=101>' + "Delete devices" + '</option>'; }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4519,6 +4520,19 @@
 | 
				
			||||||
                x += '<textarea id=d2notifyMsg style=background-color:#fcf3cf;width:100%;height:140px;resize:none;overflow-y:scroll></textarea>';
 | 
					                x += '<textarea id=d2notifyMsg style=background-color:#fcf3cf;width:100%;height:140px;resize:none;overflow-y:scroll></textarea>';
 | 
				
			||||||
                setDialogMode(2, "Device Notification", 3, d2groupActionFunctionNotifyExec, x);
 | 
					                setDialogMode(2, "Device Notification", 3, d2groupActionFunctionNotifyExec, x);
 | 
				
			||||||
                Q('d2notifyMsg').focus();
 | 
					                Q('d2notifyMsg').focus();
 | 
				
			||||||
 | 
					            } else if (op == 109) {
 | 
				
			||||||
 | 
					                // Upload files
 | 
				
			||||||
 | 
					                var wintype = false, linuxtype = false, chkNodeIds = getCheckedDevices();
 | 
				
			||||||
 | 
					                for (var i in chkNodeIds) { var n = getNodeFromId(chkNodeIds[i]); if (n.agent) { if ((n.agent.id > 0) && (n.agent.id < 5)) { wintype = true; } else { linuxtype = true; } } }
 | 
				
			||||||
 | 
					                var x = "Upload selected files to all selected devices" + '<br /><br />';
 | 
				
			||||||
 | 
					                x += '<form method=post enctype=multipart/form-data action=uploadfilebatch.ashx target=fileUploadFrame>';
 | 
				
			||||||
 | 
					                x += '<input type=hidden name=authCookie value=' + authCookie + ' /><input type=hidden name=nodeIds value=' + chkNodeIds.join(',') + ' /><input type=submit id=d2batchUploadSubmit style=display:none />';
 | 
				
			||||||
 | 
					                x += '<input type=file name=files id=d2uploadinput style=width:100% multiple=multiple onchange="d2batchUploadValidate()" /><br /><br />';
 | 
				
			||||||
 | 
					                if (wintype) { x += addHtmlValue("Windows Path", '<input style=width:250px type=text onchange="d2batchUploadValidate()" onkeyup="d2batchUploadValidate()" name=winpath id=d2winuploadpath placeholder="C:\\temp" value="" />'); }
 | 
				
			||||||
 | 
					                if (linuxtype) { x += addHtmlValue("Linux Path", '<input style=width:250px type=text onchange="d2batchUploadValidate()" onkeyup="d2batchUploadValidate()" name=linuxpath id=d2linuxuploadpath placeholder="/tmp" value="" />'); }
 | 
				
			||||||
 | 
					                x += '<br /><label><input type=checkbox name=overwriteFiles />' + "Overwrite if file exists?" + '</label></form>';
 | 
				
			||||||
 | 
					                setDialogMode(2, "Batch File Upload", 3, d2batchUploadValidateOk, x);
 | 
				
			||||||
 | 
					                d2batchUploadValidate();
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                // Power operation
 | 
					                // Power operation
 | 
				
			||||||
                meshserver.send({ action: 'poweraction', nodeids: getCheckedDevices(), actiontype: parseInt(op) });
 | 
					                meshserver.send({ action: 'poweraction', nodeids: getCheckedDevices(), actiontype: parseInt(op) });
 | 
				
			||||||
| 
						 | 
					@ -4526,6 +4540,9 @@
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function d2batchUploadValidate() { QE('idx_dlgOkButton', (Q('d2uploadinput').files.length != 0) && ((Q('d2winuploadpath') == null) || (Q('d2winuploadpath').value != '')) && ((Q('d2linuxuploadpath') == null) || (Q('d2linuxuploadpath').value != ''))); }
 | 
				
			||||||
 | 
					        function d2batchUploadValidateOk() { Q('d2batchUploadSubmit').click(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        function d2groupActionFunctionNotifyExec() {
 | 
					        function d2groupActionFunctionNotifyExec() {
 | 
				
			||||||
            var op = Q('d2deviceop').value, title = Q('dp2notifyTitle').value, msg = Q('d2notifyMsg').value, chkNodeIds = getCheckedDevices();
 | 
					            var op = Q('d2deviceop').value, title = Q('dp2notifyTitle').value, msg = Q('d2notifyMsg').value, chkNodeIds = getCheckedDevices();
 | 
				
			||||||
            if (msg.length == 0) return;
 | 
					            if (msg.length == 0) return;
 | 
				
			||||||
| 
						 | 
					@ -10735,10 +10752,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (overWriteCount == 0) {
 | 
					            if (overWriteCount == 0) {
 | 
				
			||||||
                // If no overwrite, go ahead with upload
 | 
					                // If no overwrite, go ahead with upload
 | 
				
			||||||
                p5PerformUpload(1, files);
 | 
					                p5PerformUpload(1, e.dataTransfer.files);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                // Otherwise, prompt for confirmation
 | 
					                // Otherwise, prompt for confirmation
 | 
				
			||||||
                setDialogMode(2, "Upload File", 3, p5PerformUpload, format((overWriteCount == 1)?"Upload will overwrite 1 file. Continue?":"Upload will overwrite {0} files. Continue?", overWriteCount), files);
 | 
					                setDialogMode(2, "Upload File", 3, p5PerformUpload, format((overWriteCount == 1)?"Upload will overwrite 1 file. Continue?":"Upload will overwrite {0} files. Continue?", overWriteCount), e.dataTransfer.files);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										85
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										85
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
					@ -2718,6 +2718,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
        obj.meshDeviceFileHandler.CreateMeshDeviceFile(obj, null, res, req, domain, user, meshid, nodeid);
 | 
					        obj.meshDeviceFileHandler.CreateMeshDeviceFile(obj, null, res, req, domain, user, meshid, nodeid);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Handle download of a server file by an agent
 | 
				
			||||||
 | 
					    function handleAgentDownloadFile(req, res) {
 | 
				
			||||||
 | 
					        const domain = checkUserIpAddress(req, res);
 | 
				
			||||||
 | 
					        if (domain == null) { return; }
 | 
				
			||||||
 | 
					        if (req.query.c == null) { res.sendStatus(404); return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check the inbound desktop sharing cookie
 | 
				
			||||||
 | 
					        var c = obj.parent.decodeCookie(req.query.c, obj.parent.loginCookieEncryptionKey, 5); // 5 minute timeout
 | 
				
			||||||
 | 
					        if ((c == null) || (c.a != 'tmpdl') || (c.d != domain.id) || (c.nid == null) || (c.f == null) || (obj.common.IsFilenameValid(c.f) == false)) { res.sendStatus(404); return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Send the file back
 | 
				
			||||||
 | 
					        try { res.sendFile(obj.path.join(obj.filespath, 'tmp', c.f)); return; } catch (ex) { res.sendStatus(404); }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Handle logo request
 | 
					    // Handle logo request
 | 
				
			||||||
    function handleLogoRequest(req, res) {
 | 
					    function handleLogoRequest(req, res) {
 | 
				
			||||||
        const domain = checkUserIpAddress(req, res);
 | 
					        const domain = checkUserIpAddress(req, res);
 | 
				
			||||||
| 
						 | 
					@ -3154,6 +3168,75 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Upload a file to the server and then batch upload to many agents
 | 
				
			||||||
 | 
					    function handleUploadFileBatch(req, res) {
 | 
				
			||||||
 | 
					        const domain = checkUserIpAddress(req, res);
 | 
				
			||||||
 | 
					        if (domain == null) { return; }
 | 
				
			||||||
 | 
					        if (domain.userQuota == -1) { res.sendStatus(401); return; }
 | 
				
			||||||
 | 
					        var authUserid = null;
 | 
				
			||||||
 | 
					        if ((req.session != null) && (typeof req.session.userid == 'string')) { authUserid = req.session.userid; }
 | 
				
			||||||
 | 
					        const multiparty = require('multiparty');
 | 
				
			||||||
 | 
					        const form = new multiparty.Form();
 | 
				
			||||||
 | 
					        form.parse(req, function (err, fields, files) {
 | 
				
			||||||
 | 
					            // If an authentication cookie is embedded in the form, use that.
 | 
				
			||||||
 | 
					            if ((fields != null) && (fields.auth != null) && (fields.auth.length == 1) && (typeof fields.auth[0] == 'string')) {
 | 
				
			||||||
 | 
					                var loginCookie = obj.parent.decodeCookie(fields.auth[0], obj.parent.loginCookieEncryptionKey, 60); // 60 minute timeout
 | 
				
			||||||
 | 
					                if ((loginCookie != null) && (obj.args.cookieipcheck !== false) && (loginCookie.ip != null) && (loginCookie.ip != req.clientIp)) { loginCookie = null; } // Check cookie IP binding.
 | 
				
			||||||
 | 
					                if ((loginCookie != null) && (domain.id == loginCookie.domainid)) { authUserid = loginCookie.userid; } // Use cookie authentication
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (authUserid == null) { res.sendStatus(401); return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Get the user
 | 
				
			||||||
 | 
					            const user = obj.users[authUserid];
 | 
				
			||||||
 | 
					            if ((user == null) || (user.siteadmin & 8) == 0) { res.sendStatus(401); return; } // Check if we have file rights
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Get fields
 | 
				
			||||||
 | 
					            if ((fields == null) || (fields.nodeIds == null) || (fields.nodeIds.length != 1)) { res.sendStatus(404); return; }
 | 
				
			||||||
 | 
					            var cmd = { nodeids: fields.nodeIds[0].split(','), files: [], user: user, domain: domain };
 | 
				
			||||||
 | 
					            if ((fields.winpath != null) && (fields.winpath.length == 1)) { cmd.windowsPath = fields.winpath[0]; }
 | 
				
			||||||
 | 
					            if ((fields.linuxpath != null) && (fields.linuxpath.length == 1)) { cmd.linuxPath = fields.linuxpath[0]; }
 | 
				
			||||||
 | 
					            if ((fields.overwriteFiles != null) && (fields.overwriteFiles.length == 1) && (fields.overwriteFiles[0] == 'on')) { cmd.overwrite = true; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Get server temporary path
 | 
				
			||||||
 | 
					            var serverpath = obj.path.join(obj.filespath, 'tmp')
 | 
				
			||||||
 | 
					            try { obj.fs.mkdirSync(obj.parent.filespath); } catch (ex) { }
 | 
				
			||||||
 | 
					            try { obj.fs.mkdirSync(serverpath); } catch (ex) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // More typical upload method, the file data is in a multipart mime post.
 | 
				
			||||||
 | 
					            for (var i in files.files) {
 | 
				
			||||||
 | 
					                var file = files.files[i], ftarget = getRandomPassword() + '-' + file.originalFilename, fpath = obj.path.join(serverpath, ftarget);
 | 
				
			||||||
 | 
					                cmd.files.push({ name: file.originalFilename, target: ftarget });
 | 
				
			||||||
 | 
					                // Rename the file
 | 
				
			||||||
 | 
					                obj.fs.rename(file.path, fpath, function (err) {
 | 
				
			||||||
 | 
					                    if (err && (err.code === 'EXDEV')) {
 | 
				
			||||||
 | 
					                        // On some Linux, the rename will fail with a "EXDEV" error, do a copy+unlink instead.
 | 
				
			||||||
 | 
					                        obj.common.copyFile(file.path, fpath, function (err) { obj.fs.unlink(file.path, function (err) { handleUploadFileBatchEx(cmd); }); });
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        handleUploadFileBatchEx(cmd);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            res.send('');
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Instruct one of more agents to download a URL to a given local drive location.
 | 
				
			||||||
 | 
					    function handleUploadFileBatchEx(cmd) {
 | 
				
			||||||
 | 
					        for (var i in cmd.nodeids) {
 | 
				
			||||||
 | 
					            obj.GetNodeWithRights(cmd.domain, cmd.user, cmd.nodeids[i], function (node, rights, visible) {
 | 
				
			||||||
 | 
					                if ((node == null) || ((rights & 8) == 0) || (visible == false)) return; // We don't have remote control rights to this device
 | 
				
			||||||
 | 
					                var agentPath = ((node.agent.id > 0) && (node.agent.id < 5)) ? cmd.windowsPath : cmd.linuxPath;
 | 
				
			||||||
 | 
					                for (var f in cmd.files) {
 | 
				
			||||||
 | 
					                    const acmd = { action: 'wget', overwrite: cmd.overwrite, urlpath: '/agentdownload.ashx?c=' + obj.parent.encodeCookie({ a: 'tmpdl', d: cmd.domain.id, nid: node._id, f: cmd.files[f].target }, obj.parent.loginCookieEncryptionKey), path: obj.path.join(agentPath, cmd.files[f].name) };
 | 
				
			||||||
 | 
					                    var agent = obj.wsagents[node._id];
 | 
				
			||||||
 | 
					                    if (agent != null) { try { agent.send(JSON.stringify(acmd)); } catch (ex) { } }
 | 
				
			||||||
 | 
					                    // TODO: Add support for peer servers.
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Subscribe to all events we are allowed to receive
 | 
					    // Subscribe to all events we are allowed to receive
 | 
				
			||||||
    obj.subscribe = function (userid, target) {
 | 
					    obj.subscribe = function (userid, target) {
 | 
				
			||||||
        const user = obj.users[userid];
 | 
					        const user = obj.users[userid];
 | 
				
			||||||
| 
						 | 
					@ -4793,6 +4876,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
            obj.app.get(url + 'devicepowerevents.ashx', obj.handleDevicePowerEvents);
 | 
					            obj.app.get(url + 'devicepowerevents.ashx', obj.handleDevicePowerEvents);
 | 
				
			||||||
            obj.app.get(url + 'downloadfile.ashx', handleDownloadFile);
 | 
					            obj.app.get(url + 'downloadfile.ashx', handleDownloadFile);
 | 
				
			||||||
            obj.app.post(url + 'uploadfile.ashx', handleUploadFile);
 | 
					            obj.app.post(url + 'uploadfile.ashx', handleUploadFile);
 | 
				
			||||||
 | 
					            obj.app.post(url + 'uploadfilebatch.ashx', handleUploadFileBatch);
 | 
				
			||||||
            obj.app.post(url + 'uploadmeshcorefile.ashx', handleUploadMeshCoreFile);
 | 
					            obj.app.post(url + 'uploadmeshcorefile.ashx', handleUploadMeshCoreFile);
 | 
				
			||||||
            obj.app.get(url + 'userfiles/*', handleDownloadUserFiles);
 | 
					            obj.app.get(url + 'userfiles/*', handleDownloadUserFiles);
 | 
				
			||||||
            obj.app.ws(url + 'echo.ashx', handleEchoWebSocket);
 | 
					            obj.app.ws(url + 'echo.ashx', handleEchoWebSocket);
 | 
				
			||||||
| 
						 | 
					@ -4808,6 +4892,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            obj.app.ws(url + 'devicefile.ashx', function (ws, req) { obj.meshDeviceFileHandler.CreateMeshDeviceFile(obj, ws, null, req, domain); });
 | 
					            obj.app.ws(url + 'devicefile.ashx', function (ws, req) { obj.meshDeviceFileHandler.CreateMeshDeviceFile(obj, ws, null, req, domain); });
 | 
				
			||||||
            obj.app.get(url + 'devicefile.ashx', handleDeviceFile);
 | 
					            obj.app.get(url + 'devicefile.ashx', handleDeviceFile);
 | 
				
			||||||
 | 
					            obj.app.get(url + 'agentdownload.ashx', handleAgentDownloadFile);
 | 
				
			||||||
            obj.app.get(url + 'logo.png', handleLogoRequest);
 | 
					            obj.app.get(url + 'logo.png', handleLogoRequest);
 | 
				
			||||||
            obj.app.get(url + 'loginlogo.png', handleLoginLogoRequest);
 | 
					            obj.app.get(url + 'loginlogo.png', handleLoginLogoRequest);
 | 
				
			||||||
            obj.app.post(url + 'translations', handleTranslationsRequest);
 | 
					            obj.app.post(url + 'translations', handleTranslationsRequest);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue