diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index 93f91183..60ca628b 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -785,15 +785,39 @@ "description": "Connects MeshCentral to a SMTP email server, allows MeshCentral to send email messages for 2FA or user notification.", "type": "object", "properties": { - "host": { "type": "string", "format": "hostname" }, - "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, - "from": { "type": "string", "format": "email", "description": "Email address used in the messages from field." }, + "host": { + "type": "string", + "format": "hostname" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "from": { + "type": "string", + "format": "email", + "description": "Email address used in the messages from field." + }, "tls": { "type": "boolean" }, + "auth": { + "type": "object", + "properties": { + "clientId": { "type": "string" }, + "clientSecret": { "type": "string" }, + "refreshTfoken": { "type": "string" } + }, + "required": [ "clientId", "clientSecret", "refreshToken" ] + }, "tlscertcheck": { "type": "boolean" }, "tlsstrict": { "type": "boolean" }, - "verifyemail": { "type": "boolean", "default": true, "description": "When set to false, the email format and DNS MX record are not checked." } + "verifyemail": { + "type": "boolean", + "default": true, + "description": "When set to false, the email format and DNS MX record are not checked." + } }, - "required": [ "host", "port", "from", "tls" ] + "required": [ "from" ] }, "sendmail": { "title" : "Send email using the sendmail command", diff --git a/meshcentral.js b/meshcentral.js index efc6abe5..49f0aa95 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1636,7 +1636,7 @@ function CreateMeshCentralServer(config, args) { obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); obj.mailserver.verify(); if (obj.args.lanonly == true) { addServerWarning("SendGrid server has limited use in LAN mode.", 17); } - } else if ((obj.config.smtp != null) && (obj.config.smtp.host != null) && (obj.config.smtp.from != null)) { + } else if (obj.config.smtp != null) { // SMTP server obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); obj.mailserver.verify(); diff --git a/meshmail.js b/meshmail.js index 71d52fff..589d7be5 100644 --- a/meshmail.js +++ b/meshmail.js @@ -30,7 +30,7 @@ module.exports.CreateMeshMail = function (parent, domain) { const sortCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }) const constants = (obj.parent.crypto.constants ? obj.parent.crypto.constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead. - function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&').replace(/>/g, '>').replace(//g, '>').replace(//g, '>').replace(/').replace(/\n/g, '').replace(/\t/g, '  '); if (typeof x == "boolean") return x; if (typeof x == "number") return x; } // Setup where we read our configuration from @@ -49,8 +49,19 @@ module.exports.CreateMeshMail = function (parent, domain) { 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.user != null) && (obj.config.smtp.pass != null)) { options.auth = { user: obj.config.smtp.user, pass: obj.config.smtp.pass }; } + 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); } else if (obj.config.sendmail != null) { // Setup Sendmail @@ -464,7 +475,11 @@ module.exports.CreateMeshMail = function (parent, domain) { if (obj.smtpServer == null) return; obj.smtpServer.verify(function (err, info) { if (err == null) { - console.log('SMTP mail server ' + obj.config.smtp.host + ' working as expected.'); + if (obj.config.smtp.host == 'gmail') { + console.log('Gmail server with OAuth working as expected.'); + } else { + console.log('SMTP mail server ' + obj.config.smtp.host + ' working as expected.'); + } } else { // Remove all non-object types from error to avoid a JSON stringify error. var err2 = {}; diff --git a/package.json b/package.json index 7d16097d..e77938fd 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,8 @@ "sample-config-advanced.json" ], "dependencies": { + "@yetzt/nedb": "^1.8.0", + "archiver": "^4.0.2", "body-parser": "^1.19.0", "cbor": "~5.2.0", "compression": "^1.7.4", @@ -43,13 +45,24 @@ "express": "^4.17.0", "express-handlebars": "^5.3.5", "express-ws": "^4.0.0", + "googleapis": "^96.0.0", + "image-size": "^1.0.1", "ipcheck": "^0.1.0", + "loadavg-windows": "^1.1.1", "minimist": "^1.2.5", "multiparty": "^4.2.1", - "@yetzt/nedb": "^1.8.0", "node-forge": "^1.0.0", + "node-rdpjs-2": "^0.3.5", + "node-windows": "^0.1.4", + "nodemailer": "^6.7.2", + "otplib": "^10.2.3", + "pg": "^8.7.1", + "pgtools": "^0.3.2", + "ssh2": "^1.7.0", + "web-push": "^3.4.5", "ws": "^5.2.3", - "yauzl": "^2.10.0" + "yauzl": "^2.10.0", + "yubikeyotp": "^0.2.0" }, "engines": { "node": ">=10.0.0" diff --git a/public/commander.htm b/public/commander.htm index ff4dbef2..4f9d5348 100644 --- a/public/commander.htm +++ b/public/commander.htm @@ -1,4 +1,4 @@ -
  
Disconnected