From 67feb1422fc4538ee9df8f3801650603a21b59cf Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Tue, 11 Jun 2019 11:33:44 -0700 Subject: [PATCH] Server fixes, added locale arg in web app. --- db.js | 4 +- meshuser.js | 7 +++ package.json | 2 +- views/agentinvite.handlebars | 2 +- views/default-min.handlebars | 73 ++++++++++++++++------------- views/default-mobile-min.handlebars | 2 +- views/default-mobile.handlebars | 11 +++-- views/default.handlebars | 73 ++++++++++++++++------------- webserver.js | 72 ++++++++++++++++------------ 9 files changed, 144 insertions(+), 102 deletions(-) diff --git a/db.js b/db.js index dbb9c100..48967048 100644 --- a/db.js +++ b/db.js @@ -877,7 +877,9 @@ module.exports.CreateDB = function (parent, func) { for (var i in muser) { if (user[i] == null) { delete muser[i]; } } // Send the user update - parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.webserver.CloneSafeUser(user), action: (added ? 'accountcreate' : 'accountchange'), domain: user.domain, nolog: 1 }); + var targets = ['*', 'server-users', user._id]; + if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } } + parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.webserver.CloneSafeUser(user), action: (added ? 'accountcreate' : 'accountchange'), domain: user.domain, nolog: 1 }); } return obj; diff --git a/meshuser.js b/meshuser.js index 46981672..493bbfff 100644 --- a/meshuser.js +++ b/meshuser.js @@ -28,6 +28,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use const MESHRIGHT_SERVERFILES = 32; const MESHRIGHT_WAKEDEVICE = 64; const MESHRIGHT_SETNOTES = 128; + const MESHRIGHT_REMOTEVIEWONLY = 256; + const MESHRIGHT_NOTERMINAL = 512; + const MESHRIGHT_NOFILES = 1024; + const MESHRIGHT_NOAMT = 2048; + const MESHRIGHT_DESKLIMITEDINPUT = 4096; // Site rights const SITERIGHT_SERVERBACKUP = 1; @@ -36,6 +41,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use const SITERIGHT_FILEACCESS = 8; const SITERIGHT_SERVERUPDATE = 16; const SITERIGHT_LOCKED = 32; + const SITERIGHT_NONEWGROUPS = 64; + const SITERIGHT_NOMESHCMD = 128; var obj = {}; obj.user = user; diff --git a/package.json b/package.json index b5006890..65ddbefa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.3.6-i", + "version": "0.3.6-j", "keywords": [ "Remote Management", "Intel AMT", diff --git a/views/agentinvite.handlebars b/views/agentinvite.handlebars index b759296d..5b723386 100644 --- a/views/agentinvite.handlebars +++ b/views/agentinvite.handlebars @@ -113,7 +113,7 @@

Apple™ MacOS

-

Download the installer here, right click on it and select "Open", then follow the instructions.

+

Download the installer here, right click on it or press "control" and click on the file. Then select "Open" and follow the instructions.

diff --git a/views/default-min.handlebars b/views/default-min.handlebars index 94f87311..f8dc081b 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -7437,7 +7437,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this node.lastconnect = message.time; node.lastaddr = message.addr; if ((currentNode._id == node._id) && (Q('MainComputerState').innerHTML == '')) { - QH('MainComputerState', 'Last seen:
' + new Date(node.lastconnect).toLocaleDateString() + ', ' + new Date(node.lastconnect).toLocaleTimeString() + '
'); + QH('MainComputerState', 'Last seen:
' + printDateTime(new Date(node.lastconnect)) + '
'); } } break; @@ -7483,7 +7483,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this } else { var x = '
'; - if (currentNode.lastconnect) { x += addHtmlValue2('Last agent connection', new Date(currentNode.lastconnect).toLocaleString()); } + if (currentNode.lastconnect) { x += addHtmlValue2('Last agent connection', printDateTime(new Date(currentNode.lastconnect))); } if (currentNode.lastaddr) { var splitip = currentNode.lastaddr.split(':'); if (splitip.length > 2) { @@ -7499,7 +7499,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this } } - x += addHtmlValue2('Last interfaces update', new Date(message.updateTime).toLocaleString()); + x += addHtmlValue2('Last interfaces update', printDateTime(new Date(message.updateTime))); for (var i in message.netif) { var net = message.netif[i]; x += '
' @@ -7577,7 +7577,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this var n = Q('d2devNotes'); if (n && (message.id == decodeURIComponent(n.attributes['noteid'].value))) { if (message.notes) { QH('d2devNotes', decodeURIComponent(message.notes)); } else { QH('d2devNotes', ''); } - var ro = n.attributes['ro'].value == 'true'; + var ro = (n.attributes['ro'].value == 'true'); if (ro == false) { // If we have permissions, set read/write on this note. n.removeAttribute('readonly'); QE('idx_dlgOkButton', true); @@ -9982,7 +9982,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += '
'; } powerstate += 'Agent connected'; } if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += '
'; } powerstate += 'Intel® AMT connected'; } else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += '
'; } powerstate += 'Intel® AMT detected'; } - if ((powerstate == '') && node.lastconnect) { powerstate = 'Last seen:
' + new Date(node.lastconnect).toLocaleDateString() + ', ' + new Date(node.lastconnect).toLocaleTimeString() + '
'; } + if ((powerstate == '') && node.lastconnect) { powerstate = 'Last seen:
' + printDateTime(new Date(node.lastconnect)) + '
'; } QH('MainComputerState', powerstate); // Set the node icon @@ -10166,12 +10166,12 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this var te = Math.min(Math.min(end, block[1]), now); var width = Math.round(((te - ts) * totalWidth) / 86400000); if (width > 0) { - var title = powerStateStrings2[block[2]] + ' from ' + new Date(ts).toLocaleTimeString() + ' to ' + new Date(te).toLocaleTimeString() + '.'; + var title = powerStateStrings2[block[2]] + ' from ' + printTime(new Date(ts)) + ' to ' + printTime(new Date(te)) + '.'; datavalue += '
'; } } } - x += '
 ' + date.toLocaleDateString() + '
' + datavalue + '
'; + x += '
 ' + printDate(date) + '
' + datavalue + '
'; ++count; date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day } @@ -11354,7 +11354,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this // Figure out the date var fdatestr = ''; - if (f.d != null) { var fdate = new Date(f.d), fdatestr = (fdate.getMonth() + 1) + "/" + (fdate.getDate()) + "/" + fdate.getFullYear() + " " + fdate.toLocaleTimeString() + " "; } + if (f.d != null) { var fdate = new Date(f.d), fdatestr = printDateTime(fdate) + " "; } // Figure out the size var fsize = ''; @@ -11703,10 +11703,10 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this for (var i in currentDeviceEvents) { var event = currentDeviceEvents[i]; var time = new Date(event.time); - if (time.toLocaleDateString() != dateHeader) { + if (printDate(time) != dateHeader) { if (dateHeader != null) x += ''; - x += ''; - dateHeader = time.toLocaleDateString(); + dateHeader = printDate(time); + x += '
' + time.toLocaleDateString() + '
'; } var icon = 'si3'; if (event.etype == 'user') icon = 'm2'; @@ -11714,7 +11714,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this var msg = event.msg.split('(R)').join('®'); //if (event.username && event.username != userinfo.name) { msg += ': ' + event.username; } - x += ''; + x += ''; } if (dateHeader != null) x += '
' + dateHeader + '
 ' + time.toLocaleTimeString() + ' - ' + msg + ' 
 ' + printTime(time) + ' - ' + msg + ' 
'; if (x == '') x = "
No Events Found

"; @@ -12699,7 +12699,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this // Figure out the date var fdatestr = ''; - if (f.d != null) { var fdate = new Date(f.d), fdatestr = (fdate.getMonth() + 1) + "/" + (fdate.getDate()) + "/" + fdate.getFullYear() + " " + fdate.toLocaleTimeString() + " "; } + if (f.d != null) { var fdate = new Date(f.d), fdatestr = printDateTime(fdate) + " "; } // Figure out the size var fsize = ''; @@ -12910,10 +12910,10 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this for (var i in events) { var event = events[i], time = new Date(event.time); if (event.msg) { - if (time.toLocaleDateString() != dateHeader) { + if (printDate(time) != dateHeader) { if (dateHeader != null) x += ''; - x += ''; - dateHeader = time.toLocaleDateString(); + dateHeader = printDate(time); + x += '
' + time.toLocaleDateString() + '
'; } var icon = 'si3'; if (event.etype == 'user') icon = 'm2'; @@ -12921,7 +12921,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this var msg = event.msg.split('(R)').join('®'); if (event.username && event.username != userinfo.name) { msg += ': ' + event.username; } - x += ''; + x += ''; } } if (dateHeader != null) x += '
' + dateHeader + '
 ' + time.toLocaleTimeString() + ' - ' + msg + ' 
 ' + printTime(time) + ' - ' + msg + ' 
'; @@ -13051,17 +13051,21 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this } if (sessions == 1) { lastAccess += '1 session'; } else { lastAccess += sessions + ' sessions'; } } else { - if (user.login) { lastAccess += '' + new Date(user.login * 1000).toLocaleDateString() + ''; } + if (user.login) { lastAccess += '' + printDate(new Date(user.login * 1000)) + ''; } } 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 & (0xFFFFFFFF - 224)) == 0)) { + + var urights = user.siteadmin & (0xFFFFFFFF - 224); + if ((user.siteadmin == null) || (urights == 0)) { permissions += "User"; - } else if (user.siteadmin == 8) { + } else if (urights == 8) { permissions += "User + Files"; } else if (user.siteadmin == 0xFFFFFFFF) { permissions += "Administrator"; + } else if ((urights & 2) != 0) { + permissions += "Manager"; } else { permissions += "Partial"; } @@ -13256,14 +13260,14 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this if (xxdialogMode) return; haltEvent(e); userid = decodeURIComponent(userid); - var x = '
'; + var x = '
'; x += 'Server Files, k max, blank for default

'; x += 'Full Administrator
'; x += 'Server Backup
'; x += 'Server Restore
'; x += 'Server Updates
'; x += 'Manage Users
'; - x += '
Lock Account
'; + x += '
Lock Account
'; x += 'No New Device Groups
'; x += 'No Tools (MeshCmd/Router)
'; x += '
'; @@ -13287,6 +13291,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this QE('ua_fileaccess', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_fileaccessquota', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_serverupdate', userinfo.siteadmin == 0xFFFFFFFF); + QV('d2AdminPermissions', userinfo.siteadmin == 0xFFFFFFFF) QE('ua_lockedaccount', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); QE('ua_nonewgroups', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); QE('ua_nomeshcmd', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); @@ -13364,10 +13369,10 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this } 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()); + x += addDeviceAttribute('Creation', printDateTime(new Date(user.creation * 1000))); + if (user.login) x += addDeviceAttribute('Last Login', printDateTime(new Date(user.login * 1000))); if (user.passchange == -1) { x += addDeviceAttribute('Password', 'Will be changed on next login.'); } - else if (user.passchange) { x += addDeviceAttribute('Password', 'Last changed: ' + new Date(user.passchange * 1000).toLocaleString()); } + else if (user.passchange) { x += addDeviceAttribute('Password', 'Last changed: ' + printDateTime(new Date(user.passchange * 1000))); } // Device Groups var linkCount = 0, linkCountStr = 'None'; @@ -13544,12 +13549,12 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this var te = Math.min(Math.min(end, block[1]), now); var width = Math.round((te - ts) / 112794); if (width > 0) { - var title = powerStateStrings2[block[2]] + ' from ' + new Date(ts).toLocaleTimeString() + ' to ' + new Date(te).toLocaleTimeString() + '.'; + var title = powerStateStrings2[block[2]] + ' from ' + printTime(new Date(ts)) + ' to ' + printTime(new Date(te)) + '.'; datavalue += '
'; } } } - x += '
 ' + date.toLocaleDateString() + '
' + datavalue + '
'; + x += '
 ' + printDate(date) + '
' + datavalue + '
'; ++count; date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day } @@ -13566,10 +13571,10 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this for (var i in currentUserEvents) { var event = currentUserEvents[i]; var time = new Date(event.time); - if (time.toLocaleDateString() != dateHeader) { + if (printDate(time) != dateHeader) { if (dateHeader != null) x += ''; - x += ''; - dateHeader = time.toLocaleDateString(); + dateHeader = printDate(time); + x += '
' + time.toLocaleDateString() + '
'; } var icon = 'si3'; if (event.etype == 'user') icon = 'm2'; @@ -13580,7 +13585,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this x += ''; + x += '
' + printTime(time) + ' - ' + msg + '
'; } if (dateHeader != null) x += '
' + dateHeader + '
'; x += '
'; x += '
'; - x += '
' + time.toLocaleTimeString() + ' - ' + msg + '
'; if (x == '') x = "
No Events Found

"; @@ -13720,7 +13725,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this if (node != null) { icon = node.icon; t = '' + node.name + ': ' } } - r += '
'; + r += '
'; if (icon) { r += '
'; } r += '
X
' + t + n.text + '
'; } @@ -14183,5 +14188,7 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this function u2fSupported() { return (window.u2f && ((navigator.userAgent.indexOf('Chrome/') > 0) || (navigator.userAgent.indexOf('Firefox/') > 0) || (navigator.userAgent.indexOf('Opera/') > 0) || (navigator.userAgent.indexOf('Safari/') > 0))); } function findOne(arr1, arr2) { if ((arr1 == null) || (arr2 == null)) return false; return arr2.some(function (v) { return arr1.indexOf(v) >= 0; }); }; function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); } - + function printDate(d) { return d.toLocaleDateString(args.locale); } + function printTime(d) { return d.toLocaleTimeString(args.locale); } + function printDateTime(d) { return d.toLocaleString(args.locale); } \ No newline at end of file diff --git a/views/default-mobile-min.handlebars b/views/default-mobile-min.handlebars index 91a36370..69513845 100644 --- a/views/default-mobile-min.handlebars +++ b/views/default-mobile-min.handlebars @@ -1 +1 @@ - {{{title}}}
{{{title}}}
{{{title2}}}
\ No newline at end of file + {{{title}}}
{{{title}}}
{{{title2}}}
\ No newline at end of file diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index df553c77..167496a6 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -571,6 +571,7 @@ diff --git a/views/default.handlebars b/views/default.handlebars index ecaf85eb..a8acbc39 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1389,7 +1389,7 @@ node.lastconnect = message.time; node.lastaddr = message.addr; if ((currentNode._id == node._id) && (Q('MainComputerState').innerHTML == '')) { - QH('MainComputerState', 'Last seen:
' + new Date(node.lastconnect).toLocaleDateString() + ', ' + new Date(node.lastconnect).toLocaleTimeString() + '
'); + QH('MainComputerState', 'Last seen:
' + printDateTime(new Date(node.lastconnect)) + '
'); } } break; @@ -1435,7 +1435,7 @@ } else { var x = '
'; - if (currentNode.lastconnect) { x += addHtmlValue2('Last agent connection', new Date(currentNode.lastconnect).toLocaleString()); } + if (currentNode.lastconnect) { x += addHtmlValue2('Last agent connection', printDateTime(new Date(currentNode.lastconnect))); } if (currentNode.lastaddr) { var splitip = currentNode.lastaddr.split(':'); if (splitip.length > 2) { @@ -1451,7 +1451,7 @@ } } - x += addHtmlValue2('Last interfaces update', new Date(message.updateTime).toLocaleString()); + x += addHtmlValue2('Last interfaces update', printDateTime(new Date(message.updateTime))); for (var i in message.netif) { var net = message.netif[i]; x += '
' @@ -1529,7 +1529,7 @@ var n = Q('d2devNotes'); if (n && (message.id == decodeURIComponent(n.attributes['noteid'].value))) { if (message.notes) { QH('d2devNotes', decodeURIComponent(message.notes)); } else { QH('d2devNotes', ''); } - var ro = n.attributes['ro'].value == 'true'; + var ro = (n.attributes['ro'].value == 'true'); if (ro == false) { // If we have permissions, set read/write on this note. n.removeAttribute('readonly'); QE('idx_dlgOkButton', true); @@ -3934,7 +3934,7 @@ if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += '
'; } powerstate += 'Agent connected'; } if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += '
'; } powerstate += 'Intel® AMT connected'; } else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += '
'; } powerstate += 'Intel® AMT detected'; } - if ((powerstate == '') && node.lastconnect) { powerstate = 'Last seen:
' + new Date(node.lastconnect).toLocaleDateString() + ', ' + new Date(node.lastconnect).toLocaleTimeString() + '
'; } + if ((powerstate == '') && node.lastconnect) { powerstate = 'Last seen:
' + printDateTime(new Date(node.lastconnect)) + '
'; } QH('MainComputerState', powerstate); // Set the node icon @@ -4118,12 +4118,12 @@ var te = Math.min(Math.min(end, block[1]), now); var width = Math.round(((te - ts) * totalWidth) / 86400000); if (width > 0) { - var title = powerStateStrings2[block[2]] + ' from ' + new Date(ts).toLocaleTimeString() + ' to ' + new Date(te).toLocaleTimeString() + '.'; + var title = powerStateStrings2[block[2]] + ' from ' + printTime(new Date(ts)) + ' to ' + printTime(new Date(te)) + '.'; datavalue += '
'; } } } - x += '
 ' + date.toLocaleDateString() + '
' + datavalue + '
'; + x += '
 ' + printDate(date) + '
' + datavalue + '
'; ++count; date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day } @@ -5306,7 +5306,7 @@ // Figure out the date var fdatestr = ''; - if (f.d != null) { var fdate = new Date(f.d), fdatestr = (fdate.getMonth() + 1) + "/" + (fdate.getDate()) + "/" + fdate.getFullYear() + " " + fdate.toLocaleTimeString() + " "; } + if (f.d != null) { var fdate = new Date(f.d), fdatestr = printDateTime(fdate) + " "; } // Figure out the size var fsize = ''; @@ -5655,10 +5655,10 @@ for (var i in currentDeviceEvents) { var event = currentDeviceEvents[i]; var time = new Date(event.time); - if (time.toLocaleDateString() != dateHeader) { + if (printDate(time) != dateHeader) { if (dateHeader != null) x += ''; - x += ''; - dateHeader = time.toLocaleDateString(); + dateHeader = printDate(time); + x += '
' + time.toLocaleDateString() + '
'; } var icon = 'si3'; if (event.etype == 'user') icon = 'm2'; @@ -5666,7 +5666,7 @@ var msg = event.msg.split('(R)').join('®'); //if (event.username && event.username != userinfo.name) { msg += ': ' + event.username; } - x += ''; + x += ''; } if (dateHeader != null) x += '
' + dateHeader + '
 ' + time.toLocaleTimeString() + ' - ' + msg + ' 
 ' + printTime(time) + ' - ' + msg + ' 
'; if (x == '') x = "
No Events Found

"; @@ -6651,7 +6651,7 @@ // Figure out the date var fdatestr = ''; - if (f.d != null) { var fdate = new Date(f.d), fdatestr = (fdate.getMonth() + 1) + "/" + (fdate.getDate()) + "/" + fdate.getFullYear() + " " + fdate.toLocaleTimeString() + " "; } + if (f.d != null) { var fdate = new Date(f.d), fdatestr = printDateTime(fdate) + " "; } // Figure out the size var fsize = ''; @@ -6862,10 +6862,10 @@ for (var i in events) { var event = events[i], time = new Date(event.time); if (event.msg) { - if (time.toLocaleDateString() != dateHeader) { + if (printDate(time) != dateHeader) { if (dateHeader != null) x += ''; - x += ''; - dateHeader = time.toLocaleDateString(); + dateHeader = printDate(time); + x += '
' + time.toLocaleDateString() + '
'; } var icon = 'si3'; if (event.etype == 'user') icon = 'm2'; @@ -6873,7 +6873,7 @@ var msg = event.msg.split('(R)').join('®'); if (event.username && event.username != userinfo.name) { msg += ': ' + event.username; } - x += ''; + x += ''; } } if (dateHeader != null) x += '
' + dateHeader + '
 ' + time.toLocaleTimeString() + ' - ' + msg + ' 
 ' + printTime(time) + ' - ' + msg + ' 
'; @@ -7003,17 +7003,21 @@ } if (sessions == 1) { lastAccess += '1 session'; } else { lastAccess += sessions + ' sessions'; } } else { - if (user.login) { lastAccess += '' + new Date(user.login * 1000).toLocaleDateString() + ''; } + if (user.login) { lastAccess += '' + printDate(new Date(user.login * 1000)) + ''; } } 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 & (0xFFFFFFFF - 224)) == 0)) { + + var urights = user.siteadmin & (0xFFFFFFFF - 224); + if ((user.siteadmin == null) || (urights == 0)) { permissions += "User"; - } else if (user.siteadmin == 8) { + } else if (urights == 8) { permissions += "User + Files"; } else if (user.siteadmin == 0xFFFFFFFF) { permissions += "Administrator"; + } else if ((urights & 2) != 0) { + permissions += "Manager"; } else { permissions += "Partial"; } @@ -7208,14 +7212,14 @@ if (xxdialogMode) return; haltEvent(e); userid = decodeURIComponent(userid); - var x = '
'; + var x = '
'; x += 'Server Files, k max, blank for default

'; x += 'Full Administrator
'; x += 'Server Backup
'; x += 'Server Restore
'; x += 'Server Updates
'; x += 'Manage Users
'; - x += '
Lock Account
'; + x += '
Lock Account
'; x += 'No New Device Groups
'; x += 'No Tools (MeshCmd/Router)
'; x += '
'; @@ -7239,6 +7243,7 @@ QE('ua_fileaccess', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_fileaccessquota', userinfo.siteadmin == 0xFFFFFFFF); QE('ua_serverupdate', userinfo.siteadmin == 0xFFFFFFFF); + QV('d2AdminPermissions', userinfo.siteadmin == 0xFFFFFFFF) QE('ua_lockedaccount', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); QE('ua_nonewgroups', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); QE('ua_nomeshcmd', (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id)); @@ -7316,10 +7321,10 @@ } 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()); + x += addDeviceAttribute('Creation', printDateTime(new Date(user.creation * 1000))); + if (user.login) x += addDeviceAttribute('Last Login', printDateTime(new Date(user.login * 1000))); if (user.passchange == -1) { x += addDeviceAttribute('Password', 'Will be changed on next login.'); } - else if (user.passchange) { x += addDeviceAttribute('Password', 'Last changed: ' + new Date(user.passchange * 1000).toLocaleString()); } + else if (user.passchange) { x += addDeviceAttribute('Password', 'Last changed: ' + printDateTime(new Date(user.passchange * 1000))); } // Device Groups var linkCount = 0, linkCountStr = 'None'; @@ -7496,12 +7501,12 @@ var te = Math.min(Math.min(end, block[1]), now); var width = Math.round((te - ts) / 112794); if (width > 0) { - var title = powerStateStrings2[block[2]] + ' from ' + new Date(ts).toLocaleTimeString() + ' to ' + new Date(te).toLocaleTimeString() + '.'; + var title = powerStateStrings2[block[2]] + ' from ' + printTime(new Date(ts)) + ' to ' + printTime(new Date(te)) + '.'; datavalue += '
'; } } } - x += '
 ' + date.toLocaleDateString() + '
' + datavalue + '
'; + x += '
 ' + printDate(date) + '
' + datavalue + '
'; ++count; date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day } @@ -7518,10 +7523,10 @@ for (var i in currentUserEvents) { var event = currentUserEvents[i]; var time = new Date(event.time); - if (time.toLocaleDateString() != dateHeader) { + if (printDate(time) != dateHeader) { if (dateHeader != null) x += ''; - x += ''; - dateHeader = time.toLocaleDateString(); + dateHeader = printDate(time); + x += '
' + time.toLocaleDateString() + '
'; } var icon = 'si3'; if (event.etype == 'user') icon = 'm2'; @@ -7532,7 +7537,7 @@ x += ''; + x += '
' + printTime(time) + ' - ' + msg + '
'; } if (dateHeader != null) x += '
' + dateHeader + '
'; x += '
'; x += '
'; - x += '
' + time.toLocaleTimeString() + ' - ' + msg + '
'; if (x == '') x = "
No Events Found

"; @@ -7672,7 +7677,7 @@ if (node != null) { icon = node.icon; t = '' + node.name + ': ' } } - r += '
'; + r += '
'; if (icon) { r += '
'; } r += '
X
' + t + n.text + '
'; } @@ -8135,7 +8140,9 @@ function u2fSupported() { return (window.u2f && ((navigator.userAgent.indexOf('Chrome/') > 0) || (navigator.userAgent.indexOf('Firefox/') > 0) || (navigator.userAgent.indexOf('Opera/') > 0) || (navigator.userAgent.indexOf('Safari/') > 0))); } function findOne(arr1, arr2) { if ((arr1 == null) || (arr2 == null)) return false; return arr2.some(function (v) { return arr1.indexOf(v) >= 0; }); }; function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); } - + function printDate(d) { return d.toLocaleDateString(args.locale); } + function printTime(d) { return d.toLocaleTimeString(args.locale); } + function printDateTime(d) { return d.toLocaleString(args.locale); } diff --git a/webserver.js b/webserver.js index 7819604f..797adb03 100644 --- a/webserver.js +++ b/webserver.js @@ -917,7 +917,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { var email = req.body.email; if ((email == null) || (email == '')) { email = req.session.tokenemail; } - // Check the email stirng format + // Check the email string format if (!email || checkEmail(email) == false) { req.session.loginmode = '3'; req.session.error = 'Invalid email.'; @@ -929,42 +929,56 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { req.session.error = 'Account not found.'; res.redirect(domain.url); } else { - var user = docs[0]; - if (checkUserOneTimePasswordRequired(domain, user) == true) { - // Second factor setup, request it now. - checkUserOneTimePassword(req, domain, user, req.body.token, req.body.hwtoken, function (result) { - if (result == false) { - // 2-step auth is required, but the token is not present or not valid. - if ((req.body.token != null) || (req.body.hwtoken != null)) { req.session.error = 'Invalid token, try again.'; } - req.session.loginmode = '5'; - req.session.tokenemail = email; - res.redirect(domain.url); - } else { - // Send email to perform recovery. - delete req.session.tokenemail; - if (obj.parent.mailserver != null) { - obj.parent.mailserver.sendAccountResetMail(domain, user.name, user.email); + // If many accounts have the same validated e-mail, we are going to use the first one for display, but sent a reset email for all accounts. + var responseSent = false; + for (var i in docs) { + var user = docs[i]; + if (checkUserOneTimePasswordRequired(domain, user) == true) { + // Second factor setup, request it now. + checkUserOneTimePassword(req, domain, user, req.body.token, req.body.hwtoken, function (result) { + if (result == false) { + if (i == 0) { + // 2-step auth is required, but the token is not present or not valid. + if ((req.body.token != null) || (req.body.hwtoken != null)) { req.session.error = 'Invalid token, try again.'; } + req.session.loginmode = '5'; + req.session.tokenemail = email; + res.redirect(domain.url); + } + } else { + // Send email to perform recovery. + delete req.session.tokenemail; + if (obj.parent.mailserver != null) { + obj.parent.mailserver.sendAccountResetMail(domain, user.name, user.email); + if (i == 0) { + req.session.loginmode = '1'; + req.session.error = 'Hold on, reset mail sent.'; + res.redirect(domain.url); + } + } else { + if (i == 0) { + req.session.loginmode = '3'; + req.session.error = 'Unable to sent email.'; + res.redirect(domain.url); + } + } + } + }); + } else { + // No second factor, send email to perform recovery. + if (obj.parent.mailserver != null) { + obj.parent.mailserver.sendAccountResetMail(domain, user.name, user.email); + if (i == 0) { req.session.loginmode = '1'; req.session.error = 'Hold on, reset mail sent.'; res.redirect(domain.url); - } else { + } + } else { + if (i == 0) { req.session.loginmode = '3'; req.session.error = 'Unable to sent email.'; res.redirect(domain.url); } } - }); - } else { - // No second factor, send email to perform recovery. - if (obj.parent.mailserver != null) { - obj.parent.mailserver.sendAccountResetMail(domain, user.name, user.email); - req.session.loginmode = '1'; - req.session.error = 'Hold on, reset mail sent.'; - res.redirect(domain.url); - } else { - req.session.loginmode = '3'; - req.session.error = 'Unable to sent email.'; - res.redirect(domain.url); } } }