feat(backend): enforce user-owned sessions

This commit is contained in:
User
2026-07-16 18:32:52 +02:00
parent 72db6b823d
commit 458eb13c89
15 changed files with 626 additions and 105 deletions
+14 -9
View File
@@ -1,23 +1,28 @@
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 as any).user = { id: "dev@local" };
req.principal = localPrincipal();
} else if (mode === "mock") {
(req as any).user = {
id: (req.headers["x-mock-user"] as string) ?? "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 id = req.headers["x-authenticated-user"];
if (typeof id !== "string" || id.trim() === "") {
const principal = upstreamPrincipal(req.headers);
if (!principal) {
return reply.code(401).send({ error: "authenticated upstream identity required" });
}
(req as any).user = { id };
req.principal = principal;
}
};
}
export function getUser(req: FastifyRequest): { id: string } {
return (req as any).user ?? { id: "dev@local" };
export function getPrincipal(req: FastifyRequest): PrincipalContext {
if (!req.principal) throw new Error("principal missing after authentication");
return req.principal;
}