import { CanActivate, ExecutionContext, Injectable, HttpException, HttpStatus, Logger, Inject, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { LaunchpadApiClientAuthConfig } from '../models/launchpad.auth.config'; import * as jwt from 'jsonwebtoken'; import { LaunchpadApiService } from '../services/launchpad-api/launchpad-api-service'; import { LogBody } from '../models/logbody'; @Injectable() export class LaunchpadAccessGuard implements CanActivate { constructor( @Inject('LAUNCHPAD_AUTH_CONFIG') private readonly authConfig: LaunchpadApiClientAuthConfig, private launchpadApiService: LaunchpadApiService, ) {} canActivate(context: ExecutionContext): boolean | Promise | Observable { let canActivate = false; let jwtToken = context.switchToHttp().getRequest().headers['authorization']; if (jwtToken) { jwtToken = jwtToken.replace('Bearer ', ''); try { const claims = jwt.verify(jwtToken, this.authConfig.apiJwtConfig.secret, { ignoreExpiration: false, }) as any; canActivate = this.authConfig.customMethods.validateApiRequest ? this.authConfig.customMethods.validateApiRequest( context.switchToHttp().getRequest(), claims, ) : true; if (!canActivate) { Logger.warn(`JWTGuard, jwt access claims not validated, token: ${jwtToken}`); this.launchpadApiService.launchPadLog( new LogBody( claims.sub, 'authentication failure, logout', `${this.authConfig.apiName} user jwt access claims invalidated session ended, token: ` + jwtToken, ), ); } } catch (exception) { Logger.warn(`JWTGuard, jwt not verified, token: ${jwtToken}`); this.launchpadApiService.launchPadLog( new LogBody( 'no-verifiable-user', 'authentication failure, logout', `${this.authConfig.apiName} user jwt invalidated session ended, token: ` + jwtToken, ), ); throw new HttpException('Forbidden', HttpStatus.FORBIDDEN); } } else { Logger.warn(`JWTGuard, no JWT on request`); this.launchpadApiService.launchPadLog( new LogBody( 'no-verifiable-user', 'authentication failure, logout', `${this.authConfig.apiName} request with no JWT in header, session ended`, ), ); throw new HttpException('Forbidden', HttpStatus.FORBIDDEN); } return canActivate; } }