import { FastifyInstance } from "fastify"; import fp from "fastify-plugin"; import jwt from "jsonwebtoken"; import { secrets } from "../utils/secrets"; export default fp(async (server: FastifyInstance) => { server.addHook("preHandler", async (req, reply) => { // 1️⃣ Token holen (Header oder Cookie) const cookieToken = req.cookies?.token; const authHeader = req.headers.authorization; const headerToken = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : null; const token = headerToken && headerToken.length > 10 ? headerToken : cookieToken || null; /*let token = null if(headerToken !== null && headerToken.length > 10){ token = headerToken } else if(cookieToken ){ token = cookieToken }*/ if (!token) { return reply.code(401).send({ error: "Authentication required" }); } try { // 2️⃣ JWT verifizieren const payload = jwt.verify(token, secrets.JWT_SECRET!) as { user_id: string; email: string; tenant_id: number; }; console.log("payload", payload); if (!payload?.user_id || !payload.tenant_id) { console.log(payload) return reply.code(401).send({ error: "Invalid token" }); } req.user = payload; // 3️⃣ Rolle des Nutzers im Tenant laden const { data: roleData, error: roleError } = await server.supabase .from("auth_user_roles") .select("role_id") .eq("user_id", payload.user_id) .eq("tenant_id", payload.tenant_id) .maybeSingle(); if (roleError) { console.log("Error fetching user role", roleError); return reply.code(500).send({ error: "Failed to load user role" }); } if (!roleData) { return reply.code(403).send({ error: "No role assigned for this tenant" }); } const roleId = roleData.role_id; // 4️⃣ Berechtigungen der Rolle laden const { data: permissions, error: permsError } = await server.supabase .from("auth_role_permissions") .select("permission") .eq("role_id", roleId); if (permsError) { console.log("Failed to load permissions", permsError); return reply.code(500).send({ error: "Permission lookup failed" }); } const perms = permissions?.map((p) => p.permission) ?? []; // 5️⃣ An Request hängen req.role = roleId; req.permissions = perms; req.hasPermission = (perm: string) => perms.includes(perm); } catch (err) { return reply.code(401).send({ error: "Invalid or expired token" }); } }); }); // 🧩 Fastify Type Declarations declare module "fastify" { interface FastifyRequest { user: { user_id: string; email: string; tenant_id: number; }; role: string; permissions: string[]; hasPermission: (permission: string) => boolean; } }