From f1e523e21a7bfb703d8104bdec4faff0cefe47b5 Mon Sep 17 00:00:00 2001 From: prajwal2431 Date: Wed, 8 Jan 2025 21:16:33 +0530 Subject: [PATCH] OTP function enhancement with SQL events --- config/dbQuery.sql | 18 +++++++++++++++++- login-system/dbServer.js | 2 +- login-system/login.js | 12 +++--------- login-system/otp.js | 35 ++--------------------------------- public/password_reset.html | 3 ++- 5 files changed, 25 insertions(+), 45 deletions(-) diff --git a/config/dbQuery.sql b/config/dbQuery.sql index 6020722..4a9b8a2 100644 --- a/config/dbQuery.sql +++ b/config/dbQuery.sql @@ -16,7 +16,7 @@ CREATE TABLE user_table ( email VARCHAR(80) NOT NULL UNIQUE, password VARCHAR(140) NOT NULL UNIQUE, otp VARCHAR(6) DEFAULT NULL,-- Add the otp column to store OTP values - otp_expiry BIGINT DEFAULT NULL -- Column for storing OTP expiration (Unix timestamp) + otp_created_at TIMESTAMP DEFAULT NULL -- Add timestamp to track OTP creation ); -- Create the info_table @@ -76,3 +76,19 @@ CREATE TABLE upload_file_db ( FOREIGN KEY (fac_mail) REFERENCES faculty(email) ON DELETE CASCADE, FOREIGN KEY (userid) REFERENCES info_table(id) ON DELETE CASCADE ); + +-- Create a MySQL Event to handle OTP expiration +DELIMITER $$ + +CREATE EVENT IF NOT EXISTS otp_expiry_event +ON SCHEDULE EVERY 1 MINUTE -- Runs every minute +DO +BEGIN + -- Delete expired OTPs (older than 5 minutes) from user_table + DELETE FROM user_table + WHERE otp IS NOT NULL + AND otp_created_at IS NOT NULL + AND TIMESTAMPDIFF(MINUTE, otp_created_at, CURRENT_TIMESTAMP) > 2; +END$$ + +DELIMITER ; \ No newline at end of file diff --git a/login-system/dbServer.js b/login-system/dbServer.js index 6eb7366..bb37f12 100644 --- a/login-system/dbServer.js +++ b/login-system/dbServer.js @@ -129,7 +129,7 @@ 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); +app.post("/reset", reset); // approval by stakeholder app.get("/approval", approve); diff --git a/login-system/login.js b/login-system/login.js index 8d81cba..cd2576f 100644 --- a/login-system/login.js +++ b/login-system/login.js @@ -119,20 +119,14 @@ const reset = async (req, res) => { } const userOtp = result[0].otp; - const otpExpiry = result[0].otp_expiry; + const otpExpiry = result[0].otp_created_at; if (otp !== userOtp || !userOtp) { return res.status(400).json({ success: false, message: 'Invalid OTP' }); } - // Check OTP expiry - if (Date.now() > otpExpiry) { - // Expired: Clear OTP and expiry in the database - const clearOtpQuery = 'UPDATE user_table SET otp = NULL, otp_expiry = NULL WHERE email = ?'; - await connection.query(clearOtpQuery, [email]); - - return res.status(400).json({ success: false, message: 'OTP has expired' }); - } + // At this point, the OTP is valid, and the SQL event will handle expiration. + // Proceed with resetting the password and clearing the OTP. const hashpassword = await bcrypt.hash(password, 10); const resetQuery = 'UPDATE user_table SET otp = NULL, otp_expiry = NULL, password = ? WHERE email = ?'; diff --git a/login-system/otp.js b/login-system/otp.js index 20ebe88..ea849a8 100644 --- a/login-system/otp.js +++ b/login-system/otp.js @@ -30,18 +30,6 @@ const sendOtp = async (req, res) => { connection = await connectToDB(); console.log("Connected to the database"); - // Clear expired OTPs for this user - const clearExpiredOtpQuery = 'UPDATE user_table SET otp = NULL, otp_expiry = NULL WHERE otp_expiry < ?'; - await connection.query(clearExpiredOtpQuery, [Date.now()]); - - // // Check if a valid OTP already exists - // const checkExistingOtpQuery = "SELECT otp_expiry FROM user_table WHERE email = ? AND otp_expiry > ?"; - // const [existingOtp] = await connection.query(checkExistingOtpQuery, [email, Date.now()]); - - // if (existingOtp.length > 0) { - // return res.status(400).send({ message: "An OTP is already active. Please wait for it to expire." }); - // } - // Search for the user in the database const sqlSearch = "SELECT * FROM user_table WHERE email = ?"; const [result] = await connection.query(sqlSearch, [email]); @@ -60,28 +48,9 @@ const sendOtp = async (req, res) => { digits: true // Include digits });; console.log(verifyCode); - const expirationTime = Date.now() + 2 * 60 * 1000; // 2 minutes - - const otpQuery = "UPDATE user_table SET otp = ?, otp_expiry = ? WHERE email = ?"; - await connection.query(otpQuery, [verifyCode,expirationTime, email]); - - // Schedule immediate cleanup after 2 minutes - setTimeout(async () => { - let timeoutConnection; - try { - timeoutConnection = await connectToDB(); - await timeoutConnection.query( - 'UPDATE user_table SET otp = NULL, otp_expiry = NULL WHERE email = ? AND otp_expiry < ?', - [email, Date.now()] - ); - console.log(`Expired OTP cleared for ${email}`); - } catch (err) { - console.error(`Error clearing OTP for ${email}:`, err); - } finally { - if (timeoutConnection) timeoutConnection.release(); - } - }, 2 * 60 * 1000); + const otpQuery = "UPDATE user_table SET otp = ? WHERE email = ?"; + await connection.query(otpQuery, [verifyCode, email]); // Send OTP via notification (could be an email or any other method) notify(req, res, email, "Email Verification", `This is your OTP to verify your email: ${verifyCode}`); diff --git a/public/password_reset.html b/public/password_reset.html index 72dc3c2..aa2d042 100644 --- a/public/password_reset.html +++ b/public/password_reset.html @@ -68,10 +68,11 @@

Enter Invalid email domain. Please use Gmail, Outlook, Yahoo, Protonmail, Icloud, or Tutanota. + - +