Redone Auth
This commit is contained in:
@@ -1,55 +1,91 @@
|
|||||||
import { FastifyInstance } from "fastify";
|
import { FastifyInstance } from "fastify";
|
||||||
import fp from "fastify-plugin";
|
import fp from "fastify-plugin";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import {secrets} from "../utils/secrets";
|
import { secrets } from "../utils/secrets.js";
|
||||||
|
|
||||||
export default fp(async (server: FastifyInstance) => {
|
export default fp(async (server: FastifyInstance) => {
|
||||||
server.addHook("preHandler", async (req, reply) => {
|
server.addHook("preHandler", async (req, reply) => {
|
||||||
|
// 1️⃣ Token holen (Header oder Cookie)
|
||||||
try {
|
const cookieToken = req.cookies?.token;
|
||||||
// 1) Token aus Cookie lesen
|
const authHeader = req.headers.authorization;
|
||||||
const cookieToken = req.cookies?.token
|
|
||||||
|
|
||||||
// 2) Token aus Header lesen (falls Cookie nicht da ist)
|
|
||||||
const authHeader = req.headers.authorization
|
|
||||||
const headerToken = authHeader?.startsWith("Bearer ")
|
const headerToken = authHeader?.startsWith("Bearer ")
|
||||||
? authHeader.slice(7)
|
? authHeader.slice(7)
|
||||||
: null
|
: null;
|
||||||
|
|
||||||
let token = null
|
const token =
|
||||||
|
headerToken && headerToken.length > 10 ? headerToken : cookieToken || null;
|
||||||
if(headerToken !== null && headerToken.length > 10){
|
|
||||||
token = headerToken
|
|
||||||
} else if(cookieToken ){
|
|
||||||
token = cookieToken
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return // keine Exception → Route darf z. B. public sein
|
return reply.code(401).send({ error: "Authentication required" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 2️⃣ JWT verifizieren
|
||||||
const payload = jwt.verify(token, secrets.JWT_SECRET!) as {
|
const payload = jwt.verify(token, secrets.JWT_SECRET!) as {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
email: string;
|
email: string;
|
||||||
tenant_id?: string;
|
tenant_id: number;
|
||||||
role?: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(req as any).user = payload;
|
if (!payload?.user_id || !payload.tenant_id) {
|
||||||
|
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) {
|
||||||
|
server.log.error("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) {
|
||||||
|
server.log.error("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) {
|
} catch (err) {
|
||||||
return reply.code(401).send({ error: "Invalid or expired token" });
|
return reply.code(401).send({ error: "Invalid or expired token" });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 🧩 Fastify Type Declarations
|
||||||
declare module "fastify" {
|
declare module "fastify" {
|
||||||
interface FastifyRequest {
|
interface FastifyRequest {
|
||||||
user?: {
|
user: {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
email: string;
|
email: string;
|
||||||
tenant_id?: number;
|
tenant_id: number;
|
||||||
role?: string;
|
|
||||||
};
|
};
|
||||||
|
role: string;
|
||||||
|
permissions: string[];
|
||||||
|
hasPermission: (permission: string) => boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user