mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-23 21:55:52 -05:00
Improved terminal, added server permissions, fixed desktop full screen.
This commit is contained in:
parent
af46798c16
commit
ffcdba8929
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.3.1-w",
|
||||
"version": "0.3.1-x",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -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 += '<div style=border-top-style:solid;border-top-width:1px;border-top-color:#DDDDDD;cursor:pointer;font-size:10px>';
|
||||
if ((view < 3) && (sort == 0) && (meshcount > 0)) { r += '<a onclick=account_createMesh() title="Create a new group of devices." style=cursor:pointer>Add Device Group</a> '; }
|
||||
r += '<a onclick=p10showMeshCmdDialog(0) style=cursor:pointer title="Download MeshCmd, a command line tool that performs many functions.">MeshCmd</a></div>';
|
||||
if ((view < 3) && (sort == 0) && (meshcount > 0) && ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 64) == 0))) { r += '<a onclick=account_createMesh() title="Create a new group of devices." style=cursor:pointer>Add Device Group</a> '; }
|
||||
if ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 128) == 0)) { r += '<a onclick=p10showMeshCmdDialog(0) style=cursor:pointer title="Download MeshCmd, a command line tool that performs many functions.">MeshCmd</a></div>'; }
|
||||
r += '</div><br/>';
|
||||
|
||||
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 = '<i>None</i>'; }
|
||||
if ((meshrights & 4) != 0) { nname = '<span title="Click here to edit the server-side device name" onclick=showEditNodeValueDialog(0) style=cursor:pointer>' + nname + ' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>'; }
|
||||
if (((meshrights & 4) != 0) && ((!mesh.flags) || ((mesh.flags & 2) == 0))) { nname = '<span title="Click here to edit the server-side device name" onclick=showEditNodeValueDialog(0) style=cursor:pointer>' + nname + ' <img class=hoverButton width=10 height=10 src="images/link5.png" /></span>'; }
|
||||
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 = '<i>None</i>'; }
|
||||
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 = "<div><input type=checkbox id=d20flag1 " + ((flags & 1)?'checked':'') + ">Remove device on disconnect<br></div>";
|
||||
x += "<div><input type=checkbox id=d20flag2 " + ((flags & 2) ? 'checked' : '') + ">Sync server device name to hostname<br></div>";
|
||||
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 += "<a style=cursor:pointer onclick=showUserAdminDialog(event,\"" + encodeURIComponent(user._id) + "\")>"; }
|
||||
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { permissions += "Locked, "; }
|
||||
permissions += "<span title='Server 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 += "</span>";
|
||||
//if ((user.quota != null) && ((user.siteadmin & 8) != 0)) { msg += ", " + (user.quota / 1024) + " k"; }
|
||||
if (self) { permissions += "</a>"; }
|
||||
@ -6713,6 +6723,8 @@
|
||||
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverupdate>Server Updates<br>';
|
||||
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_manageusers>Manage Users<br>';
|
||||
x += '<hr/><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_lockedaccount>Lock Account<br>';
|
||||
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nonewgroups>No New Device Groups<br>';
|
||||
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nomeshcmd>No MeshCmd<br>';
|
||||
x += '</div>';
|
||||
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 = '<img src="images/padlock12.png" height=12 width=8 title="Account is locked" style="margin-top:2px" /> '; 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 = '<img src="images/padlock12.png" height=12 width=8 title="Account is locked" style="margin-top:2px" /> '; 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 = '<div style=min-height:80px><table style=width:100%>';
|
||||
var email = user.email?EscapeHtml(user.email):'<i>Not set</i>', everify = '';
|
||||
if (serverinfo.emailcheck) { everify = ((user.emailVerified == true)?'<b style=color:green;cursor:pointer title="Email is verified">🗸</b> ':'<b style=color:red;cursor:pointer title="Email not verified">🗴</b> '); }
|
||||
x += addDeviceAttribute('Email', everify + "<a style=cursor:pointer onclick=p30showUserEmailChangeDialog(event,\"" + userid + "\")>" + email + '</a> <a style=cursor:pointer onclick=doemail(event,\"' + user.email + '\")><img class=hoverButton width=10 height=10 src="images/link1.png" /></a>');
|
||||
x += addDeviceAttribute('Server Rights', premsg + "<a style=cursor:pointer onclick=showUserAdminDialog(event,\"" + userid + "\")>" + msg + "</a>");
|
||||
x += addDeviceAttribute('Server Rights', premsg + "<a style=cursor:pointer onclick=showUserAdminDialog(event,\"" + userid + "\")>" + msg.join(', ') + "</a>");
|
||||
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());
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user