Added Verify Email, Send OTP , GET OTP , Forgot password , Reset Password

This commit is contained in:
yashrajverma 2021-05-16 16:01:39 +05:30
parent 3636c85a41
commit 803a68f3e0
11 changed files with 2651 additions and 56 deletions

View File

@ -3,8 +3,26 @@ const User = require("../models/User");
const Student = require("../models/Student"); const Student = require("../models/Student");
const jwt = require("jsonwebtoken"); const jwt = require("jsonwebtoken");
const JWT_secret = "Cantileverlabs"; const JWT_secret = "Cantileverlabs";
const messagebird = require("messagebird")("llVKD53ve6QRpbCKOHzWBADaS"); const messagebird = require("messagebird")("llVKD53ve6QRpbCKOHzWBADaS", null, [
"ENABLE_CONVERSATIONSAPI_WHATSAPP_SANDBOX",
]);
const nodemailer = require("nodemailer"); const nodemailer = require("nodemailer");
const smtpTransport = require("nodemailer-smtp-transport");
// -------------------------------------------- mail transporter -----------------------------------------
var transport = nodemailer.createTransport(
smtpTransport({
host: "email-smtp.us-east-1.amazonaws.com", //`${process.env.HOST}`
port: 465,
auth: {
user: "AKIA2G7743RRTZMVXE3X", //`${process.env.EMAIL}`
pass: "BJSjV3jArJfsnk1LhFc/hUmisEyEtbLNGgrRbv0noh8c", //`${process.env.PASS}`
},
})
);
// -------------------------------------------- mail transporter -----------------------------------------
module.exports.Protected = async (req, res, next) => { module.exports.Protected = async (req, res, next) => {
res.send("Hello User"); res.send("Hello User");
@ -14,8 +32,7 @@ module.exports.postSignup = async (req, res, next) => {
//we need firstName , lastName , email , password as input //we need firstName , lastName , email , password as input
let firstName = req.body.firstName || " "; let firstName = req.body.firstName || " ";
let lastName = req.body.lastName || " "; let lastName = req.body.lastName || " ";
let email = req.body.email; const { sending_company_email, email, password, subject, _html } = req.body;
let password = req.body.password;
let user = await User.findOne({ email: email }); let user = await User.findOne({ email: email });
if (user) { if (user) {
res.json({ res.json({
@ -23,6 +40,8 @@ module.exports.postSignup = async (req, res, next) => {
type: "error", type: "error",
}); });
} else { } else {
const email_otp = Math.floor(100000 + Math.random() * 900000);
console.log("otp", email_otp);
const hashedPass = await bcrypt.hash(password, 12); const hashedPass = await bcrypt.hash(password, 12);
user = new User({ user = new User({
firstName: firstName, firstName: firstName,
@ -30,6 +49,7 @@ module.exports.postSignup = async (req, res, next) => {
email: email, email: email,
password: hashedPass, password: hashedPass,
isAdmin: false, isAdmin: false,
email_otp,
}); });
user = await user.save(); user = await user.save();
await Student.deleteOne({ user: user._id }); await Student.deleteOne({ user: user._id });
@ -39,8 +59,21 @@ module.exports.postSignup = async (req, res, next) => {
student = await student.save(); student = await student.save();
user.student = student._id; user.student = student._id;
await user.save(); await user.save();
const message = {
from: `${sending_company_email}`, // Sender address
to: `${email}`, // List of recipients
subject: `${subject}`, // Subject line
html: `${_html}`, // design html for email message.
};
transport.sendMail(message, function (err, info) {
if (err) {
console.log(err);
} else {
console.log(info);
}
});
res.json({ res.json({
message: "Successfully signed Up", message: "OTP has sent to the Email",
type: "success", type: "success",
}); });
} }
@ -49,6 +82,43 @@ module.exports.postSignup = async (req, res, next) => {
} }
}; };
module.exports.verfiyemail = async (req, res, next) => {
const { email, otp } = req.body;
try {
let user = await User.findOne({ email: email });
if (user) {
const isMatched = await (user.email_otp == otp ? true : false);
if (isMatched) {
if (!user.isVerified) {
user.isVerified = true;
await user.save();
res.json({
message: "User Verified, Please Login",
});
} else {
res.json({
message: "User Already Verified, Please Login",
});
}
} else {
res.json({
message: "OTP Doesn't Matched!",
type: "error",
});
}
} else {
res.json({
message: "No user with this email exists",
type: "error",
});
}
} catch {
(err) => {
console.log(err);
};
}
};
module.exports.postSignin = async (req, res, next) => { module.exports.postSignin = async (req, res, next) => {
try { try {
//we need email and password as input //we need email and password as input
@ -85,8 +155,8 @@ module.exports.postSignin = async (req, res, next) => {
module.exports.sendOTP = (req, res, next) => { module.exports.sendOTP = (req, res, next) => {
//uNNYosMopvvCW9RTR1tRWJmYC test //uNNYosMopvvCW9RTR1tRWJmYC test
//llVKD53ve6QRpbCKOHzWBADaS live //llVKD53ve6QRpbCKOHzWBADaS live
const { phoneNumber } = req.body;
try { try {
const { phoneNumber } = req.body;
if (!phoneNumber) { if (!phoneNumber) {
res.status(422).json({ message: "Please Add All Required Fields" }); res.status(422).json({ message: "Please Add All Required Fields" });
return; return;
@ -132,17 +202,10 @@ module.exports.getOTP = (req, res, next) => {
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
// Email verification Starts // Forgot password Starts
var transport = nodemailer.createTransport({
service: "gmail",
auth: {
user: "5578544cc56856", //replace it with the companies mail
pass: "a510d3d969d3b3", //replace it with the companies pass
},
});
module.exports.forgotpassword = async (req, res, next) => { module.exports.forgotpassword = async (req, res, next) => {
const { email, link, _html, sending_company_email, subject } = req.body; const { email, link, sending_company_email, subject } = req.body;
//link = https://cantileverlabs.herokuapp.com/resetpassword/:id/:token //link = https://cantileverlabs.herokuapp.com/resetpassword/:id/:token
try { try {
await User.findOne({ email }).then((user) => { await User.findOne({ email }).then((user) => {
@ -161,11 +224,159 @@ module.exports.forgotpassword = async (req, res, next) => {
}) })
.then((data) => { .then((data) => {
const reset_link = `${link}/${user._id}/${token}`; const reset_link = `${link}/${user._id}/${token}`;
const message = { const message = {
from: `${sending_company_email}`, // Sender address from: `${sending_company_email}`, // Sender address
to: `${user.email}`, // List of recipients to: `${user.email}`, // List of recipients
subject: `${subject}`, // Subject line subject: `${subject}`, // Subject line
html: `${_html}`, // design html for email message. html: `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0 shrink-to-fit=no"
/>
<title>Forgot password</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="./reset.css" />
<link
href="https://fonts.googleapis.com/css?family=Poppins"
rel="stylesheet"
/>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700;800&display=swap"
rel="stylesheet"
/>
<style>
body {
font-size: 16px;
font-family: Poppins;
letter-spacing: 0.02em;
}
.gray-reset-J {
background-color: #f2f7fb;
}
.reset-J h2 {
font-weight: 600;
}
.reset-J p {
font-weight: lighter;
font-size: 20px;
}
.reset-J button {
background-color: #ffc600;
color: white;
font-weight: 600;
font-size: 19px;
width: 340px;
border-radius: 10px 10px 10px 10px;
}
.reset-logo-J img {
width: 79px;
height: 79px;
}
.reset-logo1-J img {
width: 200px;
height: 50px;
}
.reset-logo2-J img {
width: 17px;
height: 17px;
}
.reset-light-J p {
font-size: 15px;
}
.light-copyright-J {
font-weight: lighter;
color: #6d6d6d;
}
.bold-copyright-J {
font-weight: 700;
color: #6d6d6d;
}
@media (max-width: 410px) {
.reset-J button {
width: 240px;
background-color: #ffc600;
color: white;
font-weight: 600;
font-size: 19px;
border-radius: 10px 10px 10px 10px;
}
}
</style>
</head>
<body>
<div class="container justify-content-center">
<div class="row justify-content-center">
<div
class="
m-5
px-5
py-4
gray-reset-J
col-xl-6 col-lg-6 col-md-8 col-sm-11 col-12
"
>
<div class="my-3 reset-logo-J">
<img src="./images/certificate design-11.png" alt="" />
</div>
<div class="reset-J">
<div class="my-4">
<h2 style="text-align: center">Hello</h2>
</div>
<p>
We got a request to reset your Password. No need to worry you can
reset your Password by clicking the Reset Button.
</p>
<a href=${reset_link}> <button class="btn p-3 my-3">Reset Password</button></a>
<div class="my-3">
<p>
Facing any other issue write us at
<a href="#">info@cantileverlabs.com</a>
</p>
</div>
<div class="my-4 reset-logo1-J">
<img src="./images/Rectangle 1048.png" alt="" />
</div>
<div class="reset-light-J">
<p>Privacy Policy | Terms of Use | Contact us</p>
</div>
</div>
<div class="reset-logo2-J my-5">
<img src="./images/Icon material-copyright.png" alt="" />
<span class="light-copyright-J"
>copyright
<span class="bold-copyright-J">2018 Cantilever Labs</span></span
>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
`, // design html for email message.
}; };
transport.sendMail(message, function (err, info) { transport.sendMail(message, function (err, info) {
if (err) { if (err) {
@ -175,7 +386,7 @@ module.exports.forgotpassword = async (req, res, next) => {
} }
}); });
res.status(200).json({ res.status(200).json({
message: "Token Saved and link is active for 10 mins", message: "Link is Active for 10 mins",
reset_link, reset_link,
}); });
}) })
@ -225,7 +436,7 @@ module.exports.resetpassword = async (req, res, next) => {
} }
}; };
// Email verification Ends // Forgot password Ends
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
module.exports.checkProtected = (req, res, next) => { module.exports.checkProtected = (req, res, next) => {

View File

@ -28,9 +28,13 @@ const userSchema = new Schema({
isAdmin: { isAdmin: {
type: Boolean, type: Boolean,
}, },
otp: { email_otp: {
type: String, type: String,
}, },
isVerified: {
type: Boolean,
default: false,
},
passwordResetToken: String, passwordResetToken: String,
passwordResetExpires: Date, passwordResetExpires: Date,
//need to add isAdmin //need to add isAdmin

2234
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
"name": "cantilever-labs", "name": "cantilever-labs",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "index.js", "main": "app.js",
"scripts": { "scripts": {
"start:dev": "nodemon app.js", "start:dev": "nodemon app.js",
"start": "node app.js" "start": "node app.js"
@ -10,6 +10,7 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"aws-sdk": "^2.907.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"cookie-session": "^1.4.0", "cookie-session": "^1.4.0",
@ -17,10 +18,14 @@
"crypto": "^1.0.1", "crypto": "^1.0.1",
"dotenv": "^9.0.1", "dotenv": "^9.0.1",
"express": "^4.17.1", "express": "^4.17.1",
"grandjs": "^2.2.30",
"handlebars": "^4.7.7",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"messagebird": "^3.6.1", "messagebird": "^3.6.1",
"mongoose": "^5.12.2", "mongoose": "^5.12.2",
"nodemailer": "^6.6.0", "nodemailer": "^6.6.0",
"nodemailer-express-handlebars": "^4.0.0",
"nodemailer-smtp-transport": "^2.7.4",
"passport": "^0.4.1", "passport": "^0.4.1",
"passport-google-oauth": "^2.0.0", "passport-google-oauth": "^2.0.0",
"razorpay": "^2.0.6", "razorpay": "^2.0.6",

View File

@ -17,6 +17,6 @@ router.post("/forgotpassword", authController.forgotpassword);
router.post("/resetpassword/:_id/:token", authController.resetpassword); router.post("/resetpassword/:_id/:token", authController.resetpassword);
router.get("/resetpassword/:_id/:token", authController.resetpassword); router.post("/verifyemail", authController.verfiyemail);
module.exports = router; module.exports = router;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

66
views/reset.css Normal file
View File

@ -0,0 +1,66 @@
body {
font-size: 16px;
font-family: Poppins;
letter-spacing: 0.02em;
}
.gray-reset-J {
background-color: #f2f7fb;
}
.reset-J h2 {
font-weight: 600;
}
.reset-J p {
font-weight: lighter;
font-size: 20px;
}
.reset-J button {
background-color: #ffc600;
color: white;
font-weight: 600;
font-size: 19px;
width: 340px;
border-radius: 10px 10px 10px 10px;
}
.reset-logo-J img {
width: 79px;
height: 79px;
}
.reset-logo1-J img {
width: 200px;
height: 50px;
}
.reset-logo2-J img {
width: 17px;
height: 17px;
}
.reset-light-J p {
font-size: 15px;
}
.light-copyright-J {
font-weight: lighter;
color: #6d6d6d;
}
.bold-copyright-J {
font-weight: 700;
color: #6d6d6d;
}
@media (max-width: 410px) {
.reset-J button {
width: 240px;
background-color: #ffc600;
color: white;
font-weight: 600;
font-size: 19px;
border-radius: 10px 10px 10px 10px;
}
}

147
views/reset.html Normal file
View File

@ -0,0 +1,147 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0 shrink-to-fit=no"
/>
<title>Forgot password</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="./reset.css" />
<link
href="https://fonts.googleapis.com/css?family=Poppins"
rel="stylesheet"
/>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700;800&display=swap"
rel="stylesheet"
/>
<style>
body {
font-size: 16px;
font-family: Poppins;
letter-spacing: 0.02em;
}
.gray-reset-J {
background-color: #f2f7fb;
}
.reset-J h2 {
font-weight: 600;
}
.reset-J p {
font-weight: lighter;
font-size: 20px;
}
.reset-J button {
background-color: #ffc600;
color: white;
font-weight: 600;
font-size: 19px;
width: 340px;
border-radius: 10px 10px 10px 10px;
}
.reset-logo-J img {
width: 79px;
height: 79px;
}
.reset-logo1-J img {
width: 200px;
height: 50px;
}
.reset-logo2-J img {
width: 17px;
height: 17px;
}
.reset-light-J p {
font-size: 15px;
}
.light-copyright-J {
font-weight: lighter;
color: #6d6d6d;
}
.bold-copyright-J {
font-weight: 700;
color: #6d6d6d;
}
@media (max-width: 410px) {
.reset-J button {
width: 240px;
background-color: #ffc600;
color: white;
font-weight: 600;
font-size: 19px;
border-radius: 10px 10px 10px 10px;
}
}
</style>
</head>
<body>
<div class="container justify-content-center">
<div class="row justify-content-center">
<div
class="
m-5
px-5
py-4
gray-reset-J
col-xl-6 col-lg-6 col-md-8 col-sm-11 col-12
"
>
<div class="my-3 reset-logo-J">
<img src="./images/certificate design-11.png" alt="" />
</div>
<div class="reset-J">
<div class="my-4">
<h2 style="text-align: center">Hello</h2>
</div>
<p>
We got a request to reset your Password. No need to worry you can
reset your Password by clicking the Reset Button.
</p>
<a href=""> <button class="btn p-3 my-3">Reset Password</button></a>
<div class="my-3">
<p>
Facing any other issue write us at
<a href="#">info@cantileverlabs.com</a>
</p>
</div>
<div class="my-4 reset-logo1-J">
<img src="./images/Rectangle 1048.png" alt="" />
</div>
<div class="reset-light-J">
<p>Privacy Policy | Terms of Use | Contact us</p>
</div>
</div>
<div class="reset-logo2-J my-5">
<img src="./images/Icon material-copyright.png" alt="" />
<span class="light-copyright-J"
>copyright
<span class="bold-copyright-J">2018 Cantilever Labs</span></span
>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>