lbx-jwt
Version:
Provides JWT authentication for loopback applications. Includes storing roles inside tokens and handling refreshing. Built-in reuse detection.
200 lines • 7.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseMailService = exports.LBX_JWT_MAIL_TEMPLATE_DIRECTORY = void 0;
const tslib_1 = require("tslib");
const fs_1 = require("fs");
const path_1 = tslib_1.__importDefault(require("path"));
const handlebars_utilities_1 = require("../../encapsulation/handlebars.utilities");
/**
* The directory for jwt mail templates (eg. For Password reset.).
*/
exports.LBX_JWT_MAIL_TEMPLATE_DIRECTORY = path_1.default.join(__dirname, './templates');
/**
* A service that handles sending emails to users.
*/
class BaseMailService {
// eslint-disable-next-line jsdoc/require-returns
/**
* Defines static replacements that are useful for multiple email templates.
*
* By default this contains:
* - addressLine1
* - addressLine2
* - logoHeaderUrl
* - logoFooterUrl.
*
* Does not contain the html title, as this is unique per template and also not required.
*/
get defaultStaticReplacements() {
const res = {
addressLines: this.ADDRESS_LINES,
addressLinesColor: this.ADDRESS_LINES_COLOR,
logoHeaderUrl: this.LOGO_HEADER_URL,
logoHeaderWidth: this.LOGO_HEADER_WIDTH,
logoFooterUrl: this.LOGO_FOOTER_URL,
logoFooterWidth: this.LOGO_FOOTER_WIDTH,
backgroundColor: this.BACKGROUND_COLOR,
contentBackgroundColor: this.CONTENT_BACKGROUND_COLOR,
textColor: this.TEXT_COLOR,
defaultFontFamily: this.DEFAULT_FONT_FAMILY,
headlineTextColor: this.HEADLINE_TEXT_COLOR,
buttonCss: this.BUTTON_CSS,
buttonHoverCss: this.BUTTON_HOVER_CSS
};
return res;
}
constructor() {
/**
* The path to the base email template.
*/
this.BASE_MAIL_TEMPLATE_PATH = `${exports.LBX_JWT_MAIL_TEMPLATE_DIRECTORY}/base-mail.hbs`;
/**
* The width of the logo placed inside the header.
*/
this.LOGO_HEADER_WIDTH = 165;
/**
* The width of the logo placed inside the footer.
*/
this.LOGO_FOOTER_WIDTH = 500;
/**
* The label for Password Reset.
* @default 'Password Reset'
*/
this.PASSWORD_RESET_LABEL = 'Password Reset';
/**
* A css color value for the address lines in the footer.
*/
this.ADDRESS_LINES_COLOR = '#999999';
/**
* A css color value for the background of emails.
* @default 'whitesmoke'
*/
this.BACKGROUND_COLOR = 'whitesmoke';
/**
* A css color value for the background of the content box of the email.
* @default 'white'
*/
this.CONTENT_BACKGROUND_COLOR = 'white';
/**
* A css color value for any text elements.
* @default '#363636'
*/
this.TEXT_COLOR = '#363636';
/**
* The default css font family value for text elements.
* @default 'Arial, sans-serif'
*/
this.DEFAULT_FONT_FAMILY = 'Arial, sans-serif';
/**
* A css color value for headline text elements.
* @default '#363636'
*/
this.HEADLINE_TEXT_COLOR = '#363636';
/**
* The css for button elements.
*/
this.BUTTON_CSS = `
display: inline-block;
font-weight: bold;
padding: 15px;
padding-left: 20px;
padding-right: 20px;
background-color: white;
transition: background-color .3s;
color: black;
text-decoration: none;
border-radius: 5px;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);
`;
/**
* The css for button elements that are hovered.
*/
this.BUTTON_HOVER_CSS = 'background-color: whitesmoke;';
}
/**
* Sends an email for resetting the password of a specific user.
* Contains a link that is active for a limited amount of time.
* @param user - The user that should receive the email.
* @param resetToken - The reset token needed to generate the link.
*/
async sendResetPasswordMail(user, resetToken) {
const replacements = {
headline: this.PASSWORD_RESET_LABEL,
title: this.PASSWORD_RESET_LABEL,
content: this.getResetPasswordContent(resetToken, user),
...this.defaultStaticReplacements
};
const email = {
to: user.email,
from: this.WEBSERVER_MAIL,
subject: this.PASSWORD_RESET_LABEL,
html: this.getTemplate(this.BASE_MAIL_TEMPLATE_PATH)(replacements)
};
await this.handleEmail(email);
}
/**
* Gets the content for the reset password email.
* @param resetToken - The reset token needed for resetting the password.
* @param user - The user that tries to reset his password.
* @returns The finished html string that will be inserted inside the base template.
*/
getResetPasswordContent(resetToken, user) {
const contentReplacements = {
link: `${this.BASE_RESET_PASSWORD_LINK}/${resetToken.value}`,
firstLine: this.getFirstLineForUser(user),
paragraphsBeforeButton: [
'someone requested to change the password for your account.',
'Follow the link below to proceed:'
],
resetPasswordButtonLabel: 'Reset Password',
paragraphsAfterButton: [
'This link is valid for the next 5 minutes.',
'If you did not request to change your password, just ignore this email and your password will remain unchanged.'
]
};
return this.getTemplate(`${exports.LBX_JWT_MAIL_TEMPLATE_DIRECTORY}/reset-password.hbs`)(contentReplacements);
}
/**
* Defines what to do with the email.
* In a production environment this sends the email to the recipients.
* In a non production environment this saves the email data in a file for testing purposes.
* @param email - The email that should be handled.
*/
async handleEmail(email) {
if (this.PRODUCTION) {
await this.webserverMailTransporter.sendMail(email);
return;
}
if (!(0, fs_1.existsSync)(this.SAVED_EMAILS_PATH)) {
(0, fs_1.mkdirSync)(this.SAVED_EMAILS_PATH);
}
// for testing emails
(0, fs_1.writeFileSync)(`${this.SAVED_EMAILS_PATH}/${email.subject.replaceAll(' ', '')}.test.html`, email.html);
}
/**
* Gets the first line for the email based on the user the mail is sent to.
* This can be used to address the user correctly.
* @param user - The user that should receive the email.
* @returns The string that should be the first line inside the email.
*/
/**
* Gets the first line to use in an email (eg. "Dear Mr. X") based on the user that the email is sent to.
* @param user - The user that the email is sent to.
* @returns A string, most likely some sort of greeting.
*/
// eslint-disable-next-line unusedImports/no-unused-vars
getFirstLineForUser(user) {
return 'Hi,';
}
/**
* Gets the handlebars html template from the given path.
* @param path - The path of the template.
* @returns The compiled handlebars template.
*/
getTemplate(path) {
const sourceData = (0, fs_1.readFileSync)(path, 'utf8').toString();
return handlebars_utilities_1.HandlebarsUtilities.compile(sourceData);
}
}
exports.BaseMailService = BaseMailService;
//# sourceMappingURL=base-mail.service.js.map