From ec0a2177a47374252d6268129e6da72a9139c6e9 Mon Sep 17 00:00:00 2001 From: Abdul-zaki Date: Fri, 5 Sep 2025 03:57:40 -0700 Subject: [PATCH] week 20 --- middleware/auth.js | 38 ++++++++++++++++++--- routes/auth.js | 85 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 109 insertions(+), 14 deletions(-) diff --git a/middleware/auth.js b/middleware/auth.js index 7deb650..9137b17 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -1,20 +1,50 @@ import jwt from "jsonwebtoken"; import prisma from "../lib/prisma.js"; -const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key"; +const JWT_SECRET = process.env.JWT_SECRET || "a5gqd+c43XsoqaJDuD5Jiys/cEjqmuNtuLGE0xVXTLk="; export const authenticateToken = async (req, res, next) => { try { - // TODO: Implement the authentication middleware // 1. Get the token from the request header + const authHeader = req.headers["authorization"]; + if (!authHeader || !authHeader.startsWith("Bearer ")) { + return res.status(401).json({ + success: false, + message: "No token provided", + }); + } + + const token = authHeader.split(" ")[1]; + // 2. Verify the token + const decoded = jwt.verify(token, JWT_SECRET); + // 3. Get the user from the database + const user = await prisma.user.findUnique({ + where: { id: decoded.userId }, + select: { + id: true, + name: true, + email: true, + createdAt: true, + updatedAt: true, + }, + }); + // 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({ diff --git a/routes/auth.js b/routes/auth.js index 7a78cfc..9720404 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -5,21 +5,53 @@ 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 || "a5gqd+c43XsoqaJDuD5Jiys/cEjqmuNtuLGE0xVXTLk="; // 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 { name, email, password } = req.body; + if (!name || !email || !password) { + return res.status(400).json({ + success: false, + message: "Name, 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(409).json({ + success: false, + message: "Email already registered", + }); + } + // 3. Hash the password - // 4. Create the user - // 5. Generate a JWT token - // 6. Return the user data and token + const hashedPassword = await bcrypt.hash(password, 12); + // 4. Create the user + const user = await prisma.user.create({ + data: { name, email, password: hashedPassword }, + }); + // 5. Generate a JWT token + const token = jwt.sign( + { userId: user.id, email: user.email }, + JWT_SECRET, + { expiresIn: "1d" } + ); + // 6. Return the user data and token (omit password) + const { password: _, ...userWithoutPassword } = user; + res.status(201).json({ + success: true, + data: userWithoutPassword, + token, + }); } catch (error) { console.error("Registration error:", error); res.status(500).json({ @@ -33,14 +65,49 @@ router.post("/register", async (req, res) => { // POST /api/auth/login - Login user router.post("/login", async (req, res) => { try { - // TODO: Implement the login 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 exists + const user = await prisma.user.findUnique({ + where: { email }, + }); + if (!user) { + return res.status(401).json({ + success: false, + message: "Invalid credentials", + }); + } + // 3. Compare the password + const isMatch = await bcrypt.compare(password, user.password); + if (!isMatch) { + return res.status(401).json({ + success: false, + message: "Invalid credentials", + }); + } + // 4. Generate a JWT token + const token = jwt.sign( + { userId: user.id, email: user.email }, + JWT_SECRET, + { expiresIn: "1d" } + ); + // 5. Return the user data and token - - + const { password: _, ...userWithoutPassword } = user; + res.json({ + success: true, + data: userWithoutPassword, + token, + }); } catch (error) { console.error("Login error:", error); res.status(500).json({ @@ -54,9 +121,7 @@ router.post("/login", async (req, res) => { // GET /api/auth/me - Get current user profile (protected route) router.get("/me", authenticateToken, async (req, res) => { try { - // req.user will be set by the authenticateToken middleware const { password, ...userWithoutPassword } = req.user; - res.json({ success: true, data: userWithoutPassword,