mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-04-25 18:40:59 -05:00
Merge pull request #2486 from bluewave-labs/refactor/build-and-send-email
refactor: build and send
This commit is contained in:
@@ -7,7 +7,6 @@ import {
|
||||
recoveryTokenValidation,
|
||||
newPasswordValidation,
|
||||
} from "../validation/joi.js";
|
||||
import logger from "../utils/logger.js";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { getTokenFromHeaders } from "../utils/utils.js";
|
||||
import crypto from "crypto";
|
||||
@@ -15,12 +14,13 @@ import { handleValidationError, handleError } from "./controllerUtils.js";
|
||||
const SERVICE_NAME = "authController";
|
||||
|
||||
class AuthController {
|
||||
constructor(db, settingsService, emailService, jobQueue, stringService) {
|
||||
constructor({ db, settingsService, emailService, jobQueue, stringService, logger }) {
|
||||
this.db = db;
|
||||
this.settingsService = settingsService;
|
||||
this.emailService = emailService;
|
||||
this.jobQueue = jobQueue;
|
||||
this.stringService = stringService;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,21 +96,28 @@ class AuthController {
|
||||
|
||||
const token = this.issueToken(userForToken, appSettings);
|
||||
|
||||
this.emailService
|
||||
.buildAndSendEmail(
|
||||
"welcomeEmailTemplate",
|
||||
{ name: newUser.firstName },
|
||||
newUser.email,
|
||||
"Welcome to Uptime Monitor"
|
||||
)
|
||||
.catch((error) => {
|
||||
logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "registerUser",
|
||||
stack: error.stack,
|
||||
});
|
||||
try {
|
||||
const html = await this.emailService.buildEmail("welcomeEmailTemplate", {
|
||||
name: newUser.firstName,
|
||||
});
|
||||
this.emailService
|
||||
.sendEmail(newUser.email, "Welcome to Uptime Monitor", html)
|
||||
.catch((error) => {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "registerUser",
|
||||
stack: error.stack,
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
logger.warn({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "registerUser",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
|
||||
res.success({
|
||||
msg: this.stringService.authCreateUser,
|
||||
@@ -300,15 +307,16 @@ class AuthController {
|
||||
const name = user.firstName;
|
||||
const { clientHost } = this.settingsService.getSettings();
|
||||
const url = `${clientHost}/set-new-password/${recoveryToken.token}`;
|
||||
const msgId = await this.emailService.buildAndSendEmail(
|
||||
"passwordResetTemplate",
|
||||
{
|
||||
name,
|
||||
email,
|
||||
url,
|
||||
},
|
||||
|
||||
const html = await this.emailService.buildEmail("passwordResetTemplate", {
|
||||
name,
|
||||
email,
|
||||
"Checkmate Password Reset"
|
||||
url,
|
||||
});
|
||||
const msgId = await this.emailService.sendEmail(
|
||||
email,
|
||||
"Checkmate Password Reset",
|
||||
html
|
||||
);
|
||||
|
||||
return res.success({
|
||||
|
||||
@@ -71,24 +71,25 @@ class InviteController {
|
||||
|
||||
const inviteToken = await this.db.requestInviteToken({ ...req.body });
|
||||
const { clientHost } = this.settingsService.getSettings();
|
||||
this.emailService
|
||||
.buildAndSendEmail(
|
||||
"employeeActivationTemplate",
|
||||
{
|
||||
name: firstname,
|
||||
link: `${clientHost}/register/${inviteToken.token}`,
|
||||
},
|
||||
req.body.email,
|
||||
"Welcome to Uptime Monitor"
|
||||
)
|
||||
.catch((error) => {
|
||||
logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "issueInvitation",
|
||||
stack: error.stack,
|
||||
});
|
||||
|
||||
try {
|
||||
const html = await this.emailService.buildEmail("employeeActivationTemplate", {
|
||||
name: firstname,
|
||||
link: `${clientHost}/register/${inviteToken.token}`,
|
||||
});
|
||||
await this.emailService.sendEmail(
|
||||
req.body.email,
|
||||
"Welcome to Uptime Monitor",
|
||||
html
|
||||
);
|
||||
} catch (error) {
|
||||
logger.warn({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "sendInviteEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
|
||||
return res.success({
|
||||
msg: this.stringService.inviteIssued,
|
||||
|
||||
@@ -580,12 +580,8 @@ class MonitorController {
|
||||
const subject = this.stringService.testEmailSubject;
|
||||
const context = { testName: "Monitoring System" };
|
||||
|
||||
const messageId = await this.emailService.buildAndSendEmail(
|
||||
"testEmailTemplate",
|
||||
context,
|
||||
to,
|
||||
subject
|
||||
);
|
||||
const html = await this.emailService.buildEmail("testEmailTemplate", context);
|
||||
const messageId = await this.emailService.sendEmail(to, subject, html);
|
||||
|
||||
if (!messageId) {
|
||||
return res.error({
|
||||
|
||||
@@ -90,26 +90,21 @@ class SettingsController {
|
||||
const subject = this.stringService.testEmailSubject;
|
||||
const context = { testName: "Monitoring System" };
|
||||
|
||||
const messageId = await this.emailService.buildAndSendEmail(
|
||||
"testEmailTemplate",
|
||||
context,
|
||||
to,
|
||||
subject,
|
||||
{
|
||||
systemEmailHost,
|
||||
systemEmailPort,
|
||||
systemEmailUser,
|
||||
systemEmailAddress,
|
||||
systemEmailPassword,
|
||||
systemEmailConnectionHost,
|
||||
systemEmailSecure,
|
||||
systemEmailPool,
|
||||
systemEmailIgnoreTLS,
|
||||
systemEmailRequireTLS,
|
||||
systemEmailRejectUnauthorized,
|
||||
systemEmailTLSServername,
|
||||
}
|
||||
);
|
||||
const html = await this.emailService.buildEmail("testEmailTemplate", context);
|
||||
const messageId = await this.emailService.sendEmail(to, subject, html, {
|
||||
systemEmailHost,
|
||||
systemEmailPort,
|
||||
systemEmailUser,
|
||||
systemEmailAddress,
|
||||
systemEmailPassword,
|
||||
systemEmailConnectionHost,
|
||||
systemEmailSecure,
|
||||
systemEmailPool,
|
||||
systemEmailIgnoreTLS,
|
||||
systemEmailRequireTLS,
|
||||
systemEmailRejectUnauthorized,
|
||||
systemEmailTLSServername,
|
||||
});
|
||||
|
||||
if (!messageId) {
|
||||
return res.error({
|
||||
@@ -122,7 +117,7 @@ class SettingsController {
|
||||
data: { messageId },
|
||||
});
|
||||
} catch (error) {
|
||||
next(handleValidationError(error, SERVICE_NAME));
|
||||
next(handleError(error, SERVICE_NAME));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
+8
-7
@@ -239,13 +239,14 @@ const startApp = async () => {
|
||||
process.on("SIGTERM", shutdown);
|
||||
|
||||
//Create controllers
|
||||
const authController = new AuthController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
ServiceRegistry.get(EmailService.SERVICE_NAME),
|
||||
ServiceRegistry.get(JobQueue.SERVICE_NAME),
|
||||
ServiceRegistry.get(StringService.SERVICE_NAME)
|
||||
);
|
||||
const authController = new AuthController({
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
settingsService: ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
emailService: ServiceRegistry.get(EmailService.SERVICE_NAME),
|
||||
jobQueue: ServiceRegistry.get(JobQueue.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
logger: logger,
|
||||
});
|
||||
|
||||
const monitorController = new MonitorController(
|
||||
ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
|
||||
@@ -80,24 +80,28 @@ class EmailService {
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* 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<string>} A promise that resolves to the messageId of the sent email.
|
||||
*/
|
||||
buildAndSendEmail = async (template, context, to, subject, transportConfig) => {
|
||||
// TODO - Consider an update transporter method so this only needs to be recreated when smtp settings change
|
||||
buildEmail = async (template, context) => {
|
||||
try {
|
||||
const mjml = this.templateLookup[template](context);
|
||||
const html = await this.mjml2html(mjml);
|
||||
return html.html;
|
||||
} catch (error) {
|
||||
this.logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "buildEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
sendEmail = async (to, subject, html, transportConfig) => {
|
||||
let config;
|
||||
if (typeof transportConfig !== "undefined") {
|
||||
config = transportConfig;
|
||||
} else {
|
||||
config = await this.settingsService.getDBSettings();
|
||||
}
|
||||
|
||||
const {
|
||||
systemEmailHost,
|
||||
systemEmailPort,
|
||||
@@ -131,45 +135,24 @@ class EmailService {
|
||||
servername: systemEmailTLSServername,
|
||||
},
|
||||
};
|
||||
|
||||
this.transporter = this.nodemailer.createTransport(emailConfig);
|
||||
|
||||
const buildHtml = async (template, context) => {
|
||||
try {
|
||||
const mjml = this.templateLookup[template](context);
|
||||
const html = await this.mjml2html(mjml);
|
||||
return html.html;
|
||||
} catch (error) {
|
||||
this.logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "buildAndSendEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const sendEmail = async (to, subject, html) => {
|
||||
try {
|
||||
const info = await this.transporter.sendMail({
|
||||
to: to,
|
||||
from: systemEmailAddress,
|
||||
subject: subject,
|
||||
html: html,
|
||||
});
|
||||
return info;
|
||||
} catch (error) {
|
||||
this.logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "sendEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
};
|
||||
const html = await buildHtml(template, context);
|
||||
const info = await sendEmail(to, subject, html);
|
||||
return info?.messageId;
|
||||
try {
|
||||
const info = await this.transporter.sendMail({
|
||||
to: to,
|
||||
from: systemEmailAddress,
|
||||
subject: subject,
|
||||
html: html,
|
||||
});
|
||||
return info?.messageId;
|
||||
} catch (error) {
|
||||
this.logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "sendEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,16 @@ class NotificationService {
|
||||
const template = "hardwareIncidentTemplate";
|
||||
const context = { monitor: monitor.name, url: monitor.url, alerts };
|
||||
const subject = `Monitor ${monitor.name} infrastructure alerts`;
|
||||
this.emailService.buildAndSendEmail(template, context, address, subject);
|
||||
const html = await this.emailService.buildEmail(template, context);
|
||||
this.emailService.sendEmail(address, subject, html).catch((error) => {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
service: this.SERVICE_NAME,
|
||||
method: "sendHardwareEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -231,17 +240,22 @@ class NotificationService {
|
||||
const subject = this.stringService.testEmailSubject;
|
||||
const context = { testName: "Monitoring System" };
|
||||
|
||||
const messageId = await this.emailService.buildAndSendEmail(
|
||||
"testEmailTemplate",
|
||||
context,
|
||||
to,
|
||||
subject
|
||||
);
|
||||
try {
|
||||
const html = await this.emailService.buildEmail("testEmailTemplate", context);
|
||||
const messageId = await this.emailService.sendEmail(to, subject, html);
|
||||
|
||||
if (messageId) {
|
||||
return true;
|
||||
if (messageId) {
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
service: this.SERVICE_NAME,
|
||||
method: "sendTestEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -259,7 +273,17 @@ class NotificationService {
|
||||
const template = prevStatus === false ? "serverIsUpTemplate" : "serverIsDownTemplate";
|
||||
const context = { monitor: monitor.name, url: monitor.url };
|
||||
const subject = `Monitor ${monitor.name} is ${status === true ? "up" : "down"}`;
|
||||
this.emailService.buildAndSendEmail(template, context, address, subject);
|
||||
|
||||
const html = await this.emailService.buildEmail(template, context);
|
||||
this.emailService.sendEmail(address, subject, html).catch((error) => {
|
||||
this.logger.warn({
|
||||
message: error.message,
|
||||
service: this.SERVICE_NAME,
|
||||
method: "sendEmail",
|
||||
stack: error.stack,
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user