UNPKG

get-express-starter

Version:

Get production ready express boilerplate with a single command

51 lines (41 loc) 1.56 kB
import { env } from '@/config'; import { tokenTypes } from '@/config/tokens'; import { userService } from '@/services'; import type { AppJwtPayload, AuthedReq } from '@/types'; import { ApiError } from '@/utils/api-error'; import type { NextFunction, Request, Response } from 'express'; import httpStatus from 'http-status'; import jwt from 'jsonwebtoken'; /** * Middleware to authenticate a JWT token and attach the user to the request object. */ const authenticateToken = async (req: Request): Promise<void> => { const authHeader = req.headers.authorization; const token = authHeader?.split(' ')[1]; if (!token) { throw new ApiError(httpStatus.UNAUTHORIZED, 'No token provided'); } let decoded: AppJwtPayload; try { decoded = jwt.verify(token, env.jwt.secret) as AppJwtPayload; } catch { throw new ApiError(httpStatus.UNAUTHORIZED, 'Invalid or expired token'); } if (decoded.type !== tokenTypes.ACCESS) { throw new ApiError(httpStatus.UNAUTHORIZED, 'Invalid token type'); } const user = await userService.getUserById(decoded.sub); (req as AuthedReq).user = user; }; /** * Authorization middleware that checks if the authenticated user has the required role. */ const auth = (requiredRoles?: string[]) => async (req: Request, _res: Response, next: NextFunction) => { await authenticateToken(req); const { role } = (req as AuthedReq).user; if (requiredRoles?.length && !requiredRoles.includes(role)) { throw new ApiError(httpStatus.FORBIDDEN, 'Access denied'); } next(); }; export default auth;