import { CanActivate, ExecutionContext, Injectable, UnauthorizedException, } from "@nestjs/common"; import { JwtService } from "@nestjs/jwt"; import { ActorAuthService } from "src/auth/auth-services/actor.auth.service"; import { RoleEnum } from "src/Types&Enums/role.enum"; @Injectable() export class LocalActorAuthGuard implements CanActivate { constructor( private readonly actorAuthService: ActorAuthService, private readonly jwtService: JwtService, ) {} async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); const token = this.extractTokenFromHeader(request); if (!token) { if (this.isActorLoginRequest(request)) { const loginData = await this.actorAuthService.loginFromCredentials( request.body ?? {}, ); request.user = loginData; request.identity = loginData; return true; } throw new UnauthorizedException("Token not found"); } try { const payload = await this.jwtService.verifyAsync(token, { secret: `${process.env.JWT_SECRET}`, }); if ( ![ RoleEnum.EXPERT, RoleEnum.DAMAGE_EXPERT, RoleEnum.COMPANY, RoleEnum.FIELD_EXPERT, RoleEnum.REGISTRAR, ].includes(payload.role) ) { throw new UnauthorizedException("User role is not authorized"); } request.user = payload; request.identity = request.user; } catch { throw new UnauthorizedException("Invalid token"); } return true; } private isActorLoginRequest(request: { url?: string; path?: string; route?: { path?: string }; }): boolean { const path = (request.route?.path ?? request.url ?? request.path ?? "") .split("?")[0] .replace(/\/+$/, ""); return path === "/actor/login" || path.endsWith("/actor/login"); } private extractTokenFromHeader(request: { headers?: { authorization?: string }; }): string | undefined { const [type, token] = request.headers?.authorization?.split(" ") ?? []; return type === "Bearer" ? token : undefined; } }