import "server-only"; import { getSession } from "./auth-instance"; import { getIsUserAdmin } from "lib/user/utils"; import { admin, editor, user as userRole } from "./roles"; import type { BetterAuthRole } from "./types"; import { parseRoleString, isBetterAuthRole } from "./types"; /** * Simple permission helpers that wrap Better Auth's role system * * Philosophy: * - Keep it simple and clear * - Users can always manage themselves * - Only admins can manage other users * - Easy to show/hide UI elements * - Easy to extend for workflows, etc. later */ /** * Check if user has admin permissions (for showing/hiding admin areas) */ export async function hasAdminPermission(): Promise { try { const session = await getSession(); if (!session?.user) return false; const isAdmin = getIsUserAdmin(session.user); return isAdmin; } catch (error) { console.error("Error checking admin permission:", error); return false; } } /** * Check if user can list other users * Currently: only admins can list users */ export async function canListUsers(): Promise { return await hasAdminPermission(); } /** * Check if user can manage other users (create, edit, delete, etc.) * Currently: only admins can manage other users */ export async function canManageUsers(): Promise { return await hasAdminPermission(); } /** * Check if user can manage a specific user (themselves OR has manage permission) */ export async function canManageUser(targetUserId: string): Promise { try { const session = await getSession(); if (!session?.user) return false; // Can always manage own profile if (session.user.id === targetUserId) return true; // Or has admin permissions to manage other users return await canManageUsers(); } catch (error) { console.error("Error checking user management permission:", error); return false; } } /** * Require admin permissions or throw error */ export async function requireAdminPermission( action: string = "perform this action", ): Promise { const hasPermission = await hasAdminPermission(); if (!hasPermission) { throw new Error(`Unauthorized: Admin access required to ${action}`); } } /** * Require user list permissions or throw error */ export async function requireUserListPermission( action: string = "list users", ): Promise { const hasPermission = await canListUsers(); if (!hasPermission) { throw new Error(`Unauthorized: Permission required to ${action}`); } } /** * Require user management permissions or throw error */ export async function requireUserManagePermission( action: string = "manage users", ): Promise { const hasPermission = await canManageUsers(); if (!hasPermission) { throw new Error(`Unauthorized: Permission required to ${action}`); } } /** * Require permission to manage specific user or throw error */ export async function requireUserManagePermissionFor( targetUserId: string, action: string = "manage this user", ): Promise { const hasPermission = await canManageUser(targetUserId); if (!hasPermission) { throw new Error(`Unauthorized: Permission required to ${action}`); } } /** * Get current user session or null */ export async function getCurrentUser() { try { const session = await getSession(); return session?.user || null; } catch { return null; } } /** * Check if user is editor or admin (can create/edit resources) */ export async function hasEditorPermission(): Promise { try { const session = await getSession(); if (!session?.user) return false; // Check if user is admin or editor return session.user.role === "admin" || session.user.role === "editor"; } catch (error) { console.error("Error checking editor permission:", error); return false; } } /** * Get the role permissions based on user's role string */ function getRolePermissions(role: string | undefined | null): BetterAuthRole { const cleanRole = parseRoleString(role); switch (cleanRole) { case "admin": return admin as BetterAuthRole; case "editor": return editor as BetterAuthRole; case "user": default: return userRole as BetterAuthRole; } } /** * Check if role has specific permission for a resource */ function hasPermission( userRoleString: string | undefined | null, permission: | "use" | "create" | "list" | "delete" | "update" | "view" | "share", resource: "agent" | "workflow" | "mcp", ): boolean { const roleObject = getRolePermissions(userRoleString); // Validate role object structure if (!isBetterAuthRole(roleObject)) { console.error("Invalid role object structure"); return false; } const statements = roleObject.statements; const resourcePermissions = statements[resource] || []; return ( Array.isArray(resourcePermissions) && resourcePermissions.includes(permission) ); } /** * Check if user can create agents */ export async function canCreateAgent(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "create", "agent"); } catch (error) { console.error("Error checking agent create permission:", error); return false; } } /** * Check if user can edit agents */ export async function canEditAgent(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "update", "agent"); } catch (error) { console.error("Error checking agent edit permission:", error); return false; } } /** * Check if user can delete agents */ export async function canDeleteAgent(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "delete", "agent"); } catch (error) { console.error("Error checking agent delete permission:", error); return false; } } /** * Check if user can create workflows */ export async function canCreateWorkflow(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "create", "workflow"); } catch (error) { console.error("Error checking workflow create permission:", error); return false; } } /** * Check if user can edit workflows */ export async function canEditWorkflow(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "update", "workflow"); } catch (error) { console.error("Error checking workflow edit permission:", error); return false; } } /** * Check if user can delete workflows */ export async function canDeleteWorkflow(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "delete", "workflow"); } catch (error) { console.error("Error checking workflow delete permission:", error); return false; } } /** * Check if user can create MCP connections */ export async function canCreateMCP(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "create", "mcp"); } catch (error) { console.error("Error checking MCP create permission:", error); return false; } } /** * Check if user can edit MCP connections */ export async function canEditMCP(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "update", "mcp"); } catch (error) { console.error("Error checking MCP edit permission:", error); return false; } } /** * Check if user can change visibility of MCP connections */ export async function canChangeVisibilityMCP(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "share", "mcp"); } catch (error) { console.error("Error checking MCP visibility change permission:", error); return false; } } /** * Check if user can delete MCP connections */ export async function canDeleteMCP(): Promise { try { const session = await getSession(); if (!session?.user) return false; return hasPermission(session.user.role, "delete", "mcp"); } catch (error) { console.error("Error checking MCP delete permission:", error); return false; } } /** * Require editor permissions or throw error */ export async function requireEditorPermission( action: string = "perform this action", ): Promise { const hasPermission = await hasEditorPermission(); if (!hasPermission) { throw new Error( `Unauthorized: Editor or Admin access required to ${action}`, ); } } /** * Check if user can manage a specific MCP server * Users can manage their own servers, admins can manage all */ export async function canManageMCPServer( mcpOwnerId: string, visibility: string = "private", ): Promise { try { const session = await getSession(); if (!session?.user) return false; // Admins can manage all MCP servers if (session.user.role === "admin") return true; // Users can only manage their own private MCP servers if (session.user.id === mcpOwnerId && visibility === "private") return true; return false; } catch (error) { console.error("Error checking MCP management permission:", error); return false; } } /** * Check if user can share MCP servers (admin only) */ export async function canShareMCPServer(): Promise { return await hasAdminPermission(); }