import type { Hono } from "hono"; import type { AuthUser } from "./auth.ts"; import { requireAuth, tenantScope } from "./auth.ts"; import type { Db } from "./db.ts"; import { respondRpc } from "./http_errors.ts"; import { requirePermission, callIamFn } from "./permissions.ts"; type App = Hono<{ Variables: { user: AuthUser; db: Db } }>; export function registerIamRoutes(app: App) { app.get("/v1/iam/users", requireAuth, requirePermission("manage_users"), async (c) => { const tid = tenantScope(c.get("user")); const row = await callIamFn(tid, "iam.fn_user_list", { tenant_id: tid }); if (!row) { return respondRpc(c, { ok: false, code: "INTERNAL", layer: "api", message: "No se pudo consultar usuarios IAM", data: null, errors: null }); } return respondRpc(c, row as Parameters[1]); }); app.get("/v1/iam/permissions", requireAuth, requirePermission("manage_users"), async (c) => { const tid = tenantScope(c.get("user")); const row = await callIamFn(tid, "iam.fn_permission_list", {}); if (!row) { return respondRpc(c, { ok: false, code: "INTERNAL", layer: "api", message: "No se pudo consultar permisos IAM", data: null, errors: null }); } return respondRpc(c, row as Parameters[1]); }); app.get("/v1/iam/roles/:role/permissions", requireAuth, requirePermission("manage_users"), async (c) => { const tid = tenantScope(c.get("user")); const row = await callIamFn(tid, "iam.fn_role_permissions_get", { role_code: c.req.param("role") }); if (!row) { return respondRpc(c, { ok: false, code: "INTERNAL", layer: "api", message: "No se pudo consultar permisos del rol", data: null, errors: null }); } return respondRpc(c, row as Parameters[1]); }); app.put("/v1/iam/roles/:role/permissions", requireAuth, requirePermission("manage_users"), async (c) => { const body = await c.req.json<{ permissions?: string[] }>(); const tid = tenantScope(c.get("user")); const row = await callIamFn(tid, "iam.fn_role_permissions_save", { role_code: c.req.param("role"), permissions: body.permissions ?? [], }); if (!row) { return respondRpc(c, { ok: false, code: "INTERNAL", layer: "api", message: "No se pudo guardar permisos del rol", data: null, errors: null }); } return respondRpc(c, row as Parameters[1]); }); app.get("/v1/me/permissions", requireAuth, async (c) => { const user = c.get("user"); const { userPermissions } = await import("./permissions.ts"); const role = user.role === "tenant_admin" ? "tenant_admin" : "user"; const perms = await userPermissions(user.tenant_id, role); return respondRpc(c, { ok: true, code: "OK", layer: "api", message: `Permisos del usuario ${user.username}`, data: { permissions: [...perms], role: user.role }, errors: null, }); }); }