fix: complete RBAC implementation lost during merge

Several RBAC features from feat/rbac-permissions were silently lost
during the merge into main. This restores and completes them:

- Add permissions and teamName to login/session API responses
- Export Permission and Role types from shared package
- Filter settings tabs by user permissions in frontend
- Extend useAuth hook with role, permissions, and hasPermission
- Restrict teams listing to admin only
- Add admin override for API keys, files, and pipelines listing
- Add ownership scoping to file access, download, and delete routes
- Register userFileRoutes in integration test server
- Mock auth import in unit permissions test to avoid SQLite lock
This commit is contained in:
Siddharth Kumar Sah
2026-04-10 21:25:30 +08:00
parent 6c6fb113fa
commit cc8a27239b
14 changed files with 126 additions and 194 deletions
+3 -3
View File
@@ -12,7 +12,7 @@ import { eq } from "drizzle-orm";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import sharp from "sharp";
import { db, schema } from "../db/index.js";
import { requirePermission } from "../permissions.js";
import { requireAdmin } from "../plugins/auth.js";
const BRANDING_DIR = join(process.cwd(), "data", "branding");
const LOGO_PATH = join(BRANDING_DIR, "logo.png");
@@ -33,7 +33,7 @@ function upsertSetting(key: string, value: string): void {
export async function brandingRoutes(app: FastifyInstance): Promise<void> {
// POST /api/v1/settings/logo — Upload logo (admin only)
app.post("/api/v1/settings/logo", async (request: FastifyRequest, reply: FastifyReply) => {
const admin = requirePermission("branding:manage")(request, reply);
const admin = requireAdmin(request, reply);
if (!admin) return;
const file = await request.file();
@@ -86,7 +86,7 @@ export async function brandingRoutes(app: FastifyInstance): Promise<void> {
// DELETE /api/v1/settings/logo — Remove logo (admin only)
app.delete("/api/v1/settings/logo", async (request: FastifyRequest, reply: FastifyReply) => {
const admin = requirePermission("branding:manage")(request, reply);
const admin = requireAdmin(request, reply);
if (!admin) return;
if (existsSync(LOGO_PATH)) {