Skip to content

Commit b4a2757

Browse files
author
Maitray Suthar
committed
Completed registration, Added login, Added jwt token
1 parent 28d5e23 commit b4a2757

File tree

6 files changed

+1099
-528
lines changed

6 files changed

+1099
-528
lines changed

.env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
MONGODB_URL=YourConnectionString
1+
MONGODB_URL=YourConnectionString
2+
JWT_SECRET=YourSecret
3+
JWT_TIMEOUT_DURATION=2

controllers/AuthController.js

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
11
const 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+
*/
619
exports.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);

helpers/apiResponse.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,17 @@ exports.notFoundResponse = function (res, msg) {
3333

3434
exports.validationErrorWithData = function (res, msg, data) {
3535
var data = {
36-
status: 1,
36+
status: 0,
3737
message: msg,
3838
data: data
3939
}
4040
return res.status(400).json(data);
41+
}
42+
43+
exports.unauthorizedResponse = function (res, msg) {
44+
var data = {
45+
status: 0,
46+
message: msg,
47+
}
48+
return res.status(401).json(data);
4149
}

0 commit comments

Comments
 (0)