From 9738848dc5c60c5a60cf78aafb2037d4ceeb6a48 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Fri, 2 Sep 2022 15:27:07 -0700 Subject: [PATCH] Added email to console for easy debugging. --- meshcentral.js | 4 +-- meshmail.js | 98 +++++++++++++++++++++++++++++--------------------- 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/meshcentral.js b/meshcentral.js index 0f690475..30ca7280 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -3878,7 +3878,7 @@ function mainStart() { if (domainCount == 0) { allsspi = false; } for (var i in config.domains) { if (i.startsWith('_')) continue; - if ((config.domains[i].smtp != null) || (config.domains[i].sendmail != null)) { nodemailer = true; } + if (((config.domains[i].smtp != null) && (config.domains[i].smtp.name != 'console')) || (config.domains[i].sendmail != null)) { nodemailer = true; } if (config.domains[i].sendgrid != null) { sendgrid = true; } if (config.domains[i].yubikey != null) { yubikey = true; } if (config.domains[i].auth == 'ldap') { ldap = true; } @@ -3921,7 +3921,7 @@ function mainStart() { if (config.settings.plugins != null) { modules.push('semver'); } // Required for version compat testing and update checks if ((config.settings.plugins != null) && (config.settings.plugins.proxy != null)) { modules.push('https-proxy-agent'); } // Required for HTTP/HTTPS proxy support else if (config.settings.xmongodb != null) { modules.push('mongojs'); } // Add MongoJS, old driver. - if (nodemailer || (config.smtp != null) || (config.sendmail != null)) { modules.push('nodemailer'); } // Add SMTP support + if (nodemailer || ((config.smtp != null) && (config.smtp.name != 'console')) || (config.sendmail != null)) { modules.push('nodemailer'); } // Add SMTP support if (sendgrid || (config.sendgrid != null)) { modules.push('@sendgrid/mail'); } // Add SendGrid support if (args.translate) { modules.push('jsdom'); modules.push('esprima'); modules.push('minify-js'); modules.push('html-minifier'); } // Translation support if (typeof config.settings.crowdsec == 'object') { modules.push('@crowdsec/express-bouncer'); } // Add CrowdSec bounser module (https://www.npmjs.com/package/@crowdsec/express-bouncer) diff --git a/meshmail.js b/meshmail.js index 168b6769..9de93da1 100644 --- a/meshmail.js +++ b/meshmail.js @@ -43,26 +43,31 @@ module.exports.CreateMeshMail = function (parent, domain) { if (obj.config.sendgrid.verifyemail == true) { obj.verifyemail = true; } } else if (obj.config.smtp != null) { // Setup SMTP mail server - const nodemailer = require('nodemailer'); - var options = { name: obj.config.smtp.name, host: obj.config.smtp.host, secure: (obj.config.smtp.tls == true), tls: {} }; - //var options = { host: obj.config.smtp.host, secure: (obj.config.smtp.tls == true), tls: { secureProtocol: 'SSLv23_method', ciphers: 'RSA+AES:!aNULL:!MD5:!DSS', secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_COMPRESSION | constants.SSL_OP_CIPHER_SERVER_PREFERENCE, rejectUnauthorized: false } }; - if (obj.config.smtp.port != null) { options.port = obj.config.smtp.port; } - if (obj.config.smtp.tlscertcheck === false) { options.tls.rejectUnauthorized = false; } - if (obj.config.smtp.tlsstrict === true) { options.tls.secureProtocol = 'SSLv23_method'; options.tls.ciphers = 'RSA+AES:!aNULL:!MD5:!DSS'; options.tls.secureOptions = constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_COMPRESSION | constants.SSL_OP_CIPHER_SERVER_PREFERENCE; } - if ((obj.config.smtp.auth != null) && (typeof obj.config.smtp.auth == 'object')) { - var user = obj.config.smtp.from; - if ((user == null) && (obj.config.smtp.user != null)) { user = obj.config.smtp.user; } - if ((obj.config.smtp.auth.user != null) && (typeof obj.config.smtp.auth.user == 'string')) { user = obj.config.smtp.auth.user; } - if (user.toLowerCase().endsWith('@gmail.com')) { options = { service: 'gmail', auth: { user: user } }; obj.config.smtp.host = 'gmail'; } else { options.auth = { user: user } } - if (obj.config.smtp.auth.type) { options.auth.type = obj.config.smtp.auth.type; } - if (obj.config.smtp.auth.clientid) { options.auth.clientId = obj.config.smtp.auth.clientid; options.auth.type = 'OAuth2'; } - if (obj.config.smtp.auth.clientsecret) { options.auth.clientSecret = obj.config.smtp.auth.clientsecret; } - if (obj.config.smtp.auth.refreshtoken) { options.auth.refreshToken = obj.config.smtp.auth.refreshtoken; } - } - else if ((obj.config.smtp.user != null) && (obj.config.smtp.pass != null)) { options.auth = { user: obj.config.smtp.user, pass: obj.config.smtp.pass }; } - if (obj.config.smtp.verifyemail == true) { obj.verifyemail = true; } + if (obj.config.smtp.name == 'console') { + // This is for debugging, the mails will be displayed on the console + obj.smtpServer = 'console'; + } else { + const nodemailer = require('nodemailer'); + var options = { name: obj.config.smtp.name, host: obj.config.smtp.host, secure: (obj.config.smtp.tls == true), tls: {} }; + //var options = { host: obj.config.smtp.host, secure: (obj.config.smtp.tls == true), tls: { secureProtocol: 'SSLv23_method', ciphers: 'RSA+AES:!aNULL:!MD5:!DSS', secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_COMPRESSION | constants.SSL_OP_CIPHER_SERVER_PREFERENCE, rejectUnauthorized: false } }; + if (obj.config.smtp.port != null) { options.port = obj.config.smtp.port; } + if (obj.config.smtp.tlscertcheck === false) { options.tls.rejectUnauthorized = false; } + if (obj.config.smtp.tlsstrict === true) { options.tls.secureProtocol = 'SSLv23_method'; options.tls.ciphers = 'RSA+AES:!aNULL:!MD5:!DSS'; options.tls.secureOptions = constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_COMPRESSION | constants.SSL_OP_CIPHER_SERVER_PREFERENCE; } + if ((obj.config.smtp.auth != null) && (typeof obj.config.smtp.auth == 'object')) { + var user = obj.config.smtp.from; + if ((user == null) && (obj.config.smtp.user != null)) { user = obj.config.smtp.user; } + if ((obj.config.smtp.auth.user != null) && (typeof obj.config.smtp.auth.user == 'string')) { user = obj.config.smtp.auth.user; } + if (user.toLowerCase().endsWith('@gmail.com')) { options = { service: 'gmail', auth: { user: user } }; obj.config.smtp.host = 'gmail'; } else { options.auth = { user: user } } + if (obj.config.smtp.auth.type) { options.auth.type = obj.config.smtp.auth.type; } + if (obj.config.smtp.auth.clientid) { options.auth.clientId = obj.config.smtp.auth.clientid; options.auth.type = 'OAuth2'; } + if (obj.config.smtp.auth.clientsecret) { options.auth.clientSecret = obj.config.smtp.auth.clientsecret; } + if (obj.config.smtp.auth.refreshtoken) { options.auth.refreshToken = obj.config.smtp.auth.refreshtoken; } + } + else if ((obj.config.smtp.user != null) && (obj.config.smtp.pass != null)) { options.auth = { user: obj.config.smtp.user, pass: obj.config.smtp.pass }; } + if (obj.config.smtp.verifyemail == true) { obj.verifyemail = true; } - obj.smtpServer = nodemailer.createTransport(options); + obj.smtpServer = nodemailer.createTransport(options); + } } else if (obj.config.sendmail != null) { // Setup Sendmail const nodemailer = require('nodemailer'); @@ -440,39 +445,50 @@ module.exports.CreateMeshMail = function (parent, domain) { } }); } else if (obj.smtpServer != null) { - // SMTP send parent.debug('email', 'SMTP sending mail to ' + mailToSend.to + '.'); - obj.smtpServer.sendMail(mailToSend, function (err, info) { - parent.debug('email', 'SMTP response: ' + JSON.stringify(err) + ', ' + JSON.stringify(info)); + if (obj.smtpServer == 'console') { + // Display the email on the console, this is for easy debugging + if (mailToSend.from == null) { delete mailToSend.from; } + if (mailToSend.html == null) { delete mailToSend.html; } + console.log('Email', mailToSend); obj.sendingMail = false; - if (err == null) { - // Send the next mail - obj.pendingMails.shift(); - obj.retry = 0; - sendNextMail(); - } else { - obj.retry++; - parent.debug('email', 'SMTP server failed (Retry:' + obj.retry + '): ' + JSON.stringify(err)); - console.log('SMTP server failed (Retry:' + obj.retry + '/3): ' + JSON.stringify(err)); - // Wait and try again - if (obj.retry < 3) { - setTimeout(sendNextMail, 10000); - } else { - // Failed, send the next mail - parent.debug('email', 'SMTP server failed (Skipping): ' + JSON.stringify(err)); - console.log('SMTP server failed (Skipping): ' + JSON.stringify(err)); + obj.pendingMails.shift(); + obj.retry = 0; + sendNextMail(); + } else { + // SMTP send + obj.smtpServer.sendMail(mailToSend, function (err, info) { + parent.debug('email', 'SMTP response: ' + JSON.stringify(err) + ', ' + JSON.stringify(info)); + obj.sendingMail = false; + if (err == null) { + // Send the next mail obj.pendingMails.shift(); obj.retry = 0; sendNextMail(); + } else { + obj.retry++; + parent.debug('email', 'SMTP server failed (Retry:' + obj.retry + '): ' + JSON.stringify(err)); + console.log('SMTP server failed (Retry:' + obj.retry + '/3): ' + JSON.stringify(err)); + // Wait and try again + if (obj.retry < 3) { + setTimeout(sendNextMail, 10000); + } else { + // Failed, send the next mail + parent.debug('email', 'SMTP server failed (Skipping): ' + JSON.stringify(err)); + console.log('SMTP server failed (Skipping): ' + JSON.stringify(err)); + obj.pendingMails.shift(); + obj.retry = 0; + sendNextMail(); + } } - } - }); + }); + } } } // Send out the next mail in the pending list obj.verify = function () { - if (obj.smtpServer == null) return; + if ((obj.smtpServer == null) || (obj.smtpServer == 'console')) return; obj.smtpServer.verify(function (err, info) { if (err == null) { if (obj.config.smtp.host == 'gmail') {