Fixed email validation on server and web page
Ylian Saint-Hilaire committed
May 16, 2018 at 15:49 UTC
8580f5486111618c32edcf09bc4095130a9cc0aa
6 files changed
+79
-108
common.js
+3
-1
@@ -132,4 +132,6 @@ module.exports.validateString = function(str, minlen, maxlen) { return ((str !=
132
module.exports.validateInt = function(int, minval, maxval) { return ((int != null) && (typeof int == 'number') && ((minval == null) || (int >= minval)) && ((maxval == null) || (int <= maxval))); }
133
module.exports.validateArray = function (array, minlen, maxlen) { return ((array != null) && Array.isArray(array) && ((minlen == null) || (array.length >= minlen)) && ((maxlen == null) || (array.length <= maxlen))); }
134
module.exports.validateStrArray = function (array, minlen, maxlen) { if (((array != null) && Array.isArray(array)) == false) return false; for (var i in array) { if ((typeof array[i] != 'string') && ((minlen == null) || (array[i].length >= minlen)) && ((maxlen == null) || (array[i].length <= maxlen))) return false; } return true; }
135
-module.exports.validateObject = function(obj) { return ((obj != null) && (typeof obj == 'object')); }
135
+module.exports.validateObject = function (obj) { return ((obj != null) && (typeof obj == 'object')); }
136
+module.exports.validateEmail = function (email, minlen, maxlen) { if (module.exports.validateString(email, minlen, maxlen) == false) return false; var emailReg = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; return emailReg.test(email); }
137
+module.exports.validateUsername = function (username, minlen, maxlen) { return (module.exports.validateString(username, minlen, maxlen) && (username.indexOf(' ') == -1)); }
\ No newline at end of file
meshuser.js
+33
-35
@@ -341,41 +341,38 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
341
case 'changeemail':
342
{
343
// Change the email address
344
- if (obj.common.validateString(command.email, 3, 1024) == false) return;
345
- var x = command.email.split('@');
346
- if ((x.length == 2) && (x[0].length > 0) && (x[1].split('.').length > 1) && (x[1].length > 2)) {
347
- if (obj.parent.users[req.session.userid].email != command.email) {
348
- // Check if this email is already validated on a different account
349
- obj.db.GetUserWithVerifiedEmail(domain.id, command.email, function (err, docs) {
350
- if (docs.length > 0) {
351
- // Notify the duplicate email error
352
- ws.send(JSON.stringify({ action: 'msg', type: 'notify', value: 'Failed to change email address, another account already using: <b>' + EscapeHtml(command.email) + '</b>.' }));
344
+ if (obj.common.validateEmail(command.email, 1, 256) == false) return;
345
+ if (obj.parent.users[req.session.userid].email != command.email) {
346
+ // Check if this email is already validated on a different account
347
+ obj.db.GetUserWithVerifiedEmail(domain.id, command.email, function (err, docs) {
348
+ if (docs.length > 0) {
349
+ // Notify the duplicate email error
350
+ ws.send(JSON.stringify({ action: 'msg', type: 'notify', value: 'Failed to change email address, another account already using: <b>' + EscapeHtml(command.email) + '</b>.' }));
351
+ } else {
352
+ // Update the user's email
353
+ var oldemail = user.email;
354
+ user.email = command.email;
355
+ user.emailVerified = false;
356
+ obj.parent.db.SetUser(user);
357
+
358
+ // Event the change
359
+ var userinfo = obj.common.Clone(user);
360
+ delete userinfo.hash;
361
+ delete userinfo.passhint;
362
+ delete userinfo.salt;
363
+ delete userinfo.type;
364
+ delete userinfo.domain;
365
+ delete userinfo.subscriptions;
366
+ delete userinfo.passtype;
367
+ var message = { etype: 'user', username: userinfo.name, account: userinfo, action: 'accountchange', domain: domain.id };
368
+ if (oldemail != null) {
369
+ message.msg = 'Changed email of user ' + userinfo.name + ' from ' + oldemail + ' to ' + user.email;
370
} else {
354
- // Update the user's email
355
- var oldemail = user.email;
356
- user.email = command.email;
357
- user.emailVerified = false;
358
- obj.parent.db.SetUser(user);
359
-
360
- // Event the change
361
- var userinfo = obj.common.Clone(user);
362
- delete userinfo.hash;
363
- delete userinfo.passhint;
364
- delete userinfo.salt;
365
- delete userinfo.type;
366
- delete userinfo.domain;
367
- delete userinfo.subscriptions;
368
- delete userinfo.passtype;
369
- var message = { etype: 'user', username: userinfo.name, account: userinfo, action: 'accountchange', domain: domain.id };
370
- if (oldemail != null) {
371
- message.msg = 'Changed email of user ' + userinfo.name + ' from ' + oldemail + ' to ' + user.email;
372
- } else {
373
- message.msg = 'Set email of user ' + userinfo.name + ' to ' + user.email;
374
- }
375
- obj.parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, message);
371
+ message.msg = 'Set email of user ' + userinfo.name + ' to ' + user.email;
372
}
377
- });
378
- }
373
+ obj.parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, message);
374
+ }
375
+ });
376
}
377
break;
378
}
@@ -435,13 +432,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
432
{
433
// Add a new user account
434
if ((user.siteadmin & 2) == 0) break;
438
- if (obj.common.validateString(command.username, 1, 64) == false) break; // Username is between 1 and 64 characters
435
+ if (obj.common.validateUsername(command.username, 1, 64) == false) break; // Username is between 1 and 64 characters, no spaces
436
if (obj.common.validateString(command.pass, 1, 256) == false) break; // Password is between 1 and 256 characters
437
+ if ((command.email != null) && (obj.common.validateEmail(command.email, 1, 256) == false)) break; // Check if this is a valid email address
438
var newusername = command.username, newuserid = 'user/' + domain.id + '/' + command.username.toLowerCase();
439
if (newusername == '~') break; // This is a reserved user name
440
if (!obj.parent.users[newuserid]) {
441
var newuser = { type: 'user', _id: newuserid, name: newusername, creation: Date.now(), domain: domain.id };
444
- if (obj.common.validateString(command.email, 1, 256) == true) { newuser.email = command.email; } // Email is between 1 and 256 characters
442
+ if (command.email != null) { newuser.email = command.email; } // Email
443
obj.parent.users[newuserid] = newuser;
444
// Create a user, generate a salt and hash the password
445
require('./pass').hash(command.pass, function (err, salt, hash) {
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.1.7-i",
3
+ "version": "0.1.7-k",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
views/default.handlebars
+34
-45
@@ -1952,7 +1952,7 @@
1952
x += "</div>";
1953
1954
// Linux agent install
1955
- x += "<div id=agins_linux style=display:none>To add a computer to " + EscapeHtml(mesh.name) + " run the following command. Root credentails will be needed:<br />";
1955
+ x += "<div id=agins_linux style=display:none>To add a computer to " + EscapeHtml(mesh.name) + " run the following command. Root credentials will be needed.<br />";
1956
x += '<textarea id=agins_linux_area rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>';
1957
x += "</div>";
1958
@@ -1963,7 +1963,7 @@
1963
x += "</div>";
1964
1965
// Linux agent uninstall
1966
- x += "<div id=agins_linux_un style=display:none>To remove a mesh agent, run the following command. Root credentails will be needed:<br />";
1966
+ x += "<div id=agins_linux_un style=display:none>To remove a mesh agent, run the following command. Root credentials will be needed.<br />";
1967
x += '<textarea id=agins_linux_area_un rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>';
1968
x += "</div>";
1969
@@ -4505,7 +4505,7 @@
4505
function account_showChangeEmail() {
4506
if (xxdialogMode) return;
4507
var x = "Change your account e-mail address here.<br /><br />";
4508
- x += addHtmlValue('Email', '<input id=dp2email style=width:230px maxlength=32 onchange=account_validateEmail() onkeyup=account_validateEmail(event) />');
4508
+ x += addHtmlValue('Email', '<input id=dp2email style=width:230px maxlength=256 onchange=account_validateEmail() onkeyup=account_validateEmail(event) />');
4509
setDialogMode(2, "Email Address Change", 3, account_changeEmail, x);
4510
if (userinfo.email != null) { Q('dp2email').value = userinfo.email; }
4511
account_validateEmail();
@@ -4513,9 +4513,7 @@
4513
}
4514
4515
function account_validateEmail(e, email) {
4516
- var x = Q('dp2email').value.split('@');
4517
- x = (x.length == 2) && (x[0].length > 0) && (x[1].split('.').length > 1) && (x[1].length > 2) && (Q('dp2email').value.length < 1024) && (Q('dp2email').value != userinfo.email);
4518
- QE('idx_dlgOkButton', x);
4516
+ QE('idx_dlgOkButton', validateEmail(Q('dp2email').value) && (Q('dp2email').value != userinfo.email));
4517
if ((x == true) && (e != null) && (e.keyCode == 13)) { dialogclose(1); }
4518
}
4519
@@ -4526,13 +4524,12 @@
4524
function account_showDeleteAccount() {
4525
if (xxdialogMode) return;
4526
var x = "To delete this account, type in the account password in both boxes below and hit ok.<br /><br />";
4529
- x += "<form action='{{{domainurl}}}deleteaccount' method='post'><table style=margin-left:80px><tr>";
4527
+ x += "<form action='{{{domainurl}}}deleteaccount' method=post><table style=margin-left:80px><tr>";
4528
x += "<td align=right>Password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>";
4531
- x += "</tr><tr>";
4532
- x += "<td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>";
4533
- x += '</tr></table><br /><div style="padding:10px;margin-bottom:4px">';
4534
- x += '<input id="account_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)">';
4535
- x += '<input id="account_dlgOkButton" type="submit" value="OK" style="float:right;width:80px" onclick="dialogclose(1)">';
4529
+ x += "</tr><tr><td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>";
4530
+ x += '</tr></table><br /><div style=padding:10px;margin-bottom:4px>';
4531
+ x += '<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>';
4532
+ x += '<input id=account_dlgOkButton type=submit value=OK style="float:right;width:80px" onclick=dialogclose(1)>';
4533
x += '</div><br /></form>';
4534
setDialogMode(2, "Delete Account", 0, null, x);
4535
account_validateDeleteAccount();
@@ -4542,15 +4539,13 @@
4539
function account_showChangePassword() {
4540
if (xxdialogMode) return;
4541
var x = "Change your account password by entering the new password twice in the boxes below.<br /><br />";
4545
- x += "<form action='{{{domainurl}}}changepassword' method='post'><table style=margin-left:60px><tr>";
4542
+ x += "<form action='{{{domainurl}}}changepassword' method=post><table style=margin-left:60px><tr>";
4543
x += "<td align=right>Password:</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td>";
4547
- x += "</tr><tr>";
4548
- x += "<td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() /></td>";
4549
- x += "</tr><tr>";
4550
- x += "<td align=right>Password Hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off /></td>";
4551
- x += '</tr></table><br /><div style="padding:10px;margin-bottom:4px">';
4552
- x += '<input id=account_dlgCancelButton type=button value="Cancel" style="float:right;width:80px;margin-left:5px" onclick=dialogclose(0)>';
4553
- x += '<input id=account_dlgOkButton type=submit value="OK" style="float:right;width:80px" onclick="dialogclose(1)">';
4544
+ x += "</tr><tr><td align=right>Password:</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() /></td>";
4545
+ x += "</tr><tr><td align=right>Password Hint:</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off /></td>";
4546
+ x += '</tr></table><br /><div style=padding:10px;margin-bottom:4px>';
4547
+ x += '<input id=account_dlgCancelButton type=button value=Cancel style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>';
4548
+ x += '<input id=account_dlgOkButton type=submit value=OK style="float:right;width:80px" onclick=dialogclose(1)>';
4549
x += '</div><br /></form>';
4550
setDialogMode(2, "Change Password", 0, null, x);
4551
account_validateDeleteAccount();
@@ -4704,13 +4699,17 @@
4699
4700
x += '<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>User Authorizations</th><th scope=col style=text-align:left></th></tr>';
4701
4707
- var count = 1;
4708
- for (var i in currentMesh.links) {
4709
- var rights = 'Partial Rights', r = currentMesh.links[i].rights, xusername = i.split('/')[2];
4702
+ // Sort the users for this mesh
4703
+ var count = 1, sortedusers = [];
4704
+ for (var i in currentMesh.links) { sortedusers.push({ id: i, name: i.split('/')[2], rights: currentMesh.links[i].rights }); }
4705
+ sortedusers.sort(function(a, b) { if (a.name > b.name) return 1; if (a.name < b.name) return -1; return 0; });
4706
+
4707
+ // Display all users for this mesh
4708
+ for (var i in sortedusers) {
4709
+ var trash = '', rights = 'Partial Rights', r = sortedusers[i].rights;
4710
if (r == 0xFFFFFFFF) rights = 'Full Administrator'; else if (r == 0) rights = 'No Rights';
4711
- var trash = '';
4712
- if ((i != userinfo._id) && (meshrights == 0xFFFFFFFF || (((meshrights & 2) != 0) && (rights != 0xFFFFFFFF)))) { trash = '<a onclick=p20deleteUser(event,"' + i + '") title="Remote user rights to this mesh" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
4713
- x += '<tr onclick=p20viewuser("' + i + '") style=cursor:pointer' + (((count % 2) == 0)?';background-color:#DDD':'') + '><td><div title="Mesh User" class=m2></div><div> ' + xusername + '<div></div></div></td><td><div style=float:right>' + trash + '</div><div>' + rights + '</div></td></tr>';
4711
+ if ((i != userinfo._id) && (meshrights == 0xFFFFFFFF || (((meshrights & 2) != 0)))) { trash = '<a onclick=p20deleteUser(event,"' + encodeURIComponent(sortedusers[i].id) + '") title="Remote user rights to this mesh" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
4712
+ x += '<tr onclick=p20viewuser("' + encodeURIComponent(sortedusers[i].id) + '") style=cursor:pointer' + (((count % 2) == 0)?';background-color:#DDD':'') + '><td><div title="Mesh User" class=m2></div><div> ' + sortedusers[i].name + '<div></div></div></td><td><div style=float:right>' + trash + '</div><div>' + rights + '</div></td></tr>';
4713
++count;
4714
}
4715
@@ -4809,9 +4808,8 @@
4808
4809
function p20viewuser(userid) {
4810
if (xxdialogMode) return;
4812
- var cmeshrights = currentMesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights;
4813
- var meshrights = currentMesh.links[userid].rights;
4814
- var r = '';
4811
+ userid = decodeURIComponent(userid);
4812
+ var r = '', cmeshrights = currentMesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights, meshrights = currentMesh.links[userid].rights;
4813
if (meshrights == 0xFFFFFFFF) r = ', Full Administrator (all rights)'; else {
4814
if ((meshrights & 1) != 0) r += ', Edit Mesh';
4815
if ((meshrights & 2) != 0) r += ', Manage Mesh Users';
@@ -4824,26 +4822,15 @@
4822
}
4823
r = r.substring(2);
4824
if (r == '') { r = 'No Rights'; }
4827
- var x = addHtmlValue('User Name', userid.split('/')[2]);
4825
+ var buttons = 1, x = addHtmlValue('User Name', userid.split('/')[2]);
4826
x += addHtmlValue('Permissions', r);
4829
- var buttons = 1;
4827
if ((('user/{{{domain}}}/' + userinfo.name.toLowerCase()) != userid) && (cmeshrights == 0xFFFFFFFF || (((cmeshrights & 2) != 0) && (meshrights != 0xFFFFFFFF)))) buttons += 4;
4828
setDialogMode(2, "Mesh User", buttons, p20viewuserEx, x, userid);
4829
}
4830
4834
- function p20viewuserEx(button, userid) {
4835
- if (button != 2) return;
4836
- setDialogMode(2, "Remote Mesh User", 3, p20viewuserEx2, "Confirm removal of user " + userid.split('/')[2] + "?", userid);
4837
- }
4838
-
4839
- function p20deleteUser(e, userid) {
4840
- haltEvent(e);
4841
- p20viewuserEx(2, userid);
4842
- }
4843
-
4844
- function p20viewuserEx2(button, userid) {
4845
- meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid});
4846
- }
4831
+ function p20viewuserEx(button, userid) { if (button != 2) return; setDialogMode(2, "Remote Mesh User", 3, p20viewuserEx2, "Confirm removal of user " + userid.split('/')[2] + "?", userid); }
4832
+ function p20deleteUser(e, userid) { haltEvent(e); p20viewuserEx(2, decodeURIComponent(userid)); }
4833
+ function p20viewuserEx2(button, userid) { meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid}); }
4834
4835
//
4836
// MY FILES
@@ -5216,7 +5203,8 @@
5203
}
5204
5205
function showCreateNewAccountDialogValidate() {
5219
- QE('idx_dlgOkButton', (!Q('p4name') || (Q('p4name').value.length > 0)) && Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value);
5206
+ if ((Q('p4email').value.length > 0) && (validateEmail(Q('p4email').value)) == false) { QE('idx_dlgOkButton', false); return; }
5207
+ QE('idx_dlgOkButton', (!Q('p4name') || ((Q('p4name').value.length > 0) && (Q('p4name').value.indexOf(' ') == -1))) && Q('p4pass1').value.length > 0 && Q('p4pass1').value == Q('p4pass2').value);
5208
}
5209
5210
function showCreateNewAccountDialogEx() {
@@ -5784,6 +5772,7 @@
5772
function addHtmlValue2(t, v) { return '<div><div style=display:inline-block;float:right>' + v + '</div><div style=display:inline-block>' + t + '</div></div>'; }
5773
function parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = parsedUri[x]; break; } case 1: { r[name] = parsedUri[x]; var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } } } return r; }
5774
function focusTextBox(x) { setTimeout(function(){ Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); }
5775
+ function validateEmail(v) { var emailReg = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; return emailReg.test(v); }
5776
5777
</script>
5778
</body>
views/login.handlebars
+7
-25
@@ -215,19 +215,16 @@
215
}
216
217
function validateLogin(box, e) {
218
- var ok = (Q('username').value.length > 0 && Q('password').value.length > 0);
218
+ var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
219
QE('loginButton', ok);
220
setDialogMode(0);
221
- if ((e != null) && (e.keyCode == 13)) {
222
- if (box == 1) { Q('password').focus(); }
223
- if (box == 2) { Q('loginButton').click(); }
224
- }
221
+ if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
222
if (e != null) { haltEvent(e); }
223
}
224
225
function validateCreate(box,e) {
226
setDialogMode(0);
230
- var ok = ((Q('ausername').value.length > 0) && (checkEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
227
+ var ok = ((Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
228
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
229
QE('createButton', ok);
230
if (Q('apassword1').value == '') {
@@ -243,23 +240,15 @@
240
if (box == 2) { Q('apassword1').focus(); }
241
if (box == 3) { Q('apassword2').focus(); }
242
if (box == 4) { Q('apasswordhint').focus(); }
246
- if (box == 5) {
247
- if (newAccountPass == 1) {
248
- Q('anewaccountpass').focus();
249
- } else {
250
- Q('createButton').click();
251
- }
252
- }
253
- if (box == 6) {
254
- Q('createButton').click();
255
- }
243
+ if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
244
+ if (box == 6) { Q('createButton').click(); }
245
}
246
if (e != null) { haltEvent(e); }
247
}
248
249
function validateReset(e) {
250
setDialogMode(0);
262
- var x = checkEmail(Q('remail').value);
251
+ var x = validateEmail(Q('remail').value);
252
QE('eresetButton', x);
253
if ((e != null) && (e.keyCode == 13) && (x == true)) {
254
Q('eresetButton').click();
@@ -267,14 +256,6 @@
256
if (e != null) { haltEvent(e); }
257
}
258
270
- // Return true is the input string looks like an email address
271
- function checkEmail(str) {
272
- var x = str.split('@');
273
- var ok = ((x.length == 2) && (x[0].length > 0) && (x[1].split('.').length > 1) && (x[1].length > 2));
274
- if (ok == true) { var y = x[1].split('.'); for (var i in y) { if (y[i].length == 0) { ok = false; } } }
275
- return ok;
276
- }
277
-
259
// Return a password strength score
260
function checkPasswordStrength(password) {
261
var r = 0, letters = {}, varCount = 0, variations = { digits: /\d/.test(password), lower: /[a-z]/.test(password), upper: /[A-Z]/.test(password), nonWords: /\W/.test(password) }
@@ -328,6 +309,7 @@
309
function getDocWidth() { if (window.innerWidth) return window.innerWidth; if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0) return document.documentElement.clientWidth; return document.getElementsByTagName('body')[0].clientWidth; }
310
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
311
function haltReturn(e) { if (e.keyCode == 13) { haltEvent(e); } }
312
+ function validateEmail(v) { var emailReg = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; return emailReg.test(v); }
313
314
</script>
315
</body>
webserver.js
+1
-1
@@ -350,7 +350,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
350
var domain = checkUserIpAddress(req, res);
351
if (domain == null) return;
352
if (domain.newaccounts == 0) { res.sendStatus(401); return; }
353
- if (!req.body.username || !req.body.email || !req.body.password1 || !req.body.password2 || (req.body.password1 != req.body.password2) || req.body.username == '~') {
353
+ if (!obj.common.validateUsername(req.body.username, 1, 64) || !obj.common.validateEmail(req.body.email, 1, 256) || !obj.common.validateString(req.body.password1, 1, 256) || !obj.common.validateString(req.body.password2, 1, 256) || (req.body.password1 != req.body.password2) || req.body.username == '~') {
354
req.session.loginmode = 2;
355
req.session.error = '<b style=color:#8C001A>Unable to create account.</b>';;
356
res.redirect(domain.url);