From 2be99b35d68962036d80ff06e8eecbd95bffd837 Mon Sep 17 00:00:00 2001 From: Ayush Date: Tue, 29 Oct 2024 16:25:40 +0530 Subject: [PATCH] added reset password --- backend/controllers/userController.js | 123 +++++++++++++ backend/package-lock.json | 12 +- backend/package.json | 3 +- backend/routes/userRoutes.js | 6 + main.js | 238 ++++++++++++++------------ resetpass.html | 176 +++++++++++++++++++ 6 files changed, 449 insertions(+), 109 deletions(-) create mode 100644 resetpass.html diff --git a/backend/controllers/userController.js b/backend/controllers/userController.js index 27d2b586..5c0812cf 100644 --- a/backend/controllers/userController.js +++ b/backend/controllers/userController.js @@ -1,6 +1,8 @@ import User from "../models/user.js"; import jwt from "jsonwebtoken"; import dotenv from "dotenv"; +import nodemailer from "nodemailer"; +import bcrypt from "bcryptjs"; dotenv.config(); // Generate JWT token @@ -99,3 +101,124 @@ export const getAllUsers = async (req, res) => { res.status(500).json({ message: error.message }); } }; + +export function ForgotPassWordEmail(req, resp) { + const transporter = nodemailer.createTransport({ + service: "gmail", + auth: { + user: "your email id", + pass: "your password", + }, + }); + + const mailOptions = { + from: "your email id", + to: req.body.Email, + subject: "WordWise Reset Password", + html: ` + + + + + + Password Reset + + + +
+

Password Reset Request

+

Hello,

+

We received a request to reset your password. Click the button below to proceed with resetting your password.

+ + +

Thank you,
Team WordWise

+
+ + + `, + }; + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + console.log("Error sending email: " + error); + resp.status(500).send("Error sending email"); + } else { + console.log("Email sent: " + info.response); + resp.status(200).send("Form data sent successfully"); + } + }); +} + +export async function ResetPassword(req, resp) { + try { + const { password, email } = req.body; + + const user = await User.findOne({ email }); + if (!user) { + return resp + .status(404) + .json({ success: false, message: "User not found" }); + } + + const saltRounds = 10; + const hashedPassword = await bcrypt.hash(password, saltRounds); + + user.password = hashedPassword; + await user.save(); + + resp + .status(200) + .json({ success: true, message: "Password reset successfully" }); + } catch (error) { + console.error("Error resetting password:", error); + resp.status(500).json({ + success: false, + message: "An error occurred. Please try again later.", + }); + } +} diff --git a/backend/package-lock.json b/backend/package-lock.json index 3879d11d..a8eded66 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -16,7 +16,8 @@ "express-validator": "^7.2.0", "jsonwebtoken": "^9.0.2", "mongoose": "^8.7.1", - "multer": "^1.4.5-lts.1" + "multer": "^1.4.5-lts.1", + "nodemailer": "^6.9.16" }, "devDependencies": { "nodemon": "^3.1.7" @@ -1039,6 +1040,15 @@ "node": ">= 0.6" } }, + "node_modules/nodemailer": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.16.tgz", + "integrity": "sha512-psAuZdTIRN08HKVd/E8ObdV6NO7NTBY3KsC30F7M4H1OnmLCUNaS56FpYxyb26zWLSyYF9Ozch9KYHhHegsiOQ==", + "license": "MIT-0", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/nodemon": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", diff --git a/backend/package.json b/backend/package.json index c261628b..35cf3218 100644 --- a/backend/package.json +++ b/backend/package.json @@ -19,7 +19,8 @@ "express-validator": "^7.2.0", "jsonwebtoken": "^9.0.2", "mongoose": "^8.7.1", - "multer": "^1.4.5-lts.1" + "multer": "^1.4.5-lts.1", + "nodemailer": "^6.9.16" }, "devDependencies": { "nodemon": "^3.1.7" diff --git a/backend/routes/userRoutes.js b/backend/routes/userRoutes.js index a93f5d41..06d711e6 100644 --- a/backend/routes/userRoutes.js +++ b/backend/routes/userRoutes.js @@ -4,6 +4,8 @@ import { loginUser, getUserProfile, getAllUsers, + ForgotPassWordEmail, + ResetPassword, } from "../controllers/userController.js"; import authMiddleware from "../middlewares/authMiddleware.js"; import adminMiddleware from "../middlewares/adminMiddleware.js"; @@ -20,4 +22,8 @@ router.get("/profile", authMiddleware, getUserProfile); // Admin route to get all users router.get("/", authMiddleware, adminMiddleware, getAllUsers); +router.post("/forgotpassword", ForgotPassWordEmail); + +router.post("/resetpassword", ResetPassword); + export default router; diff --git a/main.js b/main.js index f13e8b99..bad9d111 100644 --- a/main.js +++ b/main.js @@ -3,40 +3,40 @@ let collapse = document.querySelectorAll("#header .collapse"); document.getElementById("backToTop").style.display = "none"; if (toggle) { - toggle.addEventListener('click', function () { - collapse.forEach(col => col.classList.toggle("collapse-toggle")); - }) + toggle.addEventListener("click", function () { + collapse.forEach((col) => col.classList.toggle("collapse-toggle")); + }); } //swiper library // main.js -document.addEventListener('DOMContentLoaded', function () { - var swiper = new Swiper('.swiper-container', { - direction: 'horizontal', +document.addEventListener("DOMContentLoaded", function () { + var swiper = new Swiper(".swiper-container", { + direction: "horizontal", loop: true, slidesPerView: 1, autoplay: { - delay: 3000 + delay: 3000, }, pagination: { - el: '.swiper-pagination', + el: ".swiper-pagination", clickable: true, }, navigation: { - nextEl: '.swiper-button-next', - prevEl: '.swiper-button-prev', + nextEl: ".swiper-button-next", + prevEl: ".swiper-button-prev", }, }); - detectColorScheme(); - }); + detectColorScheme(); +}); - window.addEventListener("scroll", function () { +window.addEventListener("scroll", function () { var scrollPosition = window.scrollY; var height = document.body.offsetHeight - window.innerHeight; if (scrollPosition > 90) { - document.getElementById("backToTop").style.display = "block"; + document.getElementById("backToTop").style.display = "block"; } else { - document.getElementById("backToTop").style.display = "none"; + document.getElementById("backToTop").style.display = "none"; } }); @@ -44,8 +44,9 @@ document.getElementById("backToTop").addEventListener("click", function () { window.scrollTo({ top: 0, behavior: "smooth" }); }); -window.onscroll = function () { myFunction() }; - +window.onscroll = function () { + myFunction(); +}; // get the current value let navbar = document.getElementById("header"); @@ -68,8 +69,8 @@ function validateSignupForm() { // Check if passwords match if (password !== confirmPassword) { - alert("Passwords do not match. Please try again."); - return false; // Prevent form submission + alert("Passwords do not match. Please try again."); + return false; // Prevent form submission } // Additional validation (if any) @@ -81,93 +82,116 @@ function validateSignupForm() { // Open the specific form (login or signup) function openForm(formType) { // Hide both forms first - document.getElementById('loginForm').style.display = 'none'; - document.getElementById('signupForm').style.display = 'none'; + document.getElementById("loginForm").style.display = "none"; + document.getElementById("signupForm").style.display = "none"; // Display the requested form - if (formType === 'login') { - document.getElementById('loginForm').style.display = 'block'; - document.getElementById('signupForm').style.display = 'none'; - } else if (formType === 'signup') { - document.getElementById('signupForm').style.display = 'block'; - document.getElementById('loginForm').style.display = 'none'; + if (formType === "login") { + document.getElementById("loginForm").style.display = "block"; + document.getElementById("signupForm").style.display = "none"; + } else if (formType === "signup") { + document.getElementById("signupForm").style.display = "block"; + document.getElementById("loginForm").style.display = "none"; } } - // Close the specific form function closeForm(formType) { - if (formType === 'login') { - document.getElementById('loginForm').style.display = 'none'; - } else if (formType === 'signup') { - document.getElementById('signupForm').style.display = 'none'; + if (formType === "login") { + document.getElementById("loginForm").style.display = "none"; + } else if (formType === "signup") { + document.getElementById("signupForm").style.display = "none"; } } //Active Nav bar function openForgotPassword() { - document.getElementById('loginForm').style.display = 'none'; - document.getElementById('email').value = ''; - document.getElementById('forgot-password-modal').style.display = 'block'; - } + document.getElementById("loginForm").style.display = "none"; + document.getElementById("email").value = ""; + document.getElementById("forgot-password-modal").style.display = "block"; +} // Close Forgot Password Modal function closeForgotPasswordModal() { - document.getElementById('email').value = ''; - document.getElementById('forgot-password-modal').style.display = 'none'; + document.getElementById("email").value = ""; + document.getElementById("forgot-password-modal").style.display = "none"; } // Simulate form submission for Forgot Password -function submitForgotPassword() { - const email = document.getElementById('email').value; - if (email) { - alert("Password reset instructions have been sent to " + email); - closeForgotPasswordModal(); // Close modal after submission +// function submitForgotPassword() { +// const email = document.getElementById("email").value; +// if (email) { +// alert("Password reset instructions have been sent to " + email); +// closeForgotPasswordModal(); // Close modal after submission +// } else { +// alert("Please enter your email."); +// } + +async function submitForgotPassword() { + const email = document.getElementById("email").value; + + try { + const response = await fetch( + "http://localhost:5000/api/users/forgotpassword", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + Email: email, + }), + } + ); + + if (response.status === 200) { + alert("Email sent successfully!"); } else { - alert("Please enter your email."); -} + alert("Failed to send email"); + } + } catch (error) { + console.error("Error:", error); + } } // Close modal when clicking outside of it -window.onclick = function(event) { - const modal = document.getElementById('forgot-password-modal'); - if (event.target == modal) { - modal.style.display = 'none'; -} +window.onclick = function (event) { + const modal = document.getElementById("forgot-password-modal"); + if (event.target == modal) { + modal.style.display = "none"; + } }; -const navLinks = document.querySelectorAll('.nav-link'); +const navLinks = document.querySelectorAll(".nav-link"); const setActiveLink = () => { - const activePath = localStorage.getItem('activeLink'); + const activePath = localStorage.getItem("activeLink"); if (activePath) { - navLinks.forEach(link => { - const linkHref = link.getAttribute('href'); + navLinks.forEach((link) => { + const linkHref = link.getAttribute("href"); if (linkHref === activePath) { - link.classList.add('active'); + link.classList.add("active"); } else { - link.classList.remove('active'); + link.classList.remove("active"); } }); } }; -document.addEventListener('DOMContentLoaded', setActiveLink); +document.addEventListener("DOMContentLoaded", setActiveLink); -navLinks.forEach(link => { - link.addEventListener('click', function() { - navLinks.forEach(link => link.classList.remove('active')); +navLinks.forEach((link) => { + link.addEventListener("click", function () { + navLinks.forEach((link) => link.classList.remove("active")); - this.classList.add('active'); + this.classList.add("active"); - localStorage.setItem('activeLink', this.getAttribute('href')); + localStorage.setItem("activeLink", this.getAttribute("href")); }); }); - function detectColorScheme() { var theme = "light"; - //local storage is used to override OS theme settings if (localStorage.getItem("theme")) { if (localStorage.getItem("theme") == "dark") { @@ -181,96 +205,96 @@ function detectColorScheme() { var theme = "dark"; } - //dark theme preferred, set document with a `data-theme` attribute if (theme == "dark") { - let toggleSwitch = document.querySelector('#theme-switch input[type="checkbox"]'); + let toggleSwitch = document.querySelector( + '#theme-switch input[type="checkbox"]' + ); document.documentElement.setAttribute("data-theme", "dark"); toggleSwitch.checked = true; } } - //identify the toggle switch HTML element -const toggleSwitch = document.querySelector('#theme-switch input[type="checkbox"]'); - +const toggleSwitch = document.querySelector( + '#theme-switch input[type="checkbox"]' +); //function that changes the theme, and sets a localStorage variable to track the theme between page loads function switchTheme(e) { if (e.target.checked) { - localStorage.setItem('theme', 'dark'); - document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem("theme", "dark"); + document.documentElement.setAttribute("data-theme", "dark"); toggleSwitch.checked = true; } else { - localStorage.setItem('theme', 'light'); - document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem("theme", "light"); + document.documentElement.setAttribute("data-theme", "light"); toggleSwitch.checked = false; } } if (toggleSwitch) //listener for changing themes - toggleSwitch.addEventListener('change', switchTheme, false); - + toggleSwitch.addEventListener("change", switchTheme, false); //pre-check the dark-theme checkbox if dark-theme is set if (document.documentElement.getAttribute("data-theme") == "dark") { toggleSwitch.checked = true; } -let aboutSection = document.querySelector('#about'); +let aboutSection = document.querySelector("#about"); if (aboutSection) { - document.querySelector('#about').addEventListener('click', function(event) { + document.querySelector("#about").addEventListener("click", function (event) { event.preventDefault(); - document.querySelector('#about-us').scrollIntoView({ behavior: 'smooth' }); - }); + document.querySelector("#about-us").scrollIntoView({ behavior: "smooth" }); + }); } function submitNewsletter() { - const emailInput = document.getElementById('emailInput'); - const errorMessage = document.getElementById('error-message'); + const emailInput = document.getElementById("emailInput"); + const errorMessage = document.getElementById("error-message"); const email = emailInput.value; // Simple email validation check - if (!email.includes('@')) { - errorMessage.style.display = 'block'; + if (!email.includes("@")) { + errorMessage.style.display = "block"; return; } else { - errorMessage.style.display = 'none'; + errorMessage.style.display = "none"; } // Send POST request - fetch('http://127.0.0.1:3000/newsletter', { - method: 'POST', + fetch("http://127.0.0.1:3000/newsletter", { + method: "POST", headers: { - 'Content-Type': 'application/json' + "Content-Type": "application/json", }, - body: JSON.stringify({ email }) - }) - .then(response => { - if (response.ok) { - alert('Subscribed successfully!'); - emailInput.value = ''; // Clear the input field - } else { - alert('Failed to subscribe. Please try again later.'); - } + body: JSON.stringify({ email }), }) - .catch(error => { - console.error('Error:', error); - alert('An error occurred. Please try again later.'); - }); + .then((response) => { + if (response.ok) { + alert("Subscribed successfully!"); + emailInput.value = ""; // Clear the input field + } else { + alert("Failed to subscribe. Please try again later."); + } + }) + .catch((error) => { + console.error("Error:", error); + alert("An error occurred. Please try again later."); + }); } // Get hamburger and nav links -var hamburger = document.getElementById('hamburger'); -var navLinks1 = document.getElementById('nav-links1'); +var hamburger = document.getElementById("hamburger"); +var navLinks1 = document.getElementById("nav-links1"); // Only add event listener if both elements exist on the page if (hamburger && navLinks1) { - hamburger.addEventListener('click', () => { - navLinks1.classList.toggle('active'); - }); + hamburger.addEventListener("click", () => { + navLinks1.classList.toggle("active"); + }); } else { - console.warn('Hamburger or Nav Links not found on this page.'); -} \ No newline at end of file + console.warn("Hamburger or Nav Links not found on this page."); +} diff --git a/resetpass.html b/resetpass.html new file mode 100644 index 00000000..56fdeeab --- /dev/null +++ b/resetpass.html @@ -0,0 +1,176 @@ + + + + + + Reset Password + + + +
+

Reset Your Password

+
+
+ +
+
+ + 👁️ +
+
+ + 👁️ +
+ +

+
+
+ + + +