fix(device-core): bind edge telemetry to enrolled route

This commit is contained in:
Codex
2026-08-13 09:41:14 +03:00
parent fe1c8054be
commit 71fff82c99
7 changed files with 309 additions and 10 deletions
@@ -22,12 +22,26 @@ export function createDeviceGatewayIngest({ repository, identifierPepper } = {})
}
return Object.freeze({
async observeDiscovery(input) {
const signal = normalizeDiscoverySignal(input);
async observeDiscovery(input, context = {}) {
const receivedSignal = normalizeDiscoverySignal(input);
const identifierDigest = hashRestrictedIdentifier(
signal.identifier,
receivedSignal.identifier,
identifierPepper,
);
const routeRef = await resolveAuthenticatedRoute(repository, {
edgeRef: context.authenticatedEdgeRef,
modelProfileRef: receivedSignal.modelProfileRef,
protocol: receivedSignal.protocol,
identifierKind: receivedSignal.identifier.kind,
identifierDigest,
observedAt: receivedSignal.observedAt,
});
const signal = routeRef === undefined
? receivedSignal
: normalizeDiscoverySignal({
...withoutKeys(receivedSignal, ["routeRef"]),
...(routeRef ? { routeRef } : {}),
});
const safeView = assertSafeProjection(toSafeDiscoveryView(signal));
const discovery = await repository.upsertQuarantineDiscovery({
identifierDigest,
@@ -42,12 +56,27 @@ export function createDeviceGatewayIngest({ repository, identifierPepper } = {})
});
},
async acceptMessage(input) {
const message = normalizeAdapterMessage(input);
async acceptMessage(input, context = {}) {
const receivedMessage = normalizeAdapterMessage(input);
const identifierDigest = hashRestrictedIdentifier(
message.identifier,
receivedMessage.identifier,
identifierPepper,
);
const routeRef = await resolveAuthenticatedRoute(repository, {
edgeRef: context.authenticatedEdgeRef,
modelProfileRef: receivedMessage.protocolProfileRef,
protocol: receivedMessage.protocol,
identifierKind: receivedMessage.identifier.kind,
identifierDigest,
observedAt: receivedMessage.observedAt,
});
const message = routeRef === undefined
? receivedMessage
: normalizeAdapterMessage({
...withoutKeys(receivedMessage, ["edgeRef", "routeRef"]),
edgeRef: context.authenticatedEdgeRef,
...(routeRef ? { routeRef } : {}),
});
const safeView = assertSafeProjection(toSafeAdapterMessageView(message));
const requestDigest = gatewayMessageRequestDigest({
edgeRef: safeView.edgeRef,
@@ -74,6 +103,21 @@ export function createDeviceGatewayIngest({ repository, identifierPepper } = {})
});
}
async function resolveAuthenticatedRoute(repository, input) {
if (input.edgeRef == null) return undefined;
if (typeof repository.resolveInboundRoute !== "function") {
throw new TypeError("device_inbound_route_repository_required");
}
return repository.resolveInboundRoute(input);
}
function withoutKeys(value, keys) {
const omitted = new Set(keys);
return Object.fromEntries(
Object.entries(value).filter(([key]) => !omitted.has(key)),
);
}
function gatewayMessageRequestDigest(value) {
return `sha256:${createHash("sha256")
.update(JSON.stringify(value), "utf8")