diff --git a/README.md b/README.md
index 361f5b6..73d5ed3 100644
--- a/README.md
+++ b/README.md
@@ -108,7 +108,16 @@ Welcome to Foodies, your go-to college dining companion! Designed for seamless c
```
PORT=3000
DATABASE_URL="http://localhost:21713/foods"
+ EMAIL="The email from which forgot the password email will be sent"
+ MAILPASS="password for the email ( app password )"
```
+ ### **STEP TO GENERATE APP PASSWORD**
+ 1) Enable 2-step verification if not
+ **In https://myaccount.google.com/security, do you see 2-step verification set to ON**
+
+ 2) Generate APP PASSWORD by clicking on below link
+ **https://myaccount.google.com/apppasswords?rapt=AEjHL4PAhcbtFEpLwfNtVix3bfiGe71GdrW_Naiuvp_NVnMZyTd0UR07M2mVnEyWzkw9kB99YVhhfEVtjxTi3QWSZ39biK-zGwnghm0u778vwmlh6TFbmh4**
+
6. **Start the Backend Server (in the terminal within the /server directory):**
In the terminal where you navigated to the /server directory, run the following command to start the backend server:
diff --git a/server/controllers/Auth.js b/server/controllers/Auth.js
index 085ed28..2fa1b24 100644
--- a/server/controllers/Auth.js
+++ b/server/controllers/Auth.js
@@ -3,6 +3,13 @@ const User = require("../models/studentLoginInfo");
const jwt = require("jsonwebtoken");
const Canteen = require("../models/canteenLoginInfo");
const Session = require("../models/session");
+const {
+ forgotPasswordToken,
+ verifyToken,
+ findUserByEmail,
+ findUserById,
+} = require("../utils/PasswordTokenAndUser");
+const nodemailer = require("nodemailer");
require("dotenv").config();
@@ -10,8 +17,16 @@ exports.studentSignup = async (req, res) => {
console.log("This is jwt", process.env.JWT_SECRET);
try {
console.log(req.body);
- const { name, email, collegeName, accountType, password } = await req.body;
- const existingUser = await User.findOne({ email });
+ const {
+ name,
+ email,
+ collegeName,
+ accountType,
+ password,
+ } = await req.body;
+ const existingUser = await User.findOne({
+ email,
+ });
if (existingUser) {
return res.status(400).json({
@@ -23,7 +38,10 @@ exports.studentSignup = async (req, res) => {
let hashedPassword;
try {
- hashedPassword = await bcrypt.hash(password, 10);
+ hashedPassword = await bcrypt.hash(
+ password,
+ 10
+ );
} catch (error) {
console.log(error);
return res.status(500).json({
@@ -81,13 +99,25 @@ exports.studentLogin = async (req, res) => {
accountType: user.accountType,
};
- if (await bcrypt.compare(password, user.password)) {
- let token = jwt.sign(payload, process.env.JWT_SECRET, {
- expiresIn: "2h",
- });
+ if (
+ await bcrypt.compare(
+ password,
+ user.password
+ )
+ ) {
+ let token = jwt.sign(
+ payload,
+ process.env.JWT_SECRET,
+ {
+ expiresIn: "2h",
+ }
+ );
// creating a session
- const session = new Session({ userId: user._id, token });
+ const session = new Session({
+ userId: user._id,
+ token,
+ });
await session.save();
user = user.toObject();
@@ -107,13 +137,18 @@ exports.studentLogin = async (req, res) => {
// message: "User logged in succesfully",
// });
- // Setting cookie
+ // Setting cookie
res.cookie("token", token, {
httpOnly: true,
secure: true,
maxAge: 3600000,
});
- res.json({ success: true, message: "Logged in successfully", token, user });
+ res.json({
+ success: true,
+ message: "Logged in successfully",
+ token,
+ user,
+ });
} else {
return res.status(403).json({
success: false,
@@ -155,13 +190,18 @@ exports.studentLogout = async (req, res) => {
const token =
req.cookies?.token ||
- req?.header("Authorization")?.replace("Bearer ", "");
+ req
+ ?.header("Authorization")
+ ?.replace("Bearer ", "");
if (token) {
await Session.findOneAndDelete({ token });
res.clearCookie("token");
}
- res.status(200).json({ success: true, message: "Logged out successfully" });
+ res.status(200).json({
+ success: true,
+ message: "Logged out successfully",
+ });
} catch (error) {
console.log(error);
return res.status(500).json({
@@ -172,11 +212,17 @@ exports.studentLogout = async (req, res) => {
};
// Controller for changing the student password
-exports.changeStudentPassword = async (req, res) => {
+exports.changeStudentPassword = async (
+ req,
+ res
+) => {
const { oldPassword, newPassword } = req.body;
const user = await User.findById(req.user._id);
- const isPasswordCorrect = await bcrypt.compare(oldPassword, user.password);
+ const isPasswordCorrect = await bcrypt.compare(
+ oldPassword,
+ user.password
+ );
if (!isPasswordCorrect) {
return res.status(400).json({
@@ -185,7 +231,10 @@ exports.changeStudentPassword = async (req, res) => {
});
}
- const newHashedPassword = await bcrypt.hash(newPassword, 10);
+ const newHashedPassword = await bcrypt.hash(
+ newPassword,
+ 10
+ );
user.password = newHashedPassword;
user.save();
@@ -201,8 +250,16 @@ exports.changeStudentPassword = async (req, res) => {
exports.canteenSignup = async (req, res) => {
console.log("Received signup request with data:", req.body);
try {
- const { name, email, collegeName, accountType, password } = req.body;
- const existingCanteen = await Canteen.findOne({ email });
+ const {
+ name,
+ email,
+ collegeName,
+ accountType,
+ password,
+ } = req.body;
+ const existingCanteen = await Canteen.findOne(
+ { email }
+ );
if (existingCanteen) {
console.log("User already exists with email:", email);
@@ -215,7 +272,10 @@ exports.canteenSignup = async (req, res) => {
let hashedPassword;
try {
- hashedPassword = await bcrypt.hash(password, 10);
+ hashedPassword = await bcrypt.hash(
+ password,
+ 10
+ );
} catch (error) {
console.error("Error in hashing password:", error);
return res.status(500).json({
@@ -263,7 +323,9 @@ exports.canteenLogin = async (req, res) => {
});
}
- let canteen = await Canteen.findOne({ email });
+ let canteen = await Canteen.findOne({
+ email,
+ });
if (!canteen) {
return res.status(401).json({
success: false,
@@ -277,10 +339,19 @@ exports.canteenLogin = async (req, res) => {
accountType: canteen.accountType,
};
- if (await bcrypt.compare(password, canteen.password)) {
- let token = jwt.sign(payload, process.env.JWT_SECRET, {
- expiresIn: "2h",
- });
+ if (
+ await bcrypt.compare(
+ password,
+ canteen.password
+ )
+ ) {
+ let token = jwt.sign(
+ payload,
+ process.env.JWT_SECRET,
+ {
+ expiresIn: "2h",
+ }
+ );
canteen = canteen.toObject();
canteen.token = token;
console.log(canteen);
@@ -301,7 +372,10 @@ exports.canteenLogin = async (req, res) => {
// });
// Create session
- const session = new Session({ userId: canteen._id, token });
+ const session = new Session({
+ userId: canteen._id,
+ token,
+ });
await session.save();
// Set cookie
@@ -310,8 +384,13 @@ exports.canteenLogin = async (req, res) => {
secure: true,
maxAge: 3600000,
});
- res.json({ success: true, message: "Logged in successfully", token, canteen, cantId: canteen._id });
-
+ res.json({
+ success: true,
+ message: "Logged in successfully",
+ token,
+ canteen,
+ cantId: canteen._id,
+ });
} else {
return res.status(403).json({
success: false,
@@ -353,13 +432,18 @@ exports.canteenLogout = async (req, res) => {
const token =
req.cookies?.token ||
- req?.header("Authorization")?.replace("Bearer ", "");
+ req
+ ?.header("Authorization")
+ ?.replace("Bearer ", "");
if (token) {
await Session.findOneAndDelete({ token });
res.clearCookie("token");
}
- res.status(200).json({ success: true, message: "Logged out successfully" });
+ res.status(200).json({
+ success: true,
+ message: "Logged out successfully",
+ });
} catch (error) {
console.log(error);
return res.status(500).json({
@@ -370,11 +454,19 @@ exports.canteenLogout = async (req, res) => {
};
// Canteen Reset Password
-exports.changeCanteenPassword = async (req, res) => {
+exports.changeCanteenPassword = async (
+ req,
+ res
+) => {
const { oldPassword, newPassword } = req.body;
- const user = await Canteen.findById(req.user._id);
+ const user = await Canteen.findById(
+ req.user._id
+ );
- const isPasswordCorrect = await bcrypt.compare(oldPassword, user.password);
+ const isPasswordCorrect = await bcrypt.compare(
+ oldPassword,
+ user.password
+ );
if (!isPasswordCorrect) {
return res.status(400).json({
@@ -383,7 +475,10 @@ exports.changeCanteenPassword = async (req, res) => {
});
}
- const newHashedPassword = await bcrypt.hash(newPassword, 10);
+ const newHashedPassword = await bcrypt.hash(
+ newPassword,
+ 10
+ );
user.password = newHashedPassword;
user.save();
@@ -393,3 +488,158 @@ exports.changeCanteenPassword = async (req, res) => {
message: "Password updated successfully.",
});
};
+
+// verify user for reset password
+exports.forgotPassword = async (req, res) => {
+ try {
+ const { email } = req.body;
+ const existingUser = await findUserByEmail(
+ email
+ );
+
+ if (!existingUser) {
+ return res.status(400).json({
+ success: false,
+ message: "User does not exist",
+ });
+ } else {
+ const tokenReturn =
+ forgotPasswordToken(existingUser);
+ // const link = `http://localhost:3000/api/v1/newPassword/${existingUser._id}/${tokenReturn}`;
+
+ const link = `https://foodies-web-app.vercel.app/api/v1/newPassword/${existingUser._id}/${tokenReturn}`;
+
+ const transporter =
+ nodemailer.createTransport({
+ service: "gmail",
+ auth: {
+ user: process.env.EMAIL,
+ pass: process.env.MAILPASS,
+ },
+ });
+
+ const mailOptions = {
+ from: process.env.EMAIL,
+ to: email,
+ subject: "Password Reset Link",
+ html: `
+
Hello,
+You have requested to reset your password. Please click the button below to reset your password:
+If you did not request this, please ignore this email.
+Thank you,
+FoodiesWeb
+© 2024 Your Company Name. All rights reserved.
++ Connecting You to Your College + Canteens +
+