express-blog-api/controllers/post.js
ak e69fe69d90 revised to use httpOnly cookie to store jwt
comments can no longer be updated or deleted - out of scope
users can now be created, updated and deleted
2023-09-27 16:50:58 -07:00

147 lines
3.8 KiB
JavaScript

const { default: mongoose } = require("mongoose");
const asyncHandler = require("express-async-handler");
const { body, validationResult } = require("express-validator");
const Post = require("../models/post.js");
const Comment = require("../models/comment.js");
// returns json object with ALL posts and comments
exports.index = asyncHandler(async (req, res, next) => {
const dbPosts = await Post.find().lean().exec();
const posts = [];
for (let i = 0; i < dbPosts.length; i++) {
const comments = await Comment.find({ post: dbPosts[i]._id });
const post = {
title: dbPosts[i].title,
date: dbPosts[i].date,
text: dbPosts[i].text,
author: dbPosts[i].author,
published: dbPosts[i].published,
_id: dbPosts[i]._id,
comments: comments,
};
posts.push(post);
}
return res.status(200).json({ posts });
});
// makes new post - C
exports.post = [
// Validate and sanitize title
body("title", "Please enter blog post title!")
.isLength({ min: 1 })
.trim()
.escape(),
// Validate and sanitize text
body("text", "Please enter blog post text!")
.isLength({ min: 1 })
.trim()
.escape(),
asyncHandler(async (req, res, next) => {
// begin by authorizing token
const token = req.cookies.JWT_TOKEN;
if (!token) {
return res.status(403).json({
message: "Not authorized!",
});
}
// then return any validation errors
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
message: "Comment produced validation errors!",
errors: errors.array(),
});
}
// else data is valid, make post object
const post = new Post({
title: req.body.title,
date: new Date(),
text: req.body.text,
author: req.user.username,
_id: new mongoose.Types.ObjectId(),
});
// save to DB
await post.save();
return res.status(200).json({
message: "Post created!",
});
}),
];
// returns post in json format - R
exports.get = asyncHandler(async (req, res, next) => {
const post = await Post.findOne({ _id: req.params.postID }).lean().exec();
return res.status(200).json({ post });
});
// updates post - U
exports.put = [
// Validate and sanitize title
body("title", "Please enter blog post title!")
.isLength({ min: 1 })
.trim()
.escape(),
// Validate and sanitize text
body("text", "Please enter blog post text!")
.isLength({ min: 1 })
.trim()
.escape(),
// Process request after sanitization and validation
asyncHandler(async (req, res, next) => {
// begin by authorizing token
const token = req.cookies.JWT_TOKEN;
if (!token) {
return res.status(403).json({
message: "Not authorized!",
});
}
// then return any validation errors
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
message: "Comment produced validation errors!",
errors: errors.array(),
});
}
// else data is valid, update post object
const dbPost = await Post.findOne({ _id: req.params.postID }).lean().exec();
const post = new Post({
title: req.body.title,
date: new Date(),
text: req.body.text,
author: dbPost.author,
published: dbPost.published,
_id: dbPost._id,
});
// save to DB
await Post.findByIdAndUpdate(dbPost._id, post, {});
return res.status(200).json({
message: "Post updated!",
});
}),
];
// deletes a post - D
exports.delete = asyncHandler(async (req, res, next) => {
const token = req.cookies.JWT_TOKEN;
if (!token) {
return res.status(403).json({
message: "Not authorized!",
});
}
await Post.findByIdAndDelete({ _id: req.params.postID }).exec();
return res.status(200).json({ message: "Post deleted!" });
});