From 12e23cb156a340e9b2603344fd433abe905f3879 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 19 Jul 2024 15:41:06 -0700 Subject: [PATCH] Removed sendgrid, use emailService for all emails. Updated env vars, updated scripts --- Server/controllers/authController.js | 36 +- Server/index.js | 4 +- Server/service/emailService.js | 39 +- Server/templates/passwordReset.mjml | 10 +- Server/templates/welcomeEmail.mjml | 1 + .../utils/emailTemplates/downAlertTemplate.js | 469 ------------------ Server/utils/emailTemplates/images/image1.png | Bin 52427 -> 0 bytes .../utils/emailTemplates/registerTemplate.js | 435 ---------------- Server/utils/sendEmail.js | 45 -- uptime.sh | 40 +- 10 files changed, 83 insertions(+), 996 deletions(-) delete mode 100644 Server/utils/emailTemplates/downAlertTemplate.js delete mode 100644 Server/utils/emailTemplates/images/image1.png delete mode 100644 Server/utils/emailTemplates/registerTemplate.js delete mode 100644 Server/utils/sendEmail.js diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js index 4da96e661..142508997 100644 --- a/Server/controllers/authController.js +++ b/Server/controllers/authController.js @@ -14,10 +14,6 @@ require("dotenv").config(); const { errorMessages, successMessages } = require("../utils/messages"); var jwt = require("jsonwebtoken"); const SERVICE_NAME = "auth"; -const { sendEmail } = require("../utils/sendEmail"); -const { - registerTemplate, -} = require("../utils/emailTemplates/registerTemplate"); /** * Creates and returns JWT token with an arbitrary payload @@ -89,15 +85,12 @@ const registerController = async (req, res, next) => { const token = issueToken(userForToken); - // Sending email to user with pre defined template - const template = registerTemplate("https://www.bluewavelabs.ca"); - await sendEmail( - [newUser.email], - "Welcome to Uptime Monitor", - template, - "Registered." + req.emailService.buildAndSendEmail( + "welcomeEmailTemplate", + { name: newUser.firstName }, + newUser.email, + "Welcome to Uptime Monitor" ); - return res.status(200).json({ success: true, msg: successMessages.AUTH_CREATE_USER, @@ -243,7 +236,7 @@ const checkAdminController = async (req, res) => { * @param {Express.Request} req * @property {Object} req.body * @property {string} req.body.email - * @param {Express.Response} res + * @property {EmailService} req.body.emailService * @returns {Promise} */ const recoveryRequestController = async (req, res, next) => { @@ -252,18 +245,23 @@ const recoveryRequestController = async (req, res, next) => { const user = await req.db.getUserByEmail(req, res); if (user) { const recoveryToken = await req.db.requestRecoveryToken(req, res); - await sendEmail( - [req.body.email], - "Uptime Monitor Password Recovery", - `Click here to reset your password`, - `Recovery token: ${recoveryToken.token}` + const name = user.firstName; + const email = req.body.email; + const url = `${process.env.CLIENT_HOST}/set-new-password/${recoveryToken.token}`; + + const msgId = await req.emailService.buildAndSendEmail( + "passwordResetTemplate", + { name, email, url }, + email, + "Bluewaves Uptime Password Resest" ); + return res.status(200).json({ success: true, msg: successMessages.AUTH_CREATE_RECOVERY_TOKEN, + data: msgId, }); } - // TODO Email token to user } catch (error) { error.service = SERVICE_NAME; next(error); diff --git a/Server/index.js b/Server/index.js index 23e5891db..45f44d0f3 100644 --- a/Server/index.js +++ b/Server/index.js @@ -59,7 +59,7 @@ const startApp = async () => { app.use((req, res, next) => { req.db = db; req.jobQueue = jobQueue; - req.emailSerivce = emailSerivce; + req.emailService = emailService; next(); }); @@ -109,7 +109,7 @@ const startApp = async () => { // Create services await connectDbAndRunServer(app, db); const jobQueue = await JobQueue.createJobQueue(db); - const emailSerivce = new EmailService(); + const emailService = new EmailService(); const cleanup = async () => { console.log("Shutting down gracefully"); diff --git a/Server/service/emailService.js b/Server/service/emailService.js index d44a20bb4..81acb5819 100644 --- a/Server/service/emailService.js +++ b/Server/service/emailService.js @@ -4,8 +4,20 @@ const nodemailer = require("nodemailer"); const { compile } = require("handlebars"); const { mjml2html } = require("mjml"); +/** + * Represents an email service that can load templates, build, and send emails. + */ class EmailService { + /** + * Constructs an instance of the EmailService, initializing template loaders and the email transporter. + */ constructor() { + /** + * Loads an email template from the filesystem. + * + * @param {string} templateName - The name of the template to load. + * @returns {Function} A compiled template function that can be used to generate HTML email content. + */ this.loadTemplate = (templateName) => { const templatePath = path.join( __dirname, @@ -15,7 +27,11 @@ class EmailService { return compile(templateContent); }; - // TODO Load less used templates in their respective functions + /** + * A lookup object to access preloaded email templates. + * @type {Object.} + * TODO Load less used templates in their respective functions + */ this.templateLookup = { welcomeEmailTemplate: this.loadTemplate("welcomeEmail"), employeeActivationTemplate: this.loadTemplate("employeeActivation"), @@ -25,17 +41,30 @@ class EmailService { passwordResetTemplate: this.loadTemplate("passwordReset"), }; + /** + * The email transporter used to send emails. + * @type {Object} + */ this.transporter = nodemailer.createTransport({ - host: process.env.EMAIL_SERVICE_HOST, - port: process.env.EMAIL_SERVICE_PORT, + host: process.env.SYSTEM_EMAIL_HOST, + port: process.env.SYSTEM_EMAIL_PORT, secure: true, // Use `true` for port 465, `false` for all other ports auth: { - user: process.env.EMAIL_SERVICE_USERNAME, - pass: process.env.EMAIL_SERVICE_PASSWORD, + user: process.env.SYSTEM_EMAIL_ADDRESS, + pass: process.env.SYSTEM_EMAIL_PASSWORD, }, }); } + /** + * Asynchronously builds and sends an email using a specified template and context. + * + * @param {string} template - The name of the template to use for the email body. + * @param {Object} context - The data context to render the template with. + * @param {string} to - The recipient's email address. + * @param {string} subject - The subject of the email. + * @returns {Promise} A promise that resolves to the messageId of the sent email. + */ buildAndSendEmail = async (template, context, to, subject) => { const buildHtml = (template, context) => { const mjml = this.templateLookup[template](context); diff --git a/Server/templates/passwordReset.mjml b/Server/templates/passwordReset.mjml index de1e23138..480fcb572 100644 --- a/Server/templates/passwordReset.mjml +++ b/Server/templates/passwordReset.mjml @@ -1,3 +1,5 @@ + + @@ -21,12 +23,10 @@

Hello {{name}}!

You are receiving this email because a password reset request - has been made for gorkem.cetin@bluewavelabs.ca. Please use the - code below on the site to reset your password. -

-

- Verification Code: {{verificationCode}} + has been made for {{email}}. Please use the + link below on the site to reset your password.

+ Reset Password

If you didn't request this, please ignore this email.

Thank you.

diff --git a/Server/templates/welcomeEmail.mjml b/Server/templates/welcomeEmail.mjml index cb71bb34c..a58c9f017 100644 --- a/Server/templates/welcomeEmail.mjml +++ b/Server/templates/welcomeEmail.mjml @@ -1,3 +1,4 @@ + diff --git a/Server/utils/emailTemplates/downAlertTemplate.js b/Server/utils/emailTemplates/downAlertTemplate.js deleted file mode 100644 index 2012d3c18..000000000 --- a/Server/utils/emailTemplates/downAlertTemplate.js +++ /dev/null @@ -1,469 +0,0 @@ -/** - * - * @param {String} loginUrl - login Url shared with registered user. - * @param {String} monitorName - * @param {String} timeStamp - * @returns {String} returns html content as String - */ -const downAlertTemplate = (loginUrl, monitorName, timeStamp) => { - return ` - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
-
-
- - - -
-
-
- - - - - - - -
- - - - - - - -
-   -
- -
- -
-
-
- - -
-
-
- - - - - -
-
-
- - - -
-
-
- - - - - - - -
- - -

Uptime Monitor

- - -
- -
-
-
- - -
-
-
- - - - - -
-
-
- - - -
-
-
- - - - - - - -
- -
-

by BlueWave Labs

-
- -
- -
-
-
- - -
-
-
- - - - - -
-
-
- - - -
-
-
- - - - - - - -
- - -

System Down Alert

- - -
- - - - - - - -
- - -

Your monitor service requires your attention

- - -
- -
-
-
- - -
-
-
- - - - - -
-
-
- - - -
-
-
- - - - - - - -
- -
-

-

  • ${monitorName}
  • -
  • ${timeStamp}
  • -

    -
    - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - -
    -

    Login your account to see more details!

    -
    - -
    - - - - - - - -
    - - - - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - -
    -

    © 2024 BlueWave Labs. All Rights Reserved.

    -
    - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - - - - - - - -
    -   -
    - -
    - -
    -
    -
    - - -
    -
    -
    - - - - -
    - - - - - - - ` -} - -module.exports = { downAlertTemplate } \ No newline at end of file diff --git a/Server/utils/emailTemplates/images/image1.png b/Server/utils/emailTemplates/images/image1.png deleted file mode 100644 index 1df9d736faff4f64368a171fb8ac4b70012bedb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52427 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 { - return ` - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - - - - - - - -
    -   -
    - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - - -

    Uptime Monitor

    - - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - -
    -

    by BlueWave Labs

    -
    - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - - -

    Registered!

    - - -
    - - - - - - - -
    - - -

    your account is ready for use

    - - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - - - - - - - - - -
    - - - - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - -
    -

    © 2024 BlueWave Labs. All Rights Reserved.

    -
    - -
    - -
    -
    -
    - - -
    -
    -
    - - - - - -
    -
    -
    - - - -
    -
    -
    - - - - - - - -
    - - - - - - - -
    -   -
    - -
    - -
    -
    -
    - - -
    -
    -
    - - - - -
    - - - - - - - ` -} - -module.exports = {registerTemplate} \ No newline at end of file diff --git a/Server/utils/sendEmail.js b/Server/utils/sendEmail.js deleted file mode 100644 index 306bec2c5..000000000 --- a/Server/utils/sendEmail.js +++ /dev/null @@ -1,45 +0,0 @@ -const sgMail = require("@sendgrid/mail"); -const logger = require("./logger"); -sgMail.setApiKey(process.env.SENDGRID_API_KEY); -const SERVICE_NAME = "Email_Service"; -/** - * @async - * @function - * @param {[String]} receivers - takes an array of strings - * @param {String} subject - takes a single string - * @param {String} contentHTML - takes a single string that contains HTML - * @param {String} contentText - takes a string to be used if contentHTML is not compatible - * @example - * await sendEmail(['veysel@bluewavelabs.ca','alex@bluewavelabs.ca'],'Testing Email Service','

    BlueWaveLabs

    ','Testing Email Service') - */ -const sendEmail = async ( - receivers, - subject, - contentHTML, - contentText = null -) => { - const msg = { - to: receivers, - from: { - name: "Uptime System", - email: process.env.SYSTEM_EMAIL_ADDRESS, // must be verified email by sendgrid - }, - subject: subject, - text: contentText || contentHTML, - html: contentHTML, - }; - try { - await sgMail.send(msg); - logger.info( - `Emails sent to receivers:${receivers} with the subject:${subject}`, - { service: SERVICE_NAME } - ); - } catch (error) { - logger.error(`Sending Email action failed, ERROR:${error}`, { - service: SERVICE_NAME, - }); - throw error; - } -}; - -module.exports = { sendEmail }; diff --git a/uptime.sh b/uptime.sh index 10e56bb57..43889078a 100755 --- a/uptime.sh +++ b/uptime.sh @@ -5,10 +5,11 @@ default_db_type="MongoDB" default_db_connection_string="mongodb://mongodb:27017/uptime_db" default_redis_host="redis" default_redis_port=6379 -default_system_email_address="veysel.boybay@outlook.com" -default_login_page_url="https://www.bluewavelabs.ca/" default_token_ttl="99d" +default_system_email_host="smtp.gmail.com" +default_system_email_port=465 + echo "Welcome to the Uptime Monitor Setup Script! \n" echo @@ -62,25 +63,31 @@ redis_port="${redis_port:-$default_redis_port}" echo "Redis Port: $redis_port" echo -read -p "Enter your System Email Address [$default_system_email_address]: " system_email_address -system_email_address="${system_email_address:-$default_system_email_address}" -echo "System Email Address: $system_email_address" +read -p "Enter your system email host [$default_system_email_host]: " system_email_host +system_email_host="${system_email_host:-$default_system_email_host}" +echo "System email host: $system_email_host" echo +read -p "Enter your system email port [$default_system_email_port]: " system_email_port +system_email_port="${system_email_port:-$default_system_email_port}" +echo "System email port: $system_email_port" +echo + +read -p "Enter your system email address: " system_email_address +echo "System email address: $system_email_address" +echo + +read -p "Enter your system email password: " system_email_password +echo "System email password: $system_email_password" +echo + + + read -p "Enter your Token TTL [$default_token_ttl]: " token_ttl token_ttl="${token_ttl:-$default_token_ttl}" echo "Token TTL: $token_ttl" echo -read -p "Enter your Login Page URL [$default_login_page_url]: " login_page_url -login_page_url="${login_page_url:-$default_login_page_url}" -echo "Login Page URL: $login_page_url" -echo - -read -p "Enter your Sendgrid API key: " sendgrid_api_key -echo "Sendgrid API key: $sendgrid_api_key" -echo - read -p "Enter your Pagespeed API key: " pagespeed_api_key echo "Pagespeed API key: $pagespeed_api_key" echo @@ -96,10 +103,11 @@ echo echo "DB_CONNECTION_STRING=\"$db_connection_string\"" echo "REDIS_HOST=\"$redis_host\"" echo "REDIS_PORT=$redis_port" + echo "SYSTEM_EMAIL_HOST=\"$system_email_host\"" + echo "SYSTEM_EMAIL_PORT=$system_email_port" echo "SYSTEM_EMAIL_ADDRESS=\"$system_email_address\"" - echo "LOGIN_PAGE_URL=\"$login_page_url\"" + echo "SYSTEM_EMAIL_PASSWORD=\"$system_email_password\"" echo "TOKEN_TTL=\"$token_ttl\"" - echo "SENDGRID_API_KEY=\"$sendgrid_api_key\"" echo "PAGESPEED_API_KEY=\"$pagespeed_api_key\"" } > ./Docker/server.env