Skip to content

Commit

Permalink
Merge pull request #526 from haseebzaki-07/new_branch_9
Browse files Browse the repository at this point in the history
Add email verification
  • Loading branch information
dhairyagothi authored Nov 7, 2024
2 parents bb887ac + 7a80621 commit 39b420b
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 6 deletions.
87 changes: 81 additions & 6 deletions backend/controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import User from '../models/User.js';
import crypto from 'crypto'; // For generating OTP
import nodemailer from 'nodemailer';
import { hashPassword, comparePassword, generateToken, verifyToken, addCookie, getCookies, removeCookie } from '../utils/authFunctions.js';

export const registerUser = async (req, res) => {
Expand All @@ -19,45 +21,118 @@ export const registerUser = async (req, res) => {
return res.status(400).json({ error: 'User already exists' });
}

const otp = crypto.randomInt(100000, 999999).toString(); // Generate OTP (6 digits)

if (isGoogle == true) {
const newUser = new User({
name,
email,
phoneNumber: phoneNumber ? phoneNumber : '',
password: ''
password: '',
otp: otp,
otpExpiry: Date.now() + 3600000, // OTP expires in 1 hour
});

await newUser.save();

const token = await generateToken(newUser._id);
await sendOtpEmail(email, otp); // Send OTP to the user's email

const token = await generateToken(newUser._id);
addCookie(res, 'token', token);

return res.status(201).json({ message: 'User registered successfully', userId: newUser._id , token: token });
return res.status(201).json({
message: 'User registered successfully. Please check your email for the OTP to verify your email.',
userId: newUser._id,
token: token,
});
} else {
const hashedPassword = await hashPassword(password);

const newUser = new User({
name,
email,
phoneNumber: phoneNumber ? phoneNumber : '',
password: hashedPassword
password: hashedPassword,
otp: otp,
otpExpiry: Date.now() + 3600000, // OTP expires in 1 hour
});

await newUser.save();

const token = await generateToken(newUser._id);
await sendOtpEmail(email, otp); // Send OTP to the user's email

const token = await generateToken(newUser._id);
addCookie(res, 'token', token);

res.status(201).json({ message: 'User registered successfully', userId: newUser._id, token: token });
res.status(201).json({
message: 'User registered successfully. Please check your email for the OTP to verify your email.',
userId: newUser._id,
token: token,
});
}
} catch (error) {
console.error(error);
res.status(500).json({ error: error.message || 'Internal Server Error' });
}
};

const sendOtpEmail = async (userEmail, otp) => {
try {
const transporter = nodemailer.createTransport({
service: 'gmail', // Or use another email provider
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});

const mailOptions = {
from: process.env.EMAIL_USER,
to: userEmail,
subject: 'Email Verification - Station Sarthi',
text: `Your OTP for email verification is: ${otp}`,
};

await transporter.sendMail(mailOptions);
} catch (error) {
console.error('Error sending email:', error);
throw new Error('Failed to send OTP');
}
};

export const verifyOtp = async (req, res) => {
try {
const { email, otp } = req.body;

const user = await User.findOne({ email });
if (!user) {
return res.status(404).json({ error: 'User not found' });
}

// Check if OTP has expired
if (Date.now() > user.otpExpiry) {
return res.status(400).json({ error: 'OTP has expired' });
}

// Check if OTP is correct
if (user.otp !== otp) {
return res.status(400).json({ error: 'Invalid OTP' });
}

// OTP is correct, mark user as verified
user.isVerified = true;
user.otp = null; // Clear OTP after verification
user.otpExpiry = null; // Clear OTP expiry after verification
await user.save();

res.status(200).json({ message: 'Email verified successfully' });
} catch (error) {
console.error(error);
res.status(500).json({ error: error.message || 'Internal Server Error' });
}
};


export const loginUser = async (req, res) => {
try {
const { email, password } = req.body;
Expand Down
4 changes: 4 additions & 0 deletions backend/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ const userSchema = new Schema({
otpExpiry: {
type: Date, // The OTP expiry timestamp
required: false,
},
isVerified: {
type: Boolean,
default: false, // This field will be set to true once the email is verified
}
}, {
timestamps: true
Expand Down
3 changes: 3 additions & 0 deletions backend/routes/authRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
loginUser,
logoutUser,
verifyUser,
verifyOtp,
} from "../controllers/authController.js";
import { createCloakroomBooking } from "../controllers/cloakroomController.js";
import { createWheelchairBooking } from "../controllers/WheelchairController.js";
Expand All @@ -24,6 +25,8 @@ const loginLimiter = rateLimit({
// Register route
router.post("/register", registerUser);

router.post("/verify-otp", verifyOtp);

// Login route with rate limiter
router.post("/login", loginLimiter, loginUser);

Expand Down

0 comments on commit 39b420b

Please sign in to comment.