0a9588abb7
- Add pagination support to findAll (page, limit query params) - Add findByTemplateId method to service - Add GET /by-template/:templateId endpoint to controller - Service already includes CRUD for QuestionBank and QuestionBankItem
57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import {
|
|
Injectable,
|
|
CanActivate,
|
|
ExecutionContext,
|
|
UnauthorizedException,
|
|
} from '@nestjs/common';
|
|
import { Reflector } from '@nestjs/core';
|
|
import { UserService } from '../user/user.service';
|
|
import { Request } from 'express';
|
|
import { IS_PUBLIC_KEY } from './public.decorator';
|
|
|
|
@Injectable()
|
|
export class ApiKeyGuard implements CanActivate {
|
|
constructor(
|
|
private reflector: Reflector,
|
|
private userService: UserService,
|
|
) {}
|
|
|
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
|
context.getHandler(),
|
|
context.getClass(),
|
|
]);
|
|
if (isPublic) {
|
|
return true;
|
|
}
|
|
|
|
const request = context
|
|
.switchToHttp()
|
|
.getRequest<Request & { user?: any; tenantId?: string }>();
|
|
const apiKey = this.extractApiKeyFromHeader(request);
|
|
|
|
if (apiKey) {
|
|
const user = await this.userService.findByApiKey(apiKey);
|
|
if (user) {
|
|
request.user = user;
|
|
request.tenantId = user.tenantId;
|
|
return true;
|
|
}
|
|
throw new UnauthorizedException('Invalid API key');
|
|
}
|
|
|
|
throw new UnauthorizedException('Missing API key');
|
|
}
|
|
|
|
private extractApiKeyFromHeader(request: Request): string | undefined {
|
|
const authHeader = request.headers.authorization;
|
|
if (authHeader && authHeader.startsWith('Bearer kb_')) {
|
|
return authHeader.substring(7, authHeader.length);
|
|
}
|
|
const headerKey = request.headers['x-api-key'] as string;
|
|
if (headerKey) return headerKey;
|
|
|
|
return undefined;
|
|
}
|
|
}
|