From cb092b7f9111e7ac2386d083ef90551d5e30fc6e Mon Sep 17 00:00:00 2001 From: sundowndev Date: Thu, 15 Nov 2018 19:28:33 +0100 Subject: [PATCH] Note routes --- app/routes/note/create.js | 13 +++++----- app/routes/note/delete.js | 23 ++++++++++++------ app/routes/note/index.js | 51 ++++++++++++++++++++++++++++----------- app/routes/note/single.js | 19 +++++++-------- app/routes/note/update.js | 35 ++++++++++++--------------- 5 files changed, 83 insertions(+), 58 deletions(-) diff --git a/app/routes/note/create.js b/app/routes/note/create.js index a0b6c2a..c7b331e 100644 --- a/app/routes/note/create.js +++ b/app/routes/note/create.js @@ -1,17 +1,18 @@ const mongoose = require('mongoose'); +const jwt = require('jsonwebtoken'); -// TODO: verify auth - -module.exports = (req, res) => { +module.exports = (req, res, next) => { const NoteModel = mongoose.model('Note'); - const Note = new NoteModel({ title: req.body.title, text: req.body.text }); + const { user } = jwt.decode(req.headers.authorization); + + const Note = new NoteModel({ title: req.body.title, text: req.body.text, user: user.id }); Note.save((err) => { if (err) { - return res.status(400).json({ success: false, msg: 'Title and text must not be blank.' }); + return next({ status: 400, error: [err] }); } - return res.status(200).json(Note); + return res.status(201).json(Note); }); }; diff --git a/app/routes/note/delete.js b/app/routes/note/delete.js index 73afb4f..3e6dedf 100644 --- a/app/routes/note/delete.js +++ b/app/routes/note/delete.js @@ -1,19 +1,26 @@ const mongoose = require('mongoose'); +const jwt = require('jsonwebtoken'); -// TODO: verify auth -// TODO: verify owner - -module.exports = (req, res) => { +module.exports = (req, res, next) => { const NoteModel = mongoose.model('Note'); - NoteModel.findOneAndDelete({ _id: req.params.id }, (err, note) => { - if (err) return res.status(500).send(err); - if (!note) return res.status(404).json({ message: 'Note does not exists.' }); + const { user } = jwt.decode(req.headers.authorization); + + NoteModel.findOne({ _id: req.params.id }, (err, note) => { + if (err) return next({ status: 500, error: [err] }); + if (!note) return next({ status: 404, message: 'Note does not exists.' }); + + if (note.user.toString() !== user.id) { + return next({ status: 403, message: 'Access forbidden.' }); + } + + note.delete(); const response = { + success: true, message: 'Note successfully deleted', }; - return res.status(200).send(response); + return res.status(204).send(response); }); }; diff --git a/app/routes/note/index.js b/app/routes/note/index.js index b857d60..d40119c 100644 --- a/app/routes/note/index.js +++ b/app/routes/note/index.js @@ -5,6 +5,10 @@ const create = require('./create'); const update = require('./update'); const remove = require('./delete'); +const CreateValidation = require.main.require('./app/validation/note/create'); +const UpdateValidation = require.main.require('./app/validation/note/update'); +const Authentication = require.main.require('./app/validation/auth'); + /** * @api {get} /note/:id Get note * @apiName GetNotes @@ -15,25 +19,21 @@ const remove = require('./delete'); * @apiSuccess {string} title Title of the note. * @apiSuccess {string} text Text of the note. */ -note.get('/:id', single); +note.get('/:id', Authentication, single); /** * @api {post} /note Create note * @apiName CreateNote * @apiGroup Note + * @apiHeaderExample {json} Header-Example: + * { + * "Authorization": "" + * } * - * @apiSuccess {Object} Object Created note. + * @apiSuccess {string} title Title of the note. + * @apiSuccess {string} text Text of the note. */ -note.post('/', create); - -/** - * @api {delete} /note/:id Delete note - * @apiName DeleteNote - * @apiGroup Note - * - * @apiParam {String} id Note unique ID. - */ -note.delete('/:id', remove); +note.post('/', Authentication, CreateValidation, create); /** * @api {put} /note/:id Update note @@ -42,8 +42,31 @@ note.delete('/:id', remove); * * @apiParam {String} id Note unique ID. * - * @apiSuccess {Object} Object Updated note. + * @apiSuccess {string} title Title of the note. + * @apiSuccess {string} text Text of the note. */ -note.put('/:id', update); +note.put('/:id', Authentication, UpdateValidation, update); + +/** + * @api {delete} /note/:id Delete note + * @apiName DeleteNote + * @apiGroup Note + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * { + * "success": true, + * "message": "Note successfully deleted." + * } + * @apiErrorExample {json} Error-Response: + * HTTP/1.1 403 Not Found + * { + * "success": false, + * "message": "Access forbidden.", + * "errors": [] + * } + * + * @apiParam {String} id Note unique ID. + */ +note.delete('/:id', Authentication, remove); module.exports = note; diff --git a/app/routes/note/single.js b/app/routes/note/single.js index 32701c1..71ca43c 100644 --- a/app/routes/note/single.js +++ b/app/routes/note/single.js @@ -1,21 +1,20 @@ const mongoose = require('mongoose'); +const jwt = require('jsonwebtoken'); -// TODO: verify owner - -module.exports = (req, res) => { +module.exports = (req, res, next) => { const NoteModel = mongoose.model('Note'); + const { user } = jwt.decode(req.headers.authorization); + NoteModel.findOne({ _id: req.params.id }) .lean() .exec() - .then((result) => { - if (result === null) { - res.status(404).json({ success: false, msg: 'Note does not exists.' }); + .then((note) => { + if (note.user.toString() !== user.id) { + return next({ status: 403, message: 'Access forbidden.' }); } - res.status(200).json(result); + return res.status(200).json(note); }) - .catch(() => { - res.status(404).json({ success: false, msg: 'Note does not exists.' }); - }); + .catch(() => next({ status: 404, message: 'Note does not exists.' })); }; diff --git a/app/routes/note/update.js b/app/routes/note/update.js index fa7f85d..4a75c56 100644 --- a/app/routes/note/update.js +++ b/app/routes/note/update.js @@ -1,28 +1,23 @@ const mongoose = require('mongoose'); +const jwt = require('jsonwebtoken'); -// TODO: verify auth -// TODO: verify owner - -module.exports = (req, res) => { +module.exports = (req, res, next) => { const NoteModel = mongoose.model('Note'); - NoteModel.findOneAndUpdate( - // the id of the item to find - { _id: req.params.id }, + const { user } = jwt.decode(req.headers.authorization); - // the change to be made. Mongoose will smartly combine your existing - // document with this change, which allows for partial updates too - req.body, + NoteModel.findOne({ _id: req.params.id }, (err, note) => { + if (err) return next({ status: 500, error: [err] }); + if (!note) return next({ status: 404, message: 'Note does not exists.' }); - // an option that asks mongoose to return the updated version - // of the document instead of the pre-updated one. - { new: true }, + if (note.user.toString() !== user.id) { + return next({ status: 403, message: 'Access forbidden.' }); + } - // the callback function - (err, note) => { - // Handle any possible database errors - if (err) return res.status(500).send(err); - return res.json(note); - }, - ); + note.title = req.body.title || note.title; + note.text = req.body.text || note.text; + note.save(); + + return res.status(200).send(note); + }); };