Converted Routes

This commit is contained in:
2025-12-06 19:29:47 +01:00
parent 7450f90a0f
commit d895583ea2
5 changed files with 898 additions and 61 deletions

View File

@@ -1,79 +1,140 @@
import { FastifyInstance } from "fastify";
import { FastifyInstance } from "fastify"
import {
authUsers,
authTenantUsers,
tenants,
authProfiles,
authUserRoles,
authRoles,
authRolePermissions,
} from "../../../db/schema"
import { eq, and, or, isNull } from "drizzle-orm"
export default async function meRoutes(server: FastifyInstance) {
server.get("/me", async (req, reply) => {
const authUser = req.user // kommt aus JWT (user_id + tenant_id)
try {
const authUser = req.user
if (!authUser) {
return reply.code(401).send({ error: "Unauthorized" })
}
if (!authUser) {
return reply.code(401).send({ error: "Unauthorized" })
}
const user_id = req.user.user_id
const tenant_id = req.user.tenant_id
const userId = authUser.user_id
const activeTenantId = authUser.tenant_id
// 1. User laden
const { data: user, error: userError } = await server.supabase
.from("auth_users")
.select("id, email, created_at, must_change_password")
.eq("id", authUser.user_id)
.single()
// ----------------------------------------------------
// 1) USER LADEN
// ----------------------------------------------------
const userResult = await server.db
.select({
id: authUsers.id,
email: authUsers.email,
created_at: authUsers.created_at,
must_change_password: authUsers.must_change_password,
})
.from(authUsers)
.where(eq(authUsers.id, userId))
.limit(1)
if (userError || !user) {
return reply.code(401).send({ error: "User not found" })
}
const user = userResult[0]
// 2. Tenants laden (alle Tenants des Users)
const { data: tenantLinks, error: tenantLinksError } = await server.supabase
.from("auth_users")
.select(`*, tenants!auth_tenant_users ( id, name,short, locked, extraModules, businessInfo, numberRanges, dokuboxkey, standardEmailForInvoices, standardPaymentDays )`)
.eq("id", authUser.user_id)
.single();
if (!user) {
return reply.code(401).send({ error: "User not found" })
}
if (tenantLinksError) {
// ----------------------------------------------------
// 2) TENANTS LADEN
// ----------------------------------------------------
const tenantRows = await server.db
.select({
id: tenants.id,
name: tenants.name,
short: tenants.short,
locked: tenants.locked,
extraModules: tenants.extraModules,
businessInfo: tenants.businessInfo,
numberRanges: tenants.numberRanges,
dokuboxkey: tenants.dokuboxkey,
standardEmailForInvoices: tenants.standardEmailForInvoices,
standardPaymentDays: tenants.standardPaymentDays,
})
.from(authTenantUsers)
.innerJoin(tenants, eq(authTenantUsers.tenant_id, tenants.id))
.where(eq(authTenantUsers.user_id, userId))
console.log(tenantLinksError)
const tenantList = tenantRows ?? []
return reply.code(401).send({ error: "Tenant Error" })
}
// ----------------------------------------------------
// 3) ACTIVE TENANT
// ----------------------------------------------------
const activeTenant = activeTenantId
const tenants = tenantLinks?.tenants
// ----------------------------------------------------
// 4) PROFIL LADEN
// ----------------------------------------------------
let profile = null
if (activeTenantId) {
const profileResult = await server.db
.select()
.from(authProfiles)
.where(
and(
eq(authProfiles.user_id, userId),
eq(authProfiles.tenant_id, activeTenantId)
)
)
.limit(1)
// 3. Aktiven Tenant bestimmen
const activeTenant = authUser.tenant_id /*|| tenants[0].id*/
profile = profileResult?.[0] ?? null
}
// 4. Profil für den aktiven Tenant laden
let profile = null
if (activeTenant) {
const { data: profileData } = await server.supabase
.from("auth_profiles")
.select("*")
.eq("user_id", user.id)
.eq("tenant_id", activeTenant)
.single()
// ----------------------------------------------------
// 5) PERMISSIONS — RPC ERSETZT
// ----------------------------------------------------
const permissionRows =
(await server.db
.select({
permission: authRolePermissions.permission,
})
.from(authUserRoles)
.innerJoin(
authRoles,
and(
eq(authRoles.id, authUserRoles.role_id),
or(
isNull(authRoles.tenant_id), // globale Rolle
eq(authRoles.tenant_id, activeTenantId) // tenant-spezifische Rolle
)
)
)
.innerJoin(
authRolePermissions,
eq(authRolePermissions.role_id, authRoles.id)
)
.where(
and(
eq(authUserRoles.user_id, userId),
eq(authUserRoles.tenant_id, activeTenantId)
)
)) ?? []
profile = profileData
}
const permissions = Array.from(
new Set(permissionRows.map((p) => p.permission))
)
// 5. Permissions laden (über Funktion)
const { data: permissionsData, error: permissionsError } = await server.supabase
.rpc("auth_get_user_permissions", {
uid: user.id,
tid: activeTenant || null
})
if(permissionsError) {
console.log(permissionsError)
}
const permissions = permissionsData.map(i => i.permission) || []
// 6. Response zurückgeben
return {
user,
tenants,
activeTenant,
profile,
permissions
// ----------------------------------------------------
// RESPONSE
// ----------------------------------------------------
return {
user,
tenants: tenantList,
activeTenant,
profile,
permissions,
}
} catch (err: any) {
console.error("ERROR in /me route:", err)
return reply.code(500).send({ error: "Internal server error" })
}
})
}
}