diff --git a/meshagent.js b/meshagent.js index 99b97857..2a2646d1 100644 --- a/meshagent.js +++ b/meshagent.js @@ -637,13 +637,15 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { obj.connectTime = Date.now(); db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); - // Device already exists, look if changes has occured + // Device already exists, look if changes have occured var changes = [], change = 0, log = 0; if (device.agent == null) { device.agent = { ver: obj.agentInfo.agentVersion, id: obj.agentInfo.agentId, caps: obj.agentInfo.capabilities }; change = 1; } if (device.rname != obj.agentInfo.computerName) { device.rname = obj.agentInfo.computerName; change = 1; changes.push('computer name'); } if (device.agent.ver != obj.agentInfo.agentVersion) { device.agent.ver = obj.agentInfo.agentVersion; change = 1; changes.push('agent version'); } if (device.agent.id != obj.agentInfo.agentId) { device.agent.id = obj.agentInfo.agentId; change = 1; changes.push('agent type'); } if ((device.agent.caps & 24) != (obj.agentInfo.capabilities & 24)) { device.agent.caps = obj.agentInfo.capabilities; change = 1; changes.push('agent capabilities'); } // If agent console or javascript support changes, update capabilities + if (mesh.flags && (mesh.flags & 2) && (device.name != obj.agentInfo.computerName)) { device.name = obj.agentInfo.computerName; change = 1; } // We want the server name to be sync'ed to the hostname + if (change == 1) { db.Set(device); diff --git a/meshuser.js b/meshuser.js index 01d72352..d434ba8c 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1040,6 +1040,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } case 'createmesh': { + // Check if we have new group restriction + if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 64) != 0)) break; + // In some situations, we need a verified email address to create a device group. if ((parent.parent.mailserver != null) && (domain.auth != 'sspi') && (user.emailVerified !== true) && (user.siteadmin != 0xFFFFFFFF)) return; // User must verify it's email first. diff --git a/package.json b/package.json index fbf3f23a..95fe0a6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.3.1-w", + "version": "0.3.1-x", "keywords": [ "Remote Management", "Intel AMT", diff --git a/public/scripts/amt-terminal-0.0.2.js b/public/scripts/amt-terminal-0.0.2.js index a6d831da..b65f7e37 100644 --- a/public/scripts/amt-terminal-0.0.2.js +++ b/public/scripts/amt-terminal-0.0.2.js @@ -42,6 +42,7 @@ var CreateAmtRemoteTerminal = function (divid) { var _backSpaceErase = false; var _cursorVisible = true; var _scrollRegion = [0, 24]; + var _altKeypadMode = false; obj.Start = function () { } @@ -101,10 +102,12 @@ var CreateAmtRemoteTerminal = function (divid) { break; case '=': // Set alternate keypad mode + _altKeypadMode = true; _termstate = 0; break; case '>': // Set numeric keypad mode + _altKeypadMode = false; _termstate = 0; break; default: @@ -115,12 +118,8 @@ var CreateAmtRemoteTerminal = function (divid) { case 2: if (b >= '0' && b <= '9') { // This is a number - if (!_escNumber[_escNumberPtr]) { - _escNumber[_escNumberPtr] = (b - '0'); - } - else { - _escNumber[_escNumberPtr] = ((_escNumber[_escNumberPtr] * 10) + (b - '0')); - } + if (!_escNumber[_escNumberPtr]) { _escNumber[_escNumberPtr] = (b - '0'); } + else { _escNumber[_escNumberPtr] = ((_escNumber[_escNumberPtr] * 10) + (b - '0')); } break; } else if (b == ';') { // New number @@ -201,12 +200,23 @@ var CreateAmtRemoteTerminal = function (divid) { if (_termx > 79) _termx = 79; } break; - case 'P': // Move the rest of the line left, this is a guess as there is no documentation about this code (???) - if (argslen == 1) { - for (i = _termx; i < (obj.width - args[0]) ; i++) { - _tscreen[_termy][i] = _tscreen[_termy][i + args[0]] - _scratt[_termy][i] = _scratt[_termy][i + args[0]]; - } + case 'P': // Delete X Character(s), default 1 char + var x = 1; + if (argslen == 1) { x = args[0]; } + for (i = _termx; i < (_termx + x) ; i++) { _tscreen[_termy][i] = ' '; _scratt[_termy][i] = (7 << 6); } + break; + case 'L': // Insert X Line(s), default 1 char + var linecount = 1; + if (argslen == 1) { linecount = args[0]; } + if (linecount == 0) { linecount = 1; } + for (y = _scrollRegion[1]; y >= _termy + linecount; y--) { + _tscreen[y] = _tscreen[y - linecount]; + _scratt[y] = _scratt[y - linecount]; + } + for (y = _termy; y < _termy + linecount; y++) { + _tscreen[y] = []; + _scratt[y] = []; + for (x = 0; x < obj.width; x++) { _tscreen[y][x] = ' '; _scratt[y][x] = (7 << 6); } } break; case 'J': // ClearScreen: @@ -288,14 +298,10 @@ var CreateAmtRemoteTerminal = function (divid) { case 'K': // EraseLine: if (argslen == 0 || (argslen == 1 && (!args[0] || args[0] == 0))) { _EraseCursorToEol(); // Erase from the cursor to the end of the line - } - else if (argslen == 1) { - if (args[0] == 1) // Erase from the beginning of the line to the cursor - { + } else if (argslen == 1) { + if (args[0] == 1) { // Erase from the beginning of the line to the cursor _EraseBolToCursor(); - } - else if (args[0] == 2) // Erase the line with the cursor - { + } else if (args[0] == 2) { // Erase the line with the cursor _EraseLine(_termy); } } @@ -336,7 +342,7 @@ var CreateAmtRemoteTerminal = function (divid) { break; default: //if (code != '@') alert(code); - //console.log('unknown process', code, args, mode); + //console.log('unknown terminal code', code, args, mode); break; } } @@ -522,6 +528,7 @@ var CreateAmtRemoteTerminal = function (divid) { _termx = _termy = 0; _backSpaceErase = false; _scrollRegion = [0, 24]; + _altKeypadMode = false; obj.TermClear(7 << 6); } @@ -594,10 +601,19 @@ var CreateAmtRemoteTerminal = function (divid) { return; } if (e.which == 27) { obj.TermSendKeys(String.fromCharCode(27)); return true; }; // ESC - if (e.which == 37) { obj.TermSendKeys(String.fromCharCode(27, 91, 68)); return true; }; // Left - if (e.which == 38) { obj.TermSendKeys(String.fromCharCode(27, 91, 65)); return true; }; // Up - if (e.which == 39) { obj.TermSendKeys(String.fromCharCode(27, 91, 67)); return true; }; // Right - if (e.which == 40) { obj.TermSendKeys(String.fromCharCode(27, 91, 66)); return true; }; // Down + + if (_altKeypadMode == true) { + if (e.which == 37) { obj.TermSendKeys(String.fromCharCode(27, 79, 68)); return true; }; // Left + if (e.which == 38) { obj.TermSendKeys(String.fromCharCode(27, 79, 65)); return true; }; // Up + if (e.which == 39) { obj.TermSendKeys(String.fromCharCode(27, 79, 67)); return true; }; // Right + if (e.which == 40) { obj.TermSendKeys(String.fromCharCode(27, 79, 66)); return true; }; // Down + } else { + if (e.which == 37) { obj.TermSendKeys(String.fromCharCode(27, 91, 68)); return true; }; // Left + if (e.which == 38) { obj.TermSendKeys(String.fromCharCode(27, 91, 65)); return true; }; // Up + if (e.which == 39) { obj.TermSendKeys(String.fromCharCode(27, 91, 67)); return true; }; // Right + if (e.which == 40) { obj.TermSendKeys(String.fromCharCode(27, 91, 66)); return true; }; // Down + } + if (e.which == 9) { obj.TermSendKeys("\t"); if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return true; }; // TAB // F1 to F12 keys diff --git a/public/styles/style.css b/public/styles/style.css index d1b8ec37..2c621ffc 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -136,7 +136,7 @@ margin: 0; padding: 0 15px; background-color: #fff; - max-height: calc(100vh - 111px); + /*max-height: calc(100vh - 111px);*/ min-width: unset; } diff --git a/views/default-min.handlebars b/views/default-min.handlebars index 7e22b0a2..9634a0ff 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -1 +1 @@ - MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file + MeshCentral
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file diff --git a/views/default.handlebars b/views/default.handlebars index 77f31a62..bc44f089 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1217,6 +1217,7 @@ QV('authAppSetupCheck', userinfo.otpsecret == 1); QV('authKeySetupCheck', userinfo.otphkeys > 0); QV('authCodesSetupCheck', userinfo.otpkeys > 0); + masterUpdate(4 + 128); if (typeof userinfo.passchange == 'number') { if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', ' - Reset on next login.'); } @@ -1656,6 +1657,7 @@ } } masterUpdate(4 + 128); + if (currentNode && (currentNode.meshid == message.event.meshid)) { refreshDevice(currentNode._id); } //meshserver.send({ action: 'files' }); // TODO: Why do we need to do this?? // If we are looking at a mesh that is now deleted, move back to "My Account" @@ -2260,8 +2262,8 @@ // Add a "Add Device Group" option r += '
'; - if ((view < 3) && (sort == 0) && (meshcount > 0)) { r += 'Add Device Group '; } - r += 'MeshCmd
'; + if ((view < 3) && (sort == 0) && (meshcount > 0) && ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 64) == 0))) { r += 'Add Device Group '; } + if ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 128) == 0)) { r += 'MeshCmd'; } r += '
'; QH('xdevices', r); @@ -3540,7 +3542,6 @@ // // MY DEVICE // - function refreshDevice(nodeid) { if (!currentNode || currentNode._id != nodeid) return; gotoDevice(nodeid, xxcurrentView, true); @@ -3578,7 +3579,7 @@ // Add node name var nname = EscapeHtml(node.name); if (nname.length == 0) { nname = 'None'; } - if ((meshrights & 4) != 0) { nname = '' + nname + ' '; } + if (((meshrights & 4) != 0) && ((!mesh.flags) || ((mesh.flags & 2) == 0))) { nname = '' + nname + ' '; } QH('p10deviceName', nname); QH('p11deviceName', nname); QH('p12deviceName', nname); @@ -5779,6 +5780,9 @@ function account_createMesh() { if (xxdialogMode) return; + // Check if we are disallowed from creating a device group + if ((userinfo.siteadmin != 0xFFFFFFFF) && ((userinfo.siteadmin & 64) != 0)) { setDialogMode(2, "New Device Group", 1, null, "This account does not have the rights to create a new device group."); return; } + // Check if we are allowed to create a new device group if ((userinfo.emailVerified !== true) && (serverinfo.emailcheck == true) && (userinfo.siteadmin != 0xFFFFFFFF)) { setDialogMode(2, "New Device Group", 1, null, "Unable to create a new device group until a email address is verified. This is required for password recovery. Go to the \"My Account\" tab to change and verify an email address."); return; } @@ -5933,7 +5937,10 @@ // Display features var meshFeatures = []; - if (currentMesh.flags) { if (currentMesh.flags & 1) { meshFeatures.push('Auto-Remove'); } } + if (currentMesh.flags) { + if (currentMesh.flags & 1) { meshFeatures.push('Auto-Remove'); } + if (currentMesh.flags & 2) { meshFeatures.push('Hostname Sync'); } + } meshFeatures = meshFeatures.join(', '); if (meshFeatures == '') { meshFeatures = 'None'; } x += addHtmlValue('Features', addLinkConditional(meshFeatures, 'p20editmeshfeatures()', (meshrights & 1) != 0)); @@ -6100,12 +6107,14 @@ if (xxdialogMode) return; var flags = (currentMesh.flags)?currentMesh.flags:0; var x = "
Remove device on disconnect
"; + x += "
Sync server device name to hostname
"; setDialogMode(2, "Edit Device Group Features", 3, p20editmeshfeaturesEx, x); } function p20editmeshfeaturesEx() { var flags = 0; if (Q('d20flag1').checked) { flags += 1; } + if (Q('d20flag2').checked) { flags += 2; } meshserver.send({ action: 'editmesh', meshid: currentMesh._id, flags: flags }); } @@ -6593,7 +6602,7 @@ if (self) { permissions += ""; } if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { permissions += "Locked, "; } permissions += ""; - if ((user.siteadmin == null) || (user.siteadmin == 0) || (user.siteadmin == 32)) { + if ((user.siteadmin == null) || (user.siteadmin == 0) || ((user.siteadmin & (0xFFFFFFFF - 224)) == 0)) { permissions += "User"; } else if (user.siteadmin == 8) { permissions += "User + Files"; @@ -6602,6 +6611,7 @@ } else { permissions += "Partial"; } + if ((user.siteadmin != null) && (user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & (64 + 128)) != 0)) { permissions += "*"; } permissions += ""; //if ((user.quota != null) && ((user.siteadmin & 8) != 0)) { msg += ", " + (user.quota / 1024) + " k"; } if (self) { permissions += ""; } @@ -6713,6 +6723,8 @@ x += 'Server Updates
'; x += 'Manage Users
'; x += '
Lock Account
'; + x += 'No New Device Groups
'; + x += 'No MeshCmd
'; x += ''; var user = users[userid.toLowerCase()]; setDialogMode(2, "Server Permissions", 3, showUserAdminDialogEx, x, user); @@ -6724,6 +6736,8 @@ Q('ua_fileaccess').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 8) != 0)); // Server Files Q('ua_serverupdate').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 16) != 0)); // Server Update Q('ua_lockedaccount').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 32) != 0)); // Account locked + Q('ua_nonewgroups').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 64) != 0)); // No New Groups + Q('ua_nomeshcmd').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 128) != 0)); // No MeshCmd } QE('ua_fulladmin', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_serverbackup', userinfo.siteadmin == 0xFFFFFFFF); @@ -6731,6 +6745,9 @@ QE('ua_serverrestore', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_fileaccess', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_serverupdate', userinfo.siteadmin == 0xFFFFFFFF); + QE('ua_lockedaccount', userinfo.siteadmin == 0xFFFFFFFF); + QE('ua_nonewgroups', userinfo.siteadmin == 0xFFFFFFFF); + QE('ua_nomeshcmd', userinfo.siteadmin == 0xFFFFFFFF); Q('ua_fileaccessquota').value = (user.quota != null)?(user.quota / 1024):''; showUserAdminDialogValidate(); return false; @@ -6743,6 +6760,9 @@ QE('ua_serverrestore', !Q('ua_fulladmin').checked); QE('ua_fileaccess', !Q('ua_fulladmin').checked); QE('ua_serverupdate', !Q('ua_fulladmin').checked); + QE('ua_lockedaccount', !Q('ua_fulladmin').checked); + QE('ua_nonewgroups', !Q('ua_fulladmin').checked); + QE('ua_nomeshcmd', !Q('ua_fulladmin').checked); QE('ua_fileaccessquota', Q('ua_fileaccess').checked && !Q('ua_fulladmin').checked); } } @@ -6756,6 +6776,8 @@ if (Q('ua_fileaccess').checked == true) siteadmin += 8; if (Q('ua_serverupdate').checked == true) siteadmin += 16; if (Q('ua_lockedaccount').checked == true) siteadmin += 32; + if (Q('ua_nonewgroups').checked == true) siteadmin += 64; + if (Q('ua_nomeshcmd').checked == true) siteadmin += 128; } var x = { action: 'edituser', name: user.name, siteadmin: siteadmin }; if (isNaN(quota) == false) { x.quota = (quota * 1024); } @@ -6783,16 +6805,17 @@ if (activeSessions == 0) { Q('MainUserImage').classList.add('gray'); } // Server permissions - var msg = '', premsg = ''; - if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { premsg = ' '; msg += 'Locked account, '; } - if ((user.siteadmin == null) || (user.siteadmin == 0) || (user.siteadmin == 32)) { msg += "No server rights"; } else if (user.siteadmin == 8) { msg += "Access to server files"; } else if (user.siteadmin == 0xFFFFFFFF) { msg += "Full administrator"; } else { msg += "Partial rights"; } + var msg = [], premsg = ''; + if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { premsg = ' '; msg.push("Locked account"); } + if ((user.siteadmin == null) || ((user.siteadmin & (0xFFFFFFFF - 224)) == 0)) { msg.push("No server rights"); } else if (user.siteadmin == 8) { msg.push("Access to server files"); } else if (user.siteadmin == 0xFFFFFFFF) { msg.push("Full administrator"); } else { msg.push("Partial rights"); } + if ((user.siteadmin != null) && ((user.siteadmin & (64 + 128)) != 0)) { msg.push("Restrictions"); } // Show user attributes var x = '
'; var email = user.email?EscapeHtml(user.email):'Not set', everify = ''; if (serverinfo.emailcheck) { everify = ((user.emailVerified == true)?'🗸 ':'🗴 '); } x += addDeviceAttribute('Email', everify + "" + email + ''); - x += addDeviceAttribute('Server Rights', premsg + "" + msg + ""); + x += addDeviceAttribute('Server Rights', premsg + "" + msg.join(', ') + ""); if (user.quota) x += addDeviceAttribute('Server Quota', EscapeHtml(parseInt(user.quota) / 1024) + ' k'); x += addDeviceAttribute('Creation', new Date(user.creation * 1000).toLocaleString()); if (user.login) x += addDeviceAttribute('Last Login', new Date(user.login * 1000).toLocaleString()); diff --git a/views/login-min.handlebars b/views/login-min.handlebars index 72b8b04b..d6808195 100644 --- a/views/login-min.handlebars +++ b/views/login-min.handlebars @@ -1 +1 @@ -{{{title}}} - Login
{{{title}}}
{{{title2}}}

Welcome


\ No newline at end of file + {{{title}}} - Login
{{{title}}}
{{{title2}}}

Welcome


\ No newline at end of file diff --git a/views/messenger-min.handlebars b/views/messenger-min.handlebars index 5111ea92..c477cfab 100644 --- a/views/messenger-min.handlebars +++ b/views/messenger-min.handlebars @@ -1 +1 @@ - MeshMessenger
MeshMessenger
\ No newline at end of file + MeshMessenger
MeshMessenger
\ No newline at end of file