Skip to content

Commit

Permalink
Merge pull request #411 from Sourabh782/forgot
Browse files Browse the repository at this point in the history
Added otp based forgot password implementation
  • Loading branch information
Harshdev098 authored Nov 9, 2024
2 parents 6674bd4 + b1924c7 commit ed207d6
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 60 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ Follow these steps to run the Research Nexas
userid INT auto_increment unique primary key,
username varchar(60) not null,
email varchar(80) not null unique,
password varchar(140) not null unique
password varchar(140) not null unique,
otp varchar(15)
);
```
```
Expand Down
5 changes: 4 additions & 1 deletion login-system/dbServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const db = require('../config/mysql_connection')

const { stk_signup, stk_signin } = require("../stakeholder/login");
const { info, check } = require("../file_upload/form_db");
const { signup, signin } = require("./login");
const { signup, signin, reset } = require("./login");
const rateLimiter = require("express-rate-limit");
const { approve, uploadedpapers, displaydetail } = require("../stakeholder/stk_approval");
const { saveNewsLetterData } = require("../backend/newsLetter");
Expand All @@ -15,6 +15,7 @@ const { logout } = require("./logout");
const { setcriteria, evaluate } = require("../stakeholder/evaluation");
const { allot, DisplayPapers } = require("../stakeholder/allotment");
const { Dis_fac_papers, fac_signup, fac_login, dis_mail, giverating } = require("../stakeholder/faculty");
const { sendOtp } = require("./otp");
const app = express();

const globalLimit = rateLimiter({
Expand Down Expand Up @@ -131,6 +132,8 @@ app.post("/fac_signup", fac_signup); // registration of faculty
app.post("/login", signin);
app.post("/stk_holder_signin", stk_signin);
app.post("/fac_login", fac_login); //login for faculty
app.post("/sendotp", sendOtp)
app.post("/resetpassword", reset);

// approval by stakeholder
app.get("/approval", approve);
Expand Down
43 changes: 41 additions & 2 deletions login-system/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const signup=async (req, res) => {
const sqlSearch = "SELECT * FROM user_table WHERE email=? OR username=?";
const search_query = mysql.format(sqlSearch, [email,username])

const sqlinsert = "INSERT INTO user_table VALUES (0,?,?,?)"
const sqlinsert = "INSERT INTO user_table VALUES (0,?,?,?,'')"
const insert_query = mysql.format(sqlinsert, [username, email, hashpassword])
await connection.query(search_query, async (err, result) => {
if (err) throw (err)
Expand Down Expand Up @@ -117,8 +117,47 @@ const signin=(req, res) => {
})
}

const reset=(req, res)=>{
const email = req.body.email.trim()
const password = req.body.password.trim();
const otp = req.body.otp.trim();
db.getConnection(async (err, connection) => {
if (err) throw (err)
const sqlSearch = "Select * from user_table where email=?"
const search_query = mysql.format(sqlSearch, [email])
await connection.query(search_query, async (err, result) => {
if (err) throw (err)
if (result.length == 0) {
console.log("User does not exist")
res.sendStatus(404)
}
else {
// console.log(result);
const userOtp = result[0].otp

if(otp !== userOtp || userOtp.length === 0){
return res.status(400).json({success: false, message: "Invalid otp"})
}

const hashpassword = await bcrypt.hash(password, 10);

const reset_query = `Update user_table set otp=?, password=? where email=?`
const query = mysql.format(reset_query, ["", hashpassword, email])

await connection.query(query, async (err, result) => {
if(err) throw (err)
})

res.json({ success: true, message: "password reset successfully" })
}
connection.release()
})
})
}

// exporting signup,signin funtion
module.exports={
signup : [signupRateLimiter,signup],
signin : [signinRateLimiter,signin]
signin : [signinRateLimiter,signin],
reset
}
2 changes: 1 addition & 1 deletion login-system/notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ const notify=(req,res,email,sub,content)=>{
});
}

module.exports=notify;
module.exports = notify;
54 changes: 54 additions & 0 deletions login-system/otp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const mysql = require('mysql')
const bcrypt = require('bcrypt')
const {generateAccessToken}=require('./token');
const notify = require('./notification');
const rateLimit = require('express-rate-limit')
require("dotenv").config()
const db = require('../config/mysql_connection')
const nodemailer = require("nodemailer");

// connecting database to the server
db.getConnection((err, connection) => {
if (err) throw err;
console.log("Database Connected Successfully")
})

const sendOtp = (req, res)=>{
const email = req.body.email;
console.log(email);


db.getConnection(async (err, connection) => {
if (err) throw (err)
const sqlSearch = "Select * from user_table where email=?"

const search_query = mysql.format(sqlSearch, [email])
await connection.query(search_query, async (err, result) => {
if (err) throw (err)
if (result.length == 0) {
console.log("User does not exist")
res.sendStatus(404)
}
else {
const verifyCode = Math.floor(100000 + Math.random() * 900000).toString();

const otp_query = `Update user_table set otp=? where email=?`
const query = mysql.format(otp_query, [verifyCode, email])

await connection.query(query, async (err, result) => {
if(err) throw (err)
})

notify(req, res, email, "Email Verification", `This is otp to verify your email: ${verifyCode}`);

return res.send({message: "otp sent successfully"})
}
connection.release()
})
})
}

// exporting signup,signin funtion
module.exports={
sendOtp
}
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"mailgun-js": "^0.22.0",
"multer": "^1.4.5-lts.1",
"mysql": "^2.18.1",
"nodemailer": "^6.9.8",
"nodemailer": "^6.9.16",
"sih_project_2": "file:"
},
"devDependencies": {
Expand Down
85 changes: 35 additions & 50 deletions public/password_reset.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@
}

/* Disable the password and reset button initially */
#password,
#reset-password-btn {
opacity: 0.5;
pointer-events: none;
}

</style>
</head>

Expand All @@ -64,7 +60,7 @@ <h4 style="text-align: center; margin: 6px 0px 10px 0px;font-size: 22px;">Enter
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="Enter your email" required>
<span id="error-message" class="error">Invalid email domain. Please use Gmail, Outlook, Yahoo, Protonmail, Icloud, or Tutanota.</span>

<!-- Validation code field -->
<label for="validation-code">Validation Code:</label>
<input type="text" id="validation-code" placeholder="Enter validation code" disabled>
Expand Down Expand Up @@ -120,17 +116,30 @@ <h4 style="text-align: center; margin: 6px 0px 10px 0px;font-size: 22px;">Enter
// Validate email and send code
validateEmailBtn.addEventListener('click', async function () {
const emailValue = emailInput.value;
console.log(emailValue);

const emailDomain = emailValue.split('@')[1];

if (emailDomain && allowedDomains.includes(emailDomain.toLowerCase())) {
emailInput.classList.add('valid');
errorMessage.style.display = 'none';

// sending otp
const response = await fetch('/sendotp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: emailValue }),
});

// Simulate sending validation code (you should replace this with actual backend logic)
validationCodeInput.disabled = false;
passwordInput.disabled = false
resetPasswordBtn.disabled = false;
alert("A validation code has been sent to your email!");

// Enable validation code input
validationCodeInput.disabled = false;

} else {
emailInput.classList.add('invalid');
Expand All @@ -139,24 +148,30 @@ <h4 style="text-align: center; margin: 6px 0px 10px 0px;font-size: 22px;">Enter
});

// Validate the entered code
validationCodeInput.addEventListener('input', function () {
resetPasswordBtn.addEventListener('click', async function (e) {
// Simulate code validation (replace with backend logic)
if (validationCodeInput.value === "123456") { // Sample validation code for demonstration
emailValidated = true;
// /resetpassword
e.preventDefault()
const emailValue = emailInput.value;
const password = passwordInput.value;
const otp = validationCodeInput.value;

// Enable password input and reset button
passwordInput.disabled = false;
resetPasswordBtn.style.opacity = '1';
resetPasswordBtn.style.pointerEvents = 'auto';
const response = await fetch('/resetpassword', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: emailValue, password, otp }),
});

} else {
emailValidated = false;
console.log(response);

if(!response.ok){

// Disable password input and reset button if the code is incorrect
passwordInput.disabled = true;
resetPasswordBtn.style.opacity = '0.5';
resetPasswordBtn.style.pointerEvents = 'none';
}

alert('Password reset successfully!');
window.location.href = 'login.html';
});

// Password criteria validation
Expand Down Expand Up @@ -194,36 +209,6 @@ <h4 style="text-align: center; margin: 6px 0px 10px 0px;font-size: 22px;">Enter
}
});

document.getElementById('resetForm').addEventListener('submit', async function (event) {
event.preventDefault();

let email = document.getElementById('email').value;
let password = document.getElementById('password').value;

if (!emailValidated) {
alert('Please validate your email first!');
return;
}

try {
const response = await fetch('http://localhost:5000/reset_password', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});

if (response.ok) {
alert('Password reset successfully!');
window.location.href = 'login.html';
} else {
alert('Error resetting password. Please try again.');
}
} catch (error) {
console.error('Error:', error);
}
});
});
</script>
</body>
Expand Down

0 comments on commit ed207d6

Please sign in to comment.