From a4a61695b0249f2dc919f13124c950114ba4c8f6 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 14 May 2024 11:12:22 -0700 Subject: [PATCH] Updated gitignore to ignore log files, Refactored Authcontroller to use DB interface, Added Try/Catch to validation to catch uncaught error, Added username optional validation to Joi so it expects a username --- Server/.gitignore | 3 +- Server/controllers/authController.js | 57 +++++++++++-------- Server/db/FakeDb.js | 29 ++++++++++ Server/db/MongoDB.js | 22 ++++++++ Server/index.js | 14 ++--- Server/models/user.js | 83 ++++++++++++++-------------- Server/validation/joi.js | 1 + 7 files changed, 137 insertions(+), 72 deletions(-) diff --git a/Server/.gitignore b/Server/.gitignore index 1dcef2d9f..3fdb59050 100644 --- a/Server/.gitignore +++ b/Server/.gitignore @@ -1,2 +1,3 @@ node_modules -.env \ No newline at end of file +.env +*.log \ No newline at end of file diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js index f1a2c6ecd..23d5b8877 100644 --- a/Server/controllers/authController.js +++ b/Server/controllers/authController.js @@ -1,32 +1,43 @@ -const express = require('express') -const UserModel = require('../models/user') -const { authValidation } = require('../validation/joi') +const express = require("express"); +const UserModel = require("../models/user"); +const { authValidation } = require("../validation/joi"); /** * @function - * @param {express.Request} req - * @param {express.Response} res + * @param {express.Request} req + * @param {express.Response} res * @returns {{success: Boolean, msg: String}} */ const registerController = async (req, res) => { - // joi validation - const { error } = await authValidation.validateAsync(req.body); - if (error) return res.status(400).json({ success: false, msg: error.details[0].message }); + // joi validation + try { + await authValidation.validateAsync(req.body); + } catch (error) { + return res + .status(400) + .json({ success: false, msg: error.details[0].message }); + } - // Check if the user exists - const isUser = await UserModel.findOne({ email: req.body.email }); - if (isUser) return res.status(400).json({ success: false, msg: "User already exists!" }) + // Check if the user exists + try { + const isUser = await req.db.getUserByEmail(req, res); + if (isUser) + return res + .status(400) + .json({ success: false, msg: "User already exists!" }); + } catch (error) { + return res.status(500).json({ success: false, msg: error.message }); + } - try { - // Create a new user - const newUser = await UserModel.create({ ...req.body }); + try { + // Create a new user + const newUser = await req.db.insertUser(req, res); + return res.json({ success: true, msg: "User created}", data: newUser }); + // Send an email to user + // Will add this later + } catch (error) { + return res.status(500).json({ success: false, msg: error.message }); + } +}; - // Send an email to user - // Will add this later - } catch (error) { - return res.status(500).json({success:false,msg:'Something went wrong!'}) - } - -} - -module.exports = {registerController} \ No newline at end of file +module.exports = { registerController }; diff --git a/Server/db/FakeDb.js b/Server/db/FakeDb.js index 6dfa89ac9..8cf05cf89 100644 --- a/Server/db/FakeDb.js +++ b/Server/db/FakeDb.js @@ -21,8 +21,10 @@ // ************************** const Monitor = require("../models/Monitor"); +const UserModel = require("../models/user"); const FAKE_MONITOR_DATA = []; +const USERS = []; for (let i = 0; i < 10; i++) { FAKE_MONITOR_DATA.push( @@ -47,6 +49,31 @@ const connect = async () => { } }; +const insertUser = async (req, res) => { + try { + const newUser = new UserModel({ ...req.body }); + USERS.push(newUser); + return newUser; + } catch (error) { + throw error; + } +}; + +const getUserByEmail = async (req, res) => { + const email = req.body.email; + try { + const idx = USERS.findIndex((user) => { + return user.email === email; + }); + if (idx === -1) { + return null; + } + return USERS[idx]; + } catch (error) { + throw new Error(`User with email ${email} not found`); + } +}; + const getAllMonitors = async () => { return FAKE_MONITOR_DATA; }; @@ -75,6 +102,8 @@ const getMonitorsByUserId = async (userId) => { module.exports = { connect, + insertUser, + getUserByEmail, getAllMonitors, getMonitorById, getMonitorsByUserId, diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js index 6ad783877..72f2d1d13 100644 --- a/Server/db/MongoDB.js +++ b/Server/db/MongoDB.js @@ -1,5 +1,6 @@ const Monitor = require("../models/Monitor"); const mongoose = require("mongoose"); +const UserModel = require("../models/user"); const connect = async () => { try { @@ -11,6 +12,25 @@ const connect = async () => { } }; +const insertUser = async (req, res) => { + try { + const newUser = await UserModel.create({ ...req.body }); + return newUser; + } catch (error) { + throw error; + } +}; + +const getUserByEmail = async (req, res) => { + try { + // Returns null if no user is found + const user = await UserModel.findOne({ email: req.body.email }); + return user; + } catch (error) { + throw error; + } +}; + // Gets all monitors const getAllMonitors = async (req, res) => { try { @@ -43,6 +63,8 @@ const getMonitorsByUserId = async (req, res) => { module.exports = { connect, + insertUser, + getUserByEmail, getAllMonitors, getMonitorById, getMonitorsByUserId, diff --git a/Server/index.js b/Server/index.js index 967a9899b..7e68c72f2 100644 --- a/Server/index.js +++ b/Server/index.js @@ -5,7 +5,7 @@ const authRouter = require("./routes/authRoute"); const monitorRouter = require("./routes/monitorRoute"); const { connectDbAndRunServer } = require("./configs/db"); require("dotenv").config(); -const logger = require('./utils/logger'); +const logger = require("./utils/logger"); // const { sendEmail } = require('./utils/sendEmail') // ************************** @@ -23,7 +23,7 @@ const db = require("./db/MongoDB"); /** * NOTES - * Email Service will be added + * Email Service will be added * Logger Service will be added (Winston or similar) */ @@ -60,11 +60,11 @@ app.use("/api/v1/monitors", monitorRouter); //health check app.use("/api/v1/healthy", (req, res) => { - try { - logger.info("Checking Health of the server.") - return res.status(200).json({ message: "Healthy" }); - } catch (error) { - logger.error(error.message) + try { + logger.info("Checking Health of the server."); + return res.status(200).json({ message: "Healthy" }); + } catch (error) { + logger.error(error.message); return res.status(500).json({ message: error.message }); } }); diff --git a/Server/models/user.js b/Server/models/user.js index 27d623179..547192293 100644 --- a/Server/models/user.js +++ b/Server/models/user.js @@ -1,45 +1,46 @@ -const mongoose = require('mongoose') -const bcrypt = require('bcrypt') +const mongoose = require("mongoose"); +const bcrypt = require("bcrypt"); const UserSchema = mongoose.Schema({ - username: { - type: String - }, - email: { - type: String, - required: true - }, - password: { - type: String, - required: true - }, - profilePicUrl: { - type: String - }, - isActive: { - type: Boolean, - default: true - }, - isVerified: { - type: Boolean, - default: false - }, - updated_at: { - type: Date, - default: Date.now - }, - created_at: { - type: Date, - default: Date.now - } -}) + username: { + type: String, + }, + email: { + type: String, + required: true, + unique: true, + }, + password: { + type: String, + required: true, + }, + profilePicUrl: { + type: String, + }, + isActive: { + type: Boolean, + default: true, + }, + isVerified: { + type: Boolean, + default: false, + }, + updated_at: { + type: Date, + default: Date.now, + }, + created_at: { + type: Date, + default: Date.now, + }, +}); -UserSchema.pre('save', async function (next) { - if (!this.isModified('password')) { - next() - } - const salt = bcrypt.genSalt(10); - this.password = await bcrypt.hash(this.password, salt); -}) +UserSchema.pre("save", async function (next) { + if (!this.isModified("password")) { + next(); + } + const salt = await bcrypt.genSalt(10); //genSalt is asynchronous, need to wait + this.password = bcrypt.hash(this.password, salt); +}); -module.exports = mongoose.model('User',UserSchema) \ No newline at end of file +module.exports = mongoose.model("User", UserSchema); diff --git a/Server/validation/joi.js b/Server/validation/joi.js index 2fb59a377..53427527e 100644 --- a/Server/validation/joi.js +++ b/Server/validation/joi.js @@ -2,6 +2,7 @@ const joi = require("joi"); const user = require("../models/user"); const authValidation = joi.object({ + username: joi.string(), email: joi.string().email().required(), password: joi.string().min(8).required(), });