import { Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; import * as jwt from 'jsonwebtoken'; import { validate as isValidUUID } from 'uuid'; @Injectable() export class JwtMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { throw new UnauthorizedException('Missing or invalid Authorization header'); } const token = authHeader.split(' ')[1]; try { const decoded = jwt.decode(token) as any; if (!decoded || !decoded.sub) { throw new UnauthorizedException('Invalid token: missing sub'); } if (!isValidUUID(decoded.sub)) { throw new UnauthorizedException('Invalid token: sub is not a valid UUIDv4'); } const { sub, realm_access, resource_access } = decoded; const roles = [ // extract the role you wanna use in guards ...(realm_access?.roles || []), // ...(resource_access?.account?.roles || []), ]; req['user'] = { sub, roles }; next(); } catch (error) { throw new UnauthorizedException('Invalid token'); } } } export interface AuthRequest extends Request { user: { sub: string; roles: string[] }; }