To Do with Auth API Example
Youtube Video This video is not an official GA Curriculum Video
Gitignore
node_modules/
.envENV
MONGO_URI=mongodb+srv://user:pass@cluster0.mauz5.mongodb.net/tododonna?retryWrites=true&w=majority
SECRET=be1c8e202b128582e2a76f88ca1c886eebb3c86ba793d7936e5978e9d9b0ae8cModels
Todo
const { model, Schema } = require('mongoose')
const todoSchema = new Schema ({
title: { type: String, required: true },
completed: { type: Boolean, required: true },
user: { type: Schema.Types.ObjectId, required: true, ref: 'User' }
}, {
timestamps: true
})
const Todo = model('Todo', todoSchema)
module.exports = TodoUser
require('dotenv').config()
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const userSchema = new mongoose.Schema({
name: {type: String, required: true },
email: {type: String, required: true, unique: true},
password: {type: String, required: true},
todos: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Todo'}]
}, {
timestamps: true
})
userSchema.pre('save', async function(next){
this.isModified('password')?
this.password = await bcrypt.hash(this.password, 8):
null;
next()
})
userSchema.methods.generateAuthToken = async function(){
const token = jwt.sign({ _id: this._id }, process.env.SECRET)
return token
}
const User = mongoose.model('User', userSchema)
module.exports = UserControllers
Todo
const Todo = require('../models/todo')
const User = require('../models/user')
exports.create = async function (req, res){
try {
req.body.user = req.user._id
const todo = await Todo.create(req.body)
req.user.todos?
req.user.todos.addToSet({ _id: todo._id }):
req.user.todos = [{_id: todo._id }]
await req.user.save()
res.json(todo)
} catch (error) {
res.status(400).json({ message: error.message })
}
}
exports.show = async function (req, res){
try{
const todo = await Todo.findOne({ _id: req.params.id })
res.json(todo)
} catch(error){
res.status(400).json({ message: error.message })
}
}
exports.indexComplete = async function (req, res){
try{
const todos = await Todo.find({ completed: true, user: req.user._id })
res.json(todos)
} catch(error){
res.status(400).json({ message: error.message })
}
}
exports.indexNotComplete = async function (req, res){
try{
const todos = await Todo.find({ completed: false, user: req.user._id })
res.json(todos)
} catch(error){
res.status(400).json({ message: error.message })
}
}
exports.update = async function(req, res){
try{
const todo = await Todo.findOneAndUpdate({ _id: req.params.id }, req.body, { new: true })
res.json(todo)
} catch(error){
res.status(400).json({ message: error.message })
}
}
exports.delete = async function(req, res){
try{
const todo = await Todo.findOneAndDelete({ _id: req.params.id })
res.sendStatus(204)
} catch(error){
res.status(400).json({ message: error.message })
}
}User
require('dotenv').config()
const User = require('../models/user')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
exports.auth = async (req, res, next) => {
try{
const token = req.header('Authorization').replace('Bearer ', '')
const data = jwt.verify(token, process.env.SECRET)
const user = await User.findOne({ _id: data._id })
if(!user){
throw new Error('bad credentials')
}
req.user = user
next()
} catch(error){
res.status(401).json({ message: error.message })
}
}
exports.createUser = async (req, res) => {
try {
const user = new User(req.body)
await user.save()
const token = await user.generateAuthToken()
res.json({ user, token })
} catch (error) {
res.status(400).json({ message: error.message })
}
}
exports.loginUser = async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email })
if(!user || !await bcrypt.compare(req.body.password, user.password)){
throw new Error('Invalid Login Credentials')
} else {
const token = await user.generateAuthToken()
res.json({ user, token })
}
} catch (error) {
res.status(400).json({ message: error.message })
}
}
exports.updateUser = async (req, res) => {
try {
const updates = Object.keys(req.body)
updates.forEach(update => req.user[update] = req.body[update])
await req.user.save()
res.json(user)
} catch (error) {
res.status(400).json({ message: error.message })
}
}
exports.deleteUser = async (req, res) => {
try {
await req.user.deleteOne()
res.sendStatus(204)
} catch (error) {
res.status(400).json({ message: error.message })
}
}Routes
Todo
const express = require('express')
const router = express.Router()
const todoCtrl = require('../controllers/todos')
const userController = require('../controllers/users')
// Index /todos
router.get('/', userController.auth, todoCtrl.indexNotComplete)
// Index /todos/completed
router.get('/completed', userController.auth, todoCtrl.indexComplete)
// Delete /todos/:id
router.delete('/:id', userController.auth, todoCtrl.delete)
// Update /todos/:id
router.put('/:id', userController.auth, todoCtrl.update)
// Create /todos
router.post('/', userController.auth, todoCtrl.create)
// Show /todos/:id
router.get('/:id', userController.auth, todoCtrl.show)
module.exports = router User
const express = require('express')
const router = express.Router()
const userController = require('../controllers/users')
router.post('/', userController.createUser)
router.post('/login', userController.loginUser)
router.put('/:id',userController.auth, userController.updateUser)
router.delete('/:id', userController.auth, userController.deleteUser)
module.exports = routerApp
const express = require('express')
const morgan = require('morgan')
const userRoutes = require('./routes/users')
const todoRoutes = require('./routes/todos')
const app = express()
app.use(express.json())
app.use(morgan('combined'))
app.use('/users', userRoutes)
app.use('/todos', todoRoutes)
module.exports = appServer
require('dotenv').config()
const app = require('./app')
const mongoose = require('mongoose')
const PORT = process.env.PORT || 3000
mongoose.connect(process.env.MONGO_URI)
mongoose.connection.once('open', () => console.log('Mongo is showing love'))
app.listen(PORT, () => {
console.log(`We in the building ${PORT}`)
})