feat(backend): enforce user-owned sessions
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user