mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
👤 feat: Agent Avatar Removal and Decouple upload/reset from Agent Updates (#10527)
* ✨ feat: Enhance agent avatar management with upload and reset functionality * ✨ feat: Refactor AvatarMenu to use DropdownPopup for improved UI and functionality * ✨ feat: Improve avatar upload handling in AgentPanel to suppress misleading "no changes" toast * ✨ feat: Refactor toast message handling and payload composition in AgentPanel for improved clarity and functionality * ✨ feat: Enhance agent avatar functionality with upload, reset, and validation improvements * ✨ feat: Refactor agent avatar upload handling and enhance related components for improved functionality and user experience * feat(agents): tighten ACL, harden GETs/search, and sanitize action metadata stop persisting refreshed S3 URLs on GET; compute per-response only enforce ACL EDIT on revert route; remove legacy admin/author/collab checks sanitize action metadata before persisting during duplication (api_key, oauth_client_id, oauth_client_secret) escape user search input, cap length (100), and use Set for public flag mapping add explicit req.file guard in avatar upload; fix empty catch lint; remove unused imports * feat: Remove outdated avatar-related translation keys * feat: Improve error logging for avatar updates and streamline file input handling * feat(agents): implement caching for S3 avatar refresh in agent list responses * fix: replace unconventional 'void e' with explicit comment to clarify intentionally ignored error Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * feat(agents): enhance avatar handling and improve search functionality * fix: clarify intentionally ignored error in agent list handler --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
c0cb48256e
commit
8907bd5d7c
17 changed files with 931 additions and 398 deletions
|
|
@ -47,6 +47,7 @@ jest.mock('~/server/services/PermissionService', () => ({
|
|||
findPubliclyAccessibleResources: jest.fn().mockResolvedValue([]),
|
||||
grantPermission: jest.fn(),
|
||||
hasPublicPermission: jest.fn().mockResolvedValue(false),
|
||||
checkPermission: jest.fn().mockResolvedValue(true),
|
||||
}));
|
||||
|
||||
jest.mock('~/models', () => ({
|
||||
|
|
@ -573,6 +574,68 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
|
|||
expect(updatedAgent.version).toBe(agentInDb.versions.length);
|
||||
});
|
||||
|
||||
test('should allow resetting avatar when value is explicitly null', async () => {
|
||||
await Agent.updateOne(
|
||||
{ id: existingAgentId },
|
||||
{
|
||||
avatar: {
|
||||
filepath: 'https://example.com/avatar.png',
|
||||
source: 's3',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
mockReq.user.id = existingAgentAuthorId.toString();
|
||||
mockReq.params.id = existingAgentId;
|
||||
mockReq.body = {
|
||||
avatar: null,
|
||||
};
|
||||
|
||||
await updateAgentHandler(mockReq, mockRes);
|
||||
|
||||
const updatedAgent = mockRes.json.mock.calls[0][0];
|
||||
expect(updatedAgent.avatar).toBeNull();
|
||||
|
||||
const agentInDb = await Agent.findOne({ id: existingAgentId });
|
||||
expect(agentInDb.avatar).toBeNull();
|
||||
});
|
||||
|
||||
test('should ignore avatar field when value is undefined', async () => {
|
||||
const originalAvatar = {
|
||||
filepath: 'https://example.com/original.png',
|
||||
source: 's3',
|
||||
};
|
||||
await Agent.updateOne({ id: existingAgentId }, { avatar: originalAvatar });
|
||||
|
||||
mockReq.user.id = existingAgentAuthorId.toString();
|
||||
mockReq.params.id = existingAgentId;
|
||||
mockReq.body = {
|
||||
avatar: undefined,
|
||||
};
|
||||
|
||||
await updateAgentHandler(mockReq, mockRes);
|
||||
|
||||
const agentInDb = await Agent.findOne({ id: existingAgentId });
|
||||
expect(agentInDb.avatar.filepath).toBe(originalAvatar.filepath);
|
||||
expect(agentInDb.avatar.source).toBe(originalAvatar.source);
|
||||
});
|
||||
|
||||
test('should not bump version when no mutable fields change', async () => {
|
||||
const existingAgent = await Agent.findOne({ id: existingAgentId });
|
||||
const originalVersionCount = existingAgent.versions.length;
|
||||
|
||||
mockReq.user.id = existingAgentAuthorId.toString();
|
||||
mockReq.params.id = existingAgentId;
|
||||
mockReq.body = {
|
||||
avatar: undefined,
|
||||
};
|
||||
|
||||
await updateAgentHandler(mockReq, mockRes);
|
||||
|
||||
const agentInDb = await Agent.findOne({ id: existingAgentId });
|
||||
expect(agentInDb.versions.length).toBe(originalVersionCount);
|
||||
});
|
||||
|
||||
test('should handle validation errors properly', async () => {
|
||||
mockReq.user.id = existingAgentAuthorId.toString();
|
||||
mockReq.params.id = existingAgentId;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue