diff --git a/backend/database.js b/backend/database.js index f8b65ad..e22fb41 100644 --- a/backend/database.js +++ b/backend/database.js @@ -2,6 +2,7 @@ import mysql from "mysql2"; import dotenv from "dotenv"; dotenv.config(); +// Create a MySQL connection pool using environment variables for configuration const pool = mysql .createPool({ host: process.env.DB_HOST, @@ -11,21 +12,26 @@ const pool = mysql }) .promise(); +// Function to authenticate a user by username and password export async function loginUser(username, password) { + // Query the users table for a matching username and password const [result] = await pool.query( "SELECT * FROM users WHERE username = ? AND password = ?", [username, password] ); + // If a user is found, return success and user data if (result.length > 0) { console.log("User found: ", result[0].username, " ", result[0].id); return { success: true, user: result[0] }; } else { + // If no user is found, return failure message console.error(`Invalid username or password!; ${result[0]}`); return { success: false, message: "Invalid username or password" }; } } +// Function to create a new user in the database export async function createUser( username, first_name, @@ -34,19 +40,22 @@ export async function createUser( email ) { try { + // Insert a new user record into the users table const [result] = await pool.query( "INSERT INTO users (username, first_name, last_name, password, email) VALUES (?, ?, ?, ?, ?)", [username, first_name, last_name, password, email] ); console.log("User created successfully!"); - return { success: true }; + return { success: true, message: "User created successfully!" }; } catch (error) { - console.error("Error creating user: ", error); - return { success: false, message: "Error creating user" }; + // Handle errors during user creation + console.log("Error creating user: ", error); + return { success: false, message: "Error creating user!" }; } } +// Function to update an existing user's information export async function updateUser( username, first_name, @@ -55,25 +64,36 @@ export async function updateUser( email ) { try { + // Update user details based on username const [result] = await pool.query( "UPDATE users SET first_name = ?, last_name = ?, password = ?, email = ? WHERE username = ?", [first_name, last_name, password, email, username] ); - return { - success: true, - message: "User updated successfully", - resultOfquery: result, - }; - } catch (error) { - console.error("Error updating user: ", error); - return { - success: false, - message: "Error updating user", - resultOfquery: result, - }; - } + const resultOfquery = result.affectedRows; + + // If a user was updated, return success + if (resultOfquery > 0) { + console.log("User updated successfully!"); + return { + success: true, + message: "User updated successfully!", + resultOfquery: result, + }; + } + + // If no user was updated, return failure + if (resultOfquery === 0) { + console.log("Error updating user!"); + return { + success: false, + message: "Error updating user!", + resultOfquery: null, + }; + } + } catch (err) {} } +// Function to delete a user from the database export async function deleteUser( username, first_name, @@ -82,26 +102,29 @@ export async function deleteUser( email ) { try { + // Delete user based on username and password const [result] = await pool.query( "DELETE FROM users WHERE username = ? AND password = ?", [username, password] ); const resultOfquery = result.affectedRows; + // If a user was deleted, return success if (resultOfquery > 0) { console.log("User deleted successfully!"); return { success: true, - message: "User deleted successfully", + message: "User deleted successfully!", resultOfquery: result, }; } + // If no user was deleted, return failure if (resultOfquery === 0) { - console.log("Error deleting user."); + console.log("Error deleting user!"); return { success: false, - message: "Error deleting user", + message: "Error deleting user!", resultOfquery: null, }; } diff --git a/backend/server.js b/backend/server.js index 27013d0..3f2b8aa 100644 --- a/backend/server.js +++ b/backend/server.js @@ -3,17 +3,22 @@ import express from "express"; const app = express(); const port = 4000; +// Importing database functions for user operations import { loginUser, createUser, updateUser, deleteUser } from "./database.js"; +// Middleware to parse URL-encoded bodies (form submissions) app.use(express.urlencoded({ extended: true })); +// Set EJS as the view engine for rendering templates app.set("view engine", "ejs"); import path from "path"; import { fileURLToPath } from "url"; +// Setup for __dirname and __filename in ES modules const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); +// Start the server and listen on the specified port app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); }); @@ -26,18 +31,21 @@ app.use(express.static("public")); // Main code below -// Route to handle GET requests to the root URL +// Route to handle GET requests to the root URL (login page) app.get("/", (req, res) => { res.render("login.ejs", { error: null, reload: false }); console.log("Frontend user requested frontend login page."); }); +// Variable to keep track of the latest logged-in user let latestUser; // Route to handle user login app.post("/login", (req, res) => { + // Attempt to log in the user with provided credentials loginUser(req.body.username, req.body.password).then((result) => { if (result.success) { + // On successful login, render the dashboard and update latestUser res.status(200).render("dashboard.ejs", { sqlResult: result, newLink: `/dashboard/${result.user.id}`, @@ -46,6 +54,7 @@ app.post("/login", (req, res) => { }); latestUser = result; } else { + // On failure, re-render login page with error message res .status(401) .render("login.ejs", { error: result.message, reload: true }); @@ -53,18 +62,22 @@ app.post("/login", (req, res) => { }); }); +// Route to handle user creation, update, and deletion app.post(["/createUser", "/updateUser", "/deleteUser"], (req, res) => { let action = req.path; let funcName; + // Determine which database function to use based on the route if (action === "/createUser") { funcName = createUser; } else if (action === "/updateUser") { funcName = updateUser; } else if (action === "/deleteUser") { + // Prevent deleting the currently logged-in user if (latestUser && req.body.username !== latestUser.user.username) { funcName = deleteUser; } else { + // Render dashboard with alert if trying to delete logged-in user res.status(400).render("dashboard.ejs", { sqlResult: latestUser, newLink: latestUser ? `/dashboard/${latestUser.id}` : "#", @@ -74,9 +87,11 @@ app.post(["/createUser", "/updateUser", "/deleteUser"], (req, res) => { return; } } else { + // Handle invalid actions res.status(400).send("Invalid action"); return; } + // Call the selected database function with user data funcName( req.body.username, req.body.first_name, @@ -85,6 +100,7 @@ app.post(["/createUser", "/updateUser", "/deleteUser"], (req, res) => { req.body.email ).then((result) => { if (result.success === true) { + // On success, render dashboard with success message res.status(201).render("dashboard.ejs", { sqlResult: latestUser, newLink: `/dashboard/${latestUser.id}`, @@ -92,6 +108,7 @@ app.post(["/createUser", "/updateUser", "/deleteUser"], (req, res) => { success: "User action successful!", }); } else { + // On failure, render dashboard with alert res.status(400).render("dashboard.ejs", { sqlResult: latestUser, newLink: `/dashboard/${latestUser.id}`, @@ -104,6 +121,7 @@ app.post(["/createUser", "/updateUser", "/deleteUser"], (req, res) => { // error handling code app.use((err, req, res, next) => { + // Log the error stack and send a generic error response console.error(err.stack); res.status(500).send("Something broke!"); }); diff --git a/backend/views/dashboard.ejs b/backend/views/dashboard.ejs index 25ecd3f..7b9cdf3 100644 --- a/backend/views/dashboard.ejs +++ b/backend/views/dashboard.ejs @@ -1,14 +1,10 @@
-