Skip to content

Commit b779ab5

Browse files
committed
Use ejs and html file for templating
1 parent 4369820 commit b779ab5

File tree

7 files changed

+174
-11
lines changed

7 files changed

+174
-11
lines changed

backend/user-service/.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,12 @@ REDIS_PORT=6379
3535
PEERPREP_QUESTION_INITDB_NAME=peerprepQuestionServiceDB # must match question service .env file and init-mongo.js
3636
PEERPREP_USER_INITDB_NAME=peerprepUserServiceDB # must match user service .env file and init-mongo.js
3737
PEERPREP_MATCHING_INITDB_NAME=peerprepMatchingServiceDB # must match user service .env file and init-mongo.js
38+
39+
# SMTP configs for email
40+
SMTP_HOST=smtp.gmail.com
41+
SMTP_PORT=587
42+
43+
SMTP_PASSWORD=scdqcveqpurzzajj
44+
45+
# App URL
46+
APP_URL=http://localhost:3000

backend/user-service/config/emailConfig.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import dotenv from "dotenv";
22

33
dotenv.config();
44

5-
export const emailOptions = {
5+
export const emailConfig = {
66
user: process.env.SMTP_USER,
77
password: process.env.SMTP_PASSWORD,
88
smtp_host: process.env.SMTP_HOST,

backend/user-service/controller/user-controller.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,17 @@ export async function forgetPassword(req, res, next) {
169169
try {
170170
const { email } = req.body;
171171
const resetToken = await TokenService.generateResetToken(email);
172-
const resetPasswordLink = `${process.env.APP_URL}/reset-password?token=${resetToken}`;
172+
const passwordResetLink = `${process.env.APP_URL}/reset-password?token=${resetToken}`;
173+
173174
await sendEmail({
174175
to: email,
175176
subject: "Reset password",
176-
html: `Click <a href=${resetPasswordLink}>here</a> to reset your password`,
177+
htmlTemplateData: { passwordResetLink },
177178
});
178179

179180
res.sendStatus(204);
180181
} catch (err) {
182+
console.error(err);
181183
next(err);
182184
}
183185
}
@@ -200,7 +202,6 @@ export async function resetPassword(req, res, next) {
200202
const salt = bcrypt.genSaltSync(PASSWORD_SALT);
201203
const hashedPassword = bcrypt.hashSync(password, salt);
202204
const updatedUser = await _updateUserById(user.id, user.username, user.email, hashedPassword);
203-
204205
await TokenService.blacklistResetToken(decoded);
205206

206207
return res.status(200).json({

backend/user-service/package-lock.json

Lines changed: 128 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/user-service/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"cookie-parser": "^1.4.6",
2121
"cors": "^2.8.5",
2222
"dotenv": "^16.4.5",
23+
"ejs": "^3.1.10",
2324
"express": "^4.19.2",
2425
"jsonwebtoken": "^9.0.2",
2526
"mongoose": "^8.5.4",

backend/user-service/services/emailService.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
import nodemailer from "nodemailer";
2-
import { emailOptions } from "../config/emailConfig";
2+
import { emailConfig } from "../config/emailConfig.js";
3+
import fs from "fs";
4+
import path from "path";
5+
import { fileURLToPath } from "url";
6+
import ejs from "ejs";
7+
8+
const __filename = fileURLToPath(import.meta.url);
9+
const __dirname = path.dirname(__filename);
310

411
const transporter = nodemailer.createTransport({
5-
host: emailOptions.smtp_host,
6-
port: emailOptions.smtp_port,
12+
host: emailConfig.smtp_host,
13+
port: emailConfig.smtp_port,
714
auth: {
8-
user: emailOptions.user,
9-
pass: emailOptions.password,
15+
user: emailConfig.user,
16+
pass: emailConfig.password,
1017
},
1118
});
1219

@@ -18,8 +25,13 @@ transporter.verify(function (error, success) {
1825
}
1926
});
2027

21-
export const sendEmail = async ({ to, subject, text, html }) => {
22-
const emailOptions = { from: emailOptions.user, to, subject, text, html };
28+
export const sendEmail = async ({ to, subject, htmlTemplateData }) => {
29+
const pathToTemplateHtml = path.resolve(__dirname, "../utils/emailTemplate.html");
30+
const template = fs.readFileSync(pathToTemplateHtml, "utf-8");
31+
32+
const html = ejs.render(template, htmlTemplateData);
33+
34+
const emailOptions = { from: emailConfig.user, to, subject, html };
2335
try {
2436
await transporter.sendMail(emailOptions);
2537
} catch (err) {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head></head>
4+
<body>
5+
<p>Dear user,</p>
6+
<p>You have requested to change your password.</p>
7+
<p>
8+
You can click <a href="<%= passwordResetLink %>">here</a>, which will bring you to a password reset page to reset your
9+
password. The link is only valid for <b>15 minutes</b>.
10+
</p>
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)