From 033401dbf7d1decb9373e2b88fe14e92d24a4be2 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 11:15:18 -0700 Subject: [PATCH 1/9] update/profile page with user data --- src/public/scripts/profile.js | 57 +++++++++++++++++++++++ src/router/user.js | 2 +- src/views/profile.ejs | 85 +++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/public/scripts/profile.js create mode 100644 src/views/profile.ejs diff --git a/src/public/scripts/profile.js b/src/public/scripts/profile.js new file mode 100644 index 0000000..f1406e6 --- /dev/null +++ b/src/public/scripts/profile.js @@ -0,0 +1,57 @@ +/** + * unlockAccount removes disabled from inputs and + * allows users to edit their profile. + */ +function unlockAccount() { + document.getElementById("save-account").disabled = false; + document.getElementById("email").disabled = false; + document.getElementById("name").disabled = false; + document.getElementById("password").disabled = false; + document.getElementById("repassword").disabled = false; + document.getElementById("save-account").classList.remove("cursor-not-allowed"); +} + +/** + * unlocPersonal removes disabled from inputs and + * allows users to edit their personal information. + */ +function unlockPersonal() { + document.getElementById("save-personal").disabled = false; + document.getElementById("dob").disabled = false; + document.getElementById("education").disabled = false; + document.getElementById("ms-single").disabled = false; + document.getElementById("ms-married").disabled = false; + document.getElementById("ms-divorced").disabled = false; + document.getElementById("ms-widowed").disabled = false; + document.getElementById("save-personal").classList.remove("cursor-not-allowed"); +} + +/** + * lockAll makes all inputs disabled on page load + */ +function lockAll() { + // Clear unsaved inputs on page load (refresh doesnt clear them) + document.getElementById("account-form").reset(); + document.getElementById("personal-form").reset(); + + // Account section + document.getElementById("save-account").disabled = true; + document.getElementById("email").disabled = true; + document.getElementById("name").disabled = true; + document.getElementById("password").disabled = true; + document.getElementById("repassword").disabled = true; + document.getElementById("save-account").classList.add("cursor-not-allowed"); + + // Personal info section + document.getElementById("save-personal").disabled = true; + document.getElementById("dob").disabled = true; + document.getElementById("education").disabled = true; + document.getElementById("ms-single").disabled = true; + document.getElementById("ms-married").disabled = true; + document.getElementById("ms-divorced").disabled = true; + document.getElementById("ms-widowed").disabled = true; + document.getElementById("save-personal").classList.add("cursor-not-allowed"); + +} + +lockAll() diff --git a/src/router/user.js b/src/router/user.js index dd8eaf6..314fdf8 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -27,7 +27,7 @@ module.exports = (middleware, users) => { }); router.get('/profile', (req, res) => { - res.render('profiles', { user: req.user }); + res.render('profile', { user: req.user }); return res.status(status.Ok); }); diff --git a/src/views/profile.ejs b/src/views/profile.ejs new file mode 100644 index 0000000..dbb8a41 --- /dev/null +++ b/src/views/profile.ejs @@ -0,0 +1,85 @@ +<%- include("./partials/fileHeader") %> +<%- include("./partials/header") %> + +
+

Welcome: <%= user.name %>

+
+
+

Account settings

+ +
+
+ + + + + + + + + + + + + +
+ +
+
+
+ +
+
+

Personal information

+ +
+
+
+ + +
+
+ + +
+ +
+ +
+ + + + +
+
+ +
+ +
+
+
+ +
+
+ + + +<%- include("./partials/navBar") %> +<%- include("./partials/footer") %> \ No newline at end of file From a2b4e8d36dcd2d70fab183fa117aa1baa633a570 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 11:19:10 -0700 Subject: [PATCH 2/9] refactor/remove debug statements --- src/auth/authentication.js | 2 -- src/router/user.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/auth/authentication.js b/src/auth/authentication.js index fe7c97d..ecbec34 100644 --- a/src/auth/authentication.js +++ b/src/auth/authentication.js @@ -39,8 +39,6 @@ module.exports = (users) => { return res.redirect("/login"); } - console.log("User logged in successfully"); - console.log("User email: " + req.body.email); req.session.authenticated = true; req.session.email = req.body.email; req.session.errMessage = ""; diff --git a/src/router/user.js b/src/router/user.js index 314fdf8..8800b32 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -43,8 +43,6 @@ module.exports = (middleware, users) => { }); router.post('/questionnaire', (req, res) => { - console.log("Questionnaire POST body:", req.body); - const questionnaireSchema = joi.object({ dob: joi.date().required(), education: joi.string().valid('primary', 'secondary', 'tertiary', 'postgraduate').required(), From 75bc3bee8fa6f369e2c96473384d2ee0fbd01498 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 11:39:49 -0700 Subject: [PATCH 3/9] update/save modified account settings --- src/router/user.js | 57 ++++++++++++++++++++++++++++++++++++++++++- src/views/profile.ejs | 15 ++++++++---- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/router/user.js b/src/router/user.js index 8800b32..407aca9 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -1,5 +1,7 @@ const status = require("../util/statuses"); +const bcrypt = require('bcrypt'); const joi = require("joi"); +const salt = 12; module.exports = (middleware, users) => { const router = require("express").Router(); @@ -27,7 +29,7 @@ module.exports = (middleware, users) => { }); router.get('/profile', (req, res) => { - res.render('profile', { user: req.user }); + res.render('profile', { user: req.user, errMessage: req.session.errMessage }); return res.status(status.Ok); }); @@ -106,5 +108,58 @@ module.exports = (middleware, users) => { }); }); + router.post("/updateAccount", async (req, res) => { + const accountSchema = joi.object({ + email: joi.string().email(), + name: joi.string().alphanum().max(20), + password: joi.string().max(20).min(8), + repassword: joi.string().max(20).min(8), + }); + + const valid = accountSchema.validate(req.body); + + if (valid.err) { + req.session.errMessage = "Invalid input", + res.status(status.BadRequest); + return res.redirect("/profile"); + } + + let update = { + // email: req.body.email, + name: req.body.name, + }; + + if ((req.body.password != "") && (req.body.password != req.body.repassword)) { + req.session.errMessage = "New passwords must match"; + res.status(status.BadRequest); + return res.redirect("/profile"); + } else if (req.body.password != "") { + let hashedPassword = await bcrypt.hashSync(req.body.password, salt); + update.password = hashedPassword; + } + + users.updateOne( + { email: req.session.email }, + { $set: update } + ).then((result) => { + if (result.matchedCount === 0) { + console.log(`User not found during account update: ${req.session.email}`); + req.session.errMessage = "User session invalid. Please log in again."; + res.status(status.NotFound).redirect("/login"); + return; + } + if (result.modifiedCount === 0 && result.matchedCount === 1) { + console.log(`User account data unchanged (already up-to-date): ${req.session.email}`); + } + + req.session.errMessage = ""; + return res.status(status.Ok).redirect("/profile"); + }).catch(err => { + console.error("Error updating account in database:", err); + req.session.errMessage = "An error occurred while saving your information. Please try again."; + return res.status(status.InternalServerError).redirect("/profile"); + }); + }); + return router; }; diff --git a/src/views/profile.ejs b/src/views/profile.ejs index dbb8a41..951ca5e 100644 --- a/src/views/profile.ejs +++ b/src/views/profile.ejs @@ -2,7 +2,12 @@ <%- include("./partials/header") %>
-

Welcome: <%= user.name %>

+

Welcome <%= user.name %>

+ + <% if (errMessage != "") { %> +
<%= errMessage %>
+ <% } %> +

Account settings

@@ -16,11 +21,11 @@ - - + + - - + +
From b88333e3b4526f94b0a3cccd3ec7a56c6a77c415 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 11:41:14 -0700 Subject: [PATCH 4/9] refactor/temp remove personal section --- src/views/profile.ejs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/profile.ejs b/src/views/profile.ejs index 951ca5e..fcfc786 100644 --- a/src/views/profile.ejs +++ b/src/views/profile.ejs @@ -32,7 +32,7 @@
- +
From f0d324151d3a134bcf340fcad72fee3e94a1cf3c Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 11:44:26 -0700 Subject: [PATCH 5/9] update/error message style --- src/views/profile.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/profile.ejs b/src/views/profile.ejs index fcfc786..22b28f0 100644 --- a/src/views/profile.ejs +++ b/src/views/profile.ejs @@ -5,7 +5,7 @@

Welcome <%= user.name %>

<% if (errMessage != "") { %> -
<%= errMessage %>
+
<%= errMessage %>
<% } %>
From b350cdad9fd62f3a8dbb975ae168d9b076fb0cbf Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 11:46:14 -0700 Subject: [PATCH 6/9] update/keep email input disabled --- src/public/scripts/profile.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/public/scripts/profile.js b/src/public/scripts/profile.js index f1406e6..21860a0 100644 --- a/src/public/scripts/profile.js +++ b/src/public/scripts/profile.js @@ -4,7 +4,7 @@ */ function unlockAccount() { document.getElementById("save-account").disabled = false; - document.getElementById("email").disabled = false; + // document.getElementById("email").disabled = false; document.getElementById("name").disabled = false; document.getElementById("password").disabled = false; document.getElementById("repassword").disabled = false; @@ -32,7 +32,7 @@ function unlockPersonal() { function lockAll() { // Clear unsaved inputs on page load (refresh doesnt clear them) document.getElementById("account-form").reset(); - document.getElementById("personal-form").reset(); + // document.getElementById("personal-form").reset(); // Account section document.getElementById("save-account").disabled = true; @@ -43,14 +43,14 @@ function lockAll() { document.getElementById("save-account").classList.add("cursor-not-allowed"); // Personal info section - document.getElementById("save-personal").disabled = true; - document.getElementById("dob").disabled = true; - document.getElementById("education").disabled = true; - document.getElementById("ms-single").disabled = true; - document.getElementById("ms-married").disabled = true; - document.getElementById("ms-divorced").disabled = true; - document.getElementById("ms-widowed").disabled = true; - document.getElementById("save-personal").classList.add("cursor-not-allowed"); + // document.getElementById("save-personal").disabled = true; + // document.getElementById("dob").disabled = true; + // document.getElementById("education").disabled = true; + // document.getElementById("ms-single").disabled = true; + // document.getElementById("ms-married").disabled = true; + // document.getElementById("ms-divorced").disabled = true; + // document.getElementById("ms-widowed").disabled = true; + // document.getElementById("save-personal").classList.add("cursor-not-allowed"); } From 3bb9ede51525e04ff8dacc09fc91da311abfd9de Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 11:52:53 -0700 Subject: [PATCH 7/9] update/cancel changes --- src/public/scripts/profile.js | 76 ++++++++++++++++++++++------------- src/views/profile.ejs | 2 +- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/public/scripts/profile.js b/src/public/scripts/profile.js index 21860a0..d803378 100644 --- a/src/public/scripts/profile.js +++ b/src/public/scripts/profile.js @@ -1,3 +1,41 @@ +/** + * lockAccount resets inputs and disabled inputs + */ +function lockAccount() { + // Clear unsaved inputs on page load (refresh doesnt clear them) + document.getElementById("account-form").reset(); + + document.getElementById("save-account").disabled = true; + document.getElementById("email").disabled = true; + document.getElementById("name").disabled = true; + document.getElementById("password").disabled = true; + document.getElementById("repassword").disabled = true; + document.getElementById("save-account").classList.add("cursor-not-allowed"); + + document.getElementById("edit-account").innerHTML = "Edit"; + document.getElementById("edit-account").onclick = unlockAccount; +} + +/** + * lockPersonal resets inputs and disabled inputs + */ +function lockPersonal() { + // Clear unsaved inputs on page load (refresh doesnt clear them) + document.getElementById("personal-form").reset(); + + document.getElementById("save-personal").disabled = true; + document.getElementById("dob").disabled = true; + document.getElementById("education").disabled = true; + document.getElementById("ms-single").disabled = true; + document.getElementById("ms-married").disabled = true; + document.getElementById("ms-divorced").disabled = true; + document.getElementById("ms-widowed").disabled = true; + document.getElementById("save-personal").classList.add("cursor-not-allowed"); + + document.getElementById("edit-personal").innerHTML = "Edit"; + document.getElementById("edit-personal").onclick = unlockPersonal; +} + /** * unlockAccount removes disabled from inputs and * allows users to edit their profile. @@ -9,6 +47,9 @@ function unlockAccount() { document.getElementById("password").disabled = false; document.getElementById("repassword").disabled = false; document.getElementById("save-account").classList.remove("cursor-not-allowed"); + + document.getElementById("edit-account").innerHTML = "Cancel changes"; + document.getElementById("edit-account").onclick = lockAccount; } /** @@ -24,34 +65,11 @@ function unlockPersonal() { document.getElementById("ms-divorced").disabled = false; document.getElementById("ms-widowed").disabled = false; document.getElementById("save-personal").classList.remove("cursor-not-allowed"); + + document.getElementById("edit-personal").innerHTML = "Cancel changes"; + document.getElementById("edit-personal").onclick = lockPersonal; } -/** - * lockAll makes all inputs disabled on page load - */ -function lockAll() { - // Clear unsaved inputs on page load (refresh doesnt clear them) - document.getElementById("account-form").reset(); - // document.getElementById("personal-form").reset(); - - // Account section - document.getElementById("save-account").disabled = true; - document.getElementById("email").disabled = true; - document.getElementById("name").disabled = true; - document.getElementById("password").disabled = true; - document.getElementById("repassword").disabled = true; - document.getElementById("save-account").classList.add("cursor-not-allowed"); - - // Personal info section - // document.getElementById("save-personal").disabled = true; - // document.getElementById("dob").disabled = true; - // document.getElementById("education").disabled = true; - // document.getElementById("ms-single").disabled = true; - // document.getElementById("ms-married").disabled = true; - // document.getElementById("ms-divorced").disabled = true; - // document.getElementById("ms-widowed").disabled = true; - // document.getElementById("save-personal").classList.add("cursor-not-allowed"); - -} - -lockAll() +// On page load, ensure forms are locked and reset +lockAccount(); +// lockPersonal(); diff --git a/src/views/profile.ejs b/src/views/profile.ejs index 22b28f0..34f0bc2 100644 --- a/src/views/profile.ejs +++ b/src/views/profile.ejs @@ -11,7 +11,7 @@

Account settings

- +
From 97a1473e213510e1c0fa61515484abf46919b595 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Tue, 6 May 2025 12:46:21 -0700 Subject: [PATCH 8/9] fix/require name on register --- src/auth/authentication.js | 11 +++++------ src/views/signup.ejs | 6 ++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/auth/authentication.js b/src/auth/authentication.js index ecbec34..b71fa12 100644 --- a/src/auth/authentication.js +++ b/src/auth/authentication.js @@ -50,7 +50,7 @@ module.exports = (users) => { router.post("/signup", async (req, res) => { const userSchema = joi.object({ email: joi.string().email().required(), - // name: joi.string().alphanum().max(20).required(), + name: joi.string().alphanum().max(20).required(), password: joi.string().max(20).min(8).required(), repassword: joi.string().max(20).min(8).required(), }); @@ -73,21 +73,20 @@ module.exports = (users) => { users.insertOne({ email: req.body.email, - // name: req.body.name, + name: req.body.name, password: hashedPassword, }).then((results, err) => { if (err) { - res.status(status.InternalServerError); console.error(err); - return res.send("Internal server error"); + res.session.errMessage = "Internal server error"; + return res.status(status.InternalServerError).redirect("/signup"); } req.session.authenticated = true; req.session.email = req.body.email; req.session.errMessage = ""; - res.status(status.Ok); - return res.redirect("/home"); + return res.status(status.Ok).redirect("/home"); }); }); diff --git a/src/views/signup.ejs b/src/views/signup.ejs index 7411268..97f1347 100644 --- a/src/views/signup.ejs +++ b/src/views/signup.ejs @@ -13,6 +13,12 @@ class="border focus:border-gray-600 w-full text-base px-2 py-1 focus:outline-none focus:ring-0 " placeholder="Enter Email" />
+
+ + +
Date: Tue, 6 May 2025 12:49:20 -0700 Subject: [PATCH 9/9] fix/ignore login err message on signup --- app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app.js b/app.js index 8e9dd77..6321d6e 100644 --- a/app.js +++ b/app.js @@ -49,6 +49,8 @@ app.get('/', (req, res) => { }); app.get('/signup', (req, res) => { + const ignore = ["User not found", "Incorrect password"]; + if (ignore.includes(req.session.errMessage)) req.session.errMessage = ""; res.render('signup', { errMessage: req.session.errMessage }); return res.status(status.Ok); });