mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Code fixes & clean up.
This commit is contained in:
		
							parent
							
								
									48368cb2ee
								
							
						
					
					
						commit
						aa6070deb5
					
				
					 6 changed files with 96 additions and 85 deletions
				
			
		
							
								
								
									
										76
									
								
								meshuser.js
									
										
									
									
									
								
							
							
						
						
									
										76
									
								
								meshuser.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -49,6 +49,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
    const MESHRIGHT_CHATNOTIFY = 16384;
 | 
			
		||||
    const MESHRIGHT_UNINSTALL = 32768;
 | 
			
		||||
    const MESHRIGHT_NODESKTOP = 65536;
 | 
			
		||||
    const MESHRIGHT_ADMIN = 0xFFFFFFFF;
 | 
			
		||||
 | 
			
		||||
    // Site rights
 | 
			
		||||
    const SITERIGHT_SERVERBACKUP = 1;           // 0x00000001
 | 
			
		||||
| 
						 | 
				
			
			@ -61,6 +62,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
    const SITERIGHT_NOMESHCMD = 128;            // 0x00000080
 | 
			
		||||
    const SITERIGHT_USERGROUPS = 256;           // 0x00000100
 | 
			
		||||
    const SITERIGHT_RECORDINGS = 512;           // 0x00000200
 | 
			
		||||
    const SITERIGHT_ADMIN = 0xFFFFFFFF;         // 0xFFFFFFFF
 | 
			
		||||
 | 
			
		||||
    var obj = {};
 | 
			
		||||
    obj.user = user;
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +301,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                            if (id.startsWith('mesh/')) {
 | 
			
		||||
                                // Check if we have rights to get this message. If we have limited events on this mesh, don't send the event to the user.
 | 
			
		||||
                                var meshrights = parent.GetMeshRights(user, id);
 | 
			
		||||
                                if ((meshrights == 0xFFFFFFFF) || ((meshrights & MESHRIGHT_LIMITEVENTS) == 0) || (ids.indexOf(user._id) >= 0)) {
 | 
			
		||||
                                if ((meshrights === MESHRIGHT_ADMIN) || ((meshrights & MESHRIGHT_LIMITEVENTS) == 0) || (ids.indexOf(user._id) >= 0)) {
 | 
			
		||||
                                    // We have the device group rights to see this event or we are directly targetted by the event
 | 
			
		||||
                                    ws.send(JSON.stringify({ action: 'event', event: event }));
 | 
			
		||||
                                } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -401,7 +403,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
            if (args.notls == true) { serverinfo.https = false; } else { serverinfo.https = true; serverinfo.redirport = args.redirport; }
 | 
			
		||||
            if (typeof domain.userconsentflags == 'number') { serverinfo.consent = domain.userconsentflags; }
 | 
			
		||||
            if ((typeof domain.usersessionidletimeout == 'number') && (domain.usersessionidletimeout > 0)) { serverinfo.timeout = (domain.usersessionidletimeout * 60 * 1000); }
 | 
			
		||||
            if (user.siteadmin == 0xFFFFFFFF) {
 | 
			
		||||
            if (user.siteadmin === SITERIGHT_ADMIN) {
 | 
			
		||||
                if (parent.parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0) { serverinfo.manageAllDeviceGroups = true; }
 | 
			
		||||
                if (obj.crossDomain === true) { serverinfo.crossDomain = []; for (var i in parent.parent.config.domains) { serverinfo.crossDomain.push(i); } }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -412,7 +414,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
            // Send user information to web socket, this is the first thing we send
 | 
			
		||||
            try { ws.send(JSON.stringify({ action: 'userinfo', userinfo: parent.CloneSafeUser(parent.users[user._id]) })); } catch (ex) { }
 | 
			
		||||
 | 
			
		||||
            if (user.siteadmin == 0xFFFFFFFF) {
 | 
			
		||||
            if (user.siteadmin === SITERIGHT_ADMIN) {
 | 
			
		||||
                // Send server tracing information
 | 
			
		||||
                try { ws.send(JSON.stringify({ action: 'traceinfo', traceSources: parent.parent.debugRemoteSources })); } catch (ex) { }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -765,7 +767,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
            case 'serverconsole':
 | 
			
		||||
                {
 | 
			
		||||
                    // This is a server console message, only process this if full administrator
 | 
			
		||||
                    if (user.siteadmin != 0xFFFFFFFF) break;
 | 
			
		||||
                    if (user.siteadmin != SITERIGHT_ADMIN) break;
 | 
			
		||||
 | 
			
		||||
                    var r = '';
 | 
			
		||||
                    var cmdargs = splitArgs(command.value);
 | 
			
		||||
| 
						 | 
				
			
			@ -1235,7 +1237,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                            var limit = 10000;
 | 
			
		||||
                            if (common.validateInt(command.limit, 1, 60000) == true) { limit = command.limit; }
 | 
			
		||||
 | 
			
		||||
                            if (((rights & MESHRIGHT_LIMITEVENTS) != 0) && (rights != 0xFFFFFFFF)) {
 | 
			
		||||
                            if (((rights & MESHRIGHT_LIMITEVENTS) != 0) && (rights != MESHRIGHT_ADMIN)) {
 | 
			
		||||
                                // Send the list of most recent events for this nodeid that only apply to us, up to 'limit' count
 | 
			
		||||
                                db.GetNodeEventsSelfWithLimit(node._id, domain.id, user._id, limit, function (err, docs) {
 | 
			
		||||
                                    if (err != null) return;
 | 
			
		||||
| 
						 | 
				
			
			@ -1260,7 +1262,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                        // TODO (UserGroups)
 | 
			
		||||
 | 
			
		||||
                        // Remove MeshID's that we do not have rights to see events for
 | 
			
		||||
                        for (var link in obj.user.links) { if (((obj.user.links[link].rights & MESHRIGHT_LIMITEVENTS) != 0) && ((obj.user.links[link].rights != 0xFFFFFFFF))) { exGroupFilter2.push(link); } }
 | 
			
		||||
                        for (var link in obj.user.links) { if (((obj.user.links[link].rights & MESHRIGHT_LIMITEVENTS) != 0) && ((obj.user.links[link].rights != MESHRIGHT_ADMIN))) { exGroupFilter2.push(link); } }
 | 
			
		||||
                        for (var i in filter2) { if (exGroupFilter2.indexOf(filter2[i]) == -1) { filter.push(filter2[i]); } }
 | 
			
		||||
 | 
			
		||||
                        if ((command.limit == null) || (typeof command.limit != 'number')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1467,7 +1469,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                            deluser = parent.users[deluserid];
 | 
			
		||||
                            if (deluser == null) { err = 'User does not exists'; }
 | 
			
		||||
                            else if ((obj.crossDomain !== true) && ((delusersplit.length != 3) || (delusersplit[1] != domain.id))) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
 | 
			
		||||
                            else if ((deluser.siteadmin == 0xFFFFFFFF) && (user.siteadmin != 0xFFFFFFFF)) { err = 'Permission denied'; } // Need full admin to remote another administrator
 | 
			
		||||
                            else if ((deluser.siteadmin === SITERIGHT_ADMIN) && (user.siteadmin != SITERIGHT_ADMIN)) { err = 'Permission denied'; } // Need full admin to remote another administrator
 | 
			
		||||
                            else if ((obj.crossDomain !== true) && (user.groups != null) && (user.groups.length > 0) && ((deluser.groups == null) || (findOne(deluser.groups, user.groups) == false))) { err = 'Invalid user group'; } // Can only perform this operation on other users of our group.
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (ex) { err = 'Validation exception: ' + ex; }
 | 
			
		||||
| 
						 | 
				
			
			@ -1702,7 +1704,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                            newuserid = 'user/' + newuserdomain.id + '/' + command.username.toLowerCase();
 | 
			
		||||
                            if (command.siteadmin != null) {
 | 
			
		||||
                                if ((typeof command.siteadmin != 'number') || (Number.isInteger(command.siteadmin) == false)) { err = 'Invalid site permissions'; } // Check permissions
 | 
			
		||||
                                else if ((user.siteadmin != 0xFFFFFFFF) && ((command.siteadmin & (0xFFFFFFFF - 224)) != 0)) { err = 'Invalid site permissions'; }
 | 
			
		||||
                                else if ((user.siteadmin != SITERIGHT_ADMIN) && ((command.siteadmin & (SITERIGHT_ADMIN - 224)) != 0)) { err = 'Invalid site permissions'; }
 | 
			
		||||
                            }
 | 
			
		||||
                            if (parent.users[newuserid]) { err = 'User already exists'; } // Account already exists
 | 
			
		||||
                            else if ((newuserdomain.auth == 'sspi') || (newuserdomain.auth == 'ldap')) { err = 'Unable to add user in this mode'; }
 | 
			
		||||
| 
						 | 
				
			
			@ -1818,10 +1820,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                    change = 0;
 | 
			
		||||
                    if (chguser) {
 | 
			
		||||
                        // If the target user is admin and we are not admin, no changes can be made.
 | 
			
		||||
                        if ((chguser.siteadmin == 0xFFFFFFFF) && (user.siteadmin != 0xFFFFFFFF)) return;
 | 
			
		||||
                        if ((chguser.siteadmin === SITERIGHT_ADMIN) && (user.siteadmin != SITERIGHT_ADMIN)) return;
 | 
			
		||||
 | 
			
		||||
                        // Can only perform this operation on other users of our group.
 | 
			
		||||
                        if (user.siteadmin != 0xFFFFFFFF) {
 | 
			
		||||
                        if (user.siteadmin != SITERIGHT_ADMIN) {
 | 
			
		||||
                            if ((user.groups != null) && (user.groups.length > 0) && ((chguser.groups == null) || (findOne(chguser.groups, user.groups) == false))) return;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1845,7 +1847,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                        // Site admins can change any server rights, user managers can only change AccountLock, NoMeshCmd and NoNewGroups
 | 
			
		||||
                        if (common.validateInt(command.siteadmin) && (chguser._id !== user._id) && (chguser.siteadmin != command.siteadmin)) { // We can't change our own siteadmin permissions.
 | 
			
		||||
                            var chgusersiteadmin = chguser.siteadmin ? chguser.siteadmin : 0;
 | 
			
		||||
                            if (user.siteadmin == 0xFFFFFFFF) { chguser.siteadmin = command.siteadmin; change = 1; }
 | 
			
		||||
                            if (user.siteadmin === SITERIGHT_ADMIN) { chguser.siteadmin = command.siteadmin; change = 1; }
 | 
			
		||||
                            else if (user.siteadmin & 2) {
 | 
			
		||||
                                var mask = 0xFFFFFF1D; // Mask: 2 (User Mangement) + 32 (Account locked) + 64 (No New Groups) + 128 (No Tools)
 | 
			
		||||
                                if ((user.siteadmin & 256) != 0) { mask -= 256; } // Mask: Manage User Groups
 | 
			
		||||
| 
						 | 
				
			
			@ -1856,7 +1858,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
 | 
			
		||||
                        // When sending a notification about a group change, we need to send to all the previous and new groups.
 | 
			
		||||
                        var allTargetGroups = chguser.groups;
 | 
			
		||||
                        if ((Array.isArray(command.groups)) && ((user._id != command.id) || (user.siteadmin == 0xFFFFFFFF))) {
 | 
			
		||||
                        if ((Array.isArray(command.groups)) && ((user._id != command.id) || (user.siteadmin === SITERIGHT_ADMIN))) {
 | 
			
		||||
                            if (command.groups.length == 0) {
 | 
			
		||||
                                // Remove the user groups
 | 
			
		||||
                                if (chguser.groups != null) { delete chguser.groups; change = 1; }
 | 
			
		||||
| 
						 | 
				
			
			@ -1891,7 +1893,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                            if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
 | 
			
		||||
                            parent.parent.DispatchEvent(targets, obj, event);
 | 
			
		||||
                        }
 | 
			
		||||
                        if ((chguser.siteadmin) && (chguser.siteadmin != 0xFFFFFFFF) && (chguser.siteadmin & 32)) {
 | 
			
		||||
                        if ((chguser.siteadmin) && (chguser.siteadmin !== SITERIGHT_ADMIN) && (chguser.siteadmin & 32)) {
 | 
			
		||||
                            // If the user is locked out of this account, disconnect now
 | 
			
		||||
                            parent.parent.DispatchEvent([chguser._id], obj, 'close'); // Disconnect all this user's sessions
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1934,9 +1936,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                                else if (parent.userGroups[command.clone] == null) { err = "Invalid clone groupid"; }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // Get new user group domain
 | 
			
		||||
                            ugrpdomain = parent.parent.config.domains[clonesplit[1]];
 | 
			
		||||
                            if (ugrpdomain == null) { err = "Invalid domain"; }
 | 
			
		||||
                            if (err == null) {
 | 
			
		||||
                                // Get new user group domain
 | 
			
		||||
                                ugrpdomain = parent.parent.config.domains[clonesplit[1]];
 | 
			
		||||
                                if (ugrpdomain == null) { err = "Invalid domain"; }
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // Get new user group domain
 | 
			
		||||
                            ugrpdomain = domain;
 | 
			
		||||
| 
						 | 
				
			
			@ -1945,7 +1949,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                        }
 | 
			
		||||
 | 
			
		||||
                        // In some situations, we need a verified email address to create a device group.
 | 
			
		||||
                        if ((err == null) && (parent.parent.mailserver != null) && (ugrpdomain.auth != 'sspi') && (ugrpdomain.auth != 'ldap') && (user.emailVerified !== true) && (user.siteadmin != 0xFFFFFFFF)) { err = "Email verification required"; } // User must verify it's email first.
 | 
			
		||||
                        if ((err == null) && (parent.parent.mailserver != null) && (ugrpdomain.auth != 'sspi') && (ugrpdomain.auth != 'ldap') && (user.emailVerified !== true) && (user.siteadmin != SITERIGHT_ADMIN)) { err = "Email verification required"; } // User must verify it's email first.
 | 
			
		||||
                    } catch (ex) { err = "Validation exception: " + ex; }
 | 
			
		||||
 | 
			
		||||
                    // Handle any errors
 | 
			
		||||
| 
						 | 
				
			
			@ -2355,7 +2359,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                    var chguser = parent.users[command.userid];
 | 
			
		||||
                    if (chguser) {
 | 
			
		||||
                        // If we are not full administrator, we can't change anything on a different full administrator
 | 
			
		||||
                        if ((user.siteadmin != 0xFFFFFFFF) & (chguser.siteadmin == 0xFFFFFFFF)) break;
 | 
			
		||||
                        if ((user.siteadmin != SITERIGHT_ADMIN) & (chguser.siteadmin === SITERIGHT_ADMIN)) break;
 | 
			
		||||
 | 
			
		||||
                        // Can only perform this operation on other users of our group.
 | 
			
		||||
                        if ((user.groups != null) && (user.groups.length > 0) && ((chguser.groups == null) || (findOne(chguser.groups, user.groups) == false))) break;
 | 
			
		||||
| 
						 | 
				
			
			@ -2499,10 +2503,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                    var err = null;
 | 
			
		||||
                    try {
 | 
			
		||||
                        // Check if we have new group restriction
 | 
			
		||||
                        if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 64) != 0)) { err = 'Permission denied'; }
 | 
			
		||||
                        if ((user.siteadmin != SITERIGHT_ADMIN) && ((user.siteadmin & 64) != 0)) { err = 'Permission denied'; }
 | 
			
		||||
 | 
			
		||||
                        // In some situations, we need a verified email address to create a device group.
 | 
			
		||||
                        else if ((parent.parent.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap') && (user.emailVerified !== true) && (user.siteadmin != 0xFFFFFFFF)) { err = 'Email verification required'; } // User must verify it's email first.
 | 
			
		||||
                        else if ((parent.parent.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap') && (user.emailVerified !== true) && (user.siteadmin != SITERIGHT_ADMIN)) { err = 'Email verification required'; } // User must verify it's email first.
 | 
			
		||||
 | 
			
		||||
                        // Create mesh
 | 
			
		||||
                        else if (common.validateString(command.meshname, 1, 64) == false) { err = 'Invalid group name'; } // Meshname is between 1 and 64 characters
 | 
			
		||||
| 
						 | 
				
			
			@ -2582,7 +2586,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
 | 
			
		||||
                    // Check if this user has rights to do this
 | 
			
		||||
                    var err = null;
 | 
			
		||||
                    if (parent.GetMeshRights(user, mesh) != 0xFFFFFFFF) { err = 'Access denied'; }
 | 
			
		||||
                    if (parent.GetMeshRights(user, mesh) != MESHRIGHT_ADMIN) { err = 'Access denied'; }
 | 
			
		||||
                    if ((command.meshid.split('/').length != 3) || (command.meshid.split('/')[1] != domain.id)) { err = 'Invalid group'; } // Invalid domain, operation only valid for current domain
 | 
			
		||||
 | 
			
		||||
                    // Handle any errors
 | 
			
		||||
| 
						 | 
				
			
			@ -2760,14 +2764,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
 | 
			
		||||
                            var targetMeshRights = 0;
 | 
			
		||||
                            if ((newuser.links != null) && (newuser.links[command.meshid] != null) && (newuser.links[command.meshid].rights != null)) { targetMeshRights = newuser.links[command.meshid].rights; }
 | 
			
		||||
                            if ((targetMeshRights == 0xFFFFFFFF) && (selfMeshRights != 0xFFFFFFFF)) { msgs.push("Can't change rights of device group administrator"); continue; } // A non-admin can't kick out an admin
 | 
			
		||||
                            if ((targetMeshRights === MESHRIGHT_ADMIN) && (selfMeshRights != MESHRIGHT_ADMIN)) { msgs.push("Can't change rights of device group administrator"); continue; } // A non-admin can't kick out an admin
 | 
			
		||||
 | 
			
		||||
                            if (command.remove === true) {
 | 
			
		||||
                                // Remove mesh from user or user group
 | 
			
		||||
                                delete newuser.links[command.meshid];
 | 
			
		||||
                            } else {
 | 
			
		||||
                                // Adjust rights since we can't add more rights that we have outself for MESHRIGHT_MANAGEUSERS
 | 
			
		||||
                                if ((selfMeshRights != 0xFFFFFFFF) && (command.meshadmin == 0xFFFFFFFF)) { msgs.push("Can't set device group administrator, if not administrator"); continue; }
 | 
			
		||||
                                if ((selfMeshRights != MESHRIGHT_ADMIN) && (command.meshadmin == MESHRIGHT_ADMIN)) { msgs.push("Can't set device group administrator, if not administrator"); continue; }
 | 
			
		||||
                                if (((selfMeshRights & 2) == 0) && ((command.meshadmin & 2) != 0) && ((targetMeshRights & 2) == 0)) { command.meshadmin -= 2; }
 | 
			
		||||
 | 
			
		||||
                                // Add mesh to user or user group
 | 
			
		||||
| 
						 | 
				
			
			@ -3008,7 +3012,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                        // Remove mesh from user
 | 
			
		||||
                        if (deluser.links != null && deluser.links[command.meshid] != null) {
 | 
			
		||||
                            var delmeshrights = deluser.links[command.meshid].rights;
 | 
			
		||||
                            if ((delmeshrights == 0xFFFFFFFF) && (parent.GetMeshRights(user, mesh) != 0xFFFFFFFF)) return; // A non-admin can't kick out an admin
 | 
			
		||||
                            if ((delmeshrights == MESHRIGHT_ADMIN) && (parent.GetMeshRights(user, mesh) != MESHRIGHT_ADMIN)) return; // A non-admin can't kick out an admin
 | 
			
		||||
                            delete deluser.links[command.meshid];
 | 
			
		||||
                            if (deluserid.startsWith('user/')) { db.SetUser(deluser); }
 | 
			
		||||
                            else if (deluserid.startsWith('ugrp/')) { db.Set(deluser); }
 | 
			
		||||
| 
						 | 
				
			
			@ -3523,7 +3527,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
 | 
			
		||||
                    // Get the node and the rights for this node
 | 
			
		||||
                    parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
 | 
			
		||||
                        if ((node == null) || (((rights & MESHRIGHT_AGENTCONSOLE) == 0) && (user.siteadmin != 0xFFFFFFFF))) return;
 | 
			
		||||
                        if ((node == null) || (((rights & MESHRIGHT_AGENTCONSOLE) == 0) && (user.siteadmin != SITERIGHT_ADMIN))) return;
 | 
			
		||||
 | 
			
		||||
                        if (command.type == 'default') {
 | 
			
		||||
                            // Send the default core to the agent
 | 
			
		||||
| 
						 | 
				
			
			@ -3555,7 +3559,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
 | 
			
		||||
                    // Get the node and the rights for this node
 | 
			
		||||
                    parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
 | 
			
		||||
                        if ((node == null) || (((rights & MESHRIGHT_AGENTCONSOLE) == 0) && (user.siteadmin != 0xFFFFFFFF))) return;
 | 
			
		||||
                        if ((node == null) || (((rights & MESHRIGHT_AGENTCONSOLE) == 0) && (user.siteadmin != SITERIGHT_ADMIN))) return;
 | 
			
		||||
 | 
			
		||||
                        // Force mesh agent disconnection
 | 
			
		||||
                        parent.forceMeshAgentDisconnect(user, domain, node._id, command.disconnectMode);
 | 
			
		||||
| 
						 | 
				
			
			@ -4188,7 +4192,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'traceinfo': {
 | 
			
		||||
                if ((user.siteadmin == 0xFFFFFFFF) && (typeof command.traceSources == 'object')) {
 | 
			
		||||
                if ((user.siteadmin === SITERIGHT_ADMIN) && (typeof command.traceSources == 'object')) {
 | 
			
		||||
                    parent.parent.debugRemoteSources = command.traceSources;
 | 
			
		||||
                    parent.parent.DispatchEvent(['*'], obj, { action: 'traceinfo', userid: user._id, username: user.name, traceSources: command.traceSources, nolog: 1, domain: domain.id });
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -4228,7 +4232,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                // Get the node and the rights for this node
 | 
			
		||||
                parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
 | 
			
		||||
                    // Check if this user has rights to do this
 | 
			
		||||
                    if (rights == 0xFFFFFFFF) {
 | 
			
		||||
                    if (rights == MESHRIGHT_ADMIN) {
 | 
			
		||||
                        var token = parent.parent.mqttbroker.generateLogin(node.meshid, node._id);
 | 
			
		||||
                        var r = { action: 'getmqttlogin', responseid: command.responseid, nodeid: node._id, user: token.user, pass: token.pass };
 | 
			
		||||
                        const serverName = parent.getWebServerName(domain);
 | 
			
		||||
| 
						 | 
				
			
			@ -4278,7 +4282,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
            }
 | 
			
		||||
            case 'distributeCore': {
 | 
			
		||||
                // This is only available when plugins are enabled since it could cause stress on the server
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                for (var i in command.nodes) {
 | 
			
		||||
                    parent.sendMeshAgentCore(user, domain, command.nodes[i]._id, 'default');
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -4286,14 +4290,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
            }
 | 
			
		||||
            case 'plugins': {
 | 
			
		||||
                // Since plugin actions generally require a server restart, use the Full admin permission
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                parent.db.getPlugins(function(err, docs) {
 | 
			
		||||
                    try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } 
 | 
			
		||||
                });
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'pluginLatestCheck': {
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                parent.parent.pluginHandler.getPluginLatest()
 | 
			
		||||
                .then(function(latest) {
 | 
			
		||||
                    try { ws.send(JSON.stringify({ action: 'pluginVersionsAvailable', list: latest })); } catch (ex) { } 
 | 
			
		||||
| 
						 | 
				
			
			@ -4301,7 +4305,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'addplugin': {
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                try {
 | 
			
		||||
                    parent.parent.pluginHandler.getPluginConfig(command.url)
 | 
			
		||||
                    .then(parent.parent.pluginHandler.addPlugin)
 | 
			
		||||
| 
						 | 
				
			
			@ -4318,7 +4322,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'installplugin': {
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                parent.parent.pluginHandler.installPlugin(command.id, command.version_only, null, function(){
 | 
			
		||||
                    parent.db.getPlugins(function(err, docs) {
 | 
			
		||||
                        try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } 
 | 
			
		||||
| 
						 | 
				
			
			@ -4329,7 +4333,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'disableplugin': {
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                parent.parent.pluginHandler.disablePlugin(command.id, function(){
 | 
			
		||||
                    parent.db.getPlugins(function(err, docs) {
 | 
			
		||||
                        try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } 
 | 
			
		||||
| 
						 | 
				
			
			@ -4340,7 +4344,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'removeplugin': {
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                parent.parent.pluginHandler.removePlugin(command.id, function(){
 | 
			
		||||
                    parent.db.getPlugins(function(err, docs) {
 | 
			
		||||
                        try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } 
 | 
			
		||||
| 
						 | 
				
			
			@ -4349,7 +4353,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case 'getpluginversions': {
 | 
			
		||||
                if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                if ((user.siteadmin != SITERIGHT_ADMIN) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled
 | 
			
		||||
                parent.parent.pluginHandler.getPluginVersions(command.id)
 | 
			
		||||
                .then(function (versionInfo) {
 | 
			
		||||
                    try { ws.send(JSON.stringify({ action: 'downgradePluginVersions', info: versionInfo, error: null })); } catch (ex) { } 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ module.exports.pluginHandler = function (parent) {
 | 
			
		|||
 | 
			
		||||
    obj.fs = require('fs');
 | 
			
		||||
    obj.path = require('path');
 | 
			
		||||
    obj.common = require('./common.js');
 | 
			
		||||
    obj.parent = parent;
 | 
			
		||||
    obj.pluginPath = obj.parent.path.join(obj.parent.datapath, 'plugins');
 | 
			
		||||
    obj.plugins = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -471,7 +472,7 @@ module.exports.pluginHandler = function (parent) {
 | 
			
		|||
                        versStr += chunk;
 | 
			
		||||
                    });
 | 
			
		||||
                    res.on('end', function () {
 | 
			
		||||
                        if (versStr[0] == '{' || versStr[0] == '[') { // let's be sure we're JSON
 | 
			
		||||
                        if ((versStr[0] == '{') || (versStr[0] == '[')) { // let's be sure we're JSON
 | 
			
		||||
                            try {
 | 
			
		||||
                                var vers = JSON.parse(versStr);
 | 
			
		||||
                                var vList = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -515,9 +516,11 @@ module.exports.pluginHandler = function (parent) {
 | 
			
		|||
    };
 | 
			
		||||
 | 
			
		||||
    obj.handleAdminReq = function (req, res, user, serv) {
 | 
			
		||||
        if (obj.common.isAlphaNumeric(req.query.pin) !== true) { res.sendStatus(401); return; }
 | 
			
		||||
        var path = obj.path.join(obj.pluginPath, req.query.pin, 'views');
 | 
			
		||||
        if (obj.common.IsFilenameValid(path) !== true) { res.sendStatus(401); return; }
 | 
			
		||||
        serv.app.set('views', path);
 | 
			
		||||
        if (obj.plugins[req.query.pin] != null && typeof obj.plugins[req.query.pin].handleAdminReq == 'function') {
 | 
			
		||||
        if ((obj.plugins[req.query.pin] != null) && (typeof obj.plugins[req.query.pin].handleAdminReq == 'function')) {
 | 
			
		||||
            obj.plugins[req.query.pin].handleAdminReq(req, res, user);
 | 
			
		||||
        } else {
 | 
			
		||||
            res.sendStatus(401);
 | 
			
		||||
| 
						 | 
				
			
			@ -525,9 +528,11 @@ module.exports.pluginHandler = function (parent) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    obj.handleAdminPostReq = function (req, res, user, serv) {
 | 
			
		||||
        if (obj.common.isAlphaNumeric(req.query.pin) !== true) { res.sendStatus(401); return; }
 | 
			
		||||
        var path = obj.path.join(obj.pluginPath, req.query.pin, 'views');
 | 
			
		||||
        if (obj.common.IsFilenameValid(path) !== true) { res.sendStatus(401); return; }
 | 
			
		||||
        serv.app.set('views', path);
 | 
			
		||||
        if (obj.plugins[req.query.pin] != null && typeof obj.plugins[req.query.pin].handleAdminPostReq == 'function') {
 | 
			
		||||
        if ((obj.plugins[req.query.pin] != null) && (typeof obj.plugins[req.query.pin].handleAdminPostReq == 'function')) {
 | 
			
		||||
            obj.plugins[req.query.pin].handleAdminPostReq(req, res, user);
 | 
			
		||||
        } else {
 | 
			
		||||
            res.sendStatus(401);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1751,7 +1751,7 @@
 | 
			
		|||
                    var publiclink = '';
 | 
			
		||||
                    if (publicfolder) { publiclink = ' (<a style=cursor:pointer onclick=\'p5showPublicLink("' + publicPath + '/' + f.nx + '")\'>' + "Link" + '</a>)'; }
 | 
			
		||||
                    if (f.s > 0) { link = '<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"downloadfile.ashx?link=' + encodeURIComponent(filetreelinkpath + '/' + f.nx) + '\">' + shortname + '</a>' + publiclink; }
 | 
			
		||||
                    h = '<div class=filelist file=3><input file=3 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value=\'' + f.nx + '\'> <span style=float:right;padding-right:4px>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
 | 
			
		||||
                    h = '<div class=filelist file=3><input file=3 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value=\'' + f.nx + '\'> <span style=float:right;padding-right:4px>' + EscapeHtml(fsize) + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (f.t < 3) { html1 += h; } else { html2 += h; }
 | 
			
		||||
| 
						 | 
				
			
			@ -2378,14 +2378,14 @@
 | 
			
		|||
                if (node.intelamt != null) {
 | 
			
		||||
                    var str = '';
 | 
			
		||||
                    var provisioningStates = { 0: nobreak("Not Activated (Pre)"), 1: nobreak("Not Activated (In)"), 2: nobreak("Activated") };
 | 
			
		||||
                    if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>' + nobreak("Unknown State") + '</i>, v' + node.intelamt.ver; } else
 | 
			
		||||
                    if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>' + nobreak("Unknown State") + '</i>, v' + EscapeHtml(node.intelamt.ver); } else
 | 
			
		||||
 | 
			
		||||
                        if ((node.intelamt.ver == null) && (node.intelamt.state == 2)) { str += '<i>' + "Activated" + '</i>'; }
 | 
			
		||||
                        else if ((node.intelamt.ver == null) || (node.intelamt.state == null)) { str += '<i>' + "Unknown Version & State" + '</i>'; }
 | 
			
		||||
                        else {
 | 
			
		||||
                            str += provisioningStates[node.intelamt.state];
 | 
			
		||||
                            if (node.intelamt.flags) { if (node.intelamt.flags & 2) { str = ' <span>' + "CCM" + '</span>'; } else if (node.intelamt.flags & 4) { str = ' <span>' + "ACM" + '</span>'; } }
 | 
			
		||||
                            str += (', v' + node.intelamt.ver);
 | 
			
		||||
                            str += (', v' + EscapeHtml(node.intelamt.ver));
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    if (node.intelamt.tls == 1) { str += ', <span>' + "TLS" + '</span>'; }
 | 
			
		||||
| 
						 | 
				
			
			@ -3669,7 +3669,7 @@
 | 
			
		|||
                        if (m[0].gatewaymac) {
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}, Gateway: {1}", EscapeHtml(m[0].mac), EscapeHtml(m[0].gatewaymac)));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}", m[0].mac));
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}", EscapeHtml(m[0].mac)));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    for (var j = 0; j < m.length; j++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3698,7 +3698,7 @@
 | 
			
		|||
            // Attribute: Intel AMT
 | 
			
		||||
            if (node.intelamt != null) {
 | 
			
		||||
                var x = '';
 | 
			
		||||
                x += addDetailItem("Version", (node.intelamt.ver) ? ('v' + node.intelamt.ver) : ('<i>' + "Unknown" + '</i>'), s);
 | 
			
		||||
                x += addDetailItem("Version", (node.intelamt.ver) ? ('v' + EscapeHtml(node.intelamt.ver)) : ('<i>' + "Unknown" + '</i>'), s);
 | 
			
		||||
                var provisioningStates = { 0: nobreak("Not Activated (Pre)"), 1: nobreak("Not Activated (In)"), 2: nobreak("Activated") };
 | 
			
		||||
                var provisioningMode = '';
 | 
			
		||||
                if ((node.intelamt.state == 2) && node.intelamt.flags) { if (node.intelamt.flags & 2) { provisioningMode = (', ' + "Client Control Mode (CCM)"); } else if (node.intelamt.flags & 4) { provisioningMode = (', ' + "Admin Control Mode (ACM)"); } }
 | 
			
		||||
| 
						 | 
				
			
			@ -4220,7 +4220,7 @@
 | 
			
		|||
        function addLink(x, f) { return '<a style=cursor:pointer;color:darkblue;text-decoration:none onclick=\'' + f + '\'>♦ ' + x + '</a>'; }
 | 
			
		||||
        function addLinkConditional(x, f, c) { if (c) return addLink(x, f); return x; }
 | 
			
		||||
        function passwordcheck(p) { var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()]).{8,}/; return re.test(p); }
 | 
			
		||||
        function getFileSizeStr(size) { if (size == 1) return "1 byte"; return format('{0} bytes', size); }
 | 
			
		||||
        function getFileSizeStr(size) { if (typeof size != 'number') { size = 0; } if (size == 1) return "1 byte"; return format('{0} bytes', size); }
 | 
			
		||||
        function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); }
 | 
			
		||||
        function focusTextBox(x) { setTimeout(function () { Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); }
 | 
			
		||||
        var isFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); } })();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5316,14 +5316,14 @@
 | 
			
		|||
                if (node.intelamt != null) {
 | 
			
		||||
                    var str = '';
 | 
			
		||||
                    var provisioningStates = { 0: nobreak("Not Activated (Pre)"), 1: nobreak("Not Activated (In)"), 2: nobreak("Activated") };
 | 
			
		||||
                    if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>' + "Unknown State" + '</i>, v' + node.intelamt.ver; } else
 | 
			
		||||
                    if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>' + "Unknown State" + '</i>, v' + EscapeHtml(node.intelamt.ver); } else
 | 
			
		||||
 | 
			
		||||
                        if ((node.intelamt.ver == null) && (node.intelamt.state == 2)) { str += '<i>' + "Activated" + '</i>'; }
 | 
			
		||||
                        else if ((node.intelamt.ver == null) || (node.intelamt.state == null)) { str += '<i>' + "Unknown Version & State" + '</i>'; }
 | 
			
		||||
                        else {
 | 
			
		||||
                            str += provisioningStates[node.intelamt.state];
 | 
			
		||||
                            if ((node.intelamt.state == 2) && node.intelamt.flags) { if (node.intelamt.flags & 2) { str += ' <span title="' + "Intel AMT is activated in Client Control Mode" + '">' + "CCM" + '</span>'; } else if (node.intelamt.flags & 4) { str += ' <span title="' + "Intel AMT is activated in Admin Control Mode" + '">' + "ACM" + '</span>'; } }
 | 
			
		||||
                            str += (', v' + node.intelamt.ver);
 | 
			
		||||
                            str += (', v' + EscapeHtml(node.intelamt.ver));
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    if (node.intelamt.tls == 1) { str += ', <span title="' + "Intel AMT is setup with TLS network security" + '">' + "TLS" + '</span>'; }
 | 
			
		||||
| 
						 | 
				
			
			@ -6959,8 +6959,8 @@
 | 
			
		|||
                for (var i in p) {
 | 
			
		||||
                    if (p[i].p != 0) {
 | 
			
		||||
                        var c = p[i].c;
 | 
			
		||||
                        if (c.length > 30) { c = '<span title="' + c + '">' + c.substring(0,30) + '...</span>' }
 | 
			
		||||
                        x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + p[i].p + '</div><a href=# style=float:right;padding-right:5px;cursor:pointer title="' + "Stop process" + '" onclick=\'return stopProcess(' + p[i].p + ',"' + p[i].c + '")\'><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u ? p[i].u : '') + '</div><div>' + c + '</div></div>';
 | 
			
		||||
                        if (c.length > 30) { c = '<span title="' + EscapeHtml(c) + '">' + EscapeHTML(c.substring(0,30)) + '...</span>' } else { c = EscapeHtml(c); }
 | 
			
		||||
                        x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + EscapeHtml(p[i].p) + '</div><a href=# style=float:right;padding-right:5px;cursor:pointer title="' + "Stop process" + '" onclick=\'return stopProcess(' + EscapeHtml(p[i].p) + ',"' + EscapeHtml(p[i].c) + '")\'><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u ? EscapeHtml(p[i].u) : '') + '</div><div>' + c + '</div></div>';
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                QH('DeskToolsProcesses', x);
 | 
			
		||||
| 
						 | 
				
			
			@ -6989,8 +6989,8 @@
 | 
			
		|||
                for (var i in s) {
 | 
			
		||||
                    if (s[i].p != 0) {
 | 
			
		||||
                        var c = s[i].d;
 | 
			
		||||
                        if (c.length > 30) { c = '<span title="' + c + '">' + c.substring(0, 30) + '...</span>' }
 | 
			
		||||
                        x += '<div onclick=showServiceDetailsDialog(' + s[i].i + ') class=deskToolsBar><div style=width:70px;float:left;padding-right:5px>' + s[i].p + '</div><div>' + c + '</div></div>';
 | 
			
		||||
                        if (c.length > 30) { c = '<span title="' + c + '">' + c.substring(0, 30) + '...</span>' } else { c = EscapeHtml(c); }
 | 
			
		||||
                        x += '<div onclick=showServiceDetailsDialog(' + s[i].i + ') class=deskToolsBar><div style=width:70px;float:left;padding-right:5px>' + EscapeHtml(s[i].p) + '</div><div>' + c + '</div></div>';
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                QH('DeskToolsServices', x);
 | 
			
		||||
| 
						 | 
				
			
			@ -7555,7 +7555,7 @@
 | 
			
		|||
                } else {
 | 
			
		||||
                    var link = shortname;
 | 
			
		||||
                    if (f.s > 0) { link = '<a href=# style=cursor:pointer onclick="return p13downloadfile(\'' + encodeURIComponentEx(newlinkpath + '/' + name) + '\',\'' + encodeURIComponentEx(name) + '\',' + f.s + ')">' + shortname + '</a>'; }
 | 
			
		||||
                    h = '<div id=fileEntry cmenu=filesContextMenu 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>';
 | 
			
		||||
                    h = '<div id=fileEntry cmenu=filesContextMenu 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>' + EscapeHTML(fsize) + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (f.t < 3) { html1 += h; } else { html2 += h; }
 | 
			
		||||
| 
						 | 
				
			
			@ -8145,7 +8145,7 @@
 | 
			
		|||
                        if (m.gatewaymac) {
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}, Gateway: {1}", EscapeHtml(m.mac), EscapeHtml(m.gatewaymac)));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}", m.mac));
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}", EscapeHtml(m.mac)));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    for (var j in m.ipv4layer) {
 | 
			
		||||
| 
						 | 
				
			
			@ -8178,7 +8178,7 @@
 | 
			
		|||
                        if (m[0].gatewaymac) {
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}, Gateway: {1}", EscapeHtml(m[0].mac), EscapeHtml(m[0].gatewaymac)));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}", m[0].mac));
 | 
			
		||||
                            x += addDetailItem("MAC Layer", format("MAC: {0}", EscapeHtml(m[0].mac)));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    for (var j = 0; j < m.length; j++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -8207,7 +8207,7 @@
 | 
			
		|||
            // Attribute: Intel AMT
 | 
			
		||||
            if (node.intelamt != null) {
 | 
			
		||||
                var x = '';
 | 
			
		||||
                x += addDetailItem("Version", (node.intelamt.ver)?('v' + node.intelamt.ver):('<i>' + "Unknown" + '</i>'), s);
 | 
			
		||||
                x += addDetailItem("Version", (node.intelamt.ver)?('v' + EscapeHtml(node.intelamt.ver)):('<i>' + "Unknown" + '</i>'), s);
 | 
			
		||||
                var provisioningStates = { 0: nobreak("Not Activated (Pre)"), 1: nobreak("Not Activated (In)"), 2: nobreak("Activated") };
 | 
			
		||||
                var provisioningMode = '';
 | 
			
		||||
                if ((node.intelamt.state == 2) && node.intelamt.flags) { if (node.intelamt.flags & 2) { provisioningMode = (', ' + "Client Control Mode (CCM)"); } else if (node.intelamt.flags & 4) { provisioningMode = (', ' + "Admin Control Mode (ACM)"); } }
 | 
			
		||||
| 
						 | 
				
			
			@ -10069,7 +10069,7 @@
 | 
			
		|||
        function getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fc'); return checkboxes.length; }
 | 
			
		||||
        function p5selectallfile() { var nv = (getFileSelCount() == 0), checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p5setActions(); }
 | 
			
		||||
        function setupBackPointers(x) { if (x.f != null) { var fs = 0, fc = 0; for (var i in x.f) { setupBackPointers(x.f[i]); x.f[i].parent = x; if (x.f[i].s) { fs += x.f[i].s; } if (x.f[i].c) { fc += x.f[i].c; } if (x.f[i].t == 3) { fc++; } } x.s = fs; x.c = fc; } return x; }
 | 
			
		||||
        function getFileSizeStr(size) { if (size == 1) return "1 byte"; return format("{0} bytes", size); }
 | 
			
		||||
        function getFileSizeStr(size) { if (typeof size != 'number') { size = 0; } if (size == 1) return "1 byte"; return format("{0} bytes", size); }
 | 
			
		||||
        function p5folderup(x) { if (x == null) { filetreelocation.pop(); } else { while (filetreelocation.length > x) { filetreelocation.pop(); } } updateFiles(); return false; }
 | 
			
		||||
        function p5folderset(x) { filetreelocation.push(decodeURIComponent(x)); updateFiles(); return false; }
 | 
			
		||||
        function p5createfolder() { setDialogMode(2, "New Folder", 3, p5createfolderEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% />'); focusTextBox('p5renameinput'); p5fileNameCheck(); }
 | 
			
		||||
| 
						 | 
				
			
			@ -11938,7 +11938,7 @@
 | 
			
		|||
                } else {
 | 
			
		||||
                    var link = shortname;
 | 
			
		||||
                    //if (f.s > 0) { link = "<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"downloadfile.ashx?link=" + encodeURIComponentEx(filetreelinkpath + '/' + f.nx) + "\">" + shortname + "</a>"; }
 | 
			
		||||
                    h = '<div class=filelist file=3><input style=float:left name=fcx class=fcb type=checkbox onchange=d3setActions() value="' + f.nx + '"> <span style=float:right>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
 | 
			
		||||
                    h = '<div class=filelist file=3><input style=float:left name=fcx class=fcb type=checkbox onchange=d3setActions() value="' + f.nx + '"> <span style=float:right>' + EscapeHtml(fsize) + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (f.t < 3) { html1 += h; } else { html2 += h; }
 | 
			
		||||
| 
						 | 
				
			
			@ -11991,18 +11991,18 @@
 | 
			
		|||
            } else {
 | 
			
		||||
                for (var i in notifications) {
 | 
			
		||||
                    var n = notifications[i], t = '', d = new Date(n.time), icon = 0;
 | 
			
		||||
                    if (n.title != null) { t = '<b>' + n.title + '</b>: ' }
 | 
			
		||||
                    if (n.title != null) { t = '<b>' + EscapeHtml(n.title) + '</b>: ' }
 | 
			
		||||
                    if (n.nodeid != null) {
 | 
			
		||||
                        var node = getNodeFromId(n.nodeid);
 | 
			
		||||
                        if (node != null) {
 | 
			
		||||
                            icon = node.icon;
 | 
			
		||||
                            if (notifySettings & 16) { t = '<b>' + meshes[node.meshid].name + ' / ' + node.name + '</b>: '; } else { t = '<b>' + node.name + '</b>: '; } // Display with or without group name
 | 
			
		||||
                            if (notifySettings & 16) { t = '<b>' + EscapeHtml(meshes[node.meshid].name) + ' / ' + EscapeHtml(node.name) + '</b>: '; } else { t = '<b>' + EscapeHtml(node.name) + '</b>: '; } // Display with or without group name
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    r += '<div title="' + format("Occured at {0}", printDateTime(d)) + '" id="notifyx' + n.id + '" class=notification style="cursor:pointer;border-top:1px solid ' + ((r == '') ? 'transparent' : 'orange') + '">';
 | 
			
		||||
                    if (icon) { r += '<div class=j' + icon + ' onclick="notificationSelected(' + n.id + ')" style=margin:5px;float:left></div>'; }
 | 
			
		||||
                    r += '<div onclick="notificationDelete(' + n.id + ')" class=unselectable title="' + "Clear this notification" + '" style=margin:5px;float:right;color:orange><b>X</b></div><div onclick="notificationSelected(' + n.id + ')" style=margin:5px>' + t + n.text + '</div></div>';
 | 
			
		||||
                    r += '<div onclick="notificationDelete(' + n.id + ')" class=unselectable title="' + "Clear this notification" + '" style=margin:5px;float:right;color:orange><b>X</b></div><div onclick="notificationSelected(' + n.id + ')" style=margin:5px>' + t + EscapeHtml(n.text) + '</div></div>';
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            var deleteall = '';
 | 
			
		||||
| 
						 | 
				
			
			@ -12656,9 +12656,9 @@
 | 
			
		|||
                installedPluginList.forEach(function(p){
 | 
			
		||||
                    var cant_action = [];
 | 
			
		||||
                    if (p.hasAdminPanel == true && p.status) {
 | 
			
		||||
                        p.nameHtml = '<a onclick="return goPlugin(\'' + p.shortName + '\', \'' + p.name.replace(/'/g, "\\'") + '\');">' + p.name + '</a>';
 | 
			
		||||
                        p.nameHtml = '<a onclick="return goPlugin(\'' + p.shortName + '\', \'' + p.name.replace(/'/g, "\\'") + '\');">' + EscapeHtml(p.name) + '</a>';
 | 
			
		||||
                    } else {
 | 
			
		||||
                        p.nameHtml = p.name;
 | 
			
		||||
                        p.nameHtml = EscapeHtml(p.name);
 | 
			
		||||
                    }
 | 
			
		||||
                    p.statusText = statusMap[p.status].text;
 | 
			
		||||
                    p.statusColor = statusMap[p.status].color;
 | 
			
		||||
| 
						 | 
				
			
			@ -12691,7 +12691,7 @@
 | 
			
		|||
                    }
 | 
			
		||||
                    p.actions += '</select>';
 | 
			
		||||
 | 
			
		||||
                    var tpl = '<td><img style=margin-top:3px src=images/plugin24.png></td><td class=gradTable1> </td><td class=gradTable2>' + p.nameHtml + '</td><td class=gradTable2>' + p.description + '</td><td class=gradTable2 style=text-align:center><a href="' + p.homepage + '" target="_blank">Home</a></td><td class=gradTable2 style=text-align:center>' + p.version + '</td><td style=text-align:center class="pluginUpgradeAvailable gradTable2">' + p.upgradeAvail + '</td><td class=gradTable2 style="text-align:center;color:#' + p.statusColor + '">' + p.statusText + '</td><td class="pluginAction gradTable2" style=text-align:center>' + p.actions + '</td><td class=gradTable3> </td>';
 | 
			
		||||
                    var tpl = '<td><img style=margin-top:3px src=images/plugin24.png></td><td class=gradTable1> </td><td class=gradTable2>' + p.nameHtml + '</td><td class=gradTable2>' + EscapeHtml(p.description) + '</td><td class=gradTable2 style=text-align:center><a href="' + EscapeHtml(p.homepage) + '" target="_blank">Home</a></td><td class=gradTable2 style=text-align:center>' + EscapeHtml(p.version) + '</td><td style=text-align:center class="pluginUpgradeAvailable gradTable2">' + p.upgradeAvail + '</td><td class=gradTable2 style="text-align:center;color:#' + p.statusColor + '">' + p.statusText + '</td><td class="pluginAction gradTable2" style=text-align:center>' + p.actions + '</td><td class=gradTable3> </td>';
 | 
			
		||||
                    var tr = tbl.insertRow(-1);
 | 
			
		||||
                    tr.innerHTML = tpl;
 | 
			
		||||
                    tr.classList.add('p42tblRow');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,7 +74,7 @@
 | 
			
		|||
        if (name != '') { document.title = name + ' - ' + document.title; }
 | 
			
		||||
 | 
			
		||||
        function load() {
 | 
			
		||||
            if (name != '') { QH('computerName', name); }
 | 
			
		||||
            if (name != '') { QH('computerName', EscapeHtml(name)); }
 | 
			
		||||
            client = MstscClient.create(Q('myCanvas'));
 | 
			
		||||
            Q('inputDomain').focus();
 | 
			
		||||
            canvas = Q('myCanvas');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										44
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										44
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1513,28 +1513,28 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
                var idsplit = cookie.u.split('/');
 | 
			
		||||
                if ((idsplit.length != 2) || (idsplit[0] != domain.id)) {
 | 
			
		||||
                    parent.debug('web', 'handleCheckMailRequest: Invalid domain.');
 | 
			
		||||
                    render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 1, domainurl: encodeURIComponent(domain.url) }, req, domain));
 | 
			
		||||
                    render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 1, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
                } else {
 | 
			
		||||
                    obj.db.Get('user/' + cookie.u.toLowerCase(), function (err, docs) {
 | 
			
		||||
                        if (docs.length == 0) {
 | 
			
		||||
                            parent.debug('web', 'handleCheckMailRequest: Invalid username.');
 | 
			
		||||
                            render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 2, domainurl: encodeURIComponent(domain.url), arg1: encodeURIComponent(idsplit[1]) }, req, domain));
 | 
			
		||||
                            render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 2, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), arg1: encodeURIComponent(idsplit[1]).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            var user = docs[0];
 | 
			
		||||
                            if (user.email != cookie.e) {
 | 
			
		||||
                                parent.debug('web', 'handleCheckMailRequest: Invalid e-mail.');
 | 
			
		||||
                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 3, domainurl: encodeURIComponent(domain.url), arg1: encodeURIComponent(user.email), arg2: encodeURIComponent(user.name) }, req, domain));
 | 
			
		||||
                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 3, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), arg1: encodeURIComponent(user.email).replace(/'/g, '%27'), arg2: encodeURIComponent(user.name).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
                            } else {
 | 
			
		||||
                                if (cookie.a == 1) {
 | 
			
		||||
                                    // Account email verification
 | 
			
		||||
                                    if (user.emailVerified == true) {
 | 
			
		||||
                                        parent.debug('web', 'handleCheckMailRequest: email already verified.');
 | 
			
		||||
                                        render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 4, domainurl: encodeURIComponent(domain.url), arg1: encodeURIComponent(user.email), arg2: encodeURIComponent(user.name) }, req, domain));
 | 
			
		||||
                                        render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 4, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), arg1: encodeURIComponent(user.email).replace(/'/g, '%27'), arg2: encodeURIComponent(user.name).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        obj.db.GetUserWithVerifiedEmail(domain.id, user.email, function (err, docs) {
 | 
			
		||||
                                            if (docs.length > 0) {
 | 
			
		||||
                                                parent.debug('web', 'handleCheckMailRequest: email already in use.');
 | 
			
		||||
                                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 5, domainurl: encodeURIComponent(domain.url), arg1: encodeURIComponent(user.email) }, req, domain));
 | 
			
		||||
                                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 5, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), arg1: encodeURIComponent(user.email).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
                                            } else {
 | 
			
		||||
                                                parent.debug('web', 'handleCheckMailRequest: email verification success.');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1549,7 +1549,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
                                                obj.parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
 | 
			
		||||
 | 
			
		||||
                                                // Send the confirmation page
 | 
			
		||||
                                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 6, domainurl: encodeURIComponent(domain.url), arg1: encodeURIComponent(user.email), arg2: encodeURIComponent(user.name) }, req, domain));
 | 
			
		||||
                                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 6, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), arg1: encodeURIComponent(user.email).replace(/'/g, '%27'), arg2: encodeURIComponent(user.name).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
 | 
			
		||||
                                                // Send a notification
 | 
			
		||||
                                                obj.parent.DispatchEvent([user._id], obj, { action: 'notify', value: 'Email verified:<br /><b>' + EscapeHtml(user.email) + '</b>.', nolog: 1, id: Math.random() });
 | 
			
		||||
| 
						 | 
				
			
			@ -1563,7 +1563,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
                                    // Account reset
 | 
			
		||||
                                    if (user.emailVerified != true) {
 | 
			
		||||
                                        parent.debug('web', 'handleCheckMailRequest: email not verified.');
 | 
			
		||||
                                        render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 7, domainurl: encodeURIComponent(domain.url), arg1: EscapeHtml(user.email), arg2: EscapeHtml(user.name) }, req, domain));
 | 
			
		||||
                                        render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 7, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), arg1: EscapeHtml(user.email), arg2: EscapeHtml(user.name) }, req, domain));
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        // Set a temporary password
 | 
			
		||||
                                        obj.crypto.randomBytes(16, function (err, buf) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1588,7 +1588,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
                                                obj.parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
 | 
			
		||||
 | 
			
		||||
                                                // Send the new password
 | 
			
		||||
                                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 8, domainurl: encodeURIComponent(domain.url), arg1: EscapeHtml(user.name), arg2: EscapeHtml(newpass) }, req, domain));
 | 
			
		||||
                                                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 8, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), arg1: EscapeHtml(user.name), arg2: EscapeHtml(newpass) }, req, domain));
 | 
			
		||||
                                                parent.debug('web', 'handleCheckMailRequest: send temporary password.');
 | 
			
		||||
 | 
			
		||||
                                                // Send to authlog
 | 
			
		||||
| 
						 | 
				
			
			@ -1597,14 +1597,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
                                        });
 | 
			
		||||
                                    }
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 9, domainurl: encodeURIComponent(domain.url) }, req, domain));
 | 
			
		||||
                                    render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 9, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 10, domainurl: encodeURIComponent(domain.url) }, req, domain));
 | 
			
		||||
                render(req, res, getRenderPage('message', req, domain), getRenderArgs({ titleid: 1, msgid: 10, domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1637,7 +1637,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        if (req.query.ws != null) {
 | 
			
		||||
            // This is a query with a websocket relay cookie, check that the cookie is valid and use it.
 | 
			
		||||
            var rcookie = parent.decodeCookie(req.query.ws, parent.loginCookieEncryptionKey, 240); // Cookie with 4 hour timeout
 | 
			
		||||
            if ((rcookie != null) && (rcookie.domainid == domain.id) && (rcookie.nodeid != null) && (rcookie.tcpport != null)) { render(req, res, getRenderPage('mstsc', req, domain), getRenderArgs({ cookie: req.query.ws, name: encodeURIComponent(req.query.name) }, req, domain)); return; }
 | 
			
		||||
            if ((rcookie != null) && (rcookie.domainid == domain.id) && (rcookie.nodeid != null) && (rcookie.tcpport != null)) {
 | 
			
		||||
                render(req, res, getRenderPage('mstsc', req, domain), getRenderArgs({ cookie: req.query.ws, name: encodeURIComponent(req.query.name).replace(/'/g, '%27') }, req, domain)); return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get the logged in user if present
 | 
			
		||||
| 
						 | 
				
			
			@ -1688,7 +1690,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
 | 
			
		||||
            // Generate a cookie and respond
 | 
			
		||||
            var cookie = parent.encodeCookie({ userid: user._id, domainid: user.domain, nodeid: node._id, tcpport: port }, parent.loginCookieEncryptionKey);
 | 
			
		||||
            render(req, res, getRenderPage('mstsc', req, domain), getRenderArgs({ cookie: cookie, name: encodeURIComponent(node.name) }, req, domain));
 | 
			
		||||
            render(req, res, getRenderPage('mstsc', req, domain), getRenderArgs({ cookie: cookie, name: encodeURIComponent(node.name).replace(/'/g, '%27') }, req, domain));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2260,7 +2262,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
                if (domain.customui != null) { customui = encodeURIComponent(JSON.stringify(domain.customui)); }
 | 
			
		||||
 | 
			
		||||
                // Refresh the session
 | 
			
		||||
                render(req, res, getRenderPage('default', req, domain), getRenderArgs({ authCookie: authCookie, authRelayCookie: authRelayCookie, viewmode: viewmode, currentNode: currentNode, logoutControls: encodeURIComponent(JSON.stringify(logoutcontrols)).replace(/'/g, '%27'), domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, passRequirements: passRequirements, customui: customui, webcerthash: Buffer.from(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer, webstate: encodeURIComponent(webstate), amtscanoptions: amtscanoptions, pluginHandler: (parent.pluginHandler == null) ? 'null' : parent.pluginHandler.prepExports() }, req, domain));
 | 
			
		||||
                render(req, res, getRenderPage('default', req, domain), getRenderArgs({ authCookie: authCookie, authRelayCookie: authRelayCookie, viewmode: viewmode, currentNode: currentNode, logoutControls: encodeURIComponent(JSON.stringify(logoutcontrols)).replace(/'/g, '%27'), domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, passRequirements: passRequirements, customui: customui, webcerthash: Buffer.from(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer, webstate: encodeURIComponent(webstate).replace(/'/g, '%27'), amtscanoptions: amtscanoptions, pluginHandler: (parent.pluginHandler == null) ? 'null' : parent.pluginHandler.prepExports() }, req, domain));
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            // Send back the login application
 | 
			
		||||
| 
						 | 
				
			
			@ -2354,7 +2356,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        if (domain.customui != null) { customui = encodeURIComponent(JSON.stringify(domain.customui)); }
 | 
			
		||||
 | 
			
		||||
        // Render the login page
 | 
			
		||||
        render(req, res, getRenderPage('login', req, domain), getRenderArgs({ loginmode: loginmode, rootCertLink: getRootCertLink(), newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, customui: customui, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), messageid: msgid, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext).split('\'').join('\\\'') : null, hwstate: hwstate, otpemail: otpemail, otpsms: otpsms, twoFactorCookieDays: twoFactorCookieDays, authStrategies: authStrategies.join(',') }, req, domain));
 | 
			
		||||
        render(req, res, getRenderPage('login', req, domain), getRenderArgs({ loginmode: loginmode, rootCertLink: getRootCertLink(), newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, customui: customui, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge).replace(/'/g, '%27'), messageid: msgid, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext).split('\'').join('\\\'') : null, hwstate: hwstate, otpemail: otpemail, otpsms: otpsms, twoFactorCookieDays: twoFactorCookieDays, authStrategies: authStrategies.join(',') }, req, domain));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle a post request on the root
 | 
			
		||||
| 
						 | 
				
			
			@ -2500,7 +2502,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        parent.debug('web', 'handleMessengerRequest()');
 | 
			
		||||
 | 
			
		||||
        var webRtcConfig = null;
 | 
			
		||||
        if (obj.parent.config.settings && obj.parent.config.settings.webrtconfig && (typeof obj.parent.config.settings.webrtconfig == 'object')) { webRtcConfig = encodeURIComponent(JSON.stringify(obj.parent.config.settings.webrtconfig)); }
 | 
			
		||||
        if (obj.parent.config.settings && obj.parent.config.settings.webrtconfig && (typeof obj.parent.config.settings.webrtconfig == 'object')) { webRtcConfig = encodeURIComponent(JSON.stringify(obj.parent.config.settings.webrtconfig)).replace(/'/g, '%27'); }
 | 
			
		||||
        res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
 | 
			
		||||
        render(req, res, getRenderPage('messenger', req, domain), getRenderArgs({ webrtconfig: webRtcConfig }, req, domain));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -3852,8 +3854,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
                if (xdomain != '') xdomain += '/';
 | 
			
		||||
                var meshsettings = 'MeshName=' + mesh.name + '\r\nMeshType=' + mesh.mtype + '\r\nMeshID=0x' + meshidhex + '\r\nServerID=' + serveridhex + '\r\n';
 | 
			
		||||
                if (obj.args.lanonly != true) { meshsettings += 'MeshServer=ws' + (obj.args.notls ? '' : 's') + '://' + serverName + ':' + httpsPort + '/' + xdomain + 'agent.ashx\r\n'; } else { meshsettings += 'MeshServer=local\r\n'; }
 | 
			
		||||
                if (req.query.tag != null) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
 | 
			
		||||
                if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += 'InstallFlags=' + req.query.installflags + '\r\n'; }
 | 
			
		||||
                if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
 | 
			
		||||
                if ((req.query.installflags != null) && (req.query.installflags != 0) && (parseInt(req.query.installflags) == req.query.installflags)) { meshsettings += 'InstallFlags=' + parseInt(req.query.installflags) + '\r\n'; }
 | 
			
		||||
                if ((domain.agentnoproxy === true) || (obj.args.lanonly == true)) { meshsettings += 'ignoreProxyFile=1\r\n'; }
 | 
			
		||||
                if (obj.args.agentconfig) { for (var i in obj.args.agentconfig) { meshsettings += obj.args.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
                if (domain.agentconfig) { for (var i in domain.agentconfig) { meshsettings += domain.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
| 
						 | 
				
			
			@ -4033,8 +4035,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        if (obj.args.agentport != null) { httpsPort = obj.args.agentport; } // If an agent only port is enabled, use that.
 | 
			
		||||
        if (obj.args.agentaliasport != null) { httpsPort = obj.args.agentaliasport; } // If an agent alias port is specified, use that.
 | 
			
		||||
        if (obj.args.lanonly != true) { meshsettings += 'MeshServer=ws' + (obj.args.notls ? '' : 's') + '://' + serverName + ':' + httpsPort + '/' + xdomain + 'agent.ashx\r\n'; } else { meshsettings += 'MeshServer=local\r\n'; }
 | 
			
		||||
        if (req.query.tag != null) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
 | 
			
		||||
        if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += 'InstallFlags=' + req.query.installflags + '\r\n'; }
 | 
			
		||||
        if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
 | 
			
		||||
        if ((req.query.installflags != null) && (req.query.installflags != 0) && (parseInt(req.query.installflags) == req.query.installflags)) { meshsettings += 'InstallFlags=' + parseInt(req.query.installflags) + '\r\n'; }
 | 
			
		||||
        if ((domain.agentnoproxy === true) || (obj.args.lanonly == true)) { meshsettings += 'ignoreProxyFile=1\r\n'; }
 | 
			
		||||
        if (obj.args.agentconfig) { for (var i in obj.args.agentconfig) { meshsettings += obj.args.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
        if (domain.agentconfig) { for (var i in domain.agentconfig) { meshsettings += domain.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
| 
						 | 
				
			
			@ -4130,8 +4132,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        if (obj.args.agentport != null) { httpsPort = obj.args.agentport; } // If an agent only port is enabled, use that.
 | 
			
		||||
        if (obj.args.agentaliasport != null) { httpsPort = obj.args.agentaliasport; } // If an agent alias port is specified, use that.
 | 
			
		||||
        if (obj.args.lanonly != true) { meshsettings += 'MeshServer=ws' + (obj.args.notls ? '' : 's') + '://' + serverName + ':' + httpsPort + '/' + xdomain + 'agent.ashx\r\n'; } else { meshsettings += 'MeshServer=local\r\n'; }
 | 
			
		||||
        if (req.query.tag != null) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
 | 
			
		||||
        if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += 'InstallFlags=' + req.query.installflags + '\r\n'; }
 | 
			
		||||
        if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
 | 
			
		||||
        if ((req.query.installflags != null) && (req.query.installflags != 0) && (parseInt(req.query.installflags) == req.query.installflags)) { meshsettings += 'InstallFlags=' + parseInt(req.query.installflags) + '\r\n'; }
 | 
			
		||||
        if ((domain.agentnoproxy === true) || (obj.args.lanonly == true)) { meshsettings += 'ignoreProxyFile=1\r\n'; }
 | 
			
		||||
        if (obj.args.agentconfig) { for (var i in obj.args.agentconfig) { meshsettings += obj.args.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
        if (domain.agentconfig) { for (var i in domain.agentconfig) { meshsettings += domain.agentconfig[i] + '\r\n'; } }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue