Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions api/models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const mongoose = require('mongoose')

const schema = new mongoose.Schema({
username: {
type: String,
required: [true, 'username required'],
unique: [true, 'username already exists']
},
password: {
type: String,
required: [true, 'Password required'],
minlength: [8, 'Password must be 8 or more characters']
},
admin: {
type: Boolean,
default: false
},
}, { timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' } })

module.exports = mongoose.model('User', schema)
50 changes: 50 additions & 0 deletions api/routes/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const router = require('express').Router()
const bcrypt = require('bcrypt')
const jsonwebtoken = require('jsonwebtoken')
const User = require('../models/user')

router.post('/signup', async (req, res, next) => {
const status = 201
try {
const {username, password} = req.body
const user = await User.findOne({username})
if (user) throw new Error('User name is already in use')

const saltRounds = 5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll want to make a more secure password and at least use 8 rounds.

const hashedPassword = await bcrypt.hash(password, saltRounds)
const response = await User.create({
username,
password: hashedPassword
})
res.status(status).json({status, response})
} catch (e) {
const error = new Error(e.message)
error.status = 400
next(error)
}
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Watch your indentation.


router.post('/login', async (req, res, next) => {
const status = 201
try {
const {username, password} = req.body
const user = await User.findOne({username})
if (user === null) {
throw new Error("Username - could not be found")
}
const goodLogin = await bcrypt.compare(password, user.password)
if (goodLogin === null) {
throw new Error('Username - Password combination could not be found')
}
const payload = {id: user._id}
const options = {expiresIn: '1 day'}
const token = jsonwebtoken.sign(payload, 'ASECRETPASSCODE', options)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'ASECRETPASSCODE' should be put into your nodemon.json or otherwise excluded from your code. It's insecure/inefficient to do so otherwise.

res.status(status).json({status, token})
} catch (e) {
const error = new Error('Password combination could not be found')
error.status = 400
next(error)
}
})

module.exports = router
18 changes: 16 additions & 2 deletions api/routes/books.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const router = require('express').Router()
const jsonwebtoken = require('jsonwebtoken')
const Book = require('../models/book')
const User = require('../models/user')

router.get('/', async (req, res, next) => {
const status = 200
Expand Down Expand Up @@ -28,12 +30,19 @@ router.get('/:id', async (req, res, next) => {
router.post('/', async (req, res, next) => {
const status = 200
try {
const token = req.headers.authorization.split('Bearer ')[1]
const payload = jsonwebtoken.verify(token, 'ASECRETPASSCODE')
const user = await User.findOne({ _id: payload.id })
if (user.admin === false) {
throw new Error('You must be an admin')
}
else {
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) {
}} catch (e) {
console.error(e)
const message = 'Failure to create. Please check request body and try again.'
const error = new Error(message)
Expand All @@ -46,7 +55,12 @@ router.post('/', async (req, res, next) => {
router.patch('/:id/reserve', async (req, res, next) => {
const { id } = req.params
try {
if (req.headers.authorization === null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't actually check to see whether or not someone is logged in, it only checks to see whether or not someone has sent over a token. If the token is invalid, it will pass with the given code.

throw new Error('You must be logged in')
}
else {
const book = await Book.findById(id)

if (!book) {
const error = new Error(`Invalid Book _id: ${id}`)
error.message = 404
Expand All @@ -60,7 +74,7 @@ router.patch('/:id/reserve', async (req, res, next) => {
const response = await Book.findById(book._id).select('-__v')
const status = 200
res.json({ status, response })
} catch (e) {
}} catch (e) {
console.error(e)
}
})
Expand Down
2 changes: 2 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ app.use(require('body-parser').json())

// Routes
app.use('/api/books', require('./api/routes/books'))
app.use('/api', require('./api/routes/auth'))
app.use('/api', require('./api/routes/auth'))

// Not Found Handler
app.use((req, res, next) => {
Expand Down
24 changes: 24 additions & 0 deletions db/seeds2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const mongoose = require('mongoose')
const User = require('../api/models/user')
const config = require('../nodemon.json')

const reset = async () => {
mongoose.connect(config.env.MONGO_DB_CONNECTION, { useNewUrlParser: true })
await User.deleteMany() // Deletes all records
return await User.create(
{
username: 'userOne',
password: 'passwordOne',
admin: false
},
{
username: 'adminOne',
password: 'passwordOne',
admin: true
})

}
reset().catch(console.error).then((response) => {
console.log(`Seeds successful! ${response.length} records created.`)
return mongoose.disconnect()
})
2 changes: 1 addition & 1 deletion nodemon.sample.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"env": {
"MONGO_DB_CONNECTION": "",
"MONGO_DB_CONNECTION": "mongodb+srv://jt-user1:KeRHniXmgkUBZx4l@cluster0-ya0qa.mongodb.net/test?retryWrites=true&w=majority",
"NODE_ENV": "development",
"PORT": 5000
}
Expand Down
Loading