diff --git a/meshctrl.js b/meshctrl.js index 6e8d6de5..26b57101 100644 --- a/meshctrl.js +++ b/meshctrl.js @@ -163,9 +163,11 @@ if (args['_'].length == 0) { console.log(" MeshCtrl ListUsers"); console.log(" MeshCtrl ListUsers --json"); console.log(" MeshCtrl ListUsers --nameexists \"bob\""); + console.log(" MeshCtrl ListUsers --filter 2fa"); console.log("\r\nOptional arguments:\r\n"); console.log(" --idexists [id] - Return 1 if id exists, 0 if not."); console.log(" --nameexists [name] - Return id if name exists."); + console.log(" --filter [filter1,...] - Filter user names: 2FA, NO2FA."); console.log(" --json - Show result as JSON."); break; } @@ -301,6 +303,7 @@ function performConfigOperations(args) { var fs = require('fs'); var path = require('path'); var configFile = path.join(__dirname, 'config.json'); + if (fs.existsSync(configFile) == false) { configFile = path.join('meshcentral-data', 'config.json'); } if (fs.existsSync(configFile) == false) { configFile = path.join(__dirname, 'meshcentral-data', 'config.json'); } if (fs.existsSync(configFile) == false) { configFile = path.join(__dirname, '..', 'meshcentral-data', 'config.json'); } if (fs.existsSync(configFile) == false) { console.log("Unable to find config.json."); return; } @@ -554,6 +557,18 @@ function serverConnect() { } break; case 'users': { // LISTUSERS + if (args.filter) { + // Filter the list of users + var filters = args.filter.toLowerCase().split(','); + var filteredusers = []; + for (var i in data.users) { + var ok = false; + if ((filters.indexOf('2fa') >= 0) && ((data.users[i].otphkeys != null) || (data.users[i].otpkeys != null) || (data.users[i].otpsecret != null))) { ok = true; } + if ((filters.indexOf('no2fa') >= 0) && ((data.users[i].otphkeys == null) && (data.users[i].otpkeys == null) && (data.users[i].otpsecret == null))) { ok = true; } + if (ok == true) { filteredusers.push(data.users[i]); } + } + data.users = filteredusers; + } if (args.json) { console.log(JSON.stringify(data.users, ' ', 2)); } else { diff --git a/views/default-min.handlebars b/views/default-min.handlebars index 622b1a4d..49ee4a7a 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -7462,14 +7462,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/default.handlebars b/views/default.handlebars index f649d130..f8387527 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -8473,14 +8473,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default-min_cs.handlebars b/views/translations/default-min_cs.handlebars index 8d4cb16a..94b656ac 100644 --- a/views/translations/default-min_cs.handlebars +++ b/views/translations/default-min_cs.handlebars @@ -7462,14 +7462,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default-min_fr.handlebars b/views/translations/default-min_fr.handlebars index d5d73bf2..e1697d6b 100644 --- a/views/translations/default-min_fr.handlebars +++ b/views/translations/default-min_fr.handlebars @@ -7462,14 +7462,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default-min_ja.handlebars b/views/translations/default-min_ja.handlebars index 94294206..b3057bbb 100644 --- a/views/translations/default-min_ja.handlebars +++ b/views/translations/default-min_ja.handlebars @@ -7462,14 +7462,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default-min_pt.handlebars b/views/translations/default-min_pt.handlebars index 844f3468..d7ebb02a 100644 --- a/views/translations/default-min_pt.handlebars +++ b/views/translations/default-min_pt.handlebars @@ -7462,14 +7462,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default_cs.handlebars b/views/translations/default_cs.handlebars index af9996ba..18eeb17a 100644 --- a/views/translations/default_cs.handlebars +++ b/views/translations/default_cs.handlebars @@ -8471,14 +8471,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default_fr.handlebars b/views/translations/default_fr.handlebars index 89d1e838..e65275ef 100644 --- a/views/translations/default_fr.handlebars +++ b/views/translations/default_fr.handlebars @@ -8471,14 +8471,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default_ja.handlebars b/views/translations/default_ja.handlebars index f1c1c480..e4eec061 100644 --- a/views/translations/default_ja.handlebars +++ b/views/translations/default_ja.handlebars @@ -8471,14 +8471,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/views/translations/default_pt.handlebars b/views/translations/default_pt.handlebars index b41b4d1c..216e0f2c 100644 --- a/views/translations/default_pt.handlebars +++ b/views/translations/default_pt.handlebars @@ -8471,14 +8471,13 @@ if ((x == null) && (Q('p4email').value.length > 0) && (ve == false)) { QE('idx_dlgOkButton', false); return; } var ok = true; - if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } + if ((features & 0x200000) == 0) { ok &= (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))); } // Username is not email address if (Q('p4randomPassword').checked == false) { ok &= (Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value && checkPasswordRequirements(Q('p4pass1').value, passRequirements)); } - if (ok && passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } } QE('idx_dlgOkButton', ok); } function showCreateNewAccountDialogEx() { - var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; + var username = ((features & 0x200000) == 0) ? Q('p4name').value : Q('p4email').value; // Username is email address var x = { action: 'adduser', username: username, email: Q('p4email').value, pass: Q('p4pass1').value, resetNextLogin: Q('p4resetNextLogin').checked, randomPassword: Q('p4randomPassword').checked }; if (serverinfo.emailcheck) { x.emailVerified = Q('p4verifiedEmail').checked; diff --git a/webserver.js b/webserver.js index cf7c17e2..5a49aec4 100644 --- a/webserver.js +++ b/webserver.js @@ -1470,7 +1470,16 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { // Figure out the minimal password requirement var passRequirements = null; if (domain.passwordrequirements != null) { - if (domain.passrequirementstr == null) { domain.passwordrequirementsstr = encodeURIComponent(JSON.stringify(domain.passwordrequirements)); } + if (domain.passrequirementstr == null) { + var passRequirements = {}; + if (typeof domain.passwordrequirements.min == 'number') { passRequirements.min = domain.passwordrequirements.min; } + if (typeof domain.passwordrequirements.max == 'number') { passRequirements.max = domain.passwordrequirements.max; } + if (typeof domain.passwordrequirements.upper == 'number') { passRequirements.upper = domain.passwordrequirements.upper; } + if (typeof domain.passwordrequirements.lower == 'number') { passRequirements.lower = domain.passwordrequirements.lower; } + if (typeof domain.passwordrequirements.numeric == 'number') { passRequirements.numeric = domain.passwordrequirements.numeric; } + if (typeof domain.passwordrequirements.nonalpha == 'number') { passRequirements.nonalpha = domain.passwordrequirements.nonalpha; } + domain.passwordrequirementsstr = encodeURIComponent(JSON.stringify(passRequirements)); + } passRequirements = domain.passwordrequirementsstr; }