mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-21 02:40:14 +01:00
🔧 refactor: Organize Sharing/Agent Components and Improve Type Safety
refactor: organize Sharing/Agent components, improve type safety for resource types and access role ids, rename enums to PascalCase refactor: organize Sharing/Agent components, improve type safety for resource types and access role ids chore: move sharing related components to dedicated "Sharing" directory chore: remove PublicSharingToggle component and update index exports chore: move non-sidepanel agent components to `~/components/Agents` chore: move AgentCategoryDisplay component with tests chore: remove commented out code refactor: change PERMISSION_BITS from const to enum for better type safety refactor: reorganize imports in GenericGrantAccessDialog and update index exports for hooks refactor: update type definitions to use ACCESS_ROLE_IDS for improved type safety refactor: remove unused canAccessPromptResource middleware and related code refactor: remove unused prompt access roles from createAccessRoleMethods refactor: update resourceType in AclEntry type definition to remove unused 'prompt' value refactor: introduce ResourceType enum and update resourceType usage across data provider files for improved type safety refactor: update resourceType usage to ResourceType enum across sharing and permissions components for improved type safety refactor: standardize resourceType usage to ResourceType enum across agent and prompt models, permissions controller, and middleware for enhanced type safety refactor: update resourceType references from PROMPT_GROUP to PROMPTGROUP for consistency across models, middleware, and components refactor: standardize access role IDs and resource type usage across agent, file, and prompt models for improved type safety and consistency chore: add typedefs for TUpdateResourcePermissionsRequest and TUpdateResourcePermissionsResponse to enhance type definitions chore: move SearchPicker to PeoplePicker dir refactor: implement debouncing for query changes in SearchPicker for improved performance chore: fix typing, import order for agent admin settings fix: agent admin settings, prevent agent form submission refactor: rename `ACCESS_ROLE_IDS` to `AccessRoleIds` refactor: replace PermissionBits with PERMISSION_BITS refactor: replace PERMISSION_BITS with PermissionBits
This commit is contained in:
parent
ae732b2ebc
commit
81b32e400a
96 changed files with 781 additions and 798 deletions
|
|
@ -25,26 +25,35 @@ export type TPrincipalSource = 'local' | 'entra';
|
|||
*/
|
||||
export type TAccessLevel = 'none' | 'viewer' | 'editor' | 'owner';
|
||||
|
||||
/**
|
||||
* Resource types for permission system
|
||||
*/
|
||||
export enum ResourceType {
|
||||
AGENT = 'agent',
|
||||
PROMPTGROUP = 'promptGroup',
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission bit constants for bitwise operations
|
||||
*/
|
||||
export const PERMISSION_BITS = {
|
||||
VIEW: 1, // 001 - Can view and use agent
|
||||
EDIT: 2, // 010 - Can modify agent settings
|
||||
DELETE: 4, // 100 - Can delete agent
|
||||
SHARE: 8, // 1000 - Can share agent with others (future)
|
||||
} as const;
|
||||
export enum PermissionBits {
|
||||
/** 001 - Can view and use agent */
|
||||
VIEW = 1,
|
||||
/** 010 - Can modify agent settings */
|
||||
EDIT = 2,
|
||||
/** 100 - Can delete agent */
|
||||
DELETE = 4,
|
||||
/** 1000 - Can share agent with others (future) */
|
||||
SHARE = 8,
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard access role IDs
|
||||
*/
|
||||
export enum ACCESS_ROLE_IDS {
|
||||
export enum AccessRoleIds {
|
||||
AGENT_VIEWER = 'agent_viewer',
|
||||
AGENT_EDITOR = 'agent_editor',
|
||||
AGENT_OWNER = 'agent_owner', // Future use
|
||||
PROMPT_VIEWER = 'prompt_viewer',
|
||||
PROMPT_EDITOR = 'prompt_editor',
|
||||
PROMPT_OWNER = 'prompt_owner',
|
||||
AGENT_OWNER = 'agent_owner',
|
||||
PROMPTGROUP_VIEWER = 'promptGroup_viewer',
|
||||
PROMPTGROUP_EDITOR = 'promptGroup_editor',
|
||||
PROMPTGROUP_OWNER = 'promptGroup_owner',
|
||||
|
|
@ -64,7 +73,7 @@ export const principalSchema = z.object({
|
|||
avatar: z.string().optional(), // for user and group types
|
||||
description: z.string().optional(), // for group type
|
||||
idOnTheSource: z.string().optional(), // Entra ID for users/groups
|
||||
accessRoleId: z.nativeEnum(ACCESS_ROLE_IDS).optional(), // Access role ID for permissions
|
||||
accessRoleId: z.nativeEnum(AccessRoleIds).optional(), // Access role ID for permissions
|
||||
memberCount: z.number().optional(), // for group type
|
||||
});
|
||||
|
||||
|
|
@ -72,10 +81,10 @@ export const principalSchema = z.object({
|
|||
* Access role schema - defines named permission sets
|
||||
*/
|
||||
export const accessRoleSchema = z.object({
|
||||
accessRoleId: z.nativeEnum(ACCESS_ROLE_IDS),
|
||||
accessRoleId: z.nativeEnum(AccessRoleIds),
|
||||
name: z.string(),
|
||||
description: z.string().optional(),
|
||||
resourceType: z.string().default('agent'),
|
||||
resourceType: z.nativeEnum(ResourceType).default(ResourceType.AGENT),
|
||||
permBits: z.number(),
|
||||
});
|
||||
|
||||
|
|
@ -98,7 +107,7 @@ export const permissionEntrySchema = z.object({
|
|||
* Resource permissions response schema
|
||||
*/
|
||||
export const resourcePermissionsResponseSchema = z.object({
|
||||
resourceType: z.string(),
|
||||
resourceType: z.nativeEnum(ResourceType),
|
||||
resourceId: z.string(),
|
||||
permissions: z.array(permissionEntrySchema),
|
||||
});
|
||||
|
|
@ -210,7 +219,7 @@ export type TPrincipalSearchResponse = {
|
|||
* Available roles response
|
||||
*/
|
||||
export type TAvailableRolesResponse = {
|
||||
resourceType: string;
|
||||
resourceType: ResourceType;
|
||||
roles: TAccessRole[];
|
||||
};
|
||||
|
||||
|
|
@ -219,11 +228,11 @@ export type TAvailableRolesResponse = {
|
|||
* This matches the enhanced aggregation-based endpoint response format
|
||||
*/
|
||||
export const getResourcePermissionsResponseSchema = z.object({
|
||||
resourceType: z.string(),
|
||||
resourceId: z.string(),
|
||||
resourceType: z.nativeEnum(ResourceType),
|
||||
resourceId: z.nativeEnum(AccessRoleIds),
|
||||
principals: z.array(principalSchema),
|
||||
public: z.boolean(),
|
||||
publicAccessRoleId: z.string().optional(),
|
||||
publicAccessRoleId: z.nativeEnum(AccessRoleIds).optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -265,9 +274,9 @@ export interface TPermissionCheck {
|
|||
* Convert permission bits to access level
|
||||
*/
|
||||
export function permBitsToAccessLevel(permBits: number): TAccessLevel {
|
||||
if ((permBits & PERMISSION_BITS.DELETE) > 0) return 'owner';
|
||||
if ((permBits & PERMISSION_BITS.EDIT) > 0) return 'editor';
|
||||
if ((permBits & PERMISSION_BITS.VIEW) > 0) return 'viewer';
|
||||
if ((permBits & PermissionBits.DELETE) > 0) return 'owner';
|
||||
if ((permBits & PermissionBits.EDIT) > 0) return 'editor';
|
||||
if ((permBits & PermissionBits.VIEW) > 0) return 'viewer';
|
||||
return 'none';
|
||||
}
|
||||
|
||||
|
|
@ -276,14 +285,14 @@ export function permBitsToAccessLevel(permBits: number): TAccessLevel {
|
|||
*/
|
||||
export function accessRoleToPermBits(accessRoleId: string): number {
|
||||
switch (accessRoleId) {
|
||||
case ACCESS_ROLE_IDS.AGENT_VIEWER:
|
||||
return PERMISSION_BITS.VIEW;
|
||||
case ACCESS_ROLE_IDS.AGENT_EDITOR:
|
||||
return PERMISSION_BITS.VIEW | PERMISSION_BITS.EDIT;
|
||||
case ACCESS_ROLE_IDS.AGENT_OWNER:
|
||||
return PERMISSION_BITS.VIEW | PERMISSION_BITS.EDIT | PERMISSION_BITS.DELETE;
|
||||
case AccessRoleIds.AGENT_VIEWER:
|
||||
return PermissionBits.VIEW;
|
||||
case AccessRoleIds.AGENT_EDITOR:
|
||||
return PermissionBits.VIEW | PermissionBits.EDIT;
|
||||
case AccessRoleIds.AGENT_OWNER:
|
||||
return PermissionBits.VIEW | PermissionBits.EDIT | PermissionBits.DELETE;
|
||||
default:
|
||||
return PERMISSION_BITS.VIEW;
|
||||
return PermissionBits.VIEW;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { AssistantsEndpoint } from './schemas';
|
||||
import * as q from './types/queries';
|
||||
import { ResourceType } from './accessPermissions';
|
||||
|
||||
// Testing this buildQuery function
|
||||
const buildQuery = (params: Record<string, unknown>): string => {
|
||||
|
|
@ -323,15 +324,16 @@ export const searchPrincipals = (params: q.PrincipalSearchParams) => {
|
|||
return url;
|
||||
};
|
||||
|
||||
export const getAccessRoles = (resourceType: string) => `/api/permissions/${resourceType}/roles`;
|
||||
export const getAccessRoles = (resourceType: ResourceType) =>
|
||||
`/api/permissions/${resourceType}/roles`;
|
||||
|
||||
export const getResourcePermissions = (resourceType: string, resourceId: string) =>
|
||||
export const getResourcePermissions = (resourceType: ResourceType, resourceId: string) =>
|
||||
`/api/permissions/${resourceType}/${resourceId}`;
|
||||
|
||||
export const updateResourcePermissions = (resourceType: string, resourceId: string) =>
|
||||
export const updateResourcePermissions = (resourceType: ResourceType, resourceId: string) =>
|
||||
`/api/permissions/${resourceType}/${resourceId}`;
|
||||
|
||||
export const getEffectivePermissions = (resourceType: string, resourceId: string) =>
|
||||
export const getEffectivePermissions = (resourceType: ResourceType, resourceId: string) =>
|
||||
`/api/permissions/${resourceType}/${resourceId}/effective`;
|
||||
|
||||
// SharePoint Graph API Token
|
||||
|
|
|
|||
|
|
@ -909,19 +909,21 @@ export function searchPrincipals(
|
|||
return request.get(endpoints.searchPrincipals(params));
|
||||
}
|
||||
|
||||
export function getAccessRoles(resourceType: string): Promise<q.AccessRolesResponse> {
|
||||
export function getAccessRoles(
|
||||
resourceType: permissions.ResourceType,
|
||||
): Promise<q.AccessRolesResponse> {
|
||||
return request.get(endpoints.getAccessRoles(resourceType));
|
||||
}
|
||||
|
||||
export function getResourcePermissions(
|
||||
resourceType: string,
|
||||
resourceType: permissions.ResourceType,
|
||||
resourceId: string,
|
||||
): Promise<permissions.TGetResourcePermissionsResponse> {
|
||||
return request.get(endpoints.getResourcePermissions(resourceType, resourceId));
|
||||
}
|
||||
|
||||
export function updateResourcePermissions(
|
||||
resourceType: string,
|
||||
resourceType: permissions.ResourceType,
|
||||
resourceId: string,
|
||||
data: permissions.TUpdateResourcePermissionsRequest,
|
||||
): Promise<permissions.TUpdateResourcePermissionsResponse> {
|
||||
|
|
@ -929,7 +931,7 @@ export function updateResourcePermissions(
|
|||
}
|
||||
|
||||
export function getEffectivePermissions(
|
||||
resourceType: string,
|
||||
resourceType: permissions.ResourceType,
|
||||
resourceId: string,
|
||||
): Promise<permissions.TEffectivePermissionsResponse> {
|
||||
return request.get(endpoints.getEffectivePermissions(resourceType, resourceId));
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { QueryKeys } from '../keys';
|
|||
import * as s from '../schemas';
|
||||
import * as t from '../types';
|
||||
import * as permissions from '../accessPermissions';
|
||||
import { ResourceType } from '../accessPermissions';
|
||||
|
||||
export { hasPermissions } from '../accessPermissions';
|
||||
|
||||
|
|
@ -405,7 +406,7 @@ export const useSearchPrincipalsQuery = (
|
|||
};
|
||||
|
||||
export const useGetAccessRolesQuery = (
|
||||
resourceType: string,
|
||||
resourceType: ResourceType,
|
||||
config?: UseQueryOptions<q.AccessRolesResponse>,
|
||||
): QueryObserverResult<q.AccessRolesResponse> => {
|
||||
return useQuery<q.AccessRolesResponse>(
|
||||
|
|
@ -423,7 +424,7 @@ export const useGetAccessRolesQuery = (
|
|||
};
|
||||
|
||||
export const useGetResourcePermissionsQuery = (
|
||||
resourceType: string,
|
||||
resourceType: ResourceType,
|
||||
resourceId: string,
|
||||
config?: UseQueryOptions<permissions.TGetResourcePermissionsResponse>,
|
||||
): QueryObserverResult<permissions.TGetResourcePermissionsResponse> => {
|
||||
|
|
@ -445,7 +446,7 @@ export const useUpdateResourcePermissionsMutation = (): UseMutationResult<
|
|||
permissions.TUpdateResourcePermissionsResponse,
|
||||
Error,
|
||||
{
|
||||
resourceType: string;
|
||||
resourceType: ResourceType;
|
||||
resourceId: string;
|
||||
data: permissions.TUpdateResourcePermissionsRequest;
|
||||
}
|
||||
|
|
@ -472,7 +473,7 @@ export const useUpdateResourcePermissionsMutation = (): UseMutationResult<
|
|||
};
|
||||
|
||||
export const useGetEffectivePermissionsQuery = (
|
||||
resourceType: string,
|
||||
resourceType: ResourceType,
|
||||
resourceId: string,
|
||||
config?: UseQueryOptions<permissions.TEffectivePermissionsResponse>,
|
||||
): QueryObserverResult<permissions.TEffectivePermissionsResponse> => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { InfiniteData } from '@tanstack/react-query';
|
||||
import type { ACCESS_ROLE_IDS } from '../accessPermissions';
|
||||
import type { AccessRoleIds } from '../accessPermissions';
|
||||
import type * as a from '../types/agents';
|
||||
import type * as s from '../schemas';
|
||||
import type * as t from '../types';
|
||||
|
|
@ -159,7 +159,7 @@ export type PrincipalSearchResponse = {
|
|||
};
|
||||
|
||||
export type AccessRole = {
|
||||
accessRoleId: ACCESS_ROLE_IDS;
|
||||
accessRoleId: AccessRoleIds;
|
||||
name: string;
|
||||
description: string;
|
||||
permBits: number;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue