From 271afb63736c087764e5bd2fc88df536ea9051b6 Mon Sep 17 00:00:00 2001 From: AbdiNasirHaji Date: Fri, 19 Dec 2025 22:19:16 +0300 Subject: [PATCH 1/2] opdated for assign --- middleware/auth.js | 73 +++++- .../migrations/20251219135401_/migration.sql | 55 +++++ prisma/migrations/migration_lock.toml | 3 + routes/auth.js | 208 ++++++++++++++++-- services/taskServices.js | 4 + 5 files changed, 321 insertions(+), 22 deletions(-) create mode 100644 prisma/migrations/20251219135401_/migration.sql create mode 100644 prisma/migrations/migration_lock.toml diff --git a/middleware/auth.js b/middleware/auth.js index 7deb650..36ad902 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -1,3 +1,45 @@ +// import jwt from "jsonwebtoken"; +// import prisma from "../lib/prisma.js"; + +// 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 +// // 2. Verify the token +// // 3. Get the user from the database +// // 4. If the user doesn't exist, throw an error +// // 5. Attach the user to the request object +// // 6. Call the next middleware + + + +// } catch (error) { +// if (error.name === "JsonWebTokenError") { +// return res.status(401).json({ +// success: false, +// message: "Invalid token", +// }); +// } + +// if (error.name === "TokenExpiredError") { +// return res.status(401).json({ +// success: false, +// message: "Token expired", +// }); +// } + +// return res.status(500).json({ +// success: false, +// message: "Authentication error", +// }); +// } +// }; + + + + import jwt from "jsonwebtoken"; import prisma from "../lib/prisma.js"; @@ -5,16 +47,39 @@ 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 authHeader = req.headers.authorization; + + if (!authHeader || !authHeader.startsWith("Bearer ")) { + return res.status(401).json({ + success: false, + message: "Access token missing or invalid", + }); + } + + 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.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 - // 6. Call the next middleware + req.user = user; - - + // 6. Call the next middleware + next(); } catch (error) { if (error.name === "JsonWebTokenError") { return res.status(401).json({ diff --git a/prisma/migrations/20251219135401_/migration.sql b/prisma/migrations/20251219135401_/migration.sql new file mode 100644 index 0000000..f942249 --- /dev/null +++ b/prisma/migrations/20251219135401_/migration.sql @@ -0,0 +1,55 @@ +-- CreateEnum +CREATE TYPE "TaskStatus" AS ENUM ('pending', 'in_progress', 'completed', 'cancelled'); + +-- CreateEnum +CREATE TYPE "Priority" AS ENUM ('low', 'medium', 'high', 'urgent'); + +-- CreateTable +CREATE TABLE "users" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "password" TEXT NOT NULL, + "name" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "users_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "tasks" ( + "id" TEXT NOT NULL, + "title" TEXT NOT NULL, + "description" TEXT NOT NULL, + "status" "TaskStatus" NOT NULL, + "priority" "Priority" NOT NULL, + "dueDate" TIMESTAMP(3), + "assignedTo" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "userId" TEXT NOT NULL, + + CONSTRAINT "tasks_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "subtasks" ( + "id" TEXT NOT NULL, + "title" TEXT NOT NULL, + "description" TEXT NOT NULL, + "completed" BOOLEAN NOT NULL DEFAULT false, + "taskId" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "subtasks_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "users_email_key" ON "users"("email"); + +-- AddForeignKey +ALTER TABLE "tasks" ADD CONSTRAINT "tasks_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "subtasks" ADD CONSTRAINT "subtasks_taskId_fkey" FOREIGN KEY ("taskId") REFERENCES "tasks"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..fbffa92 --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/routes/auth.js b/routes/auth.js index 7a78cfc..fd4e9c1 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -1,3 +1,80 @@ +// import express from "express"; +// import bcrypt from "bcryptjs"; +// import jwt from "jsonwebtoken"; +// 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"; + +// // POST /api/auth/register - Register a new user +// router.post("/register", async (req, res) => { +// try { +// // TODO: Implement the registration logic +// // 1. Validate the input +// // 2. Check if the user already exists +// // 3. Hash the password +// // 4. Create the user +// // 5. Generate a JWT token +// // 6. Return the user data and token + + + +// } catch (error) { +// console.error("Registration error:", error); +// res.status(500).json({ +// success: false, +// message: "Error registering user", +// error: error.message, +// }); +// } +// }); + +// // POST /api/auth/login - Login user +// router.post("/login", async (req, res) => { +// try { +// // TODO: Implement the login logic +// // 1. Validate the input +// // 2. Check if the user exists +// // 3. Compare the password +// // 4. Generate a JWT token +// // 5. Return the user data and token + + +// } catch (error) { +// console.error("Login error:", error); +// res.status(500).json({ +// success: false, +// message: "Error logging in", +// error: error.message, +// }); +// } +// }); + +// // 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, +// }); +// } catch (error) { +// console.error("Get profile error:", error); +// res.status(500).json({ +// success: false, +// message: "Error retrieving user profile", +// error: error.message, +// }); +// } +// }); + +// export default router; + + + import express from "express"; import bcrypt from "bcryptjs"; import jwt from "jsonwebtoken"; @@ -5,21 +82,67 @@ 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 || "okokokokkokok"; -// POST /api/auth/register - Register a new user +/** + * POST /api/auth/register + * Register a new user + */ router.post("/register", async (req, res) => { try { - // TODO: Implement the registration logic - // 1. Validate the input - // 2. Check if the user already exists + const { name, email, password } = req.body; + + // 1. Validate input + if (!name || !email || !password) { + return res.status(400).json({ + success: false, + message: "Name, email, and password are required", + }); + } + + // 2. Check if user already exists + const existingUser = await prisma.user.findUnique({ + where: { email }, + }); + + if (existingUser) { + return res.status(409).json({ + success: false, + message: "User already exists", + }); + } + // 3. Hash the password + const hashedPassword = await bcrypt.hash(password, 10); + // 4. Create the user - // 5. Generate a JWT token - // 6. Return the user data and token + const user = await prisma.user.create({ + data: { + name, + email, + password: hashedPassword, + }, + }); + // 5. Generate JWT token + const token = jwt.sign( + { id: user.id, email: user.email }, + JWT_SECRET, + { expiresIn: "7d" } + ); + // Remove password from response + const { password: _, ...userWithoutPassword } = user; + // 6. Return user data and token + res.status(201).json({ + success: true, + message: "User registered successfully", + data: { + user: userWithoutPassword, + token, + }, + }); } catch (error) { console.error("Registration error:", error); res.status(500).json({ @@ -30,17 +153,63 @@ router.post("/register", async (req, res) => { } }); -// POST /api/auth/login - Login user +/** + * POST /api/auth/login + * Login user + */ router.post("/login", async (req, res) => { try { - // TODO: Implement the login logic - // 1. Validate the input - // 2. Check if the user exists - // 3. Compare the password - // 4. Generate a JWT token - // 5. Return the user data and token - - + const { email, password } = req.body; + + // 1. Validate input + if (!email || !password) { + return res.status(400).json({ + success: false, + message: "Email and password are required", + }); + } + + // 2. Check if 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 password + const isPasswordValid = await bcrypt.compare(password, user.password); + + if (!isPasswordValid) { + return res.status(401).json({ + success: false, + message: "Invalid email or password", + }); + } + + // 4. Generate JWT token + const token = jwt.sign( + { id: user.id, email: user.email }, + JWT_SECRET, + { expiresIn: "7d" } + ); + + // Remove password from response + const { password: _, ...userWithoutPassword } = user; + + // 5. Return user data and token + res.json({ + success: true, + message: "Login successful", + data: { + user: userWithoutPassword, + token, + }, + }); } catch (error) { console.error("Login error:", error); res.status(500).json({ @@ -51,10 +220,13 @@ router.post("/login", async (req, res) => { } }); -// GET /api/auth/me - Get current user profile (protected route) +/** + * GET /api/auth/me + * Get current user profile (protected) + */ router.get("/me", authenticateToken, async (req, res) => { try { - // req.user will be set by the authenticateToken middleware + // req.user is set by authenticateToken middleware const { password, ...userWithoutPassword } = req.user; res.json({ diff --git a/services/taskServices.js b/services/taskServices.js index 1f55241..fdd89b1 100644 --- a/services/taskServices.js +++ b/services/taskServices.js @@ -61,6 +61,10 @@ export async function createTask(taskData, userId) { } } + + + + // Update task export async function updateTask(id, updateData, userId) { try { From 2e89a6f9c6ccd7bdecd9b419263f2f4574ec4279 Mon Sep 17 00:00:00 2001 From: ~100 Date: Fri, 19 Dec 2025 22:22:50 +0300 Subject: [PATCH 2/2] Update auth.js --- routes/auth.js | 75 -------------------------------------------------- 1 file changed, 75 deletions(-) diff --git a/routes/auth.js b/routes/auth.js index fd4e9c1..b13049f 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -1,78 +1,3 @@ -// import express from "express"; -// import bcrypt from "bcryptjs"; -// import jwt from "jsonwebtoken"; -// 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"; - -// // POST /api/auth/register - Register a new user -// router.post("/register", async (req, res) => { -// try { -// // TODO: Implement the registration logic -// // 1. Validate the input -// // 2. Check if the user already exists -// // 3. Hash the password -// // 4. Create the user -// // 5. Generate a JWT token -// // 6. Return the user data and token - - - -// } catch (error) { -// console.error("Registration error:", error); -// res.status(500).json({ -// success: false, -// message: "Error registering user", -// error: error.message, -// }); -// } -// }); - -// // POST /api/auth/login - Login user -// router.post("/login", async (req, res) => { -// try { -// // TODO: Implement the login logic -// // 1. Validate the input -// // 2. Check if the user exists -// // 3. Compare the password -// // 4. Generate a JWT token -// // 5. Return the user data and token - - -// } catch (error) { -// console.error("Login error:", error); -// res.status(500).json({ -// success: false, -// message: "Error logging in", -// error: error.message, -// }); -// } -// }); - -// // 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, -// }); -// } catch (error) { -// console.error("Get profile error:", error); -// res.status(500).json({ -// success: false, -// message: "Error retrieving user profile", -// error: error.message, -// }); -// } -// }); - -// export default router; - import express from "express";