feat: add bounded large-deployment discovery
This commit is contained in:
@@ -3,7 +3,12 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { SessionStore } = require('../src/session-store');
|
||||
const { AltaClient } = require('../src/alta-client');
|
||||
const {
|
||||
AltaClient,
|
||||
DEVICE_MAX_RESPONSE_BYTES,
|
||||
HIERARCHY_MAX_RESPONSE_BYTES,
|
||||
MAX_ARRAY_OBJECTS,
|
||||
} = require('../src/alta-client');
|
||||
|
||||
const ORIGIN = 'https://tenant.avasecurity.com';
|
||||
const SENTINEL = 'HERMES_SENTINEL_SECRET';
|
||||
@@ -24,17 +29,20 @@ test('uses only stored authority, fixed endpoint paths and hardened transport op
|
||||
calls.push(options);
|
||||
if (options.url.endsWith('/devices')) return response([]);
|
||||
if (options.url.endsWith('/deviceSites')) return response([{ id: 'site-1' }]);
|
||||
if (options.url.endsWith('/deviceGroups')) return response([{ id: 'group-1' }]);
|
||||
return response({ user: 'engineer' });
|
||||
};
|
||||
const client = new AltaClient({ sessionStore: readyStore(), transport });
|
||||
|
||||
assert.deepEqual(await client.getDevices(), []);
|
||||
assert.deepEqual(await client.getDeviceSites(), [{ id: 'site-1' }]);
|
||||
assert.deepEqual(await client.getDeviceGroups(), [{ id: 'group-1' }]);
|
||||
assert.deepEqual(await client.getAuthInfo(), { user: 'engineer' });
|
||||
|
||||
assert.deepEqual(calls.map((call) => call.url), [
|
||||
`${ORIGIN}/api/v1/devices`,
|
||||
`${ORIGIN}/api/v1/deviceSites`,
|
||||
`${ORIGIN}/api/v1/deviceGroups`,
|
||||
`${ORIGIN}/api/v1/auth`,
|
||||
]);
|
||||
for (const call of calls) {
|
||||
@@ -42,11 +50,56 @@ test('uses only stored authority, fixed endpoint paths and hardened transport op
|
||||
assert.equal(call.proxy, false);
|
||||
assert.equal(call.maxRedirects, 0);
|
||||
assert.match(call.headers.Cookie, /^va=HERMES_SENTINEL_SECRET$/);
|
||||
assert.ok(call.timeout > 0 && call.timeout <= 10_000);
|
||||
assert.ok(call.timeout > 0 && call.timeout <= 30_000);
|
||||
assert.ok(call.maxResponseBytes > 0);
|
||||
}
|
||||
});
|
||||
|
||||
test('uses endpoint-specific 32 MiB/4 MiB limits and a 30 second request deadline', async () => {
|
||||
const calls = [];
|
||||
const client = new AltaClient({
|
||||
sessionStore: readyStore(),
|
||||
transport: async (options) => { calls.push(options); return response([]); },
|
||||
});
|
||||
|
||||
await client.getDevices();
|
||||
await client.getDeviceSites();
|
||||
await client.getDeviceGroups();
|
||||
|
||||
assert.deepEqual(calls.map(({ maxResponseBytes }) => maxResponseBytes), [
|
||||
DEVICE_MAX_RESPONSE_BYTES,
|
||||
HIERARCHY_MAX_RESPONSE_BYTES,
|
||||
HIERARCHY_MAX_RESPONSE_BYTES,
|
||||
]);
|
||||
assert.ok(calls.every(({ timeout }) => timeout > 0 && timeout <= 30_000));
|
||||
});
|
||||
|
||||
test('accepts device bodies above 2 MiB and rejects bodies above 32 MiB before parsing', async () => {
|
||||
const acceptedBody = JSON.stringify([{
|
||||
guid: '550e8400-e29b-41d4-a716-446655440000',
|
||||
padding: 'x'.repeat((2 * 1024 * 1024) + 1),
|
||||
}]);
|
||||
const accepted = new AltaClient({
|
||||
sessionStore: readyStore(),
|
||||
transport: async () => response(Buffer.from(acceptedBody)),
|
||||
});
|
||||
assert.equal((await accepted.getDevices()).length, 1);
|
||||
|
||||
const rejected = new AltaClient({
|
||||
sessionStore: readyStore(),
|
||||
transport: async () => response(Buffer.alloc(DEVICE_MAX_RESPONSE_BYTES + 1, 0x20)),
|
||||
});
|
||||
await assert.rejects(rejected.getDevices(), { code: 'ALTA_RESPONSE_TOO_LARGE' });
|
||||
});
|
||||
|
||||
test('rejects plain array responses containing more than 10,000 objects', async () => {
|
||||
const client = new AltaClient({
|
||||
sessionStore: readyStore(),
|
||||
transport: async () => response(Array.from({ length: MAX_ARRAY_OBJECTS + 1 }, () => ({}))),
|
||||
});
|
||||
await assert.rejects(client.getDevices(), { code: 'ALTA_RESPONSE_TOO_MANY_OBJECTS' });
|
||||
});
|
||||
|
||||
test('rejects renderer-supplied URL/cookie parameters before transport', async () => {
|
||||
let calls = 0;
|
||||
const client = new AltaClient({
|
||||
|
||||
Reference in New Issue
Block a user