import type { FastifyRequest, FastifyReply } from "fastify"; import { localPrincipal, type PrincipalContext, upstreamPrincipal } from "./principal.js"; declare module "fastify" { interface FastifyRequest { principal?: PrincipalContext } } export function authPreHandler(mode: "none" | "mock" | "upstream") { return async (req: FastifyRequest, reply: FastifyReply) => { if (mode === "none") { req.principal = localPrincipal(); } else if (mode === "mock") { const subject = typeof req.headers["x-mock-user"] === "string" ? req.headers["x-mock-user"].trim() : "mock"; req.principal = { issuer: "mock", subject: subject || "mock", displayName: subject || "mock", isAdmin: false }; } else { const principal = upstreamPrincipal(req.headers); if (!principal) { return reply.code(401).send({ error: "authenticated upstream identity required" }); } req.principal = principal; } }; } export function getPrincipal(req: FastifyRequest): PrincipalContext { if (!req.principal) throw new Error("principal missing after authentication"); return req.principal; }