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 1df9d736f..000000000 Binary files a/Server/utils/emailTemplates/images/image1.png and /dev/null differ diff --git a/Server/utils/emailTemplates/registerTemplate.js b/Server/utils/emailTemplates/registerTemplate.js deleted file mode 100644 index ca2c39da7..000000000 --- a/Server/utils/emailTemplates/registerTemplate.js +++ /dev/null @@ -1,435 +0,0 @@ - - -/** - * - * @param {String} loginUrl - login Url shared with registered user. - * @returns {String} returns html content as String - */ -const registerTemplate = (loginUrl) => { - 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