Bug fixes on SMTP account verification

Ylian Saint-Hilaire committed Dec 12, 2017 at 18:23 UTC b171750f6565401f83fd2c045034cad29048ff42
5 files changed +63 -22
meshcentral.js
+7
@@ -355,6 +355,7 @@ function CreateMeshCentralServer() {
355 // Setup email server
356 if ((obj.config.smtp != null) && (obj.config.smtp.host != null) && (obj.config.smtp.from != null)) {
357 obj.mailserver = require('./meshmail.js').CreateMeshMain(obj);
358 + obj.mailserver.verify();
359 //obj.mailserver.sendMail('ylian.saint-hilaire@intel.com', 'Test Subject', 'This is a sample test', 'This is a <b>sample</b> html test');
360 }
361
@@ -365,6 +366,12 @@ function CreateMeshCentralServer() {
366 obj.DispatchEvent(['*'], obj, { etype: 'server', action: 'started', msg: 'Server started' })
367
368 obj.debug(1, 'Server started');
369 +
370 + /*
371 + obj.db.GetUserWithVerifiedEmail('', 'ylian.saint-hilaire@intel.com', function (err, docs) {
372 + console.log(JSON.stringify(docs));
373 + });
374 + */
375 });
376 });
377 });
meshmail.js
+15 -3
@@ -24,8 +24,9 @@ module.exports.CreateMeshMain = function (parent) {
24 var accountResetMailText = '[[[SERVERNAME]]] - Account Reset\r\n\r\nHi [[[USERNAME]]], [[[SERVERNAME]]] ([[[SERVERURL]]]) is requesting an account password reset. Nagivate to the following link to complete the process: [[[CALLBACKURL]]]\r\nIf you did not initiate this request, please ignore this mail.\r\n';
25
26 // Setup mail server
27 - var options = { host: parent.config.smtp.host, secure: false, tls: { rejectUnauthorized: false } };
27 + var options = { host: parent.config.smtp.host, secure: (parent.config.smtp.tls == true), tls: { rejectUnauthorized: false } };
28 if (parent.config.smtp.port != null) { options.port = parent.config.smtp.port; }
29 + if ((parent.config.smtp.user != null) && (parent.config.smtp.pass != null)) { options.auth = { user: parent.config.smtp.user, pass: parent.config.smtp.pass }; }
30 obj.smtpServer = nodemailer.createTransport(options);
31
32 // Perform all e-mail substitution
@@ -73,8 +74,19 @@ module.exports.CreateMeshMain = function (parent) {
74 sendNextMail(); // Send the next mail
75 } else {
76 obj.retry++;
76 - //console.log('SMTP server failed, will try again in a minute (' + obj.retry + ').');
77 - setTimeout(sendNextMail, 60000); // Wait and try again
77 + console.log('SMTP server failed: ' + err.response);
78 + if (obj.retry < 6) { setTimeout(sendNextMail, 60000); } // Wait and try again
79 + }
80 + });
81 + }
82 +
83 + // Send out the next mail in the pending list
84 + obj.verify = function() {
85 + obj.smtpServer.verify(function (err, info) {
86 + if (err == null) {
87 + console.log('SMTP mail server ' + parent.config.smtp.host + ' working as expected.');
88 + } else {
89 + console.log('SMTP mail server ' + parent.config.smtp.host + ' failed: ' + err.response);
90 }
91 });
92 }
meshuser.js
+27 -16
@@ -261,22 +261,30 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
261 var x = command.email.split('@');
262 if ((x.length == 2) && (x[0].length > 0) && (x[1].split('.').length > 1) && (x[1].length > 2)) {
263 if (obj.parent.users[req.session.userid].email != command.email) {
264 - // Update the user's email
265 - var oldemail = user.email;
266 - user.email = command.email;
267 - user.emailVerified = false;
268 - obj.parent.db.SetUser(user);
269 -
270 - // Event the change
271 - var userinfo = obj.common.Clone(user);
272 - delete userinfo.hash;
273 - delete userinfo.passhint;
274 - delete userinfo.salt;
275 - delete userinfo.type;
276 - delete userinfo.domain;
277 - delete userinfo.subscriptions;
278 - delete userinfo.passtype;
279 - obj.parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: userinfo.name, account: userinfo, action: 'accountchange', msg: 'Changed email of user ' + userinfo.name + ' from ' + oldemail + ' to ' + user.email, domain: domain.id })
264 + // Check if this email is already validated on a different account
265 + obj.db.GetUserWithVerifiedEmail(domain.id, command.email, function (err, docs) {
266 + if (docs.length > 0) {
267 + // Notify the duplicate email error
268 + ws.send(JSON.stringify({ action: 'msg', type: 'notify', value: 'Failed to change email address, another account already using: <b>' + EscapeHtml(command.email) + '</b>.' }));
269 + } else {
270 + // Update the user's email
271 + var oldemail = user.email;
272 + user.email = command.email;
273 + user.emailVerified = false;
274 + obj.parent.db.SetUser(user);
275 +
276 + // Event the change
277 + var userinfo = obj.common.Clone(user);
278 + delete userinfo.hash;
279 + delete userinfo.passhint;
280 + delete userinfo.salt;
281 + delete userinfo.type;
282 + delete userinfo.domain;
283 + delete userinfo.subscriptions;
284 + delete userinfo.passtype;
285 + obj.parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: userinfo.name, account: userinfo, action: 'accountchange', msg: 'Changed email of user ' + userinfo.name + ' from ' + oldemail + ' to ' + user.email, domain: domain.id })
286 + }
287 + });
288 }
289 }
290 }
@@ -960,5 +968,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
968 ws.send(JSON.stringify(files));
969 }
970
971 + function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
972 + function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
973 +
974 return obj;
975 }
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.1.0-m",
3 + "version": "0.1.0-o",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
views/default.handlebars
+13 -2
@@ -167,8 +167,8 @@
167 <div id="p2AccountActions">
168 <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>
169 <p style="margin-left:40px">
170 - <a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a><br />
170 <span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a><br /></span>
171 + <a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a><br />
172 <a onclick="account_showChangePassword()" style="cursor:pointer">Change password</a><br />
173 <a onclick="account_showDeleteAccount()" style="cursor:pointer">Delete account</a><br />
174 </p>
@@ -493,7 +493,10 @@
493 <table cellpadding=0 cellspacing=10 style="width:100%">
494 <tr>
495 <td style="text-align:left"></td>
496 - <td style="text-align:right"><a href="terms">Terms &amp; Privacy</a></td>
496 + <td style="text-align:right">
497 + <a id="verifyEmailId2" style="color:yellow;margin-left:3px;cursor:pointer" onclick="account_showVerifyEmail()">Verify Email</a>
498 + <a style="margin-left:3px" href="terms">Terms &amp; Privacy</a>
499 + </td>
500 </tr>
501 </table>
502 </div>
@@ -786,6 +789,7 @@
789 userinfo = message.userinfo;
790 updateSiteAdmin();
791 QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
792 + QV('verifyEmailId2', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
793 break;
794 }
795 case 'users': {
@@ -859,6 +863,12 @@
863 addNotification(n);
864 }
865 }
866 + } else {
867 + if (message.type == 'notify') { // This is a notification message.
868 + var n = { text:message.value };
869 + if (message.tag != undefined) { n.tag = message.tag; }
870 + addNotification(n);
871 + }
872 }
873 break;
874 }
@@ -930,6 +940,7 @@
940 userinfo = message.event.account;
941 if (oldsiteadmin != newsiteadmin) updateSiteAdmin();
942 QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
943 + QV('verifyEmailId2', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
944 }
945 if (users == null) break;
946 users[message.event.account._id] = message.event.account;