From bf500a7af8859e86cc76f52d9c033b5b58dfce78 Mon Sep 17 00:00:00 2001 From: saynis Date: Tue, 9 Dec 2025 07:20:21 +0300 Subject: [PATCH] done --- middleware/auth.js | 28 +++++++++++++++ routes/auth.js | 85 ++++++++++++++++++++++++++++++++++++++++++++++ routes/tasks.js | 6 ++-- 3 files changed, 116 insertions(+), 3 deletions(-) diff --git a/middleware/auth.js b/middleware/auth.js index 7deb650..ba15eb9 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -6,12 +6,40 @@ const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key"; 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); + // 3. Get the user from the database + const user = await prisma.user.findUnique({ + where: { id: decoded.userId }, + select: { id: true, name: true, email: 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(); diff --git a/routes/auth.js b/routes/auth.js index 7a78cfc..be3f6a5 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -11,12 +11,58 @@ const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key"; router.post("/register", async (req, res) => { try { // TODO: Implement the registration logic + const { name, email, password } = req.body; + // 1. Validate the input + if(!name || !email || !password) { + return res.status(400).json({ + success: false, + message: "Username, 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 with this email", + }); + } + + // 3. Hash the password + + const hashedPassword = await bcrypt.hash(password, 10); + // 4. Create the user + const newUser = await prisma.user.create({ + data: { + name, + email, + password: hashedPassword, + }, + }); + // 5. Generate a JWT token + const token = jwt.sign( + { userId: newUser.id, role: newUser.role}, + JWT_SECRET, + { expiresIn: "1h" } + ); + + // 6. Return the user data and token + res.status(201).json({ + success: true, + message: "User registered successfully", + user: newUser, + token, + }); + @@ -34,11 +80,50 @@ router.post("/register", async (req, res) => { router.post("/login", async (req, res) => { try { // TODO: Implement the login logic + const { email, password } = req.body; + // 1. Validate the input + 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(400).json({ + success: false, + message: "Invalid email or password", + }); + } + // 3. Compare the password + const isPasswordValid = await bcrypt.compare(password, user.password); + if (!isPasswordValid) { + return res.status(400).json({ + success: false, + message: "Invalid email or password", + }); + } // 4. Generate a JWT token + const token = jwt.sign( + { id: user.id, email: user.email }, + process.env.JWT_SECRET, + { expiresIn: "24h" } + ); + // 5. Return the user data and token + res.json({ + success: true, + message: "Login successful", + user, + token, + }); } catch (error) { diff --git a/routes/tasks.js b/routes/tasks.js index dca9b03..f87733d 100644 --- a/routes/tasks.js +++ b/routes/tasks.js @@ -22,7 +22,7 @@ router.use(authenticateToken); // This route handles GET requests to /api/tasks // req = request object (contains data sent by client) // res = response object (used to send data back to client) -router.get("/tasks", async (req, res) => { +router.get("/tasks", authenticateToken, async (req, res) => { try { const tasks = await getAllTasks(req.user.id); @@ -42,7 +42,7 @@ router.get("/tasks", async (req, res) => { // GET /api/tasks/:id - Get task by ID for the authenticated user // :id is a route parameter - it captures the value from the URL // Example: /api/tasks/1 will set req.params.id = "1" -router.get("/tasks/:id", async (req, res) => { +router.get("/tasks/:id", authenticateToken, async (req, res) => { try { const { id } = req.params; // Extract the ID from the URL const task = await getTaskById(id, req.user.id); @@ -69,7 +69,7 @@ router.get("/tasks/:id", async (req, res) => { // POST /api/tasks - Create new task for the authenticated user // POST requests are used to create new resources // req.body contains the data sent in the request body -router.post("/tasks", async (req, res) => { +router.post("/tasks", authenticateToken, async (req, res) => { try { const taskData = req.body; const newTask = await createTask(taskData, req.user.id);