Factored adduserbatch
Noah Zalev committed
Dec 7, 2021 at 19:47 UTC
0fc6dc77f151848c1ef021e5000a91a1e39d8409
1 file changed
+79
-80
meshuser.js
+79
-80
@@ -1375,86 +1375,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1375
// TODO: Notify all sessions on other peers.
1376
1377
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'userbroadcast', responseid: command.responseid, result: 'ok' })); } catch (ex) { } }
1378
- break;
1379
- }
1380
- case 'adduserbatch':
1381
- {
1382
- var err = null;
1383
-
1384
- // Add many new user accounts
1385
- if ((user.siteadmin & 2) == 0) { err = 'Access denied'; }
1386
- else if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) { err = 'Unable to create users when in SSPI or LDAP mode'; }
1387
- else if (!Array.isArray(command.users)) { err = 'Invalid users'; }
1388
- else {
1389
- var userCount = 0;
1390
- for (var i in command.users) {
1391
- if (domain.usernameisemail) { if (command.users[i].email) { command.users[i].user = command.users[i].email; } else { command.users[i].email = command.users[i].user; } } // If the email is the username, set this here.
1392
- if (common.validateUsername(command.users[i].user, 1, 256) == false) { err = 'Invalid username'; break; } // Username is between 1 and 64 characters, no spaces
1393
- if ((command.users[i].user[0] == '~') || (command.users[i].user.indexOf('/') >= 0)) { err = 'Invalid username'; break; } // This is a reserved user name or invalid name
1394
- if (common.validateString(command.users[i].pass, 1, 256) == false) { err = 'Invalid password'; break; } // Password is between 1 and 256 characters
1395
- if (common.checkPasswordRequirements(command.users[i].pass, domain.passwordrequirements) == false) { err = 'Invalid password'; break; } // Password does not meet requirements
1396
- if ((command.users[i].email != null) && (common.validateEmail(command.users[i].email, 1, 1024) == false)) { err = 'Invalid email'; break; } // Check if this is a valid email address
1397
- userCount++;
1398
- }
1399
- }
1400
-
1401
- // Handle any errors
1402
- if (err != null) {
1403
- if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'adduserbatch', responseid: command.responseid, result: err })); } catch (ex) { } }
1404
- break;
1405
- }
1406
-
1407
- // Check if we exceed the maximum number of user accounts
1408
- db.isMaxType(domain.limits.maxuseraccounts + userCount, 'user', domain.id, function (maxExceed) {
1409
- if (maxExceed) {
1410
- // Account count exceed, do notification
1411
-
1412
- // Create the notification message
1413
- var notification = { action: 'msg', type: 'notify', id: Math.random(), value: "Account limit reached.", title: "Server Limit", userid: user._id, username: user.name, domain: domain.id, titleid: 2, msgid: 10 };
1414
-
1415
- // Get the list of sessions for this user
1416
- var sessions = parent.wssessions[user._id];
1417
- if (sessions != null) { for (i in sessions) { try { if (sessions[i].domainid == domain.id) { sessions[i].send(JSON.stringify(notification)); } } catch (ex) { } } }
1418
- // TODO: Notify all sessions on other peers.
1419
- } else {
1420
- for (var i in command.users) {
1421
- // Check if this is an existing user
1422
- var newuserid = 'user/' + domain.id + '/' + command.users[i].user.toLowerCase();
1423
- var newuser = { type: 'user', _id: newuserid, name: command.users[i].user, creation: Math.floor(Date.now() / 1000), domain: domain.id };
1424
- if (domain.newaccountsrights) { newuser.siteadmin = domain.newaccountsrights; }
1425
- if (common.validateString(command.users[i].realname, 1, 256)) { newuser.realname = command.users[i].realname; }
1426
- if (command.users[i].email != null) { newuser.email = command.users[i].email.toLowerCase(); if (command.users[i].emailVerified === true) { newuser.emailVerified = true; } } // Email, always lowercase
1427
- if (command.users[i].resetNextLogin === true) { newuser.passchange = -1; } else { newuser.passchange = Math.floor(Date.now() / 1000); }
1428
- if (user.groups) { newuser.groups = user.groups; } // New accounts are automatically part of our groups (Realms).
1429
-
1430
- if (parent.users[newuserid] == null) {
1431
- parent.users[newuserid] = newuser;
1432
-
1433
- // Create a user, generate a salt and hash the password
1434
- require('./pass').hash(command.users[i].pass, function (err, salt, hash, newuser) {
1435
- if (err) throw err;
1436
- newuser.salt = salt;
1437
- newuser.hash = hash;
1438
- db.SetUser(newuser);
1439
-
1440
- var event, targets = ['*', 'server-users'];
1441
- if (newuser.groups) { for (var i in newuser.groups) { targets.push('server-users:' + i); } }
1442
- if (newuser.email == null) {
1443
- event = { etype: 'user', userid: newuser._id, username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msgid: 64, msgArgs: [newuser.name], msg: 'Account created, username is ' + newuser.name, domain: domain.id };
1444
- } else {
1445
- event = { etype: 'user', userid: newuser._id, username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msgid: 65, msgArgs: [newuser.email], msg: 'Account created, email is ' + newuser.email, domain: domain.id };
1446
- }
1447
- if (parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
1448
- parent.parent.DispatchEvent(targets, obj, event);
1449
-
1450
- // Log in the auth log
1451
- if (parent.parent.authlog) { parent.parent.authLog('https', 'User ' + user.name + ' created user account ' + newuser.name); }
1452
- }, newuser);
1453
- }
1454
- }
1455
- }
1456
- });
1457
-
1378
break;
1379
}
1380
case 'adduser':
@@ -5844,6 +5764,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5764
}
5765
5766
const serverCommands = {
5767
+ 'adduserbatch': serverCommandAddUserBatch,
5768
'files': serverCommandFiles,
5769
'getnetworkinfo': serverCommandGetNetworkInfo,
5770
'getsysinfo': serverCommandGetSysInfo,
@@ -5918,6 +5839,84 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5839
'webstats': [serverUserCommandWebStats, ""]
5840
};
5841
5842
+ function serverCommandAddUserBatch(command) {
5843
+ var err = null;
5844
+
5845
+ // Add many new user accounts
5846
+ if ((user.siteadmin & 2) == 0) { err = 'Access denied'; }
5847
+ else if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) { err = 'Unable to create users when in SSPI or LDAP mode'; }
5848
+ else if (!Array.isArray(command.users)) { err = 'Invalid users'; }
5849
+ else {
5850
+ var userCount = 0;
5851
+ for (var i in command.users) {
5852
+ if (domain.usernameisemail) { if (command.users[i].email) { command.users[i].user = command.users[i].email; } else { command.users[i].email = command.users[i].user; } } // If the email is the username, set this here.
5853
+ if (common.validateUsername(command.users[i].user, 1, 256) == false) { err = 'Invalid username'; return; } // Username is between 1 and 64 characters, no spaces
5854
+ if ((command.users[i].user[0] == '~') || (command.users[i].user.indexOf('/') >= 0)) { err = 'Invalid username'; return; } // This is a reserved user name or invalid name
5855
+ if (common.validateString(command.users[i].pass, 1, 256) == false) { err = 'Invalid password'; return; } // Password is between 1 and 256 characters
5856
+ if (common.checkPasswordRequirements(command.users[i].pass, domain.passwordrequirements) == false) { err = 'Invalid password'; return; } // Password does not meet requirements
5857
+ if ((command.users[i].email != null) && (common.validateEmail(command.users[i].email, 1, 1024) == false)) { err = 'Invalid email'; return; } // Check if this is a valid email address
5858
+ userCount++;
5859
+ }
5860
+ }
5861
+
5862
+ // Handle any errors
5863
+ if (err != null) {
5864
+ if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'adduserbatch', responseid: command.responseid, result: err })); } catch (ex) { } }
5865
+ return;
5866
+ }
5867
+
5868
+ // Check if we exceed the maximum number of user accounts
5869
+ db.isMaxType(domain.limits.maxuseraccounts + userCount, 'user', domain.id, function (maxExceed) {
5870
+ if (maxExceed) {
5871
+ // Account count exceed, do notification
5872
+
5873
+ // Create the notification message
5874
+ var notification = { action: 'msg', type: 'notify', id: Math.random(), value: "Account limit reached.", title: "Server Limit", userid: user._id, username: user.name, domain: domain.id, titleid: 2, msgid: 10 };
5875
+
5876
+ // Get the list of sessions for this user
5877
+ var sessions = parent.wssessions[user._id];
5878
+ if (sessions != null) { for (var i in sessions) { try { if (sessions[i].domainid == domain.id) { sessions[i].send(JSON.stringify(notification)); } } catch (ex) { } } }
5879
+ // TODO: Notify all sessions on other peers.
5880
+ } else {
5881
+ for (var i in command.users) {
5882
+ // Check if this is an existing user
5883
+ var newuserid = 'user/' + domain.id + '/' + command.users[i].user.toLowerCase();
5884
+ var newuser = { type: 'user', _id: newuserid, name: command.users[i].user, creation: Math.floor(Date.now() / 1000), domain: domain.id };
5885
+ if (domain.newaccountsrights) { newuser.siteadmin = domain.newaccountsrights; }
5886
+ if (common.validateString(command.users[i].realname, 1, 256)) { newuser.realname = command.users[i].realname; }
5887
+ if (command.users[i].email != null) { newuser.email = command.users[i].email.toLowerCase(); if (command.users[i].emailVerified === true) { newuser.emailVerified = true; } } // Email, always lowercase
5888
+ if (command.users[i].resetNextLogin === true) { newuser.passchange = -1; } else { newuser.passchange = Math.floor(Date.now() / 1000); }
5889
+ if (user.groups) { newuser.groups = user.groups; } // New accounts are automatically part of our groups (Realms).
5890
+
5891
+ if (parent.users[newuserid] == null) {
5892
+ parent.users[newuserid] = newuser;
5893
+
5894
+ // Create a user, generate a salt and hash the password
5895
+ require('./pass').hash(command.users[i].pass, function (err, salt, hash, newuser) {
5896
+ if (err) throw err;
5897
+ newuser.salt = salt;
5898
+ newuser.hash = hash;
5899
+ db.SetUser(newuser);
5900
+
5901
+ var event, targets = ['*', 'server-users'];
5902
+ if (newuser.groups) { for (var i in newuser.groups) { targets.push('server-users:' + i); } }
5903
+ if (newuser.email == null) {
5904
+ event = { etype: 'user', userid: newuser._id, username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msgid: 64, msgArgs: [newuser.name], msg: 'Account created, username is ' + newuser.name, domain: domain.id };
5905
+ } else {
5906
+ event = { etype: 'user', userid: newuser._id, username: newuser.name, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msgid: 65, msgArgs: [newuser.email], msg: 'Account created, email is ' + newuser.email, domain: domain.id };
5907
+ }
5908
+ if (parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to create the user. Another event will come.
5909
+ parent.parent.DispatchEvent(targets, obj, event);
5910
+
5911
+ // Log in the auth log
5912
+ if (parent.parent.authlog) { parent.parent.authLog('https', 'User ' + user.name + ' created user account ' + newuser.name); }
5913
+ }, newuser);
5914
+ }
5915
+ }
5916
+ }
5917
+ });
5918
+ }
5919
+
5920
function serverCommandFiles(command) {
5921
// Send the full list of server files to the browser app
5922
updateUserFiles(user, ws, domain);