11const UserModel = require ( "../models/UserModel" ) ;
2- const { body, validationResult } = require ( 'express-validator/check' ) ;
3- const { sanitizeBody } = require ( 'express-validator/filter' ) ;
4- var apiResponse = require ( '../helpers/apiResponse' ) ;
2+ const { body, validationResult } = require ( 'express-validator' ) ;
3+ const { sanitizeBody } = require ( 'express-validator' ) ;
4+ //helper file to prepare responses.
5+ const apiResponse = require ( '../helpers/apiResponse' ) ;
6+ const bcrypt = require ( 'bcrypt' ) ;
7+ const jwt = require ( 'jsonwebtoken' ) ;
58
9+ /**
10+ * User registration.
11+ *
12+ * @param {string } firstName
13+ * @param {string } lastName
14+ * @param {string } email
15+ * @param {string } password
16+ *
17+ * @returns {Object }
18+ */
619exports . register = [
720 // Validate fields.
821 body ( 'firstName' ) . isLength ( { min : 1 } ) . trim ( ) . withMessage ( 'First name must be specified.' )
922 . isAlphanumeric ( ) . withMessage ( 'First name has non-alphanumeric characters.' ) ,
1023 body ( 'lastName' ) . isLength ( { min : 1 } ) . trim ( ) . withMessage ( 'Last name must be specified.' )
1124 . isAlphanumeric ( ) . withMessage ( 'Last name has non-alphanumeric characters.' ) ,
1225 body ( 'email' ) . isLength ( { min : 1 } ) . trim ( ) . withMessage ( 'Email must be specified.' )
13- . isEmail ( ) . withMessage ( 'Email must be a valid email address.' ) ,
26+ . isEmail ( ) . withMessage ( 'Email must be a valid email address.' ) . custom ( value => {
27+ return UserModel . findOne ( { email : value } ) . then ( user => {
28+ if ( user ) {
29+ return Promise . reject ( 'E-mail already in use' ) ;
30+ }
31+ } ) ;
32+ } ) ,
1433 body ( 'password' ) . isLength ( { min : 6 } ) . trim ( ) . withMessage ( 'Password must be 6 characters or greater.' ) ,
1534 // Sanitize fields.
1635 sanitizeBody ( 'firstName' ) . escape ( ) ,
@@ -22,25 +41,90 @@ exports.register = [
2241 try {
2342 // Extract the validation errors from a request.
2443 const errors = validationResult ( req ) ;
25- // Create User object with escaped and trimmed data
26- var user = new UserModel (
27- {
28- firstName : req . body . firstName ,
29- lastName : req . body . lastName ,
30- email : req . body . email ,
31- password : req . body . password ,
32- }
33- ) ;
3444 if ( ! errors . isEmpty ( ) ) {
3545 // Display sanitized values/errors messages.
3646 return apiResponse . validationErrorWithData ( res , 'Validation Error.' , errors . array ( ) ) ;
3747 } else {
38- // Save user.
39- user . save ( function ( err ) {
40- if ( err ) { return apiResponse . ErrorResponse ( res , err ) ; }
41- return apiResponse . successResponseWithData ( res , 'Registration Success.' , user ) ;
42- } ) ;
43- return ;
48+ //hash input password
49+ bcrypt . hash ( req . body . password , 10 , function ( err , hash ) {
50+ // Create User object with escaped and trimmed data
51+ var user = new UserModel (
52+ {
53+ firstName : req . body . firstName ,
54+ lastName : req . body . lastName ,
55+ email : req . body . email ,
56+ password : hash ,
57+ }
58+ ) ;
59+
60+ // Save user.
61+ user . save ( function ( err ) {
62+ if ( err ) { return apiResponse . ErrorResponse ( res , err ) ; }
63+ let userData = {
64+ _id : user . _id ,
65+ firstName : user . firstName ,
66+ lastName : user . lastName ,
67+ email : user . email ,
68+ }
69+ return apiResponse . successResponseWithData ( res , 'Registration Success.' , userData ) ;
70+ } ) ;
71+ return ;
72+ } ) ;
73+ }
74+ } catch ( err ) {
75+ //throw error in json response with status 500.
76+ return apiResponse . ErrorResponse ( res , err ) ;
77+ }
78+ } ] ;
79+
80+ /**
81+ * User login.
82+ *
83+ * @param {string } email
84+ * @param {string } password
85+ *
86+ * @returns {Object }
87+ */
88+ exports . login = [
89+ body ( 'email' ) . isLength ( { min : 1 } ) . trim ( ) . withMessage ( 'Email name must be specified.' )
90+ . isEmail ( ) . withMessage ( 'Email must be a valid email address.' ) ,
91+ body ( 'password' ) . isLength ( { min : 1 } ) . trim ( ) . withMessage ( 'Password must be specified.' ) ,
92+ sanitizeBody ( 'email' ) . escape ( ) ,
93+ sanitizeBody ( 'password' ) . escape ( ) ,
94+ ( req , res , next ) => {
95+ try {
96+ const errors = validationResult ( req ) ;
97+ if ( ! errors . isEmpty ( ) ) {
98+ return apiResponse . validationErrorWithData ( res , 'Validation Error.' , errors . array ( ) ) ;
99+ } else {
100+ UserModel . findOne ( { email : req . body . email } ) . then ( user => {
101+ if ( user ) {
102+ //Compare given password with db's hash.
103+ bcrypt . compare ( req . body . password , user . password , function ( err , same ) {
104+ if ( same ) {
105+ let userData = {
106+ _id : user . _id ,
107+ firstName : user . firstName ,
108+ lastName : user . lastName ,
109+ email : user . email ,
110+ }
111+ //Prepare JWT token for authentication
112+ const jwtPayload = userData ;
113+ const jwtData = {
114+ expiresIn : process . env . JWT_TIMEOUT_DURATION ,
115+ } ;
116+ const secret = process . env . JWT_SECRET ;
117+ //Generated JWT token with Payload and secret.
118+ userData . token = jwt . sign ( jwtPayload , secret , jwtData ) ;
119+ return apiResponse . successResponseWithData ( res , 'Login Success.' , userData ) ;
120+ } else {
121+ return apiResponse . unauthorizedResponse ( res , 'Email or Password wrong.' ) ;
122+ }
123+ } ) ;
124+ } else {
125+ return apiResponse . unauthorizedResponse ( res , 'Email or Password wrong.' ) ;
126+ }
127+ } ) ;
44128 }
45129 } catch ( err ) {
46130 return apiResponse . ErrorResponse ( res , err ) ;
0 commit comments