mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 07:51:02 +00:00
56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import {
|
|
CanActivate,
|
|
ExecutionContext,
|
|
Injectable,
|
|
Logger,
|
|
UnauthorizedException,
|
|
} from "@nestjs/common";
|
|
import { ConfigService } from "@nestjs/config";
|
|
import { timingSafeEqual } from "node:crypto";
|
|
import { Request } from "express";
|
|
|
|
/**
|
|
* Shared-secret service-to-service auth for the internal surface (/payments/*).
|
|
* Callers send `x-service-token: <SERVICE_AUTH_TOKEN>` (or `Authorization: Bearer …`).
|
|
* Webhook endpoints are intentionally NOT behind this guard — they are provider-facing and
|
|
* authenticate via signature verification instead.
|
|
*/
|
|
@Injectable()
|
|
export class ServiceAuthGuard implements CanActivate {
|
|
private readonly logger = new Logger(ServiceAuthGuard.name);
|
|
private readonly token: string;
|
|
private warned = false;
|
|
|
|
constructor(config: ConfigService) {
|
|
this.token = config.get<string>("app.serviceAuthToken") ?? "";
|
|
if (!this.token && process.env.NODE_ENV === "production") {
|
|
throw new Error("SERVICE_AUTH_TOKEN must be set in production");
|
|
}
|
|
}
|
|
|
|
canActivate(context: ExecutionContext): boolean {
|
|
if (!this.token) {
|
|
if (!this.warned) {
|
|
this.logger.warn(
|
|
"SERVICE_AUTH_TOKEN unset — internal endpoints are UNGUARDED (dev only)",
|
|
);
|
|
this.warned = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const request = context.switchToHttp().getRequest<Request>();
|
|
const header = request.headers["x-service-token"];
|
|
const bearer = request.headers.authorization?.replace(/^Bearer\s+/i, "");
|
|
const presented =
|
|
(Array.isArray(header) ? header[0] : header) ?? bearer ?? "";
|
|
|
|
const expected = Buffer.from(this.token);
|
|
const actual = Buffer.from(presented);
|
|
const valid =
|
|
expected.length === actual.length && timingSafeEqual(expected, actual);
|
|
if (!valid) throw new UnauthorizedException("Invalid service token");
|
|
return true;
|
|
}
|
|
}
|