mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-22 21:31:35 +03:00
Much improved event logs
This commit is contained in:
parent
187b9ac5b1
commit
fe1891346f
@ -171,8 +171,9 @@ function createMeshCore(agent)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.parent._daipc = null; this.end(); return;
|
||||
break;
|
||||
this.parent._daipc = null;
|
||||
this.end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(xe)
|
||||
@ -306,6 +307,17 @@ function createMeshCore(agent)
|
||||
var nextTunnelIndex = 1;
|
||||
var amtPolicy = null;
|
||||
|
||||
// Add to the server event log
|
||||
function MeshServerLog(msg, state) {
|
||||
if (typeof msg == 'string') { msg = { 'action': 'log', 'msg': msg }; } else { msg.action = 'log'; }
|
||||
if (state) {
|
||||
if (state.userid) { msg.userid = state.userid; }
|
||||
if (state.username) { msg.username = state.username; }
|
||||
if (state.sessionid) { msg.sessionid = state.sessionid; }
|
||||
}
|
||||
mesh.SendCommand(msg);
|
||||
}
|
||||
|
||||
// If we are running in Duktape, agent will be null
|
||||
if (agent == null) {
|
||||
// Running in native agent, Import libraries
|
||||
@ -615,6 +627,7 @@ function createMeshCore(agent)
|
||||
switch (data.type) {
|
||||
case 'console': { // Process a console command
|
||||
if (data.value && data.sessionid) {
|
||||
MeshServerLog('Processing console command: ' + data.value, data);
|
||||
var args = splitArgs(data.value);
|
||||
processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
|
||||
}
|
||||
@ -636,6 +649,8 @@ function createMeshCore(agent)
|
||||
tunnel.rights = data.rights;
|
||||
tunnel.consent = data.consent;
|
||||
tunnel.username = data.username;
|
||||
tunnel.userid = data.userid;
|
||||
tunnel.remoteaddr = data.remoteaddr;
|
||||
tunnel.state = 0;
|
||||
tunnel.url = xurl;
|
||||
tunnel.protocol = 0;
|
||||
@ -664,12 +679,14 @@ function createMeshCore(agent)
|
||||
case 'pskill': {
|
||||
// Kill a process
|
||||
if (data.value) {
|
||||
MeshServerLog('Killing process ' + data.value, data);
|
||||
try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'openUrl': {
|
||||
// Open a local web browser and return success/fail
|
||||
MeshServerLog('Opening: ' + data.url, data);
|
||||
sendConsoleText('OpenURL: ' + data.url);
|
||||
if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
|
||||
break;
|
||||
@ -677,30 +694,32 @@ function createMeshCore(agent)
|
||||
case 'getclip': {
|
||||
// Send the load clipboard back to the user
|
||||
//sendConsoleText('getClip: ' + JSON.stringify(data));
|
||||
if (require('MeshAgent').isService)
|
||||
{
|
||||
require('clipboard').dispatchRead().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
|
||||
}
|
||||
else
|
||||
{
|
||||
require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
|
||||
if (require('MeshAgent').isService) {
|
||||
require('clipboard').dispatchRead().then(function (str) {
|
||||
if (str) {
|
||||
MeshServerLog('Getting clipboard content, ' + str.length + ' byte(s)', data);
|
||||
mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
require("clipboard").read().then(function (str) {
|
||||
if (str) {
|
||||
MeshServerLog('Getting clipboard content, ' + str.length + ' byte(s)', data);
|
||||
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')
|
||||
{
|
||||
if (require('MeshAgent').isService)
|
||||
{
|
||||
require('clipboard').dispatchWrite(data.data);
|
||||
if (typeof data.data == 'string') {
|
||||
MeshServerLog('Setting clipboard content, ' + data.data.length + ' byte(s)', data);
|
||||
if (typeof data.data == 'string') {
|
||||
if (require('MeshAgent').isService) { require('clipboard').dispatchWrite(data.data); } else { require("clipboard")(data.data); } // Set the clipboard
|
||||
mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true });
|
||||
}
|
||||
else
|
||||
{
|
||||
require("clipboard")(data.data); // Set the clipboard
|
||||
}
|
||||
mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true });
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -711,7 +730,10 @@ function createMeshCore(agent)
|
||||
break;
|
||||
}
|
||||
case 'acmactivate': {
|
||||
if (amt != null) { amt.setAcmResponse(data); }
|
||||
if (amt != null) {
|
||||
MeshServerLog('Attempting Intel AMT ACM mode activation', data);
|
||||
amt.setAcmResponse(data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'wakeonlan': {
|
||||
@ -726,6 +748,7 @@ function createMeshCore(agent)
|
||||
var forced = 0;
|
||||
if (data.forced == 1) { forced = 1; }
|
||||
data.actiontype = parseInt(data.actiontype);
|
||||
MeshServerLog('Performing power action=' + data.actiontype + ', forced=' + forced, data);
|
||||
sendConsoleText('Performing power action=' + data.actiontype + ', forced=' + forced + '.');
|
||||
var r = mesh.ExecPowerState(data.actiontype, forced);
|
||||
sendConsoleText('ExecPowerState returned code: ' + r);
|
||||
@ -740,13 +763,15 @@ function createMeshCore(agent)
|
||||
case 'toast': {
|
||||
// Display a toast message
|
||||
if (data.title && data.msg) {
|
||||
MeshServerLog('Displaying toast message, title=' + data.title + ', message=' + data.msg, data);
|
||||
try { require('toaster').Toast(data.title, data.msg); } catch (ex) { }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'openUrl': {
|
||||
// Open a local web browser and return success/fail
|
||||
sendConsoleText('OpenURL: ' + data.url);
|
||||
//sendConsoleText('OpenURL: ' + data.url);
|
||||
MeshServerLog('Opening: ' + data.url, data);
|
||||
if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
|
||||
break;
|
||||
}
|
||||
@ -1003,44 +1028,41 @@ function createMeshCore(agent)
|
||||
// Perform notification if needed. Toast messages may not be supported on all platforms.
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 16)) {
|
||||
// User Consent Prompt is required
|
||||
|
||||
// Send a console message back using the console channel, "\n" is supported.
|
||||
this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
|
||||
|
||||
var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting Terminal Access. Grant access?', 10);
|
||||
pr.ws = this;
|
||||
this.pause();
|
||||
|
||||
pr.then(
|
||||
function () {
|
||||
// Success!
|
||||
// Success
|
||||
MeshServerLog('Starting remote terminal after local user accepted (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 2)) {
|
||||
// User Notifications is required
|
||||
try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote terminal session.'); } catch (ex) { }
|
||||
}
|
||||
|
||||
this.ws.resume();
|
||||
},
|
||||
function (e) {
|
||||
// User Consent Denied/Failed!
|
||||
// User Consent Denied/Failed
|
||||
MeshServerLog('Failed to start remote terminal after local user rejected (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
|
||||
this.ws.end();
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// User Consent Prompt is not required
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 2)) {
|
||||
// User Notifications is required
|
||||
MeshServerLog('Started remote terminal with toast notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote terminal session.'); } catch (ex) { }
|
||||
} else {
|
||||
MeshServerLog('Started remote terminal without notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
}
|
||||
this.resume();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.removeAllListeners('data');
|
||||
this.on('data', onTunnelControlData);
|
||||
//this.write('MeshCore Terminal Hello');
|
||||
@ -1096,10 +1118,8 @@ function createMeshCore(agent)
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 8))
|
||||
{
|
||||
// User Consent Prompt is required
|
||||
|
||||
// Send a console message back using the console channel, "\n" is supported.
|
||||
this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
|
||||
|
||||
var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting KVM Access. Grant access?', 10);
|
||||
pr.ws = this;
|
||||
this.pause();
|
||||
@ -1107,37 +1127,32 @@ function createMeshCore(agent)
|
||||
pr.then(
|
||||
function ()
|
||||
{
|
||||
// Success!
|
||||
// Success
|
||||
MeshServerLog('Starting remote desktop after local user accepted (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1))
|
||||
{
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1)) {
|
||||
// User Notifications is required
|
||||
try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote desktop session.'); } catch (ex) { }
|
||||
}
|
||||
|
||||
this.ws.httprequest.desktop.kvm.pipe(this.ws, { dataTypeSkip: 1 });
|
||||
this.ws.resume();
|
||||
},
|
||||
function (e)
|
||||
{
|
||||
// User Consent Denied/Failed!
|
||||
// User Consent Denied/Failed
|
||||
MeshServerLog('Failed to start remote desktop after local user rejected (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
|
||||
|
||||
//var err = 'User consent: ' + e.toString();
|
||||
//var b = Buffer.alloc(5 + err.length);
|
||||
//b.writeUInt16BE(MNG_ERROR, 0);
|
||||
//b.writeUInt16BE(err.length + 4, 2);
|
||||
//Buffer.from(err).copy(b, 4);
|
||||
//this.ws.end(b);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// User Consent Prompt is not required
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 1))
|
||||
{
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 1)) {
|
||||
// User Notifications is required
|
||||
MeshServerLog('Started remote desktop with toast notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote desktop session.'); } catch (ex) { }
|
||||
} else {
|
||||
MeshServerLog('Started remote desktop without notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
}
|
||||
this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 });
|
||||
}
|
||||
@ -1161,35 +1176,36 @@ function createMeshCore(agent)
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 32))
|
||||
{
|
||||
// User Consent Prompt is required
|
||||
|
||||
// Send a console message back using the console channel, "\n" is supported.
|
||||
this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
|
||||
|
||||
var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting remote file access. Grant access?', 10);
|
||||
pr.ws = this;
|
||||
this.pause();
|
||||
|
||||
pr.then(
|
||||
function () {
|
||||
// Success!
|
||||
// Success
|
||||
MeshServerLog('Starting remote files after local user accepted (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4))
|
||||
{
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4)) {
|
||||
// User Notifications is required
|
||||
try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote file session.'); } catch (ex) { }
|
||||
}
|
||||
this.ws.resume();
|
||||
},
|
||||
function (e) {
|
||||
// User Consent Denied/Failed!
|
||||
// User Consent Denied/Failed
|
||||
MeshServerLog('Failed to start remote files after local user rejected (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// User Consent Prompt is not required
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 4)) {
|
||||
// User Notifications is required
|
||||
MeshServerLog('Started remote files with toast notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote file session.'); } catch (ex) { }
|
||||
} else {
|
||||
MeshServerLog('Started remote files without notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
}
|
||||
this.resume();
|
||||
}
|
||||
@ -1252,12 +1268,15 @@ function createMeshCore(agent)
|
||||
case 'mkdir': {
|
||||
// Create a new empty folder
|
||||
fs.mkdirSync(cmd.path);
|
||||
MeshServerLog('Create folder: \"' + cmd.path + '\"', this.httprequest);
|
||||
break;
|
||||
}
|
||||
case 'rm': {
|
||||
// Delete, possibly recursive delete
|
||||
for (var i in cmd.delfiles) {
|
||||
try { deleteFolderRecursive(obj.path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
|
||||
var p = obj.path.join(cmd.path, cmd.delfiles[i]), delcount = 0;
|
||||
try { delcount = deleteFolderRecursive(p, cmd.rec); } catch (e) { }
|
||||
MeshServerLog((cmd.rec ? 'Delete recursive: \"' : 'Delete: \"') + p + '\", ' + delcount + ' element(s) removed', this.httprequest);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1265,6 +1284,7 @@ function createMeshCore(agent)
|
||||
// Rename a file or folder
|
||||
var oldfullpath = obj.path.join(cmd.path, cmd.oldname);
|
||||
var newfullpath = obj.path.join(cmd.path, cmd.newname);
|
||||
MeshServerLog('Rename: \"' + oldfullpath + '\" to \"' + cmd.newname + '\"', this.httprequest);
|
||||
try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
|
||||
break;
|
||||
}
|
||||
@ -1272,6 +1292,7 @@ function createMeshCore(agent)
|
||||
// Download a file
|
||||
var sendNextBlock = 0;
|
||||
if (cmd.sub == 'start') { // Setup the download
|
||||
MeshServerLog('Download: \"' + cmd.path + '\"', this.httprequest);
|
||||
if (this.filedownload != null) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
|
||||
try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
@ -1317,6 +1338,7 @@ function createMeshCore(agent)
|
||||
if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
|
||||
if (cmd.path == undefined) break;
|
||||
var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
|
||||
MeshServerLog('Upload: \"' + filepath + '\"', this.httprequest);
|
||||
try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; }
|
||||
this.httprequest.uploadFileid = cmd.reqid;
|
||||
if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); }
|
||||
@ -1326,6 +1348,7 @@ function createMeshCore(agent)
|
||||
// Copy a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
|
||||
MeshServerLog('Copy: \"' + sc + '\" to \"' + ds + '\"', this.httprequest);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
@ -1334,6 +1357,7 @@ function createMeshCore(agent)
|
||||
// Move a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
|
||||
MeshServerLog('Move: \"' + sc + '\" to \"' + ds + '\"', this.httprequest);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
@ -1349,19 +1373,23 @@ function createMeshCore(agent)
|
||||
|
||||
// Delete a directory with a files and directories within it
|
||||
function deleteFolderRecursive(path, rec) {
|
||||
var count = 0;
|
||||
if (fs.existsSync(path)) {
|
||||
if (rec == true) {
|
||||
fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) {
|
||||
var curPath = obj.path.join(path, file);
|
||||
if (fs.statSync(curPath).isDirectory()) { // recurse
|
||||
deleteFolderRecursive(curPath, true);
|
||||
count += deleteFolderRecursive(curPath, true);
|
||||
} else { // delete file
|
||||
fs.unlinkSync(curPath);
|
||||
count++;
|
||||
}
|
||||
});
|
||||
}
|
||||
fs.unlinkSync(path);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
// Called when receiving control data on WebRTC
|
||||
@ -1391,6 +1419,7 @@ function createMeshCore(agent)
|
||||
// Lock the current user out of the desktop
|
||||
try {
|
||||
if (process.platform == 'win32') {
|
||||
MeshServerLog('Locking remote user out of desktop', ws.httprequest);
|
||||
var child = require('child_process');
|
||||
child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 });
|
||||
}
|
||||
@ -1557,6 +1586,9 @@ function createMeshCore(agent)
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case 'log':
|
||||
if (args['_'].length != 1) { response = 'Proper usage: log "sample text"'; } else { MeshServerLog(args['_'][0]); response = 'ok'; }
|
||||
break;
|
||||
case 'getclip':
|
||||
if (require('MeshAgent').isService) {
|
||||
require('clipboard').dispatchRead().then(function (str) { sendConsoleText(str, sessionid); });
|
||||
|
148
agents/meshcore.min.js
vendored
148
agents/meshcore.min.js
vendored
@ -171,8 +171,9 @@ function createMeshCore(agent)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.parent._daipc = null; this.end(); return;
|
||||
break;
|
||||
this.parent._daipc = null;
|
||||
this.end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(xe)
|
||||
@ -306,6 +307,17 @@ function createMeshCore(agent)
|
||||
var nextTunnelIndex = 1;
|
||||
var amtPolicy = null;
|
||||
|
||||
// Add to the server event log
|
||||
function MeshServerLog(msg, state) {
|
||||
if (typeof msg == 'string') { msg = { 'action': 'log', 'msg': msg }; } else { msg.action = 'log'; }
|
||||
if (state) {
|
||||
if (state.userid) { msg.userid = state.userid; }
|
||||
if (state.username) { msg.username = state.username; }
|
||||
if (state.sessionid) { msg.sessionid = state.sessionid; }
|
||||
}
|
||||
mesh.SendCommand(msg);
|
||||
}
|
||||
|
||||
// If we are running in Duktape, agent will be null
|
||||
if (agent == null) {
|
||||
// Running in native agent, Import libraries
|
||||
@ -615,6 +627,7 @@ function createMeshCore(agent)
|
||||
switch (data.type) {
|
||||
case 'console': { // Process a console command
|
||||
if (data.value && data.sessionid) {
|
||||
MeshServerLog('Processing console command: ' + data.value, data);
|
||||
var args = splitArgs(data.value);
|
||||
processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
|
||||
}
|
||||
@ -636,6 +649,8 @@ function createMeshCore(agent)
|
||||
tunnel.rights = data.rights;
|
||||
tunnel.consent = data.consent;
|
||||
tunnel.username = data.username;
|
||||
tunnel.userid = data.userid;
|
||||
tunnel.remoteaddr = data.remoteaddr;
|
||||
tunnel.state = 0;
|
||||
tunnel.url = xurl;
|
||||
tunnel.protocol = 0;
|
||||
@ -664,12 +679,14 @@ function createMeshCore(agent)
|
||||
case 'pskill': {
|
||||
// Kill a process
|
||||
if (data.value) {
|
||||
MeshServerLog('Killing process ' + data.value, data);
|
||||
try { process.kill(data.value); } catch (e) { sendConsoleText("pskill: " + JSON.stringify(e)); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'openUrl': {
|
||||
// Open a local web browser and return success/fail
|
||||
MeshServerLog('Opening: ' + data.url, data);
|
||||
sendConsoleText('OpenURL: ' + data.url);
|
||||
if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
|
||||
break;
|
||||
@ -677,30 +694,32 @@ function createMeshCore(agent)
|
||||
case 'getclip': {
|
||||
// Send the load clipboard back to the user
|
||||
//sendConsoleText('getClip: ' + JSON.stringify(data));
|
||||
if (require('MeshAgent').isService)
|
||||
{
|
||||
require('clipboard').dispatchRead().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
|
||||
}
|
||||
else
|
||||
{
|
||||
require("clipboard").read().then(function (str) { mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str }); });
|
||||
if (require('MeshAgent').isService) {
|
||||
require('clipboard').dispatchRead().then(function (str) {
|
||||
if (str) {
|
||||
MeshServerLog('Getting clipboard content, ' + str.length + ' byte(s)', data);
|
||||
mesh.SendCommand({ "action": "msg", "type": "getclip", "sessionid": data.sessionid, "data": str });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
require("clipboard").read().then(function (str) {
|
||||
if (str) {
|
||||
MeshServerLog('Getting clipboard content, ' + str.length + ' byte(s)', data);
|
||||
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')
|
||||
{
|
||||
if (require('MeshAgent').isService)
|
||||
{
|
||||
require('clipboard').dispatchWrite(data.data);
|
||||
if (typeof data.data == 'string') {
|
||||
MeshServerLog('Setting clipboard content, ' + data.data.length + ' byte(s)', data);
|
||||
if (typeof data.data == 'string') {
|
||||
if (require('MeshAgent').isService) { require('clipboard').dispatchWrite(data.data); } else { require("clipboard")(data.data); } // Set the clipboard
|
||||
mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true });
|
||||
}
|
||||
else
|
||||
{
|
||||
require("clipboard")(data.data); // Set the clipboard
|
||||
}
|
||||
mesh.SendCommand({ "action": "msg", "type": "setclip", "sessionid": data.sessionid, "success": true });
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -711,7 +730,10 @@ function createMeshCore(agent)
|
||||
break;
|
||||
}
|
||||
case 'acmactivate': {
|
||||
if (amt != null) { amt.setAcmResponse(data); }
|
||||
if (amt != null) {
|
||||
MeshServerLog('Attempting Intel AMT ACM mode activation', data);
|
||||
amt.setAcmResponse(data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'wakeonlan': {
|
||||
@ -726,6 +748,7 @@ function createMeshCore(agent)
|
||||
var forced = 0;
|
||||
if (data.forced == 1) { forced = 1; }
|
||||
data.actiontype = parseInt(data.actiontype);
|
||||
MeshServerLog('Performing power action=' + data.actiontype + ', forced=' + forced, data);
|
||||
sendConsoleText('Performing power action=' + data.actiontype + ', forced=' + forced + '.');
|
||||
var r = mesh.ExecPowerState(data.actiontype, forced);
|
||||
sendConsoleText('ExecPowerState returned code: ' + r);
|
||||
@ -740,13 +763,15 @@ function createMeshCore(agent)
|
||||
case 'toast': {
|
||||
// Display a toast message
|
||||
if (data.title && data.msg) {
|
||||
MeshServerLog('Displaying toast message, title=' + data.title + ', message=' + data.msg, data);
|
||||
try { require('toaster').Toast(data.title, data.msg); } catch (ex) { }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'openUrl': {
|
||||
// Open a local web browser and return success/fail
|
||||
sendConsoleText('OpenURL: ' + data.url);
|
||||
//sendConsoleText('OpenURL: ' + data.url);
|
||||
MeshServerLog('Opening: ' + data.url, data);
|
||||
if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
|
||||
break;
|
||||
}
|
||||
@ -1003,44 +1028,41 @@ function createMeshCore(agent)
|
||||
// Perform notification if needed. Toast messages may not be supported on all platforms.
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 16)) {
|
||||
// User Consent Prompt is required
|
||||
|
||||
// Send a console message back using the console channel, "\n" is supported.
|
||||
this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
|
||||
|
||||
var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting Terminal Access. Grant access?', 10);
|
||||
pr.ws = this;
|
||||
this.pause();
|
||||
|
||||
pr.then(
|
||||
function () {
|
||||
// Success!
|
||||
// Success
|
||||
MeshServerLog('Starting remote terminal after local user accepted (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 2)) {
|
||||
// User Notifications is required
|
||||
try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote terminal session.'); } catch (ex) { }
|
||||
}
|
||||
|
||||
this.ws.resume();
|
||||
},
|
||||
function (e) {
|
||||
// User Consent Denied/Failed!
|
||||
// User Consent Denied/Failed
|
||||
MeshServerLog('Failed to start remote terminal after local user rejected (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
|
||||
this.ws.end();
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// User Consent Prompt is not required
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 2)) {
|
||||
// User Notifications is required
|
||||
MeshServerLog('Started remote terminal with toast notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote terminal session.'); } catch (ex) { }
|
||||
} else {
|
||||
MeshServerLog('Started remote terminal without notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
}
|
||||
this.resume();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.removeAllListeners('data');
|
||||
this.on('data', onTunnelControlData);
|
||||
//this.write('MeshCore Terminal Hello');
|
||||
@ -1096,10 +1118,8 @@ function createMeshCore(agent)
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 8))
|
||||
{
|
||||
// User Consent Prompt is required
|
||||
|
||||
// Send a console message back using the console channel, "\n" is supported.
|
||||
this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
|
||||
|
||||
var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting KVM Access. Grant access?', 10);
|
||||
pr.ws = this;
|
||||
this.pause();
|
||||
@ -1107,37 +1127,32 @@ function createMeshCore(agent)
|
||||
pr.then(
|
||||
function ()
|
||||
{
|
||||
// Success!
|
||||
// Success
|
||||
MeshServerLog('Starting remote desktop after local user accepted (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1))
|
||||
{
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 1)) {
|
||||
// User Notifications is required
|
||||
try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote desktop session.'); } catch (ex) { }
|
||||
}
|
||||
|
||||
this.ws.httprequest.desktop.kvm.pipe(this.ws, { dataTypeSkip: 1 });
|
||||
this.ws.resume();
|
||||
},
|
||||
function (e)
|
||||
{
|
||||
// User Consent Denied/Failed!
|
||||
// User Consent Denied/Failed
|
||||
MeshServerLog('Failed to start remote desktop after local user rejected (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
|
||||
|
||||
//var err = 'User consent: ' + e.toString();
|
||||
//var b = Buffer.alloc(5 + err.length);
|
||||
//b.writeUInt16BE(MNG_ERROR, 0);
|
||||
//b.writeUInt16BE(err.length + 4, 2);
|
||||
//Buffer.from(err).copy(b, 4);
|
||||
//this.ws.end(b);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// User Consent Prompt is not required
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 1))
|
||||
{
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 1)) {
|
||||
// User Notifications is required
|
||||
MeshServerLog('Started remote desktop with toast notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote desktop session.'); } catch (ex) { }
|
||||
} else {
|
||||
MeshServerLog('Started remote desktop without notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
}
|
||||
this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 });
|
||||
}
|
||||
@ -1161,35 +1176,36 @@ function createMeshCore(agent)
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 32))
|
||||
{
|
||||
// User Consent Prompt is required
|
||||
|
||||
// Send a console message back using the console channel, "\n" is supported.
|
||||
this.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: 'Waiting for user to grant access...' }));
|
||||
|
||||
var pr = require('message-box').create('MeshCentral', this.httprequest.username + ' requesting remote file access. Grant access?', 10);
|
||||
pr.ws = this;
|
||||
this.pause();
|
||||
|
||||
pr.then(
|
||||
function () {
|
||||
// Success!
|
||||
// Success
|
||||
MeshServerLog('Starting remote files after local user accepted (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.write(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: null }));
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4))
|
||||
{
|
||||
if (this.ws.httprequest.consent && (this.ws.httprequest.consent & 4)) {
|
||||
// User Notifications is required
|
||||
try { require('toaster').Toast('MeshCentral', this.ws.httprequest.username + ' started a remote file session.'); } catch (ex) { }
|
||||
}
|
||||
this.ws.resume();
|
||||
},
|
||||
function (e) {
|
||||
// User Consent Denied/Failed!
|
||||
// User Consent Denied/Failed
|
||||
MeshServerLog('Failed to start remote files after local user rejected (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
this.ws.end(JSON.stringify({ ctrlChannel: '102938', type: 'console', msg: e.toString() }));
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// User Consent Prompt is not required
|
||||
if (this.httprequest.consent && (this.httprequest.consent & 4)) {
|
||||
// User Notifications is required
|
||||
MeshServerLog('Started remote files with toast notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
try { require('toaster').Toast('MeshCentral', this.httprequest.username + ' started a remote file session.'); } catch (ex) { }
|
||||
} else {
|
||||
MeshServerLog('Started remote files without notification (' + this.httprequest.remoteaddr + ')', this.httprequest);
|
||||
}
|
||||
this.resume();
|
||||
}
|
||||
@ -1252,12 +1268,15 @@ function createMeshCore(agent)
|
||||
case 'mkdir': {
|
||||
// Create a new empty folder
|
||||
fs.mkdirSync(cmd.path);
|
||||
MeshServerLog('Create folder: \"' + cmd.path + '\"', this.httprequest);
|
||||
break;
|
||||
}
|
||||
case 'rm': {
|
||||
// Delete, possibly recursive delete
|
||||
for (var i in cmd.delfiles) {
|
||||
try { deleteFolderRecursive(obj.path.join(cmd.path, cmd.delfiles[i]), cmd.rec); } catch (e) { }
|
||||
var p = obj.path.join(cmd.path, cmd.delfiles[i]), delcount = 0;
|
||||
try { delcount = deleteFolderRecursive(p, cmd.rec); } catch (e) { }
|
||||
MeshServerLog((cmd.rec ? 'Delete recursive: \"' : 'Delete: \"') + p + '\", ' + delcount + ' element(s) removed', this.httprequest);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1265,6 +1284,7 @@ function createMeshCore(agent)
|
||||
// Rename a file or folder
|
||||
var oldfullpath = obj.path.join(cmd.path, cmd.oldname);
|
||||
var newfullpath = obj.path.join(cmd.path, cmd.newname);
|
||||
MeshServerLog('Rename: \"' + oldfullpath + '\" to \"' + cmd.newname + '\"', this.httprequest);
|
||||
try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
|
||||
break;
|
||||
}
|
||||
@ -1272,6 +1292,7 @@ function createMeshCore(agent)
|
||||
// Download a file
|
||||
var sendNextBlock = 0;
|
||||
if (cmd.sub == 'start') { // Setup the download
|
||||
MeshServerLog('Download: \"' + cmd.path + '\"', this.httprequest);
|
||||
if (this.filedownload != null) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
|
||||
try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
@ -1317,6 +1338,7 @@ function createMeshCore(agent)
|
||||
if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
|
||||
if (cmd.path == undefined) break;
|
||||
var filepath = cmd.name ? obj.path.join(cmd.path, cmd.name) : cmd.path;
|
||||
MeshServerLog('Upload: \"' + filepath + '\"', this.httprequest);
|
||||
try { this.httprequest.uploadFile = fs.openSync(filepath, 'wbN'); } catch (e) { this.write(new Buffer(JSON.stringify({ action: 'uploaderror', reqid: cmd.reqid }))); break; }
|
||||
this.httprequest.uploadFileid = cmd.reqid;
|
||||
if (this.httprequest.uploadFile) { this.write(new Buffer(JSON.stringify({ action: 'uploadstart', reqid: this.httprequest.uploadFileid }))); }
|
||||
@ -1326,6 +1348,7 @@ function createMeshCore(agent)
|
||||
// Copy a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
|
||||
MeshServerLog('Copy: \"' + sc + '\" to \"' + ds + '\"', this.httprequest);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
@ -1334,6 +1357,7 @@ function createMeshCore(agent)
|
||||
// Move a bunch of files from scpath to dspath
|
||||
for (var i in cmd.names) {
|
||||
var sc = obj.path.join(cmd.scpath, cmd.names[i]), ds = obj.path.join(cmd.dspath, cmd.names[i]);
|
||||
MeshServerLog('Move: \"' + sc + '\" to \"' + ds + '\"', this.httprequest);
|
||||
if (sc != ds) { try { fs.copyFileSync(sc, ds); fs.unlinkSync(sc); } catch (e) { } }
|
||||
}
|
||||
break;
|
||||
@ -1349,19 +1373,23 @@ function createMeshCore(agent)
|
||||
|
||||
// Delete a directory with a files and directories within it
|
||||
function deleteFolderRecursive(path, rec) {
|
||||
var count = 0;
|
||||
if (fs.existsSync(path)) {
|
||||
if (rec == true) {
|
||||
fs.readdirSync(obj.path.join(path, '*')).forEach(function (file, index) {
|
||||
var curPath = obj.path.join(path, file);
|
||||
if (fs.statSync(curPath).isDirectory()) { // recurse
|
||||
deleteFolderRecursive(curPath, true);
|
||||
count += deleteFolderRecursive(curPath, true);
|
||||
} else { // delete file
|
||||
fs.unlinkSync(curPath);
|
||||
count++;
|
||||
}
|
||||
});
|
||||
}
|
||||
fs.unlinkSync(path);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
// Called when receiving control data on WebRTC
|
||||
@ -1391,6 +1419,7 @@ function createMeshCore(agent)
|
||||
// Lock the current user out of the desktop
|
||||
try {
|
||||
if (process.platform == 'win32') {
|
||||
MeshServerLog('Locking remote user out of desktop', ws.httprequest);
|
||||
var child = require('child_process');
|
||||
child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'RunDll32.exe user32.dll,LockWorkStation'], { type: 1 });
|
||||
}
|
||||
@ -1557,6 +1586,9 @@ function createMeshCore(agent)
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case 'log':
|
||||
if (args['_'].length != 1) { response = 'Proper usage: log "sample text"'; } else { MeshServerLog(args['_'][0]); response = 'ok'; }
|
||||
break;
|
||||
case 'getclip':
|
||||
if (require('MeshAgent').isService) {
|
||||
require('clipboard').dispatchRead().then(function (str) { sendConsoleText(str, sessionid); });
|
||||
|
20
meshagent.js
20
meshagent.js
@ -1192,6 +1192,20 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
// Nothing is done right now.
|
||||
break;
|
||||
}
|
||||
case 'log':
|
||||
{
|
||||
// Log a value in the event log
|
||||
if ((typeof command.msg == 'string') && (command.msg.length < 4096)) {
|
||||
var event = { etype: 'node', action: 'agentlog', nodeid: obj.dbNodeKey, domain: domain.id, msg: command.msg };
|
||||
if (typeof command.userid == 'string') {
|
||||
var loguser = parent.users[command.userid];
|
||||
if (loguser) { event.userid = command.userid; event.username = loguser.name; }
|
||||
}
|
||||
if ((typeof command.sessionid == 'string') && (command.sessionid.length < 500)) { event.sessionid = command.sessionid; }
|
||||
parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'ping': { sendPong(); break; }
|
||||
case 'pong': { break; }
|
||||
case 'getScript':
|
||||
@ -1273,10 +1287,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
break;
|
||||
}
|
||||
case 'log': {
|
||||
// Only the diagnostic agent can do
|
||||
if (((obj.agentInfo.capabilities & 0x40) != 0) && (typeof command.value.value == 'string') && (command.value.value.length < 256))
|
||||
{
|
||||
// Log a value in the event log of the main again
|
||||
if (((obj.agentInfo.capabilities & 0x40) != 0) && (typeof command.value.value == 'string') && (command.value.value.length < 256)) {
|
||||
// If this is a diagnostic agent, log the event in the log of the main agent
|
||||
var event = { etype: 'node', action: 'diagnostic', nodeid: obj.realNodeKey, domain: domain.id, msg: command.value.value };
|
||||
parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, event);
|
||||
}
|
||||
|
69
meshuser.js
69
meshuser.js
@ -70,7 +70,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (parent.parent.multiServer == null) {
|
||||
var targets = ['*', 'server-users'];
|
||||
if (obj.user.groups) { for (var i in obj.user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', username: obj.user.name, count: parent.wssessions[obj.user._id].length, nolog: 1, domain: domain.id });
|
||||
parent.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', userid: user._id, username: user.name, count: parent.wssessions[obj.user._id].length, nolog: 1, domain: domain.id });
|
||||
} else {
|
||||
parent.recountSessions(ws.sessionId); // Recount sessions
|
||||
}
|
||||
@ -141,6 +141,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
command.consent = mesh.consent; // Add user consent
|
||||
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
|
||||
command.username = user.name; // Add user name
|
||||
command.userid = user._id; // Add user id
|
||||
command.remoteaddr = (req.ip.startsWith('::ffff:')) ? (req.ip.substring(7)) : req.ip; // User's IP address
|
||||
delete command.nodeid; // Remove the nodeid since it's implied
|
||||
try { agent.send(JSON.stringify(command)); } catch (ex) { }
|
||||
}
|
||||
@ -157,6 +159,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
command.consent = mesh.consent; // Add user consent
|
||||
if (typeof domain.userconsentflags == 'number') { command.consent |= domain.userconsentflags; } // Add server required consent flags
|
||||
command.username = user.name; // Add user name
|
||||
command.userid = user._id; // Add user id
|
||||
command.remoteaddr = (req.ip.startsWith('::ffff:')) ? (req.ip.substring(7)) : req.ip; // User's IP address
|
||||
parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
|
||||
}
|
||||
}
|
||||
@ -214,7 +218,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (parent.parent.multiServer == null) {
|
||||
var targets = ['*', 'server-users'];
|
||||
if (obj.user.groups) { for (var i in obj.user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', username: user.name, count: parent.wssessions[user._id].length, nolog: 1, domain: domain.id });
|
||||
parent.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', userid: user._id, username: user.name, count: parent.wssessions[user._id].length, nolog: 1, domain: domain.id });
|
||||
} else {
|
||||
parent.recountSessions(ws.sessionId); // Recount sessions
|
||||
}
|
||||
@ -835,14 +839,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'clearevents':
|
||||
{
|
||||
// Delete all events
|
||||
if (user.siteadmin != 0xFFFFFFFF) break;
|
||||
db.RemoveAllEvents(domain.id);
|
||||
parent.parent.DispatchEvent(['*', 'server-global'], obj, { action: 'clearevents', nolog: 1, domain: domain.id });
|
||||
break;
|
||||
}
|
||||
case 'users':
|
||||
{
|
||||
// Request a list of all users
|
||||
@ -885,7 +881,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
parent.db.SetUser(user);
|
||||
|
||||
// Event the change
|
||||
var message = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', domain: domain.id };
|
||||
var message = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', domain: domain.id };
|
||||
if (db.changeStream) { message.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
if (oldemail != null) {
|
||||
message.msg = 'Changed email of user ' + user.name + ' from ' + oldemail + ' to ' + user.email;
|
||||
@ -994,7 +990,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (mesh.links[deluser._id] != null) { delete mesh.links[deluser._id]; parent.db.Set(common.escapeLinksFieldName(mesh)); }
|
||||
// Notify mesh change
|
||||
change = 'Removed user ' + deluser.name + ' from group ' + mesh.name;
|
||||
var event = { etype: 'mesh', username: user.name, userid: user._id, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id };
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', mesh._id, deluser._id, user._id], obj, event);
|
||||
}
|
||||
@ -1115,9 +1111,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
var event, targets = ['*', 'server-users'];
|
||||
if (newuser.groups) { for (var i in newuser.groups) { targets.push('server-users:' + i); } }
|
||||
if (newuser.email == null) {
|
||||
event = { etype: 'user', username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, username is ' + newuser.name, domain: domain.id };
|
||||
event = { etype: 'user', userid: newuser._id, username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, username is ' + newuser.name, domain: domain.id };
|
||||
} else {
|
||||
event = { etype: 'user', username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, email is ' + newuser.email, domain: domain.id };
|
||||
event = { etype: 'user', userid: newuser._id, username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, email is ' + newuser.email, domain: domain.id };
|
||||
}
|
||||
if (parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
@ -1202,9 +1198,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
var event, targets = ['*', 'server-users'];
|
||||
if (newuser.groups) { for (var i in newuser.groups) { targets.push('server-users:' + i); } }
|
||||
if (command.email == null) {
|
||||
event = { etype: 'user', username: newusername, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, username is ' + command.username, domain: domain.id };
|
||||
event = { etype: 'user', userid: newuser._id, username: newusername, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, username is ' + command.username, domain: domain.id };
|
||||
} else {
|
||||
event = { etype: 'user', username: newusername, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, email is ' + command.email.toLowerCase(), domain: domain.id };
|
||||
event = { etype: 'user', userid: newuser._id, username: newusername, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, email is ' + command.email.toLowerCase(), domain: domain.id };
|
||||
}
|
||||
if (parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
@ -1285,7 +1281,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
|
||||
var targets = ['*', 'server-users', user._id, chguser._id];
|
||||
if (allTargetGroups) { for (var i in allTargetGroups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Account changed: ' + chguser.name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Account changed: ' + chguser.name, domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
}
|
||||
@ -1324,7 +1320,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Notify change
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Mesh notification change.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Mesh notification change.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
|
||||
@ -1361,7 +1357,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
|
||||
var targets = ['*', 'server-users'];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Account password changed: ' + user.name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Account password changed: ' + user.name, domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
|
||||
@ -1411,7 +1407,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
|
||||
var targets = ['*', 'server-users', user._id, chguser._id];
|
||||
if (chguser.groups) { for (var i in chguser.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Changed account credentials.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Changed account credentials.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
} else {
|
||||
@ -1561,12 +1557,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Event the user change
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', domain: domain.id, nolog: 1 };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', domain: domain.id, nolog: 1 };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
|
||||
// Event the device group creation
|
||||
var event = { etype: 'mesh', username: user.name, meshid: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, action: 'createmesh', links: links, msg: 'Mesh created: ' + command.meshname, domain: domain.id };
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, action: 'createmesh', links: links, msg: 'Mesh created: ' + command.meshname, domain: domain.id };
|
||||
parent.parent.DispatchEvent(['*', meshid, user._id], obj, event); // Even if DB change stream is active, this event must be acted upon.
|
||||
|
||||
try { ws.send(JSON.stringify({ action: 'createmesh', responseid: command.responseid, result: 'ok', meshid: meshid })); } catch (ex) { }
|
||||
@ -1598,7 +1594,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (err != null) { if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'deletemesh', responseid: command.responseid, result: err })); } catch (ex) { } } return; }
|
||||
|
||||
// Fire the removal event first, because after this, the event will not route
|
||||
var event = { etype: 'mesh', username: user.name, meshid: command.meshid, name: command.meshname, action: 'deletemesh', msg: 'Mesh deleted: ' + command.meshname, domain: domain.id };
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: command.meshid, name: command.meshname, action: 'deletemesh', msg: 'Mesh deleted: ' + command.meshname, domain: domain.id };
|
||||
parent.parent.DispatchEvent(['*', command.meshid], obj, event); // Even if DB change stream is active, this event need to be acted on.
|
||||
|
||||
// Remove all user links to this mesh
|
||||
@ -1647,7 +1643,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if ((common.validateInt(command.consent) == true) && (command.consent != mesh.consent)) { if (change != '') change += ' and consent changed'; else change += 'Group "' + mesh.name + '" consent changed'; mesh.consent = command.consent; }
|
||||
if (change != '') {
|
||||
db.Set(common.escapeLinksFieldName(mesh));
|
||||
var event = { etype: 'mesh', username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, flags: mesh.flags, consent: mesh.consent, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id };
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, flags: mesh.flags, consent: mesh.consent, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', mesh._id, user._id], obj, event);
|
||||
}
|
||||
@ -1797,7 +1793,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
db.Set(common.escapeLinksFieldName(mesh));
|
||||
var amtpolicy2 = common.Clone(amtpolicy);
|
||||
delete amtpolicy2.password;
|
||||
var event = { etype: 'mesh', username: user.name, meshid: mesh._id, amt: amtpolicy2, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id };
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, amt: amtpolicy2, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', mesh._id, user._id], obj, event);
|
||||
|
||||
@ -1845,7 +1841,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Event the new node
|
||||
var device2 = common.Clone(device);
|
||||
delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this.
|
||||
parent.parent.DispatchEvent(['*', command.meshid], obj, { etype: 'node', username: user.name, action: 'addnode', node: device2, msg: 'Added device ' + command.devicename + ' to mesh ' + mesh.name, domain: domain.id });
|
||||
parent.parent.DispatchEvent(['*', command.meshid], obj, { etype: 'node', userid: user._id, username: user.name, action: 'addnode', node: device2, msg: 'Added device ' + command.devicename + ' to mesh ' + mesh.name, domain: domain.id });
|
||||
});
|
||||
}
|
||||
break;
|
||||
@ -1909,7 +1905,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
|
||||
// Event the node change
|
||||
var newMesh = parent.meshes[command.meshid];
|
||||
var event = { etype: 'node', username: user.name, action: 'nodemeshchange', nodeid: node._id, node: node, oldMeshId: oldMeshId, newMeshId: command.meshid, msg: 'Moved device ' + node.name + ' to group ' + newMesh.name, domain: domain.id };
|
||||
var event = { etype: 'node', userid: user._id, username: user.name, action: 'nodemeshchange', nodeid: node._id, node: node, oldMeshId: oldMeshId, newMeshId: command.meshid, msg: 'Moved device ' + node.name + ' to group ' + newMesh.name, domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', oldMeshId, command.meshid], obj, event);
|
||||
});
|
||||
@ -1950,7 +1946,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
});
|
||||
|
||||
// Event node deletion
|
||||
var event = { etype: 'node', username: user.name, action: 'removenode', nodeid: node._id, msg: 'Removed device ' + node.name + ' from group ' + mesh.name, domain: domain.id };
|
||||
var event = { etype: 'node', userid: user._id, username: user.name, action: 'removenode', nodeid: node._id, msg: 'Removed device ' + node.name + ' from group ' + mesh.name, domain: domain.id };
|
||||
// TODO: We can't use the changeStream for node delete because we will not know the meshid the device was in.
|
||||
//if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to remove the node. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', node.meshid], obj, event);
|
||||
@ -2080,7 +2076,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Get the mesh for this device
|
||||
mesh = parent.meshes[node.meshid];
|
||||
if (mesh) {
|
||||
|
||||
// Check if this user has rights to do this
|
||||
if (mesh.links[user._id] != null && ((mesh.links[user._id].rights & 8) != 0)) { // "Remote Control permission"
|
||||
|
||||
@ -2088,7 +2083,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
var agent = parent.wsagents[node._id];
|
||||
if (agent != null) {
|
||||
// Send the power command
|
||||
try { agent.send(JSON.stringify({ action: 'toast', title: command.title, msg: command.msg })); } catch (ex) { }
|
||||
try { agent.send(JSON.stringify({ action: 'toast', title: command.title, msg: command.msg, sessionid: ws.sessionId, username: user.name, userid: user._id })); } catch (ex) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2143,7 +2138,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 4) == 0)) return;
|
||||
|
||||
// Ready the node change event
|
||||
var changes = [], event = { etype: 'node', username: user.name, action: 'changenode', nodeid: node._id, domain: domain.id };
|
||||
var changes = [], event = { etype: 'node', userid: user._id, username: user.name, action: 'changenode', nodeid: node._id, domain: domain.id };
|
||||
change = 0;
|
||||
event.msg = ": ";
|
||||
|
||||
@ -2405,7 +2400,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Notify change
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added authentication application.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added authentication application.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
} else {
|
||||
@ -2428,7 +2423,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Notify change
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed authentication application.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed authentication application.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
} else {
|
||||
@ -2467,7 +2462,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Notify change
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
break;
|
||||
@ -2502,7 +2497,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Notify change
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed security key.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed security key.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
break;
|
||||
@ -2552,7 +2547,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Notify change TODO: Should be done on all sessions/servers for this user.
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
} else {
|
||||
@ -2605,7 +2600,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Notify change
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
var event = { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
} else {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.3.8-s",
|
||||
"version": "0.3.8-t",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -837,7 +837,7 @@ NoMeshesPanel img {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
#p3events {
|
||||
#p3events, #p16events, #p31events {
|
||||
height: calc(100vh - 245px);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
@ -848,12 +848,6 @@ NoMeshesPanel img {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.p3eventsTable {
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#p4name, #p4email, #p4pass1, #p4pass2 {
|
||||
width: 230px;
|
||||
}
|
||||
@ -1360,6 +1354,14 @@ a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.si5 {
|
||||
background: url(../images/icons16.png) -80px 0px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
border: none;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mi {
|
||||
background: url(../images/meshicon50.png) 0px 0px;
|
||||
height: 50px;
|
||||
@ -1582,6 +1584,14 @@ a {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#p16events .g1 {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#p31events .g1 {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#p3users .g1 {
|
||||
height: 24px;
|
||||
float: left;
|
||||
@ -1617,6 +1627,14 @@ a {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#p16events .g2 {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#p31events .g2 {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#p3users .g2 {
|
||||
height: 24px;
|
||||
float: right;
|
||||
@ -2288,6 +2306,7 @@ a {
|
||||
width: calc(100vw - 120px);
|
||||
}
|
||||
|
||||
/*
|
||||
#p16events, #p31events {
|
||||
max-height: calc(100vh - 245px);
|
||||
overflow-y: auto;
|
||||
@ -2296,6 +2315,7 @@ a {
|
||||
.room4submenu #p16events, #p31events {
|
||||
max-height: calc(100vh - 269px);
|
||||
}
|
||||
*/
|
||||
|
||||
.night #p16events, #p31events {
|
||||
color: #222;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1063,11 +1063,6 @@
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'clearevents': {
|
||||
//events = [];
|
||||
//events_update();
|
||||
break;
|
||||
}
|
||||
case 'login': {
|
||||
// Update the last login time
|
||||
if (users != null && users['user/' + domain + '/' + message.event.username.toLowerCase()]) { users['user/' + domain + '/' + message.event.username.toLowerCase()].login = message.event.time; }
|
||||
|
@ -286,7 +286,6 @@
|
||||
<table class="pTable">
|
||||
<tr>
|
||||
<td class="h1"></td>
|
||||
<td> <input id="p2deleteall" type=button onclick=showDeleteAllEventsDialog() style="display:none" value="Delete All..." /></td>
|
||||
<td class="auto-style1">
|
||||
Show
|
||||
<select id=p3limitdropdown onchange=refreshEvents()>
|
||||
@ -762,7 +761,7 @@
|
||||
<td class="h2"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id=p31events></div>
|
||||
<div id=p31events style=""></div>
|
||||
</div>
|
||||
<div id=p40 style="display:none;">
|
||||
<h1>My Server Stats</h1>
|
||||
@ -1263,7 +1262,6 @@
|
||||
if (xxcurrentView == 4 || ((xxcurrentView >= 30) && (xxcurrentView < 40))) { setDialogMode(0); go(1); currentUser = null; }
|
||||
}
|
||||
meshserver.send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
|
||||
QV('p2deleteall', userinfo.siteadmin == 0xFFFFFFFF);
|
||||
QV('ServerConsole', userinfo.siteadmin === 0xFFFFFFFF);
|
||||
if ((xxcurrentView == 115) && (userinfo.siteadmin != 0xFFFFFFFF)) { go(6); }
|
||||
if ((xxcurrentView == 6) && ((userinfo.siteadmin & 21) == 0)) { go(1); }
|
||||
@ -1689,6 +1687,23 @@
|
||||
}
|
||||
case 'event': {
|
||||
if (!message.event.nolog) {
|
||||
if (currentNode && (message.event.nodeid == currentNode._id)) {
|
||||
// If this event has a nodeid and we are looking at this node, update the log in real time.
|
||||
currentDeviceEvents.unshift(message.event);
|
||||
var eventLimit = parseInt(p16limitdropdown.value);
|
||||
while (currentDeviceEvents.length > eventLimit) { currentDeviceEvents.pop(); } // Remove element(s) at the end
|
||||
masterUpdate(1024);
|
||||
}
|
||||
|
||||
if (currentUser && (message.event.userid == currentUser._id)) {
|
||||
// If this event has a userid and we are looking at this user, update the log in real time.
|
||||
currentUserEvents.unshift(message.event);
|
||||
var eventLimit = parseInt(p31limitdropdown.value);
|
||||
while (currentUserEvents.length > eventLimit) { currentUserEvents.pop(); } // Remove element(s) at the end
|
||||
masterUpdate(2048);
|
||||
}
|
||||
|
||||
// Add this event to the master events log.
|
||||
events.unshift(message.event);
|
||||
var eventLimit = parseInt(p3limitdropdown.value);
|
||||
while (events.length > eventLimit) { events.pop(); } // Remove element(s) at the end
|
||||
@ -2001,11 +2016,6 @@
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'clearevents': {
|
||||
events = [];
|
||||
masterUpdate(32);
|
||||
break;
|
||||
}
|
||||
case 'login': {
|
||||
// Update the last login time
|
||||
if (users != null && users['user/' + domain + '/' + message.event.username.toLowerCase()]) {
|
||||
@ -4147,6 +4157,7 @@
|
||||
function deviceUrlFunction() {
|
||||
if (xxdialogMode) return;
|
||||
setDialogMode(2, "Open Page on Device", 3, deviceUrlFunctionEx, '<input id=d2devurl placeholder="http://server.com" style=width:100%;overflow-y:scroll></input>');
|
||||
Q('d2devurl').focus();
|
||||
}
|
||||
|
||||
function deviceUrlFunctionEx() {
|
||||
@ -4156,6 +4167,7 @@
|
||||
function deviceToastFunction() {
|
||||
if (xxdialogMode) return;
|
||||
setDialogMode(2, "Device Notification", 3, deviceToastFunctionEx, '<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>');
|
||||
Q('d2devToast').focus();
|
||||
}
|
||||
|
||||
function deviceToastFunctionEx() {
|
||||
@ -5830,50 +5842,56 @@
|
||||
function deviceEventsUpdate() {
|
||||
var x = '', dateHeader = null;
|
||||
for (var i in currentDeviceEvents) {
|
||||
var event = currentDeviceEvents[i];
|
||||
var time = new Date(event.time);
|
||||
if (printDate(time) != dateHeader) {
|
||||
if (dateHeader != null) x += '</table>';
|
||||
dateHeader = printDate(time);
|
||||
x += '<table style=width:100% cellpadding=0 cellspacing=0><tr><td class=DevSt colspan=4>' + dateHeader + '</td></tr>';
|
||||
}
|
||||
var icon = 'si3';
|
||||
if (event.etype == 'user') icon = 'm2';
|
||||
if (event.etype == 'server') icon = 'si3';
|
||||
var event = currentDeviceEvents[i], time = new Date(event.time);
|
||||
if (event.msg) {
|
||||
if (event.h == null) { event.h = Math.random(); }
|
||||
if (printDate(time) != dateHeader) {
|
||||
if (dateHeader != null) x += '</table>';
|
||||
dateHeader = printDate(time);
|
||||
x += '<table class=p3eventsTable cellpadding=0 cellspacing=0><tr><td colspan=4 class=DevSt>' + dateHeader + '</td></tr>';
|
||||
}
|
||||
var icon = 'si3';
|
||||
if (event.etype == 'user') icon = 'm2';
|
||||
if (event.etype == 'server') icon = 'si3';
|
||||
|
||||
var msg = event.msg.split('(R)').join('®');
|
||||
//if (event.username && event.username != userinfo.name) { msg += ': ' + event.username; }
|
||||
x += '<tr><td style=width:18px><div class=' + icon + '></div></td><td class=g1 style=float:none> </td><td style=background-color:#C9C9C9>' + printTime(time) + ' - ' + msg + '</td><td class=g2 style=float:none> </td></tr><tr style=height:2px></tr>';
|
||||
var msg = event.msg.split('(R)').join('®');
|
||||
if (event.username) {
|
||||
if ((userinfo.siteadmin & 2) && (event.userid)) {
|
||||
msg = '<a href=# onclick=\'gotoUser("' + encodeURIComponent(event.userid) + '");haltEvent(event);\'>' + event.username + '</a> → ' + msg;
|
||||
} else {
|
||||
msg = event.username + ' → ' + msg;
|
||||
}
|
||||
}
|
||||
x += '<tr onclick=showEventDetails(' + event.h + ',1) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
||||
}
|
||||
}
|
||||
if (dateHeader != null) x += '</table>';
|
||||
if (x == '') x = "<br><i>No Events Found</i><br><br>";
|
||||
QH('p16events', x);
|
||||
}
|
||||
|
||||
/*
|
||||
function showDeleteAllEventsDialog() {
|
||||
if (xxdialogMode) return;
|
||||
var x = "Delete all events in the server event log?<br /><br />";
|
||||
x += "<input id=p3check type=checkbox onchange=validateDeleteAllEventsDialog() />Confirm";
|
||||
setDialogMode(2, "Delete All Events", 3, showDeleteAllEventsDialogEx, x);
|
||||
validateDeleteAllEventsDialog();
|
||||
}
|
||||
|
||||
function validateDeleteAllEventsDialog() {
|
||||
QE('idx_dlgOkButton', Q('p3check').checked);
|
||||
}
|
||||
|
||||
function showDeleteAllEventsDialogEx(buttons, tag) {
|
||||
meshserver.send({ action: 'clearevents' });
|
||||
}
|
||||
*/
|
||||
|
||||
function refreshDeviceEvents() {
|
||||
//currentDeviceEvents = null;
|
||||
//QH('p16events', '');
|
||||
meshserver.send({ action: 'events', nodeid: currentNode._id, limit: parseInt(p16limitdropdown.value) });
|
||||
}
|
||||
|
||||
function showEventDetails(h, mode) {
|
||||
var eventList, xevent;
|
||||
if (mode == 1) { eventList = currentDeviceEvents; }
|
||||
if (mode == 2) { eventList = events; }
|
||||
if (mode == 3) { eventList = currentUserEvents; }
|
||||
for (var i in eventList) { if (eventList[i].h == h) { xevent = eventList[i]; break; } }
|
||||
if (xevent) {
|
||||
if (xxdialogMode) return false;
|
||||
var x = '<div style=overflow-y:auto>';
|
||||
for (var i in xevent) {
|
||||
if ((i == 'h') || (i == '_id') || (i == 'ids') || (i == 'domain') || (xevent[i] == null) || (typeof xevent[i] == 'object')) continue;
|
||||
x += addHtmlValue3(EscapeHtml(i), EscapeHtml(xevent[i]));
|
||||
}
|
||||
x += '</div>';
|
||||
setDialogMode(2, "Event Details", 9, null, x);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CONSOLE
|
||||
//
|
||||
@ -7206,6 +7224,7 @@
|
||||
for (var i in events) {
|
||||
var event = events[i], time = new Date(event.time);
|
||||
if (event.msg) {
|
||||
if (event.h == null) { event.h = Math.random(); }
|
||||
if (printDate(time) != dateHeader) {
|
||||
if (dateHeader != null) x += '</table>';
|
||||
dateHeader = printDate(time);
|
||||
@ -7216,8 +7235,21 @@
|
||||
if (event.etype == 'server') icon = 'si3';
|
||||
|
||||
var msg = event.msg.split('(R)').join('®');
|
||||
if (event.username && event.username != userinfo.name) { msg += ': ' + event.username; }
|
||||
x += '<tr onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
||||
if (event.nodeid) {
|
||||
var node = getNodeFromId(event.nodeid);
|
||||
if (node != null) {
|
||||
icon = 'si' + node.icon;
|
||||
msg = '<a href=# onclick=\'gotoDevice("' + event.nodeid + '",10);haltEvent(event);\'>' + node.name + '</a> → ' + msg;
|
||||
}
|
||||
}
|
||||
if (event.username) {
|
||||
if ((userinfo.siteadmin & 2) && (event.userid)) {
|
||||
msg = '<a href=# onclick=\'gotoUser("' + encodeURIComponent(event.userid) + '");haltEvent(event);\'>' + event.username + '</a> → ' + msg;
|
||||
} else {
|
||||
msg = event.username + ' → ' + msg;
|
||||
}
|
||||
}
|
||||
x += '<tr onclick=showEventDetails(' + event.h + ',2) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
||||
}
|
||||
}
|
||||
if (dateHeader != null) x += '</table>';
|
||||
@ -7225,22 +7257,6 @@
|
||||
QH('p3events', x);
|
||||
}
|
||||
|
||||
function showDeleteAllEventsDialog() {
|
||||
if (xxdialogMode) return;
|
||||
var x = "Delete all events in the server event log?<br /><br />";
|
||||
x += "<label><input id=p3check type=checkbox onchange=validateDeleteAllEventsDialog() />Confirm</label>";
|
||||
setDialogMode(2, "Delete All Events", 3, showDeleteAllEventsDialogEx, x);
|
||||
validateDeleteAllEventsDialog();
|
||||
}
|
||||
|
||||
function validateDeleteAllEventsDialog() {
|
||||
QE('idx_dlgOkButton', Q('p3check').checked);
|
||||
}
|
||||
|
||||
function showDeleteAllEventsDialogEx(buttons, tag) {
|
||||
meshserver.send({ action: 'clearevents' });
|
||||
}
|
||||
|
||||
function refreshEvents() {
|
||||
meshserver.send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
|
||||
}
|
||||
@ -7902,23 +7918,35 @@
|
||||
function userEventsUpdate() {
|
||||
var x = '', dateHeader = null;
|
||||
for (var i in currentUserEvents) {
|
||||
var event = currentUserEvents[i];
|
||||
var time = new Date(event.time);
|
||||
if (printDate(time) != dateHeader) {
|
||||
if (dateHeader != null) x += '</table>';
|
||||
dateHeader = printDate(time);
|
||||
x += '<table style=width:100% cellpadding=0 cellspacing=0><tr><td class=DevSt>' + dateHeader + '</td></tr>';
|
||||
}
|
||||
var icon = 'si3';
|
||||
if (event.etype == 'user') icon = 'm2';
|
||||
if (event.etype == 'server') icon = 'si3';
|
||||
var event = currentUserEvents[i], time = new Date(event.time);
|
||||
if (event.msg) {
|
||||
if (event.h == null) { event.h = Math.random(); }
|
||||
if (printDate(time) != dateHeader) {
|
||||
if (dateHeader != null) x += '</table>';
|
||||
dateHeader = printDate(time);
|
||||
x += '<table class=p3eventsTable cellpadding=0 cellspacing=0><tr><td colspan=4 class=DevSt>' + dateHeader + '</td></tr>';
|
||||
}
|
||||
var icon = 'si3';
|
||||
if (event.etype == 'user') icon = 'm2';
|
||||
if (event.etype == 'server') icon = 'si3';
|
||||
|
||||
var msg = event.msg.split('(R)').join('®');
|
||||
if (event.username && event.username != userinfo.name) { msg += ': ' + event.username; }
|
||||
x += '<tr><td><div class=bar18 style=height:18px;width:100%;font-size:medium>';
|
||||
x += '<div style=float:left;height:18px;width:18px;background-color:white><div class=' + icon + ' style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>';
|
||||
x += '<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>';
|
||||
x += '<div style=font-size:14px><span style=width:300px>' + printTime(time) + ' - ' + msg + '</span></div></div></td></tr>';
|
||||
var msg = event.msg.split('(R)').join('®');
|
||||
if (event.nodeid) {
|
||||
var node = getNodeFromId(event.nodeid);
|
||||
if (node != null) {
|
||||
icon = 'si' + node.icon;
|
||||
msg = '<a href=# onclick=\'gotoDevice("' + event.nodeid + '",10);haltEvent(event);\'>' + node.name + '</a> → ' + msg;
|
||||
}
|
||||
}
|
||||
if (event.username && (event.username != currentUser.name)) {
|
||||
if ((userinfo.siteadmin & 2) && (event.userid)) {
|
||||
msg = '<a href=# onclick=\'gotoUser("' + encodeURIComponent(event.userid) + '");haltEvent(event);\'>' + event.username + '</a> → ' + msg;
|
||||
} else {
|
||||
msg = event.username + ' → ' + msg;
|
||||
}
|
||||
}
|
||||
x += '<tr onclick=showEventDetails(' + event.h + ',3) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
||||
}
|
||||
}
|
||||
if (dateHeader != null) x += '</table>';
|
||||
if (x == '') x = "<br><i>No Events Found</i><br><br>";
|
||||
@ -8516,6 +8544,7 @@
|
||||
//function addHtmlValue(t, v) { return '<div style=height:20px><div style=float:right;width:220px><b>' + v + '</b></div><div>' + t + '</div></div>'; }
|
||||
function addHtmlValue(t, v) { return '<table><td style=width:120px>' + t + '<td><b>' + v + '</b></table>'; }
|
||||
function addHtmlValue2(t, v) { return '<div><div style=display:inline-block;float:right>' + v + '</div><div style=display:inline-block>' + t + '</div></div>'; }
|
||||
function addHtmlValue3(t, v) { return '<div><b>' + t + '</b></div><div style=margin-left:16px>' + v + '</div>'; }
|
||||
function parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; }
|
||||
function focusTextBox(x) { setTimeout(function(){ Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); }
|
||||
function validateEmail(v) { var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailReg.test(v); } // New version
|
||||
|
File diff suppressed because one or more lines are too long
32
webserver.js
32
webserver.js
@ -319,7 +319,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (user.name != username) {
|
||||
user.name = username;
|
||||
obj.db.SetUser(user);
|
||||
var event = { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'Changed account display name to ' + username, domain: domain.id };
|
||||
var event = { etype: 'user', userid: userid, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'Changed account display name to ' + username, domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
|
||||
}
|
||||
@ -365,7 +365,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (usercount == 0) { user.siteadmin = 4294967295; /*if (domain.newaccounts === 2) { delete domain.newaccounts; }*/ } // If this is the first user, give the account site admin.
|
||||
obj.users[user._id] = user;
|
||||
obj.db.SetUser(user);
|
||||
var event = { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, name is ' + name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, name is ' + name, domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
|
||||
obj.parent.DispatchEvent(['*', 'server-users'], obj, event);
|
||||
return fn(null, user._id);
|
||||
@ -375,7 +375,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (user.name != username) {
|
||||
user.name = username;
|
||||
obj.db.SetUser(user);
|
||||
var event = { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'Changed account display name to ' + username, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'Changed account display name to ' + username, domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
|
||||
}
|
||||
@ -495,7 +495,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
// Destroy the user's session to log them out will be re-created next request
|
||||
if (req.session.userid) {
|
||||
var user = obj.users[req.session.userid];
|
||||
if (user != null) { obj.parent.DispatchEvent(['*'], obj, { etype: 'user', username: user.name, action: 'logout', msg: 'Account logout', domain: domain.id }); }
|
||||
if (user != null) { obj.parent.DispatchEvent(['*'], obj, { etype: 'user', userid: user._id, username: user.name, action: 'logout', msg: 'Account logout', domain: domain.id }); }
|
||||
}
|
||||
req.session = null;
|
||||
res.redirect(domain.url);
|
||||
@ -697,7 +697,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
// Notify account login
|
||||
var targets = ['*', 'server-users'];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
obj.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'login', msg: 'Account login', domain: domain.id });
|
||||
obj.parent.DispatchEvent(targets, obj, { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'login', msg: 'Account login', domain: domain.id });
|
||||
|
||||
// Regenerate session when signing in to prevent fixation
|
||||
//req.session.regenerate(function () {
|
||||
@ -824,7 +824,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
// Send the verification email
|
||||
if ((obj.parent.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap') && (obj.common.validateEmail(user.email, 1, 256) == true)) { obj.parent.mailserver.sendAccountCheckMail(domain, user.name, user.email); }
|
||||
}, 0);
|
||||
var event = { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, email is ' + req.body.email, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, email is ' + req.body.email, domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
|
||||
obj.parent.DispatchEvent(['*', 'server-users'], obj, event);
|
||||
}
|
||||
@ -886,7 +886,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
user.passchange = Math.floor(Date.now() / 1000);
|
||||
delete user.passtype;
|
||||
obj.db.SetUser(user);
|
||||
var event = { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'User password reset', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'User password reset', domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
obj.parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
|
||||
|
||||
@ -1030,7 +1030,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
obj.db.SetUser(user);
|
||||
|
||||
// Event the change
|
||||
var event = { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'Verified email of user ' + EscapeHtml(user.name) + ' (' + EscapeHtml(user.email) + ')', domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'Verified email of user ' + EscapeHtml(user.name) + ' (' + EscapeHtml(user.email) + ')', domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
obj.parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
|
||||
|
||||
@ -1065,7 +1065,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
obj.db.SetUser(userinfo);
|
||||
|
||||
// Event the change
|
||||
var event = { etype: 'user', username: userinfo.name, account: obj.CloneSafeUser(userinfo), action: 'accountchange', msg: 'Password reset for user ' + EscapeHtml(user.name), domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: userinfo.name, account: obj.CloneSafeUser(userinfo), action: 'accountchange', msg: 'Password reset for user ' + EscapeHtml(user.name), domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
obj.parent.DispatchEvent(['*', 'server-users', user._id], obj, event);
|
||||
|
||||
@ -1134,7 +1134,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (mesh.links[userid] != null) { delete mesh.links[userid]; obj.db.Set(obj.common.escapeLinksFieldName(mesh)); }
|
||||
// Notify mesh change
|
||||
var change = 'Removed user ' + user.name + ' from group ' + mesh.name;
|
||||
obj.parent.DispatchEvent(['*', mesh._id, user._id, userid], obj, { etype: 'mesh', username: user.name, userid: userid, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id });
|
||||
obj.parent.DispatchEvent(['*', mesh._id, user._id, userid], obj, { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1147,7 +1147,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
delete obj.users[user._id];
|
||||
req.session = null;
|
||||
res.redirect(domain.url + getQueryPortion(req));
|
||||
obj.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', username: user.name, action: 'accountremove', msg: 'Account removed', domain: domain.id });
|
||||
obj.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', userid: user._id, username: user.name, action: 'accountremove', msg: 'Account removed', domain: domain.id });
|
||||
} else {
|
||||
res.redirect(domain.url + getQueryPortion(req));
|
||||
}
|
||||
@ -1206,7 +1206,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
obj.db.SetUser(user);
|
||||
req.session.viewmode = 2;
|
||||
res.redirect(domain.url + getQueryPortion(req));
|
||||
obj.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', username: user.name, action: 'passchange', msg: 'Account password changed: ' + user.name, domain: domain.id });
|
||||
obj.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', userid: user._id, username: user.name, action: 'passchange', msg: 'Account password changed: ' + user.name, domain: domain.id });
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
@ -1291,7 +1291,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (usercount == 0) { user2.siteadmin = 4294967295; } // If this is the first user, give the account site admin.
|
||||
obj.users[req.session.userid] = user2;
|
||||
obj.db.SetUser(user2);
|
||||
var event = { etype: 'user', username: req.connection.user, account: obj.CloneSafeUser(user2), action: 'accountcreate', msg: 'Domain account created, user ' + req.connection.user, domain: domain.id };
|
||||
var event = { etype: 'user', userid: req.session.userid, username: req.connection.user, account: obj.CloneSafeUser(user2), action: 'accountcreate', msg: 'Domain account created, user ' + req.connection.user, domain: domain.id };
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
|
||||
obj.parent.DispatchEvent(['*', 'server-users'], obj, event);
|
||||
}
|
||||
@ -3311,7 +3311,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (u) {
|
||||
var targets = ['*', 'server-users'];
|
||||
if (u.groups) { for (var i in u.groups) { targets.push('server-users:' + i); } }
|
||||
obj.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', username: x[2], count: newcount, domain: x[1], nolog: 1, nopeers: 1 });
|
||||
obj.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', userid: userid, username: x[2], count: newcount, domain: x[1], nolog: 1, nopeers: 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3325,7 +3325,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (u) {
|
||||
var targets = ['*', 'server-users'];
|
||||
if (u.groups) { for (var i in u.groups) { targets.push('server-users:' + i); } }
|
||||
obj.parent.DispatchEvent(['*'], obj, { action: 'wssessioncount', username: x[2], count: 0, domain: x[1], nolog: 1, nopeers: 1 })
|
||||
obj.parent.DispatchEvent(['*'], obj, { action: 'wssessioncount', userid: userid, username: x[2], count: 0, domain: x[1], nolog: 1, nopeers: 1 })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3350,7 +3350,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
if (u) {
|
||||
var targets = ['*', 'server-users'];
|
||||
if (u.groups) { for (var i in u.groups) { targets.push('server-users:' + i); } }
|
||||
obj.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', username: x[2], count: newcount, domain: x[1], nolog: 1, nopeers: 1 });
|
||||
obj.parent.DispatchEvent(targets, obj, { action: 'wssessioncount', userid: userid, username: x[2], count: newcount, domain: x[1], nolog: 1, nopeers: 1 });
|
||||
obj.sessionsCount[userid] = newcount;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user