Added Windows Service control in remote desktop tools

This commit is contained in:
Ylian Saint-Hilaire 2019-07-31 16:49:23 -07:00
parent c4b0e04d82
commit df271eb36e
15 changed files with 256 additions and 38 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.

View File

@ -672,7 +672,9 @@ function createMeshCore(agent)
case 'ps': { case 'ps': {
// Return the list of running processes // Return the list of running processes
if (data.sessionid) { if (data.sessionid) {
processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); }); processManager.getProcesses(function (plist) {
mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid });
});
} }
break; break;
} }
@ -684,6 +686,39 @@ function createMeshCore(agent)
} }
break; break;
} }
case 'services': {
// Return the list of installed services
var services = null;
try { services = require('service-manager').manager.enumerateService(); } catch (e) { }
if (services != null) { mesh.SendCommand({ "action": "msg", "type": "services", "value": JSON.stringify(services), "sessionid": data.sessionid }); }
break;
}
case 'serviceStop': {
// Stop a service
try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.stop(); }
} catch (e) { }
break;
}
case 'serviceStart': {
// Start a service
try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.start(); }
} catch (e) { }
break;
}
/*
case 'serviceRestart': {
// Start a service
try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.stop(); service.start(); }
} catch (e) { }
break;
}
*/
case 'openUrl': { case 'openUrl': {
// Open a local web browser and return success/fail // Open a local web browser and return success/fail
MeshServerLog('Opening: ' + data.url, data); MeshServerLog('Opening: ' + data.url, data);
@ -2037,6 +2072,11 @@ function createMeshCore(agent)
response = JSON.stringify(addedModules); response = JSON.stringify(addedModules);
break; break;
} }
case 'listservices': {
var services = require('service-manager').manager.enumerateService();
response = JSON.stringify(services, null, 1);
break;
}
case 'getscript': { case 'getscript': {
if (args['_'].length != 1) { if (args['_'].length != 1) {
response = 'Proper usage: getscript [scriptNumber].'; response = 'Proper usage: getscript [scriptNumber].';

View File

@ -672,7 +672,9 @@ function createMeshCore(agent)
case 'ps': { case 'ps': {
// Return the list of running processes // Return the list of running processes
if (data.sessionid) { if (data.sessionid) {
processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); }); processManager.getProcesses(function (plist) {
mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid });
});
} }
break; break;
} }
@ -684,6 +686,39 @@ function createMeshCore(agent)
} }
break; break;
} }
case 'services': {
// Return the list of installed services
var services = null;
try { services = require('service-manager').manager.enumerateService(); } catch (e) { }
if (services != null) { mesh.SendCommand({ "action": "msg", "type": "services", "value": JSON.stringify(services), "sessionid": data.sessionid }); }
break;
}
case 'serviceStop': {
// Stop a service
try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.stop(); }
} catch (e) { }
break;
}
case 'serviceStart': {
// Start a service
try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.start(); }
} catch (e) { }
break;
}
/*
case 'serviceRestart': {
// Start a service
try {
var service = require('service-manager').manager.getService(data.serviceName);
if (service != null) { service.stop(); service.start(); }
} catch (e) { }
break;
}
*/
case 'openUrl': { case 'openUrl': {
// Open a local web browser and return success/fail // Open a local web browser and return success/fail
MeshServerLog('Opening: ' + data.url, data); MeshServerLog('Opening: ' + data.url, data);
@ -2037,6 +2072,11 @@ function createMeshCore(agent)
response = JSON.stringify(addedModules); response = JSON.stringify(addedModules);
break; break;
} }
case 'listservices': {
var services = require('service-manager').manager.enumerateService();
response = JSON.stringify(services, null, 1);
break;
}
case 'getscript': { case 'getscript': {
if (args['_'].length != 1) { if (args['_'].length != 1) {
response = 'Proper usage: getscript [scriptNumber].'; response = 'Proper usage: getscript [scriptNumber].';

18
db.js
View File

@ -531,12 +531,12 @@ module.exports.CreateDB = function (parent, func) {
} }
}; };
obj.GetAll = function (func) { obj.file.find({}).toArray(func); }; obj.GetAll = function (func) { obj.file.find({}).toArray(func); };
obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }, { type: 0 }).toArray(func); }; obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }).project({ type: 0 }).toArray(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 }).toArray(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 }).toArray(func); };
obj.GetAllType = function (type, func) { obj.file.find({ type: type }).toArray(func); }; obj.GetAllType = function (type, func) { obj.file.find({ type: type }).toArray(func); };
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }).toArray(func); }; obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }).toArray(func); };
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }, { type: 0 }).toArray(func); }; obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }).project({ type: 0 }).toArray(func); };
obj.GetUserWithVerifiedEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email, emailVerified: true }, { type: 0 }).toArray(func); }; obj.GetUserWithVerifiedEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email, emailVerified: true }).project({ type: 0 }).toArray(func); };
obj.Remove = function (id) { obj.file.deleteOne({ _id: id }); }; obj.Remove = function (id) { obj.file.deleteOne({ _id: id }); };
obj.RemoveAll = function (func) { obj.file.deleteMany({}, { multi: true }, func); }; obj.RemoveAll = function (func) { obj.file.deleteMany({}, { multi: true }, func); };
obj.RemoveAllOfType = function (type, func) { obj.file.deleteMany({ type: type }, { multi: true }, func); }; obj.RemoveAllOfType = function (type, func) { obj.file.deleteMany({ type: type }, { multi: true }, func); };
@ -557,18 +557,18 @@ module.exports.CreateDB = function (parent, func) {
// Database actions on the events collection // Database actions on the events collection
obj.GetAllEvents = function (func) { obj.eventsfile.find({}).toArray(func); }; obj.GetAllEvents = function (func) { obj.eventsfile.find({}).toArray(func); };
obj.StoreEvent = function (event) { obj.eventsfile.insertOne(event); }; obj.StoreEvent = function (event) { obj.eventsfile.insertOne(event); };
obj.GetEvents = function (ids, domain, func) { obj.eventsfile.find({ domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).toArray(func); }; obj.GetEvents = function (ids, domain, func) { obj.eventsfile.find({ domain: domain, ids: { $in: ids } }).project({ type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).toArray(func); };
obj.GetEventsWithLimit = function (ids, domain, limit, func) { obj.eventsfile.find({ domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).toArray(func); }; obj.GetEventsWithLimit = function (ids, domain, limit, func) { obj.eventsfile.find({ domain: domain, ids: { $in: ids } }).project({ type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).toArray(func); };
obj.GetUserEvents = function (ids, domain, username, func) { obj.eventsfile.find({ domain: domain, $or: [{ ids: { $in: ids } }, { username: username }] }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).toArray(func); }; obj.GetUserEvents = function (ids, domain, username, func) { obj.eventsfile.find({ domain: domain, $or: [{ ids: { $in: ids } }, { username: username }] }).project({ type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).toArray(func); };
obj.GetUserEventsWithLimit = function (ids, domain, username, limit, func) { obj.eventsfile.find({ domain: domain, $or: [{ ids: { $in: ids } }, { username: username }] }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).toArray(func); }; obj.GetUserEventsWithLimit = function (ids, domain, username, limit, func) { obj.eventsfile.find({ domain: domain, $or: [{ ids: { $in: ids } }, { username: username }] }).project({ type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).toArray(func); };
obj.GetNodeEventsWithLimit = function (nodeid, domain, limit, func) { obj.eventsfile.find({ domain: domain, nodeid: nodeid }, { type: 0, etype: 0, _id: 0, domain: 0, ids: 0, node: 0, nodeid: 0 }).sort({ time: -1 }).limit(limit).toArray(func); }; obj.GetNodeEventsWithLimit = function (nodeid, domain, limit, func) { obj.eventsfile.find({ domain: domain, nodeid: nodeid }).project({ type: 0, etype: 0, _id: 0, domain: 0, ids: 0, node: 0, nodeid: 0 }).sort({ time: -1 }).limit(limit).toArray(func); };
obj.RemoveAllEvents = function (domain) { obj.eventsfile.deleteMany({ domain: domain }, { multi: true }); }; obj.RemoveAllEvents = function (domain) { obj.eventsfile.deleteMany({ domain: domain }, { multi: true }); };
obj.RemoveAllNodeEvents = function (domain, nodeid) { obj.eventsfile.deleteMany({ domain: domain, nodeid: nodeid }, { multi: true }); }; obj.RemoveAllNodeEvents = function (domain, nodeid) { obj.eventsfile.deleteMany({ domain: domain, nodeid: nodeid }, { multi: true }); };
// Database actions on the power collection // Database actions on the power collection
obj.getAllPower = function (func) { obj.powerfile.find({}).toArray(func); }; obj.getAllPower = function (func) { obj.powerfile.find({}).toArray(func); };
obj.storePowerEvent = function (event, multiServer, func) { if (multiServer != null) { event.server = multiServer.serverid; } obj.powerfile.insertOne(event, func); }; obj.storePowerEvent = function (event, multiServer, func) { if (multiServer != null) { event.server = multiServer.serverid; } obj.powerfile.insertOne(event, func); };
obj.getPowerTimeline = function (nodeid, func) { obj.powerfile.find({ nodeid: { $in: ['*', nodeid] } }, { _id: 0, nodeid: 0, s: 0 }).sort({ time: 1 }).toArray(func); }; obj.getPowerTimeline = function (nodeid, func) { obj.powerfile.find({ nodeid: { $in: ['*', nodeid] } }).project({ _id: 0, nodeid: 0, s: 0 }).sort({ time: 1 }).toArray(func); };
obj.removeAllPowerEvents = function () { obj.powerfile.deleteMany({}, { multi: true }); }; obj.removeAllPowerEvents = function () { obj.powerfile.deleteMany({}, { multi: true }); };
obj.removeAllPowerEventsForNode = function (nodeid) { obj.powerfile.deleteMany({ nodeid: nodeid }, { multi: true }); }; obj.removeAllPowerEventsForNode = function (nodeid) { obj.powerfile.deleteMany({ nodeid: nodeid }, { multi: true }); };

View File

@ -1438,10 +1438,10 @@ function CreateMeshCentralServer(config, args) {
// List of possible mesh agents // List of possible mesh agents
obj.meshAgentsArchitectureNumbers = { obj.meshAgentsArchitectureNumbers = {
0: { id: 0, localname: 'Unknown', rname: 'meshconsole.exe', desc: 'Unknown agent', update: false, amt: true, platform: 'unknown', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, 0: { id: 0, localname: 'Unknown', rname: 'meshconsole.exe', desc: 'Unknown agent', update: false, amt: true, platform: 'unknown', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' },
1: { id: 1, localname: 'MeshConsole.exe', rname: 'meshconsole.exe', desc: 'Windows x86-32 console', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' }, 1: { id: 1, localname: 'MeshConsole.exe', rname: 'meshconsole32.exe', desc: 'Windows x86-32 console', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' },
2: { id: 2, localname: 'MeshConsole64.exe', rname: 'meshconsole.exe', desc: 'Windows x86-64 console', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' }, 2: { id: 2, localname: 'MeshConsole64.exe', rname: 'meshconsole64.exe', desc: 'Windows x86-64 console', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' },
3: { id: 3, localname: 'MeshService-signed.exe', rname: 'meshagent.exe', desc: 'Windows x86-32 service', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' }, 3: { id: 3, localname: 'MeshService-signed.exe', rname: 'meshagent32.exe', desc: 'Windows x86-32 service', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' },
4: { id: 4, localname: 'MeshService64-signed.exe', rname: 'meshagent.exe', desc: 'Windows x86-64 service', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' }, 4: { id: 4, localname: 'MeshService64-signed.exe', rname: 'meshagent64.exe', desc: 'Windows x86-64 service', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'windows-recovery', arcore: 'windows-agentrecovery' },
5: { id: 5, localname: 'meshagent_x86', rname: 'meshagent', desc: 'Linux x86-32', update: true, amt: true, platform: 'linux', core: 'linux-amt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, 5: { id: 5, localname: 'meshagent_x86', rname: 'meshagent', desc: 'Linux x86-32', update: true, amt: true, platform: 'linux', core: 'linux-amt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' },
6: { id: 6, localname: 'meshagent_x86-64', rname: 'meshagent', desc: 'Linux x86-64', update: true, amt: true, platform: 'linux', core: 'linux-amt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, 6: { id: 6, localname: 'meshagent_x86-64', rname: 'meshagent', desc: 'Linux x86-64', update: true, amt: true, platform: 'linux', core: 'linux-amt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' },
7: { id: 7, localname: 'meshagent_mips', rname: 'meshagent', desc: 'Linux MIPS', update: true, amt: false, platform: 'linux', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, 7: { id: 7, localname: 'meshagent_mips', rname: 'meshagent', desc: 'Linux MIPS', update: true, amt: false, platform: 'linux', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' },

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.3.8-x", "version": "0.3.8-y",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -2056,15 +2056,34 @@ a {
margin: auto; margin: auto;
} }
#deskToolsBar { .deskToolsTopTab {
position:absolute; position:absolute;
background-color:lightgray;
padding:2px;
top:2px;
left:0px;
width:80px;
bottom:2px;
border-top-left-radius:4px;
border-top-right-radius:4px;
cursor:pointer;
}
#deskToolsAreaTop {
position: absolute;
/*
padding: 3px; padding: 3px;
border-radius: 3px 3px 0px 0px; border-radius: 3px 3px 0px 0px;
top: 5px; top: 5px;
left: 4px; left: 4px;
bottom: 26px; bottom: 26px;
background-color: lightgray;
cursor: pointer; cursor: pointer;
*/
top: 0px;
left: 4px;
right: 4px;
height: 26px;
background-color: gray;
} }
#deskToolsArea { #deskToolsArea {
@ -2088,6 +2107,17 @@ a {
float: left; float: left;
} }
#deskToolsServiceHeader {
border-bottom: 1px solid darkgray;
padding: 3px;
}
#deskToolsServiceHeader .colmn1 {
width: 50px;
padding-right: 5px;
float: left;
}
#DeskToolsProcesses { #DeskToolsProcesses {
overflow-y: scroll; overflow-y: scroll;
position: absolute; position: absolute;
@ -2097,6 +2127,15 @@ a {
color:black; color:black;
} }
#DeskToolsServices {
overflow-y: scroll;
position: absolute;
top: 24px;
bottom: 0px;
width: 100%;
color:black;
}
.deskToolsBar { .deskToolsBar {
padding: 3px; padding: 3px;
} }

File diff suppressed because one or more lines are too long

View File

@ -467,14 +467,27 @@
<canvas id=Desk width=640 height=480 oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event) onmousewheel=dmousewheel(event)></canvas> <canvas id=Desk width=640 height=480 oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event) onmousewheel=dmousewheel(event)></canvas>
</div> </div>
<div id=DeskTools> <div id=DeskTools>
<a id=DeskToolsRefreshButton style="" onclick="refreshDeskTools()">Refresh</a> <div id=deskToolsAreaTop>
<div id=DeskToolsBar>Processes</div> <a id=DeskToolsRefreshButton style="right:2px" onclick="refreshDeskTools()">Refresh</a>
<div id=deskToolsTopTabProcess class="deskToolsTopTab" onclick="changeDeskToolTab(0)" style="left:0px;bottom:0px">Processes</div>
<div id=deskToolsTopTabService class="deskToolsTopTab" onclick="changeDeskToolTab(1)" style="display:none;left:90px;color:gray">Services</div>
</div>
<div id=deskToolsArea> <div id=deskToolsArea>
<div id="DeskToolsProcessTab">
<div id=deskToolsHeader> <div id=deskToolsHeader>
<a class="colmn1" title="Sort by process id" onclick=sortProcess(0)>PID</a> <a class="colmn1" title="Sort by process id" onclick=sortProcess(0)>PID</a>
<a class="colmn2" title="Sort by name" onclick=sortProcess(1)>Name</a></div> <a class="colmn2" title="Sort by name" onclick=sortProcess(1)>Name</a>
</div>
<div id="DeskToolsProcesses" style=""></div> <div id="DeskToolsProcesses" style=""></div>
</div> </div>
<div id="DeskToolsServiceTab" style="display:none">
<div id=deskToolsServiceHeader>
<a class="colmn1" style="width:70px" title="Sort by state" onclick=sortService(0)>State</a>
<a class="colmn2" title="Sort by name" onclick=sortService(1)>Name</a>
</div>
<div id="DeskToolsServices" style=""></div>
</div>
</div>
</div> </div>
<div id=p11DeskConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p11clearConsoleMsg()></div> <div id=p11DeskConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p11clearConsoleMsg()></div>
</div> </div>
@ -1452,6 +1465,8 @@
addNotification(n); addNotification(n);
} else if (message.type == 'ps') { } else if (message.type == 'ps') {
showDeskToolsProcesses(message); showDeskToolsProcesses(message);
} else if (message.type == 'services') {
showDeskToolsServices(message);
} else if ((message.type == 'getclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) { } else if ((message.type == 'getclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) {
Q('d2clipText').value = message.data; Q('d2clipText').value = message.data;
} else if ((message.type == 'setclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) { } else if ((message.type == 'setclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) {
@ -5112,22 +5127,41 @@
if (QS('DeskTools').display == 'none') { if (QS('DeskTools').display == 'none') {
QV('DeskTools', true); QV('DeskTools', true);
Q('DeskTools').nodeid = currentNode._id; Q('DeskTools').nodeid = currentNode._id;
refreshDeskTools(); QH('DeskToolsProcesses', '');
QH('DeskToolsServices', '');
QV('deskToolsTopTabService', false);
changeDeskToolTab(0)
refreshDeskTools(0);
refreshDeskTools(1);
} else { } else {
QV('DeskTools', false); QV('DeskTools', false);
} }
} }
var deskToolTabSelection = 0;
function changeDeskToolTab(tabnum) {
deskToolTabSelection = tabnum;
QV('DeskToolsProcessTab', tabnum == 0);
QV('DeskToolsServiceTab', tabnum == 1);
QS('deskToolsTopTabProcess')['bottom'] = (tabnum == 0) ? '0px' : '3px';
QS('deskToolsTopTabService')['bottom'] = (tabnum == 1) ? '0px' : '3px';
QS('deskToolsTopTabProcess')['color'] = (tabnum == 0) ? 'black' : 'gray';
QS('deskToolsTopTabService')['color'] = (tabnum == 1) ? 'black' : 'gray';
}
// Refresh all of the desktop tool panels // Refresh all of the desktop tool panels
function refreshDeskTools() { function refreshDeskTools(x) {
var sel = (x == null) ? deskToolTabSelection : x;
QV('DeskToolsRefreshButton', false); QV('DeskToolsRefreshButton', false);
setTimeout(refreshDeskToolsEx, 500); setTimeout(refreshDeskToolsEx, 500);
meshserver.send({ action: 'msg', type:'ps', nodeid: currentNode._id }); if (sel == 0) meshserver.send({ action: 'msg', type: 'ps', nodeid: currentNode._id });
if (sel == 1) meshserver.send({ action: 'msg', type: 'services', nodeid: currentNode._id });
} }
function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); } function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); }
var deskTools = { sort: 1, msg: null }; var deskTools = { sort: 1, ssort: 1, msg: null, smsg: null };
function sortProcess(sort) { deskTools.sort = sort; showDeskToolsProcesses(deskTools.msg); } function sortProcess(sort) { deskTools.sort = sort; showDeskToolsProcesses(deskTools.msg); }
function sortProcessPid(a, b) { if (a.p > b.p) return 1; if (a.p < b.p) return (-1); return 0; } function sortService(sort) { deskTools.ssort = sort; showDeskToolsServices(deskTools.smsg); }
function sortProcessPid(a, b) { if (a.p > b.p) return 1; if (a.p < b.p) return (-1); return sortProcessName(a, b); }
function sortProcessName(a, b) { if (a.d > b.d) return 1; if (a.d < b.d) return (-1); return 0; } function sortProcessName(a, b) { if (a.d > b.d) return 1; if (a.d < b.d) return (-1); return 0; }
function showDeskToolsProcesses(message) { function showDeskToolsProcesses(message) {
deskTools.msg = message; deskTools.msg = message;
@ -5149,6 +5183,68 @@
QH('DeskToolsProcesses', x); QH('DeskToolsProcesses', x);
} }
} }
function showDeskToolsServices(message) {
deskTools.smsg = message;
if (message == null) { QH('DeskToolsProcesses', ''); return; }
if (Q('DeskTools').nodeid != message.nodeid) return;
QV('deskToolsTopTabService', true);
var s = [], services = null;
try { services = JSON.parse(message.value); } catch (e) { }
deskTools.services = services;
if (services != null) {
for (var i in services) {
if (services[i].status) {
s.push({ p: capitalizeFirstLetter(services[i].status.state.toLowerCase()), d: services[i].displayName, i: i });
}
}
if (deskTools.ssort == 0) { s.sort(sortProcessPid); } else if (deskTools.ssort == 1) { s.sort(sortProcessName); }
var x = '';
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>';
}
}
QH('DeskToolsServices', x);
}
}
function showServiceDetailsDialog(index) {
if (xxdialogMode) return;
var service = deskTools.services[index];
if (service != null) {
var x = '';
if (service.name) { x += addHtmlValue('Name', service.name); }
if (service.displayName) { x += addHtmlValue('Display name', service.displayName); }
if (service.status) {
if (service.status.state) { x += addHtmlValue('State', capitalizeFirstLetter(service.status.state.toLowerCase())); }
if (service.status.pid) { x += addHtmlValue('PID', service.status.pid); }
var serviceTypes = [];
if (service.status.isFileSystemDriver === true) { serviceTypes.push('FileSystemDriver'); }
if (service.status.isInteractive === true) { serviceTypes.push('Interactive'); }
if (service.status.isKernelDriver === true) { serviceTypes.push('KernelDriver'); }
if (service.status.isOwnProcess === true) { serviceTypes.push('OwnProcess'); }
if (service.status.isSharedProcess === true) { serviceTypes.push('SharedProcess'); }
if (serviceTypes.length > 0) { x += addHtmlValue('Type', serviceTypes.join(', ')); }
}
x += '<br/><div style=float:right;margin-bottom:12px><input type=button value="Close" onclick=showServiceDetailsDialogEx(0,' + index + ')></div><div style=margin-bottom:12px><input type=button value="Start" onclick=showServiceDetailsDialogEx(1,' + index + ')><input type=button value="Stop" onclick=showServiceDetailsDialogEx(2,' + index + ')></div>';
// <input type=button value="Restart" onclick=showServiceDetailsDialogEx(3,' + index + ')>
setDialogMode(2, "Service Details", 8, null, x, name);
}
}
function showServiceDetailsDialogEx(action, index) {
setDialogMode(0);
if (action == 0) return;
var service = deskTools.services[index];
if (service != null) {
if (action == 1) { meshserver.send({ action: 'msg', type: 'serviceStart', nodeid: currentNode._id, serviceName: service.name }); }
if (action == 2) { meshserver.send({ action: 'msg', type: 'serviceStop', nodeid: currentNode._id, serviceName: service.name }); }
//if (action == 3) { meshserver.send({ action: 'msg', type: 'serviceRestart', nodeid: currentNode._id, serviceName: service.name }); }
setTimeout(function () { refreshDeskTools(1) }, 1000);
}
}
// Toggle mouse and keyboard input // Toggle mouse and keyboard input
function toggleKvmControl() { putstore('DeskControl', (Q("DeskControl").checked?1:0)); } function toggleKvmControl() { putstore('DeskControl', (Q("DeskControl").checked?1:0)); }
@ -7609,9 +7705,9 @@
userid = decodeURIComponent(userid); userid = decodeURIComponent(userid);
var user = users[userid.toLowerCase()], groups = ""; var user = users[userid.toLowerCase()], groups = "";
if (user.groups != null) { groups = user.groups.join(', ') } if (user.groups != null) { groups = user.groups.join(', ') }
var x = 'Enter a comma seperate list of groups.<br /><br />'; var x = 'Enter a comma seperate list of administrative realms names.<br /><br />';
x += addHtmlValue('Groups', '<input id=dp4usergroups style=width:230px value="' + groups + '" placeholder="Group1, Group2, Group3" maxlength=256 onchange=p4validateUserGroups() onkeyup=p4validateUserGroups() />'); x += addHtmlValue('Realms', '<input id=dp4usergroups style=width:230px value="' + groups + '" placeholder="Name1, Name2, Name3" maxlength=256 onchange=p4validateUserGroups() onkeyup=p4validateUserGroups() />');
setDialogMode(2, "User Groups", 3, showUserGroupDialogEx, x, user); setDialogMode(2, "Administrative Realms", 3, showUserGroupDialogEx, x, user);
focusTextBox('dp4usergroups'); focusTextBox('dp4usergroups');
p4validateUserGroups(); p4validateUserGroups();
return false; return false;
@ -7757,10 +7853,12 @@
} }
x += addDeviceAttribute('Device Groups', linkCountStr); x += addDeviceAttribute('Device Groups', linkCountStr);
// User Groups // Administrative Realms
if ((userinfo.siteadmin == 0xFFFFFFFF) || (userinfo.siteadmin & 2)) {
var userGroups = '<i>None</i>'; var userGroups = '<i>None</i>';
if (user.groups) { userGroups = ''; for (var i in user.groups) { userGroups += '<span class="tagSpan">' + user.groups[i] + '</span>'; } } if (user.groups) { userGroups = ''; for (var i in user.groups) { userGroups += '<span class="tagSpan">' + user.groups[i] + '</span>'; } }
x += addDeviceAttribute('User Groups', addLinkConditional(userGroups, 'showUserGroupDialog(event,\"' + userid + '\")', (userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.groups == null) && (userinfo.siteadmin & 2) && (userinfo._id != user._id) && (user._id != 0xFFFFFFFF)))); x += addDeviceAttribute('Admin Realms', addLinkConditional(userGroups, 'showUserGroupDialog(event,\"' + userid + '\")', (userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.groups == null) && (userinfo._id != user._id) && (user.siteadmin != 0xFFFFFFFF))));
}
var multiFactor = 0; var multiFactor = 0;
if ((user.otpsecret > 0) || (user.otphkeys > 0)) { if ((user.otpsecret > 0) || (user.otphkeys > 0)) {
@ -8579,6 +8677,7 @@
function u2fSupported() { return (window.u2f && ((navigator.userAgent.indexOf('Chrome/') > 0) || (navigator.userAgent.indexOf('Firefox/') > 0) || (navigator.userAgent.indexOf('Opera/') > 0) || (navigator.userAgent.indexOf('Safari/') > 0))); } function u2fSupported() { return (window.u2f && ((navigator.userAgent.indexOf('Chrome/') > 0) || (navigator.userAgent.indexOf('Firefox/') > 0) || (navigator.userAgent.indexOf('Opera/') > 0) || (navigator.userAgent.indexOf('Safari/') > 0))); }
function findOne(arr1, arr2) { if ((arr1 == null) || (arr2 == null)) return false; return arr2.some(function (v) { return arr1.indexOf(v) >= 0; }); }; function findOne(arr1, arr2) { if ((arr1 == null) || (arr2 == null)) return false; return arr2.some(function (v) { return arr1.indexOf(v) >= 0; }); };
function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); } function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); }
function capitalizeFirstLetter(x) { return x.charAt(0).toUpperCase() + x.slice(1); }
function printDate(d) { return d.toLocaleDateString(args.locale); } function printDate(d) { return d.toLocaleDateString(args.locale); }
function printTime(d) { return d.toLocaleTimeString(args.locale); } function printTime(d) { return d.toLocaleTimeString(args.locale); }
function printDateTime(d) { return d.toLocaleString(args.locale); } function printDateTime(d) { return d.toLocaleString(args.locale); }

File diff suppressed because one or more lines are too long