import { CanActivate, ExecutionContext, Injectable, UnauthorizedException, } from "@nestjs/common"; import { JwtService } from "@nestjs/jwt"; import { Request } from "express"; import { RoleEnum } from "src/Types&Enums/role.enum"; const GLOBAL_GUARD_ROLES = new Set([ RoleEnum.USER, RoleEnum.FIELD_EXPERT, RoleEnum.REGISTRAR, ]); @Injectable() export class GlobalGuard implements CanActivate { constructor(private readonly jwtService: JwtService) {} async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); const token = this.extractTokenFromHeader(request); if (!token) { throw new UnauthorizedException("Missing Bearer token"); } try { const payload = await this.jwtService.verifyAsync(token, { secret: `${process.env.JWT_SECRET}`, }); if (!payload?.role || !GLOBAL_GUARD_ROLES.has(String(payload.role))) { throw new UnauthorizedException( `Role "${payload?.role ?? "unknown"}" is not allowed on user-panel APIs. Use /user/login for USER, or /actor/login for experts.`, ); } request.user = payload; request.identity = request.user; } catch (error) { if (error instanceof UnauthorizedException) { throw error; } throw new UnauthorizedException("Invalid or expired token"); } return true; } private extractTokenFromHeader(request: Request): string | undefined { const [type, token] = request.headers.authorization?.split(" ") ?? []; return type === "Bearer" ? token : undefined; } }