import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { AppLogger } from '../../logger'; import { GuardMetadata } from '../enums'; import { DecodedToken } from '../dto'; import { AuthenticationGuardService } from './services'; @Injectable() export class AuthenticationGuard implements CanActivate { private readonly TAG: string = `${this.constructor.name}`; constructor(private readonly authenticationGuardService: AuthenticationGuardService, private readonly reflector: Reflector) { AppLogger.log('Init', this.TAG); } async canActivate( context: ExecutionContext, ): Promise { const request: any = context.switchToHttp().getRequest(); if (request && request.headers && request.headers.authorization) { const cleanJwt: string = request.headers.authorization.substring(7, request.headers.authorization.length); const serviceAccountOnly: boolean = this.reflector.get(GuardMetadata.SERVICE_ACCOUNT_ONLY, context.getHandler()); const decodedToken: DecodedToken = await this.validateRequest(cleanJwt, serviceAccountOnly); if (!decodedToken) { throw new UnauthorizedException(); } request.token = decodedToken; return true; } throw new UnauthorizedException(); } async validateRequest(token: string, serviceAccountOnly: boolean): Promise { try { const decodedToken: DecodedToken = await this.authenticationGuardService.verify(token, serviceAccountOnly); if (!decodedToken) { throw new UnauthorizedException(); } return decodedToken; } catch (e) { AppLogger.error(e, this.TAG); throw new UnauthorizedException(); } } }