Skip to content

Commit

Permalink
ft(reset password): user should be able to reset password
Browse files Browse the repository at this point in the history
add send email for user
add reset password function

[finishes #168781681]
  • Loading branch information
sabin18 committed Oct 15, 2019
1 parent 68e37dd commit 7c95c2d
Show file tree
Hide file tree
Showing 10 changed files with 621 additions and 69 deletions.
264 changes: 198 additions & 66 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"method-override": "^2.3.10",
"methods": "^1.1.2",
"mocha": "^6.2.1",
"moment": "^2.24.0",
"mongoose": "^5.2.2",
"mongoose-unique-validator": "^2.0.1",
"morgan": "^1.9.1",
Expand Down
62 changes: 62 additions & 0 deletions src/controllers/userController.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import responseError from '../utils/responseError';
import strings from '../utils/stringsUtil';
import hashPassword from '../utils/hashPassword';
import generateToken from '../utils/generateToken';
import EmailToken from '../utils/EmailToken';

dotenv.config();

const { users } = models;

Expand Down Expand Up @@ -68,6 +71,65 @@ export default class UserController {
}
}

static Providelink(req, res) {
const { email } = req.body;
models.users.findOne({
where: {
email,
},
}).then(user => {
if (user == null) {
return responseUtil(res, 404, strings.users.error.USER_NOT_FOUND);
}
const verifyToken = EmailToken.ResetToken(user);
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: email,
from: 'BarefootNomad@gmail.com',
subject: 'Barefoot Nomad Resetpassword Link',
html: `<div style="font-family:Avenir,Helvetica,sans-serif;box-sizing:border-box;padding:35px;">
<h1 style="color: #848484;">Barefoot Nomad</h1>
<p style="font-family:Avenir,Helvetica,sans-serif;box-sizing:border-box;color:#74787e;font-size:16px;line-height:1.5em;margin-top:0;text-align:left">Welcome Back,<br> We are happy to be with you. Please you can reset your password now.<br> Click the button below to reset your password.</p>
<p><a style="background-color: #3097d1; border: 2px solid #3097d1; padding: 8px; color: #fff; font-size: 16px; text-decoration: none;cursor: pointer;" href="${req.protocol}://${req.headers.host}/api/v1/users/resetpassword/${verifyToken}">Reset passowrd</a>
</a></p>
<p style="color:#74787e;font-size:16px;line-height:1.5em;margin-top:0;text-align:left">Thank you for using our application!</p>
<p style="color:#74787e;font-size:16px;line-height:1.5em;margin-top:0;">Regards,<br>Barefoot Nomad Caret Team</p>
</div>`
};
sgMail.send(msg);
return responseUtil(res, 200, strings.users.success.SEND_EMAIL);
});
}

static Changepassword(req, res) {
const { email, newpassword, confirmpassword } = req.body;
models.users.findOne({
where: {
email,
},
}).then(user => {
if (user == null) {
return responseUtil(res, 404, strings.users.error.USER_NOT_FOUND);
}
if (newpassword !== confirmpassword) {
return responseUtil(res, 400, strings.users.error.PASSWORD_NOT_MATCH);
}
const compare = bcrypt.compareSync(req.body.newpassword, user.password);
if (compare) {
return responseUtil(res, 409, strings.users.error.PASSWORD_ALREADY_EXISTS);
}
models.users.update({

password: hashPassword(req.body.newpassword),
}, {
where: {
email,
},
});
return responseUtil(res, 200, strings.users.success.PASSWORD_CHANGED);
});
}

static async signIn(req, res) {
const { email, password } = req.body;
const user = await models.users.findOne({ where: { email } });
Expand Down
39 changes: 39 additions & 0 deletions src/middlewares/checkResetpassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import validateResetpassword from '../validation/validateResetpassword';
import responseError from '../utils/responseError';
import strings from '../utils/stringsUtil';

const checkReset = ({ body }, res, next) => {
const { error } = validateResetpassword.validateResetpassword(body);
if (error) {
const errorMessages = [];
error.details.forEach(detail => {
errorMessages.push(detail.message);
});
return responseError(
res,
400,
strings.users.error.BAD_SIGNUP_REQUEST,
errorMessages
);
}
return next();
};

const checkEmail = ({ body }, res, next) => {
const { error } = validateResetpassword.validateEmail(body);
if (error) {
const errorMessages = [];
error.details.forEach(detail => {
errorMessages.push(detail.message);
});
return responseError(
res,
400,
strings.users.error.BAD_SIGNUP_REQUEST,
errorMessages
);
}
return next();
};

export default { checkReset, checkEmail };
83 changes: 83 additions & 0 deletions src/routes/api/users.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import express from 'express';
import UserController from '../../controllers/userController';
import checkSignup from '../../middlewares/checkSignup';
import EmailToken from '../../utils/EmailToken';
import validateResetpassword from '../../middlewares/checkResetpassword';
import checkLogin from '../../middlewares/checkLogin';
import verifyExist from '../../middlewares/verifyExist';
import confirmPassword from '../../middlewares/confirmPassword';
Expand Down Expand Up @@ -114,8 +116,89 @@ const router = express.Router();
* '404':
* description: User no registered!
*/
/**
* @swagger
* definitions:
* forgotpassword:
* type: object
* properties:
* email:
* type: string
* example: krinkun09@gmail.com
*/
/**
* @swagger
* users/forgotpassword:
* post:
* tags:
* - Authentication
* name: Forgotpassword
* summary: Send link on Email
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: body
* in: body
* schema:
* $ref: '#/definitions/forgotpassword'
* responses:
* '200':
* description: please check your email to see the link for reseting password
* '400':
* description: can not find that user
*/
/**
* @swagger
* definitions:
* resetpassword:
* type: object
* properties:
* email:
* type: string
* example: krinkun09@gmail.com
* password:
* type: string
* format: string
* example: Pa55W0rd
*/
/**
* @swagger
* users/resetpassword/{token}:
* patch:
* tags:
* - Authentication
* name: Reset password
* summary: change password of the user
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: token
* in: path
* - name: body
* in: body
* schema:
* $ref: '#/definitions/resetpassword'
* responses:
* '200':
* description: password changed successfully'
* '404':
* description: can not find that user
* '409':
* description: you can not change password with old password
* '403':
* description: you are not authorized to access this endpoint
* '400':
* description: Token expired request a new one
*/

router.post('/register', checkSignup, verifyExist, confirmPassword, signup);
router.get('/verify/:token', UserController.userVerify);
router.post('/forgotpassword', validateResetpassword.checkEmail, UserController.Providelink);
router.patch('/resetpassword/:token', EmailToken.UseraccessRequired, validateResetpassword.checkReset, UserController.Changepassword);
router.post('/login', checkLogin, signIn);

export default router;
53 changes: 53 additions & 0 deletions src/tests/mockData/signupMockdata.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ const testdata = {
},

verifyUser: { id: 3, isVerified: false },
validuser: {
id: '3',
username: 'caretdevs',
email: 'teamcaret@gmail.com',
password: 'Pa$5W0rd',
confirmPassword: 'Pa$5W0rd',
},

invaliduser: {
id: '11',
username: 'caretdevs',
email: 'team11@gmail.com',
password: 'Pa$5W0rd',
confirmPassword: 'Pa$5W0rd',
},

missingEmail: {
username: 'caretdevs1',
Expand Down Expand Up @@ -35,6 +50,44 @@ const testdata = {
confirmPassword: 'Pa$5W0rDD',
},

passwordData: {
email: 'teamcaret@gmail.com',
},
MissingEmailData: {
email: '',
},
InvalidEmailData: {
email: 'teamcaret@gmail',
},
passwordData3: {
email: 'teamcaret41@gmail.com',
},
passwordData2: {
email: 'teamcaret@gmail.com',
newpassword: 'Pa$6W0rd',
confirmpassword: 'Pa$6W0rd',
},
Missingpassword: {
email: 'teamcaret@gmail.com',
newpassword: '',
confirmpassword: 'Pa$6W0rd',
},
Invalidpassword: {
email: 'teamcaret@gmail.com',
newpassword: 'Pa$6W0re',
confirmpassword: 'Pa$6W0rd',
},
invaliduser2: {
email: 'teamcaret41@gmail.com',
newpassword: 'Pa$5W0re',
confirmpassword: 'Pa$6W0rd',
},
wrongEmail: {
email: 'teamcaret41@gmail.com',
newpassword: 'Pa$5W0re',
confirmpassword: 'Pa$6W0rd',
},

};

export default testdata;
Loading

0 comments on commit 7c95c2d

Please sign in to comment.