feat: Add granular role-based permissions system with Entra ID integration

- Implement RBAC with viewer/editor/owner roles using bitwise permissions
      - Add AccessRole, AclEntry, and Group models for permission management
      - Create PermissionService for core permission logic and validation
      - Integrate Microsoft Graph API for Entra ID user/group search
      - Add middleware for resource access validation with custom ID resolvers
      - Implement bulk permission updates with transaction support
      - Create permission management UI with people picker and role selection
      - Add public sharing capabilities for resources
      - Include database migration for existing agent ownership
      - Support hybrid local/Entra ID identity management
      - Add comprehensive test coverage for all new services

chore: Update @librechat/data-schemas to version 0.0.9 and export common module in index.ts

fix: Update userGroup tests to mock logger correctly and change principalId expectation from null to undefined
This commit is contained in:
Danny Avila 2025-06-09 15:48:10 -04:00
parent fa54c9ae90
commit eed43e6662
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
88 changed files with 9992 additions and 539 deletions

View file

@ -35,3 +35,4 @@ export { default as useOnClickOutside } from './useOnClickOutside';
export { default as useSpeechToText } from './Input/useSpeechToText';
export { default as useTextToSpeech } from './Input/useTextToSpeech';
export { default as useGenerationsByLatest } from './useGenerationsByLatest';
export { useResourcePermissions } from './useResourcePermissions';

View file

@ -0,0 +1,25 @@
import {
useGetEffectivePermissionsQuery,
hasPermissions,
} from 'librechat-data-provider/react-query';
/**
* fetches resource permissions once and returns a function to check any permission
* More efficient when checking multiple permissions for the same resource
* @param resourceType - Type of resource (e.g., 'agent')
* @param resourceId - ID of the resource
* @returns Object with hasPermission function and loading state
*/
export const useResourcePermissions = (resourceType: string, resourceId: string) => {
const { data, isLoading } = useGetEffectivePermissionsQuery(resourceType, resourceId);
const hasPermission = (requiredPermission: number): boolean => {
return data ? hasPermissions(data.permissionBits, requiredPermission) : false;
};
return {
hasPermission,
isLoading,
permissionBits: data?.permissionBits || 0,
};
};