Added email validation login page.
This commit is contained in:
parent
26111b84d2
commit
c89f8fd524
Binary file not shown.
|
@ -298,9 +298,9 @@ module.exports.CreateAmtScanner = function (parent) {
|
||||||
//console.log(rinfo.address + ': Intel AMT ' + majorVersion + '.' + minorVersion + ', ' + provisioningStateStr + '-Provisioning, Open Ports: [' + openPorts.join(', ') + ']');
|
//console.log(rinfo.address + ': Intel AMT ' + majorVersion + '.' + minorVersion + ', ' + provisioningStateStr + '-Provisioning, Open Ports: [' + openPorts.join(', ') + ']');
|
||||||
obj.dns.reverse(rinfo.address, function (err, hostnames) {
|
obj.dns.reverse(rinfo.address, function (err, hostnames) {
|
||||||
if ((err == null) && (hostnames != null) && (hostnames.length > 0)) {
|
if ((err == null) && (hostnames != null) && (hostnames.length > 0)) {
|
||||||
user.results[rinfo.address] = { ver: majorVersion + '.' + minorVersion, tls: (((openPort == 16993) || (dualPorts == true)) ? 1 : 0), state: provisioningState, hostname: hostnames[0] };
|
user.results[rinfo.address] = { ver: majorVersion + '.' + minorVersion, tls: (((openPort == 16993) || (dualPorts == true)) ? 1 : 0), state: provisioningState, hostname: hostnames[0], hosttype: 'host' };
|
||||||
} else {
|
} else {
|
||||||
user.results[rinfo.address] = { ver: majorVersion + '.' + minorVersion, tls: (((openPort == 16993) || (dualPorts == true)) ? 1 : 0), state: provisioningState, hostname: rinfo.address };
|
user.results[rinfo.address] = { ver: majorVersion + '.' + minorVersion, tls: (((openPort == 16993) || (dualPorts == true)) ? 1 : 0), state: provisioningState, hostname: rinfo.address, hosttype: 'addr' };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "meshcentral",
|
"name": "meshcentral",
|
||||||
"version": "0.5.10",
|
"version": "0.5.11",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Remote Management",
|
"Remote Management",
|
||||||
"Intel AMT",
|
"Intel AMT",
|
||||||
|
|
|
@ -388,7 +388,7 @@ body {
|
||||||
color: blue;
|
color: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#loginpanel, #createpanel, #resetpanel, #tokenpanel, #resettokenpanel, #resetpasswordpanel, #resetpasswordpanel {
|
#loginpanel, #createpanel, #resetpanel, #tokenpanel, #resettokenpanel, #resetpasswordpanel, #resetpasswordpanel, #checkemailpanel {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #979797;
|
background-color: #979797;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2584,19 +2584,20 @@
|
||||||
var x = '';
|
var x = '';
|
||||||
if (message.event.results == null) {
|
if (message.event.results == null) {
|
||||||
// The scan could not occur because of an error. Likely the user range was invalid.
|
// The scan could not occur because of an error. Likely the user range was invalid.
|
||||||
x = '<div style=width:100%;text-align:center;margin-top:12px>' + "Unable to scan this address range." + '</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>' + "Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100" + '</div>';
|
x = '<div style=width:100%;text-align:center;margin-top:12px>' + "Unable to scan this address range." + '</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>' + "Sample IP range values" + '<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>';
|
||||||
} else {
|
} else {
|
||||||
// Go thru all the results and populate the dialog box
|
// Go thru all the results and populate the dialog box
|
||||||
amtScanResults = message.event.results;
|
amtScanResults = message.event.results;
|
||||||
for (var i in message.event.results) {
|
for (var i in message.event.results) {
|
||||||
var r = message.event.results[i], shortname = r.hostname;
|
var r = message.event.results[i], shortname = r.hostname;
|
||||||
|
if (r.hosttype == 'host') { shortname = capitalizeFirstLetter(shortname.split('.')[0]); }
|
||||||
if (shortname.length > 20) { shortname = shortname.substring(0, 20) + '...'; }
|
if (shortname.length > 20) { shortname = shortname.substring(0, 20) + '...'; }
|
||||||
var str = '<b title="' + EscapeHtml(r.hostname) + '">' + EscapeHtml(shortname) + '</b> - v' + r.ver;
|
var str = '<b title="' + EscapeHtml(r.hostname) + '">' + EscapeHtml(shortname) + '</b> - v' + r.ver;
|
||||||
if (r.state == 2) { if (r.tls == 1) { str += " with TLS."; } else { str += " without TLS."; } } else { str += ' not activated.'; }
|
if (r.state == 2) { if (r.tls == 1) { str += " with TLS."; } else { str += " without TLS."; } } else { str += ' not activated.'; }
|
||||||
x += '<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="' + EscapeHtml(i) + '" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>' + str + '</div></div></div>';
|
x += '<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="' + EscapeHtml(i) + '" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>' + str + '</div></div></div>';
|
||||||
}
|
}
|
||||||
// If no results where found, display a nice message
|
// If no results where found, display a nice message
|
||||||
if (x == '') { x = '<div style=width:100%;text-align:center;margin-top:12px>Scan returned no results.</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>'; }
|
if (x == '') { x = '<div style=width:100%;text-align:center;margin-top:12px>' + "Scan returned no results." + '</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>' + "Sample IP range values" + '<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>'; }
|
||||||
}
|
}
|
||||||
// Set the html in the dialog box and re-enable the scan button
|
// Set the html in the dialog box and re-enable the scan button
|
||||||
QH('dp1results', x);
|
QH('dp1results', x);
|
||||||
|
@ -3535,7 +3536,9 @@
|
||||||
if (elements[i].checked) {
|
if (elements[i].checked) {
|
||||||
var ipaddr = elements[i].getAttribute('tag');
|
var ipaddr = elements[i].getAttribute('tag');
|
||||||
var amtinfo = amtScanResults[ipaddr];
|
var amtinfo = amtScanResults[ipaddr];
|
||||||
meshserver.send({ action: 'addamtdevice', meshid: meshid, devicename: amtinfo.hostname, hostname: amtinfo.hostname, amtusername: '', amtpassword: '', amttls: amtinfo.tls });
|
var name = amtinfo.hostname;
|
||||||
|
if (amtinfo.hosttype == 'host') { name = capitalizeFirstLetter(name.split('.')[0]); }
|
||||||
|
meshserver.send({ action: 'addamtdevice', meshid: meshid, devicename: name, hostname: amtinfo.hostname, amtusername: '', amtpassword: '', amttls: amtinfo.tls });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12019,6 +12022,7 @@
|
||||||
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
|
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
|
||||||
function addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
function addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||||
function getOrderedList(objList, oname) { var r = []; for (var i in objList) { r.push(objList[i]); } r.sort(function(a, b) { var aa = a[oname].toLowerCase(), bb = b[oname].toLowerCase(); if (aa > bb) return 1; if (aa < bb) return -1; return 0; }); return r; }
|
function getOrderedList(objList, oname) { var r = []; for (var i in objList) { r.push(objList[i]); } r.sort(function(a, b) { var aa = a[oname].toLowerCase(), bb = b[oname].toLowerCase(); if (aa > bb) return 1; if (aa < bb) return -1; return 0; }); return r; }
|
||||||
|
function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); }
|
||||||
function nobreak(x) { return x.split(' ').join(' '); }
|
function nobreak(x) { return x.split(' ').join(' '); }
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -222,6 +222,31 @@
|
||||||
<input id=resetpasswordformargs name="urlargs" type="hidden" value="" />
|
<input id=resetpasswordformargs name="urlargs" type="hidden" value="" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<div id=checkemailpanel style="display:none;position:relative">
|
||||||
|
<form method=post>
|
||||||
|
<input type=hidden name=action value=checkemail />
|
||||||
|
<div id=message7></div>
|
||||||
|
<table id="checkCheckOperations" style="width:100%;display:none">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div id="unconfirmedEmail"></div><br />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div>
|
||||||
|
<input id=changeEmailButton type=button value="Change Email Address" onclick="changeEmailAddress()" />
|
||||||
|
<input id=checkEmailButton2 type=button value="Resend Confirmation Email" onclick="resentEmailConfirmation()" />
|
||||||
|
<input id=checkEmailButton type=submit style="display:none" />
|
||||||
|
<input id=checkEmailVal name=email type="hidden" value="" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr /><a onclick="return xgo(1,event);" href="#" style=cursor:pointer>Back to login</a>
|
||||||
|
<input id=checkemailformargs name="urlargs" type="hidden" value="" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -277,7 +302,7 @@
|
||||||
|
|
||||||
// Display the right server message
|
// Display the right server message
|
||||||
var messageid = parseInt('{{{messageid}}}');
|
var messageid = parseInt('{{{messageid}}}');
|
||||||
var okmessages = ['', "Hold on, reset mail sent.", "Email sent."];
|
var okmessages = ['', "Hold on, reset mail sent.", "Email sent.", "Email verification required, check your mailbox and click the confirmation link."];
|
||||||
var failmessages = ["Unable to create account.", "Account limit reached.", "Existing account with this email address.", "Invalid account creation token.", "Username already exists.", "Password rejected, use a different one.", "Invalid email.", "Account not found.", "Invalid token, try again.", "Unable to sent email.", "Account locked.", "Access denied.", "Login failed, check username and password.", "Password change requested.", "IP address blocked, try again later."];
|
var failmessages = ["Unable to create account.", "Account limit reached.", "Existing account with this email address.", "Invalid account creation token.", "Username already exists.", "Password rejected, use a different one.", "Invalid email.", "Account not found.", "Invalid token, try again.", "Unable to sent email.", "Account locked.", "Access denied.", "Login failed, check username and password.", "Password change requested.", "IP address blocked, try again later."];
|
||||||
if (messageid > 0) {
|
if (messageid > 0) {
|
||||||
var msg = '';
|
var msg = '';
|
||||||
|
@ -285,7 +310,7 @@
|
||||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||||
if (msg != '') {
|
if (msg != '') {
|
||||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
for (var i = 1; i < 8; i++) { QH('message' + i, msg); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +329,7 @@
|
||||||
Q('tokenformargs').value = xurlargs;
|
Q('tokenformargs').value = xurlargs;
|
||||||
Q('resettokenformargs').value = xurlargs;
|
Q('resettokenformargs').value = xurlargs;
|
||||||
Q('resetpasswordformargs').value = xurlargs;
|
Q('resetpasswordformargs').value = xurlargs;
|
||||||
|
Q('checkemailformargs').value = xurlargs;
|
||||||
}
|
}
|
||||||
|
|
||||||
//var webPageFullScreen = getstore('webPageFullScreen', true);
|
//var webPageFullScreen = getstore('webPageFullScreen', true);
|
||||||
|
@ -446,6 +472,7 @@
|
||||||
QV('message4', false);
|
QV('message4', false);
|
||||||
QV('message5', false);
|
QV('message5', false);
|
||||||
QV('message6', false);
|
QV('message6', false);
|
||||||
|
QV('message7', false);
|
||||||
go(x);
|
go(x);
|
||||||
haltEvent(e);
|
haltEvent(e);
|
||||||
return false;
|
return false;
|
||||||
|
@ -461,12 +488,18 @@
|
||||||
QV('tokenpanel', x == 4);
|
QV('tokenpanel', x == 4);
|
||||||
QV('resettokenpanel', x == 5);
|
QV('resettokenpanel', x == 5);
|
||||||
QV('resetpasswordpanel', x == 6);
|
QV('resetpasswordpanel', x == 6);
|
||||||
|
QV('checkemailpanel', x == 7);
|
||||||
if (x == 1) { Q('username').focus(); }
|
if (x == 1) { Q('username').focus(); }
|
||||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||||
if (x == 3) { Q('remail').focus(); }
|
if (x == 3) { Q('remail').focus(); }
|
||||||
if (x == 4) { Q('tokenInput').focus(); }
|
if (x == 4) { Q('tokenInput').focus(); }
|
||||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||||
if (x == 6) { Q('rapassword1').focus(); }
|
if (x == 6) { Q('rapassword1').focus(); }
|
||||||
|
if (x == 7) {
|
||||||
|
QH('unconfirmedEmail', passhint);
|
||||||
|
QV('checkCheckOperations', Q('unconfirmedEmail').innerHTML != '');
|
||||||
|
QH('checkEmailVal', passhint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateLogin(box, e) {
|
function validateLogin(box, e) {
|
||||||
|
@ -654,6 +687,28 @@
|
||||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeEmailAddress() {
|
||||||
|
var email = Q('unconfirmedEmail').innerHTML;
|
||||||
|
var x = addHtmlValue("Email", '<input id=dp1email style=width:230px maxlength=256 value="' + email + '" autocomplete=off onchange=validateEmailAddress() onkeyup=validateEmailAddress() />');
|
||||||
|
setDialogMode(1, "Email Confirmation", 3, changeEmailAddressEx, x);
|
||||||
|
validateEmailAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateEmailAddress() {
|
||||||
|
QE('idx_dlgOkButton', (validateEmail(Q('dp1email').value) == true));
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeEmailAddressEx() {
|
||||||
|
Q('checkEmailVal').value = Q('dp1email').value;
|
||||||
|
QH('unconfirmedEmail', Q('dp1email').value);
|
||||||
|
Q('checkEmailButton').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resentEmailConfirmation() {
|
||||||
|
Q('checkEmailVal').value = Q('unconfirmedEmail').innerHTML;
|
||||||
|
Q('checkEmailButton').click();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// POPUP DIALOG
|
// POPUP DIALOG
|
||||||
//
|
//
|
||||||
|
@ -750,6 +805,7 @@
|
||||||
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
|
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
|
||||||
function addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
function addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||||
function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; }
|
function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; }
|
||||||
|
function addHtmlValue(t, v) { return '<table><td style=width:120px;text-align:left>' + t + '<td><b>' + v + '</b></table>'; }
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
138
webserver.js
138
webserver.js
|
@ -820,6 +820,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
res.cookie('twofactor', twoFactorCookie, { maxAge: (30 * 24 * 60 * 60 * 1000), httpOnly: true, sameSite: 'strict', secure: true });
|
res.cookie('twofactor', twoFactorCookie, { maxAge: (30 * 24 * 60 * 60 * 1000), httpOnly: true, sameSite: 'strict', secure: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if email address needs to be confirmed
|
||||||
|
var emailcheck = ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
|
||||||
|
if (emailcheck && (user.emailVerified !== true)) {
|
||||||
|
parent.debug('web', 'Redirecting using ' + user.name + ' to email check login page');
|
||||||
|
req.session.messageid = 3; // "Email verification required" message
|
||||||
|
req.session.loginmode = '7';
|
||||||
|
req.session.passhint = user.email;
|
||||||
|
req.session.cuserid = userid;
|
||||||
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Login successful
|
// Login successful
|
||||||
if (obj.parent.authlog) { obj.parent.authLog('https', 'Accepted password for ' + xusername + ' from ' + cleanRemoteAddr(req.ip) + ' port ' + req.connection.remotePort); }
|
if (obj.parent.authlog) { obj.parent.authLog('https', 'Accepted password for ' + xusername + ' from ' + cleanRemoteAddr(req.ip) + ' port ' + req.connection.remotePort); }
|
||||||
parent.debug('web', 'handleLoginRequest: successful 2FA login');
|
parent.debug('web', 'handleLoginRequest: successful 2FA login');
|
||||||
|
@ -829,6 +841,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if email address needs to be confirmed
|
||||||
|
var emailcheck = ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
|
||||||
|
if (emailcheck && (user.emailVerified !== true)) {
|
||||||
|
parent.debug('web', 'Redirecting using ' + user.name + ' to email check login page');
|
||||||
|
req.session.messageid = 3; // "Email verification required" message
|
||||||
|
req.session.loginmode = '7';
|
||||||
|
req.session.passhint = user.email;
|
||||||
|
req.session.cuserid = userid;
|
||||||
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Login successful
|
// Login successful
|
||||||
if (obj.parent.authlog) { obj.parent.authLog('https', 'Accepted password for ' + xusername + ' from ' + cleanRemoteAddr(req.ip) + ' port ' + req.connection.remotePort); }
|
if (obj.parent.authlog) { obj.parent.authLog('https', 'Accepted password for ' + xusername + ' from ' + cleanRemoteAddr(req.ip) + ' port ' + req.connection.remotePort); }
|
||||||
parent.debug('web', 'handleLoginRequest: successful login');
|
parent.debug('web', 'handleLoginRequest: successful login');
|
||||||
|
@ -902,6 +926,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
delete req.session.tokenemail;
|
delete req.session.tokenemail;
|
||||||
delete req.session.messageid;
|
delete req.session.messageid;
|
||||||
delete req.session.passhint;
|
delete req.session.passhint;
|
||||||
|
delete req.session.cuserid;
|
||||||
req.session.userid = userid;
|
req.session.userid = userid;
|
||||||
req.session.domainid = domain.id;
|
req.session.domainid = domain.id;
|
||||||
req.session.currentNode = '';
|
req.session.currentNode = '';
|
||||||
|
@ -1060,6 +1085,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
delete req.session.tokenemail;
|
delete req.session.tokenemail;
|
||||||
delete req.session.messageid;
|
delete req.session.messageid;
|
||||||
delete req.session.passhint;
|
delete req.session.passhint;
|
||||||
|
delete req.session.cuserid;
|
||||||
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1122,6 +1148,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
delete req.session.tokenemail;
|
delete req.session.tokenemail;
|
||||||
delete req.session.messageid;
|
delete req.session.messageid;
|
||||||
delete req.session.passhint;
|
delete req.session.passhint;
|
||||||
|
delete req.session.cuserid;
|
||||||
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1222,6 +1249,80 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle account email change and email verification request
|
||||||
|
function handleCheckAccountEmailRequest(req, res, direct) {
|
||||||
|
const domain = checkUserIpAddress(req, res);
|
||||||
|
if (domain == null) { return; }
|
||||||
|
if ((obj.parent.mailserver == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (typeof req.session.cuserid != 'string') || (obj.users[req.session.cuserid] == null) || (!obj.common.validateEmail(req.body.email, 1, 256))) { parent.debug('web', 'handleCheckAccountEmailRequest: failed checks.'); res.sendStatus(404); return; }
|
||||||
|
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
|
||||||
|
|
||||||
|
// Always lowercase the email address
|
||||||
|
if (req.body.email) { req.body.email = req.body.email.toLowerCase(); }
|
||||||
|
|
||||||
|
// Get the email from the body or session.
|
||||||
|
var email = req.body.email;
|
||||||
|
if ((email == null) || (email == '')) { email = req.session.tokenemail; }
|
||||||
|
|
||||||
|
// Check if this request is for an allows email domain
|
||||||
|
if ((domain.newaccountemaildomains != null) && Array.isArray(domain.newaccountemaildomains)) {
|
||||||
|
var i = -1;
|
||||||
|
if (typeof req.body.email == 'string') { i = req.body.email.indexOf('@'); }
|
||||||
|
if (i == -1) {
|
||||||
|
parent.debug('web', 'handleCreateAccountRequest: unable to create account (1)');
|
||||||
|
req.session.loginmode = '7';
|
||||||
|
req.session.messageid = 106; // Invalid email.
|
||||||
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var emailok = false, emaildomain = req.body.email.substring(i + 1).toLowerCase();
|
||||||
|
for (var i in domain.newaccountemaildomains) { if (emaildomain == domain.newaccountemaildomains[i].toLowerCase()) { emailok = true; } }
|
||||||
|
if (emailok == false) {
|
||||||
|
parent.debug('web', 'handleCreateAccountRequest: unable to create account (2)');
|
||||||
|
req.session.loginmode = '7';
|
||||||
|
req.session.messageid = 106; // Invalid email.
|
||||||
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the email string format
|
||||||
|
if (!email || checkEmail(email) == false) {
|
||||||
|
parent.debug('web', 'handleCheckAccountEmailRequest: Invalid email');
|
||||||
|
req.session.loginmode = '7';
|
||||||
|
req.session.messageid = 106; // Invalid email.
|
||||||
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
|
} else {
|
||||||
|
// Check is email already exists
|
||||||
|
obj.db.GetUserWithVerifiedEmail(domain.id, email, function (err, docs) {
|
||||||
|
if ((err != null) || (docs.length > 0)) {
|
||||||
|
// Email already exitst
|
||||||
|
req.session.messageid = 102; // Existing account with this email address.
|
||||||
|
} else {
|
||||||
|
// Update the user and notify of user email address change
|
||||||
|
var user = obj.users[req.session.cuserid];
|
||||||
|
if (user.email != email) {
|
||||||
|
user.email = email;
|
||||||
|
db.SetUser(user);
|
||||||
|
var targets = ['*', 'server-users', user._id];
|
||||||
|
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||||
|
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msg: 'Account changed: ' + user.name, domain: domain.id };
|
||||||
|
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||||
|
parent.DispatchEvent(targets, obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the verification email
|
||||||
|
obj.parent.mailserver.sendAccountCheckMail(domain, user.name, user.email, obj.getLanguageCodes(req));
|
||||||
|
|
||||||
|
// Send the response
|
||||||
|
req.session.messageid = 2; // Email sent.
|
||||||
|
}
|
||||||
|
req.session.loginmode = '7';
|
||||||
|
delete req.session.cuserid;
|
||||||
|
if (direct === true) { handleRootRequestEx(req, res, domain); } else { res.redirect(domain.url + getQueryPortion(req)); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Called to process a web based email verification request
|
// Called to process a web based email verification request
|
||||||
function handleCheckMailRequest(req, res) {
|
function handleCheckMailRequest(req, res) {
|
||||||
const domain = checkUserIpAddress(req, res);
|
const domain = checkUserIpAddress(req, res);
|
||||||
|
@ -1678,6 +1779,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
delete req.session.domainid;
|
delete req.session.domainid;
|
||||||
delete req.session.currentNode;
|
delete req.session.currentNode;
|
||||||
delete req.session.passhint;
|
delete req.session.passhint;
|
||||||
|
delete req.session.cuserid;
|
||||||
req.session.messageid = 110; // Account locked.
|
req.session.messageid = 110; // Account locked.
|
||||||
res.redirect(domain.url + getQueryPortion(req)); // BAD***
|
res.redirect(domain.url + getQueryPortion(req)); // BAD***
|
||||||
return;
|
return;
|
||||||
|
@ -1816,7 +1918,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
var passhint = null, msgid = 0;
|
var passhint = null, msgid = 0;
|
||||||
if (req.session != null) {
|
if (req.session != null) {
|
||||||
msgid = req.session.messageid;
|
msgid = req.session.messageid;
|
||||||
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true)) { passhint = EscapeHtml(req.session.passhint); }
|
if ((loginmode == '7') || ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true))) { passhint = EscapeHtml(req.session.passhint); }
|
||||||
delete req.session.messageid;
|
delete req.session.messageid;
|
||||||
delete req.session.passhint;
|
delete req.session.passhint;
|
||||||
}
|
}
|
||||||
|
@ -1859,6 +1961,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
case 'createaccount': { handleCreateAccountRequest(req, res, true); break; }
|
case 'createaccount': { handleCreateAccountRequest(req, res, true); break; }
|
||||||
case 'resetpassword': { handleResetPasswordRequest(req, res, true); break; }
|
case 'resetpassword': { handleResetPasswordRequest(req, res, true); break; }
|
||||||
case 'resetaccount': { handleResetAccountRequest(req, res, true); break; }
|
case 'resetaccount': { handleResetAccountRequest(req, res, true); break; }
|
||||||
|
case 'checkemail': { handleCheckAccountEmailRequest(req, res, true); break; }
|
||||||
default: { handleLoginRequest(req, res, true); break; }
|
default: { handleLoginRequest(req, res, true); break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3898,6 +4001,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
if (domain == null) { return; }
|
if (domain == null) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var emailcheck = ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
|
||||||
|
|
||||||
// A web socket session can be authenticated in many ways (Default user, session, user/pass and cookie). Check authentication here.
|
// A web socket session can be authenticated in many ways (Default user, session, user/pass and cookie). Check authentication here.
|
||||||
if ((req.query.user != null) && (req.query.pass != null)) {
|
if ((req.query.user != null) && (req.query.pass != null)) {
|
||||||
// A user/pass is provided in URL arguments
|
// A user/pass is provided in URL arguments
|
||||||
|
@ -3928,13 +4033,23 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
|
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa })); ws.close(); } catch (e) { }
|
||||||
} else {
|
} else {
|
||||||
// We are authenticated with 2nd factor.
|
// We are authenticated with 2nd factor.
|
||||||
func(ws, req, domain, user);
|
// Check email verification
|
||||||
|
if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
|
||||||
|
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
|
||||||
|
} else {
|
||||||
|
func(ws, req, domain, user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We are authenticated
|
// Check email verification
|
||||||
func(ws, req, domain, user);
|
if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
|
||||||
|
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
|
||||||
|
} else {
|
||||||
|
// We are authenticated
|
||||||
|
func(ws, req, domain, user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Failed to authenticate, see if a default user is active
|
// Failed to authenticate, see if a default user is active
|
||||||
|
@ -4000,14 +4115,23 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We are authenticated with 2nd factor.
|
// We are authenticated with 2nd factor.
|
||||||
func(ws, req, domain, user);
|
// Check email verification
|
||||||
|
if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
|
||||||
|
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
|
||||||
|
} else {
|
||||||
|
func(ws, req, domain, user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We are authenticated
|
// We are authenticated
|
||||||
func(ws, req, domain, user);
|
// Check email verification
|
||||||
}
|
if (emailcheck && (user.email != null) && (user.emailVerified !== true)) {
|
||||||
|
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true })); ws.close(); } catch (e) { }
|
||||||
|
} else {
|
||||||
|
func(ws, req, domain, user);
|
||||||
|
} }
|
||||||
} else {
|
} else {
|
||||||
// Failed to authenticate, see if a default user is active
|
// Failed to authenticate, see if a default user is active
|
||||||
if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
|
if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
|
||||||
|
|
Loading…
Reference in New Issue