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
23 changes: 20 additions & 3 deletions middleware/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,31 @@ export const authenticateToken = async (req, res, next) => {
try {
// TODO: Implement the authentication middleware
// 1. Get the token from the request header
const token = req.headers["authorization"]?.split(" ")[1];
if (!token) {
return res.status(401).json({
success: false,
message: "No token provided",
});
}

// 2. Verify the token
const decoded = jwt.verify(token, JWT_SECRET || "9f3c8a72b4e6d1a0c57e3f91d2b8a4e5");
// 3. Get the user from the database
const user = await prisma.user.findUnique({
where: { id: decoded.id },
});
// 4. If the user doesn't exist, throw an error
if (!user) {
return res.status(401).json({
success: false,
message: "User not found",
});
}
// 5. Attach the user to the request object
req.user = user;
// 6. Call the next middleware



next();
} catch (error) {
if (error.name === "JsonWebTokenError") {
return res.status(401).json({
Expand Down
207 changes: 201 additions & 6 deletions routes/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,51 @@ import prisma from "../lib/prisma.js";
import { authenticateToken } from "../middleware/auth.js";

const router = express.Router();
const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key";
const JWT_SECRET = process.env.JWT_SECRET || "9f3c8a72b4e6d1a0c57e3f91d2b8a4e5";

// POST /api/auth/register - Register a new user
router.post("/register", async (req, res) => {
try {
// TODO: Implement the registration logic
// 1. Validate the input
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({
success: false,
message: "Email and password are required",
});
}

// 2. Check if the user already exists
const existingUser = await prisma.user.findUnique({
where: { email },
});
if (existingUser) {
return res.status(400).json({
success: false,
message: "User already exists",
});
}

// 3. Hash the password
const hashedPassword = await bcrypt.hash(password, 10);
// 4. Create the user
const newUser = await prisma.user.create({
data: {
email,
password: hashedPassword,
},
});
// 5. Generate a JWT token
const token = jwt.sign({ id: newUser.id }, JWT_SECRET, { expiresIn: "1h" });
// 6. Return the user data and token



res.json({
success: true,
data: {
user: newUser,
token,
},
});
} catch (error) {
console.error("Registration error:", error);
res.status(500).json({
Expand All @@ -35,12 +65,35 @@ router.post("/login", async (req, res) => {
try {
// TODO: Implement the login logic
// 1. Validate the input
const { email, password } = req.body;
// 2. Check if the user exists
const user = await prisma.user.findUnique({
where: { email },
});
if (!user) {
return res.status(401).json({
success: false,
message: "Invalid email or password",
});
}
// 3. Compare the password
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(401).json({
success: false,
message: "Invalid email or password",
});
}
// 4. Generate a JWT token
const token = jwt.sign({ id: user.id }, JWT_SECRET, { expiresIn: "1h" });
// 5. Return the user data and token


res.json({
success: true,
data: {
user,
token,
},
});
} catch (error) {
console.error("Login error:", error);
res.status(500).json({
Expand All @@ -50,6 +103,148 @@ router.post("/login", async (req, res) => {
});
}
});
//add email verification field
const emailVerificationField = async () => {
// Add email verification field to user model
await prisma.user.updateMany({
where: { emailVerified: null },
data: { emailVerified: false },
});
};

// create password reset endpoint
router.post("/reset-password", async (req, res) => {
const { email } = req.body;
if (!email) {
return res.status(400).json({
success: false,
message: "Email is required",
});
}

// Check if the user exists
const user = await prisma.user.findUnique({
where: { email },
});
if (!user) {
return res.status(404).json({
success: false,
message: "User not found",
});
}

// Generate a password reset token
const token = generatePasswordResetToken(user.id);
sendPasswordResetEmail(email, token);

res.json({
success: true,
message: "Password reset email sent",
});
});

//send reset email
const sendPasswordResetEmail = (email, token) => {
// In a real application, you would send the email here.
console.log(`Send password reset email to ${email} with token: ${token}`);
};
//create reset password endpoint
router.post("/reset-password/:token", async (req, res) => {
const { token } = req.params;
const { newPassword } = req.body;

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

try {
const decoded = jwt.verify(token, JWT_SECRET);
const user = await prisma.user.findUnique({
where: { id: decoded.id },
});
if (!user) {
return res.status(404).json({
success: false,
message: "User not found",
});
}

// Update user's password
const hashedPassword = await bcrypt.hash(newPassword, 10);
await prisma.user.update({
where: { id: user.id },
data: { password: hashedPassword },
});

res.json({
success: true,
message: "Password reset successfully",
});
} catch (error) {
console.error("Password reset error:", error);
res.status(500).json({
success: false,
message: "Error resetting password",
error: error.message,
});
}
});

//generate verification token
const generateVerificationToken = (userId) => {
return jwt.sign({ id: userId }, JWT_SECRET, { expiresIn: "1d" });
};

//send verification token
const sendVerificationEmail = (email, token) => {
// In a real application, you would send the email here.
console.log(`Send verification email to ${email} with token: ${token}`);
};

//create verification endpoint
router.post("/verify-email", async (req, res) => {
const { token } = req.body;
if (!token) {
return res.status(400).json({
success: false,
message: "Verification token is required",
});
}

try {
const decoded = jwt.verify(token, JWT_SECRET);
const user = await prisma.user.findUnique({
where: { id: decoded.id },
});
if (!user) {
return res.status(404).json({
success: false,
message: "User not found",
});
}

// Update user's email verification status
await prisma.user.update({
where: { id: user.id },
data: { emailVerified: true },
});

res.json({
success: true,
message: "Email verified successfully",
});
} catch (error) {
console.error("Email verification error:", error);
res.status(500).json({
success: false,
message: "Error verifying email",
error: error.message,
});
}
});

// GET /api/auth/me - Get current user profile (protected route)
router.get("/me", authenticateToken, async (req, res) => {
Expand Down