Skip to content

Commit

Permalink
Merge pull request Sahil1786#108 from Laxelspal/origine-main
Browse files Browse the repository at this point in the history
added reset password functionality
  • Loading branch information
Sahil1786 authored May 18, 2024
2 parents 65a81a4 + 6f9fd78 commit d5b048d
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 81 deletions.
2 changes: 2 additions & 0 deletions model/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const userSchema = new mongoose.Schema({
approved: { type: Boolean, default: false },
// googleId: String,
// profile: String,
resetTokenExpiration: Date,
resetToken:String
});

const User = new mongoose.model("User", userSchema);
Expand Down
174 changes: 95 additions & 79 deletions routers/userRoutes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const express = require("express");
const router = new express.Router();
const path =require("path");

const bcrypt = require("bcrypt");
const saltRounds = 10;
Expand Down Expand Up @@ -83,83 +84,6 @@ router.post("/login", async function (req, res) {
}
});

router.route("/forgot-password").get(async (req, res) => {
res.render("forget-password");
});

router.route("/reset-password").get(async (req, res) => {
const { email, token } = req.query;

try {
const user = await User.findOne({
email,
resetToken: token,
resetTokenExpiration: { $gt: Date.now() },
});

if (!user) {
return res.status(400).send("Invalid or expired reset token");
}

// Verify the token
try {
const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
// Process the decoded token (e.g., extract information from it)
console.log(decodedToken);
// Continue with the reset-password logic
res.render("reset-password", { email, token });
} catch (error) {
// Handle JWT verification errors
console.error("JWT verification error:", error.message);
// You might want to send an error response or redirect the user
res.status(401).send("Unauthorized");
}
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
}
});

router.post(async (req, res) => {
const { email, token, newPassword } = req.body;

try {
// Verify the token again
const user = await User.findOne({
email,
resetToken: token,
resetTokenExpiration: { $gt: Date.now() },
});

if (!user) {
return res.status(400).send("Invalid or expired reset token");
}

try {
const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
// Process the decoded token (e.g., extract information from it)
console.log(decodedToken);

// Update the user's password and reset the resetToken fields
const hash = await bcrypt.hash(newPassword, saltRounds);
user.password = hash;
user.resetToken = null;
user.resetTokenExpiration = null;
await user.save();

res.redirect("/login"); // Redirect to login page or any other desired page
} catch (error) {
// Handle JWT verification errors
console.error("JWT verification error:", error.message);
// You might want to send an error response or redirect the user
res.status(401).send("Unauthorized");
}
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
}
});

// extra details added for the user
router.post("/add-details", async (req, res) => {
try {
Expand Down Expand Up @@ -354,7 +278,12 @@ router.post("/User_singUp", async function (req, res) {
}
});

router.post(async (req, res) => {
router.route("/forgot-password").get(async (req, res) => {
res.render("forget-password");
});

//send Email for the reset password
router.route("/forgot-password").post(async (req, res) => {
const { email } = req.body;
try {
const user = await User.findOne({ email });
Expand All @@ -370,6 +299,9 @@ router.post(async (req, res) => {
);

user.resetTokenExpiration = Date.now() + 300000; // 5 minutes
user.resetToken = resetToken;

console.log("use after setting ",user);
await user.save();

// Send the reset link to the user via email
Expand All @@ -393,7 +325,7 @@ router.post(async (req, res) => {
attachments: [
{
filename: "logo.png",
path: path.join(__dirname, "public", "img", "logo.png"),
path: path.join( "public", "img", "logo.png"),
cid: "logo",
},
],
Expand All @@ -414,4 +346,88 @@ router.post(async (req, res) => {
}
});

// verify Email and render reset password page
router.route("/reset-password").get(async (req, res) => {
const { email, token } = req.query;
try {
const user = await User.findOne({
email,
resetToken: token,
resetTokenExpiration: { $gt: Date.now() },
});

if (!user) {
return res.status(400).send("Invalid or expired reset token");
}

// Verify the token
try {
const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
// Process the decoded token (e.g., extract information from it)
console.log(decodedToken);
// Continue with the reset-password logic
res.render("set_password", { email, token });
} catch (error) {
// Handle JWT verification errors
console.error("JWT verification error:", error.message);
// You might want to send an error response or redirect the user
res.status(401).send("Unauthorized");
}
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
}
});


//verify the password
router.route("/reset-password").post(async (req, res) => {
const {email,token} =req.query;
const { newPassword } = req.body;
// console.log(" User Info",email,token,newPassword);

try {
// Verify the token again
const user = await User.findOne({
email,
resetToken: token,
resetTokenExpiration: { $gt: Date.now() },
});

if (!user) {
return res.status(400).send("Invalid or expired reset token");
}

try {
const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
// Process the decoded token (e.g., extract information from it)
console.log(decodedToken);

// Update the user's password and reset the resetToken fields
const hash = await bcrypt.hash(newPassword, saltRounds);
user.password = hash;
user.resetToken = null;
user.resetTokenExpiration = null;
await user.save();

return res.render("UserDashBoard", {
fullName: user.fullName,
email: user.email,
phoneNo: user.Mobile,
address: user.address,
});

// Redirect to login page or any other desired page
} catch (error) {
// Handle JWT verification errors
console.error("JWT verification error:", error.message);
// You might want to send an error response or redirect the user
res.status(401).send("Unauthorized");
}
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
}
});

module.exports = router;
3 changes: 1 addition & 2 deletions views/forget-password.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@
<div class="input-group">
<label for="" class="label-title">Enter your Email</label>
<input type="email" name="email" placeholder="Enter your Email">
<span class="icon">&#9993;</span>

<span class="icon"> &#9993;</span>
</div>
<div class="input-group">
<button class="submit-btn" type="submit">Send Reset Email</button>
Expand Down
133 changes: 133 additions & 0 deletions views/set_password.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- <link rel="stylesheet" href="/public/css/index.css"> -->
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,200&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'poppins', sans-serif;
}
.wrapper{
background-color: #106fde;
width: 100%;
height: 100vh;
padding: 15px;
display: flex;
flex-direction: column;
gap: 20px;
justify-content: center;
align-items: center;
}
.container{
width: 500px;
background-color: #fff;
padding: 30px;
border-radius: 16px;
background-color: rgba(0,0,0,0.08) 0px 4px 12px;
/* flex-shrink: 1; */
}
.title-section{
margin-bottom: 30px;
}
.title{
color: #38475a;
font-size: 25px;
font-weight: 500;
text-transform: capitalize;
margin-bottom: 10px;
}
.input-group{
position: relative;
}
.input-group .label-title{
color: #38475a;
text-transform: capitalize;
margin-bottom: 11px;
font-size: 14px;
display: block;
font-weight: 500;
}
.input-group input{
width: 100%;
background-color: none;
color: #38475a;
height: 50px;
font-size: 16px;
font-weight: 300;
border: 1px solid #EAECF0;
padding: 9px 18px 9px 52px;
outline: none;
border-radius: 8px;
margin-bottom: 20px;
}
.input-group .input::placeholder{
color: #38475a;
font-size: 16px;
font-weight: 400;
}
.input-group .icon{
position: absolute;
color: #38475a;
left: 13px;
font-size: 23px;
text-align: center;
top: calc(50% - 11px);
}
.submit-btn{
width: 100%;
background-color: #106fde;
border: 1px solid transparent;
border-radius: 8px;
font-size: 16px;
color: #fff;
padding: 13px 24px;
font-weight: 500;
text-align: center;
text-transform: capitalize;
cursor: pointer;
}
.submit-btn:hover{
opacity: 0.95;
}
.logo{
width: 10%;
flex: 0 0 0;
}
</style>
<title>Password Reset</title>
</head>
<body>

<div class="wrapper">
<img src="img/logo.png" alt="" class="logo">
<div class="container">
<div class="title-section">
<h2 class="title">Reset Password</h2>

<form action="/reset-password?email=<%=email%>&token=<%=token%>" class="form" method="post">
<div class="input-group">
<label for="" class="label-title">Enter new Password</label>
<input type="password" name="newPassword" placeholder="Enter your password">
<!-- <span class="icon"> &#xf3ed;</span> -->

</div>
<div class="input-group">
<button class="submit-btn" type="submit">Update my password</button>

</div>
</form>
</div>
</div>



</body>
</html>

0 comments on commit d5b048d

Please sign in to comment.