From 073f8b2e30e64a7a3daaf73f56b4f25e8a1eb305 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 22 May 2024 11:38:36 -0700 Subject: [PATCH] Added verification middleware, protected monitor routes --- Server/controllers/authController.js | 17 +++++++--- Server/controllers/monitorController.js | 1 - Server/index.js | 5 +-- Server/middleware/jwtVerification.js | 1 - Server/middleware/verifyJWT.js | 42 +++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 8 deletions(-) delete mode 100644 Server/middleware/jwtVerification.js create mode 100644 Server/middleware/verifyJWT.js diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js index 2c0c8d755..07306d1cf 100644 --- a/Server/controllers/authController.js +++ b/Server/controllers/authController.js @@ -2,9 +2,18 @@ const express = require("express"); const { registerValidation, loginValidation } = require("../validation/joi"); const logger = require("../utils/logger"); require("dotenv").config(); - var jwt = require("jsonwebtoken"); +/** + * Creates and returns JWT token with an arbitrary payload + * @function + * @param {Object} payload + * @returns {String} + */ +const issueToken = (payload) => { + return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: "1h" }); +}; + /** * @function * @param {express.Request} req @@ -44,11 +53,11 @@ const registerController = async (req, res) => { // TODO: Send an email to user // Will add this later logger.info("New user created!", { service: "auth", userId: newUser._id }); - const token = jwt.sign(newUser, process.env.JWT_SECRET); + const token = issueToken(newUser); return res .status(200) - .json({ success: true, msg: "User created}", data: token }); + .json({ success: true, msg: "User created", data: token }); } catch (error) { logger.error(error.message, { service: "auth" }); return res.status(500).json({ success: false, msg: error.message }); @@ -88,7 +97,7 @@ const loginController = async (req, res) => { delete userWithoutPassword.password; // Happy path, return token - const token = jwt.sign(userWithoutPassword, process.env.JWT_SECRET); + const token = issueToken(userWithoutPassword); return res .status(200) .json({ success: true, msg: "Found user", data: token }); diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index 8b2f72ab1..3a46427c4 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -5,7 +5,6 @@ const { } = require("../validation/joi"); const logger = require("../utils/logger"); -const Monitor = require("../models/Monitor"); /** * Returns all monitors diff --git a/Server/index.js b/Server/index.js index 4d2765cd8..5068c98d8 100644 --- a/Server/index.js +++ b/Server/index.js @@ -6,6 +6,8 @@ const monitorRouter = require("./routes/monitorRoute"); const { connectDbAndRunServer } = require("./configs/db"); require("dotenv").config(); const logger = require("./utils/logger"); +var { verifyJWT } = require("./middleware/verifyJWT"); + // const { sendEmail } = require('./utils/sendEmail') // ************************** @@ -58,8 +60,7 @@ app.use((req, res, next) => { //routes app.use("/api/v1/auth", authRouter); - -app.use("/api/v1/monitors", monitorRouter); +app.use("/api/v1/monitors", verifyJWT, monitorRouter); // Testing email service // app.use('/sendEmail', async (req, res) => { diff --git a/Server/middleware/jwtVerification.js b/Server/middleware/jwtVerification.js deleted file mode 100644 index 0472b98ee..000000000 --- a/Server/middleware/jwtVerification.js +++ /dev/null @@ -1 +0,0 @@ -const verifyJwt = (req, res, next) => {}; diff --git a/Server/middleware/verifyJWT.js b/Server/middleware/verifyJWT.js new file mode 100644 index 000000000..53464c606 --- /dev/null +++ b/Server/middleware/verifyJWT.js @@ -0,0 +1,42 @@ +const jwt = require("jsonwebtoken"); +const logger = require("../utils/logger"); +const SERVICE_NAME = "verifyJWT"; +const TOKEN_PREFIX = "Bearer "; + +/** + * Verifies the JWT token + * @function + * @param {express.Request} req + * @param {express.Response} res + * @param {express.NextFunction} next + * @returns {express.Response} + */ +const verifyJWT = (req, res, next) => { + const token = req.headers["authorization"]; + // Make sure a token is provided + if (!token) { + logger.error("No token provided", { service: SERVICE_NAME }); + return res.status(401).json({ success: false, msg: "No token provided" }); + } + // Make sure it is properly formatted + if (token.startsWith(TOKEN_PREFIX)) { + const parsedToken = token.slice(TOKEN_PREFIX.length, token.length); + // Verify the token's authenticity + jwt.verify(parsedToken, process.env.JWT_SECRET, (err, decoded) => { + if (err) { + logger.error("Invalid token", { service: SERVICE_NAME }); + return res.status(401).json({ success: false, msg: "Invalid token" }); + } + //Add the user to the request object for use in the route + req.user = decoded; + next(); + }); + } else { + logger.error("Invalid token format", { service: SERVICE_NAME }); + return res + .status(400) + .json({ success: false, msg: "Invalid token format" }); + } +}; + +module.exports = { verifyJWT };