mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	More work on IP-KVM support.
This commit is contained in:
		
							parent
							
								
									bf50a72672
								
							
						
					
					
						commit
						718f58c5dc
					
				
					 4 changed files with 160 additions and 44 deletions
				
			
		
							
								
								
									
										86
									
								
								meshipkvm.js
									
										
									
									
									
								
							
							
						
						
									
										86
									
								
								meshipkvm.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,10 +9,12 @@
 | 
			
		|||
function CreateIPKVMManager(parent) {
 | 
			
		||||
    const obj = {};
 | 
			
		||||
    const managedGroups = {} // meshid --> Manager
 | 
			
		||||
    const managedPorts = {} // nodeid --> PortInfo
 | 
			
		||||
    
 | 
			
		||||
    // Subscribe for mesh creation events
 | 
			
		||||
    parent.AddEventDispatch(['server-createmesh', 'server-deletemesh'], obj);
 | 
			
		||||
    obj.HandleEvent = function (source, event, ids, id) {
 | 
			
		||||
        console.log();
 | 
			
		||||
        if ((event != null) && (event.action == 'createmesh') && (event.mtype == 4)) {
 | 
			
		||||
            // Start managing this new device group
 | 
			
		||||
            startManagement(parent.webserver.meshes[event.meshid]);
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +38,7 @@ function CreateIPKVMManager(parent) {
 | 
			
		|||
        if (mesh.kvm.model == 1) { // Raritan KX III
 | 
			
		||||
            const manager = CreateRaritanKX3Manager(host, port, mesh.kvm.user, mesh.kvm.pass);
 | 
			
		||||
            manager.meshid = mesh._id;
 | 
			
		||||
            manager.domainid = mesh._id.split('/')[1];
 | 
			
		||||
            managedGroups[mesh._id] = manager;
 | 
			
		||||
            manager.onStateChanged = onStateChanged;
 | 
			
		||||
            manager.onPortsChanged = onPortsChanged;
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +49,18 @@ function CreateIPKVMManager(parent) {
 | 
			
		|||
    // Stop managing a IP KVM device
 | 
			
		||||
    function stopManagement(meshid) {
 | 
			
		||||
        const manager = managedGroups[meshid];
 | 
			
		||||
        if (manager != null) { delete managedGroups[meshid]; manager.stop(); }
 | 
			
		||||
        if (manager != null) {
 | 
			
		||||
            // Remove all managed ports
 | 
			
		||||
            for (var i = 0; i < manager.ports.length; i++) {
 | 
			
		||||
                const port = manager.ports[i];
 | 
			
		||||
                const nodeid = generateIpKvmNodeId(manager.meshid, port.PortId, manager.domainid);
 | 
			
		||||
                delete managedPorts[nodeid]; // Remove the managed port
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Remove the manager
 | 
			
		||||
            delete managedGroups[meshid];
 | 
			
		||||
            manager.stop();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Called when a KVM device changes state
 | 
			
		||||
| 
						 | 
				
			
			@ -62,12 +76,82 @@ function CreateIPKVMManager(parent) {
 | 
			
		|||
    function onPortsChanged(sender, updatedPorts) {
 | 
			
		||||
        for (var i = 0; i < updatedPorts.length; i++) {
 | 
			
		||||
            const port = sender.ports[updatedPorts[i]];
 | 
			
		||||
            const nodeid = generateIpKvmNodeId(sender.meshid, port.PortId, sender.domainid);
 | 
			
		||||
            if ((port.Status == 1) && (port.Class == 'KVM')) {
 | 
			
		||||
                console.log(port.PortNumber + ', ' + port.PortId + ', ' + port.Name + ', ' + port.Type + ', ' + ((port.StatAvailable == 0) ? 'Idle' : 'Connected'));
 | 
			
		||||
                if ((managedPorts[nodeid] == null) || (managedPorts[nodeid].name != port.Name)) {
 | 
			
		||||
                    parent.db.Get(nodeid, function (err, nodes) {
 | 
			
		||||
                        if ((err != null) || (nodes == null)) return;
 | 
			
		||||
                        const mesh = parent.webserver.meshes[sender.meshid];
 | 
			
		||||
                        if (nodes.length == 0) {
 | 
			
		||||
                            // The device does not exist, create it
 | 
			
		||||
                            const device = { type: 'node', mtype: 4, _id: nodeid, icon: 1, meshid: sender.meshid, name: port.Name, rname: port.Name, domain: sender.domainid, porttype: port.Type, portid: port.PortId, portnum: port.PortNumber };
 | 
			
		||||
                            parent.db.Set(device);
 | 
			
		||||
 | 
			
		||||
                            // Event the new node
 | 
			
		||||
                            parent.DispatchEvent(parent.webserver.CreateMeshDispatchTargets(sender.meshid, [nodeid]), obj, { etype: 'node', action: 'addnode', nodeid: nodeid, node: device, msgid: 57, msgArgs: [port.Name, mesh.name], msg: ('Added device ' + port.Name + ' to device group ' + mesh.name), domain: sender.domainid });
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // The device exists, update it
 | 
			
		||||
                            var changed = false;
 | 
			
		||||
                            const device = nodes[0];
 | 
			
		||||
                            if (device.rname != port.Name) { device.rname = port.Name; changed = true; } // Update the device port name
 | 
			
		||||
                            if ((mesh.flags) && (mesh.flags & 2) && (device.name != port.Name)) { device.name = port.Name; changed = true; } // Sync device name to port name
 | 
			
		||||
                            if (changed) {
 | 
			
		||||
                                // Update the database and event the node change
 | 
			
		||||
                                parent.db.Set(device);
 | 
			
		||||
                                parent.DispatchEvent(parent.webserver.CreateMeshDispatchTargets(sender.meshid, [nodeid]), obj, { etype: 'node', action: 'changenode', nodeid: nodeid, node: device, domain: sender.domainid, nolog: 1 });
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Set the connectivity state if needed
 | 
			
		||||
                        if (managedPorts[nodeid] == null) {
 | 
			
		||||
                            parent.SetConnectivityState(sender.meshid, nodeid, Date.now(), 1, 1, null, null);
 | 
			
		||||
                            managedPorts[nodeid] = { name: port.Name, busy: false };
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Update busy state
 | 
			
		||||
                        const portInfo = managedPorts[nodeid];
 | 
			
		||||
                        if (portInfo.busy != (port.StatAvailable != 0)) {
 | 
			
		||||
                            console.log('Busy state', (port.StatAvailable != 0));
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Update busy state
 | 
			
		||||
                    const portInfo = managedPorts[nodeid];
 | 
			
		||||
                    if (portInfo.busy != (port.StatAvailable != 0)) {
 | 
			
		||||
                        console.log('Busy state', (port.StatAvailable != 0));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (managedPorts[nodeid] != null) {
 | 
			
		||||
                    // This port is no longer connected
 | 
			
		||||
                    parent.ClearConnectivityState(sender.meshid, nodeid, 1, null, null);
 | 
			
		||||
 | 
			
		||||
                    // If the device group policy is set to auto-remove devices, remove it now
 | 
			
		||||
                    if ((mesh.flags) && (mesh.flags & 1)) {                       // Auto-remove devices
 | 
			
		||||
                        parent.db.Remove(nodeid);                                 // Remove node with that id
 | 
			
		||||
                        parent.db.Remove('nt' + nodeid);                          // Remove notes
 | 
			
		||||
                        parent.db.Remove('lc' + nodeid);                          // Remove last connect time
 | 
			
		||||
                        parent.db.Remove('al' + nodeid);                          // Remove error log last time
 | 
			
		||||
                        parent.db.RemoveAllNodeEvents(nodeid);                    // Remove all events for this node
 | 
			
		||||
                        parent.db.removeAllPowerEventsForNode(nodeid);            // Remove all power events for this node
 | 
			
		||||
 | 
			
		||||
                        // Event node deletion
 | 
			
		||||
                        parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(sender.meshid, [nodeid]), obj, { etype: 'node', action: 'removenode', nodeid: nodeid, domain: domain.id, nolog: 1 });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Remove the managed port
 | 
			
		||||
                    delete managedPorts[nodeid];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Generate the nodeid from the device group and device identifier
 | 
			
		||||
    function generateIpKvmNodeId(meshid, portid, domainid) {
 | 
			
		||||
        return 'node/' + domainid + '/' + parent.crypto.createHash('sha384').update(Buffer.from(meshid + '/' + portid)).digest().toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2528,7 +2528,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                        parent.parent.DispatchEvent(targets, obj, event);
 | 
			
		||||
 | 
			
		||||
                        // Event the device group creation
 | 
			
		||||
                        var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, action: 'createmesh', links: links, msgid: 76, msgArgs: [command.meshname], msg: 'Device group created: ' + command.meshname, domain: domain.id, creation: mesh.creation, creatorid: mesh.creatorid, creatorname: mesh.creatorname, flags: mesh.flags, consent: mesh.consent };
 | 
			
		||||
                        var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: meshid, mtype: command.meshtype, mesh: parent.CloneSafeMesh(mesh), action: 'createmesh', msgid: 76, msgArgs: [command.meshname], msg: 'Device group created: ' + command.meshname, domain: domain.id };
 | 
			
		||||
                        parent.parent.DispatchEvent(['*', 'server-createmesh', meshid, user._id], obj, event); // Even if DB change stream is active, this event must be acted upon.
 | 
			
		||||
 | 
			
		||||
                        // Log in the auth log
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1765,8 +1765,8 @@
 | 
			
		|||
                        }
 | 
			
		||||
                        case 'createmesh': {
 | 
			
		||||
                            // A new mesh was created
 | 
			
		||||
                            if ((meshes[message.event.meshid] == null) && ((userinfo.manageAllDeviceGroups) || (message.event.links[userinfo._id] != null))) { // Check if this is a mesh create for a mesh we own. If site administrator, we get all messages so need to ignore some.
 | 
			
		||||
                                meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
 | 
			
		||||
                            if ((meshes[message.event.meshid] == null) && ((userinfo.manageAllDeviceGroups) || (message.event.mesh.links[userinfo._id] != null))) { // Check if this is a mesh create for a mesh we own. If site administrator, we get all messages so need to ignore some.
 | 
			
		||||
                                meshes[message.event.meshid] = message.event.mesh;
 | 
			
		||||
                                mainUpdate(4 + 128);
 | 
			
		||||
                                meshserver.send({ action: 'files' });
 | 
			
		||||
                            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3218,7 +3218,7 @@
 | 
			
		|||
            var states = [];
 | 
			
		||||
            if (node.state > 0 && node.state < powerStatetable.length) state.push(powerStatetable[node.state]);
 | 
			
		||||
            if (node.conn) {
 | 
			
		||||
                if ((node.conn & 1) != 0) { states.push('<span>' + "Agent" + '</span>'); }
 | 
			
		||||
                if ((node.conn & 1) != 0) { if (node.mtype == 4) { states.push('<span>' + ((node.mtype == 4)?"IP-KVM":"Agent") + '</span>'); } else { states.push('<span>' + "IP KVM" + '</span>'); } }
 | 
			
		||||
                if ((node.conn & 2) != 0) { states.push('<span>' + "CIRA" + '</span>'); }
 | 
			
		||||
                else if ((node.conn & 4) != 0) { states.push('<span>' + "Intel® AMT" + '</span>'); }
 | 
			
		||||
                if ((node.conn & 8) != 0) { states.push('<span>' + "Relay" + '</span>'); }
 | 
			
		||||
| 
						 | 
				
			
			@ -3356,7 +3356,7 @@
 | 
			
		|||
                if (node.rname != null) { x += addDeviceAttribute('<span>' + "Name" + '</span>', '<span>' + EscapeHtml(node.rname) + '</span>'); }
 | 
			
		||||
 | 
			
		||||
                // Attribute: Host
 | 
			
		||||
                if ((features & 1) == 0) { // If not WAN-only, local hostname is in use
 | 
			
		||||
                if (((features & 1) == 0) && (node.mtype != 4)) { // If not WAN-only, local hostname is in use
 | 
			
		||||
                    if ((meshrights & 4) != 0) {
 | 
			
		||||
                        if (node.host) {
 | 
			
		||||
                            x += addDeviceAttribute("Hostname", '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>' + EscapeHtml(node.host) + '</span>');
 | 
			
		||||
| 
						 | 
				
			
			@ -3376,6 +3376,12 @@
 | 
			
		|||
                    x += addDeviceAttribute("Description", description);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // IP-KVM information
 | 
			
		||||
                if (node.mtype == 4) {
 | 
			
		||||
                    if (node.portnum) { x += addDeviceAttribute("Port Number", node.portnum); }
 | 
			
		||||
                    if (node.porttype) { x += addDeviceAttribute("Port Type", node.porttype); }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Attribute: Mesh Agent
 | 
			
		||||
                if ((node.agent != null) && (node.agent.id != null) && (node.mtype == 3)) {
 | 
			
		||||
                    if (node.agent.id == 4) { x += addDeviceAttribute("Device Type", "Windows"); }
 | 
			
		||||
| 
						 | 
				
			
			@ -3476,7 +3482,7 @@
 | 
			
		|||
                var connectivity = node.conn;
 | 
			
		||||
                if (connectivity && connectivity > 1) {
 | 
			
		||||
                    var cstate = [];
 | 
			
		||||
                    if ((node.conn & 1) != 0) cstate.push('<span>' + "Agent" + '</span>');
 | 
			
		||||
                    if ((node.conn & 1) != 0) cstate.push('<span>' + ((node.mtype == 4) ? "IP-KVM" : "Agent") + '</span>');
 | 
			
		||||
                    if ((node.conn & 2) != 0) cstate.push('<span>' + "Intel® AMT CIRA" + '</span>');
 | 
			
		||||
                    else if ((node.conn & 4) != 0) cstate.push('<span>' + "Intel® AMT" + '</span>');
 | 
			
		||||
                    if ((node.conn & 8) != 0) cstate.push('<span>' + "Agent Relay" + '</span>');
 | 
			
		||||
| 
						 | 
				
			
			@ -3488,7 +3494,7 @@
 | 
			
		|||
                var groupingTags = '<i>' + "None" + '</i>';
 | 
			
		||||
                if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '<span style="background-color:lightgray;padding:3px;border-radius:5px">' + EscapeHtml(node.tags[i]) + '</span> '; } }
 | 
			
		||||
                if ((meshrights & 4) != 0) {
 | 
			
		||||
                    x += addDeviceAttribute("Tags", '<span onclick=showEditNodeValueDialog(3) style=line-height:26px;cursor:pointer;color:black>' + groupingTags + '</span>');
 | 
			
		||||
                    x += addDeviceAttribute("Tags", '<span onclick=showEditNodeValueDialog(3) style=cursor:pointer;color:black>' + groupingTags + '</span>');
 | 
			
		||||
                } else {
 | 
			
		||||
                    x += addDeviceAttribute("Tags", '<span style=line-height:26px;color:black>' + groupingTags + '</span>');
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -3536,7 +3542,7 @@
 | 
			
		|||
                // Set the node power state
 | 
			
		||||
                var powerstate = PowerStateStr(node.state);
 | 
			
		||||
                //if (node.state == 0) { powerstate = 'Unknown State'; }
 | 
			
		||||
                if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += "Mesh Agent"; }
 | 
			
		||||
                if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += ((mesh.mtype == 4) ? "IP-KVM" : "Mesh Agent"); }
 | 
			
		||||
                if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += "Intel® AMT connected"; }
 | 
			
		||||
                else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += "Intel® AMT detected"; }
 | 
			
		||||
                if ((connectivity & 16) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += "MQTT channel connected"; }
 | 
			
		||||
| 
						 | 
				
			
			@ -3600,17 +3606,17 @@
 | 
			
		|||
            if ((currentDevicePanel != 1) &&
 | 
			
		||||
                (currentNode != null) &&
 | 
			
		||||
                ((meshrights & 8) || (meshrights & 256)) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 65536) == 0)) &&
 | 
			
		||||
                (((currentNode.agent == null) && ((typeof currentNode.intelamt.sku !== 'number') || ((currentNode.intelamt.sku & 8) != 0))) || (currentNode.agent && (currentNode.agent.caps & 1)))
 | 
			
		||||
                (((currentNode.agent == null) && (currentNode.intelamt) && ((typeof currentNode.intelamt.sku !== 'number') || ((currentNode.intelamt.sku & 8) != 0))) || (currentNode.agent && (currentNode.agent.caps & 1)))
 | 
			
		||||
            ) { menus.push({ n: "Desktop", f: 'setupDeviceMenu(1)' }); }
 | 
			
		||||
 | 
			
		||||
            if ((currentDevicePanel != 5) &&
 | 
			
		||||
                (currentNode != null) &&
 | 
			
		||||
                ((meshrights & 8) || (meshrights & 256)) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 512) == 0)) &&
 | 
			
		||||
                (((currentNode.agent == null) && ((typeof currentNode.intelamt.sku !== 'number') || ((currentNode.intelamt.sku & 8) != 0))) || (currentNode.agent && (currentNode.agent.caps & 2)))
 | 
			
		||||
                (((currentNode.agent == null) && (currentNode.intelamt) && ((typeof currentNode.intelamt.sku !== 'number') || ((currentNode.intelamt.sku & 8) != 0))) || (currentNode.agent && (currentNode.agent.caps & 2)))
 | 
			
		||||
            ) { menus.push({ n: "Terminal", f: 'setupDeviceMenu(5)' }); }
 | 
			
		||||
 | 
			
		||||
            if ((currentDevicePanel != 2) && (currentNode != null) && (meshrights & 8) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 1024) == 0)) && ((currentNode.mtype != 1) && (currentNode.agent.caps & 4))) { menus.push({ n: "Files", f: 'setupDeviceMenu(2)' }); }
 | 
			
		||||
            if ((currentDevicePanel != 3) && (currentNode != null) && (currentNode.mtype != 3) && ((meshrights & 1048576) != 0)) { menus.push({ n: "Details", f: 'setupDeviceMenu(3)' }); }
 | 
			
		||||
            if ((currentDevicePanel != 2) && (currentNode != null) && (meshrights & 8) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 1024) == 0)) && ((currentNode.mtype != 1) && (currentNode.agent) && (currentNode.agent.caps & 4))) { menus.push({ n: "Files", f: 'setupDeviceMenu(2)' }); }
 | 
			
		||||
            if ((currentDevicePanel != 3) && (currentNode != null) && (currentNode.mtype < 3) && ((meshrights & 1048576) != 0)) { menus.push({ n: "Details", f: 'setupDeviceMenu(3)' }); }
 | 
			
		||||
            if ((currentDevicePanel != 4) && (currentNode != null) && (meshrights & 0x00000010) && (currentNode.mtype == 2)) { menus.push({ n: "Console", f: 'setupDeviceMenu(4)' }); }
 | 
			
		||||
            updateFooterMenu(menus);
 | 
			
		||||
            updateCurrentUrl();
 | 
			
		||||
| 
						 | 
				
			
			@ -5144,7 +5150,7 @@
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        function p13setActions() {
 | 
			
		||||
            var advancedFeatures = (currentNode.agent.id != 14); // Reduct file feature on some devices.
 | 
			
		||||
            var advancedFeatures = ((currentNode.agent) && (currentNode.agent.id != 14)); // Reduct file feature on some devices.
 | 
			
		||||
            if (p13filetree == null) {
 | 
			
		||||
                QE('p13DeleteFileButton', false);
 | 
			
		||||
                QE('p13NewFolderButton', false);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2984,8 +2984,8 @@
 | 
			
		|||
                        }
 | 
			
		||||
                        case 'createmesh': {
 | 
			
		||||
                            // A new mesh was created
 | 
			
		||||
                            if ((meshes[message.event.meshid] == null) && ((serverinfo.manageAllDeviceGroups) || (message.event.links[userinfo._id] != null))) { // Check if this is a mesh create for a mesh we own. If site administrator, we get all messages so need to ignore some.
 | 
			
		||||
                                meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links, creation: message.event.creation, creatorid: message.event.creatorid, creatorname: message.event.creatorname, flags: message.event.flags, consent: message.event.consent };
 | 
			
		||||
                            if ((meshes[message.event.meshid] == null) && ((serverinfo.manageAllDeviceGroups) || (message.event.mesh.links[userinfo._id] != null))) { // Check if this is a mesh create for a mesh we own. If site administrator, we get all messages so need to ignore some.
 | 
			
		||||
                                meshes[message.event.meshid] = message.event.mesh;
 | 
			
		||||
                                mainUpdate(4 + 128 + 8192 + 16384);
 | 
			
		||||
                                meshserver.send({ action: 'files' });
 | 
			
		||||
                            }
 | 
			
		||||
| 
						 | 
				
			
			@ -4366,7 +4366,11 @@
 | 
			
		|||
            } else if (view == 2) {
 | 
			
		||||
                var states = [];
 | 
			
		||||
                if (node.conn) {
 | 
			
		||||
                    if ((node.conn & 1) != 0) { states.push('<span title="' + "Mesh agent is connected and ready for use." + '">' + "Agent" + '</span>'); }
 | 
			
		||||
                    if (node.mtype == 4) {
 | 
			
		||||
                        if ((node.conn & 1) != 0) { states.push('<span title="' + "IP-KVM port is connected and ready for use." + '">' + "IP-KVM" + '</span>'); }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if ((node.conn & 1) != 0) { states.push('<span title="' + "Mesh agent is connected and ready for use." + '">' + "Agent" + '</span>'); }
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((node.conn & 2) != 0) { states.push('<span title="' + "Intel® AMT CIRA is connected and ready for use." + '">' + "CIRA" + '</span>'); }
 | 
			
		||||
                    else if ((node.conn & 4) != 0) { states.push('<span title="' + "Intel® AMT is routable." + '">' + "AMT" + '</span>'); }
 | 
			
		||||
                    if ((node.conn & 8) != 0) { states.push('<span title="' + "Mesh agent is reachable using another agent as relay." + '">' + "Relay" + '</span>'); }
 | 
			
		||||
| 
						 | 
				
			
			@ -5130,7 +5134,13 @@
 | 
			
		|||
            var states = [];
 | 
			
		||||
            if (node.state > 0 && node.state < powerStatetable.length) state.push(powerStatetable[node.state]);
 | 
			
		||||
            if (node.conn) {
 | 
			
		||||
                if ((node.conn & 1) != 0) { states.push('<span title="' + "Mesh agent is connected and ready for use." + '">' + "Agent" + '</span>'); }
 | 
			
		||||
                if ((node.conn & 1) != 0) { 
 | 
			
		||||
                    if (node.mtype == 4) {
 | 
			
		||||
                        states.push('<span title="' + "IP KVM port is up and ready for use." + '">' + "IP-KVM" + '</span>');
 | 
			
		||||
                    } else {
 | 
			
		||||
                        states.push('<span title="' + "Mesh agent is connected and ready for use." + '">' + "Agent" + '</span>');
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if ((node.conn & 2) != 0) { states.push('<span title="' + "Intel® AMT CIRA is connected and ready for use." + '">' + "CIRA" + '</span>'); }
 | 
			
		||||
                else if ((node.conn & 4) != 0) { states.push('<span title="' + "Intel® AMT is routable." + '">' + "AMT" + '</span>'); }
 | 
			
		||||
                if ((node.conn & 8) != 0) { states.push('<span title="' + "Mesh agent is reachable using another agent as relay." + '">' + "Relay" + '</span>'); }
 | 
			
		||||
| 
						 | 
				
			
			@ -6659,7 +6669,7 @@
 | 
			
		|||
                if ((node.rname != null) && (node.name != node.rname)) { x += addDeviceAttribute('<span title="' + "The name of this computer as set in the operating system" + '">' + "OS Name" + '</span>', '<span title="' + "The name of this computer as set in the operating system" + '">' + EscapeHtml(node.rname) + '</span>'); }
 | 
			
		||||
 | 
			
		||||
                // Attribute: Host
 | 
			
		||||
                if ((features & 1) == 0) { // If not WAN-only, local hostname is in use
 | 
			
		||||
                if (((features & 1) == 0) && (node.mtype != 4)) { // If not WAN-only, local hostname is in use
 | 
			
		||||
                    x += addDeviceAttribute("Hostname", addLinkConditional('<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>' + (node.host?EscapeHtml(node.host):('<i>' + "None" + '</i>')) + '</span>', 'showEditNodeValueDialog(1)', meshrights & 4));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -6671,6 +6681,12 @@
 | 
			
		|||
                    x += addDeviceAttribute("Description", description);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // IP-KVM information
 | 
			
		||||
                if (node.mtype == 4) {
 | 
			
		||||
                    if (node.portnum) { x += addDeviceAttribute("Port Number", node.portnum); }
 | 
			
		||||
                    if (node.porttype) { x += addDeviceAttribute("Port Type", node.porttype); }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Attribute: Mesh Agent
 | 
			
		||||
                if ((node.agent != null) && (node.agent.id != null) && (node.mtype == 3)) {
 | 
			
		||||
                    if (node.agent.id == 4) { x += addDeviceAttribute("Device Type", "Windows"); }
 | 
			
		||||
| 
						 | 
				
			
			@ -6854,20 +6870,22 @@
 | 
			
		|||
 | 
			
		||||
                x += '</table><br />';
 | 
			
		||||
                // Show action button, only show if we have permissions 4, 8, 64
 | 
			
		||||
                if (((meshrights & (4 + 8 + 64)) != 0) && (node.mtype != 3) && ((node.agent == null) || (node.agent.id != 34))) { x += '<input type=button value="' + "Actions" + '" title="' + "Perform power actions on the device" + '" onclick=deviceActionFunction() />'; }
 | 
			
		||||
                if (((meshrights & (4 + 8 + 64)) != 0) && (node.mtype < 3) && ((node.agent == null) || (node.agent.id != 34))) { x += '<input type=button value="' + "Actions" + '" title="' + "Perform power actions on the device" + '" onclick=deviceActionFunction() />'; }
 | 
			
		||||
                x += '<input type=button value="' + "Notes" + '" title="' + "View notes about this device" + '" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponentEx(node._id) + '") />';
 | 
			
		||||
                x += '<input type=button value="' + "Log Event" + '" title="' + "Write an event for this device" + '" onclick=writeDeviceEvent("' + encodeURIComponentEx(node._id) + '") />';
 | 
			
		||||
                if ((meshrights & 8) && ((connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0)))) { x += '<input type=button value="' + "Message" + '" title="' + "Display a text message on the remote device" + '" onclick=deviceMessageFunction() />';  }
 | 
			
		||||
                //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="' + "Display a text message of the remote device" + '" onclick=deviceToastFunction() />';  }
 | 
			
		||||
                if ((meshrights & 8) && (connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0))) { x += '<input type=button value="' + "Chat" + '" title="' + "Open chat window to this computer" + '" onclick=deviceChat(event) />'; }
 | 
			
		||||
                if ((serverinfo != null) && (serverinfo.altmessenging != null) && (meshrights & 8) && (connectivity & 1)) {
 | 
			
		||||
                    for (var i in serverinfo.altmessenging) { x += '<input type=button value="' + EscapeHtml(serverinfo.altmessenging[i].name) + '" onclick=altDeviceChat(event,' + i + ') />'; }
 | 
			
		||||
                }
 | 
			
		||||
                if ((serverinfo.guestdevicesharing !== false) && (node.agent != null) && (node.agent.caps & 3) && (connectivity & 1) && ((meshrights & 0x80008) == 0x80008) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 0x1000) == 0))) {
 | 
			
		||||
                    x += '<input type=button value="' + "Share" + '" title="' + "Create a link to share this device with a guest" + '" onclick=showShareDevice() />';
 | 
			
		||||
                    QV('DeskGuestShareButton', true);
 | 
			
		||||
                } else {
 | 
			
		||||
                    QV('DeskGuestShareButton', false);
 | 
			
		||||
                if (node.mtype != 4) {
 | 
			
		||||
                    if ((meshrights & 8) && ((connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0)))) { x += '<input type=button value="' + "Message" + '" title="' + "Display a text message on the remote device" + '" onclick=deviceMessageFunction() />';  }
 | 
			
		||||
                    //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="' + "Display a text message of the remote device" + '" onclick=deviceToastFunction() />';  }
 | 
			
		||||
                    if ((meshrights & 8) && (connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0))) { x += '<input type=button value="' + "Chat" + '" title="' + "Open chat window to this computer" + '" onclick=deviceChat(event) />'; }
 | 
			
		||||
                    if ((serverinfo != null) && (serverinfo.altmessenging != null) && (meshrights & 8) && (connectivity & 1)) {
 | 
			
		||||
                        for (var i in serverinfo.altmessenging) { x += '<input type=button value="' + EscapeHtml(serverinfo.altmessenging[i].name) + '" onclick=altDeviceChat(event,' + i + ') />'; }
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((serverinfo.guestdevicesharing !== false) && (node.agent != null) && (node.agent.caps & 3) && (connectivity & 1) && ((meshrights & 0x80008) == 0x80008) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 0x1000) == 0))) {
 | 
			
		||||
                        x += '<input type=button value="' + "Share" + '" title="' + "Create a link to share this device with a guest" + '" onclick=showShareDevice() />';
 | 
			
		||||
                        QV('DeskGuestShareButton', true);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        QV('DeskGuestShareButton', false);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Custom UI
 | 
			
		||||
| 
						 | 
				
			
			@ -6892,7 +6910,7 @@
 | 
			
		|||
 | 
			
		||||
                // Show bottom buttons
 | 
			
		||||
                x = '<div class="p10html3right">';
 | 
			
		||||
                if ((meshrights & 1) != 0) { // MESHRIGHT_EDITMESH
 | 
			
		||||
                if (((meshrights & 1) != 0) && (node.mtype != 4)) { // MESHRIGHT_EDITMESH
 | 
			
		||||
                    // TODO: Show change group only if there is another mesh of the same type.
 | 
			
		||||
                    x += ' <a href=# onclick=p10showChangeGroupDialog(["' + node._id + '"]) title="' + "Move this device to a different device group" + '">' + "Change Group" + '</a>';
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -6978,7 +6996,14 @@
 | 
			
		|||
                //if (node.state == 0) { powerstate = 'Unknown State'; }
 | 
			
		||||
                var agentPrivilages = '';
 | 
			
		||||
                if ((node.agent != null) && (node.agent.root === false)) { agentPrivilages = ', <span title="' + "Agent is running on remote device with reduced privilages." + '">' + "Restricted" + '</span>'; }
 | 
			
		||||
                if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="' + "Agent connected" + '">' + "Agent connected" + '</span>' + agentPrivilages; }
 | 
			
		||||
                if ((connectivity & 1) != 0) {
 | 
			
		||||
                    if (powerstate.length > 0) { powerstate += '<br/>'; }
 | 
			
		||||
                    if (node.mtype == 4) {
 | 
			
		||||
                        powerstate += '<span style=font-size:12px title="' + "IP-KVM port connected" + '">' + "IP-KVM port connected" + '</span>' + agentPrivilages;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        powerstate += '<span style=font-size:12px title="' + "Agent connected" + '">' + "Agent connected" + '</span>' + agentPrivilages;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="' + "Intel® AMT connected" + '">' + "Intel® AMT connected" + '</span>'; }
 | 
			
		||||
                else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="' + "Intel® AMT detected" + '">' + "Intel® AMT detected" + '</span>'; }
 | 
			
		||||
                if ((connectivity & 16) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="' + "MQTT connected" + '">' + "MQTT channel connected" + '</span>'; }
 | 
			
		||||
| 
						 | 
				
			
			@ -7002,13 +7027,13 @@
 | 
			
		|||
                // Show or hide the tabs
 | 
			
		||||
                // mesh.mtype: 1 = Intel AMT only, 2 = Mesh Agent, 3 = Local Device
 | 
			
		||||
                // node.agent.caps (bitmask): 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console
 | 
			
		||||
                QV('MainDevDesktop', desktopAccess && ((((node.agent == null) && ((typeof node.intelamt.sku !== 'number') || ((node.intelamt.sku & 8) != 0)))
 | 
			
		||||
                QV('MainDevDesktop', desktopAccess && ((((node.agent == null) && (node.intelamt != null) && ((typeof node.intelamt.sku !== 'number') || ((node.intelamt.sku & 8) != 0)))
 | 
			
		||||
                    || ((node.agent != null) && ((node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2)))))
 | 
			
		||||
                    && ((meshrights & 8) || (meshrights & 256)))
 | 
			
		||||
                    );
 | 
			
		||||
                QV('MainDevTerminal', (((node.agent == null) && (node.intelamt != null)) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8) && terminalAccess);
 | 
			
		||||
                QV('MainDevTerminal', (((node.agent == null) && (node.intelamt != null)) || ((node.agent) && (node.agent.caps == null)) || ((node.agent) && ((node.agent.caps & 2) != 0)) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8) && terminalAccess);
 | 
			
		||||
                QV('MainDevFiles', (node.agent != null) && (node.agent.caps != null) && ((node.agent.caps & 4) != 0) && (meshrights & 8) && fileAccess);
 | 
			
		||||
                QV('MainDevInfo', (node.mtype != 3) & ((meshrights & 1048576) != 0));
 | 
			
		||||
                QV('MainDevInfo', (node.mtype < 3) && ((meshrights & 1048576) != 0));
 | 
			
		||||
                QV('MainDevAmt', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (meshrights & 8) && amtAccess);
 | 
			
		||||
                QV('MainDevConsole', (consoleRights && ((node.agent != null) && (node.agent.caps != null) && ((node.agent.caps & 8) != 0))) && (meshrights & 8));
 | 
			
		||||
                QV('MainDevPlugins', false);
 | 
			
		||||
| 
						 | 
				
			
			@ -11564,6 +11589,7 @@
 | 
			
		|||
            if (mname.length == 0) { mname = '<i>' + "None" + '</i>'; }
 | 
			
		||||
            if ((meshrights & 1) != 0) { mname = '<span tabindex=0 title="' + "Click here to edit the device group name" + '" onclick=p20editmesh(1) onkeyup="if (event.key == \'Enter\') p20editmesh(1)" style=cursor:pointer>' + mname + ' <img class=hoverButton src="images/link5.png" /></span>'; }
 | 
			
		||||
            QH('p20meshName', mname);
 | 
			
		||||
            QV('MeshSummary', (currentMesh.mtype != 4));
 | 
			
		||||
 | 
			
		||||
            var meshtype = format("Unknown #{0}", currentMesh.mtype);
 | 
			
		||||
            if (currentMesh.mtype == 1) meshtype = "Intel® AMT only, no agent";
 | 
			
		||||
| 
						 | 
				
			
			@ -11597,11 +11623,11 @@
 | 
			
		|||
            if (currentMesh.creation != null) { x += addHtmlValue("Creation Time", printDateTime(new Date(currentMesh.creation))); }
 | 
			
		||||
 | 
			
		||||
            // Display features
 | 
			
		||||
            if (currentMesh.mtype < 3) {
 | 
			
		||||
            if (currentMesh.mtype != 3) {
 | 
			
		||||
                var meshFeatures = [];
 | 
			
		||||
                if (currentMesh.flags) {
 | 
			
		||||
                    if (currentMesh.flags & 1) { meshFeatures.push("Auto-Remove"); }
 | 
			
		||||
                    if (currentMesh.flags & 2) { meshFeatures.push("Hostname Sync"); }
 | 
			
		||||
                    if (currentMesh.flags & 2) { meshFeatures.push((currentMesh.mtype == 4)?"Port Name Sync":"Hostname Sync"); }
 | 
			
		||||
                    if ((serverinfo.devGroupSessionRecording == 1) && (currentMesh.flags & 4)) { meshFeatures.push("Record Sessions"); }
 | 
			
		||||
                }
 | 
			
		||||
                if ((typeof currentMesh.expireDevs == 'number') && (currentMesh.expireDevs > 0)) { meshFeatures.push("Remove inactive"); }
 | 
			
		||||
| 
						 | 
				
			
			@ -12036,11 +12062,11 @@
 | 
			
		|||
            if (xxdialogMode) return;
 | 
			
		||||
            var flags = (currentMesh.flags)?currentMesh.flags:0, x = '', expire = 0;
 | 
			
		||||
            if ((typeof currentMesh.expireDevs == 'number') && (currentMesh.expireDevs > 0)) { expire = currentMesh.expireDevs; if (expire > 2000) { expire = 2000; } }
 | 
			
		||||
            if (serverinfo.devGroupSessionRecording == 1) {
 | 
			
		||||
            if ((serverinfo.devGroupSessionRecording == 1) && (currentMesh.mtype != 4)) {
 | 
			
		||||
                x += '<div><label><input type=checkbox id=d20flag4 onchange=p20editmeshfeaturesValidate() ' + ((flags & 4) ? 'checked' : '') + '>' + "Record sessions" + '</label><br></div>';
 | 
			
		||||
            }
 | 
			
		||||
            if (currentMesh.mtype == 2) {
 | 
			
		||||
                x += '<div><label><input type=checkbox id=d20flag2 onchange=p20editmeshfeaturesValidate() ' + ((flags & 2) ? 'checked' : '') + '>' + "Sync server device name to hostname" + '</label><br></div>';
 | 
			
		||||
            if ((currentMesh.mtype == 2) || (currentMesh.mtype == 4)) {
 | 
			
		||||
                x += '<div><label><input type=checkbox id=d20flag2 onchange=p20editmeshfeaturesValidate() ' + ((flags & 2) ? 'checked' : '') + '>' + ((currentMesh.mtype == 4)?"Sync server device name to port name":"Sync server device name to hostname") + '</label><br></div>';
 | 
			
		||||
                x += '<div><label><input type=checkbox id=d20flag1 onchange=p20editmeshfeaturesValidate() ' + ((flags & 1) ? 'checked' : '') + '>' + "Remove device on disconnect" + '</label><br></div>';
 | 
			
		||||
            }
 | 
			
		||||
            x += '<div><label><input type=checkbox id=d20expireDevice onchange=p20editmeshfeaturesValidate() ' + ((expire > 0) ? 'checked' : '') + '>' + "Automatically remove inactive devices" + '</label><br></div>';
 | 
			
		||||
| 
						 | 
				
			
			@ -12060,7 +12086,7 @@
 | 
			
		|||
 | 
			
		||||
        function p20editmeshfeaturesValidate() {
 | 
			
		||||
            var flags = 0, ok = true;
 | 
			
		||||
            if ((currentMesh.mtype == 2) && (Q('d20flag1').checked)) { flags += 1; }
 | 
			
		||||
            if (((currentMesh.mtype == 2) || (currentMesh.mtype == 4)) && (Q('d20flag1').checked)) { flags += 1; }
 | 
			
		||||
            QE('d20expireDevice', (flags & 1) == 0);
 | 
			
		||||
            var x = ((flags & 1) == 0) && Q('d20expireDevice').checked;
 | 
			
		||||
            QV('d20expireDeviceDev', x);
 | 
			
		||||
| 
						 | 
				
			
			@ -12070,11 +12096,11 @@
 | 
			
		|||
 | 
			
		||||
        function p20editmeshfeaturesEx() {
 | 
			
		||||
            var flags = 0;
 | 
			
		||||
            if (currentMesh.mtype == 2) {
 | 
			
		||||
            if ((currentMesh.mtype == 2) || (currentMesh.mtype == 4)) {
 | 
			
		||||
                if (Q('d20flag1').checked) { flags += 1; }
 | 
			
		||||
                if (Q('d20flag2').checked) { flags += 2; }
 | 
			
		||||
            }
 | 
			
		||||
            if (serverinfo.devGroupSessionRecording == 1) { if (Q('d20flag4').checked) { flags += 4; } }
 | 
			
		||||
            if ((serverinfo.devGroupSessionRecording == 1) && (currentMesh.mtype != 4)) { if (Q('d20flag4').checked) { flags += 4; } }
 | 
			
		||||
            var expireDevs = 0;
 | 
			
		||||
            if (((flags & 1) == 0) && Q('d20expireDevice').checked) { expireDevs = parseInt(Q('d20expireDeviceDays').value); }
 | 
			
		||||
            meshserver.send({ action: 'editmesh', meshid: currentMesh._id, flags: flags, expireDevs: expireDevs });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue