Skip to content

Commit

Permalink
OTP function enhancement with SQL events
Browse files Browse the repository at this point in the history
  • Loading branch information
prajwal2431 committed Jan 8, 2025
1 parent 8cf956a commit f1e523e
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 45 deletions.
18 changes: 17 additions & 1 deletion config/dbQuery.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ;
2 changes: 1 addition & 1 deletion login-system/dbServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 3 additions & 9 deletions login-system/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ?';
Expand Down
35 changes: 2 additions & 33 deletions login-system/otp.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand All @@ -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}`);
Expand Down
3 changes: 2 additions & 1 deletion public/password_reset.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ <h4 style="text-align: center; margin: 6px 0px 10px 0px;font-size: 22px;">Enter
<span id="error-message" class="error">Invalid email domain. Please use Gmail, Outlook, Yahoo, Protonmail, Icloud, or Tutanota.</span>

<!-- Validation code field -->
<button type="button" id="validate-email-btn">Send Validation Code</button>
<label for="validation-code">Validation Code:</label>
<input type="text" id="validation-code" placeholder="Enter validation code" disabled>
<p id="otp-timer" style="color: red; display: none;">Please wait <span id="timer">120</span> seconds before requesting another OTP.</p>
<button type="button" id="validate-email-btn">Send Validation Code</button>


<!-- Password field -->
<label for="password">New Password:</label>
Expand Down

0 comments on commit f1e523e

Please sign in to comment.