144 lines
4.7 KiB
JavaScript
144 lines
4.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
DEVICE_ADAPTER_MESSAGE_SCHEMA,
|
|
DEVICE_DISCOVERY_SIGNAL_SCHEMA,
|
|
} from "../../../packages/device-protocol-contract/src/index.mjs";
|
|
import { createDeviceGatewayIngest } from "../src/gateway-ingest.mjs";
|
|
|
|
const identifierPepper = "test-only-identifier-pepper-with-32-bytes";
|
|
const rawImei = "000000000000001";
|
|
|
|
test("shared gateway ingest masks identifiers for HTTP and Edge callers", async () => {
|
|
const stored = [];
|
|
const ingest = createDeviceGatewayIngest({
|
|
identifierPepper,
|
|
repository: {
|
|
async upsertQuarantineDiscovery(value) {
|
|
stored.push(value);
|
|
return {
|
|
created: true,
|
|
value: { ...value.safeView, discoveryRef: "discovery:test" },
|
|
};
|
|
},
|
|
async acceptAdapterMessage(value) {
|
|
stored.push(value);
|
|
return {
|
|
acceptance: {
|
|
schemaVersion: "nodedc.device-adapter-acceptance.v1",
|
|
acceptanceRef: "acceptance:test",
|
|
idempotencyKey: value.safeView.idempotencyKey,
|
|
status: "accepted",
|
|
replayed: false,
|
|
acceptedAt: "2026-08-11T12:00:00.000Z",
|
|
},
|
|
claimedDeviceRef: "device:11111111-1111-4111-8111-111111111111",
|
|
};
|
|
},
|
|
},
|
|
});
|
|
|
|
const discovery = await ingest.observeDiscovery(discoverySignal());
|
|
const acceptance = await ingest.acceptMessage(adapterMessage());
|
|
|
|
assert.equal(discovery.value.identifier.masked, "***********0001");
|
|
assert.equal(acceptance.value.status, "accepted");
|
|
assert.equal(
|
|
acceptance.claimedDeviceRef,
|
|
"device:11111111-1111-4111-8111-111111111111",
|
|
);
|
|
assert.match(stored[0].identifierDigest, /^hmac-sha256:[a-f0-9]{64}$/);
|
|
assert.match(stored[1].requestDigest, /^sha256:[a-f0-9]{64}$/);
|
|
assert.equal(JSON.stringify(stored).includes(rawImei), false);
|
|
});
|
|
|
|
test("authenticated Edge identity resolves the allowlisted project route", async () => {
|
|
const stored = [];
|
|
const resolutions = [];
|
|
const authenticatedEdgeRef = "edge:11111111-1111-4111-8111-111111111111";
|
|
const routeRef = "route:22222222-2222-4222-8222-222222222222";
|
|
const ingest = createDeviceGatewayIngest({
|
|
identifierPepper,
|
|
repository: {
|
|
async resolveInboundRoute(value) {
|
|
resolutions.push(value);
|
|
return routeRef;
|
|
},
|
|
async upsertQuarantineDiscovery(value) {
|
|
stored.push(value);
|
|
return {
|
|
created: false,
|
|
value: { ...value.safeView, discoveryRef: "discovery:test" },
|
|
};
|
|
},
|
|
async acceptAdapterMessage(value) {
|
|
stored.push(value);
|
|
return {
|
|
acceptance: {
|
|
schemaVersion: "nodedc.device-adapter-acceptance.v1",
|
|
acceptanceRef: "acceptance:test",
|
|
idempotencyKey: value.safeView.idempotencyKey,
|
|
status: "accepted",
|
|
replayed: false,
|
|
acceptedAt: "2026-08-11T12:00:00.000Z",
|
|
},
|
|
claimedDeviceRef: null,
|
|
};
|
|
},
|
|
},
|
|
});
|
|
|
|
await ingest.observeDiscovery(discoverySignal(), { authenticatedEdgeRef });
|
|
await ingest.acceptMessage(adapterMessage(), { authenticatedEdgeRef });
|
|
|
|
assert.equal(resolutions.length, 2);
|
|
assert.equal(resolutions[0].edgeRef, authenticatedEdgeRef);
|
|
assert.match(resolutions[0].identifierDigest, /^hmac-sha256:[a-f0-9]{64}$/);
|
|
assert.equal(stored[0].safeView.routeRef, routeRef);
|
|
assert.equal(stored[1].safeView.routeRef, routeRef);
|
|
assert.equal(stored[1].safeView.edgeRef, authenticatedEdgeRef);
|
|
assert.notEqual(stored[1].safeView.edgeRef, adapterMessage().edgeRef);
|
|
assert.equal(JSON.stringify(resolutions).includes(rawImei), false);
|
|
});
|
|
|
|
function discoverySignal() {
|
|
return {
|
|
schemaVersion: DEVICE_DISCOVERY_SIGNAL_SCHEMA,
|
|
sessionRef: "session:test",
|
|
modelProfileRef: "arusnavi.b2.internal.v1",
|
|
protocol: "INTERNAL",
|
|
observedAt: "2026-08-11T12:00:00.000Z",
|
|
identifier: { kind: "imei", value: rawImei },
|
|
evidence: {
|
|
transport: "tcp",
|
|
bytesObserved: 16,
|
|
framingStatus: "verified",
|
|
specificationRef: "arusnavi.internal.framing.test-v1",
|
|
},
|
|
};
|
|
}
|
|
|
|
function adapterMessage() {
|
|
return {
|
|
schemaVersion: DEVICE_ADAPTER_MESSAGE_SCHEMA,
|
|
edgeRef: "edge:test",
|
|
adapterRef: "arusnavi-b2",
|
|
protocolProfileRef: "arusnavi.b2.internal.v1",
|
|
protocol: "INTERNAL",
|
|
sessionRef: "session:test",
|
|
messageRef: "package:1:test",
|
|
messageType: "telemetry.package",
|
|
sequence: 1,
|
|
observedAt: "2026-08-11T12:00:00.000Z",
|
|
idempotencyKey: `sha256:${"a".repeat(64)}`,
|
|
identifier: { kind: "imei", value: rawImei },
|
|
payloadSchemaRef: "arusnavi.internal.package-metadata.v1",
|
|
payload: {
|
|
packageNumber: 1,
|
|
packetCount: 1,
|
|
packageDigest: `sha256:${"b".repeat(64)}`,
|
|
},
|
|
};
|
|
}
|