diff --git a/src/middleware/auth.ts b/src/middleware/auth.ts index 2456981..71c36c6 100644 --- a/src/middleware/auth.ts +++ b/src/middleware/auth.ts @@ -1,55 +1,24 @@ -import { NextFunction, Request, Response } from 'express'; -import jwt, { JwtPayload } from 'jsonwebtoken'; -import { HttpError } from '../utils/httpError'; -import env from '../config/env'; +import { Request, Response, NextFunction } from 'express'; +import authenticateCanonical from './authenticate'; +import AppError from '../utils/AppError'; -const jwtSecret = env.JWT_SECRET; - -export interface AuthenticatedRequest extends Request { - user?: JwtPayload & { - role?: string; - sub?: string; - }; -} +export type AuthenticatedRequest = Request & { + user?: { role?: string; userId?: string; id?: string; _id?: unknown }; +}; -export const authenticate = ( +/** Canonical database-backed authentication, retained under the old import. */ +export const authenticate = authenticateCanonical as ( req: AuthenticatedRequest, res: Response, next: NextFunction, -): void => { - const authHeader = req.headers.authorization; - - if (!authHeader || !authHeader.startsWith('Bearer ')) { - next(new HttpError(401, 'Authorization header missing or malformed')); - return; - } - - const token = authHeader.split(' ')[1]; - - try { - const payload = jwt.verify(token, jwtSecret); - - if (typeof payload === 'string') { - next(new HttpError(401, 'Invalid authorization token')); - return; - } - - req.user = payload; - next(); - } catch (error) { - next(new HttpError(401, 'Invalid or expired authorization token')); - } -}; +) => void; export const authorize = (allowedRoles: string[] = ['driver', 'admin']) => { - return (req: AuthenticatedRequest, res: Response, next: NextFunction): void => { - const role = req.user?.role; - - if (!role || !allowedRoles.includes(role)) { - next(new HttpError(403, 'Insufficient permissions to perform this action')); + return (req: AuthenticatedRequest, _res: Response, next: NextFunction): void => { + if (!req.user?.role || !allowedRoles.includes(String(req.user.role))) { + next(new AppError('Insufficient permissions to perform this action', 403)); return; } - next(); }; }; diff --git a/src/middlewares/authMiddleware.ts b/src/middlewares/authMiddleware.ts index d432ddf..6167313 100644 --- a/src/middlewares/authMiddleware.ts +++ b/src/middlewares/authMiddleware.ts @@ -1,60 +1,3 @@ -import { Request, Response, NextFunction } from 'express'; -import jwt, { JwtPayload } from 'jsonwebtoken'; -import { StatusCodes } from 'http-status-codes'; -import AppError from '../utils/AppError'; -import env from '../config/env'; - -export interface AuthenticatedRequest extends Request { - user?: JwtPayload & { - userId?: string; - id?: string; - role?: string; - }; -} - -/** - * Verifies the `Authorization: Bearer ` header and attaches the - * decoded JWT payload to `req.user` for downstream handlers. - * - * Throws 401 if the header is missing/malformed or the token is invalid/expired. - */ -export const authMiddleware = ( - req: AuthenticatedRequest, - _res: Response, - next: NextFunction, -): void => { - const authHeader = req.headers.authorization; - - if (!authHeader || !authHeader.startsWith('Bearer ')) { - next( - new AppError( - 'Authentication required. Please provide a valid Bearer token.', - StatusCodes.UNAUTHORIZED, - ), - ); - return; - } - - const token = authHeader.split(' ')[1]; - - if (!token) { - next(new AppError('Authentication token missing.', StatusCodes.UNAUTHORIZED)); - return; - } - - try { - const decoded = jwt.verify(token, env.JWT_SECRET); - - if (typeof decoded === 'string') { - next(new AppError('Invalid authorization token.', StatusCodes.UNAUTHORIZED)); - return; - } - - req.user = decoded; - next(); - } catch (error) { - next(new AppError('Invalid or expired token. Please log in again.', StatusCodes.UNAUTHORIZED)); - } -}; - -export default authMiddleware; +/** Backwards-compatible path for the canonical database-backed middleware. */ +export { default, default as authMiddleware } from '../middleware/authenticate'; +export type { AuthenticatedRequest } from '../middleware/auth';