mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-11-07 04:42:54 -05:00
Added SMTP email support, email verification and password reset support
This commit is contained in:
@@ -167,6 +167,8 @@
|
||||
<div id="p2AccountActions">
|
||||
<p><strong><img alt="" width=150 height=103 src=images/mainaccount.png style=margin-bottom:10px;margin-right:20px;float:right />Account actions</strong></p>
|
||||
<p style="margin-left:40px">
|
||||
<a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a><br />
|
||||
<span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a><br /></span>
|
||||
<a onclick="account_showChangePassword()" style="cursor:pointer">Change password</a><br />
|
||||
<a onclick="account_showDeleteAccount()" style="cursor:pointer">Delete account</a><br />
|
||||
</p>
|
||||
@@ -686,6 +688,22 @@
|
||||
if (t != null) { desktopsettings = JSON.parse(t); }
|
||||
applyDesktopSettings();
|
||||
|
||||
// Mouse Scroll on desktop
|
||||
if (navigator.userAgent.match(/mozilla/i)) {
|
||||
Q('Desk').addEventListener('DOMMouseScroll', function (e) {
|
||||
return dmousewheel(e);
|
||||
//if (loginState == 3) { SendMouseMsg(KeyAction.SCROLL, e); return false; }
|
||||
//return true;
|
||||
});
|
||||
}
|
||||
else {
|
||||
Q('Desk').addEventListener('mousewheel', function (e) {
|
||||
return dmousewheel(e);
|
||||
//if (loginState == 3) { SendMouseMsg(KeyAction.SCROLL, e); return false; }
|
||||
//return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Terminal special keys
|
||||
var x = '';
|
||||
for (var c = 1; c < 27; c++) x += "<option value='" + c + "'>Ctrl-" + String.fromCharCode(64 + c) + " (" + c + ")</option>";
|
||||
@@ -760,13 +778,14 @@
|
||||
|
||||
function onMessage(server, message) {
|
||||
switch (message.action) {
|
||||
case 'serverinfo': {
|
||||
serverinfo = message.serverinfo;
|
||||
break;
|
||||
}
|
||||
case 'userinfo': {
|
||||
userinfo = message.userinfo;
|
||||
updateSiteAdmin();
|
||||
break;
|
||||
}
|
||||
case 'serverinfo': {
|
||||
serverinfo = message.serverinfo;
|
||||
QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
|
||||
break;
|
||||
}
|
||||
case 'users': {
|
||||
@@ -910,6 +929,7 @@
|
||||
if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.Send({ action: 'files' }); }
|
||||
userinfo = message.event.account;
|
||||
if (oldsiteadmin != newsiteadmin) updateSiteAdmin();
|
||||
QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
|
||||
}
|
||||
if (users == null) break;
|
||||
users[message.event.account._id] = message.event.account;
|
||||
@@ -2971,6 +2991,7 @@
|
||||
function dmousedown(e) { if (!xxdialogMode && desktop != undefined) desktop.m.mousedown(e) }
|
||||
function dmouseup(e) { if (!xxdialogMode && desktop != undefined) desktop.m.mouseup(e) }
|
||||
function dmousemove(e) { if (!xxdialogMode && desktop != undefined) desktop.m.mousemove(e) }
|
||||
function dmousewheel(e) { if (!xxdialogMode && desktop != undefined) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
|
||||
function drotate(x) { if (!xxdialogMode && desktop != undefined) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
|
||||
|
||||
//
|
||||
@@ -3646,6 +3667,34 @@
|
||||
// MY ACCOUNT
|
||||
//
|
||||
|
||||
function account_showVerifyEmail() {
|
||||
if (xxdialogMode || (userinfo.emailVerified == true) || (serverinfo.emailcheck != true)) return;
|
||||
var x = "Click ok to send a verification mail to:<br /><div style=padding:8px><b>" + EscapeHtml(userinfo.email) + "</b></div>Please wait a few minute to receive the verification.";
|
||||
setDialogMode(2, "Email Verification", 3, account_showVerifyEmailEx, x);
|
||||
}
|
||||
|
||||
function account_showVerifyEmailEx() {
|
||||
meshserver.Send({ action: 'verifyemail', email: userinfo.email });
|
||||
}
|
||||
|
||||
function account_showChangeEmail() {
|
||||
if (xxdialogMode) return;
|
||||
var x = "Change your account e-mail address here.<br /><br />";
|
||||
x += addHtmlValue('Email', '<input id=dp2email style=width:230px maxlength=32 onchange=account_validateEmail() onkeyup=account_validateEmail() />');
|
||||
setDialogMode(2, "Email Address Change", 3, account_changeEmail, x);
|
||||
if (userinfo.email != null) { Q('dp2email').value = userinfo.email; }
|
||||
account_validateEmail();
|
||||
}
|
||||
|
||||
function account_validateEmail() {
|
||||
var x = Q('dp2email').value.split('@');
|
||||
QE('idx_dlgOkButton', (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));
|
||||
}
|
||||
|
||||
function account_changeEmail() {
|
||||
meshserver.Send({ action: 'changeemail', email: Q('dp2email').value });
|
||||
}
|
||||
|
||||
function account_showDeleteAccount() {
|
||||
if (xxdialogMode) return;
|
||||
var x = "To delete this account, type in the account password in both boxes below and hit ok.<br /><br />";
|
||||
@@ -4229,7 +4278,7 @@
|
||||
if ((user.quota != undefined) && ((user.siteadmin & 8) != 0)) { msg += ", " + (user.quota / 1024) + " k"; }
|
||||
if (user.name != userinfo.name) { msg += "</a>"; }
|
||||
if (user.email != null) {
|
||||
msg = '<table style=width:100%><tr><td>' + EscapeHtml(user.name) + ', <a onclick=doemail(event,\"' + user.email + '\")>' + user.email + '</a><td align=right>' + msg + '</table>';
|
||||
msg = '<table style=width:100%><tr><td>' + EscapeHtml(user.name) + ', <a onclick=doemail(event,\"' + user.email + '\")>' + user.email + '</a>' + (((serverinfo.emailcheck == true) && (user.emailVerified != true))?' (unverified)':'') + '<td align=right>' + msg + '</table>';
|
||||
} else {
|
||||
msg = '<table style=width:100%><tr><td>' + EscapeHtml(user.name) + '<td align=right>' + msg + '</table>';
|
||||
}
|
||||
|
||||
@@ -53,8 +53,12 @@
|
||||
<td align=right><input id=loginButton type=submit value="Log In" disabled="disabled" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="newAccountDiv" style="display:none">
|
||||
<hr />Don't have an account? <a onclick=xgo(2) style=cursor:pointer>Create one</a>.
|
||||
<div id="hrAccountDiv" style="display:none"><hr /></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
Forgot username/password? <a onclick=xgo(3) style=cursor:pointer>Reset account</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Don't have an account? <a onclick=xgo(2) style=cursor:pointer>Create one</a>.
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -101,6 +105,29 @@
|
||||
<hr /><a onclick=xgo(1) style=cursor:pointer>Back to login</a>
|
||||
</form>
|
||||
</div>
|
||||
<div id=resetpanel style="background-color: #979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<form action=resetaccount method=post>
|
||||
<div id=message3>
|
||||
{{{message}}}
|
||||
</div>
|
||||
<div>
|
||||
<b>Account Reset</b>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td align=right width=100>Email:</td>
|
||||
<td><input id=remail type=text name=email onchange=validateReset() onkeyup=validateReset() /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2>
|
||||
<div style=float:right><input id=eresetButton type=submit value="Reset Account" disabled="disabled" /></div>
|
||||
<div id=passWarning style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr /><a onclick=xgo(1) style=cursor:pointer>Back to login</a>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -141,6 +168,7 @@
|
||||
<script>
|
||||
var passhint = "{{{passhint}}}";
|
||||
var newAccountPass = {{{newAccountPass}}};
|
||||
var emailCheck = {{{emailcheck}}};
|
||||
|
||||
function startup() {
|
||||
window.onresize = center;
|
||||
@@ -151,6 +179,8 @@
|
||||
QV('newAccountDiv', '{{{newAccount}}}' != '0' );
|
||||
if ((passhint != null) && (passhint.length > 0)) { QV("showPassHintLink", true); }
|
||||
QV("newAccountPass", (newAccountPass == 1));
|
||||
QV("resetAccountDiv", (emailCheck == true));
|
||||
QV("hrAccountDiv", (emailCheck == true) || (newAccountPass == 1))
|
||||
}
|
||||
|
||||
function showPassHint() {
|
||||
@@ -168,6 +198,7 @@
|
||||
QV("showPassHintLink", false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
}
|
||||
|
||||
function validateLogin() {
|
||||
@@ -178,7 +209,7 @@
|
||||
|
||||
function validateCreate() {
|
||||
setDialogMode(0);
|
||||
var ok = (Q('ausername').value.length > 0 && Q('aemail').value.length > 0 && Q('apassword1').value.length > 0 && (Q('apassword2').value == Q('apassword1').value));
|
||||
var ok = ((Q('ausername').value.length > 0) && (checkEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
|
||||
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
|
||||
QE('createButton', ok);
|
||||
if (Q('apassword1').value == '') {
|
||||
@@ -191,6 +222,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
function validateReset() {
|
||||
setDialogMode(0);
|
||||
QE('eresetButton', checkEmail(Q('remail').value));
|
||||
}
|
||||
|
||||
// Return true is the input string looks like an email address
|
||||
function checkEmail(str) {
|
||||
var x = str.split('@');
|
||||
var ok = ((x.length == 2) && (x[0].length > 0) && (x[1].split('.').length > 1) && (x[1].length > 2));
|
||||
if (ok == true) { var y = x[1].split('.'); for (var i in y) { if (y[i].length == 0) { ok = false; } } }
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Return a password strength score
|
||||
function checkPasswordStrength(password) {
|
||||
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) }
|
||||
|
||||
42
views/message.handlebars
Normal file
42
views/message.handlebars
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv=X-UA-Compatible content="IE=edge" />
|
||||
<meta content="text/html;charset=utf-8" http-equiv=Content-Type />
|
||||
<meta name=viewport content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" />
|
||||
<meta name=apple-mobile-web-app-capable content=yes />
|
||||
<meta name=format-detection content="telephone=no" />
|
||||
<link type=text/css href="/styles/style.css" media="screen" rel="stylesheet" title="CSS" />
|
||||
<title>MeshCentral - {{{title3}}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id=container style=max-height:100vh>
|
||||
<div id=mastheadx></div>
|
||||
<div id=masthead style="background:url(/images/logoback.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style=float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px>
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
|
||||
</div>
|
||||
<div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px>
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id=page_content style=max-height:calc(100vh-138px)>
|
||||
<div id=column_l>
|
||||
<h1>{{{title3}}}</h1>
|
||||
<p style=margin-left:20px>{{{message}}}</p>
|
||||
<br />
|
||||
</div>
|
||||
<div id=footer>
|
||||
<table cellpadding=0 cellspacing=10 style=width:100%>
|
||||
<tr>
|
||||
<td style=text-align:left></td>
|
||||
<td style=text-align:right>
|
||||
<a href=terms>Terms & Privacy</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user