import { Body, Controller, Headers, Post, UnauthorizedException } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { timingSafeEqual } from 'node:crypto'; import { ApiTags } from '@nestjs/swagger'; import { SecurityDetectionService, type SecurityEventInput } from './security-detection.service'; @ApiTags('gateway-security-events') @Controller('gateway/events/security-detection') export class SecurityEventController { constructor(private readonly security: SecurityDetectionService, private readonly config: ConfigService) {} @Post() record(@Body() body: SecurityEventInput, @Headers('x-security-event-token') supplied?: string) { const expected = this.config.get('SECURITY_EVENT_TOKEN'); if (!expected || !supplied || !safeEqual(expected, supplied)) throw new UnauthorizedException('安全事件来源认证失败'); return this.security.recordEvent(body); } } function safeEqual(left: string, right: string) { const a = Buffer.from(left); const b = Buffer.from(right); return a.length === b.length && timingSafeEqual(a, b); }