Updated agents, shift-device click will now open a new browser tab.

This commit is contained in:
Ylian Saint-Hilaire 2019-01-29 14:08:29 -08:00
parent 50fa7d760a
commit b0394da585
27 changed files with 206 additions and 57 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -92,6 +92,11 @@ function UserSessions()
{ {
} }
this._advapi = this._marshal.CreateNativeProxy('Advapi32.dll');
this._advapi.CreateMethod('AllocateAndInitializeSid');
this._advapi.CreateMethod('CheckTokenMembership');
this._advapi.CreateMethod('FreeSid');
this._user32 = this._marshal.CreateNativeProxy('user32.dll'); this._user32 = this._marshal.CreateNativeProxy('user32.dll');
this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1}); this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1});
this._user32.CreateMethod('UnregisterPowerSettingNotification'); this._user32.CreateMethod('UnregisterPowerSettingNotification');
@ -150,6 +155,26 @@ function UserSessions()
'WTSIsRemoteSession': 29 'WTSIsRemoteSession': 29
}; };
this.isRoot = function isRoot()
{
var NTAuthority = this._marshal.CreateVariable(6);
NTAuthority.toBuffer().writeInt8(5, 5);
var AdministratorsGroup = this._marshal.CreatePointer();
var admin = false;
if (this._advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
{
var member = this._marshal.CreateInteger();
if (this._advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
{
if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
}
this._advapi.FreeSid(AdministratorsGroup.Deref());
}
return admin;
}
this.getSessionAttribute = function getSessionAttribute(sessionId, attr) this.getSessionAttribute = function getSessionAttribute(sessionId, attr)
{ {
var buffer = this._marshal.CreatePointer(); var buffer = this._marshal.CreatePointer();

File diff suppressed because one or more lines are too long

View File

@ -92,6 +92,11 @@ function UserSessions()
{ {
} }
this._advapi = this._marshal.CreateNativeProxy('Advapi32.dll');
this._advapi.CreateMethod('AllocateAndInitializeSid');
this._advapi.CreateMethod('CheckTokenMembership');
this._advapi.CreateMethod('FreeSid');
this._user32 = this._marshal.CreateNativeProxy('user32.dll'); this._user32 = this._marshal.CreateNativeProxy('user32.dll');
this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1}); this._user32.CreateMethod({ method: 'RegisterPowerSettingNotification', threadDispatch: 1});
this._user32.CreateMethod('UnregisterPowerSettingNotification'); this._user32.CreateMethod('UnregisterPowerSettingNotification');
@ -150,6 +155,26 @@ function UserSessions()
'WTSIsRemoteSession': 29 'WTSIsRemoteSession': 29
}; };
this.isRoot = function isRoot()
{
var NTAuthority = this._marshal.CreateVariable(6);
NTAuthority.toBuffer().writeInt8(5, 5);
var AdministratorsGroup = this._marshal.CreatePointer();
var admin = false;
if (this._advapi.AllocateAndInitializeSid(NTAuthority, 2, 32, 544, 0, 0, 0, 0, 0, 0, AdministratorsGroup).Val != 0)
{
var member = this._marshal.CreateInteger();
if (this._advapi.CheckTokenMembership(0, AdministratorsGroup.Deref(), member).Val != 0)
{
if (member.toBuffer().readUInt32LE() != 0) { admin = true; }
}
this._advapi.FreeSid(AdministratorsGroup.Deref());
}
return admin;
}
this.getSessionAttribute = function getSessionAttribute(sessionId, attr) this.getSessionAttribute = function getSessionAttribute(sessionId, attr)
{ {
var buffer = this._marshal.CreatePointer(); var buffer = this._marshal.CreatePointer();

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2018-2019 Intel Corporation Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -15,6 +15,7 @@ limitations under the License.
*/ */
var KEY_QUERY_VALUE = 0x0001; var KEY_QUERY_VALUE = 0x0001;
var KEY_ENUMERATE_SUB_KEYS = 0x0008;
var KEY_WRITE = 0x20006; var KEY_WRITE = 0x20006;
var KEY_DATA_TYPES = var KEY_DATA_TYPES =
@ -39,7 +40,10 @@ function windows_registry()
this._marshal = require('_GenericMarshal'); this._marshal = require('_GenericMarshal');
this._AdvApi = this._marshal.CreateNativeProxy('Advapi32.dll'); this._AdvApi = this._marshal.CreateNativeProxy('Advapi32.dll');
this._AdvApi.CreateMethod('RegCreateKeyExA'); this._AdvApi.CreateMethod('RegCreateKeyExA');
this._AdvApi.CreateMethod('RegEnumKeyExA');
this._AdvApi.CreateMethod('RegEnumValueA');
this._AdvApi.CreateMethod('RegOpenKeyExA'); this._AdvApi.CreateMethod('RegOpenKeyExA');
this._AdvApi.CreateMethod('RegQueryInfoKeyA');
this._AdvApi.CreateMethod('RegQueryValueExA'); this._AdvApi.CreateMethod('RegQueryValueExA');
this._AdvApi.CreateMethod('RegCloseKey'); this._AdvApi.CreateMethod('RegCloseKey');
this._AdvApi.CreateMethod('RegDeleteKeyA'); this._AdvApi.CreateMethod('RegDeleteKeyA');
@ -49,16 +53,63 @@ function windows_registry()
this.QueryKey = function QueryKey(hkey, path, key) this.QueryKey = function QueryKey(hkey, path, key)
{ {
var err;
var h = this._marshal.CreatePointer(); var h = this._marshal.CreatePointer();
var len = this._marshal.CreateVariable(4); var len = this._marshal.CreateVariable(4);
var valType = this._marshal.CreateVariable(4); var valType = this._marshal.CreateVariable(4);
key = this._marshal.CreateVariable(key);
var HK = this._marshal.CreatePointer(hkey); var HK = this._marshal.CreatePointer(hkey);
var retVal = null; var retVal = null;
if (key) { key = this._marshal.CreateVariable(key); }
if (!path) { path = ''; }
if (this._AdvApi.RegOpenKeyExA(HK, this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE, h).Val != 0)
if ((err = this._AdvApi.RegOpenKeyExA(HK, this._marshal.CreateVariable(path), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, h).Val) != 0)
{ {
throw ('Error Opening Registry Key: ' + path); throw ('Opening Registry Key: ' + path + ' => Returned Error: ' + err);
}
if ((path == '' && !key) || !key)
{
var result = { subkeys: [], values: [] };
// Enumerate keys
var achClass = this._marshal.CreateVariable(1024);
var achKey = this._marshal.CreateVariable(1024);
var achValue = this._marshal.CreateVariable(32768);
var achValueSize = this._marshal.CreateVariable(4);
var nameSize = this._marshal.CreateVariable(4);
var achClassSize = this._marshal.CreateVariable(4); achClassSize.toBuffer().writeUInt32LE(1024);
var numSubKeys = this._marshal.CreateVariable(4);
var numValues = this._marshal.CreateVariable(4);
var longestSubkeySize = this._marshal.CreateVariable(4);
var longestClassString = this._marshal.CreateVariable(4);
var longestValueName = this._marshal.CreateVariable(4);
var longestValueData = this._marshal.CreateVariable(4);
var securityDescriptor = this._marshal.CreateVariable(4);
var lastWriteTime = this._marshal.CreateVariable(8);
retVal = this._AdvApi.RegQueryInfoKeyA(h.Deref(), achClass, achClassSize, 0,
numSubKeys, longestSubkeySize, longestClassString, numValues,
longestValueName, longestValueData, securityDescriptor, lastWriteTime);
if (retVal.Val != 0) { throw ('RegQueryInfoKeyA() returned error: ' + retVal.Val); }
for(var i = 0; i < numSubKeys.toBuffer().readUInt32LE(); ++i)
{
nameSize.toBuffer().writeUInt32LE(1024);
retVal = this._AdvApi.RegEnumKeyExA(h.Deref(), i, achKey, nameSize, 0, 0, 0, lastWriteTime);
if(retVal.Val == 0)
{
result.subkeys.push(achKey.String);
}
}
for (var i = 0; i < numValues.toBuffer().readUInt32LE() ; ++i)
{
achValueSize.toBuffer().writeUInt32LE(32768);
if(this._AdvApi.RegEnumValueA(h.Deref(), i, achValue, achValueSize, 0, 0, 0, 0).Val == 0)
{
result.values.push(achValue.String);
}
}
return (result);
} }
if(this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, 0, 0, len).Val == 0) if(this._AdvApi.RegQueryValueExA(h.Deref(), key, 0, 0, 0, len).Val == 0)

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
var KEY_QUERY_VALUE=1;var KEY_WRITE=131078;var KEY_DATA_TYPES={REG_NONE:0,REG_SZ:1,REG_EXPAND_SZ:2,REG_BINARY:3,REG_DWORD:4,REG_DWORD_BIG_ENDIAN:5,REG_LINK:6,REG_MULTI_SZ:7,REG_RESOURCE_LIST:8,REG_FULL_RESOURCE_DESCRIPTOR:9,REG_RESOURCE_REQUIREMENTS_LIST:10,REG_QWORD:11};function windows_registry(){this._ObjectId="win-registry";this._marshal=require("_GenericMarshal");this._AdvApi=this._marshal.CreateNativeProxy("Advapi32.dll");this._AdvApi.CreateMethod("RegCreateKeyExA");this._AdvApi.CreateMethod("RegOpenKeyExA");this._AdvApi.CreateMethod("RegQueryValueExA");this._AdvApi.CreateMethod("RegCloseKey");this._AdvApi.CreateMethod("RegDeleteKeyA");this._AdvApi.CreateMethod("RegDeleteValueA");this._AdvApi.CreateMethod("RegSetValueExA");this.HKEY={Root:Buffer.from("80000000","hex").swap32(),CurrentUser:Buffer.from("80000001","hex").swap32(),LocalMachine:Buffer.from("80000002","hex").swap32(),Users:Buffer.from("80000003","hex").swap32()};this.QueryKey=function b(g,k,i){var e=this._marshal.CreatePointer();var j=this._marshal.CreateVariable(4);var m=this._marshal.CreateVariable(4);i=this._marshal.CreateVariable(i);var f=this._marshal.CreatePointer(g);var l=null;if(this._AdvApi.RegOpenKeyExA(f,this._marshal.CreateVariable(k),0,KEY_QUERY_VALUE,e).Val!=0){throw ("Error Opening Registry Key: "+k)}if(this._AdvApi.RegQueryValueExA(e.Deref(),i,0,0,0,j).Val==0){var d=this._marshal.CreateVariable(j.toBuffer().readUInt32LE());if(this._AdvApi.RegQueryValueExA(e.Deref(),i,0,m,d,j).Val==0){switch(m.toBuffer().readUInt32LE()){case KEY_DATA_TYPES.REG_DWORD:l=d.toBuffer().readUInt32LE();break;case KEY_DATA_TYPES.REG_DWORD_BIG_ENDIAN:l=d.toBuffer().readUInt32BE();break;case KEY_DATA_TYPES.REG_SZ:l=d.String;break;case KEY_DATA_TYPES.REG_BINARY:default:l=d.toBuffer();l._data=d;break}}}else{this._AdvApi.RegCloseKey(e.Deref());throw ("Not Found")}this._AdvApi.RegCloseKey(e.Deref());return(l)};this.WriteKey=function c(g,j,i,l){var k;var f=this._marshal.CreatePointer();if(this._AdvApi.RegCreateKeyExA(this._marshal.CreatePointer(g),this._marshal.CreateVariable(j),0,0,0,KEY_WRITE,0,f,0).Val!=0){throw ("Error Opening Registry Key: "+j)}var d;var e;switch(typeof(l)){case"boolean":e=KEY_DATA_TYPES.REG_DWORD;d=this._marshal.CreateVariable(4);d.toBuffer().writeUInt32LE(l?1:0);break;case"number":e=KEY_DATA_TYPES.REG_DWORD;d=this._marshal.CreateVariable(4);d.toBuffer().writeUInt32LE(l);break;case"string":e=KEY_DATA_TYPES.REG_SZ;d=this._marshal.CreateVariable(l);break;default:e=KEY_DATA_TYPES.REG_BINARY;d=this._marshal.CreateVariable(l.length);l.copy(d.toBuffer());break}if(this._AdvApi.RegSetValueExA(f.Deref(),this._marshal.CreateVariable(i),0,e,d,d._size).Val!=0){this._AdvApi.RegCloseKey(f.Deref());throw ("Error writing reg key: "+i)}this._AdvApi.RegCloseKey(f.Deref())};this.DeleteKey=function a(e,g,f){if(!f){if(this._AdvApi.RegDeleteKeyA(this._marshal.CreatePointer(e),this._marshal.CreateVariable(g)).Val!=0){throw ("Error Deleting Key: "+g)}}else{var d=this._marshal.CreatePointer();var i;if(this._AdvApi.RegOpenKeyExA(this._marshal.CreatePointer(e),this._marshal.CreateVariable(g),0,KEY_QUERY_VALUE|KEY_WRITE,d).Val!=0){throw ("Error Opening Registry Key: "+g)}if((i=this._AdvApi.RegDeleteValueA(d.Deref(),this._marshal.CreateVariable(f)).Val)!=0){this._AdvApi.RegCloseKey(d.Deref());throw ("Error["+i+"] Deleting Key: "+g+"."+f)}this._AdvApi.RegCloseKey(d.Deref())}}}module.exports=new windows_registry(); var KEY_QUERY_VALUE=1;var KEY_ENUMERATE_SUB_KEYS=8;var KEY_WRITE=131078;var KEY_DATA_TYPES={REG_NONE:0,REG_SZ:1,REG_EXPAND_SZ:2,REG_BINARY:3,REG_DWORD:4,REG_DWORD_BIG_ENDIAN:5,REG_LINK:6,REG_MULTI_SZ:7,REG_RESOURCE_LIST:8,REG_FULL_RESOURCE_DESCRIPTOR:9,REG_RESOURCE_REQUIREMENTS_LIST:10,REG_QWORD:11};function windows_registry(){this._ObjectId="win-registry";this._marshal=require("_GenericMarshal");this._AdvApi=this._marshal.CreateNativeProxy("Advapi32.dll");this._AdvApi.CreateMethod("RegCreateKeyExA");this._AdvApi.CreateMethod("RegEnumKeyExA");this._AdvApi.CreateMethod("RegEnumValueA");this._AdvApi.CreateMethod("RegOpenKeyExA");this._AdvApi.CreateMethod("RegQueryInfoKeyA");this._AdvApi.CreateMethod("RegQueryValueExA");this._AdvApi.CreateMethod("RegCloseKey");this._AdvApi.CreateMethod("RegDeleteKeyA");this._AdvApi.CreateMethod("RegDeleteValueA");this._AdvApi.CreateMethod("RegSetValueExA");this.HKEY={Root:Buffer.from("80000000","hex").swap32(),CurrentUser:Buffer.from("80000001","hex").swap32(),LocalMachine:Buffer.from("80000002","hex").swap32(),Users:Buffer.from("80000003","hex").swap32()};this.QueryKey=function b(o,A,q){var l;var m=this._marshal.CreatePointer();var s=this._marshal.CreateVariable(4);var E=this._marshal.CreateVariable(4);var n=this._marshal.CreatePointer(o);var C=null;if(q){q=this._marshal.CreateVariable(q)}if(!A){A=""}if((l=this._AdvApi.RegOpenKeyExA(n,this._marshal.CreateVariable(A),0,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,m).Val)!=0){throw ("Opening Registry Key: "+A+" => Returned Error: "+l)}if((A==""&&!q)||!q){var B={subkeys:[],values:[]};var d=this._marshal.CreateVariable(1024);var f=this._marshal.CreateVariable(1024);var g=this._marshal.CreateVariable(32768);var j=this._marshal.CreateVariable(4);var x=this._marshal.CreateVariable(4);var e=this._marshal.CreateVariable(4);e.toBuffer().writeUInt32LE(1024);var y=this._marshal.CreateVariable(4);var z=this._marshal.CreateVariable(4);var u=this._marshal.CreateVariable(4);var t=this._marshal.CreateVariable(4);var w=this._marshal.CreateVariable(4);var v=this._marshal.CreateVariable(4);var D=this._marshal.CreateVariable(4);var r=this._marshal.CreateVariable(8);C=this._AdvApi.RegQueryInfoKeyA(m.Deref(),d,e,0,y,u,t,z,w,v,D,r);if(C.Val!=0){throw ("RegQueryInfoKeyA() returned error: "+C.Val)}for(var p=0;p<y.toBuffer().readUInt32LE();++p){x.toBuffer().writeUInt32LE(1024);C=this._AdvApi.RegEnumKeyExA(m.Deref(),p,f,x,0,0,0,r);if(C.Val==0){B.subkeys.push(f.String)}}for(var p=0;p<z.toBuffer().readUInt32LE();++p){j.toBuffer().writeUInt32LE(32768);if(this._AdvApi.RegEnumValueA(m.Deref(),p,g,j,0,0,0,0).Val==0){B.values.push(g.String)}}return(B)}if(this._AdvApi.RegQueryValueExA(m.Deref(),q,0,0,0,s).Val==0){var k=this._marshal.CreateVariable(s.toBuffer().readUInt32LE());if(this._AdvApi.RegQueryValueExA(m.Deref(),q,0,E,k,s).Val==0){switch(E.toBuffer().readUInt32LE()){case KEY_DATA_TYPES.REG_DWORD:C=k.toBuffer().readUInt32LE();break;case KEY_DATA_TYPES.REG_DWORD_BIG_ENDIAN:C=k.toBuffer().readUInt32BE();break;case KEY_DATA_TYPES.REG_SZ:C=k.String;break;case KEY_DATA_TYPES.REG_BINARY:default:C=k.toBuffer();C._data=k;break}}}else{this._AdvApi.RegCloseKey(m.Deref());throw ("Not Found")}this._AdvApi.RegCloseKey(m.Deref());return(C)};this.WriteKey=function c(g,j,i,l){var k;var f=this._marshal.CreatePointer();if(this._AdvApi.RegCreateKeyExA(this._marshal.CreatePointer(g),this._marshal.CreateVariable(j),0,0,0,KEY_WRITE,0,f,0).Val!=0){throw ("Error Opening Registry Key: "+j)}var d;var e;switch(typeof(l)){case"boolean":e=KEY_DATA_TYPES.REG_DWORD;d=this._marshal.CreateVariable(4);d.toBuffer().writeUInt32LE(l?1:0);break;case"number":e=KEY_DATA_TYPES.REG_DWORD;d=this._marshal.CreateVariable(4);d.toBuffer().writeUInt32LE(l);break;case"string":e=KEY_DATA_TYPES.REG_SZ;d=this._marshal.CreateVariable(l);break;default:e=KEY_DATA_TYPES.REG_BINARY;d=this._marshal.CreateVariable(l.length);l.copy(d.toBuffer());break}if(this._AdvApi.RegSetValueExA(f.Deref(),this._marshal.CreateVariable(i),0,e,d,d._size).Val!=0){this._AdvApi.RegCloseKey(f.Deref());throw ("Error writing reg key: "+i)}this._AdvApi.RegCloseKey(f.Deref())};this.DeleteKey=function a(e,g,f){if(!f){if(this._AdvApi.RegDeleteKeyA(this._marshal.CreatePointer(e),this._marshal.CreateVariable(g)).Val!=0){throw ("Error Deleting Key: "+g)}}else{var d=this._marshal.CreatePointer();var i;if(this._AdvApi.RegOpenKeyExA(this._marshal.CreatePointer(e),this._marshal.CreateVariable(g),0,KEY_QUERY_VALUE|KEY_WRITE,d).Val!=0){throw ("Error Opening Registry Key: "+g)}if((i=this._AdvApi.RegDeleteValueA(d.Deref(),this._marshal.CreateVariable(f)).Val)!=0){this._AdvApi.RegCloseKey(d.Deref());throw ("Error["+i+"] Deleting Key: "+g+"."+f)}this._AdvApi.RegCloseKey(d.Deref())}}}module.exports=new windows_registry();

2
db.js
View File

@ -151,7 +151,7 @@ module.exports.CreateDB = function (parent) {
obj.Get = function (id, func) { obj.file.find({ _id: id }, func); }; obj.Get = function (id, func) { obj.file.find({ _id: id }, func); };
obj.GetAll = function (func) { obj.file.find({}, func); }; obj.GetAll = function (func) { obj.file.find({}, func); };
obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }, { type: 0 }, func); }; obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }, { type: 0 }, func); };
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, func) { obj.file.find({ type: type, domain: domain, meshid: { $in: meshes } }, { type: 0 }, func); }; obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, id, func) { var x = { type: type, domain: domain, meshid: { $in: meshes } }; if (id) { x._id = id; } obj.file.find(x, { type: 0 }, func); };
obj.GetAllType = function (type, func) { obj.file.find({ type: type }, func); }; obj.GetAllType = function (type, func) { obj.file.find({ type: type }, func); };
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }, func); }; obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }, func); };
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }, { type: 0 }, func); }; obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }, { type: 0 }, func); };

View File

@ -230,6 +230,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
switch (command.action) { switch (command.action) {
case 'ping': { try { ws.send(JSON.stringify({ action: 'pong' })); } catch (ex) { } break; } case 'ping': { try { ws.send(JSON.stringify({ action: 'pong' })); } catch (ex) { } break; }
case 'authcookie':
{
// Renew the authentication cookie
try { ws.send(JSON.stringify({ action: 'authcookie', cookie: obj.parent.parent.encodeCookie({ userid: user._id, domainid: domain.id }, obj.parent.loginCookieEncryptionKey) })); } catch (ex) { }
break;
}
case 'serverstats': case 'serverstats':
{ {
if ((user.siteadmin) != 0) { if ((user.siteadmin) != 0) {
@ -267,7 +273,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
} }
// Request a list of all nodes // Request a list of all nodes
obj.db.GetAllTypeNoTypeFieldMeshFiltered(links, domain.id, 'node', function (err, docs) { obj.db.GetAllTypeNoTypeFieldMeshFiltered(links, domain.id, 'node', command.id, function (err, docs) {
var r = {}; var r = {};
for (i in docs) { for (i in docs) {
// Add the connection state // Add the connection state

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.2.7-a", "version": "0.2.7-b",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -33,21 +33,21 @@
</head> </head>
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" oncontextmenu="handleContextMenu(event)" style="display:none"> <body id="body" onload="if (typeof(startup) !== 'undefined') startup();" oncontextmenu="handleContextMenu(event)" style="display:none">
<!-- right click menu --> <!-- right click menu -->
<div id="contextMenu" class="contextMenu" style="display:none"> <div id="contextMenu" class="contextMenu noselect" style="display:none">
<div id="cxinfo" class="cmtext" onclick="cmaction(1)"><b>Information</b></div> <div id="cxinfo" class="cmtext" onclick="cmaction(1,event)"><b>Information</b></div>
<div id="cxdesktop" class="cmtext" onclick="cmaction(3)">Desktop</div> <div id="cxdesktop" class="cmtext" onclick="cmaction(3,event)">Desktop</div>
<div id="cxterminal" class="cmtext" onclick="cmaction(2)">Terminal</div> <div id="cxterminal" class="cmtext" onclick="cmaction(2,event)">Terminal</div>
<div id="cxfiles" class="cmtext" onclick="cmaction(4)">Files</div> <div id="cxfiles" class="cmtext" onclick="cmaction(4,event)">Files</div>
<div id="cxevents" class="cmtext" onclick="cmaction(5)">Events</div> <div id="cxevents" class="cmtext" onclick="cmaction(5,event)">Events</div>
<div id="cxconsole" class="cmtext" onclick="cmaction(6)">Console</div> <div id="cxconsole" class="cmtext" onclick="cmaction(6,event)">Console</div>
<hr id="cxmgroupsplit" /> <hr id="cxmgroupsplit" />
<div id="cxmdesktop" class="cmtext" onclick="cmaction(7)" style=display:none>Multi-Desktop</div> <div id="cxmdesktop" class="cmtext" onclick="cmaction(7,event)" style=display:none>Multi-Desktop</div>
</div> </div>
<div id="meshContextMenu" class="contextMenu" style="display: none; min-width: 0px"> <div id="meshContextMenu" class="contextMenu,noselect" style="display: none; min-width: 0px">
<div id="cxselectall" class="cmtext" onclick="cmmeshaction(1)">Select All</div> <div id="cxselectall" class="cmtext" onclick="cmmeshaction(1,event)">Select All</div>
<div id="cxselectnone" class="cmtext" onclick="cmmeshaction(2)">Select None</div> <div id="cxselectnone" class="cmtext" onclick="cmmeshaction(2,event)">Select None</div>
<hr id="cxmgroupsplit2" style=display:none /> <hr id="cxmgroupsplit2" style=display:none />
<div id="cxmmdesktop" class="cmtext" style=display:none onclick="cmmeshaction(3)">Multi-Desktop</div> <div id="cxmmdesktop" class="cmtext" style=display:none onclick="cmmeshaction(3,event)">Multi-Desktop</div>
</div> </div>
<!-- main page --> <!-- main page -->
<div id=container style=max-height:100vh;position:relative> <div id=container style=max-height:100vh;position:relative>
@ -156,7 +156,7 @@
<div id=devViewButton3 class=viewSelector onclick=onDeviceViewChange(3) title="Desktops"><div class="viewSelector3"></div></div> <div id=devViewButton3 class=viewSelector onclick=onDeviceViewChange(3) title="Desktops"><div class="viewSelector3"></div></div>
<div id=devViewButton4 class=viewSelector onclick=onDeviceViewChange(4) title="Map"><div class="viewSelector4"></div></div> <div id=devViewButton4 class=viewSelector onclick=onDeviceViewChange(4) title="Map"><div class="viewSelector4"></div></div>
</div><div><h1>My Devices</h1></div> </div><div><h1>My Devices</h1></div>
<table style=width:100%;height:24px;background-color:#d3d9d6;vertical-align:middle;border-spacing:0> <table class="noselect" style=width:100%;height:24px;background-color:#d3d9d6;vertical-align:middle;border-spacing:0>
<tr> <tr>
<td class=h1></td> <td class=h1></td>
<td id=devListToolbar class=style14 style=display:none> <td id=devListToolbar class=style14 style=display:none>
@ -221,7 +221,7 @@
</tr> </tr>
</table> </table>
</div> </div>
<div id="xdevices" style="max-height:calc(100vh - 239px);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;display:none"></div> <div id="xdevices" class="noselect" style="max-height:calc(100vh - 239px);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;display:none"></div>
<div id="xdevicesmap" style="height:calc(100vh - 239px);width:100%;overflow:hidden;position:relative;display:none"> <div id="xdevicesmap" style="height:calc(100vh - 239px);width:100%;overflow:hidden;position:relative;display:none">
<div id=xmapSearchResultsDlg style="position:absolute;display:none;max-height:280px;left:5px;top:5px;max-width:250px;z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666"> <div id=xmapSearchResultsDlg style="position:absolute;display:none;max-height:280px;left:5px;top:5px;max-width:250px;z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666">
<div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0">
@ -371,7 +371,7 @@
<tr> <tr>
<td style=width:auto valign=top> <td style=width:auto valign=top>
<div id=p10title> <div id=p10title>
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p10BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>General - <span id=p10deviceName></span></h1> <h1>General - <span id=p10deviceName></span></h1>
</div> </div>
<div id=p10html></div> <div id=p10html></div>
@ -389,7 +389,7 @@
<div id=p11 class=noselect style=display:none> <div id=p11 class=noselect style=display:none>
<div id="p11title"> <div id="p11title">
<div id=p11deviceNameHeader> <div id=p11deviceNameHeader>
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p11BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<div style="float:right" id="devListToolbarViewIcons"><div class="viewSelector" onclick=deskToggleFull(event) title="Full Screen. Hold shift to browser full screen."><div class="viewSelector5"></div></div></div> <div style="float:right" id="devListToolbarViewIcons"><div class="viewSelector" onclick=deskToggleFull(event) title="Full Screen. Hold shift to browser full screen."><div class="viewSelector5"></div></div></div>
<h1>Desktop - <span id=p11deviceName></span></h1> <h1>Desktop - <span id=p11deviceName></span></h1>
</div> </div>
@ -475,7 +475,7 @@
</div> </div>
<div id=p12 style="display:none"> <div id=p12 style="display:none">
<div id="p12title"> <div id="p12title">
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p12BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>Terminal - <span id=p12deviceName></span></h1> <h1>Terminal - <span id=p12deviceName></span></h1>
</div> </div>
<div id="p12warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick=showFeaturesDlg()> <div id="p12warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick=showFeaturesDlg()>
@ -536,7 +536,7 @@
</div> </div>
<div id=p13 style=display:none> <div id=p13 style=display:none>
<div id="p13title"> <div id="p13title">
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p13BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>Files - <span id=p13deviceName></span></h1> <h1>Files - <span id=p13deviceName></span></h1>
</div> </div>
<table id="p13toolbar" style="width: 100%" cellpadding="0" cellspacing="0"> <table id="p13toolbar" style="width: 100%" cellpadding="0" cellspacing="0">
@ -596,14 +596,14 @@
</div> </div>
<div id=p14 style=display:none> <div id=p14 style=display:none>
<div id="p14title"> <div id="p14title">
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p14BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>Intel&reg; AMT - <span id=p14deviceName></span></h1> <h1>Intel&reg; AMT - <span id=p14deviceName></span></h1>
</div> </div>
<iframe id=p14iframe style="width:100%;height:calc(100vh - 242px);border:0;overflow:hidden" src="/commander.htm"></iframe> <iframe id=p14iframe style="width:100%;height:calc(100vh - 242px);border:0;overflow:hidden" src="/commander.htm"></iframe>
</div> </div>
<div id=p15 style=display:none> <div id=p15 style=display:none>
<div id="p15title"> <div id="p15title">
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p15BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>Console - <span id=p15deviceName></span></h1> <h1>Console - <span id=p15deviceName></span></h1>
</div> </div>
<table cellpadding=0 cellspacing=0 style="width:100%;padding:0px;padding:0px;margin-top:0px"> <table cellpadding=0 cellspacing=0 style="width:100%;padding:0px;padding:0px;margin-top:0px">
@ -643,7 +643,7 @@
</div> </div>
<div id=p16 style=display:none> <div id=p16 style=display:none>
<div id="p16title"> <div id="p16title">
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div> <div id="p16BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>Events - <span id=p16deviceName></span></h1> <h1>Events - <span id=p16deviceName></span></h1>
</div> </div>
<div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px> <div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px>
@ -849,7 +849,7 @@
var meshserver = null; var meshserver = null;
var meshes = {}; var meshes = {};
var meshcount = 0; var meshcount = 0;
var nodes = []; var nodes = null;
var filetree = {}; var filetree = {};
var userinfo = null; var userinfo = null;
var serverinfo = null; var serverinfo = null;
@ -868,6 +868,7 @@
var domain = "{{{domain}}}"; var domain = "{{{domain}}}";
var domainUrl = "{{{domainurl}}}"; var domainUrl = "{{{domainurl}}}";
var authCookie = "{{{authCookie}}}"; var authCookie = "{{{authCookie}}}";
var authCookieRenewTimer = null;
var multiDesktop = {}; var multiDesktop = {};
var multiDesktopFilter = null; var multiDesktopFilter = null;
var serverPublicNamePort = "{{{serverDnsName}}}:{{{serverPublicPort}}}"; var serverPublicNamePort = "{{{serverDnsName}}}:{{{serverPublicPort}}}";
@ -889,8 +890,6 @@
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; } if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
} }
toggleFullScreen();
// Check if we are in debug mode // Check if we are in debug mode
args = parseUriArgs(); args = parseUriArgs();
debugmode = args.debug; debugmode = args.debug;
@ -899,12 +898,13 @@
QV('autoconnectbutton2', debugmode); // Terminal QV('autoconnectbutton2', debugmode); // Terminal
QV('autoconnectbutton1', debugmode); // Desktop QV('autoconnectbutton1', debugmode); // Desktop
toggleFullScreen();
// Setup page visuals // Setup page visuals
if (args.hide) { if (args.hide) {
var hide = parseInt(args.hide); var hide = parseInt(args.hide);
QV('masthead', !(hide & 1)); QV('masthead', !(hide & 1));
QV('topbarmaster', !(hide & 2)); QV('topbarmaster', !(hide & 2));
QV('page_leftbar', !(hide & 2));
QV('footer', !(hide & 4)); QV('footer', !(hide & 4));
QV('p10title', !(hide & 8)); QV('p10title', !(hide & 8));
QV('p11title', !(hide & 8)); QV('p11title', !(hide & 8));
@ -913,6 +913,21 @@
QV('p14title', !(hide & 8)); QV('p14title', !(hide & 8));
QV('p15title', !(hide & 8)); QV('p15title', !(hide & 8));
QV('p16title', !(hide & 8)); QV('p16title', !(hide & 8));
if (hide & 16) {
QV('page_leftbar', false);
QS('page_content').left = '0px';
}
}
// We are looking at a single device, remove all the back buttons
if ('{{currentNode}}' != '') {
QV('p10BackButton', false);
QV('p11BackButton', false);
QV('p12BackButton', false);
QV('p13BackButton', false);
QV('p14BackButton', false);
QV('p15BackButton', false);
QV('p16BackButton', false);
} }
p1updateInfo(); p1updateInfo();
@ -980,6 +995,8 @@
// Toggle the web page to full screen // Toggle the web page to full screen
function toggleFullScreen(toggle) { function toggleFullScreen(toggle) {
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); } if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
var hide = 0;
if (args.hide) { hide = parseInt(args.hide); }
if (webPageFullScreen == false) { if (webPageFullScreen == false) {
QS('container').width = '960px'; QS('container').width = '960px';
QS('container')['border-right'] = '1px solid #b7b7b7'; QS('container')['border-right'] = '1px solid #b7b7b7';
@ -1007,7 +1024,7 @@
QS('container')['overflow'] = 'hidden'; QS('container')['overflow'] = 'hidden';
QS('page_content').position = 'absolute'; QS('page_content').position = 'absolute';
QS('page_content').top = '66px'; QS('page_content').top = '66px';
QS('page_content').left = '90px'; QS('page_content').left = (hide & 16)?'0px':'90px';
QS('page_content').right = '0px'; QS('page_content').right = '0px';
QS('page_content').bottom = '0px'; QS('page_content').bottom = '0px';
QS('column_l').height = 'calc(100vh - 135px)'; QS('column_l').height = 'calc(100vh - 135px)';
@ -1016,14 +1033,14 @@
QS('column_l')["max-height"] = 'calc(100vh - 135px)'; QS('column_l')["max-height"] = 'calc(100vh - 135px)';
QV('MainMenuSpan', false); QV('MainMenuSpan', false);
QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen); QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
QV('page_leftbar', true); QV('page_leftbar', !(hide & 16));
} }
//center(); //center();
masterUpdate(512); masterUpdate(512);
QV('body', true); QV('body', true);
} }
function getNodeFromId(id) { for (var i in nodes) { if (nodes[i]._id == id) return nodes[i]; } return null; } function getNodeFromId(id) { if (nodes != null) { for (var i in nodes) { if (nodes[i]._id == id) return nodes[i]; } } return null; }
function reload() { window.location.href = window.location.href; } function reload() { window.location.href = window.location.href; }
function onStateChanged(server, state, prevState, errorCode) { function onStateChanged(server, state, prevState, errorCode) {
@ -1043,12 +1060,14 @@
QV('logoutControl', false); QV('logoutControl', false);
if (errorCode == 'noauth') { QH('p0span', 'Unable to perform authentication'); return; } if (errorCode == 'noauth') { QH('p0span', 'Unable to perform authentication'); return; }
if (prevState == 2) { setTimeout(serverPoll, 5000); } else { QH('p0span', 'Unable to connect web socket'); } if (prevState == 2) { setTimeout(serverPoll, 5000); } else { QH('p0span', 'Unable to connect web socket'); }
if (authCookieRenewTimer != null) { clearInterval(authCookieRenewTimer); authCookieRenewTimer = null; }
} else if (state == 2) { } else if (state == 2) {
// Fetch list of meshes, nodes, files // Fetch list of meshes, nodes, files
meshserver.send({ action: 'meshes' }); meshserver.send({ action: 'meshes' });
meshserver.send({ action: 'nodes' }); meshserver.send({ action: 'nodes', id: '{{currentNode}}' });
meshserver.send({ action: 'files' }); if ('{{currentNode}}' == '') { meshserver.send({ action: 'files' }); }
go(1); go(1);
authCookieRenewTimer = setInterval(function () { meshserver.send({ action: 'authcookie' }); }, 1800000); // Request a cookie refresh every 30 minutes.
} }
} }
@ -1140,6 +1159,11 @@
updateServerStats(message); updateServerStats(message);
break; break;
} }
case 'authcookie': {
// Got an authentication cookie refresh
authCookie = message.cookie;
break;
}
case 'serverinfo': { case 'serverinfo': {
serverinfo = message.serverinfo; serverinfo = message.serverinfo;
break; break;
@ -1221,7 +1245,7 @@
// Check if this is a message from a node // Check if this is a message from a node
if (message.nodeid != null) { if (message.nodeid != null) {
var index = -1; var index = -1;
for (var i in nodes) { if (nodes[i]._id == message.nodeid) { index = i; break; } } if (nodes != null) { for (var i in nodes) { if (nodes[i]._id == message.nodeid) { index = i; break; } } }
if (index != -1) { if (index != -1) {
// Node was found, dispatch the message // Node was found, dispatch the message
if (message.type == 'console') { p15consoleReceive(nodes[index], message.value); } // This is a console message. if (message.type == 'console') { p15consoleReceive(nodes[index], message.value); } // This is a console message.
@ -1444,7 +1468,7 @@
// Delete all nodes in that mesh // Delete all nodes in that mesh
var newnodes = []; var newnodes = [];
for (var i in nodes) { if (nodes[i].meshid != message.event.meshid) { newnodes.push(nodes[i]); } } if (nodes != null) { for (var i in nodes) { if (nodes[i].meshid != message.event.meshid) { newnodes.push(nodes[i]); } } }
nodes = newnodes; nodes = newnodes;
masterUpdate(4); masterUpdate(4);
@ -1464,6 +1488,7 @@
node.state = 0; node.state = 0;
if (!node.icon) node.icon = 1; if (!node.icon) node.icon = 1;
node.ident = ++nodeShortIdent; node.ident = ++nodeShortIdent;
if (nodes == null) { }
nodes.push(node); nodes.push(node);
// Web page update // Web page update
@ -1753,6 +1778,7 @@
var deviceHeaders = {}; var deviceHeaders = {};
var oldviewmode = 0; var oldviewmode = 0;
function updateDevices() { function updateDevices() {
if (nodes == null) { return; }
var r = '', c = 0, current = null, count = 0, displayedMeshes = {}, view = Q('viewselect').value, groups = {}, groupCount = {}; var r = '', c = 0, current = null, count = 0, displayedMeshes = {}, view = Q('viewselect').value, groups = {}, groupCount = {};
QV('xdevices', view < 4); QV('xdevices', view < 4);
QV('xdevicesmap', view == 4); QV('xdevicesmap', view == 4);
@ -1842,19 +1868,19 @@
var nodestate = NodeStateStr(nodes[i]); var nodestate = NodeStateStr(nodes[i]);
if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; } if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; }
if (view == 1) { if (view == 1) {
r += '<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:' + deviceBoxWidth + 'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\')><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:' + (deviceBoxWidth - 100) + 'px title="' + title + '">' + name + '</div><div>' + nodestate + '</div></div><div class=g2></div></div></div></div>'; r += '<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:' + deviceBoxWidth + 'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div><div style=height:100%;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:' + (deviceBoxWidth - 100) + 'px title="' + title + '">' + name + '</div><div>' + nodestate + '</div></div><div class=g2></div></div></div></div>';
} else if (view == 2) { } else if (view == 2) {
r += '<tr><td><div id=devs class=bar18 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium>'; r += '<tr><td><div id=devs class=bar18 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium>';
r += '<div style=width:22px;float:left;background-color:white><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div>'; r += '<div style=width:22px;float:left;background-color:white><input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox></div>';
r += '<div style=float:left;height:18px;width:18px;background-color:white onclick=gotoDevice(\'' + nodes[i]._id + '\')><div class=j' + icon + ' style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>'; r += '<div style=float:left;height:18px;width:18px;background-color:white onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)><div class=j' + icon + ' style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>';
r += '<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>'; r += '<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>';
r += '<div style=cursor:pointer;font-size:14px title="' + title + '" onclick=gotoDevice(\'' + nodes[i]._id + '\')><span style=float:right>' + nodestate + '</span><span style=width:300px>' + name + '</span></div></div></td></tr>'; r += '<div style=cursor:pointer;font-size:14px title="' + title + '" onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)><span style=float:right>' + nodestate + '</span><span style=width:300px>' + name + '</span></div></div></td></tr>';
} else if ((view == 3) && (nodes[i].conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && ((nodes[i].agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM. } else if ((view == 3) && (nodes[i].conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && ((nodes[i].agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM.
if ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + nodes[i]._id) >= 0)) { if ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + nodes[i]._id) >= 0)) {
r += '<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div style=padding:3px;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\',11)>'; r += '<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div style=padding:3px;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\',11,null,event)>';
//r += '<input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox style=float:left>'; //r += '<input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox style=float:left>';
r += '<div class="j' + icon + '" style=width:16px;float:left></div>&nbsp;' + name + '</div>'; r += '<div class="j' + icon + '" style=width:16px;float:left></div>&nbsp;' + name + '</div>';
r += '<span onclick=gotoDevice(\'' + nodes[i]._id + '\')></span><div id=xkvmid_' + nodes[i]._id.split('/')[2] + '><div id=skvmid_' + nodes[i]._id.split('/')[2] + ' style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\'' + nodes[i]._id + '\')>Disconnected</div></div>'; r += '<span onclick=gotoDevice(\'' + nodes[i]._id + '\',null,null,event)></span><div id=xkvmid_' + nodes[i]._id.split('/')[2] + '><div id=skvmid_' + nodes[i]._id.split('/')[2] + ' style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\'' + nodes[i]._id + '\')>Disconnected</div></div>';
r += '</div>'; r += '</div>';
kvmDivs.push(nodes[i]._id); kvmDivs.push(nodes[i]._id);
} }
@ -2479,7 +2505,7 @@
// Get the node and set the menu options // Get the node and set the menu options
var nodeid = contextelement.children[1].attributes.onclick.value; var nodeid = contextelement.children[1].attributes.onclick.value;
var node = getNodeFromId(nodeid.substring(12, nodeid.length - 2)); var node = getNodeFromId(nodeid.substring(12, nodeid.length - 18));
var mesh = meshes[node.meshid]; var mesh = meshes[node.meshid];
var meshlinks = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()]; var meshlinks = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()];
var meshrights = meshlinks.rights; var meshrights = meshlinks.rights;
@ -2493,16 +2519,20 @@
return haltEvent(event); return haltEvent(event);
} }
function cmaction(action) { function cmaction(action,event) {
var nodeid = contextelement.children[1].attributes.onclick.value; var nodeid = contextelement.children[1].attributes.onclick.value;
nodeid = nodeid.substring(12, nodeid.length - 2); nodeid = nodeid.substring(12, nodeid.length - 18);
if (action == 1) gotoDevice(nodeid, 10); // General
if (action == 2) gotoDevice(nodeid, 12); // Desktop
if (action == 3) gotoDevice(nodeid, 11); // Terminal
if (action == 4) gotoDevice(nodeid, 13); // Files
if (action == 5) gotoDevice(nodeid, 16); // Events
if (action == 6) gotoDevice(nodeid, 15); // Console
if (action == 7) { Q('viewselect').value = 3; Q('viewselect').onchange(); Q('autoConnectDesktopCheckbox').checked = true; Q('autoConnectDesktopCheckbox').onclick(); } // Multi-Desktop if (action == 7) { Q('viewselect').value = 3; Q('viewselect').onchange(); Q('autoConnectDesktopCheckbox').checked = true; Q('autoConnectDesktopCheckbox').onclick(); } // Multi-Desktop
if ((action > 0) && (action < 7)) {
var panel = [0, 10, 12, 11, 13, 16, 15][action]; // (invalid), General, Desktop, Terminal, Files, Events, Console
if (event && (event.shiftKey == true)) {
// Open the device in a different tab
window.open(window.location.origin + '?node=' + nodeid.split('/')[2] + '&viewmode=' + panel + '&hide=16', 'meshcentral:' + nodeid);
} else {
// Go to the right panel
gotoDevice(nodeid, panel);
}
}
} }
function cmmeshaction(action) { function cmmeshaction(action) {
@ -3145,7 +3175,13 @@
var powerTimelineUpdate = null; var powerTimelineUpdate = null;
var powerTimeline = null; var powerTimeline = null;
function getCurrentNode() { return currentNode; }; function getCurrentNode() { return currentNode; };
function gotoDevice(nodeid, panel, refresh) { function gotoDevice(nodeid, panel, refresh, event) {
if (event && (event.shiftKey == true)) {
// Open the device in a different tab
window.open(window.location.origin + '?node=' + nodeid.split('/')[2] + '&viewmode=10&hide=16', 'meshcentral:' + nodeid);
return;
}
//disconnectAllKvmFunction(); //disconnectAllKvmFunction();
var node = getNodeFromId(nodeid); var node = getNodeFromId(nodeid);
var mesh = meshes[node.meshid]; var mesh = meshes[node.meshid];
@ -3355,6 +3391,9 @@
// Ask for device events // Ask for device events
refreshDeviceEvents(); refreshDeviceEvents();
// Update the web page title
if ((currentNode) && (xxcurrentView >= 10) && (xxcurrentView < 20)) { document.title = 'MeshCentral - ' + currentNode.name; } else { document.title = 'MeshCentral'; }
} }
setupDesktop(); // Always refresh the desktop, even if we are on the same device, we need to do some canvas switching. setupDesktop(); // Always refresh the desktop, even if we are on the same device, we need to do some canvas switching.
if (!panel) panel = 10; if (!panel) panel = 10;
@ -6605,6 +6644,9 @@
} }
if (x == 1) masterUpdate(4); if (x == 1) masterUpdate(4);
// Update the web page title
if ((currentNode) && (x >= 10) && (x < 20)) { document.title = 'MeshCentral - ' + currentNode.name; } else { document.title = 'MeshCentral'; }
} }
// Generic methods // Generic methods