@peers-app/peers-sdk 0.27.3 → 0.27.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contracts/contract-proxy.d.ts +7 -0
- package/dist/contracts/contract-proxy.js +19 -2
- package/dist/contracts/contract-transport.d.ts +2 -1
- package/dist/contracts/contract-transport.js +24 -2
- package/dist/contracts/create-local-consumer.js +16 -1
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/system/index.d.ts +2 -0
- package/dist/contracts/system/index.js +2 -0
- package/dist/contracts/system/invites-contract.js +2 -1
- package/dist/contracts/system/sync-check-contract.d.ts +97 -0
- package/dist/contracts/system/sync-check-contract.js +115 -0
- package/dist/contracts/tool-arguments.d.ts +15 -0
- package/dist/contracts/tool-arguments.js +41 -0
- package/dist/contracts/tool-catalog-service.js +2 -12
- package/dist/contracts/tool-catalog.js +6 -2
- package/dist/data/change-tracking.d.ts +40 -0
- package/dist/data/change-tracking.js +89 -0
- package/dist/data/orm/types.d.ts +24 -7
- package/dist/data/orm/types.js +97 -24
- package/dist/define/manifest.js +6 -34
- package/dist/device/binary-peer-connection-v2.d.ts +7 -15
- package/dist/device/binary-peer-connection-v2.js +14 -30
- package/dist/device/connection.d.ts +34 -43
- package/dist/device/connection.js +188 -186
- package/dist/device/device.d.ts +1 -8
- package/dist/device/device.js +1 -30
- package/dist/device/socket.type.d.ts +6 -12
- package/dist/package-loader/package-loader.js +27 -22
- package/dist/system-ids.d.ts +5 -0
- package/dist/system-ids.js +6 -1
- package/package.json +4 -2
- package/dist/context/user-context-identity.test.d.ts +0 -1
- package/dist/context/user-context-identity.test.js +0 -220
- package/dist/contracts/__tests__/action-dispatch.test.d.ts +0 -1
- package/dist/contracts/__tests__/action-dispatch.test.js +0 -319
- package/dist/contracts/__tests__/also-implements.test.d.ts +0 -1
- package/dist/contracts/__tests__/also-implements.test.js +0 -110
- package/dist/contracts/__tests__/builder.test.d.ts +0 -1
- package/dist/contracts/__tests__/builder.test.js +0 -669
- package/dist/contracts/__tests__/contract-events.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-events.test.js +0 -199
- package/dist/contracts/__tests__/contract-observables.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-observables.test.js +0 -290
- package/dist/contracts/__tests__/contract-provider-router.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-provider-router.test.js +0 -315
- package/dist/contracts/__tests__/contract-proxy.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-proxy.test.js +0 -657
- package/dist/contracts/__tests__/contract-resolvers.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-resolvers.test.js +0 -758
- package/dist/contracts/__tests__/contract-subscription-lifecycle.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-subscription-lifecycle.test.js +0 -353
- package/dist/contracts/__tests__/contract-table-events.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-table-events.test.js +0 -209
- package/dist/contracts/__tests__/contract-transport.test.d.ts +0 -1
- package/dist/contracts/__tests__/contract-transport.test.js +0 -163
- package/dist/contracts/__tests__/extract.test.d.ts +0 -1
- package/dist/contracts/__tests__/extract.test.js +0 -145
- package/dist/contracts/__tests__/frozen-contracts.test.d.ts +0 -1
- package/dist/contracts/__tests__/frozen-contracts.test.js +0 -191
- package/dist/contracts/__tests__/generic-tool-dispatch.test.d.ts +0 -1
- package/dist/contracts/__tests__/generic-tool-dispatch.test.js +0 -130
- package/dist/contracts/__tests__/host-contract-client.test.d.ts +0 -1
- package/dist/contracts/__tests__/host-contract-client.test.js +0 -793
- package/dist/contracts/__tests__/host-contract-consumer.test.d.ts +0 -1
- package/dist/contracts/__tests__/host-contract-consumer.test.js +0 -163
- package/dist/contracts/__tests__/host-contract-transport.test.d.ts +0 -1
- package/dist/contracts/__tests__/host-contract-transport.test.js +0 -66
- package/dist/contracts/__tests__/integration.test.d.ts +0 -1
- package/dist/contracts/__tests__/integration.test.js +0 -348
- package/dist/contracts/__tests__/legacy-removal.test.d.ts +0 -1
- package/dist/contracts/__tests__/legacy-removal.test.js +0 -128
- package/dist/contracts/__tests__/persistent-registry.test.d.ts +0 -1
- package/dist/contracts/__tests__/persistent-registry.test.js +0 -109
- package/dist/contracts/__tests__/playground.test.d.ts +0 -1
- package/dist/contracts/__tests__/playground.test.js +0 -216
- package/dist/contracts/__tests__/registry.test.d.ts +0 -1
- package/dist/contracts/__tests__/registry.test.js +0 -238
- package/dist/contracts/__tests__/remote-contract-transport.test.d.ts +0 -1
- package/dist/contracts/__tests__/remote-contract-transport.test.js +0 -119
- package/dist/contracts/__tests__/system-contracts.test.d.ts +0 -1
- package/dist/contracts/__tests__/system-contracts.test.js +0 -247
- package/dist/contracts/__tests__/target-dispatch.d.ts +0 -11
- package/dist/contracts/__tests__/target-dispatch.js +0 -24
- package/dist/contracts/__tests__/tool-catalog-inventory.test.d.ts +0 -1
- package/dist/contracts/__tests__/tool-catalog-inventory.test.js +0 -44
- package/dist/contracts/__tests__/tool-catalog-service.test.d.ts +0 -1
- package/dist/contracts/__tests__/tool-catalog-service.test.js +0 -482
- package/dist/contracts/__tests__/tool-catalog.test.d.ts +0 -1
- package/dist/contracts/__tests__/tool-catalog.test.js +0 -1199
- package/dist/contracts/__tests__/validate.test.d.ts +0 -1
- package/dist/contracts/__tests__/validate.test.js +0 -991
- package/dist/contracts/__tests__/workflow-context.test.d.ts +0 -1
- package/dist/contracts/__tests__/workflow-context.test.js +0 -50
- package/dist/data/access-level.test.d.ts +0 -1
- package/dist/data/access-level.test.js +0 -53
- package/dist/data/change-tracking.test.d.ts +0 -1
- package/dist/data/change-tracking.test.js +0 -62
- package/dist/data/files/files.test.d.ts +0 -1
- package/dist/data/files/files.test.js +0 -770
- package/dist/data/group-members.test.d.ts +0 -1
- package/dist/data/group-members.test.js +0 -336
- package/dist/data/group-share.test.d.ts +0 -1
- package/dist/data/group-share.test.js +0 -110
- package/dist/data/groups.test.d.ts +0 -1
- package/dist/data/groups.test.js +0 -153
- package/dist/data/orm/cursor.test.d.ts +0 -1
- package/dist/data/orm/cursor.test.js +0 -314
- package/dist/data/orm/data-query.mongo.test.d.ts +0 -1
- package/dist/data/orm/data-query.mongo.test.js +0 -367
- package/dist/data/orm/data-query.sqlite.test.d.ts +0 -1
- package/dist/data/orm/data-query.sqlite.test.js +0 -365
- package/dist/data/orm/data-query.test.d.ts +0 -1
- package/dist/data/orm/data-query.test.js +0 -545
- package/dist/data/orm/dependency-injection.test.d.ts +0 -1
- package/dist/data/orm/dependency-injection.test.js +0 -171
- package/dist/data/orm/event-registry.test.d.ts +0 -1
- package/dist/data/orm/event-registry.test.js +0 -44
- package/dist/data/orm/multi-cursors.test.d.ts +0 -1
- package/dist/data/orm/multi-cursors.test.js +0 -463
- package/dist/data/orm/sql.data-source.test.d.ts +0 -1
- package/dist/data/orm/sql.data-source.test.js +0 -731
- package/dist/data/orm/table-container-events.test.d.ts +0 -1
- package/dist/data/orm/table-container-events.test.js +0 -101
- package/dist/data/orm/table-container.test.d.ts +0 -1
- package/dist/data/orm/table-container.test.js +0 -273
- package/dist/data/orm/table.event-source.test.d.ts +0 -1
- package/dist/data/orm/table.event-source.test.js +0 -331
- package/dist/data/orm/types.test.d.ts +0 -1
- package/dist/data/orm/types.test.js +0 -409
- package/dist/data/package-table-identity.test.d.ts +0 -1
- package/dist/data/package-table-identity.test.js +0 -46
- package/dist/data/package-version-permissions.test.d.ts +0 -1
- package/dist/data/package-version-permissions.test.js +0 -107
- package/dist/data/package-version-resolver.test.d.ts +0 -4
- package/dist/data/package-version-resolver.test.js +0 -543
- package/dist/data/package-versions.test.d.ts +0 -1
- package/dist/data/package-versions.test.js +0 -227
- package/dist/data/persistent-vars.conflict.test.d.ts +0 -1
- package/dist/data/persistent-vars.conflict.test.js +0 -126
- package/dist/data/persistent-vars.migration.test.d.ts +0 -1
- package/dist/data/persistent-vars.migration.test.js +0 -133
- package/dist/data/persistent-vars.package-scope.test.d.ts +0 -1
- package/dist/data/persistent-vars.package-scope.test.js +0 -27
- package/dist/data/sync-recovery-queue.test.d.ts +0 -1
- package/dist/data/sync-recovery-queue.test.js +0 -215
- package/dist/data/table-signing.test.d.ts +0 -1
- package/dist/data/table-signing.test.js +0 -118
- package/dist/data/tool-access.test.d.ts +0 -1
- package/dist/data/tool-access.test.js +0 -166
- package/dist/data/user-permissions.test.d.ts +0 -1
- package/dist/data/user-permissions.test.js +0 -305
- package/dist/data/user-trust-levels.test.d.ts +0 -1
- package/dist/data/user-trust-levels.test.js +0 -37
- package/dist/define/also-implements.test.d.ts +0 -1
- package/dist/define/also-implements.test.js +0 -123
- package/dist/define/declare-contract.test.d.ts +0 -1
- package/dist/define/declare-contract.test.js +0 -573
- package/dist/define/define.test.d.ts +0 -1
- package/dist/define/define.test.js +0 -1010
- package/dist/define/empty-fields.test.d.ts +0 -1
- package/dist/define/empty-fields.test.js +0 -55
- package/dist/define/events-observables.test.d.ts +0 -1
- package/dist/define/events-observables.test.js +0 -1013
- package/dist/define/serve-members.test.d.ts +0 -1
- package/dist/define/serve-members.test.js +0 -630
- package/dist/define/vars.test.d.ts +0 -1
- package/dist/define/vars.test.js +0 -39
- package/dist/device/binary-peer-connection-v2.test.d.ts +0 -1
- package/dist/device/binary-peer-connection-v2.test.js +0 -730
- package/dist/device/binary-peer-connection.d.ts +0 -58
- package/dist/device/binary-peer-connection.js +0 -516
- package/dist/device/binary-peer-connection.test.d.ts +0 -1
- package/dist/device/binary-peer-connection.test.js +0 -184
- package/dist/device/connection.test.d.ts +0 -1
- package/dist/device/connection.test.js +0 -613
- package/dist/device/device-election.test.d.ts +0 -1
- package/dist/device/device-election.test.js +0 -516
- package/dist/device/device.test.d.ts +0 -1
- package/dist/device/device.test.js +0 -243
- package/dist/device/frame-cipher.test.d.ts +0 -1
- package/dist/device/frame-cipher.test.js +0 -219
- package/dist/device/get-trust-level-fn.test.d.ts +0 -1
- package/dist/device/get-trust-level-fn.test.js +0 -685
- package/dist/device/streamed-socket.d.ts +0 -23
- package/dist/device/streamed-socket.js +0 -255
- package/dist/device/streamed-socket.test.d.ts +0 -1
- package/dist/device/streamed-socket.test.js +0 -216
- package/dist/device/tx-encoding.test.d.ts +0 -1
- package/dist/device/tx-encoding.test.js +0 -295
- package/dist/device-pairing/cpace.test.d.ts +0 -1
- package/dist/device-pairing/cpace.test.js +0 -116
- package/dist/device-pairing/device-pairing.test.d.ts +0 -1
- package/dist/device-pairing/device-pairing.test.js +0 -211
- package/dist/hlc.test.d.ts +0 -1
- package/dist/hlc.test.js +0 -45
- package/dist/host-credentials.test.d.ts +0 -1
- package/dist/host-credentials.test.js +0 -88
- package/dist/identity/account-email.test.d.ts +0 -1
- package/dist/identity/account-email.test.js +0 -59
- package/dist/identity/anchor-document.test.d.ts +0 -1
- package/dist/identity/anchor-document.test.js +0 -16
- package/dist/identity/anchor-resolution.test.d.ts +0 -1
- package/dist/identity/anchor-resolution.test.js +0 -130
- package/dist/identity/key-change.test.d.ts +0 -1
- package/dist/identity/key-change.test.js +0 -811
- package/dist/invites/group-approval.test.d.ts +0 -1
- package/dist/invites/group-approval.test.js +0 -223
- package/dist/invites/invite-token.test.d.ts +0 -1
- package/dist/invites/invite-token.test.js +0 -123
- package/dist/keys.test.d.ts +0 -1
- package/dist/keys.test.js +0 -336
- package/dist/logging/console-logger.test.d.ts +0 -1
- package/dist/logging/console-logger.test.js +0 -300
- package/dist/logging/console-logs.table.test.d.ts +0 -1
- package/dist/logging/console-logs.table.test.js +0 -156
- package/dist/observable.test.d.ts +0 -1
- package/dist/observable.test.js +0 -309
- package/dist/package-build/build-package.test.d.ts +0 -1
- package/dist/package-build/build-package.test.js +0 -204
- package/dist/package-build/contract-add.test.d.ts +0 -1
- package/dist/package-build/contract-add.test.js +0 -467
- package/dist/package-build/freeze-contracts.test.d.ts +0 -1
- package/dist/package-build/freeze-contracts.test.js +0 -355
- package/dist/package-installer/package-author-signing.test.d.ts +0 -1
- package/dist/package-installer/package-author-signing.test.js +0 -200
- package/dist/package-installer/package-cloner.test.d.ts +0 -1
- package/dist/package-installer/package-cloner.test.js +0 -278
- package/dist/package-installer/package-creator.test.d.ts +0 -1
- package/dist/package-installer/package-creator.test.js +0 -908
- package/dist/package-installer/package-dev-tools.test.d.ts +0 -1
- package/dist/package-installer/package-dev-tools.test.js +0 -64
- package/dist/package-installer/package-installer.test.d.ts +0 -1
- package/dist/package-installer/package-installer.test.js +0 -882
- package/dist/package-installer/package-propagation.test.d.ts +0 -1
- package/dist/package-installer/package-propagation.test.js +0 -1269
- package/dist/package-installer/package-publisher.test.d.ts +0 -1
- package/dist/package-installer/package-publisher.test.js +0 -153
- package/dist/package-installer/package-remote-checker.test.d.ts +0 -1
- package/dist/package-installer/package-remote-checker.test.js +0 -334
- package/dist/package-installer/package-seed-installer.test.d.ts +0 -1
- package/dist/package-installer/package-seed-installer.test.js +0 -123
- package/dist/package-installer/package-tarball.test.d.ts +0 -1
- package/dist/package-installer/package-tarball.test.js +0 -75
- package/dist/package-installer/peers-core-installer.test.d.ts +0 -1
- package/dist/package-installer/peers-core-installer.test.js +0 -49
- package/dist/package-installer/peers-core-trust-anchor.test.d.ts +0 -1
- package/dist/package-installer/peers-core-trust-anchor.test.js +0 -155
- package/dist/package-loader/contract-package-loader.test.d.ts +0 -1
- package/dist/package-loader/contract-package-loader.test.js +0 -274
- package/dist/package-loader/host-authority-loading.test.d.ts +0 -1
- package/dist/package-loader/host-authority-loading.test.js +0 -104
- package/dist/package-loader/host-dispatch-policy.test.d.ts +0 -1
- package/dist/package-loader/host-dispatch-policy.test.js +0 -56
- package/dist/package-loader/isolated-artifact.test.d.ts +0 -1
- package/dist/package-loader/isolated-artifact.test.js +0 -688
- package/dist/package-loader/isolated-persistent-var-gateway.test.d.ts +0 -1
- package/dist/package-loader/isolated-persistent-var-gateway.test.js +0 -56
- package/dist/package-loader/isolated-table-gateway.test.d.ts +0 -1
- package/dist/package-loader/isolated-table-gateway.test.js +0 -633
- package/dist/package-loader/package-loader.test.d.ts +0 -1
- package/dist/package-loader/package-loader.test.js +0 -1764
- package/dist/package-loader/resolve-consumed-contracts.test.d.ts +0 -1
- package/dist/package-loader/resolve-consumed-contracts.test.js +0 -166
- package/dist/serial-json.compat.test.d.ts +0 -1
- package/dist/serial-json.compat.test.js +0 -369
- package/dist/serial-json.test.d.ts +0 -1
- package/dist/serial-json.test.js +0 -401
- package/dist/testing/mock-host-contract.test.d.ts +0 -1
- package/dist/testing/mock-host-contract.test.js +0 -782
- package/dist/utils.test.d.ts +0 -1
- package/dist/utils.test.js +0 -232
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const msgpack_1 = require("@msgpack/msgpack");
|
|
4
|
-
const serial_json_1 = require("../serial-json");
|
|
5
|
-
const tx_encoding_1 = require("./tx-encoding");
|
|
6
|
-
describe("tx-encode-decode", () => {
|
|
7
|
-
describe("txEncode and txDecode", () => {
|
|
8
|
-
it("should encode and decode simple objects", () => {
|
|
9
|
-
const testObj = {
|
|
10
|
-
name: "test",
|
|
11
|
-
number: 42,
|
|
12
|
-
bool: true,
|
|
13
|
-
str: "hello world",
|
|
14
|
-
};
|
|
15
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
16
|
-
expect(encoded).toBeInstanceOf(Uint8Array);
|
|
17
|
-
expect(encoded.length).toBeGreaterThan(0);
|
|
18
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
19
|
-
expect(decoded).toEqual(testObj);
|
|
20
|
-
});
|
|
21
|
-
it("should encode and decode arrays", () => {
|
|
22
|
-
const testArray = [1, 2, 3, "four", { five: 5 }];
|
|
23
|
-
const encoded = (0, tx_encoding_1.txEncode)(testArray);
|
|
24
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
25
|
-
expect(decoded).toEqual(testArray);
|
|
26
|
-
});
|
|
27
|
-
it("should encode and decode nested objects", () => {
|
|
28
|
-
const testObj = {
|
|
29
|
-
level1: {
|
|
30
|
-
level2: {
|
|
31
|
-
level3: {
|
|
32
|
-
value: "deep nested value",
|
|
33
|
-
number: 123,
|
|
34
|
-
},
|
|
35
|
-
array: [1, 2, 3],
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
40
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
41
|
-
expect(decoded).toEqual(testObj);
|
|
42
|
-
});
|
|
43
|
-
it("should encode and decode special types (dates, etc.)", () => {
|
|
44
|
-
const testObj = {
|
|
45
|
-
date: new Date("2023-01-01T00:00:00.000Z"),
|
|
46
|
-
nan: NaN,
|
|
47
|
-
infinity: Infinity,
|
|
48
|
-
negInfinity: -Infinity,
|
|
49
|
-
undef: undefined,
|
|
50
|
-
nullVal: null,
|
|
51
|
-
};
|
|
52
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
53
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
54
|
-
expect(decoded.date).toBeInstanceOf(Date);
|
|
55
|
-
expect(decoded.date.toISOString()).toBe("2023-01-01T00:00:00.000Z");
|
|
56
|
-
expect(Number.isNaN(decoded.nan)).toBe(true);
|
|
57
|
-
expect(decoded.infinity).toBe(Infinity);
|
|
58
|
-
expect(decoded.negInfinity).toBe(-Infinity);
|
|
59
|
-
expect(decoded.undef).toBeUndefined();
|
|
60
|
-
expect(decoded.nullVal).toBeNull();
|
|
61
|
-
});
|
|
62
|
-
it("should encode and decode Uint8Array", () => {
|
|
63
|
-
const testObj = {
|
|
64
|
-
data: new Uint8Array([72, 101, 108, 108, 111]),
|
|
65
|
-
metadata: { size: 5 },
|
|
66
|
-
};
|
|
67
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
68
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
69
|
-
expect(decoded.data).toBeInstanceOf(Uint8Array);
|
|
70
|
-
expect(decoded.data).toEqual(testObj.data);
|
|
71
|
-
expect(decoded.metadata).toEqual(testObj.metadata);
|
|
72
|
-
});
|
|
73
|
-
it("should encode and decode Buffer", () => {
|
|
74
|
-
const testObj = {
|
|
75
|
-
buffer: Buffer.from("Hello Buffer"),
|
|
76
|
-
name: "test",
|
|
77
|
-
};
|
|
78
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
79
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
80
|
-
expect(Buffer.isBuffer(decoded.buffer)).toBe(true);
|
|
81
|
-
expect(decoded.buffer).toEqual(testObj.buffer);
|
|
82
|
-
expect(decoded.name).toBe("test");
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
describe("compression threshold", () => {
|
|
86
|
-
it("should not compress small payloads (< 1024 bytes)", () => {
|
|
87
|
-
const smallObj = { message: "small" };
|
|
88
|
-
const encoded = (0, tx_encoding_1.txEncode)(smallObj);
|
|
89
|
-
// First byte is the flag
|
|
90
|
-
expect(encoded[0]).toBe(0); // flag = 0 means not compressed
|
|
91
|
-
});
|
|
92
|
-
it("should compress large payloads (> 1024 bytes)", () => {
|
|
93
|
-
// Create an object that will exceed 8KB when msgpack-encoded
|
|
94
|
-
// msgpack is more compact than JSON, so we need significantly more data
|
|
95
|
-
// A string of 20,000 chars is roughly 20KB in JSON, but msgpack uses length prefix + bytes
|
|
96
|
-
// So we need even more to ensure msgpack encoding exceeds 8KB
|
|
97
|
-
const largeObj = {
|
|
98
|
-
data: "x".repeat(30000),
|
|
99
|
-
array: Array.from({ length: 1000 }, (_, i) => ({
|
|
100
|
-
id: i,
|
|
101
|
-
value: `item ${i} with some extra text to make it larger and ensure we exceed the threshold`,
|
|
102
|
-
nested: { prop: `nested value ${i}` },
|
|
103
|
-
})),
|
|
104
|
-
};
|
|
105
|
-
const encoded = (0, tx_encoding_1.txEncode)(largeObj);
|
|
106
|
-
// Verify the encoded size (without flag byte) exceeds 8KB threshold
|
|
107
|
-
const encodedSize = encoded.length - 1; // subtract flag byte
|
|
108
|
-
expect(encodedSize).toBeGreaterThan(8 * 1024);
|
|
109
|
-
// First byte is the flag
|
|
110
|
-
expect(encoded[0]).toBe(1); // flag = 1 means compressed
|
|
111
|
-
// Verify it can still be decoded correctly
|
|
112
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
113
|
-
expect(decoded).toEqual(largeObj);
|
|
114
|
-
});
|
|
115
|
-
it("should have smaller encoded size for large compressible data", () => {
|
|
116
|
-
// Create data that exceeds 8KB when msgpack-encoded and compresses well
|
|
117
|
-
// Use data with some repetition but also enough variety to ensure msgpack size is large
|
|
118
|
-
const largeRepetitiveObj = {
|
|
119
|
-
data: "repeat ".repeat(10000), // Highly repetitive string - will compress well
|
|
120
|
-
values: Array.from({ length: 5000 }, (_, i) => `item ${i} with some text that repeats to create compressible data pattern`),
|
|
121
|
-
};
|
|
122
|
-
// First, verify the msgpack-encoded size exceeds 8KB threshold
|
|
123
|
-
const noCycles = (0, serial_json_1.toJSON)(largeRepetitiveObj);
|
|
124
|
-
const msgpackEncoded = (0, msgpack_1.encode)(noCycles);
|
|
125
|
-
expect(msgpackEncoded.length).toBeGreaterThan(8 * 1024);
|
|
126
|
-
const encoded = (0, tx_encoding_1.txEncode)(largeRepetitiveObj);
|
|
127
|
-
// Verify compression flag is set (means compression was applied)
|
|
128
|
-
expect(encoded[0]).toBe(1); // flag = 1 means compressed
|
|
129
|
-
// Compressed size should be significantly smaller than the raw msgpack data
|
|
130
|
-
const compressedSize = encoded.length - 1; // subtract flag byte
|
|
131
|
-
expect(compressedSize).toBeLessThan(msgpackEncoded.length * 0.8); // Should be at least 20% smaller
|
|
132
|
-
// Verify correctness
|
|
133
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
134
|
-
expect(decoded).toEqual(largeRepetitiveObj);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
describe("error handling", () => {
|
|
138
|
-
it("should throw error on empty payload", () => {
|
|
139
|
-
const emptyPayload = new Uint8Array(0);
|
|
140
|
-
expect(() => (0, tx_encoding_1.txDecode)(emptyPayload)).toThrow("Empty payload");
|
|
141
|
-
});
|
|
142
|
-
it("should throw error on unknown flag", () => {
|
|
143
|
-
// Create a payload with an invalid flag (2)
|
|
144
|
-
const invalidPayload = new Uint8Array([2, 0, 0, 0]);
|
|
145
|
-
expect(() => (0, tx_encoding_1.txDecode)(invalidPayload)).toThrow("Unknown tx flag: 2");
|
|
146
|
-
});
|
|
147
|
-
it("should throw error on unknown flag (255)", () => {
|
|
148
|
-
const invalidPayload = new Uint8Array([255, 0, 0, 0]);
|
|
149
|
-
expect(() => (0, tx_encoding_1.txDecode)(invalidPayload)).toThrow("Unknown tx flag: 255");
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
describe("untrusted input", () => {
|
|
153
|
-
afterEach(() => {
|
|
154
|
-
delete Object.prototype.polluted;
|
|
155
|
-
});
|
|
156
|
-
it("does not let a decoded message write onto Object.prototype", () => {
|
|
157
|
-
const decoded = (0, tx_encoding_1.txDecode)((0, tx_encoding_1.txEncode)({ __this_ref: "__proto__", polluted: "yes" }));
|
|
158
|
-
expect({}.polluted).toBeUndefined();
|
|
159
|
-
expect(decoded).toEqual({ polluted: "yes" });
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
describe("round-trip consistency", () => {
|
|
163
|
-
it("should handle empty objects", () => {
|
|
164
|
-
const emptyObj = {};
|
|
165
|
-
const encoded = (0, tx_encoding_1.txEncode)(emptyObj);
|
|
166
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
167
|
-
expect(decoded).toEqual(emptyObj);
|
|
168
|
-
});
|
|
169
|
-
it("should handle empty arrays", () => {
|
|
170
|
-
const emptyArray = [];
|
|
171
|
-
const encoded = (0, tx_encoding_1.txEncode)(emptyArray);
|
|
172
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
173
|
-
expect(decoded).toEqual(emptyArray);
|
|
174
|
-
});
|
|
175
|
-
it("should handle strings with special characters", () => {
|
|
176
|
-
const testObj = {
|
|
177
|
-
emoji: "🚀🎉",
|
|
178
|
-
unicode: "Hello 世界",
|
|
179
|
-
special: "line1\nline2\ttab",
|
|
180
|
-
quotes: 'He said "hello"',
|
|
181
|
-
};
|
|
182
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
183
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
184
|
-
expect(decoded).toEqual(testObj);
|
|
185
|
-
});
|
|
186
|
-
it("should handle very large numbers", () => {
|
|
187
|
-
const testObj = {
|
|
188
|
-
maxSafeInt: Number.MAX_SAFE_INTEGER,
|
|
189
|
-
minSafeInt: Number.MIN_SAFE_INTEGER,
|
|
190
|
-
large: 9007199254740991,
|
|
191
|
-
small: -9007199254740991,
|
|
192
|
-
};
|
|
193
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
194
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
195
|
-
expect(decoded).toEqual(testObj);
|
|
196
|
-
});
|
|
197
|
-
it("should handle mixed type arrays", () => {
|
|
198
|
-
const testArray = [
|
|
199
|
-
1,
|
|
200
|
-
"string",
|
|
201
|
-
true,
|
|
202
|
-
null,
|
|
203
|
-
undefined,
|
|
204
|
-
{ obj: "value" },
|
|
205
|
-
[1, 2, 3],
|
|
206
|
-
new Date("2023-01-01"),
|
|
207
|
-
new Uint8Array([1, 2, 3]),
|
|
208
|
-
];
|
|
209
|
-
const encoded = (0, tx_encoding_1.txEncode)(testArray);
|
|
210
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
211
|
-
expect(decoded[0]).toBe(1);
|
|
212
|
-
expect(decoded[1]).toBe("string");
|
|
213
|
-
expect(decoded[2]).toBe(true);
|
|
214
|
-
expect(decoded[3]).toBeNull();
|
|
215
|
-
expect(decoded[4]).toBeUndefined();
|
|
216
|
-
expect(decoded[5]).toEqual({ obj: "value" });
|
|
217
|
-
expect(decoded[6]).toEqual([1, 2, 3]);
|
|
218
|
-
expect(decoded[7]).toBeInstanceOf(Date);
|
|
219
|
-
expect(decoded[8]).toBeInstanceOf(Uint8Array);
|
|
220
|
-
expect(decoded[8]).toEqual(new Uint8Array([1, 2, 3]));
|
|
221
|
-
});
|
|
222
|
-
it("should handle objects with circular references removed by toJSON", () => {
|
|
223
|
-
// toJSON handles circular references, so this should work
|
|
224
|
-
const obj = { name: "test" };
|
|
225
|
-
obj.self = obj; // circular reference
|
|
226
|
-
const encoded = (0, tx_encoding_1.txEncode)(obj);
|
|
227
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
228
|
-
// The circular reference should be handled by toJSON/fromJSON
|
|
229
|
-
expect(decoded).toHaveProperty("name", "test");
|
|
230
|
-
expect(decoded).toHaveProperty("self");
|
|
231
|
-
expect(decoded.self).toBe(decoded); // self-reference restored
|
|
232
|
-
});
|
|
233
|
-
it("should preserve data integrity across multiple encode/decode cycles", () => {
|
|
234
|
-
const original = {
|
|
235
|
-
id: 123,
|
|
236
|
-
name: "multi-cycle test",
|
|
237
|
-
data: new Uint8Array([1, 2, 3, 4, 5]),
|
|
238
|
-
timestamp: new Date("2023-06-15T12:00:00.000Z"),
|
|
239
|
-
};
|
|
240
|
-
// Encode and decode multiple times
|
|
241
|
-
let current = original;
|
|
242
|
-
for (let i = 0; i < 5; i++) {
|
|
243
|
-
const encoded = (0, tx_encoding_1.txEncode)(current);
|
|
244
|
-
current = (0, tx_encoding_1.txDecode)(encoded);
|
|
245
|
-
}
|
|
246
|
-
expect(current.id).toBe(original.id);
|
|
247
|
-
expect(current.name).toBe(original.name);
|
|
248
|
-
expect(current.data).toEqual(original.data);
|
|
249
|
-
expect(current.timestamp).toEqual(original.timestamp);
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
describe("payload structure", () => {
|
|
253
|
-
it("should have flag byte as first byte", () => {
|
|
254
|
-
const testObj = { test: "value" };
|
|
255
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
256
|
-
// First byte should be 0 or 1
|
|
257
|
-
expect(encoded[0]).toBeGreaterThanOrEqual(0);
|
|
258
|
-
expect(encoded[0]).toBeLessThanOrEqual(1);
|
|
259
|
-
});
|
|
260
|
-
it("should have body after flag byte", () => {
|
|
261
|
-
const testObj = { test: "value" };
|
|
262
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
263
|
-
// Should have at least 2 bytes (flag + body)
|
|
264
|
-
expect(encoded.length).toBeGreaterThan(1);
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
describe("edge cases", () => {
|
|
268
|
-
it("should handle objects at exactly 1024 bytes threshold", () => {
|
|
269
|
-
// Create an object that when msgpack-encoded is very close to 1024 bytes
|
|
270
|
-
// This is tricky to get exact, so we just verify it works
|
|
271
|
-
const testObj = {
|
|
272
|
-
data: "x".repeat(1000),
|
|
273
|
-
};
|
|
274
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
275
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
276
|
-
expect(decoded).toEqual(testObj);
|
|
277
|
-
});
|
|
278
|
-
it("should handle primitive values", () => {
|
|
279
|
-
expect((0, tx_encoding_1.txDecode)((0, tx_encoding_1.txEncode)(42))).toBe(42);
|
|
280
|
-
expect((0, tx_encoding_1.txDecode)((0, tx_encoding_1.txEncode)("string"))).toBe("string");
|
|
281
|
-
expect((0, tx_encoding_1.txDecode)((0, tx_encoding_1.txEncode)(true))).toBe(true);
|
|
282
|
-
expect((0, tx_encoding_1.txDecode)((0, tx_encoding_1.txEncode)(false))).toBe(false);
|
|
283
|
-
expect((0, tx_encoding_1.txDecode)((0, tx_encoding_1.txEncode)(null))).toBe(null);
|
|
284
|
-
});
|
|
285
|
-
it("should handle objects with only undefined values", () => {
|
|
286
|
-
const testObj = {
|
|
287
|
-
a: undefined,
|
|
288
|
-
b: undefined,
|
|
289
|
-
};
|
|
290
|
-
const encoded = (0, tx_encoding_1.txEncode)(testObj);
|
|
291
|
-
const decoded = (0, tx_encoding_1.txDecode)(encoded);
|
|
292
|
-
expect(decoded).toEqual(testObj);
|
|
293
|
-
});
|
|
294
|
-
});
|
|
295
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const cpace_1 = require("./cpace");
|
|
4
|
-
// Test vectors from draft-irtf-cfrg-cpace, "CPace using group X25519 and hash SHA-512".
|
|
5
|
-
const VECTOR = {
|
|
6
|
-
PRS: "50617373776F7264",
|
|
7
|
-
CI: "0B415F696E69746961746F720B425F726573706F6E646572",
|
|
8
|
-
sid: "7E4B4791D6A8EF019B936C79FB7F2C57",
|
|
9
|
-
g: "D04BF6D41F6A289632A2E929FA29BEBD51092512A7829FDDE7D314B62F05A73F",
|
|
10
|
-
ya: "21B4F4BD9E64ED355C3EB676A28EBEDAF6D8F17BDC365995B319097153044080",
|
|
11
|
-
ADa: "414461",
|
|
12
|
-
Ya: "1D13C89278CDADD826F6D8D7F887701430F8380DDC17611CDD6DC989CE0C9F32",
|
|
13
|
-
yb: "848B0779FF415F0AF4EA14DF9DD1D3C29AC41D836C7808896C4EBA19C51AC40A",
|
|
14
|
-
ADb: "414462",
|
|
15
|
-
Yb: "248CCCF6D5CDC3646F0AD593F9E6CEF4E69D4945F8372E623512ECEA32185623",
|
|
16
|
-
K: "5B067EFFBDC0B2A0E1D907B21EBB25CFEDB96A852179A847C37E43EE71322C6B",
|
|
17
|
-
ISK_IR: "6E19B875F7A561D6B3CA3DBB9EF42AC55DE3E717881018204B8922B4D5E53BB2AA82C300BEA7B65D2B671DA71922DDF6472301B79BC270ADFA8BF413285F2263",
|
|
18
|
-
};
|
|
19
|
-
// scalar_mult_vfy vectors: low-order (and non-canonical low-order) inputs abort; the rest
|
|
20
|
-
// must produce the draft's exact outputs, proving bit #255 is cleared before the ladder.
|
|
21
|
-
const VFY_SCALAR = "AF46E36BF0527C9D3B16154B82465EDD62144C0AC1FC5A18506A2244BA449AFF";
|
|
22
|
-
const LOW_ORDER_POINTS = [
|
|
23
|
-
"0000000000000000000000000000000000000000000000000000000000000000",
|
|
24
|
-
"0100000000000000000000000000000000000000000000000000000000000000",
|
|
25
|
-
"ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F",
|
|
26
|
-
"E0EB7A7C3B41B8AE1656E3FAF19FC46ADA098DEB9C32B1FD866205165F49B800",
|
|
27
|
-
"5F9C95BCA3508C24B1D0B1559C83EF5B04445CC4581C8E86D8224EDDD09F1157",
|
|
28
|
-
"EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F",
|
|
29
|
-
"EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F",
|
|
30
|
-
];
|
|
31
|
-
const NON_CANONICAL_POINTS = [
|
|
32
|
-
[
|
|
33
|
-
"DAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
34
|
-
"D8E2C776BBACD510D09FD9278B7EDCD25FC5AE9ADFBA3B6E040E8D3B71B21806",
|
|
35
|
-
],
|
|
36
|
-
[
|
|
37
|
-
"DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
38
|
-
"C85C655EBE8BE44BA9C0FFDE69F2FE10194458D137F09BBFF725CE58803CDB38",
|
|
39
|
-
],
|
|
40
|
-
[
|
|
41
|
-
"D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
42
|
-
"DB64DAFA9B8FDD136914E61461935FE92AA372CB056314E1231BC4EC12417456",
|
|
43
|
-
],
|
|
44
|
-
[
|
|
45
|
-
"CDEB7A7C3B41B8AE1656E3FAF19FC46ADA098DEB9C32B1FD866205165F49B880",
|
|
46
|
-
"E062DCD5376D58297BE2618C7498F55BAA07D7E03184E8AADA20BCA28888BF7A",
|
|
47
|
-
],
|
|
48
|
-
[
|
|
49
|
-
"4C9C95BCA3508C24B1D0B1559C83EF5B04445CC4581C8E86D8224EDDD09F11D7",
|
|
50
|
-
"993C6AD11C4C29DA9A56F7691FD0FF8D732E49DE6250B6C2E80003FF4629A175",
|
|
51
|
-
],
|
|
52
|
-
];
|
|
53
|
-
function hex(value) {
|
|
54
|
-
return Uint8Array.from(Buffer.from(value, "hex"));
|
|
55
|
-
}
|
|
56
|
-
function toHex(value) {
|
|
57
|
-
return Buffer.from(value).toString("hex").toUpperCase();
|
|
58
|
-
}
|
|
59
|
-
describe("cpace string utilities", () => {
|
|
60
|
-
it("matches prepend_len and lv_cat vectors", () => {
|
|
61
|
-
expect(toHex((0, cpace_1.cpacePrependLength)(new Uint8Array(0)))).toBe("00");
|
|
62
|
-
expect(toHex((0, cpace_1.cpacePrependLength)(Buffer.from("1234")))).toBe("0431323334");
|
|
63
|
-
expect(toHex((0, cpace_1.cpacePrependLength)(new Uint8Array(128))).slice(0, 4)).toBe("8001");
|
|
64
|
-
expect(toHex((0, cpace_1.cpaceLvCat)(Buffer.from("1234"), Buffer.from("5"), new Uint8Array(0), Buffer.from("678")))).toBe("043132333401350003363738");
|
|
65
|
-
});
|
|
66
|
-
it("matches transcript_ir vector", () => {
|
|
67
|
-
expect(toHex((0, cpace_1.cpaceTranscript)(Buffer.from("123"), Buffer.from("PartyA"), Buffer.from("234"), Buffer.from("PartyB")))).toBe("03313233065061727479410332333406506172747942");
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
describe("cpace CPace255 vectors", () => {
|
|
71
|
-
it("derives the generator string and secret generator", () => {
|
|
72
|
-
const generatorString = (0, cpace_1.cpaceGeneratorString)(hex(VECTOR.PRS), hex(VECTOR.CI), hex(VECTOR.sid));
|
|
73
|
-
expect(generatorString).toHaveLength(170);
|
|
74
|
-
expect(toHex(generatorString).startsWith("0843506163653235350850617373776F72646D00")).toBe(true);
|
|
75
|
-
expect(toHex((0, cpace_1.cpaceCalculateGenerator)(hex(VECTOR.PRS), hex(VECTOR.CI), hex(VECTOR.sid)))).toBe(VECTOR.g);
|
|
76
|
-
});
|
|
77
|
-
it("derives both shares, the shared point, and the initiator/responder ISK", () => {
|
|
78
|
-
const parameters = {
|
|
79
|
-
password: hex(VECTOR.PRS),
|
|
80
|
-
channelId: hex(VECTOR.CI),
|
|
81
|
-
sessionId: hex(VECTOR.sid),
|
|
82
|
-
initiatorAd: hex(VECTOR.ADa),
|
|
83
|
-
responderAd: hex(VECTOR.ADb),
|
|
84
|
-
};
|
|
85
|
-
const initiator = (0, cpace_1.cpaceStart)("initiator", parameters, hex(VECTOR.ya));
|
|
86
|
-
const responder = (0, cpace_1.cpaceStart)("responder", parameters, hex(VECTOR.yb));
|
|
87
|
-
expect(toHex(initiator.share)).toBe(VECTOR.Ya);
|
|
88
|
-
expect(toHex(responder.share)).toBe(VECTOR.Yb);
|
|
89
|
-
expect(toHex((0, cpace_1.cpaceScalarMultVerify)(hex(VECTOR.ya), hex(VECTOR.Yb)))).toBe(VECTOR.K);
|
|
90
|
-
expect(toHex((0, cpace_1.cpaceDeriveIsk)(hex(VECTOR.K), hex(VECTOR.sid), (0, cpace_1.cpaceTranscript)(hex(VECTOR.Ya), hex(VECTOR.ADa), hex(VECTOR.Yb), hex(VECTOR.ADb))))).toBe(VECTOR.ISK_IR);
|
|
91
|
-
const initiatorIsk = toHex(initiator.finish(hex(VECTOR.Yb)));
|
|
92
|
-
const responderIsk = toHex(responder.finish(hex(VECTOR.Ya)));
|
|
93
|
-
expect(initiatorIsk).toBe(VECTOR.ISK_IR);
|
|
94
|
-
expect(responderIsk).toBe(VECTOR.ISK_IR);
|
|
95
|
-
});
|
|
96
|
-
it("rejects low-order points and clears bit #255 of non-canonical inputs", () => {
|
|
97
|
-
for (const point of LOW_ORDER_POINTS) {
|
|
98
|
-
expect(() => (0, cpace_1.cpaceScalarMultVerify)(hex(VFY_SCALAR), hex(point))).toThrow(/low-order/);
|
|
99
|
-
}
|
|
100
|
-
for (const [point, expected] of NON_CANONICAL_POINTS) {
|
|
101
|
-
expect(toHex((0, cpace_1.cpaceScalarMultVerify)(hex(VFY_SCALAR), hex(point)))).toBe(expected);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
it("produces unrelated keys for different passwords and identical keys for the same password", () => {
|
|
105
|
-
const shared = { channelId: Buffer.from("channel"), sessionId: new Uint8Array(0) };
|
|
106
|
-
const good = (0, cpace_1.cpaceStart)("initiator", { ...shared, password: Buffer.from("guitar-revenge") });
|
|
107
|
-
const right = (0, cpace_1.cpaceStart)("responder", { ...shared, password: Buffer.from("guitar-revenge") });
|
|
108
|
-
const wrong = (0, cpace_1.cpaceStart)("responder", { ...shared, password: Buffer.from("guitar-reward") });
|
|
109
|
-
const rightShare = Uint8Array.from(right.share);
|
|
110
|
-
const wrongShare = Uint8Array.from(wrong.share);
|
|
111
|
-
const goodShare = Uint8Array.from(good.share);
|
|
112
|
-
expect(toHex(right.finish(goodShare))).toBe(toHex(good.finish(rightShare)));
|
|
113
|
-
const second = (0, cpace_1.cpaceStart)("initiator", { ...shared, password: Buffer.from("guitar-revenge") });
|
|
114
|
-
expect(toHex(wrong.finish(Uint8Array.from(second.share)))).not.toBe(toHex(second.finish(wrongShare)));
|
|
115
|
-
});
|
|
116
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const device_1 = require("../device/device");
|
|
4
|
-
const keys_1 = require("../keys");
|
|
5
|
-
const utils_1 = require("../utils");
|
|
6
|
-
const _1 = require(".");
|
|
7
|
-
const NOW = 1_800_000_000_000;
|
|
8
|
-
const ORIGIN = "https://peers.app";
|
|
9
|
-
const FINGERPRINT = Array.from({ length: 32 }, (_, index) => index.toString(16).padStart(2, "0"))
|
|
10
|
-
.join(":")
|
|
11
|
-
.toUpperCase();
|
|
12
|
-
describe("pairing code", () => {
|
|
13
|
-
it("uses the full PGP word lists with no duplicates", () => {
|
|
14
|
-
expect(_1.PGP_EVEN_WORDS).toHaveLength(256);
|
|
15
|
-
expect(_1.PGP_ODD_WORDS).toHaveLength(256);
|
|
16
|
-
expect(new Set([..._1.PGP_EVEN_WORDS, ..._1.PGP_ODD_WORDS]).size).toBe(512);
|
|
17
|
-
});
|
|
18
|
-
it("generates even/odd/even words and round-trips through formatting and parsing", () => {
|
|
19
|
-
const words = (0, _1.generatePairingWords)();
|
|
20
|
-
expect(_1.PGP_EVEN_WORDS).toContain(words[0]);
|
|
21
|
-
expect(_1.PGP_ODD_WORDS).toContain(words[1]);
|
|
22
|
-
expect(_1.PGP_EVEN_WORDS).toContain(words[2]);
|
|
23
|
-
const text = (0, _1.formatPairingCode)(7, words);
|
|
24
|
-
expect(text).toBe(`7-${words.join("-")}`);
|
|
25
|
-
expect((0, _1.parsePairingCode)(text)).toEqual({ nameplate: 7, words });
|
|
26
|
-
expect((0, _1.parsePairingCode)(` 7 ${words.join(" ").toUpperCase()} `)).toEqual({
|
|
27
|
-
nameplate: 7,
|
|
28
|
-
words,
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
it("rejects wrong slots, unknown words, bad nameplates, and wrong lengths", () => {
|
|
32
|
-
expect(() => (0, _1.parsePairingCode)("7-adroitness-aardvark-absurd")).toThrow(/word 1/);
|
|
33
|
-
expect(() => (0, _1.parsePairingCode)("7-aardvark-absurd-acme")).toThrow(/word 2/);
|
|
34
|
-
expect(() => (0, _1.parsePairingCode)("7-aardvark-adroitness-nope")).toThrow(/word 3/);
|
|
35
|
-
expect(() => (0, _1.parsePairingCode)("0-aardvark-adroitness-acme")).toThrow(/room number/);
|
|
36
|
-
expect(() => (0, _1.parsePairingCode)("10000-aardvark-adroitness-acme")).toThrow(/room number/);
|
|
37
|
-
expect(() => (0, _1.parsePairingCode)("aardvark-adroitness-acme")).toThrow(/three words/);
|
|
38
|
-
expect(() => (0, _1.parsePairingCode)("7-aardvark-adroitness")).toThrow(/three words/);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe("pairing PAKE and signaling", () => {
|
|
42
|
-
const code = (0, _1.parsePairingCode)("42-aardvark-adroitness-acme");
|
|
43
|
-
it("derives matching keys for the same code and different keys for a wrong code", () => {
|
|
44
|
-
const source = (0, _1.startPairingPake)("source", code, ORIGIN);
|
|
45
|
-
const destination = (0, _1.startPairingPake)("destination", code, ORIGIN);
|
|
46
|
-
const sourceKeys = source.finish(destination.share);
|
|
47
|
-
const destinationKeys = destination.finish(source.share);
|
|
48
|
-
expect(sourceKeys).toEqual(destinationKeys);
|
|
49
|
-
expect(sourceKeys.signalingKey).not.toBe(sourceKeys.confirmKey);
|
|
50
|
-
const token = (0, _1.derivePairingWebSocketToken)(sourceKeys.signalingKey);
|
|
51
|
-
expect(token).toBe((0, _1.derivePairingWebSocketToken)(destinationKeys.signalingKey));
|
|
52
|
-
expect(token).not.toBe(sourceKeys.signalingKey);
|
|
53
|
-
expect(token).not.toBe(sourceKeys.confirmKey);
|
|
54
|
-
const wrong = (0, _1.startPairingPake)("source", (0, _1.parsePairingCode)("42-absurd-adroitness-acme"), ORIGIN);
|
|
55
|
-
const honest = (0, _1.startPairingPake)("destination", code, ORIGIN);
|
|
56
|
-
expect(wrong.finish(honest.share)).not.toEqual(honest.finish(wrong.share));
|
|
57
|
-
const otherRoom = (0, _1.startPairingPake)("source", { ...code, nameplate: 43 }, ORIGIN);
|
|
58
|
-
const thisRoom = (0, _1.startPairingPake)("destination", code, ORIGIN);
|
|
59
|
-
expect(otherRoom.finish(thisRoom.share)).not.toEqual(thisRoom.finish(otherRoom.share));
|
|
60
|
-
});
|
|
61
|
-
it("accepts the pake share unauthenticated and everything else only with the key", () => {
|
|
62
|
-
const share = (0, _1.startPairingPake)("source", code, ORIGIN).share;
|
|
63
|
-
const pake = (0, _1.createPairingPakeSignal)({
|
|
64
|
-
nameplate: 42,
|
|
65
|
-
senderRole: "source",
|
|
66
|
-
sequence: 1,
|
|
67
|
-
share,
|
|
68
|
-
});
|
|
69
|
-
expect((0, _1.verifyPairingSignal)(pake, undefined, {
|
|
70
|
-
nameplate: 42,
|
|
71
|
-
senderRole: "source",
|
|
72
|
-
nextSequence: 1,
|
|
73
|
-
})).toEqual(pake);
|
|
74
|
-
const keys = (0, _1.startPairingPake)("destination", code, ORIGIN);
|
|
75
|
-
const signalingKey = keys.finish(share).signalingKey;
|
|
76
|
-
const options = (0, _1.signPairingSignal)({
|
|
77
|
-
version: 3,
|
|
78
|
-
nameplate: 42,
|
|
79
|
-
senderRole: "destination",
|
|
80
|
-
sequence: 2,
|
|
81
|
-
kind: "transport-options",
|
|
82
|
-
payload: {
|
|
83
|
-
endpointNonce: (0, keys_1.newToken)(32),
|
|
84
|
-
webrtc: false,
|
|
85
|
-
websocket: { urls: ["http://192.168.1.20:3341", "wss://peers.example.com"] },
|
|
86
|
-
},
|
|
87
|
-
}, signalingKey);
|
|
88
|
-
expect((0, _1.verifyPairingSignal)(options, signalingKey, {
|
|
89
|
-
nameplate: 42,
|
|
90
|
-
senderRole: "destination",
|
|
91
|
-
nextSequence: 2,
|
|
92
|
-
})).toEqual(options);
|
|
93
|
-
expect(() => (0, _1.signPairingSignal)({
|
|
94
|
-
...options,
|
|
95
|
-
payload: { ...options.payload, websocket: { urls: ["ftp://nope"] } },
|
|
96
|
-
}, signalingKey)).toThrow();
|
|
97
|
-
const choice = (0, _1.signPairingSignal)({
|
|
98
|
-
version: 3,
|
|
99
|
-
nameplate: 42,
|
|
100
|
-
senderRole: "source",
|
|
101
|
-
sequence: 2,
|
|
102
|
-
kind: "transport-choice",
|
|
103
|
-
payload: { endpointNonce: (0, keys_1.newToken)(32), selected: "ws", url: "http://192.168.1.20:3341" },
|
|
104
|
-
}, signalingKey);
|
|
105
|
-
expect((0, _1.verifyPairingSignal)(choice, signalingKey, {
|
|
106
|
-
nameplate: 42,
|
|
107
|
-
senderRole: "source",
|
|
108
|
-
nextSequence: 2,
|
|
109
|
-
})).toEqual(choice);
|
|
110
|
-
const offerSdp = `v=0\r\na=fingerprint:sha-256 ${FINGERPRINT}\r\n`;
|
|
111
|
-
const signal = (0, _1.signPairingSignal)({
|
|
112
|
-
version: 3,
|
|
113
|
-
nameplate: 42,
|
|
114
|
-
senderRole: "source",
|
|
115
|
-
sequence: 3,
|
|
116
|
-
kind: "offer",
|
|
117
|
-
payload: { type: "offer", sdp: offerSdp },
|
|
118
|
-
}, signalingKey);
|
|
119
|
-
const expected = { nameplate: 42, senderRole: "source", nextSequence: 3 };
|
|
120
|
-
expect((0, _1.verifyPairingSignal)(signal, signalingKey, expected)).toEqual(signal);
|
|
121
|
-
expect(() => (0, _1.verifyPairingSignal)(signal, undefined, expected)).toThrow(/before authentication/);
|
|
122
|
-
expect(() => (0, _1.verifyPairingSignal)({ ...signal, payload: { ...signal.payload, sdp: `${offerSdp}modified` } }, signalingKey, expected)).toThrow(/authentication failed/);
|
|
123
|
-
expect(() => (0, _1.verifyPairingSignal)(signal, signalingKey, { ...expected, senderRole: "destination" })).toThrow(/out of order/);
|
|
124
|
-
expect(() => (0, _1.verifyPairingSignal)(signal, signalingKey, { ...expected, nextSequence: 4 })).toThrow(/out of order/);
|
|
125
|
-
expect(() => (0, _1.verifyPairingSignal)(signal, signalingKey, { ...expected, nameplate: 41 })).toThrow(/out of order/);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
describe("pairing transcript, confirmation, and credentials", () => {
|
|
129
|
-
const source = new device_1.Device();
|
|
130
|
-
const destination = new device_1.Device();
|
|
131
|
-
const sdp = `v=0\r\na=fingerprint:sha-256 ${FINGERPRINT}\r\n`;
|
|
132
|
-
const transcript = {
|
|
133
|
-
version: 3,
|
|
134
|
-
serviceOrigin: ORIGIN,
|
|
135
|
-
nameplate: 42,
|
|
136
|
-
sourceIdentity: (0, keys_1.openSignedObject)(source.getDeviceInfo()),
|
|
137
|
-
destinationIdentity: (0, keys_1.openSignedObject)(destination.getDeviceInfo()),
|
|
138
|
-
sourceEndpointNonce: (0, keys_1.newToken)(32),
|
|
139
|
-
destinationEndpointNonce: (0, keys_1.newToken)(32),
|
|
140
|
-
transport: "wrtc",
|
|
141
|
-
transportBinding: (0, _1.webRtcPairingTransportBinding)(sdp, sdp),
|
|
142
|
-
};
|
|
143
|
-
it("hashes the transcript deterministically and changes with any input", () => {
|
|
144
|
-
const hash = (0, _1.computeDevicePairingTranscriptHash)(transcript);
|
|
145
|
-
expect((0, _1.computeDevicePairingTranscriptHash)(transcript)).toBe(hash);
|
|
146
|
-
expect((0, _1.computeDevicePairingTranscriptHash)({ ...transcript, nameplate: 43 })).not.toBe(hash);
|
|
147
|
-
expect(transcript.transportBinding).toBe(`${(0, _1.extractSha256SdpFingerprint)(sdp)}|${(0, _1.extractSha256SdpFingerprint)(sdp)}`);
|
|
148
|
-
expect((0, _1.computeDevicePairingTranscriptHash)({
|
|
149
|
-
...transcript,
|
|
150
|
-
transportBinding: transcript.transportBinding.replace("00", "FF"),
|
|
151
|
-
})).not.toBe(hash);
|
|
152
|
-
expect((0, _1.computeDevicePairingTranscriptHash)({
|
|
153
|
-
...transcript,
|
|
154
|
-
transport: "ws",
|
|
155
|
-
transportBinding: "http://192.168.1.20:3341",
|
|
156
|
-
})).not.toBe(hash);
|
|
157
|
-
});
|
|
158
|
-
it("confirms only with the same key, role, transcript, and identity", () => {
|
|
159
|
-
const code = (0, _1.parsePairingCode)("42-aardvark-adroitness-acme");
|
|
160
|
-
const sourcePake = (0, _1.startPairingPake)("source", code, ORIGIN);
|
|
161
|
-
const destinationPake = (0, _1.startPairingPake)("destination", code, ORIGIN);
|
|
162
|
-
const keys = sourcePake.finish(destinationPake.share);
|
|
163
|
-
const wrongKeys = (0, _1.startPairingPake)("destination", (0, _1.parsePairingCode)("42-absurd-adroitness-acme"), ORIGIN).finish((0, _1.startPairingPake)("source", code, ORIGIN).share);
|
|
164
|
-
const transcriptHash = (0, _1.computeDevicePairingTranscriptHash)(transcript);
|
|
165
|
-
const confirmation = (0, _1.createPairingConfirmation)({
|
|
166
|
-
role: "destination",
|
|
167
|
-
transcriptHash,
|
|
168
|
-
device: transcript.destinationIdentity,
|
|
169
|
-
presentation: { deviceName: "Phone", deviceType: "mobile" },
|
|
170
|
-
}, keys.confirmKey);
|
|
171
|
-
const expected = {
|
|
172
|
-
role: "destination",
|
|
173
|
-
transcriptHash,
|
|
174
|
-
device: transcript.destinationIdentity,
|
|
175
|
-
};
|
|
176
|
-
expect((0, _1.verifyPairingConfirmation)(confirmation, keys.confirmKey, expected)).toEqual(confirmation);
|
|
177
|
-
expect(() => (0, _1.verifyPairingConfirmation)(confirmation, wrongKeys.confirmKey, expected)).toThrow(/did not match/);
|
|
178
|
-
expect(() => (0, _1.verifyPairingConfirmation)(confirmation, keys.confirmKey, { ...expected, role: "source" })).toThrow(/does not match/);
|
|
179
|
-
expect(() => (0, _1.verifyPairingConfirmation)(confirmation, keys.confirmKey, {
|
|
180
|
-
...expected,
|
|
181
|
-
device: transcript.sourceIdentity,
|
|
182
|
-
})).toThrow(/identity mismatch/);
|
|
183
|
-
expect(() => (0, _1.verifyPairingConfirmation)({ ...confirmation, presentation: { deviceName: "Evil" } }, keys.confirmKey, expected)).toThrow(/did not match/);
|
|
184
|
-
});
|
|
185
|
-
it("requires the expected identities and transcript for credentials and receipt", () => {
|
|
186
|
-
const transcriptHash = (0, keys_1.newToken)(32);
|
|
187
|
-
const expiresAt = NOW + 60_000;
|
|
188
|
-
const credentials = { userId: (0, utils_1.newid)(), secretKey: (0, keys_1.newKeys)().secretKey };
|
|
189
|
-
const destinationInfo = (0, keys_1.openSignedObject)(destination.getDeviceInfo());
|
|
190
|
-
const envelope = (0, _1.createPairingCredentialEnvelope)(source, destinationInfo, credentials, transcriptHash, expiresAt);
|
|
191
|
-
expect((0, _1.openPairingCredentialEnvelope)(destination, envelope, {
|
|
192
|
-
sourcePublicKey: source.publicKey,
|
|
193
|
-
sourcePublicBoxKey: source.publicBoxKey,
|
|
194
|
-
transcriptHash,
|
|
195
|
-
now: NOW,
|
|
196
|
-
})).toEqual({ version: 3, transcriptHash, expiresAt, ...credentials });
|
|
197
|
-
expect(() => (0, _1.openPairingCredentialEnvelope)(new device_1.Device(), envelope, {
|
|
198
|
-
sourcePublicKey: source.publicKey,
|
|
199
|
-
sourcePublicBoxKey: source.publicBoxKey,
|
|
200
|
-
transcriptHash,
|
|
201
|
-
now: NOW,
|
|
202
|
-
})).toThrow();
|
|
203
|
-
const initialized = new device_1.Device(credentials.userId);
|
|
204
|
-
const initializedInfo = (0, keys_1.openSignedObject)(initialized.getDeviceInfo());
|
|
205
|
-
const receipt = (0, _1.createSignedPairingInstallationReceipt)(destination, transcriptHash, initializedInfo, NOW);
|
|
206
|
-
expect((0, _1.verifySignedPairingInstallationReceipt)(receipt, {
|
|
207
|
-
temporaryDestinationPublicKey: destination.publicKey,
|
|
208
|
-
transcriptHash,
|
|
209
|
-
})).toEqual(initializedInfo);
|
|
210
|
-
});
|
|
211
|
-
});
|
package/dist/hlc.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|