Now not only admin but author can also create/edit/delete post. To enable this in server, we have to replaceisAdmin middleware from from routes and replace with new middleware that will check if user is admin or author or both.

With this approach, we can add author features with very little code change in frontend. We just have to create few middlewares and apply them in our server routes.

Middlewares

// server/middlewares/index
export const canCreateRead = async (req, res, next) => {
  try {
    // you get req.user._id from verified jwt token
    const user = await User.findById(req.user._id);
    // console.log("isAdmin ===> ", user);
    switch (user.role) {
      case "Admin":
        next();
        break;
      case "Author":
        next();
        break;
      default:
        return res.status(400).send("Unauthorized");
    }
  } catch (err) {
    console.log(err);
  }
};

export const canUpdateDeletePost = async (req, res, next) => {
  try {
    const { postId } = req.params;
    const post = await Post.findById(postId);

    // you get req.user._id from verified jwt token
    const user = await User.findById(req.user._id);
    // console.log("isAdmin ===> ", user);
    switch (user.role) {
      case "Admin":
        next();
        break;
      case "Author":
        if (post.postedBy.toString() !== req.user._id.toString()) {
          return res.status(400).send("Unauthorized");
        } else {
          next();
        }
        break;
      default:
        return res.status(400).send("Unauthorized");
    }
  } catch (err) {
    console.log(err);
  }
};

export const canDeleteMedia = async (req, res, next) => {
  try {
    const { id } = req.params;
    const media = await Media.findById(id);

    // you get req.user._id from verified jwt token
    const user = await User.findById(req.user._id);
    // console.log("isAdmin ===> ", user);
    switch (user.role) {
      case "Admin":
        next();
        break;
      case "Author":
        if (media.postedBy.toString() !== req.user._id.toString()) {
          return res.status(400).send("Unauthorized");
        } else {
          next();
        }
        break;
      default:
        return res.status(400).send("Unauthorized");
    }
  } catch (err) {
    console.log(err);
  }
};

Routes

Now update routes middlewares

// server/routes/post
const express = require("express");
import formidable from "express-formidable";

const router = express.Router();

// controllers
const {
  uploadImage,
  uploadImageFile,
  createPost,
  posts,
  media,
  removeMedia,
  singlePost,
  removePost,
  editPost,
  postsByAuthor,
} = require("../controllers/post");

import {
  requireSignin,
  isAdmin,
  canCreateRead,
  canUpdateDeletePost,
  canDeleteMedia,
} from "../middlewares";

// APPLY canPost MIDDLEWARE (if role is admin or author)
router.post("/upload-image", requireSignin, isAdmin, uploadImage);
router.post(
  "/upload-image-file",
  formidable(),
  requireSignin,
  canCreateRead,
  uploadImageFile
);
router.post("/create-post", requireSignin, canCreateRead, createPost);
router.get("/posts", posts);
router.get("/media", requireSignin, canCreateRead, media);
router.delete("/media/:id", requireSignin, canDeleteMedia, removeMedia);
router.get("/post/:slug", singlePost);
router.put("/post/:postId", requireSignin, canUpdateDeletePost, editPost);
router.delete("/post/:postId", requireSignin, canUpdateDeletePost, removePost);
// author
router.get("/posts-by-author", requireSignin, postsByAuthor);

module.exports = router;