feat(internal-admin): add InternalTokenGuard for Süper Panel admin calls
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Foundation guard for /internal/admin/* endpoints called from Süper Panel (sp.semih.ai) over Coolify internal network. Verifies X-Internal-Token header against INTERNAL_API_TOKEN env with constant-time compare. Not yet wired to any endpoint — internal-admin module/controllers will land in follow-up commits as panel-side mutation features ship. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
28
apps/api/src/common/guards/internal-token.guard.ts
Normal file
28
apps/api/src/common/guards/internal-token.guard.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
type CanActivate,
|
||||
type ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from "@nestjs/common";
|
||||
import { timingSafeEqual } from "node:crypto";
|
||||
|
||||
@Injectable()
|
||||
export class InternalTokenGuard implements CanActivate {
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const expected = process.env.INTERNAL_API_TOKEN ?? "";
|
||||
if (!expected) {
|
||||
throw new UnauthorizedException("INTERNAL_API_TOKEN not configured");
|
||||
}
|
||||
const req = context.switchToHttp().getRequest();
|
||||
const provided = String(req.headers["x-internal-token"] ?? "");
|
||||
if (!provided) {
|
||||
throw new UnauthorizedException("missing internal token");
|
||||
}
|
||||
const a = Buffer.from(provided);
|
||||
const b = Buffer.from(expected);
|
||||
if (a.length !== b.length || !timingSafeEqual(a, b)) {
|
||||
throw new UnauthorizedException("invalid internal token");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user