From bbfb0f9f05f706769a974198d935b369aeed617d Mon Sep 17 00:00:00 2001 From: ak Date: Sat, 30 Sep 2023 22:53:19 -0700 Subject: [PATCH] consolidated routes posts now update authors when user's username is changed --- controllers/login.js | 29 ------------------ controllers/user.js | 72 +++++++++++++++++++++++++++++++++++++++++--- routes/index.js | 9 ++++-- 3 files changed, 73 insertions(+), 37 deletions(-) delete mode 100644 controllers/login.js diff --git a/controllers/login.js b/controllers/login.js deleted file mode 100644 index bd90346..0000000 --- a/controllers/login.js +++ /dev/null @@ -1,29 +0,0 @@ -const asyncHandler = require("express-async-handler"); -const jwt = require("jsonwebtoken"); -const bcrypt = require("bcryptjs"); -const User = require("../models/user.js"); - -let opts = {}; - -exports.post = asyncHandler(async (req, res, next) => { - const { username, password } = req.body; // get fields from body - const user = await User.findOne({ username: username }).lean().exec(); // gets user based on username - if (user) { - const match = await bcrypt.compare(password, user.password); // compare bcrypt hashed passwords - if (match) { - opts.expiresIn = "1d"; - const token = jwt.sign({ username }, process.env.SECRET_KEY, opts); // create token and return below - return res - .cookie("JWT_TOKEN", token, { - httpOnly: true, - sameSite: "none", - secure: true, - }) - .status(200) - .json({ - message: "Authentication complete", // a winrar is you - }); - } - } - return res.status(401).json({ message: "Authentication failed" }); // epic fail -}); diff --git a/controllers/user.js b/controllers/user.js index 98ef22e..2e57db8 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -1,6 +1,8 @@ const asyncHandler = require("express-async-handler"); const bcrypt = require("bcryptjs"); const User = require("../models/user.js"); +const Post = require("../models/post.js"); +const jwt = require("jsonwebtoken"); const { body, validationResult } = require("express-validator"); const { default: mongoose } = require("mongoose"); @@ -90,9 +92,7 @@ exports.put = [ // check for duplicates const { username, password } = req.body; // get fields from body - const exists = await User.findOne({ username: originalUsername }) - .lean() - .exec(); + const exists = await User.findOne({ username: username }).lean().exec(); if (exists) { return res.status(409).json({ message: "Username is taken!", @@ -100,13 +100,40 @@ exports.put = [ } // otherwise update user + const dbUser = await User.findOne({ username: req.params.username }) + .lean() + .exec(); const user = new User({ username: username, password: await bcrypt.hash(password, 10), + _id: dbUser._id, }); - await user.save(); // make and save user + + // find all posts that were under the old user's username and rename them to current user's username + const dbPosts = await Post.find({ author: req.params.username }) + .lean() + .exec(); + if (dbPosts) { + for (let i = 0; i < dbPosts.length; i++) { + const currentPost = dbPosts[i]; + const post = new Post({ + title: currentPost.title, + date: currentPost.date, + text: currentPost.text, + author: currentPost.author, + published: username, + _id: currentPost._id, + }); + // updates posts + await Post.findByIdAndUpdate(currentPost._id, post, {}); + } + } + + // save to DB + await User.findByIdAndUpdate(dbUser._id, user, {}); + return res.status(200).json({ - message: "User created!", + message: "User updated!", }); }), ]; @@ -117,3 +144,38 @@ exports.delete = asyncHandler(async (req, res, next) => { await User.findOneAndDelete({ username: originalUsername }).exec(); return res.status(200).json({ message: "Post deleted!" }); }); + +exports.login = asyncHandler(async (req, res, next) => { + const { username, password } = req.body; // get fields from body + const user = await User.findOne({ username: username }).lean().exec(); // gets user based on username + if (user) { + const match = await bcrypt.compare(password, user.password); // compare bcrypt hashed passwords + let opts = {}; + if (match) { + opts.expiresIn = "1d"; + const token = jwt.sign({ username }, process.env.SECRET_KEY, opts); // create token and return below + return res + .cookie("JWT_TOKEN", token, { + httpOnly: true, + sameSite: "none", + secure: true, + }) + .status(200) + .json({ + message: "Authentication complete", // a winrar is you + }); + } + } + return res.status(401).json({ message: "Authentication failed" }); // epic fail +}); + +exports.logout = (req, res, next) => { + return res + .clearCookie("JWT_TOKEN", { + httpOnly: true, + sameSite: "none", + secure: true, + }) + .status(200) + .json({ message: "Successfully logged out!" }); +}; diff --git a/routes/index.js b/routes/index.js index f801912..f392c7b 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,6 +1,6 @@ const express = require("express"); const router = express.Router(); -const login_controller = require("../controllers/login.js"); +const user_controller = require("../controllers/user.js"); const post_controller = require("../controllers/post.js"); const ping_controller = require("../controllers/ping.js"); const hasToken = require("../middleware/hasToken.js"); @@ -8,8 +8,11 @@ const hasToken = require("../middleware/hasToken.js"); // list all posts and append comments to each post based on id, return as json router.get("/", post_controller.index); -// login page -router.post("/login", login_controller.post); +// login +router.post("/login", user_controller.login); + +// logout +router.get("/logout", user_controller.logout); // authentication checking page - used by frontend router.get("/ping", ping_controller.get);