-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ed3ed90
commit a02c8aa
Showing
40 changed files
with
3,081 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const express = require("express"); | ||
const path = require("path"); | ||
const cookieParser = require("cookie-parser"); | ||
const logger = require("morgan"); | ||
const cors = require("cors"); | ||
|
||
const userRouter = require("./routes/userRouter"); | ||
const authRouter = require("./routes/authRouter"); | ||
const authorRouter = require("./routes/authorRouter"); | ||
const bookRouter = require("./routes/bookRouter") | ||
const bookShelvesRouter = require("./routes/bookShelvesRouter"); | ||
const commentRouter = require("./routes/commentRouter"); | ||
const libraryRouter = require("./routes/libraryRouter"); | ||
const orderRouter = require("./routes/orderRouter"); | ||
const publisherRouter = require("./routes/publisherRouter"); | ||
|
||
|
||
const app = express(); | ||
|
||
app.use(logger("dev")); | ||
app.use(cors()); | ||
app.use(express.json()); | ||
app.use(express.urlencoded({ extended: false })); | ||
app.use(cookieParser()); | ||
app.use(express.static(path.join(__dirname, "public"))); | ||
|
||
//routes | ||
app.use('/auth', authRouter); | ||
app.use("/user", userRouter); | ||
app.use("/book", bookRouter); | ||
app.use("/bookShelves", bookShelvesRouter); | ||
app.use("/order", orderRouter); | ||
app.use("/comment", commentRouter); | ||
app.use("/author", authorRouter); | ||
app.use("/library", libraryRouter); | ||
app.use("/publisher", publisherRouter); | ||
|
||
|
||
module.exports = app; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
NODE_ENV=development | ||
DOMAIN=127.0.0.1 | ||
PORT=8000 | ||
DATABASE=mongodb+srv://shaghayeghnz:[email protected]/test?authSource=admin&replicaSet=atlas-s5abiw-shard-0&readPreference=primary&appname=MongoDB%20Compass&ssl=true | ||
|
||
JWT_EXPIRES_IN=90d | ||
JWT_SECRET=secret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
const jwt = require("jsonwebtoken"); | ||
const { promisify } = require("util"); | ||
const bcrypt = require("bcryptjs"); | ||
|
||
const User = require("./../models/userModel"); | ||
const catchAsync = require("./../util/catchAsync"); | ||
const AppError = require("./../util/appError"); | ||
|
||
const createSendToken = (user, statusCode, res) => { | ||
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { | ||
expiresIn: process.env.JWT_EXPIRES_IN, | ||
}); | ||
|
||
// Remove the password from the output | ||
user.password = undefined; | ||
|
||
res.status(statusCode).json({ | ||
status: "Success", | ||
token, | ||
user | ||
}); | ||
}; | ||
|
||
exports.signUp = catchAsync(async (req, res, next) => { | ||
const newUser = await User.create(req.body); | ||
|
||
createSendToken(newUser, 201, res); | ||
}); | ||
|
||
exports.logIn = catchAsync(async (req, res, next) => { | ||
const { username, password } = req.body; | ||
|
||
//Check if email and password exist | ||
if (!username || !password) { | ||
return next(new AppError("Please enter your username and password", 400)); | ||
} | ||
|
||
//Check if the user exists && if the password is correct | ||
const user = await User.find({ username: username }).select("+password"); | ||
|
||
if((user.length !== 1) || !(await bcrypt.compare(password, user[0].password))) { | ||
return next(new AppError("Wrong username or password", 401)); | ||
} | ||
|
||
//If everyhing ok, send token to client | ||
createSendToken(user[0], 200, res); | ||
}); | ||
|
||
exports.isLoggedIn = catchAsync(async (req, res, next) => { | ||
//Getting token and check if it's there | ||
let token; | ||
|
||
if ( | ||
req.headers.authorization && | ||
req.headers.authorization.startsWith("Bearer") | ||
) { | ||
token = req.headers.authorization.split(" ")[1]; | ||
} | ||
|
||
if (!token) { | ||
return next(new AppError("Please log in first!", 401)); | ||
} | ||
//Validate token | ||
const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET); | ||
|
||
//Check if user still exists | ||
const currentUser = await User.findById(decoded.id); | ||
|
||
if (!currentUser) { | ||
return next( | ||
new AppError("User with this token does not exist!", 401) | ||
); | ||
} | ||
|
||
req.user = currentUser; | ||
res.locals.user = currentUser; | ||
next(); | ||
}); | ||
|
||
exports.restrictedTo = (...roles) => { | ||
return (req, res, next) => { | ||
if (!roles.includes(req.user.role)) { | ||
return next( | ||
new AppError("You do not have permission!", 403) | ||
); | ||
} | ||
next(); | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
const AuthorModel = require("../models/authorModel"); | ||
|
||
const catchAsync = require("../util/catchAsync"); | ||
const AppError = require("../util/appError"); | ||
|
||
exports.getAuthor = catchAsync(async (req, res, next) => { | ||
const { authorID } = req.params; | ||
if (!authorID) { | ||
return next(new AppError("Request is not providing the author ID!", 400)); | ||
} | ||
const author = await AuthorModel.findById(authorID); | ||
if (!author) { | ||
return next(new AppError("No authors found!", 404)); | ||
} | ||
res.status(200).json({ | ||
status: "Success", | ||
author, | ||
}); | ||
}); | ||
|
||
exports.createAuthor = catchAsync(async (req, res, next) => { | ||
const newAuthor = await AuthorModel.create({ | ||
name: req.body.name, | ||
artisticName: req.body.artisticName, | ||
genre: req.body.genre, | ||
URL: req.body.URL, | ||
born: req.body.born, | ||
died: req.body.died, | ||
}); | ||
|
||
res.status(201).json({ | ||
status: "Success", | ||
newAuthor, | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
const book_bookShelvesModel = require("../models/book-bookShelves"); | ||
|
||
const catchAsync = require("../util/catchAsync"); | ||
const AppError = require("../util/appError"); | ||
|
||
exports.getBooksOfBookShelf = catchAsync(async (req, res, next) => { | ||
const { bookshelfID } = req.params; | ||
if (!bookshelfID) { | ||
return next( | ||
new AppError("Request is not providing the book shelf ID!", 400) | ||
); | ||
} | ||
|
||
const bookShelf = await book_bookShelvesModel.find({ | ||
bookShelves: bookshelfID, | ||
}); | ||
if (!bookShelf) { | ||
return next(new AppError("No book shelf found!", 404)); | ||
} | ||
res.status(200).json({ | ||
status: "Success", | ||
bookShelf, | ||
}); | ||
}); | ||
|
||
exports.addBooksToBookShelf = catchAsync(async (req, res, next) => { | ||
|
||
const newBooks = await book_bookShelvesModel.create({ | ||
books: req.body.books, | ||
bookShelves: req.body.bookShelves, | ||
}); | ||
|
||
res.status(201).json({ | ||
status: "Success", | ||
newBooks, | ||
}); | ||
}); | ||
|
||
|
||
//todo: update the number of books in bookshelf | ||
|
||
//! delete books of bookshelf | ||
// exports.deleteBooksOfBookShelf = catchAsync(async (req, res, next) => { | ||
// const { bookShelfID } = req.params; | ||
// if (!bookShelfID) { | ||
// return next( | ||
// new AppError("Request is not providing the book shelf ID!", 400) | ||
// ); | ||
// } | ||
|
||
// const bookShelf = await book_bookShelvesModel.find({ | ||
// bookShelves: bookShelfID, | ||
// }); | ||
// if (!bookShelf) { | ||
// return next(new AppError("No books found in this book shelf!", 404)); | ||
// } | ||
|
||
// if (bookShelf.books.includes(req.body.book)) { | ||
// } | ||
|
||
// res.status(200).json({ | ||
// status: "Success", | ||
// bookShelves, | ||
// }); | ||
// }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
const book_libraryModel = require("../models/book-library"); | ||
|
||
const catchAsync = require("../util/catchAsync"); | ||
const AppError = require("../util/appError"); | ||
|
||
exports.getBooksOfLibrary = catchAsync(async (req, res, next) => { | ||
const { libraryID } = req.params; | ||
if (!libraryID) { | ||
return next(new AppError("Request is not providing the library ID!", 400)); | ||
} | ||
|
||
const library = await book_libraryModel.find({ | ||
library: libraryID, | ||
}); | ||
if (!library) { | ||
return next(new AppError("No books found in the this library!", 404)); | ||
} | ||
res.status(200).json({ | ||
status: "Success", | ||
library, | ||
}); | ||
}); | ||
|
||
exports.addBooksToLibrary = catchAsync(async (req, res, next) => { | ||
|
||
const newBooks = await book_libraryModel.create({ | ||
bookID: req.body.bookID, | ||
library: req.body.library, | ||
}); | ||
|
||
res.status(201).json({ | ||
status: "Success", | ||
newBooks, | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
const BookModel = require("../models/bookModel"); | ||
const { sellingStatus } = require("../models/bookModel"); | ||
const APIFeatures = require("../util/apiFeatures"); | ||
const catchAsync = require("../util/catchAsync"); | ||
const AppError = require("../util/appError"); | ||
|
||
exports.getAllBooks = catchAsync(async (req, res, next) => { | ||
|
||
const features = new APIFeatures(BookModel.find(), req.query) | ||
.filter() | ||
.sort() | ||
.limitFields() | ||
.paginate(); | ||
|
||
const books = await features.query; | ||
|
||
res.status(200).json({ | ||
status: "Success", | ||
results: books.length, | ||
books, | ||
}); | ||
}); | ||
|
||
exports.getBook = catchAsync(async (req, res, next) => { | ||
const { bookID } = req.params; | ||
if (!bookID) { | ||
return next(new AppError("Request is not providing the book ID!", 400)); | ||
} | ||
const book = await BookModel.findById(bookID); | ||
if (!book) { | ||
return next(new AppError("No book found with this ID!", 404)); | ||
} | ||
|
||
res.status(200).json({ | ||
status: "Success", | ||
book, | ||
}); | ||
}); | ||
|
||
exports.addBook = catchAsync(async (req, res, next) => { | ||
let coverName = req.file ? req.file.filename : "default.png"; | ||
|
||
const newBook = await BookModel.create({ | ||
bookISBN: req.body.bookISBN, | ||
title: req.body.title, | ||
edition: req.body.edition, | ||
genre: req.body.genre, | ||
litreraryAwards: req.body.litreraryAwards, | ||
reviews: req.body.reviews, | ||
summary: req.body.summary, | ||
cover: coverName, | ||
status: req.body.status, | ||
price: req.body.price, | ||
publishedYear: req.body.publishedYear, | ||
hasE_Book: req.body.hasE_Book, | ||
trivia: req.body.trivia, | ||
author: req.body.author, | ||
publisher: req.body.publisher, | ||
}); | ||
|
||
res.status(200).json({ | ||
status: "Success", | ||
newBook, | ||
}); | ||
}); | ||
|
||
exports.updateStatus = catchAsync(async (req, res, next) => { | ||
const { bookID } = req.params; | ||
if (!bookID) { | ||
return next(new AppError("Request is not providing the book ID!", 400)); | ||
} | ||
const book = await BookModel.findOneAndUpdate(bookID, { | ||
status: sellingStatus.AVAILABLE, | ||
}); | ||
|
||
if (!book) { | ||
return next(new AppError("No book found!", 404)); | ||
} | ||
|
||
res.status(200).json({ | ||
status: "Success", | ||
book, | ||
}); | ||
}); | ||
|
||
exports.deleteBook = catchAsync(async (req, res, next) => { | ||
const { bookID } = req.params; | ||
if (!bookID) { | ||
return next(new AppError("Request is not providing the book ID!", 400)); | ||
} | ||
const book = await BookModel.findByIdAndDelete(bookID); | ||
|
||
if (!book) { | ||
return next(new AppError("No book found!", 404)); | ||
} | ||
|
||
res.status(200).json({ | ||
status: "Success", | ||
book, | ||
}); | ||
}); |
Oops, something went wrong.