mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-22 12:52:50 +03:00
Database performance fix + Server side clipboard support.
This commit is contained in:
parent
46dd1c666b
commit
27f6629b33
@ -466,6 +466,21 @@ function createMeshCore(agent) {
|
||||
if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
|
||||
break;
|
||||
}
|
||||
case 'getclip': {
|
||||
// Send the load clipboard back to the user
|
||||
sendConsoleText('getClip: ' + JSON.stringify(data));
|
||||
require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
|
||||
break;
|
||||
}
|
||||
case 'setclip': {
|
||||
// Set the load clipboard to a user value
|
||||
sendConsoleText('setClip: ' + JSON.stringify(data));
|
||||
if (typeof data.data == 'string') {
|
||||
require("clipboard")(data.data); // Set the clipboard
|
||||
mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Unknown action, ignore it.
|
||||
break;
|
||||
@ -1108,7 +1123,7 @@ function createMeshCore(agent) {
|
||||
var response = null;
|
||||
switch (cmd) {
|
||||
case 'help': { // Displays available commands
|
||||
response = 'Available commands: help, info, osinfo,args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtdeactivate,\r\namtpolicy, getscript.';
|
||||
response = 'Available commands: help, info, osinfo,args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl, amtreset, amtccm, amtdeactivate,\r\namtpolicy, getscript, getclip, setclip.';
|
||||
break;
|
||||
}
|
||||
/*
|
||||
@ -1130,6 +1145,14 @@ function createMeshCore(agent) {
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case 'getclip': {
|
||||
require("clipboard").read().then(function (str) { sendConsoleText(str, sessionid); });
|
||||
break;
|
||||
}
|
||||
case 'setclip': {
|
||||
if (args['_'].length != 1) { response = 'Proper usage: setclip (text)'; } else { require("clipboard")(args['_'][0]); response = 'Setting clipboard to: ' + args['_'][0]; }
|
||||
break;
|
||||
}
|
||||
case 'amtreset': {
|
||||
resetMei();
|
||||
resetMicroLms();
|
||||
|
2
agents/meshcore.min.js
vendored
2
agents/meshcore.min.js
vendored
File diff suppressed because one or more lines are too long
178
agents/modules_meshcore/clipboard.js
Normal file
178
agents/modules_meshcore/clipboard.js
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
Copyright 2019 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
var promise = require('promise');
|
||||
|
||||
function nativeAddModule(name)
|
||||
{
|
||||
var value = getJSModule(name);
|
||||
var ret = "duk_peval_string_noresult(ctx, \"addModule('" + name + "', Buffer.from('" + Buffer.from(value).toString('base64') + "', 'base64').toString());\");";
|
||||
module.exports(ret);
|
||||
}
|
||||
|
||||
function lin_readtext()
|
||||
{
|
||||
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
||||
try
|
||||
{
|
||||
require('monitor-info')
|
||||
}
|
||||
catch(exc)
|
||||
{
|
||||
ret._rej(exc);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
var X11 = require('monitor-info')._X11;
|
||||
if (!X11)
|
||||
{
|
||||
ret._rej('X11 required for Clipboard Manipulation');
|
||||
}
|
||||
else
|
||||
{
|
||||
var SelectionNotify = 31;
|
||||
var AnyPropertyType = 0;
|
||||
var GM = require('monitor-info')._gm;
|
||||
|
||||
ret._getInfoPromise = require('monitor-info').getInfo();
|
||||
ret._getInfoPromise._masterPromise = ret;
|
||||
ret._getInfoPromise.then(function (mon)
|
||||
{
|
||||
if (mon.length > 0)
|
||||
{
|
||||
var white = X11.XWhitePixel(mon[0].display, mon[0].screenId).Val;
|
||||
|
||||
this._masterPromise.CLIPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('CLIPBOARD'), 0);
|
||||
this._masterPromise.FMTID = X11.XInternAtom(mon[0].display, GM.CreateVariable('UTF8_STRING'), 0);
|
||||
this._masterPromise.PROPID = X11.XInternAtom(mon[0].display, GM.CreateVariable('XSEL_DATA'), 0);
|
||||
this._masterPromise.INCRID = X11.XInternAtom(mon[0].display, GM.CreateVariable('INCR'), 0);
|
||||
this._masterPromise.ROOTWIN = X11.XRootWindow(mon[0].display, mon[0].screenId);
|
||||
this._masterPromise.FAKEWIN = X11.XCreateSimpleWindow(mon[0].display, this._masterPromise.ROOTWIN, 0, 0, mon[0].right, 5, 0, white, white);
|
||||
|
||||
X11.XSync(mon[0].display, 0);
|
||||
X11.XConvertSelection(mon[0].display, this._masterPromise.CLIPID, this._masterPromise.FMTID, this._masterPromise.PROPID, this._masterPromise.FAKEWIN, 0);
|
||||
X11.XSync(mon[0].display, 0);
|
||||
|
||||
this._masterPromise.DescriptorEvent = require('DescriptorEvents').addDescriptor(X11.XConnectionNumber(mon[0].display).Val, { readset: true });
|
||||
this._masterPromise.DescriptorEvent._masterPromise = this._masterPromise;
|
||||
this._masterPromise.DescriptorEvent._display = mon[0].display;
|
||||
this._masterPromise.DescriptorEvent.on('readset', function (fd)
|
||||
{
|
||||
var XE = GM.CreateVariable(1024);
|
||||
while (X11.XPending(this._display).Val)
|
||||
{
|
||||
X11.XNextEventSync(this._display, XE);
|
||||
if(XE.Deref(0, 4).toBuffer().readUInt32LE() == SelectionNotify)
|
||||
{
|
||||
var id = GM.CreatePointer();
|
||||
var bits = GM.CreatePointer();
|
||||
var sz = GM.CreatePointer();
|
||||
var tail = GM.CreatePointer();
|
||||
var result = GM.CreatePointer();
|
||||
|
||||
X11.XGetWindowProperty(this._display, this._masterPromise.FAKEWIN, this._masterPromise.PROPID, 0, 65535, 0, AnyPropertyType, id, bits, sz, tail, result);
|
||||
this._masterPromise._res(result.Deref().String);
|
||||
X11.XFree(result.Deref());
|
||||
X11.XDestroyWindow(this._display, this._masterPromise.FAKEWIN);
|
||||
|
||||
this.removeDescriptor(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
function lin_copytext()
|
||||
{
|
||||
}
|
||||
|
||||
function win_readtext()
|
||||
{
|
||||
var ret = '';
|
||||
var CF_TEXT = 1;
|
||||
var GM = require('_GenericMarshal');
|
||||
var user32 = GM.CreateNativeProxy('user32.dll');
|
||||
var kernel32 = GM.CreateNativeProxy('kernel32.dll');
|
||||
kernel32.CreateMethod('GlobalAlloc');
|
||||
kernel32.CreateMethod('GlobalLock');
|
||||
kernel32.CreateMethod('GlobalUnlock');
|
||||
user32.CreateMethod('OpenClipboard');
|
||||
user32.CreateMethod('CloseClipboard');
|
||||
user32.CreateMethod('GetClipboardData');
|
||||
|
||||
user32.OpenClipboard(0);
|
||||
var h = user32.GetClipboardData(CF_TEXT);
|
||||
if(h.Val!=0)
|
||||
{
|
||||
var hbuffer = kernel32.GlobalLock(h);
|
||||
ret = hbuffer.String;
|
||||
kernel32.GlobalUnlock(h);
|
||||
}
|
||||
user32.CloseClipboard();
|
||||
|
||||
var p = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
||||
p._res(ret);
|
||||
return (p);
|
||||
}
|
||||
|
||||
function win_copytext(txt)
|
||||
{
|
||||
var GMEM_MOVEABLE = 0x0002;
|
||||
var CF_TEXT = 1;
|
||||
|
||||
var GM = require('_GenericMarshal');
|
||||
var user32 = GM.CreateNativeProxy('user32.dll');
|
||||
var kernel32 = GM.CreateNativeProxy('kernel32.dll');
|
||||
kernel32.CreateMethod('GlobalAlloc');
|
||||
kernel32.CreateMethod('GlobalLock');
|
||||
kernel32.CreateMethod('GlobalUnlock');
|
||||
user32.CreateMethod('OpenClipboard');
|
||||
user32.CreateMethod('EmptyClipboard');
|
||||
user32.CreateMethod('CloseClipboard');
|
||||
user32.CreateMethod('SetClipboardData');
|
||||
|
||||
var h = kernel32.GlobalAlloc(GMEM_MOVEABLE, txt.length + 2);
|
||||
h.autoFree(false);
|
||||
var hbuffer = kernel32.GlobalLock(h);
|
||||
hbuffer.autoFree(false);
|
||||
var tmp = Buffer.alloc(txt.length + 1);
|
||||
Buffer.from(txt).copy(tmp);
|
||||
tmp.copy(hbuffer.Deref(0, txt.length + 1).toBuffer());
|
||||
kernel32.GlobalUnlock(h);
|
||||
|
||||
user32.OpenClipboard(0);
|
||||
user32.EmptyClipboard();
|
||||
user32.SetClipboardData(CF_TEXT, h);
|
||||
user32.CloseClipboard();
|
||||
}
|
||||
|
||||
switch(process.platform)
|
||||
{
|
||||
case 'win32':
|
||||
module.exports = win_copytext;
|
||||
module.exports.read = win_readtext;
|
||||
break;
|
||||
case 'linux':
|
||||
module.exports = lin_copytext;
|
||||
module.exports.read = lin_readtext;
|
||||
break;
|
||||
case 'darwin':
|
||||
break;
|
||||
}
|
||||
module.exports.nativeAddModule = nativeAddModule;
|
1
agents/modules_meshcore_min/clipboard.min.js
vendored
Normal file
1
agents/modules_meshcore_min/clipboard.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
var promise=require("promise");function nativeAddModule(a){var c=getJSModule(a);var b="duk_peval_string_noresult(ctx, \"addModule('"+a+"', Buffer.from('"+Buffer.from(c).toString("base64")+"', 'base64').toString());\");";module.exports(b)}function lin_readtext(){var d=new promise(function(h,g){this._res=h;this._rej=g});try{require("monitor-info")}catch(b){d._rej(b);return(d)}var f=require("monitor-info")._X11;if(!f){d._rej("X11 required for Clipboard Manipulation")}else{var e=31;var a=0;var c=require("monitor-info")._gm;d._getInfoPromise=require("monitor-info").getInfo();d._getInfoPromise._masterPromise=d;d._getInfoPromise.then(function(g){if(g.length>0){var h=f.XWhitePixel(g[0].display,g[0].screenId).Val;this._masterPromise.CLIPID=f.XInternAtom(g[0].display,c.CreateVariable("CLIPBOARD"),0);this._masterPromise.FMTID=f.XInternAtom(g[0].display,c.CreateVariable("UTF8_STRING"),0);this._masterPromise.PROPID=f.XInternAtom(g[0].display,c.CreateVariable("XSEL_DATA"),0);this._masterPromise.INCRID=f.XInternAtom(g[0].display,c.CreateVariable("INCR"),0);this._masterPromise.ROOTWIN=f.XRootWindow(g[0].display,g[0].screenId);this._masterPromise.FAKEWIN=f.XCreateSimpleWindow(g[0].display,this._masterPromise.ROOTWIN,0,0,g[0].right,5,0,h,h);f.XSync(g[0].display,0);f.XConvertSelection(g[0].display,this._masterPromise.CLIPID,this._masterPromise.FMTID,this._masterPromise.PROPID,this._masterPromise.FAKEWIN,0);f.XSync(g[0].display,0);this._masterPromise.DescriptorEvent=require("DescriptorEvents").addDescriptor(f.XConnectionNumber(g[0].display).Val,{readset:true});this._masterPromise.DescriptorEvent._masterPromise=this._masterPromise;this._masterPromise.DescriptorEvent._display=g[0].display;this._masterPromise.DescriptorEvent.on("readset",function(j){var o=c.CreateVariable(1024);while(f.XPending(this._display).Val){f.XNextEventSync(this._display,o);if(o.Deref(0,4).toBuffer().readUInt32LE()==e){var k=c.CreatePointer();var i=c.CreatePointer();var m=c.CreatePointer();var n=c.CreatePointer();var l=c.CreatePointer();f.XGetWindowProperty(this._display,this._masterPromise.FAKEWIN,this._masterPromise.PROPID,0,65535,0,a,k,i,m,n,l);this._masterPromise._res(l.Deref().String);f.XFree(l.Deref());f.XDestroyWindow(this._display,this._masterPromise.FAKEWIN);this.removeDescriptor(j);break}}})}})}return(d)}function lin_copytext(){}function win_readtext(){var g="";var a=1;var b=require("_GenericMarshal");var i=b.CreateNativeProxy("user32.dll");var e=b.CreateNativeProxy("kernel32.dll");e.CreateMethod("GlobalAlloc");e.CreateMethod("GlobalLock");e.CreateMethod("GlobalUnlock");i.CreateMethod("OpenClipboard");i.CreateMethod("CloseClipboard");i.CreateMethod("GetClipboardData");i.OpenClipboard(0);var c=i.GetClipboardData(a);if(c.Val!=0){var d=e.GlobalLock(c);g=d.String;e.GlobalUnlock(c)}i.CloseClipboard();var f=new promise(function(j,h){this._res=j;this._rej=h});f._res(g);return(f)}function win_copytext(i){var c=2;var a=1;var b=require("_GenericMarshal");var j=b.CreateNativeProxy("user32.dll");var f=b.CreateNativeProxy("kernel32.dll");f.CreateMethod("GlobalAlloc");f.CreateMethod("GlobalLock");f.CreateMethod("GlobalUnlock");j.CreateMethod("OpenClipboard");j.CreateMethod("EmptyClipboard");j.CreateMethod("CloseClipboard");j.CreateMethod("SetClipboardData");var d=f.GlobalAlloc(c,i.length+2);d.autoFree(false);var e=f.GlobalLock(d);e.autoFree(false);var g=Buffer.alloc(i.length+1);Buffer.from(i).copy(g);g.copy(e.Deref(0,i.length+1).toBuffer());f.GlobalUnlock(d);j.OpenClipboard(0);j.EmptyClipboard();j.SetClipboardData(a,d);j.CloseClipboard()}switch(process.platform){case"win32":module.exports=win_copytext;module.exports.read=win_readtext;break;case"linux":module.exports=lin_copytext;module.exports.read=lin_readtext;break;case"darwin":break}module.exports.nativeAddModule=nativeAddModule;
|
4
db.js
4
db.js
@ -46,7 +46,7 @@ module.exports.CreateDB = function (parent) {
|
||||
obj.file.createIndex({ type: 1, domain: 1, meshid: 1 }, { sparse: 1 }); // Speeds up GetAllTypeNoTypeField() and GetAllTypeNoTypeFieldMeshFiltered()
|
||||
obj.file.createIndex({ email: 1 }, { sparse: 1 }); // Speeds up GetUserWithEmail() and GetUserWithVerifiedEmail()
|
||||
obj.file.createIndex({ ids: 1, time: -1 }, { sparse: 1 }); // Speeds up GetEvents() and GetEventsWithLimit()
|
||||
obj.file.createIndex({ type: 1, node: 1, time: -1 }, { sparse: 1 }); // Speeds up getPowerTimeline()
|
||||
obj.file.createIndex({ type: 1, nodeid: 1, time: 1 }, { sparse: 1 }); // Speeds up getPowerTimeline()
|
||||
obj.file.createIndex({ mesh: 1 }, { sparse: 1 }); // Speeds up RemoveMesh()
|
||||
} else {
|
||||
// Use NeDB (The default)
|
||||
@ -186,7 +186,7 @@ module.exports.CreateDB = function (parent) {
|
||||
obj.SetUser = function (user) { var u = Clone(user); if (u.subscriptions) { delete u.subscriptions; } obj.Set(u); };
|
||||
obj.dispose = function () { for (var x in obj) { if (obj[x].close) { obj[x].close(); } delete obj[x]; } };
|
||||
obj.clearOldEntries = function (type, days, domain) { var cutoff = Date.now() - (1000 * 60 * 60 * 24 * days); obj.file.remove({ type: type, time: { $lt: cutoff } }, { multi: true }); };
|
||||
obj.getPowerTimeline = function (nodeid, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'power', node: { $in: ['*', nodeid] } }).sort({ time: 1 }).exec(func); } else { obj.file.find({ type: 'power', node: { $in: ['*', nodeid] } }).sort({ time: 1 }, func); } };
|
||||
obj.getPowerTimeline = function (nodeid, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'power', nodeid: { $in: ['*', nodeid] } }).sort({ time: 1 }).exec(func); } else { obj.file.find({ type: 'power', node: { $in: ['*', nodeid] } }).sort({ time: 1 }, func); } };
|
||||
obj.getLocalAmtNodes = function (func) { obj.file.find({ type: 'node', host: { $exists: true, $ne: null }, intelamt: { $exists: true } }, func); };
|
||||
obj.getAmtUuidNode = function (meshid, uuid, func) { obj.file.find({ type: 'node', meshid: meshid, 'intelamt.uuid': uuid }, func); };
|
||||
obj.isMaxType = function (max, type, domainid, func) { if (max == null) { func(false); } else { obj.file.count({ type: type, domain: domainid }, function (err, count) { func((err != null) || (count > max)); }); } }
|
||||
|
@ -363,6 +363,21 @@ function CreateMeshCentralServer(config, args) {
|
||||
obj.db.RemoveAll(function () { obj.db.InsertMany(json, function (err) { if (err != null) { console.log(err); } else { console.log('Imported ' + json.length + ' objects(s) from ' + obj.args.dbimport + '.'); } process.exit(); }); });
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if (obj.args.dbimport) {
|
||||
// Import the entire database from a very large JSON file
|
||||
obj.db.RemoveAll(function () {
|
||||
if (obj.args.dbimport == true) { obj.args.dbimport = obj.getConfigFilePath('meshcentral.db.json'); }
|
||||
var json = null, json2 = "", badCharCount = 0;
|
||||
const StreamArray = require('stream-json/streamers/StreamArray');
|
||||
const jsonStream = StreamArray.withParser();
|
||||
jsonStream.on('data', function (data) { obj.db.Set(data.value); });
|
||||
jsonStream.on('end', () => { console.log('Done.'); process.exit(); });
|
||||
obj.fs.createReadStream(obj.args.dbimport).pipe(jsonStream.input);
|
||||
});
|
||||
return;
|
||||
}
|
||||
*/
|
||||
if (obj.args.dbmerge) {
|
||||
// Import the entire database from a JSON file
|
||||
if (obj.args.dbmerge == true) { obj.args.dbmerge = obj.getConfigFilePath('meshcentral.db.json'); }
|
||||
@ -521,6 +536,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
if (obj.args.minifycore === 0) obj.args.minifycore = false;
|
||||
|
||||
// Clear old event entries and power entires
|
||||
// TODO: Replace this is delete indexes on NeDB and MongoDB.
|
||||
obj.db.clearOldEntries('event', 30); // Clear all event entires that are older than 30 days.
|
||||
obj.db.clearOldEntries('power', 10); // Clear all event entires that are older than 10 days. If a node is connected longer than 10 days, current power state will be used for everything.
|
||||
|
||||
@ -565,9 +581,9 @@ function CreateMeshCentralServer(config, args) {
|
||||
|
||||
// Set all nodes to power state of unknown (0)
|
||||
if (obj.multiServer == null) {
|
||||
obj.db.file.insert({ type: 'power', time: Date.now(), node: '*', power: 0, s: 1 });
|
||||
obj.db.file.insert({ type: 'power', time: Date.now(), nodeid: '*', power: 0, s: 1 });
|
||||
} else {
|
||||
obj.db.file.insert({ type: 'power', time: Date.now(), node: '*', power: 0, s: 1, server: obj.multiServer.serverid });
|
||||
obj.db.file.insert({ type: 'power', time: Date.now(), nodeid: '*', power: 0, s: 1, server: obj.multiServer.serverid });
|
||||
}
|
||||
|
||||
// Read or setup database configuration values
|
||||
@ -802,7 +818,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
obj.DispatchEvent(['*'], obj, { etype: 'server', action: 'stopped', msg: 'Server stopped' });
|
||||
|
||||
// Set all nodes to power state of unknown (0)
|
||||
var record = { type: 'power', time: Date.now(), node: '*', power: 0, s: 2 };
|
||||
var record = { type: 'power', time: Date.now(), nodeid: '*', power: 0, s: 2 };
|
||||
if (obj.multiServer != null) { record.server = obj.multiServer.serverid; }
|
||||
obj.db.file.insert(record, function () {
|
||||
if (restoreFile) {
|
||||
@ -977,7 +993,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
eventConnectChange = 1;
|
||||
|
||||
// Set new power state in database
|
||||
var record = { type: 'power', time: connectTime, node: nodeid, power: powerState };
|
||||
var record = { type: 'power', time: connectTime, nodeid: nodeid, power: powerState };
|
||||
if (oldPowerState != null) record.oldPower = oldPowerState;
|
||||
obj.db.file.insert(record);
|
||||
}
|
||||
@ -1008,7 +1024,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
state.powerState = powerState;
|
||||
|
||||
// Set new power state in database
|
||||
var record = { type: 'power', time: connectTime, node: nodeid, power: powerState, server: obj.multiServer.serverid };
|
||||
var record = { type: 'power', time: connectTime, nodeid: nodeid, power: powerState, server: obj.multiServer.serverid };
|
||||
if (oldPowerState != null) record.oldPower = oldPowerState;
|
||||
obj.db.file.insert(record);
|
||||
}
|
||||
@ -1052,7 +1068,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
eventConnectChange = 1;
|
||||
|
||||
// Set new power state in database
|
||||
obj.db.file.insert({ type: 'power', time: Date.now(), node: nodeid, power: powerState, oldPower: oldPowerState });
|
||||
obj.db.file.insert({ type: 'power', time: Date.now(), nodeid: nodeid, power: powerState, oldPower: oldPowerState });
|
||||
}
|
||||
|
||||
// Event the node connection change
|
||||
|
45
meshuser.js
45
meshuser.js
@ -181,7 +181,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
var os = require('os');
|
||||
var stats = { action: 'serverstats', totalmem: os.totalmem(), freemem: os.freemem() };
|
||||
if (obj.parent.parent.platform != 'win32') { stats.cpuavg = os.loadavg(); } // else { stats.cpuavg = [ 0.2435345, 0.523234234, 0.6435345345 ]; }
|
||||
var serverStats = { "User Accounts": Object.keys(obj.parent.users).length, "Device Groups": Object.keys(obj.parent.meshes).length, "Connected Agents": Object.keys(obj.parent.wsagents).length, "Connected Users": Object.keys(obj.parent.wssessions2).length };
|
||||
var serverStats = { "User Accounts": Object.keys(obj.parent.users).length, "Device Groups": Object.keys(obj.parent.meshes).length, "Agent Sessions": Object.keys(obj.parent.wsagents).length, "Users Sessions": Object.keys(obj.parent.wssessions2).length };
|
||||
if (obj.parent.parent.mpsserver != null) { serverStats['Connected Intel® AMT'] = Object.keys(obj.parent.parent.mpsserver.ciraConnections).length; }
|
||||
stats.values = { "Server State": serverStats }
|
||||
try { ws.send(JSON.stringify(stats)); } catch (ex) { }
|
||||
@ -1802,6 +1802,49 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'getClip': {
|
||||
if (obj.common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid
|
||||
|
||||
// Get the device
|
||||
obj.db.Get(command.nodeid, function (err, nodes) {
|
||||
if (nodes.length != 1) return;
|
||||
var node = nodes[0];
|
||||
|
||||
// Get the mesh for this device
|
||||
mesh = obj.parent.meshes[node.meshid];
|
||||
if (mesh) {
|
||||
// Check if this user has "remote" rights to do this
|
||||
if ((mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 16) == 0)) return;
|
||||
|
||||
// Ask for clipboard data from agent
|
||||
var agent = obj.parent.wsagents[node._id];
|
||||
if (agent != null) { try { agent.send(JSON.stringify({ action: 'getClip' })); } catch (ex) { } }
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'setClip': {
|
||||
if (obj.common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid
|
||||
if (obj.common.validateString(command.data, 1, 65535) == false) break; // Check
|
||||
|
||||
// Get the device
|
||||
obj.db.Get(command.nodeid, function (err, nodes) {
|
||||
if (nodes.length != 1) return;
|
||||
var node = nodes[0];
|
||||
|
||||
// Get the mesh for this device
|
||||
mesh = obj.parent.meshes[node.meshid];
|
||||
if (mesh) {
|
||||
// Check if this user has "remote" rights to do this
|
||||
if ((mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 16) == 0)) return;
|
||||
|
||||
// Send clipboard data to the agent
|
||||
var agent = obj.parent.wsagents[node._id];
|
||||
if (agent != null) { try { agent.send(JSON.stringify({ action: 'setClip', data: command.data })); } catch (ex) { } }
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'getNotes':
|
||||
{
|
||||
// Argument validation
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.2.8-o",
|
||||
"version": "0.2.8-q",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
File diff suppressed because one or more lines are too long
@ -488,7 +488,8 @@
|
||||
<option value=6>Win+R</option>
|
||||
</select>
|
||||
<input id="DeskWD" type=button value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()">
|
||||
<input id="DeskCAD" style="margin-left:6px" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()">
|
||||
<input id="DeskClip" style="margin-left:6px;display:none" type="button" value="Clipboard" onkeypress="return false" onkeydown="return false" onclick="showDeskClip()">
|
||||
<input id="DeskCAD" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()">
|
||||
<span id="DeskControlSpan" style="margin-left:6px" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()">Input</span>
|
||||
</div>
|
||||
</td>
|
||||
@ -920,6 +921,7 @@
|
||||
QV('p13AutoConnect', debugmode); // Files
|
||||
QV('autoconnectbutton2', debugmode); // Terminal
|
||||
QV('autoconnectbutton1', debugmode); // Desktop
|
||||
QV('DeskClip', debugmode); // Clipboard feature, not completed so show in in debug mode only.
|
||||
|
||||
toggleFullScreen();
|
||||
|
||||
@ -1291,6 +1293,12 @@
|
||||
addNotification(n);
|
||||
} else if (message.type == 'ps') {
|
||||
showDeskToolsProcesses(message);
|
||||
} else if ((message.type == 'getclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) {
|
||||
Q('d2clipText').value = message.data;
|
||||
} else if ((message.type == 'setclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) {
|
||||
// Display success/fail on the clipboard dialog box.
|
||||
QH('dlgClipStatus', message.success ? '<span style=color:green>Success</span>' : '<span style=color:red>Failed</span>')
|
||||
setTimeout(function () { try { QH('dlgClipStatus', ''); } catch (ex) { } }, 2000);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -4012,6 +4020,7 @@
|
||||
QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (deskState != 0) && (desktopsettings.showfocus));
|
||||
QV('DeskCAD', meshrights & 8);
|
||||
QE('DeskCAD', deskState == 3);
|
||||
QE('DeskClip', deskState == 3);
|
||||
QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
|
||||
QE('DeskWD', deskState == 3);
|
||||
QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
|
||||
@ -4410,6 +4419,29 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Show clipboard dialog
|
||||
function showDeskClip() {
|
||||
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
||||
Q('DeskClip').blur();
|
||||
var x = '<input id=dlgClipGet type=button value="Get Clipboard" style=width:120px onclick=showDeskClipGet()>';
|
||||
x += '<input id=dlgClipSet type=button value="Set Clipboard" style=width:120px onclick=showDeskClipSet()>';
|
||||
x += '<div id=dlgClipStatus style="display:inline-block;margin-left:8px" ></div>';
|
||||
x += '<textarea id=d2clipText style="width:100%;height:184px;resize:none" maxlength=65535></textarea>';
|
||||
x += '<input type=button value="Close" style=width:80px;float:right onclick=dialogclose(0)><div style=height:26px> </div>';
|
||||
setDialogMode(2, "Remote Clipboard", 8, null, x, 'clipboard');
|
||||
Q('d2clipText').focus();
|
||||
}
|
||||
|
||||
function showDeskClipGet() {
|
||||
if (desktop == null || desktop.State != 3) return;
|
||||
meshserver.send({ action: 'msg', type: 'getclip', nodeid: currentNode._id });
|
||||
}
|
||||
|
||||
function showDeskClipSet() {
|
||||
if (desktop == null || desktop.State != 3) return;
|
||||
meshserver.send({ action: 'msg', type: 'setclip', nodeid: currentNode._id, data: Q('d2clipText').value });
|
||||
}
|
||||
|
||||
// Send CTRL-ALT-DEL
|
||||
function sendCAD() {
|
||||
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
||||
|
Loading…
Reference in New Issue
Block a user