@peers-app/peers-sdk 0.27.3 → 0.27.4
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/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/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/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.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.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
package/dist/keys.test.js
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const SQLiteDB = require("better-sqlite3");
|
|
4
|
-
const nacl = require("tweetnacl");
|
|
5
|
-
const tweetnacl_util_1 = require("tweetnacl-util");
|
|
6
|
-
const zod_1 = require("zod");
|
|
7
|
-
const sql_data_source_1 = require("./data/orm/sql.data-source");
|
|
8
|
-
const types_1 = require("./data/orm/types");
|
|
9
|
-
const keys_1 = require("./keys");
|
|
10
|
-
const serial_json_1 = require("./serial-json");
|
|
11
|
-
const zod_types_1 = require("./types/zod-types");
|
|
12
|
-
const utils_1 = require("./utils");
|
|
13
|
-
describe("keys", () => {
|
|
14
|
-
it("should allow creating a new key pair", () => {
|
|
15
|
-
const keys = (0, keys_1.newKeys)();
|
|
16
|
-
expect(keys.publicKey).toBeTruthy();
|
|
17
|
-
expect(keys.secretKey).toBeTruthy();
|
|
18
|
-
expect(keys.publicBoxKey).toBeTruthy();
|
|
19
|
-
});
|
|
20
|
-
describe("message signing", () => {
|
|
21
|
-
it("should allow signing a message with a secret key and opening it with the corresponding public key", () => {
|
|
22
|
-
const keys = (0, keys_1.newKeys)();
|
|
23
|
-
const msg = "hello world";
|
|
24
|
-
const signed = (0, keys_1.signMessageWithSecretKey)(msg, keys.secretKey);
|
|
25
|
-
expect(signed).toBeTruthy();
|
|
26
|
-
expect(signed).not.toEqual(msg);
|
|
27
|
-
const opened = (0, keys_1.openMessageWithPublicKey)(signed, keys.publicKey);
|
|
28
|
-
expect(opened).toEqual(msg);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe("object signing", () => {
|
|
32
|
-
it("should allow signing an object with a secret key and opening it with the corresponding public key", () => {
|
|
33
|
-
const keys = (0, keys_1.newKeys)();
|
|
34
|
-
const obj = { hello: "world" };
|
|
35
|
-
const signed = (0, keys_1.signObjectWithSecretKey)(obj, keys.secretKey);
|
|
36
|
-
expect(signed).toBeTruthy();
|
|
37
|
-
expect(signed).not.toEqual(obj);
|
|
38
|
-
const opened = (0, keys_1.openSignedObject)(signed);
|
|
39
|
-
expect(opened).toEqual(obj);
|
|
40
|
-
});
|
|
41
|
-
it("should throw an error if the data changes after the signature", () => {
|
|
42
|
-
const keys = (0, keys_1.newKeys)();
|
|
43
|
-
const obj = { hello: "world" };
|
|
44
|
-
const signed = (0, keys_1.signObjectWithSecretKey)(obj, keys.secretKey);
|
|
45
|
-
expect(signed).toBeTruthy();
|
|
46
|
-
signed.contents = { hello: "world2" };
|
|
47
|
-
expect(signed).not.toEqual(obj);
|
|
48
|
-
expect(() => (0, keys_1.openSignedObject)(signed)).toThrow(/signature/i);
|
|
49
|
-
});
|
|
50
|
-
it("should handle null and undefined gracefully", () => {
|
|
51
|
-
const keys = (0, keys_1.newKeys)();
|
|
52
|
-
const obj = undefined;
|
|
53
|
-
const signed = (0, keys_1.signObjectWithSecretKey)(obj, keys.secretKey);
|
|
54
|
-
expect(signed).toBeTruthy();
|
|
55
|
-
expect(signed).not.toEqual(obj);
|
|
56
|
-
const opened = (0, keys_1.openSignedObject)(signed);
|
|
57
|
-
expect(opened).toEqual(obj);
|
|
58
|
-
});
|
|
59
|
-
it.each([
|
|
60
|
-
false,
|
|
61
|
-
true,
|
|
62
|
-
0,
|
|
63
|
-
1,
|
|
64
|
-
Math.PI,
|
|
65
|
-
"",
|
|
66
|
-
"s",
|
|
67
|
-
])(`should handle simple values: \`%s\``, (value) => {
|
|
68
|
-
const keys = (0, keys_1.newKeys)();
|
|
69
|
-
const signed = (0, keys_1.signObjectWithSecretKey)(value, keys.secretKey);
|
|
70
|
-
expect(signed).toBeTruthy();
|
|
71
|
-
expect(signed).not.toEqual(value);
|
|
72
|
-
const opened = (0, keys_1.openSignedObject)(signed);
|
|
73
|
-
expect(opened).toEqual(value);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
describe("message boxing", () => {
|
|
77
|
-
it("should allow boxing data with a public key so it can only be opened with the secret key", () => {
|
|
78
|
-
const from = (0, keys_1.newKeys)();
|
|
79
|
-
const to = (0, keys_1.newKeys)();
|
|
80
|
-
const msg = "hello world";
|
|
81
|
-
const boxed = (0, keys_1.boxDataWithKeys)(msg, to.publicBoxKey, from.secretKey);
|
|
82
|
-
expect(boxed).toBeTruthy();
|
|
83
|
-
const opened = (0, keys_1.openBoxWithSecretKey)(boxed, to.secretKey);
|
|
84
|
-
expect(opened).toEqual(msg);
|
|
85
|
-
});
|
|
86
|
-
it("should allow boxing objects", () => {
|
|
87
|
-
const from = (0, keys_1.newKeys)();
|
|
88
|
-
const to = (0, keys_1.newKeys)();
|
|
89
|
-
const msg = { hello: "world" };
|
|
90
|
-
const boxed = (0, keys_1.boxDataWithKeys)(msg, to.publicBoxKey, from.secretKey);
|
|
91
|
-
expect(boxed).toBeTruthy();
|
|
92
|
-
const opened = (0, keys_1.openBoxWithSecretKey)(boxed, to.secretKey);
|
|
93
|
-
expect(opened).toEqual(msg);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
describe("message encryption", () => {
|
|
97
|
-
it("should allow encrypting a message with a secret key so it can only be decrypted with that same secret key", () => {
|
|
98
|
-
const keys = (0, keys_1.newKeys)();
|
|
99
|
-
const msg = "hello world";
|
|
100
|
-
const boxed = (0, keys_1.encryptData)(msg, keys.secretKey);
|
|
101
|
-
expect(boxed).toBeTruthy();
|
|
102
|
-
const opened = (0, keys_1.decryptData)(boxed, keys.secretKey);
|
|
103
|
-
expect(opened).toEqual(msg);
|
|
104
|
-
});
|
|
105
|
-
it("should allow encrypting objects", () => {
|
|
106
|
-
const keys = (0, keys_1.newKeys)();
|
|
107
|
-
const msg = { hello: "world" };
|
|
108
|
-
const boxed = (0, keys_1.encryptData)(msg, keys.secretKey);
|
|
109
|
-
expect(boxed).toBeTruthy();
|
|
110
|
-
const opened = (0, keys_1.decryptData)(boxed, keys.secretKey);
|
|
111
|
-
expect(opened).toEqual(msg);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
describe("loading keys", () => {
|
|
115
|
-
it("should allow loading keys from a secret key", () => {
|
|
116
|
-
const keys = (0, keys_1.newKeys)();
|
|
117
|
-
const loadedKeys = (0, keys_1.hydrateKeys)(keys.secretKey);
|
|
118
|
-
expect(loadedKeys.secretKey).toEqual(keys.secretKey);
|
|
119
|
-
expect(loadedKeys.publicKey).toEqual(keys.publicKey);
|
|
120
|
-
expect(loadedKeys.publicBoxKey).toEqual(keys.publicBoxKey);
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
describe("hashBytes", () => {
|
|
124
|
-
it("should hash buffer data consistently", () => {
|
|
125
|
-
const data = Buffer.from("Hello, World!", "utf8");
|
|
126
|
-
const hash1 = (0, keys_1.hashBytes)(data);
|
|
127
|
-
const hash2 = (0, keys_1.hashBytes)(data);
|
|
128
|
-
expect(hash1).toBe(hash2);
|
|
129
|
-
expect(hash1).toBeTruthy();
|
|
130
|
-
});
|
|
131
|
-
it("should produce different hashes for different data", () => {
|
|
132
|
-
const data1 = Buffer.from("Hello, World!", "utf8");
|
|
133
|
-
const data2 = Buffer.from("Hello, World?", "utf8");
|
|
134
|
-
const hash1 = (0, keys_1.hashBytes)(data1);
|
|
135
|
-
const hash2 = (0, keys_1.hashBytes)(data2);
|
|
136
|
-
expect(hash1).not.toBe(hash2);
|
|
137
|
-
});
|
|
138
|
-
it("should work with binary data", () => {
|
|
139
|
-
// Create binary data with all byte values
|
|
140
|
-
const binaryData = Buffer.alloc(256);
|
|
141
|
-
for (let i = 0; i < 256; i++) {
|
|
142
|
-
binaryData[i] = i;
|
|
143
|
-
}
|
|
144
|
-
const hash = (0, keys_1.hashBytes)(binaryData);
|
|
145
|
-
expect(hash).toBeTruthy();
|
|
146
|
-
// Verify consistency
|
|
147
|
-
const hash2 = (0, keys_1.hashBytes)(binaryData);
|
|
148
|
-
expect(hash).toBe(hash2);
|
|
149
|
-
});
|
|
150
|
-
it("should be equivalent to hashValue for string data", () => {
|
|
151
|
-
const text = "Hello, World!";
|
|
152
|
-
const stringBuffer = Buffer.from(text, "utf8");
|
|
153
|
-
const bufferHash = (0, keys_1.hashBytes)(stringBuffer);
|
|
154
|
-
const stringHash = (0, keys_1.hashValue)(text);
|
|
155
|
-
expect(bufferHash).toBe(stringHash);
|
|
156
|
-
});
|
|
157
|
-
it("should handle empty buffer", () => {
|
|
158
|
-
const emptyBuffer = Buffer.alloc(0);
|
|
159
|
-
const hash = (0, keys_1.hashBytes)(emptyBuffer);
|
|
160
|
-
expect(hash).toBeTruthy();
|
|
161
|
-
});
|
|
162
|
-
it("should handle large buffers", () => {
|
|
163
|
-
// 1MB of data
|
|
164
|
-
const largeBuffer = Buffer.alloc(1024 * 1024, "A");
|
|
165
|
-
const hash = (0, keys_1.hashBytes)(largeBuffer);
|
|
166
|
-
expect(hash).toBeTruthy();
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
describe("object signature embedding", () => {
|
|
170
|
-
it("should add signature to object and verify it successfully", () => {
|
|
171
|
-
const keys = (0, keys_1.newKeys)();
|
|
172
|
-
const obj = { name: "test", value: 42 };
|
|
173
|
-
const signedObj = (0, keys_1.addSignatureToObject)(obj, keys.secretKey);
|
|
174
|
-
expect(signedObj).toHaveProperty("signature");
|
|
175
|
-
expect(signedObj.name).toBe("test");
|
|
176
|
-
expect(signedObj.value).toBe(42);
|
|
177
|
-
expect((0, keys_1.isObjectSignatureValid)(signedObj)).toBe(true);
|
|
178
|
-
});
|
|
179
|
-
it("should fail verification if object is modified after signing", () => {
|
|
180
|
-
const keys = (0, keys_1.newKeys)();
|
|
181
|
-
const obj = { name: "test", value: 42 };
|
|
182
|
-
const signedObj = (0, keys_1.addSignatureToObject)(obj, keys.secretKey);
|
|
183
|
-
signedObj.value = 999; // modify after signing
|
|
184
|
-
expect((0, keys_1.isObjectSignatureValid)(signedObj)).toBe(false);
|
|
185
|
-
});
|
|
186
|
-
it("should fail verification if signature is tampered with", () => {
|
|
187
|
-
const keys = (0, keys_1.newKeys)();
|
|
188
|
-
const obj = { name: "test", value: 42 };
|
|
189
|
-
const signedObj = (0, keys_1.addSignatureToObject)(obj, keys.secretKey);
|
|
190
|
-
signedObj.signature = `${signedObj.signature}tampered`;
|
|
191
|
-
expect((0, keys_1.isObjectSignatureValid)(signedObj)).toBe(false);
|
|
192
|
-
});
|
|
193
|
-
it("should extract public key from signature", () => {
|
|
194
|
-
const keys = (0, keys_1.newKeys)();
|
|
195
|
-
const obj = { name: "test", value: 42 };
|
|
196
|
-
const signedObj = (0, keys_1.addSignatureToObject)(obj, keys.secretKey);
|
|
197
|
-
const extractedPublicKey = (0, keys_1.getPublicKeyFromObjectSignature)(signedObj);
|
|
198
|
-
expect(extractedPublicKey).toBe(keys.publicKey);
|
|
199
|
-
});
|
|
200
|
-
it("should return undefined for malformed signature", () => {
|
|
201
|
-
const obj = { name: "test", value: 42, signature: "malformed" };
|
|
202
|
-
const extractedPublicKey = (0, keys_1.getPublicKeyFromObjectSignature)(obj);
|
|
203
|
-
expect(extractedPublicKey).toBeUndefined();
|
|
204
|
-
});
|
|
205
|
-
it("should handle objects with existing signature property", () => {
|
|
206
|
-
const keys = (0, keys_1.newKeys)();
|
|
207
|
-
const obj = { name: "test", value: 42, signature: "old-signature" };
|
|
208
|
-
const signedObj = (0, keys_1.addSignatureToObject)(obj, keys.secretKey);
|
|
209
|
-
expect(signedObj.signature).not.toBe("old-signature");
|
|
210
|
-
expect((0, keys_1.isObjectSignatureValid)(signedObj)).toBe(true);
|
|
211
|
-
});
|
|
212
|
-
it("should work with complex nested objects", () => {
|
|
213
|
-
const keys = (0, keys_1.newKeys)();
|
|
214
|
-
const obj = {
|
|
215
|
-
user: { name: "Alice", age: 30 },
|
|
216
|
-
settings: { theme: "dark", notifications: true },
|
|
217
|
-
data: [1, 2, 3, { nested: true }],
|
|
218
|
-
};
|
|
219
|
-
const signedObj = (0, keys_1.addSignatureToObject)(obj, keys.secretKey);
|
|
220
|
-
expect((0, keys_1.isObjectSignatureValid)(signedObj)).toBe(true);
|
|
221
|
-
expect(signedObj.user.name).toBe("Alice");
|
|
222
|
-
expect(signedObj.data[3].nested).toBe(true);
|
|
223
|
-
});
|
|
224
|
-
it("should handle empty objects", () => {
|
|
225
|
-
const keys = (0, keys_1.newKeys)();
|
|
226
|
-
const obj = {};
|
|
227
|
-
const signedObj = (0, keys_1.addSignatureToObject)(obj, keys.secretKey);
|
|
228
|
-
expect((0, keys_1.isObjectSignatureValid)(signedObj)).toBe(true);
|
|
229
|
-
expect((0, keys_1.getPublicKeyFromObjectSignature)(signedObj)).toBe(keys.publicKey);
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
describe("canonical signatures", () => {
|
|
233
|
-
it("canonicalJSONString sorts keys at every level and drops null/undefined keys", () => {
|
|
234
|
-
const a = { z: 1, a: { y: [3, { q: 1, p: 2 }], x: undefined, w: null }, m: undefined };
|
|
235
|
-
const b = { a: { y: [3, { p: 2, q: 1 }] }, z: 1 };
|
|
236
|
-
expect((0, keys_1.canonicalJSONString)(a)).toBe((0, keys_1.canonicalJSONString)(b));
|
|
237
|
-
expect((0, keys_1.canonicalJSONString)(a)).toBe('{"a":{"y":[3,{"p":2,"q":1}]},"z":1}');
|
|
238
|
-
});
|
|
239
|
-
it("canonicalJSONString keeps array elements and encodes extended types", () => {
|
|
240
|
-
const date = new Date("2026-01-02T03:04:05.000Z");
|
|
241
|
-
expect((0, keys_1.canonicalJSONString)([1, null, undefined])).toBe('[1,null,"__UNDEFINED"]');
|
|
242
|
-
expect((0, keys_1.canonicalJSONString)({ when: date })).toBe(`{"when":"__DATE ${date.toISOString()}"}`);
|
|
243
|
-
expect((0, keys_1.canonicalJSONString)({ b: Buffer.from("hi") })).toBe('{"b":"__BUFFER aGk="}');
|
|
244
|
-
});
|
|
245
|
-
it("verifies after the keys are reordered", () => {
|
|
246
|
-
const keys = (0, keys_1.newKeys)();
|
|
247
|
-
const signed = (0, keys_1.addSignatureToObject)({ userId: "u1", name: "Alice", publicKey: keys.publicKey }, keys.secretKey);
|
|
248
|
-
// Same fields, different insertion order (as a row read back from SQLite would be).
|
|
249
|
-
const reordered = {
|
|
250
|
-
publicKey: signed.publicKey,
|
|
251
|
-
signature: signed.signature,
|
|
252
|
-
name: signed.name,
|
|
253
|
-
userId: signed.userId,
|
|
254
|
-
};
|
|
255
|
-
expect(() => (0, keys_1.verifyObjectSignature)(reordered)).not.toThrow();
|
|
256
|
-
});
|
|
257
|
-
it("treats an absent, undefined, and null optional field identically", () => {
|
|
258
|
-
const keys = (0, keys_1.newKeys)();
|
|
259
|
-
const signed = (0, keys_1.addSignatureToObject)({ userId: "u1", name: "Alice" }, keys.secretKey);
|
|
260
|
-
expect((0, keys_1.isObjectSignatureValid)({ ...signed, avatar: undefined })).toBe(true);
|
|
261
|
-
expect((0, keys_1.isObjectSignatureValid)({ ...signed, avatar: null })).toBe(true);
|
|
262
|
-
// A real value change still fails.
|
|
263
|
-
expect((0, keys_1.isObjectSignatureValid)({ ...signed, avatar: "x" })).toBe(false);
|
|
264
|
-
});
|
|
265
|
-
it("still fails when a value changes, regardless of order", () => {
|
|
266
|
-
const keys = (0, keys_1.newKeys)();
|
|
267
|
-
const signed = (0, keys_1.addSignatureToObject)({ a: 1, b: 2 }, keys.secretKey);
|
|
268
|
-
expect((0, keys_1.isObjectSignatureValid)({ b: 3, a: 1, signature: signed.signature })).toBe(false);
|
|
269
|
-
});
|
|
270
|
-
it("accepts legacy insertion-order signatures written before canonicalization", () => {
|
|
271
|
-
const keys = (0, keys_1.newKeys)();
|
|
272
|
-
// Key order deliberately not sorted, so canonical and legacy bytes differ.
|
|
273
|
-
const contents = { userId: "u1", name: "Alice", publicKey: keys.publicKey, maybe: undefined };
|
|
274
|
-
const legacyBytes = (0, tweetnacl_util_1.decodeUTF8)((0, serial_json_1.toJSONString)(contents));
|
|
275
|
-
expect((0, serial_json_1.toJSONString)(contents)).not.toBe((0, keys_1.canonicalJSONString)(contents));
|
|
276
|
-
const legacySig = nacl.sign.detached(legacyBytes, (0, keys_1.decodeBase64)(keys.secretKey));
|
|
277
|
-
const signature = Buffer.from(legacySig).toString("base64url");
|
|
278
|
-
expect(() => (0, keys_1.openSignedObject)({ contents, signature, publicKey: keys.publicKey })).not.toThrow();
|
|
279
|
-
expect(() => (0, keys_1.verifyObjectSignature)({ ...contents, signature: `${keys.publicKey}:${signature}` })).not.toThrow();
|
|
280
|
-
// Tampering is still caught on the legacy path.
|
|
281
|
-
expect(() => (0, keys_1.openSignedObject)({
|
|
282
|
-
contents: { ...contents, name: "Mallory" },
|
|
283
|
-
signature,
|
|
284
|
-
publicKey: keys.publicKey,
|
|
285
|
-
})).toThrow(/signature/i);
|
|
286
|
-
});
|
|
287
|
-
it("survives a round trip through a SQLite table", async () => {
|
|
288
|
-
const db = new SQLiteDB(":memory:");
|
|
289
|
-
const harness = {
|
|
290
|
-
get: async (sql, params = []) => db.prepare(sql).get(params),
|
|
291
|
-
all: async (sql, params = []) => db.prepare(sql).all(params),
|
|
292
|
-
exec: async (sql, params = []) => ({
|
|
293
|
-
changes: db.prepare(sql).run(params).changes,
|
|
294
|
-
}),
|
|
295
|
-
close: async () => {
|
|
296
|
-
db.close();
|
|
297
|
-
},
|
|
298
|
-
};
|
|
299
|
-
const schema = zod_1.z.object({
|
|
300
|
-
userId: zod_types_1.zodPeerId,
|
|
301
|
-
name: zod_1.z.string(),
|
|
302
|
-
publicKey: zod_1.z.string(),
|
|
303
|
-
publicBoxKey: zod_1.z.string(),
|
|
304
|
-
avatar: zod_1.z.string().optional(),
|
|
305
|
-
signature: zod_1.z.string(),
|
|
306
|
-
});
|
|
307
|
-
const metaData = {
|
|
308
|
-
name: "test_signed_users",
|
|
309
|
-
description: "signed users",
|
|
310
|
-
primaryKeyName: "userId",
|
|
311
|
-
fields: (0, types_1.schemaToFields)(schema),
|
|
312
|
-
};
|
|
313
|
-
const table = new sql_data_source_1.SQLDataSource(harness, metaData);
|
|
314
|
-
try {
|
|
315
|
-
const keys = (0, keys_1.newKeys)();
|
|
316
|
-
// Signed with keys in an order that differs from the schema's column order and with an
|
|
317
|
-
// optional field omitted; SQLite will hand back column order and `avatar: undefined`.
|
|
318
|
-
const signed = (0, keys_1.addSignatureToObject)({
|
|
319
|
-
publicBoxKey: keys.publicBoxKey,
|
|
320
|
-
name: "Alice",
|
|
321
|
-
userId: (0, utils_1.newid)(),
|
|
322
|
-
publicKey: keys.publicKey,
|
|
323
|
-
}, keys.secretKey);
|
|
324
|
-
await table.save(signed);
|
|
325
|
-
const stored = await table.get(signed.userId);
|
|
326
|
-
if (!stored)
|
|
327
|
-
throw new Error("row was not stored");
|
|
328
|
-
expect(Object.keys(stored)).not.toEqual(Object.keys(signed));
|
|
329
|
-
expect(() => (0, keys_1.verifyObjectSignature)(stored)).not.toThrow();
|
|
330
|
-
}
|
|
331
|
-
finally {
|
|
332
|
-
await harness.close();
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const console_logger_1 = require("./console-logger");
|
|
4
|
-
// Mock the ConsoleLogs table
|
|
5
|
-
jest.mock("./console-logs.table", () => {
|
|
6
|
-
const mockTable = {
|
|
7
|
-
insert: jest.fn().mockResolvedValue(undefined),
|
|
8
|
-
dataChanged: {
|
|
9
|
-
subscribe: jest.fn(),
|
|
10
|
-
},
|
|
11
|
-
};
|
|
12
|
-
return {
|
|
13
|
-
ConsoleLogs: jest.fn().mockResolvedValue(mockTable),
|
|
14
|
-
__mockTable: mockTable, // Export for test access
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
// Get reference to mock table
|
|
18
|
-
const { __mockTable: mockTable } = require("./console-logs.table");
|
|
19
|
-
// Mock utils
|
|
20
|
-
jest.mock("../utils", () => ({
|
|
21
|
-
newid: () => "test-id-123",
|
|
22
|
-
getTimestamp: () => "2024-01-01T00:00:00.000Z",
|
|
23
|
-
sleep: jest.fn().mockResolvedValue(undefined),
|
|
24
|
-
}));
|
|
25
|
-
describe("console-logger", () => {
|
|
26
|
-
let originalConsole;
|
|
27
|
-
describe("extractCoreMessage", () => {
|
|
28
|
-
it("should extract core message from messages with [prefix] tags", () => {
|
|
29
|
-
expect((0, console_logger_1.extractCoreMessage)("[main] Error message")).toBe("Error message");
|
|
30
|
-
expect((0, console_logger_1.extractCoreMessage)("[renderer] [main] Error message")).toBe("Error message");
|
|
31
|
-
expect((0, console_logger_1.extractCoreMessage)("[process-1] [process-2] [process-3] Error message")).toBe("Error message");
|
|
32
|
-
});
|
|
33
|
-
it("should remove Error: prefix", () => {
|
|
34
|
-
expect((0, console_logger_1.extractCoreMessage)("Error: Something went wrong")).toBe("Something went wrong");
|
|
35
|
-
expect((0, console_logger_1.extractCoreMessage)("[main] Error: Something went wrong")).toBe("Something went wrong");
|
|
36
|
-
});
|
|
37
|
-
it("should remove timestamp patterns", () => {
|
|
38
|
-
expect((0, console_logger_1.extractCoreMessage)("2024-01-01T12:00:00.000Z Error message")).toBe("Error message");
|
|
39
|
-
expect((0, console_logger_1.extractCoreMessage)("2024-01-01 12:00:00 Error message")).toBe("Error message");
|
|
40
|
-
});
|
|
41
|
-
it("should handle combinations of prefixes", () => {
|
|
42
|
-
expect((0, console_logger_1.extractCoreMessage)("[renderer] 2024-01-01T12:00:00.000Z Error: Failed to write log")).toBe("Failed to write log");
|
|
43
|
-
expect((0, console_logger_1.extractCoreMessage)("[main] [renderer] Error: Failed to write log")).toBe("Failed to write log");
|
|
44
|
-
});
|
|
45
|
-
it("should return the same message if no prefixes found", () => {
|
|
46
|
-
expect((0, console_logger_1.extractCoreMessage)("Plain error message")).toBe("Plain error message");
|
|
47
|
-
});
|
|
48
|
-
it("should handle empty or whitespace messages", () => {
|
|
49
|
-
expect((0, console_logger_1.extractCoreMessage)("")).toBe("");
|
|
50
|
-
expect((0, console_logger_1.extractCoreMessage)(" ")).toBe("");
|
|
51
|
-
expect((0, console_logger_1.extractCoreMessage)("[main]")).toBe("");
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
beforeAll(() => {
|
|
55
|
-
// Save original console methods
|
|
56
|
-
originalConsole = {
|
|
57
|
-
debug: console.debug,
|
|
58
|
-
info: console.info,
|
|
59
|
-
log: console.log,
|
|
60
|
-
warn: console.warn,
|
|
61
|
-
error: console.error,
|
|
62
|
-
};
|
|
63
|
-
});
|
|
64
|
-
beforeEach(() => {
|
|
65
|
-
// Clear all mocks
|
|
66
|
-
jest.clearAllMocks();
|
|
67
|
-
// Restore console before each test
|
|
68
|
-
(0, console_logger_1.restoreConsole)();
|
|
69
|
-
// Reset mock table
|
|
70
|
-
mockTable.insert.mockClear();
|
|
71
|
-
});
|
|
72
|
-
afterAll(() => {
|
|
73
|
-
// Restore original console methods
|
|
74
|
-
console.debug = originalConsole.debug;
|
|
75
|
-
console.info = originalConsole.info;
|
|
76
|
-
console.log = originalConsole.log;
|
|
77
|
-
console.warn = originalConsole.warn;
|
|
78
|
-
console.error = originalConsole.error;
|
|
79
|
-
});
|
|
80
|
-
describe("Single-process infinite loop detection", () => {
|
|
81
|
-
it("should detect infinite loop when logging from within log handler", async () => {
|
|
82
|
-
// Setup mock to throw error that triggers another log
|
|
83
|
-
let callCount = 0;
|
|
84
|
-
mockTable.insert.mockImplementation(() => {
|
|
85
|
-
callCount++;
|
|
86
|
-
if (callCount < 10) {
|
|
87
|
-
// This would trigger another log attempt
|
|
88
|
-
throw new Error("Database error");
|
|
89
|
-
}
|
|
90
|
-
return Promise.resolve();
|
|
91
|
-
});
|
|
92
|
-
(0, console_logger_1.setupConsoleLogsProxy)("test-process");
|
|
93
|
-
// Wait for setup to complete
|
|
94
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
95
|
-
// This should trigger the loop
|
|
96
|
-
console.error("Initial error");
|
|
97
|
-
// Wait for async operations
|
|
98
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
99
|
-
// Should have called insert but stopped early due to recursion guard
|
|
100
|
-
expect(mockTable.insert).toHaveBeenCalled();
|
|
101
|
-
// The calls should be limited
|
|
102
|
-
expect(callCount).toBeLessThanOrEqual(5);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
describe("Cross-process infinite loop detection", () => {
|
|
106
|
-
it("should detect when same log is written too many times in window", async () => {
|
|
107
|
-
(0, console_logger_1.setupConsoleLogsProxy)("test-process");
|
|
108
|
-
// Wait for setup
|
|
109
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
110
|
-
mockTable.insert.mockClear();
|
|
111
|
-
// Log the same message many times quickly (simulating cross-process loop)
|
|
112
|
-
for (let i = 0; i < 15; i++) {
|
|
113
|
-
console.error("Same error message");
|
|
114
|
-
// Small delay to ensure they're processed
|
|
115
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
116
|
-
}
|
|
117
|
-
// Wait for async operations
|
|
118
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
119
|
-
// Should have stopped writing after threshold (10)
|
|
120
|
-
expect(mockTable.insert.mock.calls.length).toBeLessThan(15);
|
|
121
|
-
expect(mockTable.insert.mock.calls.length).toBeGreaterThan(0);
|
|
122
|
-
});
|
|
123
|
-
it("should NOT detect loop for different messages", async () => {
|
|
124
|
-
(0, console_logger_1.setupConsoleLogsProxy)("test-process");
|
|
125
|
-
// Wait for setup
|
|
126
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
127
|
-
// Clear setup log
|
|
128
|
-
mockTable.insert.mockClear();
|
|
129
|
-
// Log different messages
|
|
130
|
-
for (let i = 0; i < 15; i++) {
|
|
131
|
-
console.error(`Different error message ${i}`);
|
|
132
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
133
|
-
}
|
|
134
|
-
// Wait for async operations
|
|
135
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
136
|
-
// Should have written most/all messages (allow for timing variance)
|
|
137
|
-
expect(mockTable.insert.mock.calls.length).toBeGreaterThanOrEqual(14);
|
|
138
|
-
expect(mockTable.insert.mock.calls.length).toBeLessThanOrEqual(15);
|
|
139
|
-
});
|
|
140
|
-
it("should detect loop even with modified messages (prefix added)", async () => {
|
|
141
|
-
(0, console_logger_1.setupConsoleLogsProxy)("test-process");
|
|
142
|
-
// Wait for setup
|
|
143
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
144
|
-
mockTable.insert.mockClear();
|
|
145
|
-
// Simulate cross-process loop where each process adds a prefix
|
|
146
|
-
// This represents Process A logging "Error X"
|
|
147
|
-
// Process B seeing it and logging "[main] Error X"
|
|
148
|
-
// Process A seeing that and logging "[renderer] [main] Error X"
|
|
149
|
-
const baseMessage = "Failed to write log to database";
|
|
150
|
-
const messages = [
|
|
151
|
-
baseMessage,
|
|
152
|
-
`[main] ${baseMessage}`,
|
|
153
|
-
`[renderer] [main] ${baseMessage}`,
|
|
154
|
-
`[main] [renderer] [main] ${baseMessage}`,
|
|
155
|
-
`[renderer] [main] [renderer] [main] ${baseMessage}`,
|
|
156
|
-
];
|
|
157
|
-
// Log these messages in sequence, simulating the loop
|
|
158
|
-
// Need enough to trigger the threshold (MAX_IDENTICAL_LOGS_IN_WINDOW = 10)
|
|
159
|
-
for (let cycle = 0; cycle < 3; cycle++) {
|
|
160
|
-
for (const msg of messages) {
|
|
161
|
-
console.error(msg);
|
|
162
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
// Wait for async operations
|
|
166
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
167
|
-
// Should detect this as a loop even though messages have different prefixes
|
|
168
|
-
// because extractCoreMessage normalizes them all to the same core message
|
|
169
|
-
// We logged 15 messages (5 variants x 3 cycles), but they all have the same core
|
|
170
|
-
// So after 10, it should start blocking
|
|
171
|
-
const insertCount = mockTable.insert.mock.calls.length;
|
|
172
|
-
// Should be: 1 (setup) + 10 (threshold) = 11, might be a bit more due to timing
|
|
173
|
-
expect(insertCount).toBeGreaterThan(1); // At least setup + some logs
|
|
174
|
-
expect(insertCount).toBeLessThan(17); // Definitely less than all 15 + setup
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
describe("Loop detection recovery", () => {
|
|
178
|
-
it("should allow logging again after window expires", async () => {
|
|
179
|
-
(0, console_logger_1.setupConsoleLogsProxy)("test-process");
|
|
180
|
-
// Wait for setup
|
|
181
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
182
|
-
mockTable.insert.mockClear();
|
|
183
|
-
// Trigger loop detection
|
|
184
|
-
for (let i = 0; i < 12; i++) {
|
|
185
|
-
console.error("Same error");
|
|
186
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
187
|
-
}
|
|
188
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
189
|
-
const firstBatchCount = mockTable.insert.mock.calls.length;
|
|
190
|
-
// Wait for window to expire (5 seconds in real code, but we can't easily test that)
|
|
191
|
-
// Just verify the blocking is in place
|
|
192
|
-
console.error("Same error");
|
|
193
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
194
|
-
// Should still be blocked
|
|
195
|
-
expect(mockTable.insert.mock.calls.length).toBe(firstBatchCount);
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
describe("Normal logging behavior", () => {
|
|
199
|
-
it("should write logs to database for normal usage", async () => {
|
|
200
|
-
(0, console_logger_1.setupConsoleLogsProxy)("test-process");
|
|
201
|
-
// Wait for setup to complete
|
|
202
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
203
|
-
mockTable.insert.mockClear();
|
|
204
|
-
console.log("Test message");
|
|
205
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
206
|
-
console.error("Test error");
|
|
207
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
208
|
-
console.warn("Test warning");
|
|
209
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
210
|
-
// Verify at least the logs were attempted
|
|
211
|
-
expect(mockTable.insert).toHaveBeenCalled();
|
|
212
|
-
expect(mockTable.insert.mock.calls.length).toBeGreaterThanOrEqual(1);
|
|
213
|
-
expect(mockTable.insert.mock.calls.length).toBeLessThanOrEqual(3);
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
describe("Logger class", () => {
|
|
217
|
-
it("should create logger with specified source", async () => {
|
|
218
|
-
const logger = new console_logger_1.Logger("MyModule");
|
|
219
|
-
// Wait for Logger to initialize
|
|
220
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
221
|
-
mockTable.insert.mockClear();
|
|
222
|
-
logger.log("Test message");
|
|
223
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
224
|
-
expect(mockTable.insert).toHaveBeenCalled();
|
|
225
|
-
const call = mockTable.insert.mock.calls[0];
|
|
226
|
-
expect(call[0].source).toBe("MyModule");
|
|
227
|
-
expect(call[0].message).toBe("Test message");
|
|
228
|
-
});
|
|
229
|
-
it("should support all log levels", async () => {
|
|
230
|
-
const logger = new console_logger_1.Logger("TestModule");
|
|
231
|
-
// Wait for Logger to initialize
|
|
232
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
233
|
-
mockTable.insert.mockClear();
|
|
234
|
-
logger.debug("Debug message");
|
|
235
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
236
|
-
logger.info("Info message");
|
|
237
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
238
|
-
logger.log("Log message");
|
|
239
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
240
|
-
logger.warn("Warn message");
|
|
241
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
242
|
-
logger.error("Error message");
|
|
243
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
244
|
-
// Should have most/all logs
|
|
245
|
-
expect(mockTable.insert.mock.calls.length).toBeGreaterThanOrEqual(4);
|
|
246
|
-
// Check that different levels were used
|
|
247
|
-
const levels = mockTable.insert.mock.calls.map((call) => call[0].level);
|
|
248
|
-
const uniqueLevels = new Set(levels);
|
|
249
|
-
expect(uniqueLevels.size).toBeGreaterThanOrEqual(4);
|
|
250
|
-
});
|
|
251
|
-
it("should queue logs before initialization and flush after", async () => {
|
|
252
|
-
// Create a delayed promise for ConsoleLogs
|
|
253
|
-
let resolveConsoleLogs;
|
|
254
|
-
const delayedPromise = new Promise((resolve) => {
|
|
255
|
-
resolveConsoleLogs = resolve;
|
|
256
|
-
});
|
|
257
|
-
const { ConsoleLogs } = require("./console-logs.table");
|
|
258
|
-
ConsoleLogs.mockReturnValueOnce(delayedPromise);
|
|
259
|
-
const logger = new console_logger_1.Logger("EarlyModule");
|
|
260
|
-
// Log before initialization
|
|
261
|
-
logger.log("Early message 1");
|
|
262
|
-
logger.warn("Early message 2");
|
|
263
|
-
logger.error("Early message 3");
|
|
264
|
-
// Small delay to ensure logs are queued
|
|
265
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
266
|
-
// Should not have written yet
|
|
267
|
-
expect(mockTable.insert).not.toHaveBeenCalled();
|
|
268
|
-
// Now resolve the ConsoleLogs promise
|
|
269
|
-
resolveConsoleLogs(mockTable);
|
|
270
|
-
// Wait for flush
|
|
271
|
-
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
272
|
-
// Should have flushed pending logs
|
|
273
|
-
expect(mockTable.insert.mock.calls.length).toBeGreaterThanOrEqual(2);
|
|
274
|
-
});
|
|
275
|
-
it("should write logs directly after initialization", async () => {
|
|
276
|
-
const logger = new console_logger_1.Logger("LateModule");
|
|
277
|
-
// Wait for initialization
|
|
278
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
279
|
-
mockTable.insert.mockClear();
|
|
280
|
-
logger.log("Direct message");
|
|
281
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
282
|
-
expect(mockTable.insert).toHaveBeenCalledTimes(1);
|
|
283
|
-
expect(mockTable.insert.mock.calls[0][0].message).toBe("Direct message");
|
|
284
|
-
});
|
|
285
|
-
it("should use reliable source from constructor", async () => {
|
|
286
|
-
const logger1 = new console_logger_1.Logger("SourceA");
|
|
287
|
-
const logger2 = new console_logger_1.Logger("SourceB");
|
|
288
|
-
// Wait for initialization
|
|
289
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
290
|
-
mockTable.insert.mockClear();
|
|
291
|
-
logger1.log("From A");
|
|
292
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
293
|
-
logger2.log("From B");
|
|
294
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
295
|
-
expect(mockTable.insert).toHaveBeenCalledTimes(2);
|
|
296
|
-
expect(mockTable.insert.mock.calls[0][0].source).toBe("SourceA");
|
|
297
|
-
expect(mockTable.insert.mock.calls[1][0].source).toBe("SourceB");
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|