diff --git a/src/controllers/Post/createPost.js b/src/controllers/Post/createPost.js new file mode 100644 index 00000000..a257d029 --- /dev/null +++ b/src/controllers/Post/createPost.js @@ -0,0 +1,42 @@ + +/** + * @module Create Post Controller + * + * @param {Request} req - HTTP Request from the client + * @param {Response} res - HTTP Response for the client + * + * @description + * This controller will allow the user to create his own post, if all parameters are correct. + * + * @todo + * Nothing for now. + */ + + + + +module.exports.createPost = (req, res) => { + + // check if all the parameters are valid. + + const { postTitle, postContent } = req.body; + + if (!postTitle || !postContent) { + return res.status(400).send('post content or post title cannot be blank.'); + } + + // create a new post record + + Post.create({ + title: postTitle, + content: postContent, + // ownerId: 1, + ownerId: req.user.id, + }) + + + // inform the user with the process status. + + return res.status(200).send('post created'); +} + diff --git a/src/controllers/Post/deletePost.js b/src/controllers/Post/deletePost.js new file mode 100644 index 00000000..208bb5bf --- /dev/null +++ b/src/controllers/Post/deletePost.js @@ -0,0 +1,52 @@ + +/** + * @module Delete Post Controller + * + * @param {Request} req - HTTP Request from the client + * @param {Response} res - HTTP Response for the client + * + * @description + * This controller will allow the user to delete his own post, if all parameters are correct. + * + * @todo + * Nothing for now. + */ + + + + +module.exports.deletePost = async (req, res) => { + + + if (!req.params.postId) { + return res.status(400).send('invalid post id.'); + } + + // find the original post. + + const foundPost = await Post.findOne({ + where: { + id: req.params.postId, + } + }); + + // check that it exists. + + if (!foundPost) { + return res.status(404).send({ msg: 'The post that you are trying to update does not exist.' }); + } + + // check if the owner is the active user. + + if (foundPost.ownerId != req.user.id) { + return res.status(401).send({ msg: 'You are not allowed to change a ressource that you do not own.' }) + } + + foundPost.destroy() + + + // inform the user with the process status. + + return res.status(200).send('post deleted'); +} + diff --git a/src/controllers/Post/getAllPosts.js b/src/controllers/Post/getAllPosts.js new file mode 100644 index 00000000..02b97b56 --- /dev/null +++ b/src/controllers/Post/getAllPosts.js @@ -0,0 +1,34 @@ + +/** + * @module Get All Posts Controller + * + * @param {Request} req - HTTP Request from the client + * @param {Response} res - HTTP Response for the client + * + * @description + * This controller allows to read a all the existing posts, if all parameters are correct. + * + * @todo + * Nothing for now. + */ + + + + +module.exports.getAllPosts = async (req, res) => { + + // fetch all the posts. + + const foundPosts = await Post.findAll({ + attributes: ['title', 'content'], + }) + + if (!foundPosts || !foundPosts.length ) { + return res.status(404).send('No posts for now.'); + } + + // send back to the user the fetched data. + + return res.status(200).json(foundPosts); +} + diff --git a/src/controllers/Post/getPost.js b/src/controllers/Post/getPost.js new file mode 100644 index 00000000..a095b26b --- /dev/null +++ b/src/controllers/Post/getPost.js @@ -0,0 +1,44 @@ + +/** + * @module Get Post Controller + * + * @param {Request} req - HTTP Request from the client + * @param {Response} res - HTTP Response for the client + * + * @description + * This controller allows to read a specific post, if all parameters are correct. + * + * @todo + * Nothing for now. + */ + + + + +module.exports.getPost = async (req, res) => { + + // check if all the parameters are valid. + + if (!req.params.postId) { + return res.status(400).send('post id can not be null.'); + } + + + // fetch the requested post. + + const foundPost = await Post.findOne({ + where: { + id: req.params.postId, + }, + attributes: ['title', 'content'], + }) + + if (!foundPost) { + return res.status(404).send('Post ressource not found.'); + } + + // send back to the user the fetched data. + + return res.status(200).json(foundPost); +} + diff --git a/src/controllers/Post/index.js b/src/controllers/Post/index.js new file mode 100644 index 00000000..8cb9752a --- /dev/null +++ b/src/controllers/Post/index.js @@ -0,0 +1,14 @@ +const { createPost } = require('./createPost'); +const { getPost } = require('./getPost'); +const { getAllPosts } = require('./getAllPosts'); +const { updatePost } = require('./updatePost'); +const { deletePost } = require('./deletePost'); + + +module.exports = { + createPost, + getPost, + getAllPosts, + updatePost, + deletePost, +}; \ No newline at end of file diff --git a/src/controllers/Post/updatePost.js b/src/controllers/Post/updatePost.js new file mode 100644 index 00000000..2ff78958 --- /dev/null +++ b/src/controllers/Post/updatePost.js @@ -0,0 +1,62 @@ + +/** + * @module Update Post Controller + * + * @param {Request} req - HTTP Request from the client + * @param {Response} res - HTTP Response for the client + * + * @description + * This controller will allow the user to update his own post, if all parameters are correct. + * + * @todo + * Nothing for now. + */ + + + + +module.exports.updatePost = async (req, res) => { + + // check if all the parameters are valid. + + const { newPostTitle, newPostContent } = req.body; + + if (!newPostTitle || !newPostContent) { + return res.status(400).send('post content or post title cannot be blank.'); + } + + if (!req.params.postId) { + return res.status(400).send('invalid post id.'); + } + + // find the original post. + + const foundPost = await Post.findOne({ + where: { + id: req.params.postId, + } + }); + + // check that it exists. + + if (!foundPost) { + return res.status(404).send({ msg: 'The post that you are trying to update does not exist.' }); + } + + // check if the owner is the active user. + + if (foundPost.ownerId != req.user.id) { + return res.status(401).send({ msg: 'You are not allowed to change a ressource that you do not own.' }) + } + + foundPost.update({ + title: newPostTitle, + content: newPostContent, + }) + + + // inform the user with the process status. + + return res.status(200).send('post updated'); +} + diff --git a/src/controllers/User/Posts/listAllUserPosts.js b/src/controllers/User/Posts/listAllUserPosts.js new file mode 100644 index 00000000..6c6ed43c --- /dev/null +++ b/src/controllers/User/Posts/listAllUserPosts.js @@ -0,0 +1,44 @@ + +/** + * @module list All User Posts Controller + * + * @param {Request} req - HTTP Request from the client + * @param {Response} res - HTTP Response for the client + * + * @description + * This controller allows to list all the posts related to a specific user, if all parameters are correct. + * + * @todo + * Nothing for now. + */ + + + + +module.exports.listAllUserPosts = async (req, res) => { + + // check if all the parameters are valid. + + if (!req.params.id) { + return res.status(400).send('user id can not be null.'); + } + + + // list the user posts. + + const foundPosts = await Post.findAll({ + where: { + ownerId: req.params.id, + }, + attributes: ['title', 'content'], + }) + + if (!foundPosts) { + return res.status(404).send('This user did not posted yet.'); + } + + // send back to the user the fetched data. + + return res.status(200).json(foundPosts); +} + diff --git a/src/controllers/User/Posts/listOneUserPost.js b/src/controllers/User/Posts/listOneUserPost.js new file mode 100644 index 00000000..2ffe0bb6 --- /dev/null +++ b/src/controllers/User/Posts/listOneUserPost.js @@ -0,0 +1,45 @@ + +/** + * @module List One User Post Controller + * + * @param {Request} req - HTTP Request from the client + * @param {Response} res - HTTP Response for the client + * + * @description + * This controller allows to read a specific post written by a given user, if all parameters are correct. + * + * @todo + * Nothing for now. + */ + + + + +module.exports.listOneUserPost = async (req, res) => { + + + // fetch the requested post. + + const foundPost = await Post.findOne({ + where: { + id: req.params.postId, + }, + attributes: ['title', 'content', 'ownerId'], + }) + + if (!foundPost) { + return res.status(404).send('Post ressource not found.'); + } + + // check if the given user is the owner. + + if (req.params.id != foundPost.ownerId) { + return res.status(403).send('The requested post does not belong to the selected user.'); + } + + + // send back to the user the fetched data. + + return res.status(200).json(foundPost); +} + diff --git a/src/controllers/User/index.js b/src/controllers/User/index.js index 489ca762..6b52563c 100644 --- a/src/controllers/User/index.js +++ b/src/controllers/User/index.js @@ -24,6 +24,12 @@ const { countUsers } = require('./Helpers/countUsers'); const { listUsers } = require('./Helpers/listUsers'); const { queryUser } = require('./Helpers/queryUser'); + +const { listAllUserPosts } = require('./Posts/listAllUserPosts'); +const { listOneUserPost } = require('./Posts/listOneUserPost'); + + + module.exports = { confirmEmail, deleteAccount, @@ -46,4 +52,6 @@ module.exports = { countUsers, listUsers, queryUser, + listAllUserPosts, + listOneUserPost, }; diff --git a/src/index.js b/src/index.js index e372ec09..29b547cf 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ require('dotenv').config(); -require('./models/index'); +require('./models') // Configure Imports const express = require('express'); @@ -9,7 +9,6 @@ const schedule = require('node-schedule'); const { removeUnconfirmedAccounts, emailConfirmationRemainder } = require('./jobs/accountCleanup'); const { eventRemainder } = require("./jobs/eventNotifications"); -require('./models') // Configure Local Variables const app = express(); @@ -44,6 +43,11 @@ app.use('/event', require('./routes/eventRoutes')); app.use("/user", require("./routes/userRoutes")); app.use("/u", require("./routes/uRoutes")); +// Post Endpoints + +app.use('/posts', require('./routes/postRoutes')); + + // Sync the Database (async () => { diff --git a/src/models/Post.js b/src/models/Post.js new file mode 100644 index 00000000..eb514351 --- /dev/null +++ b/src/models/Post.js @@ -0,0 +1,7 @@ +module.exports = (sequelize, DataTypes) => { + return sequelize.define('Post', { + title: DataTypes.STRING, + content: DataTypes.TEXT, + ownerId: DataTypes.INTEGER, + }); +}; diff --git a/src/models/index.js b/src/models/index.js index 782f20cd..00e2ad94 100644 --- a/src/models/index.js +++ b/src/models/index.js @@ -31,11 +31,13 @@ if (env === 'development') { const Article = require('./Article'); const User = require('./User'); const Event = require('./Event'); +const Post = require('./Post'); // Define Models global.Article = Article(sequelize, DataTypes); global.User = User(sequelize, DataTypes); global.Event = Event(sequelize, DataTypes); +global.Post = Post(sequelize,DataTypes); // Setup Relationships @@ -73,4 +75,8 @@ global.User.belongsToMany(global.User, { +// TODO: Relationship for post system. + + + global.sequelize = sequelize; diff --git a/src/routes/postRoutes.js b/src/routes/postRoutes.js new file mode 100644 index 00000000..b6401484 --- /dev/null +++ b/src/routes/postRoutes.js @@ -0,0 +1,15 @@ +const express = require('express'); +const router = express.Router(); +const postControllers = require('../controllers/Post'); + + +router.get('/', postControllers.getAllPosts) +router.get('/:postId', postControllers.getPost); + + + +router.post('/create', postControllers.createPost); +router.post('/:postId/update', postControllers.updatePost); +router.post('/:postId/delete', postControllers.deletePost); + +module.exports = router; \ No newline at end of file diff --git a/src/routes/userRoutes.js b/src/routes/userRoutes.js index d7eb3a03..b1a9cdad 100644 --- a/src/routes/userRoutes.js +++ b/src/routes/userRoutes.js @@ -38,6 +38,11 @@ router.post('/setPassword', verifyLogin, userControllers.setPass); router.post('/delete', verifyLogin, userControllers.deleteAccount); +// user posts endpoints + +router.get('/:id/posts', userControllers.listAllUserPosts); +router.get('/:id/posts/:postId', userControllers.listOneUserPost) + // email verification end point