From ba998eb401ff97653246fd7e9c6102dc196c5dd2 Mon Sep 17 00:00:00 2001 From: Justin xzHome Date: Mon, 14 Jul 2025 23:17:49 +0900 Subject: [PATCH] Authentication and Authorization --- api/src/middlewares/authMiddleware.ts | 35 +++++++++++++++++++ api/src/routes/products/index.ts | 7 ++-- api/src/routes/products/productsController.ts | 2 +- api/src/type/express/index.d.ts | 3 +- 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 api/src/middlewares/authMiddleware.ts diff --git a/api/src/middlewares/authMiddleware.ts b/api/src/middlewares/authMiddleware.ts new file mode 100644 index 0000000..fcc35cd --- /dev/null +++ b/api/src/middlewares/authMiddleware.ts @@ -0,0 +1,35 @@ +import { Request, Response, NextFunction } from 'express'; +import jwt from 'jsonwebtoken'; + +export function verifyToken(req: Request, res: Response, next: NextFunction) { + const token = req.header('Authorization'); + + if (!token) { + res.status(401).json({error: "Access denied"}); + return; + } + + try { + const decoded = jwt.verify(token, 'your-secret'); + if (typeof decoded !== 'object' || !decoded?.userId) { + res.status(401).json({error: "Access denied"}); + return; + } + req.role = decoded.role; + req.userId = decoded.userId; + console.log(decoded); + next(); + } catch (e) { + res.status(401).json({error: "Access denied"}); + + } +}; + +export function verifySeller(req: Request, res: Response, next: NextFunction) { + const role = req.role; + if (role !== 'seller') { + res.status(401).json({error: "Access denied"}); + return; + } + next(); +}; \ No newline at end of file diff --git a/api/src/routes/products/index.ts b/api/src/routes/products/index.ts index 0934fcb..9e4f7f1 100644 --- a/api/src/routes/products/index.ts +++ b/api/src/routes/products/index.ts @@ -8,6 +8,7 @@ import { listProducts, import { validateData } from "../../middlewares/validationMiddleware"; import { z, ZodObject, ZodTypeAny } from 'zod/v4'; import { productsTable, createProductSchema, updateProductSchema } from "../../db/productsSchema"; +import { verifySeller, verifyToken } from "../../middlewares/authMiddleware"; type ProductType = z.infer; @@ -17,8 +18,8 @@ const router = Router(); // products endpoints where validator can be added later router.get('/', listProducts); router.get('/:id', getProductById); -router.post('/', validateData(createProductSchema), createProduct); -router.put('/:id', validateData(updateProductSchema), updateProduct); -router.delete('/:id', deleteProduct); +router.post('/', verifyToken, verifySeller, validateData(createProductSchema), createProduct); +router.put('/:id', verifyToken, verifySeller, validateData(updateProductSchema), updateProduct); +router.delete('/:id', verifyToken, verifySeller, deleteProduct); export default router; \ No newline at end of file diff --git a/api/src/routes/products/productsController.ts b/api/src/routes/products/productsController.ts index 812117a..f34c011 100644 --- a/api/src/routes/products/productsController.ts +++ b/api/src/routes/products/productsController.ts @@ -36,7 +36,7 @@ export async function getProductById(req: Request, res: Response) { export async function createProduct(req: Request, res: Response) { try{ - + console.log("req.userID = " + req.userId); const productId = await db .insert(productsTable) .values(req.cleanBody) diff --git a/api/src/type/express/index.d.ts b/api/src/type/express/index.d.ts index 032dcab..9fef9b8 100644 --- a/api/src/type/express/index.d.ts +++ b/api/src/type/express/index.d.ts @@ -5,7 +5,8 @@ declare global { namespace Express { export interface Request { userId?: Number; - cleanBody?: any + cleanBody?: any; + role: string; } } } \ No newline at end of file