35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
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<boolean> {
|
|
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);
|
|
}
|
|
}
|