import { CanActivate, ExecutionContext, Injectable, Logger } from '@nestjs/common'; import { JwtAuthGuard } from './jwt-auth.guard'; import { ApiKeyGuard } from './api-key.guard'; import { lastValueFrom, isObservable } from 'rxjs'; @Injectable() export class JwtOrApiKeyGuard implements CanActivate { private readonly logger = new Logger(JwtOrApiKeyGuard.name); constructor( private readonly jwtGuard: JwtAuthGuard, private readonly apiKeyGuard: ApiKeyGuard, ) {} async canActivate(context: ExecutionContext): Promise { const req = context.switchToHttp().getRequest(); const tag = `[${req.method} ${req.url}]`; // Try JWT first try { const result = this.jwtGuard.canActivate(context); const jwtOk = isObservable(result) ? await lastValueFrom(result) : await result; if (jwtOk) { this.logger.debug(`${tag} authenticated via JWT`); return true; } } catch (err) { this.logger.debug(`${tag} JWT failed (${err.message}), trying API key…`); } // Fall back to API key return this.apiKeyGuard.canActivate(context); } }