feat: publish Alta Local Camera Discovery

This commit is contained in:
2026-09-01 18:02:14 +00:00
commit 33f28a3d73
30 changed files with 4939 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
'use strict';
const test = require('node:test');
const assert = require('node:assert/strict');
const { EventEmitter } = require('node:events');
const {
altaKeyFromName,
cameraFromService,
isLocalAddress,
normalizeResults,
scanCameras,
} = require('../src/discovery');
const validService = (overrides = {}) => ({
name: 'ABH7-C62U-GC3E',
type: 'vaioncam',
protocol: 'tcp',
host: 'avacam-abh7-c62u-gc3e.local.',
addresses: ['fe80::1', '10.0.0.223'],
port: 443,
...overrides,
});
test('extracts an Alta Key from service names', () => {
assert.equal(altaKeyFromName('abh7-c62u-gc3e'), 'ABH7-C62U-GC3E');
assert.equal(altaKeyFromName('ABH7-C62U-GC3E._vaioncam._tcp.local'), 'ABH7-C62U-GC3E');
assert.equal(altaKeyFromName('not-a-key'), null);
});
test('projects a correlated local Bonjour service into a safe camera row', () => {
assert.deepEqual(cameraFromService(validService()), {
alta_key: 'ABH7-C62U-GC3E',
hostname: 'avacam-abh7-c62u-gc3e.local',
web_ui_url: 'https://avacam-abh7-c62u-gc3e.local',
ip_address: '10.0.0.223',
port: 443,
service: '_vaioncam._tcp.local',
});
});
test('rejects uncorrelated or non-local service announcements', () => {
assert.equal(cameraFromService(validService({ type: undefined })), null);
assert.equal(cameraFromService(validService({ protocol: undefined })), null);
assert.equal(cameraFromService(validService({ host: 'avacam-attacker.local.' })), null);
assert.equal(cameraFromService(validService({ port: 8443 })), null);
assert.equal(cameraFromService(validService({ addresses: ['203.0.113.10'] })), null);
assert.equal(cameraFromService(validService({ addresses: [] })), null);
});
test('recognizes supported private and link-local IP scopes', () => {
for (const address of ['10.0.0.1', '172.16.0.1', '172.31.255.254', '192.168.1.1', '169.254.1.1', 'fe80::1', 'fc00::1', 'fd12::1']) {
assert.equal(isLocalAddress(address), true, address);
}
for (const address of ['8.8.8.8', '172.32.0.1', '2001:4860:4860::8888', 'not-an-ip']) {
assert.equal(isLocalAddress(address), false, address);
}
});
test('deduplicates and sorts cameras', () => {
const a = { alta_key: 'AHG2-Z4ND-FVRN', ip_address: '10.0.0.192' };
const b = { alta_key: 'ABH7-C62U-GC3E', ip_address: '10.0.0.223' };
assert.deepEqual(normalizeResults([a, b, a]), [b, a]);
});
test('scans through the Bonjour adapter and closes resources', async () => {
let browserStopped = false;
let bonjourDestroyed = false;
class FakeBonjour {
find(query) {
assert.deepEqual(query, { type: 'vaioncam', protocol: 'tcp' });
const browser = new EventEmitter();
browser.stop = () => { browserStopped = true; };
process.nextTick(() => browser.emit('up', validService()));
return browser;
}
destroy() { bonjourDestroyed = true; }
}
const rows = await scanCameras({ durationMs: 5, BonjourClass: FakeBonjour });
assert.equal(rows.length, 1);
assert.equal(rows[0].alta_key, 'ABH7-C62U-GC3E');
assert.equal(browserStopped, true);
assert.equal(bonjourDestroyed, true);
});
test('caps scan results and closes discovery immediately at the cap', async () => {
let browserStopped = false;
class FakeBonjour {
find() {
const browser = new EventEmitter();
browser.stop = () => { browserStopped = true; };
process.nextTick(() => {
for (let index = 0; index < 10; index += 1) {
const key = `AAAA-BBBB-${String(index).padStart(4, '0')}`;
browser.emit('up', validService({
name: key,
host: `avacam-${key.toLowerCase()}.local.`,
addresses: [`10.0.0.${index + 1}`],
}));
}
});
return browser;
}
destroy() {}
}
const rows = await scanCameras({ durationMs: 1000, maxResults: 3, BonjourClass: FakeBonjour });
assert.equal(rows.length, 3);
assert.equal(browserStopped, true);
});