import assert from "node:assert/strict"; import { connect } from "node:net"; import test from "node:test"; import { createControlCoreApp, } from "../../device-control-core/src/app.mjs"; import { createCoreDiscoveryClient } from "../src/core-client.mjs"; import { createDeviceGatewayRuntime } from "../src/runtime.mjs"; const gatewayToken = "test-only-gateway-token-with-32-bytes"; const identifierPepper = "test-only-identifier-pepper-with-32-bytes"; const specificationHeader = Buffer.from( "FF23E9EF782DE7120300", "hex", ); const specificationPackage = Buffer.from( "5B01010000FBDEC251EC5D", "hex", ); test("B2 HEADER2 becomes a persisted masked quarantine discovery before ACK", async () => { let stored; const core = createControlCoreApp({ discoveryIngestEnabled: true, gatewayToken, identifierPepper, repository: { health: async () => "ready", upsertQuarantineDiscovery: async (value) => { stored = value; return { created: true, value: { ...value.safeView, discoveryRef: "discovery:integration-001", }, }; }, }, }); await listen(core); const coreAddress = core.address(); const observe = createCoreDiscoveryClient({ coreUrl: `http://127.0.0.1:${coreAddress.port}`, gatewayToken, }); const gateway = createDeviceGatewayRuntime({ healthPort: 0, tcpHost: "0.0.0.0", tcpPort: 0, listenEnabled: true, publicIngressEnabled: true, now: () => new Date(0x52db95de * 1000), onDiscovery: observe, }); const addresses = await gateway.start(); try { const response = await exchange( addresses.tcpAddress.port, Buffer.concat([specificationHeader, specificationPackage]), 13, ); assert.equal( response.toString("hex").toUpperCase(), "7B0400A0DE95DB527D7B00017D", ); assert.match(stored.identifierDigest, /^hmac-sha256:[a-f0-9]{64}$/); assert.equal(stored.safeView.lifecycleState, "quarantine"); assert.equal(stored.safeView.identifier.masked, "***********7769"); assert.equal(stored.safeView.commandTransport, "disabled"); assert.equal( JSON.stringify(stored).includes("865209039777769"), false, ); } finally { await gateway.stop(); await close(core); } }); function listen(server) { return new Promise((resolve, reject) => { server.once("error", reject); server.listen(0, "127.0.0.1", resolve); }); } function close(server) { return new Promise((resolve, reject) => { server.close((error) => (error ? reject(error) : resolve())); }); } function exchange(port, payload, expectedBytes) { return new Promise((resolve, reject) => { const chunks = []; let byteLength = 0; const socket = connect({ host: "127.0.0.1", port }, () => { socket.write(payload); }); socket.on("data", (chunk) => { chunks.push(chunk); byteLength += chunk.length; if (byteLength >= expectedBytes) { socket.destroy(); resolve(Buffer.concat(chunks, byteLength)); } }); socket.on("error", reject); }); }