Skip to content

Commit 9cd757d

Browse files
committed
Added Update & delete book functionality
1 parent a99d5e5 commit 9cd757d

File tree

3 files changed

+115
-61
lines changed

3 files changed

+115
-61
lines changed

controllers/AuthController.js

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
11
const UserModel = require("../models/UserModel");
2-
const { body,validationResult } = require('express-validator');
3-
const { sanitizeBody } = require('express-validator');
2+
const { body,validationResult } = require("express-validator");
3+
const { sanitizeBody } = require("express-validator");
44
//helper file to prepare responses.
5-
const apiResponse = require('../helpers/apiResponse');
6-
const bcrypt = require('bcrypt');
7-
const jwt = require('jsonwebtoken');
5+
const apiResponse = require("../helpers/apiResponse");
6+
const bcrypt = require("bcrypt");
7+
const jwt = require("jsonwebtoken");
88

99
/**
1010
* User registration.
11-
*
12-
* @param {string} firstName
11+
*
12+
* @param {string} firstName
1313
* @param {string} lastName
1414
* @param {string} email
1515
* @param {string} password
16-
*
16+
*
1717
* @returns {Object}
1818
*/
1919
exports.register = [
2020
// Validate fields.
21-
body('firstName').isLength({ min: 1 }).trim().withMessage('First name must be specified.')
22-
.isAlphanumeric().withMessage('First name has non-alphanumeric characters.'),
23-
body('lastName').isLength({ min: 1 }).trim().withMessage('Last name must be specified.')
24-
.isAlphanumeric().withMessage('Last name has non-alphanumeric characters.'),
25-
body('email').isLength({ min: 1 }).trim().withMessage('Email must be specified.')
26-
.isEmail().withMessage('Email must be a valid email address.').custom(value => {
27-
return UserModel.findOne({email : value}).then(user => {
21+
body("firstName").isLength({ min: 1 }).trim().withMessage("First name must be specified.")
22+
.isAlphanumeric().withMessage("First name has non-alphanumeric characters."),
23+
body("lastName").isLength({ min: 1 }).trim().withMessage("Last name must be specified.")
24+
.isAlphanumeric().withMessage("Last name has non-alphanumeric characters."),
25+
body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.")
26+
.isEmail().withMessage("Email must be a valid email address.").custom((value) => {
27+
return UserModel.findOne({email : value}).then((user) => {
2828
if (user) {
29-
return Promise.reject('E-mail already in use');
29+
return Promise.reject("E-mail already in use");
3030
}
3131
});
3232
}),
33-
body('password').isLength({ min: 6 }).trim().withMessage('Password must be 6 characters or greater.'),
33+
body("password").isLength({ min: 6 }).trim().withMessage("Password must be 6 characters or greater."),
3434
// Sanitize fields.
35-
sanitizeBody('firstName').escape(),
36-
sanitizeBody('lastName').escape(),
37-
sanitizeBody('email').escape(),
38-
sanitizeBody('password').escape(),
35+
sanitizeBody("firstName").escape(),
36+
sanitizeBody("lastName").escape(),
37+
sanitizeBody("email").escape(),
38+
sanitizeBody("password").escape(),
3939
// Process request after validation and sanitization.
4040
(req, res, next) => {
4141
try {
4242
// Extract the validation errors from a request.
4343
const errors = validationResult(req);
4444
if (!errors.isEmpty()) {
4545
// Display sanitized values/errors messages.
46-
return apiResponse.validationErrorWithData(res, 'Validation Error.', errors.array());
46+
return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array());
4747
}else {
4848
//hash input password
4949
bcrypt.hash(req.body.password,10,function(err, hash) {
@@ -53,7 +53,7 @@ exports.register = [
5353
firstName: req.body.firstName,
5454
lastName: req.body.lastName,
5555
email: req.body.email,
56-
password: hash,
56+
password: hash
5757
}
5858
);
5959

@@ -64,38 +64,37 @@ exports.register = [
6464
_id: user._id,
6565
firstName: user.firstName,
6666
lastName: user.lastName,
67-
email: user.email,
67+
email: user.email
6868
}
69-
return apiResponse.successResponseWithData(res,'Registration Success.', userData);
70-
});
71-
return;
69+
return apiResponse.successResponseWithData(res,"Registration Success.", userData);
70+
});
7271
});
7372
}
7473
} catch (err) {
75-
//throw error in json response with status 500.
74+
//throw error in json response with status 500.
7675
return apiResponse.ErrorResponse(res, err);
77-
}
76+
}
7877
}];
7978

8079
/**
8180
* User login.
82-
*
81+
*
8382
* @param {string} email
8483
* @param {string} password
85-
*
84+
*
8685
* @returns {Object}
8786
*/
8887
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(),
88+
body("email").isLength({ min: 1 }).trim().withMessage("Email name must be specified.")
89+
.isEmail().withMessage("Email must be a valid email address."),
90+
body("password").isLength({ min: 1 }).trim().withMessage("Password must be specified."),
91+
sanitizeBody("email").escape(),
92+
sanitizeBody("password").escape(),
9493
(req, res, next) => {
9594
try {
9695
const errors = validationResult(req);
9796
if (!errors.isEmpty()) {
98-
return apiResponse.validationErrorWithData(res, 'Validation Error.', errors.array());
97+
return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array());
9998
}else {
10099
UserModel.findOne({email : req.body.email}).then(user => {
101100
if (user) {
@@ -116,17 +115,17 @@ exports.login = [
116115
const secret = process.env.JWT_SECRET;
117116
//Generated JWT token with Payload and secret.
118117
userData.token = jwt.sign(jwtPayload, secret, jwtData);
119-
return apiResponse.successResponseWithData(res,'Login Success.', userData);
118+
return apiResponse.successResponseWithData(res,"Login Success.", userData);
120119
}else{
121-
return apiResponse.unauthorizedResponse(res, 'Email or Password wrong.');
120+
return apiResponse.unauthorizedResponse(res, "Email or Password wrong.");
122121
}
123122
});
124123
}else{
125-
return apiResponse.unauthorizedResponse(res, 'Email or Password wrong.');
124+
return apiResponse.unauthorizedResponse(res, "Email or Password wrong.");
126125
}
127126
});
128127
}
129128
} catch (err) {
130129
return apiResponse.ErrorResponse(res, err);
131-
}
130+
}
132131
}];

controllers/BookController.js

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ const apiResponse = require('../helpers/apiResponse');
55
const auth = require('../middlewares/jwt');
66
var moment = require('moment');
77
var mongoose = require('mongoose');
8+
mongoose.set('useFindAndModify', false);
89

10+
// Book Schema
911
function BookData(data) {
1012
this.title= data.title;
1113
this.description = data.description;
@@ -39,6 +41,8 @@ exports.bookList = [
3941
/**
4042
* Book Detail.
4143
*
44+
* @param {string} id
45+
*
4246
* @returns {Object}
4347
*/
4448
exports.bookDetail = [
@@ -64,7 +68,7 @@ exports.bookDetail = [
6468
];
6569

6670
/**
67-
* Store book.
71+
* Book store.
6872
*
6973
* @param {string} title
7074
* @param {string} description
@@ -76,7 +80,7 @@ exports.bookStore = [
7680
auth,
7781
body('title', 'Title must not be empty.').isLength({ min: 1 }).trim(),
7882
body('description', 'Description must not be empty.').isLength({ min: 1 }).trim(),
79-
body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim().custom(value => {
83+
body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim().custom((value,{req}) => {
8084
return Book.findOne({isbn : value,user: req.user._id}).then(book => {
8185
if (book) {
8286
return Promise.reject('Book already exist with this ISBN no.');
@@ -113,7 +117,7 @@ exports.bookStore = [
113117
];
114118

115119
/**
116-
* Store book.
120+
* Book update.
117121
*
118122
* @param {string} title
119123
* @param {string} description
@@ -125,7 +129,13 @@ exports.bookUpdate = [
125129
auth,
126130
body('title', 'Title must not be empty.').isLength({ min: 1 }).trim(),
127131
body('description', 'Description must not be empty.').isLength({ min: 1 }).trim(),
128-
body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim(),
132+
body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim().custom((value,{req}) => {
133+
return Book.findOne({isbn : value,user: req.user._id, _id: { "$ne": req.params.id }}).then(book => {
134+
if (book) {
135+
return Promise.reject('Book already exist with this ISBN no.');
136+
}
137+
});
138+
}),
129139
sanitizeBody('*').escape(),
130140
(req, res, next) => {
131141
try {
@@ -143,25 +153,69 @@ exports.bookUpdate = [
143153
else {
144154
if(!mongoose.Types.ObjectId.isValid(req.params.id)){
145155
return apiResponse.validationErrorWithData(res, 'Invalid Error.', "Invalid ID");
156+
}else{
157+
Book.findById(req.params.id, function (err, foundBook) {
158+
if(foundBook === null){
159+
return apiResponse.notFoundResponse(res,"Book not exists with this id");
160+
}else{
161+
//Check authorized user
162+
if(foundBook.user.toString() !== req.user._id){
163+
return apiResponse.unauthorizedResponse(res, 'You are not authorized to do this operation.');
164+
}else{
165+
//update book.
166+
Book.findByIdAndUpdate(req.params.id, book, {},function (err) {
167+
if (err) {
168+
return apiResponse.ErrorResponse(res, err);
169+
}else{
170+
let bookData = new BookData(book);
171+
return apiResponse.successResponseWithData(res,'Book update Success.', bookData);
172+
}
173+
});
174+
}
175+
}
176+
});
146177
}
147-
Book.findOne({isbn : req.body.isbn,user: req.user._id, _id: { "$ne": req.params.id }}).then(book => {
148-
if (book) {
149-
return apiResponse.validationErrorWithData(res, 'Validation Error.', "Book already exist with this ISBN no.");
150-
}
151-
});
152-
//Check authorized user
153-
Book.findById(req.params.id, function (err, book) {
154-
if(book.user.toString() !== req.user._id){
178+
}
179+
} catch (err) {
180+
//throw error in json response with status 500.
181+
return apiResponse.ErrorResponse(res, err);
182+
}
183+
}
184+
];
185+
186+
/**
187+
* Book Delete.
188+
*
189+
* @param {string} id
190+
*
191+
* @returns {Object}
192+
*/
193+
exports.bookDelete = [
194+
auth,
195+
function (req, res) {
196+
if(!mongoose.Types.ObjectId.isValid(req.params.id)){
197+
return apiResponse.validationErrorWithData(res, 'Invalid Error.', "Invalid ID");
198+
}
199+
try {
200+
Book.findById(req.params.id, function (err, foundBook) {
201+
if(foundBook === null){
202+
return apiResponse.notFoundResponse(res,"Book not exists with this id");
203+
}else{
204+
//Check authorized user
205+
if(foundBook.user.toString() !== req.user._id){
155206
return apiResponse.unauthorizedResponse(res, 'You are not authorized to do this operation.');
207+
}else{
208+
//delete book.
209+
Book.findByIdAndRemove(req.params.id,function (err) {
210+
if (err) {
211+
return apiResponse.ErrorResponse(res, err);
212+
}else{
213+
return apiResponse.successResponse(res,'Book delete Success.');
214+
}
215+
});
156216
}
157-
});
158-
//Save book.
159-
Book.findByIdAndUpdate(req.params.id, book, {},function (err) {
160-
if (err) { return apiResponse.ErrorResponse(res, err); }
161-
let bookData = new BookData(book);
162-
return apiResponse.successResponseWithData(res,'Book update Success.', bookData);
163-
});
164-
}
217+
}
218+
});
165219
} catch (err) {
166220
//throw error in json response with status 500.
167221
return apiResponse.ErrorResponse(res, err);

routes/book.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ router.get("/", BookController.bookList);
77
router.get("/:id", BookController.bookDetail);
88
router.post("/", BookController.bookStore);
99
router.put("/:id", BookController.bookUpdate);
10+
router.delete("/:id", BookController.bookDelete);
1011

1112
module.exports = router;

0 commit comments

Comments
 (0)