29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
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;
|
|
}
|