19 lines
1.1 KiB
TypeScript
19 lines
1.1 KiB
TypeScript
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<string>('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); }
|