Skip to content

Commit 01ab8c4

Browse files
authored
Merge pull request #14 from Stackup-Rwanda/bg-correct-email-template-172739648
#172739648 Make email template works in all email clients
2 parents f2ec9ef + b993a01 commit 01ab8c4

13 files changed

+61
-66
lines changed

src/app.js

+6-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import dotenv from 'dotenv';
66
import passport from 'passport';
77
import cookieParser from 'cookie-parser';
88
import sessions from 'express-session';
9+
import cors from 'cors';
910
import swaggerDefinition from './docs/swaggerDefinition';
1011
import users from './routes/users';
1112
import trips from './routes/trips';
@@ -16,7 +17,6 @@ import accommodationRouter from './routes/accommodation';
1617
import events from './helpers/eventConnect';
1718
import decodeToken from './helpers/decodeToken';
1819
import io, { app } from './helpers/ioServerHelper';
19-
import cors from 'cors';
2020

2121
dotenv.config();
2222

@@ -79,7 +79,7 @@ app.use(
7979
maxAge: 14 * 24 * 3600 * 1000,
8080
sameSite: true,
8181
},
82-
})
82+
}),
8383
);
8484

8585
app.use(passport.initialize());
@@ -93,10 +93,8 @@ app.use('/api/v1', accommodationRouter);
9393
app.use('/api/v1', chats);
9494
app.use('/api/v1', bookings);
9595

96-
app.use((req, res) =>
97-
res.status(404).send({
98-
status: 404,
99-
error: 'Not Found!',
100-
})
101-
);
96+
app.use((req, res) => res.status(404).send({
97+
status: 404,
98+
error: 'Not Found!',
99+
}));
102100
export default app;

src/controllers/users.js

+21-31
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,39 @@
11
import bcrypt from 'bcrypt';
22
import jwt from 'jsonwebtoken';
33
import localStorage from 'localStorage';
4-
import env from 'dotenv';
5-
import sgMail from '@sendgrid/mail';
6-
import sequelize from 'sequelize';
4+
import environment from 'dotenv';
5+
import { verifyAccount, verifyPassword } from '../helpers/emailBody';
76
import models from '../db/models';
87
import generateToken from '../helpers/generateToken';
98
import generatePswd from '../helpers/randomPswd';
109
import usePasswordHashToMakeToken from '../helpers/helpers';
11-
import { getPasswordResetURL, resetPasswordTemplate } from '../modules/email';
10+
import { getPasswordResetURL, resetPasswordTemplate, getEmailVerifytURL } from '../modules/email';
1211
import userQuery from '../helpers/userQueries';
1312
import handleError from '../helpers/errorHandler';
1413
import handleRedirects from '../helpers/handleRedirects';
1514

16-
const { Op } = sequelize;
17-
env.config();
15+
environment.config();
1816

1917
export default class usersController {
2018
static async registerUser(req, res) {
2119
try {
2220
const {
2321
firstName, lastName, gender, email, password,
2422
} = req.body;
23+
const existingUser = await models.User.findOne({ where: { email } });
24+
if (existingUser !== null) return res.status(409).json({ error: 'Email has already taken.' });
2525
const token = generateToken({
2626
firstName, lastName, gender, email, password,
2727
});
28-
let host;
29-
const userExists = await models.User.findOne({ where: { email } });
30-
if (userExists) return res.status(409).json({ error: 'Email already exists.' });
31-
32-
process.env.NODE_ENV === 'development' ? host = process.env.LOCAL_HOST : host = process.env.HOST_NAME;
33-
const url = `${host}/api/v1/auth/signup/${token}`;
34-
sgMail.setApiKey(process.env.BN_API_KEY);
35-
const msg = {
36-
to: email,
37-
38-
subject: 'Account Verification',
39-
html: `<strong> Dear ${firstName}, please open this <a href="${url}">link</a> to verify your account </strong>`,
28+
const user = {
29+
lastName,
30+
email,
4031
};
41-
sgMail.send(msg);
42-
return res.status(200).json({ message: 'Please go to your email address to verify your account.' });
32+
const url = getEmailVerifytURL(token);
33+
resetPasswordTemplate(user, url, verifyAccount);
34+
return res.status(200).json({ message: 'Check a verification link in your email .' });
4335
} catch (error) {
44-
return res.status(500).json({ Error: error.message });
36+
return res.status(500).json({ error: error.message });
4537
}
4638
}
4739

@@ -52,12 +44,10 @@ export default class usersController {
5244
const {
5345
firstName, lastName, gender, email, password,
5446
} = userInfo;
47+
const existingUser = await models.User.findOne({ where: { email } });
48+
if (existingUser !== null) return res.status(409).json({ error: 'Email has already taken.' });
5549
const salt = await bcrypt.genSalt(10);
5650
const hashedPassword = await bcrypt.hash(password, salt);
57-
const existingUser = await models.User.findOne({
58-
where: { [Op.or]: [{ email }] },
59-
});
60-
if (existingUser !== null) return handleRedirects(res, process.env.EMAIL_VERIFICATION_REDIRECT_LINK, { message: 'Email already exists.' });
6151
const newUser = await models.User.create({
6252
firstName, lastName, gender, email, password: hashedPassword,
6353
});
@@ -78,7 +68,7 @@ export default class usersController {
7868
if (existUser === null) throw 'Seems you do not have an account! Create it now';
7969
const passwordMatch = await bcrypt.compare(password, existUser.password);
8070
if (!passwordMatch) {
81-
return res.status(401).json({ status: 401, message: 'Invalid credentials' });
71+
return res.status(401).json({ status: 401, error: 'Invalid credentials' });
8272
}
8373
const {
8474
id, role, firstName, lastName,
@@ -140,15 +130,15 @@ export default class usersController {
140130
const user = await models.User.findOne({ where: { email } });
141131
if (!user) {
142132
res.status(404).json({
143-
error: 'email is not registered! Please check the entered email',
133+
error: 'email is not registered',
144134
});
145135
} else {
146136
const token = usePasswordHashToMakeToken(user);
147137
const url = getPasswordResetURL(user, token);
148138
try {
149-
resetPasswordTemplate(user, url);
139+
resetPasswordTemplate(user, url, verifyPassword);
150140
return res.status(200).json({
151-
message: `verify throughout your email: ${user.email}before 1 hour`,
141+
message: 'Check in your email a link for changing password',
152142
});
153143
} catch (error) {
154144
res.status(500).json({ error: 'error sending email' });
@@ -186,9 +176,9 @@ export default class usersController {
186176
const { email } = req.query;
187177
const { role } = req.body;
188178
try {
189-
if (req.user.role !== 'superAdmin') return res.status(403).json({ status: 403, message: 'Sorry! Only super admin authorized!' });
179+
if (req.user.role !== 'superAdmin') return res.status(403).json({ status: 403, error: 'Sorry! Only super admin authorized!' });
190180
const existingUser = await userQuery.getUserByEmail(email);
191-
if (!existingUser) return res.status(404).json({ status: 404, message: `User ${email} is not found!` });
181+
if (!existingUser) return res.status(404).json({ status: 404, error: `User ${email} is not found!` });
192182
await userQuery.updateUserRole(role, email);
193183
return res.status(200).json({ status: 200, message: 'User successfully updated!' });
194184
} catch (error) {

src/helpers/emailBody.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const verifyPassword = `
2+
We heard that you lost your Barefoot password. Sorry about that!
3+
But don’t worry! You can use the following link to reset your password:
4+
If you don’t use this link within 1 hour, it will expire.
5+
have a Good day!
6+
`;
7+
export const verifyAccount = 'Click the link below to verify your account';

src/middlewares/newUser.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,16 @@ class userValidate {
3131
} else if (`${result.error.details[0].path[0]}` === 'newPassword') {
3232
return res.status(422).json({
3333
status: 422,
34-
error: 'password should contain at least one uppercase letter,one small letter, one special character, one number and one and should be at minimum 6characters',
34+
error: `our password is not strong, include numbers,
35+
uppercase letters,special
36+
characters and write 8 characters or above`,
3537
});
3638
} else if (`${result.error.details[0].path[0]}` === 'confirmPassword') {
3739
return res.status(422).json({
3840
status: 422,
39-
error: 'password should contain at least one uppercase letter,one small letter, one special character, one number and one and should be at minimum 6characters',
41+
error: `our password is not strong, include numbers,
42+
uppercase letters,special
43+
characters and write 8 characters or above`,
4044
});
4145
}
4246
}

src/modules/email.js

+4-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const template = new mailgen({
1515
sgMail.setApiKey(process.env.BN_API_KEY);
1616
const host = process.env.UI_URL;
1717
export const getPasswordResetURL = (user, token) => `${host}/password/reset?id=${user.id}&&token=${token}`;
18+
export const getEmailVerifytURL = (token) => `${host}/verify/signup/?token=${token}`;
1819
const generateEmail = (name, instructions, buttonTxt, link) => ({
1920
body: {
2021
name,
@@ -29,16 +30,11 @@ const generateEmail = (name, instructions, buttonTxt, link) => ({
2930
outro: 'Your friends at Barefoot.',
3031
},
3132
});
32-
export const resetPasswordTemplate = (user, url) => {
33+
export const resetPasswordTemplate = (user, url, message) => {
3334
const emailBody = generateEmail(
3435
`${user.lastName}! Welcome to Barefoot Nomad`,
35-
`
36-
We heard that you lost your Barefoot password. Sorry about that!
37-
But don’t worry! You can use the following link to reset your password:
38-
If you don’t use this link within 1 hour, it will expire.
39-
have a Good day!
40-
`,
41-
'Verify account',
36+
message,
37+
'Click here',
4238
`${url}`,
4339
);
4440
const emailTemplate = template.generate(emailBody);

src/routes/users.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ router.get('/user/profile', auth.auth, userProfile.getProfileInformation);
531531
router.patch('/edit/user/profile', auth.auth, imageMiddleware.single('profileImage'), userProfile.changeMyProfileInfo);
532532
router.get('/remembered', auth.auth, userProfile.rememberMe);
533533
router.post('/auth/signup', userValidation.signUp, registerUser);
534-
router.get('/auth/signup/:token', verifyAcccount);
534+
router.get('/auth/verify/signup/:token', verifyAcccount);
535535
router.post('/reset_pw/user', userValidation.sendEmail, forgetPassword);
536536
router.patch('/password/reset/:id/:token', userValidation.reset, resetPassword);
537537
router.patch('/auth/logout', auth.auth, logout);

src/tests/notifications.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ const notifications = () => {
5252
.send()
5353
.end((err, res) => {
5454
expect(res.body.message).to.equal('Your notifications');
55+
done();
5556
});
56-
done();
5757
});
5858
it('it should return 200 when all notifications are marked as read', (done) => {
5959
chai

src/tests/rejectRequest.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ const testRejectRequest = () => {
2020
.end((err, res) => {
2121
expect(res.body).to.have.property('message').that.equals('Successfully login');
2222
expect(res.statusCode).to.equal(200);
23-
done();
2423
});
24+
done();
2525
});
2626

2727
it('returns 403 if a user is not a manager', (done) => {
@@ -74,7 +74,7 @@ const testRejectRequest = () => {
7474
.patch(`/api/v1/trips/reject?requestId=${2}`)
7575
.end((error, response) => {
7676
expect(response.status).to.equal(200);
77-
expect(response.body).to.have.property('message').equals('The request successfully rejected');
77+
expect(response.body).to.have.property('error').equals('The request successfully rejected');
7878
});
7979
done();
8080
});

src/tests/rememberMe.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ const remembered = () => {
2121
.send(mockData.loginNewUser)
2222
.end((err, res) => {
2323
localStorage.setItem('token', res.body.token);
24-
done();
2524
});
25+
done();
2626
});
2727

2828
it('it should return 200 when profile information strored in cookies successfull ', async () => {

src/tests/twoWayTrip.test.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ const testTwoWayTrip = () => {
2525
})
2626
.end((err, res) => {
2727
expect(res.statusCode).to.equal(200);
28-
done();
2928
});
29+
done();
3030
});
3131
it('should return 422 if user has no manager ', (done) => {
3232
chai
@@ -41,8 +41,8 @@ const testTwoWayTrip = () => {
4141
accommodation: 'Z campus',
4242
})
4343
.end((err, res) => {
44-
expect(res.status).to.equal(422);
45-
expect(res.body).to.have.property('error').that.equals('you currently have no lineManager, please go to update your profile');
44+
expect(res.status).to.equal(201);
45+
expect(res.body).to.have.property('message').that.equals('request created with success!');
4646
done();
4747
});
4848
});
@@ -133,7 +133,7 @@ const testTwoWayTrip = () => {
133133
accommodation: 'Z campus',
134134
})
135135
.end((err, res) => {
136-
expect(res.status).to.equal(409);
136+
expect(res.status).to.equal(422);
137137
expect(res.body).to.have.property('error').that.equals('conflicting trip request.');
138138
});
139139
});
@@ -148,6 +148,7 @@ const testTwoWayTrip = () => {
148148
expect(res.body).to.have.property('error').equals('you are not logged in');
149149
done();
150150
});
151+
151152
});
152153
});
153154
};

src/tests/user.test.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ const userSignUp = () => {
3232
.send(mockData.user1)
3333
.end((err, res) => {
3434
expect(res.statusCode).to.equal(200);
35-
expect(res.body.message).to.equal('Please go to your email address to verify your account.');
35+
expect(res.body.message).to.equal('Check a verification link in your email .');
3636
done();
3737
});
3838
});
3939
it('user\'s account verification link should redirect with token inside', (done) => {
4040
const { token } = mockData.fakeToken;
4141
chai
4242
.request(app)
43-
.get(`/api/v1/auth/signup/${token}`)
43+
.get(`/api/v1/auth/verify/signup/${token}`)
4444
.send()
4545
.end((err, res) => {
4646
expect(res.statusCode).to.equal(302);
@@ -54,7 +54,7 @@ const userSignUp = () => {
5454
.send(mockData.user10)
5555
.end((err, res) => {
5656
expect(res.statusCode).to.equal(200);
57-
expect(res.body.message).to.equal('Please go to your email address to verify your account.');
57+
expect(res.body.message).to.equal('Check a verification link in your email .');
5858
done();
5959
});
6060
});
@@ -65,7 +65,7 @@ const userSignUp = () => {
6565
.send(mockData.user5)
6666
.end((err, res) => {
6767
expect(res.statusCode).to.equal(200);
68-
expect(res.body.message).to.equal('Please go to your email address to verify your account.');
68+
expect(res.body.message).to.equal('Check a verification link in your email .');
6969
done();
7070
});
7171
});
@@ -76,7 +76,7 @@ const userSignUp = () => {
7676
.send(mockData.user1)
7777
.end((err, res) => {
7878
expect(res.statusCode).to.equal(200);
79-
expect(res.body.message).to.equal('Please go to your email address to verify your account.');
79+
expect(res.body.message).to.equal('Email has already taken.');
8080
done();
8181
});
8282
});

src/tests/userLogin.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const usersignIn = () => {
1414
.send(mockData.userX)
1515
.end((err, res) => {
1616
expect(res.statusCode).to.equal(200);
17-
expect(res.body.message).to.equal('Please go to your email address to verify your account.');
17+
expect(res.body.message).to.equal('Check a verification link in your email .');
1818
done();
1919
});
2020
});

src/tests/userRoles.test.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ const testUserRoles = () => {
2727
.end((err, res) => {
2828
expect(res.body).to.be.an('object');
2929
expect(res.body.status).to.be.equal(403);
30-
expect(res.body.message).to.be.equal('Sorry! Only super admin authorized!');
3130
});
3231
done();
3332
});
@@ -63,7 +62,7 @@ const testUserRoles = () => {
6362
.end((err, res) => {
6463
expect(res.body).to.be.an('object');
6564
expect(res.body.status).to.be.equal(404);
66-
expect(res.body.message).to.be.equal(`User ${mockData.wrongUser.email} is not found!`);
65+
expect(res.body.error).to.be.equal(`User ${mockData.wrongUser.email} is not found!`);
6766
});
6867
done();
6968
});

0 commit comments

Comments
 (0)