Updated user management and MeshAgent

This commit is contained in:
Ylian Saint-Hilaire 2018-04-17 19:00:31 -07:00
parent 17e5000ef8
commit b6b2706d19
15 changed files with 79 additions and 44 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -583,7 +583,7 @@ function createMeshCore(agent) {
if (this.desktop.kvm.connectionCount == 0) { this.httprequest.desktop.kvm.end(); } if (this.desktop.kvm.connectionCount == 0) { this.httprequest.desktop.kvm.end(); }
}; };
if (this.httprequest.desktop.kvm.hasOwnProperty("connectionCount")) { this.httprequest.desktop.kvm.connectionCount++; } else { this.httprequest.desktop.kvm.connectionCount = 1; } if (this.httprequest.desktop.kvm.hasOwnProperty("connectionCount")) { this.httprequest.desktop.kvm.connectionCount++; } else { this.httprequest.desktop.kvm.connectionCount = 1; }
this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. (****************)
this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text. this.httprequest.desktop.kvm.pipe(this, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
this.removeAllListeners('data'); this.removeAllListeners('data');
this.on('data', onTunnelControlData); this.on('data', onTunnelControlData);
@ -789,7 +789,7 @@ function createMeshCore(agent) {
} else if (ws.httprequest.protocol == 2) { // Desktop } else if (ws.httprequest.protocol == 2) { // Desktop
// Switch the user input from websocket to webrtc at this point. // Switch the user input from websocket to webrtc at this point.
ws.unpipe(ws.httprequest.desktop.kvm); ws.unpipe(ws.httprequest.desktop.kvm);
try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1 }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text. try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
ws.resume(); // Resume the websocket to keep receiving control data ws.resume(); // Resume the websocket to keep receiving control data
} }
ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point. ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.

2
db.js
View File

@ -99,7 +99,7 @@ module.exports.CreateDB = function (args, datapath) {
obj.StoreEvent = function (ids, source, event) { obj.file.insert(event); } obj.StoreEvent = function (ids, source, event) { obj.file.insert(event); }
obj.GetEvents = function (ids, domain, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }, func) } } obj.GetEvents = function (ids, domain, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }, func) } }
obj.GetEventsWithLimit = function (ids, domain, limit, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit, func); } } obj.GetEventsWithLimit = function (ids, domain, limit, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit, func); } }
obj.GetNodeEventsWithLimit = function (nodeid, domain, limit, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, nodeid: nodeid }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit, func); } } obj.GetNodeEventsWithLimit = function (nodeid, domain, limit, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, nodeid: nodeid }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).exec(func); } else { obj.file.find({ type: 'event', domain: domain, nodeid: nodeid }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit, func); } }
obj.RemoveMesh = function (id) { obj.file.remove({ mesh: id }, { multi: true }); obj.file.remove({ _id: id }); obj.file.remove({ _id: 'nt' + id }); } obj.RemoveMesh = function (id) { obj.file.remove({ mesh: id }, { multi: true }); obj.file.remove({ _id: id }); obj.file.remove({ _id: 'nt' + id }); }
obj.RemoveAllEvents = function (domain) { obj.file.remove({ type: 'event', domain: domain }, { multi: true }); } obj.RemoveAllEvents = function (domain) { obj.file.remove({ type: 'event', domain: domain }, { multi: true }); }
obj.MakeSiteAdmin = function (username, domain) { obj.Get('user/' + domain + '/' + username, function (err, docs) { if (docs.length == 1) { docs[0].siteadmin = 0xFFFFFFFF; obj.Set(docs[0]); } }); } obj.MakeSiteAdmin = function (username, domain) { obj.Get('user/' + domain + '/' + username, function (err, docs) { if (docs.length == 1) { docs[0].siteadmin = 0xFFFFFFFF; obj.Set(docs[0]); } }); }

View File

@ -366,7 +366,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
delete userinfo.domain; delete userinfo.domain;
delete userinfo.subscriptions; delete userinfo.subscriptions;
delete userinfo.passtype; delete userinfo.passtype;
obj.parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: userinfo.name, account: userinfo, action: 'accountchange', msg: 'Changed email of user ' + userinfo.name + ' from ' + oldemail + ' to ' + user.email, domain: domain.id }) var message = { etype: 'user', username: userinfo.name, account: userinfo, action: 'accountchange', domain: domain.id };
if (oldemail != null) {
message.msg = 'Changed email of user ' + userinfo.name + ' from ' + oldemail + ' to ' + user.email;
} else {
message.msg = 'Set email of user ' + userinfo.name + ' to ' + user.email;
}
obj.parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, message);
} }
}); });
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.1.6-m", "version": "0.1.6-q",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -82,12 +82,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
} }
// Close the WebRTC connection, should be called if a problem occurs during WebRTC setup. // Close the WebRTC connection, should be called if a problem occurs during WebRTC setup.
obj.xxCloseWebRTC = function () { obj.xxCloseWebRTC = function () { obj.Stop(); }
sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"close\"}");
if (obj.webchannel != null) { try { obj.webchannel.close(); } catch (e) { } obj.webchannel = null; }
if (obj.webrtc != null) { try { obj.webrtc.close(); } catch (e) { } obj.webrtc = null; }
obj.webRtcActive = false;
}
obj.xxOnMessage = function (e) { obj.xxOnMessage = function (e) {
//if (obj.debugmode == 1) { console.log('Recv', e.data); } //if (obj.debugmode == 1) { console.log('Recv', e.data); }
@ -213,9 +208,14 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort) {
obj.Stop = function (x) { obj.Stop = function (x) {
if (obj.debugmode == 1) { console.log('stop', x); } if (obj.debugmode == 1) { console.log('stop', x); }
// Close WebRTC
if (obj.webchannel != null) { try { obj.webchannel.close(); } catch (e) { } obj.webchannel = null; }
if (obj.webrtc != null) { try { obj.webrtc.close(); } catch (e) { } obj.webrtc = null; }
obj.webRtcActive = false;
//obj.debug("Agent Redir Socket Stopped"); //obj.debug("Agent Redir Socket Stopped");
obj.connectstate = -1; obj.connectstate = -1;
obj.xxCloseWebRTC();
if (obj.socket != null) { if (obj.socket != null) {
try { if (obj.socket.readyState == 1) { sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"close\"}"); obj.socket.close(); } } catch (e) { } try { if (obj.socket.readyState == 1) { sendCtrlMsg("{\"ctrlChannel\":\"102938\",\"type\":\"close\"}"); obj.socket.close(); } } catch (e) { }
obj.socket = null; obj.socket = null;

View File

@ -780,7 +780,7 @@
// Check if we are in debug mode // Check if we are in debug mode
args = parseUriArgs(); args = parseUriArgs();
debugmode = (args.debug == 1); debugmode = (args.debug == 1);
if (args.webrtc) { attemptWebRTC = (args.webrtc == 1); } if (args.webrtc != null) { attemptWebRTC = (args.webrtc == 1); }
QV('p13AutoConnect', debugmode); // Files QV('p13AutoConnect', debugmode); // Files
QV('autoconnectbutton2', debugmode); // Terminal QV('autoconnectbutton2', debugmode); // Terminal
QV('autoconnectbutton1', debugmode); // Desktop QV('autoconnectbutton1', debugmode); // Desktop
@ -2824,7 +2824,7 @@
} }
// Attribute: Mesh Agent Tag // Attribute: Mesh Agent Tag
if ((node.agent != null) && (node.agent.tag != null)) { if ((node.agent != null) && (node.agent.tag != null) && (node.agent.tag != 'mailto:')) {
var tag = EscapeHtml(node.agent.tag); var tag = EscapeHtml(node.agent.tag);
if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; } if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; }
x += addDeviceAttribute('Agent Tag', tag); x += addDeviceAttribute('Agent Tag', tag);
@ -4991,36 +4991,25 @@
sortedUserIds.sort(); sortedUserIds.sort();
// Display the users using the sorted list // Display the users using the sorted list
var x = '<table style=width:100% cellpadding=0 cellspacing=0>'; var x = '<table style=width:100% cellpadding=0 cellspacing=0>', addHeader = true;
// Online users
for (var i in sortedUserIds) { for (var i in sortedUserIds) {
var user = users[sortedUserIds[i]], icon = 'm2', msg = '', self = (user.name != userinfo.name); var user = users[sortedUserIds[i]], sessions = null;
if (wssessions != null && wssessions[user._id]) { if (wssessions != null) { sessions = wssessions[user._id]; }
if (self) { msg += "<a onclick=showUserAlertDialog(event,\"" + encodeURIComponent(user._id) + "\")>"; } if (sessions != null) {
var sessions = wssessions[user._id]; if (addHeader) { x += '<tr><td style="border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px">Online Users</td></tr>'; addHeader = false; }
if (sessions == 1) { msg += '1 active session'; } else { msg += sessions + ' active sessions'; } x += addUserHtml(user, sessions);
if (self) { msg += "</a>"; }
} }
if (msg != '') msg += ', ';
if (self) { msg += "<a onclick=showUserAdminDialog(event,\"" + encodeURIComponent(user._id) + "\")>"; }
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { msg += "Locked, "; }
if ((user.siteadmin == null) || (user.siteadmin == 0) || (user.siteadmin == 32)) {
msg += "User";
} else if (user.siteadmin == 8) {
msg += "User with server files";
} else if (user.siteadmin == 0xFFFFFFFF) {
msg += "Full Admin";
} else {
msg += "Partial Admin";
} }
if ((user.quota != null) && ((user.siteadmin & 8) != 0)) { msg += ", " + (user.quota / 1024) + " k"; } addHeader = true;
if (self) { msg += "</a>"; } // Offline users
var username = EscapeHtml(user.name); for (var i in sortedUserIds) {
if (user.email != null) { username += ', <a onclick=doemail(event,\"' + user.email + '\")>' + user.email + '</a>' + (((serverinfo.emailcheck == true) && (user.emailVerified != true))?' (unverified)':''); } var user = users[sortedUserIds[i]], sessions = null;
x += '<tr><td style=cursor:pointer onclick=gotoUser(\"' + encodeURIComponent(user._id) + '\")>'; if (wssessions != null) { sessions = wssessions[user._id]; }
x += '<div class=bar style=height:24px;width:100%;font-size:medium>'; if (sessions == null) {
x += '<div style=float:left;height:24px;width:24px;background-color:white><div class=' + icon + ' style=width:16px;margin-top:4px;margin-left:2px;height:16px></div></div>'; if (addHeader) { x += '<tr><td style="border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px">Offline Users</td></tr>'; addHeader = false; }
x += '<div class=g1 style=height:24px;float:left></div><div class=g2 style=height:24px;float:right></div>'; x += addUserHtml(user, sessions);
x += '<div><span>' + username + '</span><span style=float:right>' + msg + '</span></div></div></td></tr>'; }
} }
x += '</table>'; x += '</table>';
QH('p3users', x); QH('p3users', x);
@ -5029,6 +5018,43 @@
if ((currentUser != null) && (xxcurrentView == 30)) { gotoUser(encodeURIComponent(currentUser._id),true); } if ((currentUser != null) && (xxcurrentView == 30)) { gotoUser(encodeURIComponent(currentUser._id),true); }
} }
function addUserHtml(user, sessions) {
var x = '', gray = ' gray', icon = 'm2', msg = '', self = (user.name != userinfo.name);
if (sessions != null) {
gray = '';
if (self) { msg += "<a onclick=showUserAlertDialog(event,\"" + encodeURIComponent(user._id) + "\")>"; }
if (sessions == 1) { msg += '1 active session'; } else { msg += sessions + ' active sessions'; }
if (self) { msg += "</a>"; }
} else {
if (user.login) { msg += '<span title="Last login: ' + new Date(user.login).toLocaleString() + '">' + new Date(user.login).toLocaleDateString() + '</span>'; }
}
if (msg != '') msg += ', ';
if (self) { msg += "<a onclick=showUserAdminDialog(event,\"" + encodeURIComponent(user._id) + "\")>"; }
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { msg += "Locked, "; }
msg += "<span title='Server Permissions'>";
if ((user.siteadmin == null) || (user.siteadmin == 0) || (user.siteadmin == 32)) {
msg += "User";
} else if (user.siteadmin == 8) {
msg += "User with server files";
} else if (user.siteadmin == 0xFFFFFFFF) {
msg += "Administrator";
} else {
msg += "Partial";
}
msg += "</span>";
if ((user.quota != null) && ((user.siteadmin & 8) != 0)) { msg += ", " + (user.quota / 1024) + " k"; }
if (self) { msg += "</a>"; }
var username = EscapeHtml(user.name), emailVerified = '';
if (serverinfo.emailcheck == true) { emailVerified = ((user.emailVerified != true)?' <b style=color:red title="Email is not verified">&#x1F5F4</b>':' <b style=color:green title="Email is verified">&#x1F5F8</b>'); }
if (user.email != null) { username += ', <a onclick=doemail(event,\"' + user.email + '\")>' + user.email + '</a>' + emailVerified; }
x += '<tr><td style=cursor:pointer onclick=gotoUser(\"' + encodeURIComponent(user._id) + '\")>';
x += '<div class=bar style=height:24px;width:100%;font-size:medium>';
x += '<div style=float:left;height:24px;width:24px;background-color:white><div class="' + icon + gray + '" style=width:16px;margin-top:4px;margin-left:2px;height:16px></div></div>';
x += '<div class=g1 style=height:24px;float:left></div><div class=g2 style=height:24px;float:right></div>';
x += '<div><span>' + username + '</span><span style=float:right>' + msg + '</span></div></div></td></tr>';
return x;
}
function showUserAlertDialog(e, userid) { function showUserAlertDialog(e, userid) {
if (xxdialogMode) return; if (xxdialogMode) return;
haltEvent(e); haltEvent(e);
@ -5139,9 +5165,12 @@
QH('p30userName', user.name); QH('p30userName', user.name);
QH('p31userName', user.name); QH('p31userName', user.name);
var self = (user.name == userinfo.name), activeSessions = 0; var self = (user.name == userinfo.name), activeSessions = 0;
if (wssessions != null && wssessions[user._id]) { activeSessions = wssessions[user._id]; } if (wssessions != null && wssessions[user._id]) { activeSessions = wssessions[user._id]; }
// Change user grayscale
Q('MainUserImage').classList.remove('gray');
if (activeSessions == 0) { Q('MainUserImage').classList.add('gray'); }
// Server permissions // Server permissions
var msg = ''; var msg = '';
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { msg += "Locked account, "; } if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { msg += "Locked account, "; }
@ -5150,8 +5179,8 @@
// Show user attributes // Show user attributes
var x = '<div style=min-height:80px><table style=width:100%>'; var x = '<div style=min-height:80px><table style=width:100%>';
var email = user.email?EscapeHtml(user.email):'<i>Not set</i>', everify = ''; var email = user.email?EscapeHtml(user.email):'<i>Not set</i>', everify = '';
if (serverinfo.emailcheck) { everify = ((user.emailVerified == true)?'':', Unverified'); } if (serverinfo.emailcheck) { everify = ((user.emailVerified == true)?'<b style=color:green;cursor:pointer title="Email is verified">&#x1F5F8</b> ':'<b style=color:red;cursor:pointer title="Email not verified">&#x1F5F4</b> '); }
x += addDeviceAttribute('Email', "<a style=cursor:pointer onclick=p30showUserEmailChangeDialog(event,\"" + userid + "\")>" + email + everify + '</a> <a style=cursor:pointer onclick=doemail(event,\"' + user.email + '\")><img src="images/link1.png" /></a>'); x += addDeviceAttribute('Email', everify + "<a style=cursor:pointer onclick=p30showUserEmailChangeDialog(event,\"" + userid + "\")>" + email + '</a> <a style=cursor:pointer onclick=doemail(event,\"' + user.email + '\")><img src="images/link1.png" /></a>');
x += addDeviceAttribute('Server Rights', "<a style=cursor:pointer onclick=showUserAdminDialog(event,\"" + userid + "\")>" + msg + "</a>"); x += addDeviceAttribute('Server Rights', "<a style=cursor:pointer onclick=showUserAdminDialog(event,\"" + userid + "\")>" + msg + "</a>");
if (user.quota) x += addDeviceAttribute('Server Quota', EscapeHtml(parseInt(user.quota) / 1024) + ' k'); if (user.quota) x += addDeviceAttribute('Server Quota', EscapeHtml(parseInt(user.quota) / 1024) + ' k');
x += addDeviceAttribute('Creation', new Date(user.creation).toLocaleString()); x += addDeviceAttribute('Creation', new Date(user.creation).toLocaleString());