AUTHORIZATION FOR /reviews(POST)

 REVIEWS ARE ASSIGNED WITH AN AUTHOR. ONLY USERS LOGGED IN CAN ADD A REVIEW.

1)A NEW FIELD AUTHOR IS ADDED TO THE SCHEMA OF REVIEWS.

const reviewSchema = new Schema({
  rating: {
    type: Number,
    min: 1,
    max: 5,
  },
  comment: String,

  createdAt: {
    type: Date,
    default: Date.now(),
  },
  author: {
    type: Schema.Types.ObjectId,
    ref: "User",
  },


IN SHOW.EJS

 <% if(currUser){ %>
    <div class="col-8 offset-2 mb-2 mt-3">
      <h4>Leave a Review!</h4>
      <form
        action="/listings/<%=listing._id%>/reviews"
        method="post"
        class="needs-validation"
        novalidate
      >
        <div class="col-8 offset-2 mb-2 mt-3">
          <label for="rating" class="form-label">Rating</label>
          <input
            type="range"
            min="1"
            max="5"
            id="rating"
            name="review[rating]"
            class="form-range"
            required
          />
        </div>
        <div class="col-8 offset-2">
          <label for="comment" class="form-label">Comments</label>
          <textarea
            name="review[comment]"
            id="comment"
            rows="5"
            cols="30"
            class="form-control"
            required
          ></textarea>
          <div class="invalid-feedback">Add a valid Review!</div>
        </div>

        <button class="btn btn-outline-dark offset-2 mb-2 mt-3">submit</button>
      </form>
    </div>
    <% } %>

WHEN A NEW REVIEW IS ADDED , THE USER LOGGED IN BECOMES THE AUTHOR.

router.post(
  "/",
  ValidateReview,
  isLoggedIn,
  wrapAsync(async (req, res) => {
    let { id } = req.params;
    let listing = await Listing.findById(id);
    let newRev = new Review(req.body.review);
    newRev.author = req.user._id;
    console.log(newRev.author);
    console.log(newRev);
    await newRev.save();
    listing.reviews.push(newRev);
    await listing.save();

    console.log("review saved");
    req.flash("success", "New Review Added!");

    res.redirect(`/listings/${id}`);
  })
);


2) HERE , WE WILL DISPLAY THE AUTHOR NAME ALONG WITH THE REVIEW AND THE REVIEW CAN BE DELETED BY ONLY THE AUTHOR HIMSELF.

A MIDDLEWARE IS CREATED.

AUTHOR IS SENT AS AN OBJECT BY POPULATING WITH THE REVIEW.

LISTING.JS

// SHOW ROUTE
router.get(
  "/:id",
  wrapAsync(async (req, res) => {
    let { id } = req.params;
    const listing = await Listing.findById(id)
      .populate({
        path: "reviews",
        populate: { path: "author" },
      })
      .populate("owner");
    if (!listing) {
      req.flash("error", "Listing requested doesn't exist!");
      res.redirect("/listings");
    }
    res.render("listings/show.ejs", { listing });
  })
);


IN SHOW.EJS   <div class="card col-5 ms-3 mb-4">

      <div class="card-body">
        <p class="card-title"><b><%= review.author.username %></b></p>
        <p class="card-text"><%= review.comment %></p>
        <p class="card-text"><%= review.rating %> stars</p>
      </div>

A MIDDLEWARE IS CREATED TO VERIFY THE AUTHENTICATION OF THE AUTHOR.

module.exports.isAuthor = async (req, res, next) => {
  let {id, reviewId } = req.params;
  let review = await Review.findById(reviewId);
  if (!review.author.equals(res.locals.currUser._id)) {
    req.flash("error", "you donot have access to delete!");
    return res.redirect(`/listings/${id}`);
  }
  next();
};



Comments