Actually, it is not that easy. Follow my article and this will definitely help you.
1st=> genarate a token using -> crypto
const crypto = require("crypto");
//this is a node built
in library that helps us creating secure unique random values
2nd=>
in the password reset click function -> this middleware should handle in the controller
exports.postReset = (req, res, next) => {
crypto.randomBytes(32, (err, buffer) => {
//
creates a random token of 32byte and
//returns
a callback function either returns an error or buffer of bytes
if (err) {
console.log(err);
return res.redirect("/reset");
}
const token = buffer.toString("hex");
//hex->
buffer will store hexa values.. conterting hexa into normal ascii
});
};
//this will continue
after we have finished the other work...
to be cont: =>
3rd=> we need to add a not
required field for User model
resetToken: String,
resetTokenExpire:Date,
4th=>make a new form for password reset
//reset.ejs
<form class="login-form"
action="/reset " method="POST">
<div class="form-control">
<label for="email">E-mail</label>
<input type="text" name="email" id="email" />
</div>
<input type="hidden" value="<%= csrfToken%>" name="_csrf" />
<button class="btn" type="submit">Reset Password</button>
</form>
5th=> add the routes
router.get("/reset", authController.getReset);
router.post("/reset", authController.postReset);
6th=> in contollers
viewing page controller
exports.getReset = (req, res, next) => {
res.render("auth/reset", { //reset.ejs
active: "reset",
pageTitle: "Password Reset",
errorMessage: "",
});
};
post reset page -> we done previous work.. from =>to be cont:
exports.postReset = (req, res, next) => {
crypto.randomBytes(32, (err, buffer) => {
//creates
a random token of 32byte and
//returns
a callback function either returns an error or buffer of bytes
if (err) {
console.log(err);
return res.redirect("/reset");
}
const token = buffer.toString("hex");
//hex-> buffer will store hexa values.. converting hexa into
normal ASCII
//find
the user he is actually registered!
User.findOne({ email: req.body.email })
.then((user) => {
if (!user) {
req.flash("error", "No Account Found...!!!");
}
user.resetToken = token;
user.resetTokenExpire = Date.now() + 3600000;
//set expiration date to
one hour
return user.save(); //update the user
})
.then((result) => {
console.log("Succeed...!!!");
res.redirect("/login");
//sending
the mail -> look for my previous tutorial to clarify more details
mailOptions.subject = "SendGrid Mail";
mailOptions.content = `<h1> You requested to pasword
reset</h1><br><br/> <a href="http://localhost:3000/reset/${token}">clickHere
to Reset</a>`;
sendgrid
.send_via_sendgrid(mailOptions)
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
});
});
};
7th=> now create that request
handle page
new password reset page form=>
<form class="login-form"
action="/new-password "
method="POST">
<div class="form-control">
<label for="password">Password</label>
<input type="password" name="password"
id="password" />
</div>
<input type="hidden" value="<%= passwordToken%>" name="passwordToken"
/>
<input type="hidden" value="<%= userId%>"
name="userId" />
<input type="hidden" value="<%= csrfToken%>" name="_csrf" />
<button class="btn" type="submit">Update Password</button>
</form>
// <need to send
password token hidden>
8th=>add the routes
router.get("/reset/:token", authController.getNewPassword); //token
passed as a get parameter
9th=> add the controller for incoming password reset link request
exports.getNewPassword = (req, res, next) => {
const token = req.params.token;
//in
the address parameters we passing the token
//(see
get request data passing my node tutorial)
User.findOne({ resetToken: token, resetTokenExpire: { $gt: Date.now() } })
//only
allowed users are both conditions are matching
.then((user) => {
if (!user) {
res.redirect("/");
}
let message = req.flash("error");
if (message.length > 0) {
message = message[0];
} else {
message = null;
}
res.render("auth/new-password", {
active: "new-password",
pageTitle: "New Password Reset",
errorMessage: message,
userId: user._id.toString(),
passwordToken:token,//this will need in
later
});
})
.catch((err) => {
console.log(err);
});
};
10th=> Adding the logic to
update the password
Do the changes in new password form -> adding the password
token (both view and get controller field)
set the routes in router
router.post("/new-password", authController.postNewPassword);
Add the controller
exports.postNewPassword = (req, res, next) => {
const newPassword = req.body.password;//extract the data from the form
const userId = req.body.userId;
const passwordToken = req.body.passwordToken;
let resetUser;
User.findOne({
resetToken: passwordToken,
resetTokenExpire: { $gt: Date.now() },
_id: userId,
}) //only allowed users are both conditions are
matching
.then((user) => {
resetUser = user;
return bcrypt.hash(newPassword, 12);
})
.then((hashedpass) => {
resetUser.password = hashedpass;
resetUser.resetToken = undefined;
resetUser.resetTokenExpire = undefined;
resetUser.save();
})
.then((result) => {
res.redirect("/login");
})
.catch((err) => {
console.log(err);
});
};
Yes Finally...!!!! 😊🙏

0 Comments