import assert from "node:assert/strict"; import { assertReaderProduct, createReaderToken, hashReaderToken, normalizeManagedReaderBindingRequest, normalizeReaderBindingRequest, readerBindingRequestHash, safeReaderBinding, } from "../src/reader-binding.mjs"; const now = new Date("2026-07-15T12:00:00.000Z"); const policy = normalizeReaderBindingRequest({ source: { tenantId: "tenant-01", connectionId: "connection-01", providerId: "example-provider" }, allowedDataProductIds: ["fleet.positions.current.v1"], expiresAt: "2026-08-01T12:00:00.000Z", }, { now }); const token = createReaderToken(); assert.match(token, /^ndc_edprb_[A-Za-z0-9_-]{40,}$/); assert.equal(hashReaderToken(token), hashReaderToken(token)); assert.equal(assertReaderProduct({ ...policy, active: true }, "fleet.positions.current.v1", now), "fleet.positions.current.v1"); assert.throws(() => assertReaderProduct({ ...policy, active: true }, "other.product.v1", now), /reader_binding_data_product_forbidden/); const safe = safeReaderBinding({ id: "reader-01", ...policy, active: true, token, tokenHash: hashReaderToken(token) }); assert.equal("token" in safe, false); assert.equal("tokenHash" in safe, false); const managed = normalizeManagedReaderBindingRequest({ source: { tenantId: policy.tenantId, connectionId: policy.connectionId, providerId: policy.providerId }, allowedDataProductIds: ["fleet.positions.current.v1"], expiresAt: null, generation: 2, capabilityDigest: hashReaderToken(token), }, { now }); assert.equal(managed.generation, 2); assert.match(readerBindingRequestHash(managed), /^[a-f0-9]{64}$/); const safeManaged = safeReaderBinding({ id: "reader-managed-01", bindingKey: "dprg-reader-managed", generation: 2, ...managed, active: true, }); assert.equal(safeManaged.bindingKey, "dprg-reader-managed"); assert.equal(safeManaged.generation, 2); assert.equal(safeManaged.expiresAt, null); assert.equal( assertReaderProduct(safeManaged, "fleet.positions.current.v1", new Date("2036-07-15T12:00:00.000Z")), "fleet.positions.current.v1", ); assert.equal(JSON.stringify(safeManaged).includes(managed.capabilityDigest), false); assert.throws(() => normalizeManagedReaderBindingRequest({ source: { tenantId: policy.tenantId, connectionId: policy.connectionId, providerId: policy.providerId }, allowedDataProductIds: managed.allowedDataProductIds, expiresAt: managed.expiresAt, generation: managed.generation, capabilityDigest: managed.capabilityDigest, token: "forbidden", }, { now }), /managed_reader_binding_secret_material_forbidden/); assert.throws(() => normalizeManagedReaderBindingRequest({ source: { tenantId: policy.tenantId, connectionId: policy.connectionId, providerId: policy.providerId }, allowedDataProductIds: managed.allowedDataProductIds, expiresAt: policy.expiresAt, generation: managed.generation, capabilityDigest: managed.capabilityDigest, }), /managed_reader_binding_must_be_durable/); console.log("external-data-plane reader bindings: ok");