diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index 480af74f..32c2eb02 100644 Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index ebb4dea6..9949a757 100644 Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ diff --git a/agents/MeshService-signed.exe b/agents/MeshService-signed.exe index 2a1bdb4a..2477cda3 100644 Binary files a/agents/MeshService-signed.exe and b/agents/MeshService-signed.exe differ diff --git a/agents/MeshService.exe b/agents/MeshService.exe index 9a6fa53f..d5833e5e 100644 Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ diff --git a/agents/MeshService64-signed.exe b/agents/MeshService64-signed.exe index e6af1837..2158f8e5 100644 Binary files a/agents/MeshService64-signed.exe and b/agents/MeshService64-signed.exe differ diff --git a/agents/MeshService64.exe b/agents/MeshService64.exe index 8d841301..400584ef 100644 Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ diff --git a/agents/meshcore.js b/agents/meshcore.js index 68bb7435..791f7d34 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -672,7 +672,9 @@ function createMeshCore(agent) case 'ps': { // Return the list of running processes 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; } @@ -684,6 +686,39 @@ function createMeshCore(agent) } 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': { // Open a local web browser and return success/fail MeshServerLog('Opening: ' + data.url, data); @@ -2037,6 +2072,11 @@ function createMeshCore(agent) response = JSON.stringify(addedModules); break; } + case 'listservices': { + var services = require('service-manager').manager.enumerateService(); + response = JSON.stringify(services, null, 1); + break; + } case 'getscript': { if (args['_'].length != 1) { response = 'Proper usage: getscript [scriptNumber].'; diff --git a/agents/meshcore.min.js b/agents/meshcore.min.js index 68bb7435..791f7d34 100644 --- a/agents/meshcore.min.js +++ b/agents/meshcore.min.js @@ -672,7 +672,9 @@ function createMeshCore(agent) case 'ps': { // Return the list of running processes 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; } @@ -684,6 +686,39 @@ function createMeshCore(agent) } 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': { // Open a local web browser and return success/fail MeshServerLog('Opening: ' + data.url, data); @@ -2037,6 +2072,11 @@ function createMeshCore(agent) response = JSON.stringify(addedModules); break; } + case 'listservices': { + var services = require('service-manager').manager.enumerateService(); + response = JSON.stringify(services, null, 1); + break; + } case 'getscript': { if (args['_'].length != 1) { response = 'Proper usage: getscript [scriptNumber].'; diff --git a/db.js b/db.js index bea2ddd1..dfdb0b2a 100644 --- a/db.js +++ b/db.js @@ -531,12 +531,12 @@ module.exports.CreateDB = function (parent, 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.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.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }, { 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.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 }).project({ type: 0 }).toArray(func); }; obj.Remove = function (id) { obj.file.deleteOne({ _id: id }); }; obj.RemoveAll = function (func) { obj.file.deleteMany({}, { 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 obj.GetAllEvents = function (func) { obj.eventsfile.find({}).toArray(func); }; 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.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.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.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.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.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 } }).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 }] }).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 }] }).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 }).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.RemoveAllNodeEvents = function (domain, nodeid) { obj.eventsfile.deleteMany({ domain: domain, nodeid: nodeid }, { multi: true }); }; // Database actions on the power collection 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.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.removeAllPowerEventsForNode = function (nodeid) { obj.powerfile.deleteMany({ nodeid: nodeid }, { multi: true }); }; diff --git a/meshcentral.js b/meshcentral.js index f83da4df..e9801b43 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1438,10 +1438,10 @@ function CreateMeshCentralServer(config, args) { // List of possible mesh agents 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' }, - 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' }, - 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' }, - 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' }, - 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' }, + 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: '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: '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: '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' }, 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' }, diff --git a/package.json b/package.json index 11615a11..b90ea903 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.3.8-x", + "version": "0.3.8-y", "keywords": [ "Remote Management", "Intel AMT", diff --git a/public/styles/style.css b/public/styles/style.css index e3dd8ec5..1a26113a 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -2056,15 +2056,34 @@ a { margin: auto; } -#deskToolsBar { +.deskToolsTopTab { + 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; border-radius: 3px 3px 0px 0px; top: 5px; left: 4px; bottom: 26px; - background-color: lightgray; cursor: pointer; + */ + top: 0px; + left: 4px; + right: 4px; + height: 26px; + background-color: gray; } #deskToolsArea { @@ -2088,6 +2107,17 @@ a { float: left; } +#deskToolsServiceHeader { + border-bottom: 1px solid darkgray; + padding: 3px; +} + + #deskToolsServiceHeader .colmn1 { + width: 50px; + padding-right: 5px; + float: left; + } + #DeskToolsProcesses { overflow-y: scroll; position: absolute; @@ -2097,6 +2127,15 @@ a { color:black; } +#DeskToolsServices { + overflow-y: scroll; + position: absolute; + top: 24px; + bottom: 0px; + width: 100%; + color:black; +} + .deskToolsBar { padding: 3px; } diff --git a/views/default-min.handlebars b/views/default-min.handlebars index cbe90332..90785de7 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -1 +1 @@ -
{{{logoutControl}}}
My Devices | My Account | My Events | My Files | My Users | My Server |
{{{logoutControl}}}
My Devices | My Account | My Events | My Files | My Users | My Server |