-
Notifications
You must be signed in to change notification settings - Fork 26
Shahab-homework #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Shahab-homework #23
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| const jwt = require('jsonwebtoken'); | ||
|
|
||
| module.exports = (req, res, next) => { | ||
| try { | ||
| const token = req.headers.authorization.split(" ")[1]; | ||
| const decoded = jwt.verify(token, process.env.JWT_KEY); | ||
| req.userData = decoded; | ||
| next(); | ||
| } catch (error) { | ||
| return res.status(401).json({ | ||
| message: 'Auth failed' | ||
| }); | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| const mongoose = require("mongoose"); | ||
|
|
||
| const userSchema = mongoose.Schema({ | ||
| username: { | ||
| type: String, | ||
| required: true | ||
| }, | ||
| password: { | ||
| type: String, | ||
| required: true | ||
| }, | ||
| admin: { | ||
| type: Boolean, | ||
| default: false | ||
| } | ||
| }); | ||
| module.exports = mongoose.model("User", userSchema); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,78 +1,93 @@ | ||
| const router = require('express').Router() | ||
| const Book = require('../models/book') | ||
| const router = require("express").Router(); | ||
| const Book = require("../models/book"); | ||
| const checkAuth = require("../middleware/check-auth"); | ||
|
|
||
| router.get('/', async (req, res, next) => { | ||
| const status = 200 | ||
| const response = await Book.find().select('-__v') | ||
|
|
||
| res.json({ status, response }) | ||
| }) | ||
| router.get("/", async (req, res, next) => { | ||
| const status = 200; | ||
| const response = await Book.find().select("-__v"); | ||
|
|
||
| router.get('/:id', async (req, res, next) => { | ||
| const { id } = req.params | ||
| const status = 200 | ||
| res.json({ status, response }); | ||
| }); | ||
|
|
||
| router.get("/:id", async (req, res, next) => { | ||
| const { id } = req.params; | ||
| const status = 200; | ||
| try { | ||
| const response = await Book.findById(id).select('-__v') | ||
| if (!response) throw new Error(`Invalid Book _id: ${id}`) | ||
| res.json({ status, response }) | ||
| const response = await Book.findById(id).select("-__v"); | ||
| if (!response) throw new Error(`Invalid Book _id: ${id}`); | ||
|
|
||
| res.json({ status, response }); | ||
| } catch (e) { | ||
| console.error(e) | ||
| const error = new Error(`Cannot find book with id ${id}.`) | ||
| error.status = 404 | ||
| next(error) | ||
| console.error(e); | ||
| const error = new Error(`Cannot find book with id ${id}.`); | ||
| error.status = 404; | ||
| next(error); | ||
| } | ||
| }) | ||
| }); | ||
|
|
||
| // You should only be able to create a book if the user is an admin | ||
| router.post('/', async (req, res, next) => { | ||
| const status = 200 | ||
| try { | ||
| const book = await Book.create(req.body) | ||
| if (!book) throw new Error(`Request body failed: ${JSON.stringify(req.body)}`) | ||
|
|
||
| const response = await Book.findById(book._id).select('-__v') | ||
| res.json({ status, response }) | ||
| } catch (e) { | ||
| console.error(e) | ||
| const message = 'Failure to create. Please check request body and try again.' | ||
| const error = new Error(message) | ||
| error.status = 400 | ||
| next(error) | ||
|
|
||
| router.post("/", async (req, res, next) => { | ||
| const token = req.headers.authorization.split("Bearer ")[1]; | ||
| const payload = verify(token, SECRET_KEY); | ||
| const adminUser = await User.findOne({ _id: payload.id }); | ||
| const status = 200; | ||
| if (!adminUser.admin) { | ||
| return res.status(401).json({ | ||
| message: "Not an admin user" | ||
| }); | ||
| } else { | ||
| try { | ||
| const book = await Book.create(req.body); | ||
| if (!book) | ||
| throw new Error(`Request body failed: ${JSON.stringify(req.body)}`); | ||
|
|
||
| const response = await Book.findById(book._id).select("-__v"); | ||
| res.json({ status, response }); | ||
| } catch (e) { | ||
| console.error(e); | ||
| const message = | ||
| "Failure to create. Please check request body and try again."; | ||
| const error = new Error(message); | ||
| error.status = 400; | ||
| next(error); | ||
| } | ||
| } | ||
| }) | ||
| }); | ||
|
|
||
| // You should only be able to reserve a book if a user is logged in | ||
| router.patch('/:id/reserve', async (req, res, next) => { | ||
| const { id } = req.params | ||
| // checkAuth does chek the logged in member | ||
| router.patch("/:id/reserve", checkAuth, async (req, res, next) => { | ||
| const { id } = req.params; | ||
| try { | ||
| const book = await Book.findById(id) | ||
| const book = await Book.findById(id); | ||
| if (!book) { | ||
| const error = new Error(`Invalid Book _id: ${id}`) | ||
| error.message = 404 | ||
| return next(error) | ||
| const error = new Error(`Invalid Book _id: ${id}`); | ||
| error.message = 404; | ||
| return next(error); | ||
| } | ||
|
|
||
| book.reserved.status = true | ||
| book.reserved.status = true; | ||
| // Set the reserved memberId to the current user | ||
| await book.save() | ||
|
|
||
| const response = await Book.findById(book._id).select('-__v') | ||
| const status = 200 | ||
| res.json({ status, response }) | ||
| book.reserved.memberId = req.userData; | ||
| await book.save(); | ||
|
|
||
| const response = await Book.findById(book._id).select("-__v"); | ||
| const status = 200; | ||
| res.json({ status, response }); | ||
| } catch (e) { | ||
| console.error(e) | ||
| console.error(e); | ||
| } | ||
| }) | ||
| }); | ||
|
|
||
| // You should only be able to return a book if the user is logged in | ||
| // and that user is the one who reserved the book | ||
| router.patch('/:id/return', async (req, res, next) => { | ||
| const status = 200 | ||
| const message = 'You must implement this route!' | ||
| console.log(message) | ||
| res.status(status).json({ status, message }) | ||
| }) | ||
| router.patch("/:id/return", checkAuth, async (req, res, next) => { | ||
| const status = 200; | ||
| const message = "You must implement this route!"; | ||
|
|
||
| console.log(message); | ||
| res.status(status).json({ status, message }); | ||
| }); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This route yet to be implemented. |
||
|
|
||
| module.exports = router | ||
| module.exports = router; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| const express = require("express"); | ||
| const router = express.Router(); | ||
| const mongoose = require("mongoose"); | ||
| const bcrypt = require("bcrypt"); | ||
| const jwt = require("jsonwebtoken"); | ||
| const checkAuth = require("../middleware/check-auth"); | ||
| const User = require("../models/user"); | ||
|
|
||
| router.post("/signup", (req, res, next) => { | ||
| if (req.body.username) { | ||
| User.find({ username: req.body.username }) | ||
| .exec() | ||
| .then(user => { | ||
| if (user.length >= 1) { | ||
| return res.status(409).json({ | ||
| message: "Username is already taken" | ||
| }); | ||
| } else { | ||
| if (req.body.password) { | ||
| if (req.body.password.length >= 8) { | ||
| bcrypt.hash(req.body.password, 10, (err, hash) => { | ||
| if (err) { | ||
| return res.status(500).json({ | ||
| error: err | ||
| }); | ||
| } else { | ||
| const user = new User({ | ||
| _id: new mongoose.Types.ObjectId(), | ||
| username: req.body.username, | ||
| password: hash | ||
| }); | ||
| user | ||
| .save() | ||
| .then(result => { | ||
| console.log(result); | ||
| res.status(201).json({ | ||
| message: "User created" | ||
| }); | ||
| }) | ||
| .catch(err => { | ||
| console.log(err); | ||
| res.status(500).json({ | ||
| error: err | ||
| }); | ||
| }); | ||
| } | ||
| }); | ||
| } else { | ||
| return res.status(409).json({ | ||
| message: "Password is less than 8 characters" | ||
| }); | ||
| } | ||
| } else { | ||
| return res.status(409).json({ | ||
| message: "Password is not provided" | ||
| }); | ||
| } | ||
| } | ||
| }); | ||
| } else { | ||
| return res.status(409).json({ | ||
| message: "Username is not provided" | ||
| }); | ||
| } | ||
| /// | ||
| }); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks good but this function is quite long! |
||
| /********************************************************* */ | ||
| router.post("/login", (req, res, next) => { | ||
| User.find({ username: req.body.username }) | ||
| .exec() | ||
| .then(user => { | ||
| if (user.length < 1) { | ||
| return res.status(401).json({ | ||
| message: "Username is not found" | ||
| }); | ||
| } | ||
| bcrypt.compare(req.body.password, user[0].password, (err, result) => { | ||
| if (err) { | ||
| return res.status(401).json({ | ||
| message: "Username and password do not match" | ||
| }); | ||
| } | ||
| if (result) { | ||
| const token = jwt.sign( | ||
| { | ||
| username: user[0].username, | ||
| userId: user[0]._id | ||
| }, | ||
| process.env.JWT_KEY, | ||
| { | ||
| expiresIn: "1h" | ||
| } | ||
| ); | ||
| return res.status(200).json({ | ||
| message: "Auth successful", | ||
| token: token | ||
| }); | ||
| } | ||
| res.status(401).json({ | ||
| message: "somthing went wrong" | ||
| }); | ||
| }); | ||
| }) | ||
| .catch(err => { | ||
| console.log(err); | ||
| res.status(500).json({ | ||
| error: err | ||
| }); | ||
| }); | ||
| }); | ||
| /*************************************************** */ | ||
| router.patch("/users/:id/permissions", checkAuth, async (req, res, next) => { | ||
| User.findById(req.params.id) | ||
| .exec() | ||
| .then(order => { | ||
| if (order) { | ||
| if (!order.admin) { | ||
| return res.status(401).json({ | ||
| message: "The JWT token is for a user who is not an admin" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is just checking whether or not the User you just found is an admin, not that the JWT Token is for an admin. |
||
| }); | ||
| } | ||
| res.status(204).json({ | ||
| message: "User has been updated" | ||
| }); | ||
| } else { | ||
| res.status(404).json({ | ||
| message: "User cannot be found" | ||
| }); | ||
| } | ||
| }) | ||
| .catch(err => { | ||
| res.status(500).json({ | ||
| error: err | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| module.exports = router; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,39 @@ | ||
| const { MONGO_DB_CONNECTION, NODE_ENV, PORT } = process.env | ||
| const express = require('express') | ||
| const mongoose = require('mongoose') | ||
| const app = express() | ||
| const { MONGO_DB_CONNECTION, NODE_ENV, PORT } = process.env; | ||
| const express = require("express"); | ||
| const mongoose = require("mongoose"); | ||
| const app = express(); | ||
|
|
||
| // Database Connection | ||
| if (MONGO_DB_CONNECTION) { | ||
| mongoose.connect(MONGO_DB_CONNECTION, { useNewUrlParser: true }) | ||
| console.log('Connected to database...') | ||
| mongoose.connect(MONGO_DB_CONNECTION, { useNewUrlParser: true }); | ||
| console.log("Connected to database..."); | ||
| } else { | ||
| console.log('Could not connect to database!') | ||
| console.log("Could not connect to database!"); | ||
| } | ||
|
|
||
| // Application-level Middleware | ||
| if (NODE_ENV === 'development') app.use(require('morgan')('dev')) | ||
| app.use(require('body-parser').json()) | ||
| if (NODE_ENV === "development") app.use(require("morgan")("dev")); | ||
| app.use(require("body-parser").json()); | ||
|
|
||
| // Routes | ||
| app.use('/api/books', require('./api/routes/books')) | ||
| app.use("/api/books", require("./api/routes/books")); | ||
|
|
||
| app.use("/api", require("./api/routes/user")); | ||
|
|
||
| // Not Found Handler | ||
| app.use((req, res, next) => { | ||
| const error = new Error(`Could not ${req.method} ${req.path}`) | ||
| error.status = 404 | ||
| next(error) | ||
| }) | ||
| const error = new Error(`Could not ${req.method} ${req.path}`); | ||
| error.status = 404; | ||
| next(error); | ||
| }); | ||
|
|
||
| // Error Handler | ||
| app.use((err, req, res, next) => { | ||
| if (NODE_ENV === 'development') console.error(err) | ||
| const { message, status } = err | ||
| res.status(status).json({ status, message }) | ||
| }) | ||
| if (NODE_ENV === "development") console.error(err); | ||
| const { message, status } = err; | ||
| res.status(status).json({ status, message }); | ||
| }); | ||
|
|
||
| // Open Connection | ||
| const listener = () => console.log(`Listening on Port ${PORT}!`) | ||
| app.listen(PORT, listener) | ||
| const listener = () => console.log(`Listening on Port ${PORT}!`); | ||
| app.listen(PORT, listener); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wont' this assign the
memberIdto be the entire object that isuserData?