From 1eeb7646574b583ca4d0586a91c7e22218047db7 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Wed, 1 Apr 2020 13:15:14 -0700 Subject: [PATCH] Improved MeshCtrl.js --- meshctrl.js | 91 ++++++++++++++++++++++++++++++++++++++-- meshuser.js | 38 ++++++++++++++--- package.json | 2 +- translate/translate.json | 2 +- views/default.handlebars | 16 ++++--- 5 files changed, 132 insertions(+), 17 deletions(-) diff --git a/meshctrl.js b/meshctrl.js index f99141ff..fb2cf9f2 100644 --- a/meshctrl.js +++ b/meshctrl.js @@ -3,7 +3,7 @@ const crypto = require('crypto'); var settings = {}; const args = require('minimist')(process.argv.slice(2)); -const possibleCommands = ['listusers', 'listdevicegroups', 'listdevices', 'listusersofdevicegroup', 'serverinfo', 'userinfo', 'adduser', 'removeuser', 'adddevicegroup', 'removedevicegroup', 'broadcast', 'showevents', 'addusertodevicegroup', 'removeuserfromdevicegroup', 'sendinviteemail', 'generateinvitelink', 'config']; +const possibleCommands = ['listusers', 'listdevicegroups', 'listdevices', 'listusersofdevicegroup', 'serverinfo', 'userinfo', 'adduser', 'removeuser', 'adddevicegroup', 'removedevicegroup', 'broadcast', 'showevents', 'addusertodevicegroup', 'removeuserfromdevicegroup', 'addusertodevice', 'removeuserfromdevice', 'sendinviteemail', 'generateinvitelink', 'config']; //console.log(args); if (args['_'].length == 0) { @@ -25,6 +25,8 @@ if (args['_'].length == 0) { console.log(" RemoveDeviceGroup - Delete a device group."); console.log(" AddUserToDeviceGroup - Add a user to a device group."); console.log(" RemoveUserFromDeviceGroup - Remove a user from a device group."); + console.log(" AddUserToDevice - Add a user to a device."); + console.log(" RemoveUserFromDevice - Remove a user from a device."); console.log(" SendInviteEmail - Send an agent install invitation email."); console.log(" GenerateInviteLink - Create an invitation link."); console.log(" Broadcast - Display a message to all online users."); @@ -68,6 +70,18 @@ if (args['_'].length == 0) { else { ok = true; } break; } + case 'addusertodevice': { + if (args.userid == null) { console.log("Add user to device missing useid, use --userid [userid]"); } + else if (args.id == null) { console.log("Add user to device missing device id, use --id [deviceid]"); } + else { ok = true; } + break; + } + case 'removeuserfromdevice': { + if (args.userid == null) { console.log("Remove user from device missing useid, use --userid [userid]"); } + else if (args.id == null) { console.log("Remove user from device missing device id, use --id [deviceid]"); } + else { ok = true; } + break; + } case 'adddevicegroup': { if (args.name == null) { console.log("Message group name, use --name [name]"); } else { ok = true; } @@ -262,6 +276,14 @@ if (args['_'].length == 0) { console.log(" --noterminal - Hide the terminal tab from this user."); console.log(" --nofiles - Hide the files tab from this user."); console.log(" --noamt - Hide the Intel AMT tab from this user."); + console.log(" --limitedevents - User can only see his own events."); + console.log(" --chatnotify - Allow chat and notification options."); + console.log(" --uninstall - Allow remote uninstall of the agent."); + if (args.limiteddesktop) { meshrights |= 4096; } + if (args.limitedevents) { meshrights |= 8192; } + if (args.chatnotify) { meshrights |= 16384; } + if (args.uninstall) { meshrights |= 32768; } + break; } case 'removeuserfromdevicegroup': { @@ -272,11 +294,43 @@ if (args['_'].length == 0) { console.log(" --userid [userid] - The user identifier."); break; } + case 'addusertodevice': { + console.log("Add a user to a device, Example usages:\r\n"); + console.log(" MeshCtrl AddUserToDevice --id deviceid --userid userid --fullrights"); + console.log(" MeshCtrl AddUserToDevice --id deviceid --userid userid --remotecontrol"); + console.log("\r\nRequired arguments:\r\n"); + console.log(" --id [deviceid] - The device identifier."); + console.log(" --userid [userid] - The user identifier."); + console.log("\r\nOptional arguments:\r\n"); + console.log(" --fullrights - Allow full rights over this device."); + console.log(" --remotecontrol - Allow device remote control operations."); + console.log(" --agentconsole - Allow agent console operations."); + console.log(" --serverfiles - Allow access to group server files."); + console.log(" --wakedevices - Allow device wake operation."); + console.log(" --notes - Allow editing of device notes."); + console.log(" --desktopviewonly - Restrict user to view-only remote desktop."); + console.log(" --limiteddesktop - Limit remote desktop keys."); + console.log(" --noterminal - Hide the terminal tab from this user."); + console.log(" --nofiles - Hide the files tab from this user."); + console.log(" --noamt - Hide the Intel AMT tab from this user."); + console.log(" --limitedevents - User can only see his own events."); + console.log(" --chatnotify - Allow chat and notification options."); + console.log(" --uninstall - Allow remote uninstall of the agent."); + break; + } + case 'removeuserfromdevice': { + console.log("Remove a user from a device, Example usages:\r\n"); + console.log(" MeshCtrl RemoveuserFromDeviceGroup --id deviceid --userid userid"); + console.log("\r\nRequired arguments:\r\n"); + console.log(" --id [deviceid] - The device identifier."); + console.log(" --userid [userid] - The user identifier."); + break; + } case 'broadcast': { console.log("Display a message to all logged in users, Example usages:\r\n"); console.log(" MeshCtrl Broadcast --msg \"This is a test\""); console.log("\r\nRequired arguments:\r\n"); - console.log(" --msg [message] - Message to display."); + console.log(" --msg [message] - Message to display."); break; } default: { @@ -532,6 +586,9 @@ function serverConnect() { if (args.nofiles) { meshrights |= 1024; } if (args.noamt) { meshrights |= 2048; } if (args.limiteddesktop) { meshrights |= 4096; } + if (args.limitedevents) { meshrights |= 8192; } + if (args.chatnotify) { meshrights |= 16384; } + if (args.uninstall) { meshrights |= 32768; } var op = { action: 'addmeshuser', meshid: args.id, usernames: [args.userid], meshadmin: meshrights, responseid: 'meshctrl' }; ws.send(JSON.stringify(op)); break; @@ -541,13 +598,38 @@ function serverConnect() { ws.send(JSON.stringify(op)); break; } + case 'addusertodevice': { + var meshrights = 0; + if (args.fullrights) { meshrights = (8 + 16 + 32 + 64 + 128 + 16384 + 32768); } + if (args.remotecontrol) { meshrights |= 8; } + if (args.agentconsole) { meshrights |= 16; } + if (args.serverfiles) { meshrights |= 32; } + if (args.wakedevices) { meshrights |= 64; } + if (args.notes) { meshrights |= 128; } + if (args.desktopviewonly) { meshrights |= 256; } + if (args.noterminal) { meshrights |= 512; } + if (args.nofiles) { meshrights |= 1024; } + if (args.noamt) { meshrights |= 2048; } + if (args.limiteddesktop) { meshrights |= 4096; } + if (args.limitedevents) { meshrights |= 8192; } + if (args.chatnotify) { meshrights |= 16384; } + if (args.uninstall) { meshrights |= 32768; } + var op = { action: 'adddeviceuser', nodeid: args.id, usernames: [args.userid], rights: meshrights, responseid: 'meshctrl' }; + ws.send(JSON.stringify(op)); + break; + } + case 'removeuserfromdevice': { + var op = { action: 'adddeviceuser', nodeid: args.id, usernames: [args.userid], rights: 0, responseid: 'meshctrl' }; + ws.send(JSON.stringify(op)); + break; + } case 'sendinviteemail': { - var op = { action: "inviteAgent", meshid: args.id, email: args.email, name: "", os: "0", responseid: 'meshctrl' } + var op = { action: 'inviteAgent', meshid: args.id, email: args.email, name: '', os: '0', responseid: 'meshctrl' } ws.send(JSON.stringify(op)); break; } case 'generateinvitelink': { - var op = { action: "createInviteLink", meshid: args.id, expire: args.hours, flags: 0, responseid: 'meshctrl' } + var op = { action: 'createInviteLink', meshid: args.id, expire: args.hours, flags: 0, responseid: 'meshctrl' } ws.send(JSON.stringify(op)); break; } @@ -604,6 +686,7 @@ function serverConnect() { case 'addmeshuser': // case 'removemeshuser': // case 'inviteAgent': // + case 'adddeviceuser': // case 'userbroadcast': { // BROADCAST if (data.responseid == 'meshctrl') { if (data.meshid) { console.log(data.result, data.meshid); } diff --git a/meshuser.js b/meshuser.js index 3c4a4592..2af7aa83 100644 --- a/meshuser.js +++ b/meshuser.js @@ -2392,16 +2392,22 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use for (var i in command.usernames) { command.userids.push('user/' + domain.id + '/' + command.usernames[i].toLowerCase()); } } - var unknownUsers = [], removedCount = 0, failCount = 0; + var unknownUsers = [], successCount = 0, failCount = 0, msgs = []; for (var i in command.userids) { // Check if the user exists var newuserid = command.userids[i], newuser = null; if (newuserid.startsWith('user/')) { newuser = parent.users[newuserid]; } else if (newuserid.startsWith('ugrp/')) { newuser = parent.userGroups[newuserid]; } + // Search for a user name in that windows domain is the username starts with *\ + if ((newuser == null) && (newuserid.startsWith('user/' + domain.id + '/*\\')) == true) { + var search = newuserid.split('/')[2].substring(1); + for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == domain.id)) { newuser = parent.users[i]; command.userids[i] = newuserid = parent.users[i]._id; break; } } + } + if (newuser != null) { // Can't add or modify self - if (newuserid == obj.user._id) { continue; } + if (newuserid == obj.user._id) { errors.push("Can't add self."); continue; } // Add mesh to user or user group if (newuser.links == null) { newuser.links = {}; } @@ -2432,19 +2438,23 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use var event = { etype: 'mesh', username: newuser.name, userid: user._id, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Added user ' + newuser.name + ' to mesh ' + mesh.name, domain: domain.id, invite: mesh.invite }; 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, newuserid], obj, event); - removedCount++; + msgs.push("Added user " + newuser._id.split('/')[2]); + successCount++; } else { - unknownUsers.push(command.userids[i]); + msgs.push("Unknown user " + newuserid._id.split('/')[2]); + unknownUsers.push(newuserid); failCount++; } } + if ((successCount == 0) && (failCount == 0)) { msgs.push("Nothing done"); } + if (unknownUsers.length > 0) { // Send error back, user not found. displayNotificationMessage('User' + ((unknownUsers.length > 1) ? 's' : '') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', 'Device Group', 'ServerNotify'); } - if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: 'ok', removed: removedCount, failed: failCount })); } catch (ex) { } } + if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: msgs.join(', '), success: successCount, failed: failCount })); } catch (ex) { } } break; } case 'adddeviceuser': { @@ -2456,7 +2466,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use else if ((command.rights & 7) != 0) { err = 'Invalid rights'; } // EDITMESH, MANAGEUSERS or MANAGECOMPUTERS rights can't be assigned to a user to device link else if ((common.validateStrArray(command.usernames, 1, 64) == false) && (common.validateStrArray(command.userids, 1, 128) == false)) { err = 'Invalid usernames'; } // Username is between 1 and 64 characters else { - if (command.nodeid.indexOf('/') == -1) { command.nodeid = 'node/' + domain.id + '/' + command.meshid; } + if (command.nodeid.indexOf('/') == -1) { command.nodeid = 'node/' + domain.id + '/' + command.nodeid; } else if ((command.nodeid.split('/').length != 3) || (command.nodeid.split('/')[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain } } catch (ex) { err = 'Validation exception: ' + ex; } @@ -2487,6 +2497,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use for (var i in command.userids) { var newuserid = command.userids[i]; var newuser = parent.users[newuserid]; + + // Search for a user name in that windows domain is the username starts with *\ + if ((newuser == null) && (newuserid.startsWith('user/' + domain.id + '/*\\')) == true) { + var search = newuserid.split('/')[2].substring(1); + for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == domain.id)) { newuser = parent.users[i]; command.userids[i] = newuserid = newuser._id; break; } } + } + if (newuser != null) { // Add this user to the dispatch target list dispatchTargets.push(newuser._id); @@ -2537,6 +2554,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 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(dispatchTargets, obj, event); } + + if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'adddeviceuser', responseid: command.responseid, result: 'ok' })); } catch (ex) { } } }); break; @@ -2569,6 +2588,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use var deluserid = command.userid, deluser = null; if (deluserid.startsWith('user/')) { deluser = parent.users[deluserid]; } else if (deluserid.startsWith('ugrp/')) { deluser = parent.userGroups[deluserid]; } + + // Search for a user name in that windows domain is the username starts with *\ + if ((deluser == null) && (deluserid.startsWith('user/' + domain.id + '/*\\')) == true) { + var search = deluserid.split('/')[2].substring(1); + for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == domain.id)) { deluser = parent.users[i]; command.userid = deluserid = deluser._id; break; } } + } + if (deluser != null) { // Remove mesh from user if (deluser.links != null && deluser.links[command.meshid] != null) { diff --git a/package.json b/package.json index 85104b66..2faeee99 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.5.0-x", + "version": "0.5.0-y", "keywords": [ "Remote Management", "Intel AMT", diff --git a/translate/translate.json b/translate/translate.json index bf53f2eb..b461137a 100644 --- a/translate/translate.json +++ b/translate/translate.json @@ -27870,4 +27870,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/views/default.handlebars b/views/default.handlebars index f3aef181..d3758dc0 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -3125,7 +3125,9 @@ } // If there is nothing to display, explain the problem + var viewNothing = false; if ((r == '') && (nodes.length > 0) && (Q('SearchInput').value != '')) { + viewNothing = true; if (sort == 3) { r = '
' + "No devices are included in any groups, click on a device\'s \"Groups\" to add to a group." + '
'; } else { @@ -3172,7 +3174,7 @@ } } - if (r != '') { + if ((r != '') && (viewNothing == false)) { r += ''; if (view == 2) { // This height of 1 div at the end to fix a problem in Linux firefox browsers @@ -9587,20 +9589,24 @@ if ((user.otpsecret > 0) || (user.otphkeys > 0)) { username += ' '; } if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { username += ' '; } - x += ''; + x += ''; x += '
'; + x += '
'; x += '
'; - x += '
'; + x += '
'; x += '
' + username + '' + msg + '
' + groups + '' + lastAccess + '' + permissions; return x; } // Highlights the user being hovered function userMouseHover(element, over) { - var e = element.children[0].children[0]; + var e = element.children[0].children[0].children[1]; e.children[1].classList.remove('g1s'); e.children[2].classList.remove('g2s'); - if (over == 1) { e.children[1].classList.add('g1s'); e.children[2].classList.add('g2s'); } + if (over == 1) { + e.children[1].classList.add('g1s'); + e.children[2].classList.add('g2s'); + } element.children[0].children[0].style['background-color'] = ((over == 0) ? '#c9c9c9' : '#b9b9b9'); }