fix: contain malformed metadata and stale discovery

This commit is contained in:
2026-08-20 01:44:23 +00:00
parent 3b5e2acb75
commit 7d484a3998
10 changed files with 276 additions and 13 deletions
+91
View File
@@ -162,6 +162,96 @@ test('runtime enforces a bounded whole-discovery deadline', async () => {
});
});
test('newest hierarchy discovery owns the launch allowlist when completions arrive out of order', async () => {
const sessionStore = createSessionStore();
sessionStore.establish('https://customer.avasecurity.com', 'synthetic-cookie');
const deviceA = '550e8400-e29b-41d4-a716-44665544000a';
const deviceB = '550e8400-e29b-41d4-a716-44665544000b';
const pending = [];
const launches = [];
const runtime = new AppRuntime({
sessionStore,
altaClient: {
getDevices: () => new Promise((resolve) => pending.push(resolve)),
getDeviceSites: async () => [],
getDeviceGroups: async () => [],
},
proxyManager: {
launchProxy(request) {
launches.push(request.deviceId);
return { processId: 5000 + launches.length, deviceId: request.deviceId, status: 'running' };
},
listTrackedProxies: () => [],
},
});
const staleA = runtime.getDeviceHierarchy();
const freshB = runtime.getDeviceHierarchy();
pending[1]([{ guid: deviceB }]);
assert.equal((await freshB).success, true);
assert.equal((await runtime.launchProxy(deviceB, 'operator@example.com')).success, true);
pending[0]([{ guid: deviceA }]);
assert.deepEqual(await staleA, {
success: false,
stale: true,
hierarchy: { devices: [], sites: [], groups: [] },
message: 'Alta device discovery result is stale',
});
assert.equal((await runtime.launchProxy(deviceA, 'operator@example.com')).success, false);
assert.deepEqual(launches, [deviceB]);
});
test('disconnect and session changes invalidate pending discovery without repopulating the allowlist', async () => {
const deviceId = '550e8400-e29b-41d4-a716-44665544000c';
for (const invalidate of ['disconnect', 'session-change']) {
const sessionStore = createSessionStore();
sessionStore.establish('https://first.avasecurity.com', 'synthetic-cookie');
let resolveDevices;
const runtime = new AppRuntime({
sessionStore,
altaClient: {
getDevices: () => new Promise((resolve) => { resolveDevices = resolve; }),
getDeviceSites: async () => [],
getDeviceGroups: async () => [],
},
proxyManager: { listTrackedProxies: () => [] },
});
const discovery = runtime.getDeviceHierarchy();
if (invalidate === 'disconnect') {
assert.equal((await runtime.disconnect()).success, true);
} else {
sessionStore.establish('https://second.avasecurity.com', 'replacement-cookie');
runtime.onSessionChanged();
}
resolveDevices([{ guid: deviceId }]);
assert.equal((await discovery).stale, true, invalidate);
assert.equal(runtime.allowedDeviceIds.size, 0, invalidate);
}
});
test('launch allowlist remains bound to the session origin that produced it', async () => {
const deviceId = '550e8400-e29b-41d4-a716-44665544000d';
const sessionStore = createSessionStore();
sessionStore.establish('https://first.avasecurity.com', 'synthetic-cookie');
let launches = 0;
const runtime = new AppRuntime({
sessionStore,
altaClient: {
getDevices: async () => [{ guid: deviceId }],
getDeviceSites: async () => [],
getDeviceGroups: async () => [],
},
proxyManager: {
listTrackedProxies: () => [],
launchProxy() { launches += 1; },
},
});
assert.equal((await runtime.getDeviceHierarchy()).success, true);
sessionStore.establish('https://second.avasecurity.com', 'replacement-cookie');
assert.equal((await runtime.launchProxy(deviceId, 'operator@example.com')).success, false);
assert.equal(launches, 0);
});
test('runtime rejects discovery deadlines above 60 seconds', () => {
assert.throws(() => new AppRuntime({ discoveryTimeoutMs: 60_001 }), /discovery timeout/i);
});
@@ -439,6 +529,7 @@ test('preload and renderer expose only narrow, credential-free contracts', () =>
assert.doesNotMatch(preload, /launchProxy:\s*\([^)]*(?:cookie|origin)/i);
assert.doesNotMatch(renderer, /cookieValue|sessionData\.cookies|cookies\s*:/);
assert.match(renderer, /state\.connected\s*&&\s*\(!wasConnected\s*\|\|\s*state\.origin\s*!==\s*previousOrigin\)/);
assert.match(read('main.js'), /onConnectionStateChanged:\s*\(\)\s*=>\s*\{\s*runtime\.onSessionChanged\(\)/);
assert.doesNotMatch(html, /id="cookieKey"|updateProgress|Install Update/);
assert.match(html, /id="altaUsername"/);
assert.match(renderer, /openFixedReleasesPage/);