jest.mock('~/server/services/PermissionService', () => ({ findPubliclyAccessibleResources: jest.fn(), findAccessibleResources: jest.fn(), hasPublicPermission: jest.fn(), grantPermission: jest.fn().mockResolvedValue({}), })); jest.mock('~/server/services/Config', () => ({ getCachedTools: jest.fn(), getMCPServerTools: jest.fn(), })); const mongoose = require('mongoose'); const { actionDelimiter } = require('librechat-data-provider'); const { agentSchema, actionSchema } = require('@librechat/data-schemas'); const { MongoMemoryServer } = require('mongodb-memory-server'); const { duplicateAgent } = require('../v1'); let mongoServer; beforeAll(async () => { mongoServer = await MongoMemoryServer.create(); const mongoUri = mongoServer.getUri(); if (!mongoose.models.Agent) { mongoose.model('Agent', agentSchema); } if (!mongoose.models.Action) { mongoose.model('Action', actionSchema); } await mongoose.connect(mongoUri); }, 20000); afterAll(async () => { await mongoose.disconnect(); await mongoServer.stop(); }); beforeEach(async () => { await mongoose.models.Agent.deleteMany({}); await mongoose.models.Action.deleteMany({}); }); describe('duplicateAgentHandler — action domain extraction', () => { it('builds duplicated action entries using metadata.domain, not action_id', async () => { const userId = new mongoose.Types.ObjectId(); const originalAgentId = `agent_original`; const agent = await mongoose.models.Agent.create({ id: originalAgentId, name: 'Test Agent', author: userId.toString(), provider: 'openai', model: 'gpt-4', tools: [], actions: [`api.example.com${actionDelimiter}act_original`], versions: [{ name: 'Test Agent', createdAt: new Date(), updatedAt: new Date() }], }); await mongoose.models.Action.create({ user: userId, action_id: 'act_original', agent_id: originalAgentId, metadata: { domain: 'api.example.com' }, }); const req = { params: { id: agent.id }, user: { id: userId.toString() }, }; const res = { status: jest.fn().mockReturnThis(), json: jest.fn(), }; await duplicateAgent(req, res); expect(res.status).toHaveBeenCalledWith(201); const { agent: newAgent, actions: newActions } = res.json.mock.calls[0][0]; expect(newAgent.id).not.toBe(originalAgentId); expect(String(newAgent.author)).toBe(userId.toString()); expect(newActions).toHaveLength(1); expect(newActions[0].metadata.domain).toBe('api.example.com'); expect(newActions[0].agent_id).toBe(newAgent.id); for (const actionEntry of newAgent.actions) { const [domain, actionId] = actionEntry.split(actionDelimiter); expect(domain).toBe('api.example.com'); expect(actionId).toBeTruthy(); expect(actionId).not.toBe('act_original'); } const allActions = await mongoose.models.Action.find({}).lean(); expect(allActions).toHaveLength(2); const originalAction = allActions.find((a) => a.action_id === 'act_original'); expect(originalAction.agent_id).toBe(originalAgentId); const duplicatedAction = allActions.find((a) => a.action_id !== 'act_original'); expect(duplicatedAction.agent_id).toBe(newAgent.id); expect(duplicatedAction.metadata.domain).toBe('api.example.com'); }); it('strips sensitive metadata fields from duplicated actions', async () => { const userId = new mongoose.Types.ObjectId(); const originalAgentId = 'agent_sensitive'; await mongoose.models.Agent.create({ id: originalAgentId, name: 'Sensitive Agent', author: userId.toString(), provider: 'openai', model: 'gpt-4', tools: [], actions: [`secure.api.com${actionDelimiter}act_secret`], versions: [{ name: 'Sensitive Agent', createdAt: new Date(), updatedAt: new Date() }], }); await mongoose.models.Action.create({ user: userId, action_id: 'act_secret', agent_id: originalAgentId, metadata: { domain: 'secure.api.com', api_key: 'sk-secret-key-12345', oauth_client_id: 'client_id_xyz', oauth_client_secret: 'client_secret_xyz', }, }); const req = { params: { id: originalAgentId }, user: { id: userId.toString() }, }; const res = { status: jest.fn().mockReturnThis(), json: jest.fn(), }; await duplicateAgent(req, res); expect(res.status).toHaveBeenCalledWith(201); const duplicatedAction = await mongoose.models.Action.findOne({ agent_id: { $ne: originalAgentId }, }).lean(); expect(duplicatedAction.metadata.domain).toBe('secure.api.com'); expect(duplicatedAction.metadata.api_key).toBeUndefined(); expect(duplicatedAction.metadata.oauth_client_id).toBeUndefined(); expect(duplicatedAction.metadata.oauth_client_secret).toBeUndefined(); const originalAction = await mongoose.models.Action.findOne({ action_id: 'act_secret', }).lean(); expect(originalAction.metadata.api_key).toBe('sk-secret-key-12345'); }); });