Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# node modules
node_modules/

# Enviroment variables
.env
28 changes: 28 additions & 0 deletions backend/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import express from "express";
import cookieParser from "cookie-parser";

import userRoute from "./routes/auth.routes.js";
const app = express();


// logs req in console (in dev mode)
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});


app.use(cookieParser());
app.use(express.json({ limit: "16kb" }));
app.use(
express.urlencoded({
extended: true,
})
);




app.use("/api/auth",userRoute)

export { app };
198 changes: 198 additions & 0 deletions backend/controllers/auth.controllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import e from "express";
import User from "../models/user.model.js";
import { sendToken } from "./../utils/sendToken.js";

/**
* @desc Register a new user
* @route POST /api/auth/register
* @access Public
*/

export const register = async (req, res) => {
try {
const { fullName, email, password } = req.body;

console.log(req.body);

// check if all the required fields are present

if (
[fullName, email, password].some((field) => !field || field.trim() === "")
) {
return res
.status(400)
.json({ message: "Name, email, and password are required" });
}

// Check if user already exists

const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(400).json({ message: "User already exists" });
}

const user = await User.create({
fullName,
email,
password,
});

return sendToken(user, res);
} catch (error) {
console.error("Error during registration:", error);
return res.status(500).json({ message: "Internal server error" });
}
};

/**
* @desc Login a user
* @route POST /api/auth/login
* @access Public
*/

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

// check if all the required fields are present
if ([email, password].some((field) => !field || field.trim() === "")) {
return res
.status(400)
.json({ message: "Email and password are required" });
}
const user = await User.findOne({ email: email.trim().toLowerCase() });

if (!user) {
return res.status(401).json({
message: " that email or password is wrong!.",
});
}
// Check if the password matches
if (password === user.password) {
return sendToken(user, res);
} else {
return res.status(401).json({
message: " that email or password is wrong!.",
});
}
} catch (error) {
console.error("Login error:", error.message);
res.status(500).json({
message: "Something went wrong. Please try again later.",
error: error.message,
});
}
};

/**
* @desc Logout a user
* @route GET /api/auth/logout
* @access Private
*/

export const logout = (req, res) => {
try {
res.clearCookie("token", {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "Strict",
});

res.status(200).json({ message: "Logged out successfully." });
} catch (error) {
console.error("Logout error:", error.message);
res.status(500).json({
message: "Error during logout.",
error: error.message,
});
}
};

/**
* @desc Set new password
* @route POST /api/auth/new-password
* @access Public
*/

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

if (!email || !token || !newPassword) {
return res.status(400).json({
message: "Email, token, and new password are required",
});
}

const user = await User.findOne({
email,
resetPasswordToken: token,
resetPasswordExpire: { $gt: Date.now() },
});

if (!user) {
return res.status(400).json({ message: "Invalid or expired token" });
}

user.password = newPassword;
user.resetPasswordToken = undefined;
user.resetPasswordExpire = undefined;
await user.save();

return res.status(200).json({ message: "Password updated successfully" });
} catch (error) {
console.error("Error resetting password:", error);
return res.status(500).json({ message: "Internal server error" });
}
};

/**
* @desc Request password reset
* @route POST /api/auth/reset-password
* @access Public
*/

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

if (!email) return res.status(400).json({ message: "Email is required" });

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

const resetToken = Math.random().toString(36).substr(2, 8);

user.resetPasswordToken = resetToken;
user.resetPasswordExpire = Date.now() + 15 * 60 * 1000;
await user.save();

res.clearCookie("token", {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "Strict",
});
res.status(200).json({
message: "Reset token generated",
resetToken,
});
};

/**
* @desc Get user profile
* @route GET /api/auth/profile
* @access Private
*/

export const profile = async (req, res) => {
try {
const user = await User.findById(req.user._id).select(
"-password -resetPasswordToken -resetPasswordExpire"
);

if (!user) {
return res.status(404).json({ message: "User not found" });
}

return res.status(200).json(user);
} catch (error) {}
};
14 changes: 14 additions & 0 deletions backend/models/user.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import mongoose from "mongoose";

const userSchema = new mongoose.Schema({
fullName: String,
email: { type: String, unique: true, required: true },
password: { type: String, required: true },
isEmailVerified: { type: Boolean, default: false },
resetPasswordToken: String,
resetPasswordExpire: Date,
});

const User = mongoose.model("User", userSchema);

export default User;
Loading