e115934061
Publish `@librechat/data-schemas` to NPM / pack (push) Failing after 8s
Publish `@librechat/client` to NPM / pack (push) Failing after 0s
GitNexus Index / index (push) Failing after 1s
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been skipped
Sync Helm Chart Tags / Sync chart tags (push) Failing after 2s
Publish `librechat-data-provider` to NPM / pack (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Failing after 0s
Sync Helm Chart Tags / Ignore non-main push (push) Has been skipped
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Failing after 1s
Publish `@librechat/client` to NPM / publish-npm (push) Has been cancelled
Publish `librechat-data-provider` to NPM / publish-npm (push) Has been cancelled
GitNexus Index / post-index (push) Has been cancelled
Publish `@librechat/data-schemas` to NPM / publish-npm (push) Has been cancelled
103 lines
3.3 KiB
JavaScript
103 lines
3.3 KiB
JavaScript
jest.mock('@librechat/data-schemas', () => ({
|
|
logger: { debug: jest.fn(), error: jest.fn(), warn: jest.fn() },
|
|
}));
|
|
|
|
jest.mock('@librechat/api', () => ({
|
|
checkAccess: jest.fn(),
|
|
loadWebSearchAuth: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('~/models', () => ({
|
|
getRoleByName: jest.fn(),
|
|
createToolCall: jest.fn(),
|
|
getToolCallsByConvo: jest.fn(),
|
|
getMessage: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('~/server/services/Files/process', () => ({
|
|
processFileURL: jest.fn(),
|
|
uploadImageBuffer: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('~/server/services/Files/Code/process', () => ({
|
|
processCodeOutput: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('~/server/services/Tools/credentials', () => ({
|
|
loadAuthValues: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('~/app/clients/tools/util', () => ({
|
|
loadTools: jest.fn(),
|
|
}));
|
|
|
|
const { Tools, AuthType } = require('librechat-data-provider');
|
|
const { verifyToolAuth } = require('../tools');
|
|
|
|
/**
|
|
* Phase 8 behavioral pin: `verifyToolAuth(execute_code)` unconditionally
|
|
* returns system-authenticated. Sandbox auth moved server-side into the
|
|
* agents library, so the per-user `CODE_API_KEY` check that previously
|
|
* gated this endpoint is gone. The deployment contract is: if the
|
|
* admin enabled the `execute_code` capability, the sandbox is
|
|
* reachable. This endpoint does not probe reachability (would be too
|
|
* expensive per UI-gate query); failures surface at execution time.
|
|
*
|
|
* A regression where someone re-adds an auth check here would
|
|
* resurrect the per-user key-entry dialog on the client, which Phase 8
|
|
* explicitly removed. Pin the contract.
|
|
*/
|
|
describe('verifyToolAuth — execute_code system-auth contract', () => {
|
|
const makeReq = (toolId) => ({
|
|
params: { toolId },
|
|
user: { id: 'user-1' },
|
|
config: {},
|
|
});
|
|
|
|
const makeRes = () => {
|
|
const res = {};
|
|
res.status = jest.fn().mockReturnValue(res);
|
|
res.json = jest.fn().mockReturnValue(res);
|
|
return res;
|
|
};
|
|
|
|
it('returns authenticated: true with SYSTEM_DEFINED for execute_code', async () => {
|
|
const res = makeRes();
|
|
await verifyToolAuth(makeReq(Tools.execute_code), res);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(200);
|
|
expect(res.json).toHaveBeenCalledWith({
|
|
authenticated: true,
|
|
message: AuthType.SYSTEM_DEFINED,
|
|
});
|
|
});
|
|
|
|
it('returns 404 for unknown tool ids (not in directCallableTools)', async () => {
|
|
const res = makeRes();
|
|
await verifyToolAuth(makeReq('not_a_real_tool'), res);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(404);
|
|
expect(res.json).toHaveBeenCalledWith({ message: 'Tool not found' });
|
|
});
|
|
|
|
it('does NOT invoke loadAuthValues for execute_code (no per-user credential check)', async () => {
|
|
/* Regression guard: a future refactor that threads per-user auth back
|
|
in would resurface the key-entry dialog on the client. Pin that
|
|
the auth path is never consulted. */
|
|
const { loadAuthValues } = require('~/server/services/Tools/credentials');
|
|
loadAuthValues.mockClear();
|
|
|
|
await verifyToolAuth(makeReq(Tools.execute_code), makeRes());
|
|
|
|
expect(loadAuthValues).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('does NOT reference AuthType.USER_PROVIDED in the response (Phase 8 removed the path)', async () => {
|
|
const res = makeRes();
|
|
await verifyToolAuth(makeReq(Tools.execute_code), res);
|
|
|
|
const payload = res.json.mock.calls[0][0];
|
|
expect(payload.message).not.toBe(AuthType.USER_PROVIDED);
|
|
});
|
|
});
|