From 61ed6cf2bcfb05d068a6bb30113f2a1717ed575b Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 23 Apr 2021 13:49:47 +0100 Subject: [PATCH] Updating config management for SMTP as well as finalising the work around generating and sending emails. --- .../src/api/controllers/admin/configs.js | 9 +++++ .../worker/src/api/controllers/admin/email.js | 34 +++++++++++-------- .../worker/src/api/routes/admin/configs.js | 4 ++- packages/worker/src/api/routes/admin/email.js | 7 ++-- packages/worker/src/utilities/email.js | 21 ++++++++++++ 5 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 packages/worker/src/utilities/email.js diff --git a/packages/worker/src/api/controllers/admin/configs.js b/packages/worker/src/api/controllers/admin/configs.js index df19dc9a56..5ca216878d 100644 --- a/packages/worker/src/api/controllers/admin/configs.js +++ b/packages/worker/src/api/controllers/admin/configs.js @@ -5,6 +5,8 @@ const { getConfigParams, determineScopedConfig, } = require("@budibase/auth").db +const { Configs } = require("../../../constants") +const email = require("../../../utilities/email") const GLOBAL_DB = StaticDatabases.GLOBAL.name @@ -22,6 +24,13 @@ exports.save = async function(ctx) { }) } + // verify the configuration + switch (type) { + case Configs.SMTP: + await email.verifyConfig(configDoc) + break; + } + try { const response = await db.post(configDoc) ctx.body = { diff --git a/packages/worker/src/api/controllers/admin/email.js b/packages/worker/src/api/controllers/admin/email.js index 6c9343ea5a..0755596841 100644 --- a/packages/worker/src/api/controllers/admin/email.js +++ b/packages/worker/src/api/controllers/admin/email.js @@ -1,10 +1,14 @@ const CouchDB = require("../../../db") const { StaticDatabases, determineScopedConfig } = require("@budibase/auth").db -const { EmailTemplatePurpose, TemplateTypes, Configs } = require("../../../constants") +const { + EmailTemplatePurpose, + TemplateTypes, + Configs, +} = require("../../../constants") const { getTemplateByPurpose } = require("../../../constants/templates") const { getSettingsTemplateContext } = require("../../../utilities/templates") const { processString } = require("@budibase/string-templates") -const nodemailer = require("nodemailer") +const { createSMTPTransport } = require("../../../utilities/email") const GLOBAL_DB = StaticDatabases.GLOBAL.name const TYPE = TemplateTypes.EMAIL @@ -14,15 +18,7 @@ const FULL_EMAIL_PURPOSES = [ EmailTemplatePurpose.PASSWORD_RECOVERY, ] -function createSMTPTransport(config) { - const transport = nodemailer.createTransport({ - port: config.port, - host: config.host, - - }) -} - -exports.buildEmail = async (email, user, purpose) => { +async function buildEmail(purpose, email, user) { // this isn't a full email if (FULL_EMAIL_PURPOSES.indexOf(purpose) === -1) { throw `Unable to build an email of type ${purpose}` @@ -37,7 +33,7 @@ exports.buildEmail = async (email, user, purpose) => { const context = { ...(await getSettingsTemplateContext()), email, - user, + user: user || {}, } body = await processString(body, context) @@ -51,14 +47,24 @@ exports.buildEmail = async (email, user, purpose) => { } exports.sendEmail = async ctx => { - const { groupId, email, purpose } = ctx.request.body + const { groupId, email, userId, purpose } = ctx.request.body const db = new CouchDB(GLOBAL_DB) const params = {} if (groupId) { params.group = groupId } params.type = Configs.SMTP + let user = {} + if (userId) { + user = db.get(userId) + } const config = await determineScopedConfig(db, params) const transport = createSMTPTransport(config) + const message = { + from: config.from, + subject: config.subject, + to: email, + html: await buildEmail(purpose, email, user), + } + await transport.sendMail(message) } - diff --git a/packages/worker/src/api/routes/admin/configs.js b/packages/worker/src/api/routes/admin/configs.js index d64900cece..0b8c9626d1 100644 --- a/packages/worker/src/api/routes/admin/configs.js +++ b/packages/worker/src/api/routes/admin/configs.js @@ -10,7 +10,9 @@ function smtpValidation() { return Joi.object({ port: Joi.number().required(), host: Joi.string().required(), - from: Joi.string().email().required(), + from: Joi.string() + .email() + .required(), secure: Joi.boolean().optional(), selfSigned: Joi.boolean().optional(), auth: Joi.object({ diff --git a/packages/worker/src/api/routes/admin/email.js b/packages/worker/src/api/routes/admin/email.js index 4a122f4791..66079c5fbb 100644 --- a/packages/worker/src/api/routes/admin/email.js +++ b/packages/worker/src/api/routes/admin/email.js @@ -15,7 +15,10 @@ function buildEmailSendValidation() { }).required().unknown(true)) } -router - .post("/api/admin/email/send", buildEmailSendValidation(), controller.sendEmail) +router.post( + "/api/admin/email/send", + buildEmailSendValidation(), + controller.sendEmail +) module.exports = router diff --git a/packages/worker/src/utilities/email.js b/packages/worker/src/utilities/email.js new file mode 100644 index 0000000000..bc3933531a --- /dev/null +++ b/packages/worker/src/utilities/email.js @@ -0,0 +1,21 @@ +const nodemailer = require("nodemailer") + +exports.createSMTPTransport = (config) => { + const options = { + port: config.port, + host: config.host, + secure: config.secure || false, + auth: config.auth, + } + if (config.selfSigned) { + options.tls = { + rejectUnauthorized: false, + } + } + return nodemailer.createTransport(options) +} + +exports.verifyConfig = async config => { + const transport = exports.createSMTPTransport(config) + await transport.verify() +}