agent-comms 2.18.3 → 2.18.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/dist/bridges/user/web/dist/bundle.js +1 -1
- package/dist/bridges/user/web/frontend/project-tree.js +3 -3
- package/dist/bridges/user/web/frontend/project-tree.js.map +1 -1
- package/dist/bridges/user/web/test/port-discovery.unit.test.js +10 -11
- package/dist/bridges/user/web/test/port-discovery.unit.test.js.map +1 -1
- package/dist/bridges/user/web/test/web-server.integration.test.js +12 -13
- package/dist/bridges/user/web/test/web-server.integration.test.js.map +1 -1
- package/dist/core/test/bridge.unit.test.js +11 -12
- package/dist/core/test/bridge.unit.test.js.map +1 -1
- package/dist/core/test/identity.unit.test.js +21 -22
- package/dist/core/test/identity.unit.test.js.map +1 -1
- package/dist/test/approval.integration.test.js +52 -45
- package/dist/test/approval.integration.test.js.map +1 -1
- package/dist/test/become-coordinator-actual-port.integration.test.d.ts +0 -2
- package/dist/test/become-coordinator-actual-port.integration.test.d.ts.map +1 -1
- package/dist/test/become-coordinator-actual-port.integration.test.js +14 -39
- package/dist/test/become-coordinator-actual-port.integration.test.js.map +1 -1
- package/dist/test/bridge-mesh.test.js +9 -10
- package/dist/test/bridge-mesh.test.js.map +1 -1
- package/dist/test/broadcast-window.integration.test.js +4 -7
- package/dist/test/broadcast-window.integration.test.js.map +1 -1
- package/dist/test/coordinator-socket-error.integration.test.js +3 -4
- package/dist/test/coordinator-socket-error.integration.test.js.map +1 -1
- package/dist/test/create-room-mints-owner-grant.test.js +9 -8
- package/dist/test/create-room-mints-owner-grant.test.js.map +1 -1
- package/dist/test/create-room-name-sanitisation.test.js +6 -7
- package/dist/test/create-room-name-sanitisation.test.js.map +1 -1
- package/dist/test/dm-admission.integration.test.js +10 -11
- package/dist/test/dm-admission.integration.test.js.map +1 -1
- package/dist/test/federation.integration.test.js +21 -20
- package/dist/test/federation.integration.test.js.map +1 -1
- package/dist/test/filestore.test.js +16 -17
- package/dist/test/filestore.test.js.map +1 -1
- package/dist/test/handshake.test.js +26 -27
- package/dist/test/handshake.test.js.map +1 -1
- package/dist/test/identity-cert.test.js +3 -4
- package/dist/test/identity-cert.test.js.map +1 -1
- package/dist/test/identity-device-id.test.js +6 -7
- package/dist/test/identity-device-id.test.js.map +1 -1
- package/dist/test/identity-restart.integration.test.js +9 -10
- package/dist/test/identity-restart.integration.test.js.map +1 -1
- package/dist/test/identity-store.test.js +27 -24
- package/dist/test/identity-store.test.js.map +1 -1
- package/dist/test/listener-policy.integration.test.js +63 -56
- package/dist/test/listener-policy.integration.test.js.map +1 -1
- package/dist/test/mcp-registry-retry.test.js +10 -11
- package/dist/test/mcp-registry-retry.test.js.map +1 -1
- package/dist/test/mesh-e2e.integration.test.js +26 -19
- package/dist/test/mesh-e2e.integration.test.js.map +1 -1
- package/dist/test/presence-readvertise.integration.test.js +5 -6
- package/dist/test/presence-readvertise.integration.test.js.map +1 -1
- package/dist/test/random-id.test.js +3 -4
- package/dist/test/random-id.test.js.map +1 -1
- package/dist/test/room-admission-tool-actions.test.js +20 -15
- package/dist/test/room-admission-tool-actions.test.js.map +1 -1
- package/dist/test/room-destroy-revocation.integration.test.js +3 -4
- package/dist/test/room-destroy-revocation.integration.test.js.map +1 -1
- package/dist/test/room-invite-directed.integration.test.js +13 -12
- package/dist/test/room-invite-directed.integration.test.js.map +1 -1
- package/dist/test/room-join-admission.test.js +31 -24
- package/dist/test/room-join-admission.test.js.map +1 -1
- package/dist/test/room-kick-revocation.integration.test.js +5 -6
- package/dist/test/room-kick-revocation.integration.test.js.map +1 -1
- package/dist/test/room-leave-revocation.integration.test.js +10 -9
- package/dist/test/room-leave-revocation.integration.test.js.map +1 -1
- package/dist/test/room-path.test.js +16 -17
- package/dist/test/room-path.test.js.map +1 -1
- package/dist/test/room-read-directed.integration.test.js +14 -11
- package/dist/test/room-read-directed.integration.test.js.map +1 -1
- package/dist/test/room-router.test.js +27 -29
- package/dist/test/room-router.test.js.map +1 -1
- package/dist/test/room-send-directed.integration.test.js +11 -12
- package/dist/test/room-send-directed.integration.test.js.map +1 -1
- package/dist/test/room-send-retry-queue.test.js +10 -11
- package/dist/test/room-send-retry-queue.test.js.map +1 -1
- package/dist/test/room-send-retry.integration.test.js +5 -8
- package/dist/test/room-send-retry.integration.test.js.map +1 -1
- package/dist/test/room-state-sync.integration.test.js +18 -15
- package/dist/test/room-state-sync.integration.test.js.map +1 -1
- package/dist/test/room-token-store.test.js +21 -22
- package/dist/test/room-token-store.test.js.map +1 -1
- package/dist/test/room-token-verification.test.js +19 -20
- package/dist/test/room-token-verification.test.js.map +1 -1
- package/dist/test/state-sync-convergence.test.js +25 -26
- package/dist/test/state-sync-convergence.test.js.map +1 -1
- package/dist/test/visibility.integration.test.js +48 -49
- package/dist/test/visibility.integration.test.js.map +1 -1
- package/dist/test/wire-mesh-identity.test.js +7 -8
- package/dist/test/wire-mesh-identity.test.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-send-retry.integration.test.js","sourceRoot":"","sources":["../../src/test/room-send-retry.integration.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"room-send-retry.integration.test.js","sourceRoot":"","sources":["../../src/test/room-send-retry.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Integration test for room-state sync (P3.6): a joiner's own local Room record gets the room's real name/description/type from room.join's response, and a later room.members refresh picks up changes made after the join (here, simulated by mutating the owner's own room record directly, since no rename/re-describe verb exists yet).
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
5
|
-
import { test } from "node:test";
|
|
4
|
+
import { test, expect } from "vitest";
|
|
6
5
|
import { MeshStore } from "../core/mesh-store.js";
|
|
7
6
|
import { waitFor, wireTestTransport } from "./test-transport.js";
|
|
8
7
|
let nextPort = 21_010;
|
|
@@ -45,7 +44,7 @@ async function joinAndAccept(owner, member, roomId) {
|
|
|
45
44
|
owner.acceptRoomJoin(roomId, member.peerId);
|
|
46
45
|
await joinPromise;
|
|
47
46
|
}
|
|
48
|
-
|
|
47
|
+
test("a joiner's own local room record carries the room's real name, description, and type", async () => {
|
|
49
48
|
const { owner, member } = await makeConnectedPair(freshPort());
|
|
50
49
|
try {
|
|
51
50
|
const room = await owner.createRoom({
|
|
@@ -56,18 +55,20 @@ void test("a joiner's own local room record carries the room's real name, descri
|
|
|
56
55
|
});
|
|
57
56
|
await joinAndAccept(owner, member, room.id);
|
|
58
57
|
const memberCopy = await member.getRoom(room.id);
|
|
59
|
-
|
|
58
|
+
expect(memberCopy).toBeTruthy();
|
|
59
|
+
if (memberCopy === undefined)
|
|
60
|
+
throw new Error("expected member's own copy of the room");
|
|
60
61
|
// createRoom slugs the raw name before storing it (General-Chat, not General Chat) -- the point of this assertion is that member's own copy matches owner's own stored value exactly, not the pre-slug input.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
expect(memberCopy.name).toBe("General-Chat");
|
|
63
|
+
expect(memberCopy.description).toBe("the main room");
|
|
64
|
+
expect(memberCopy.type).toBe("private");
|
|
64
65
|
}
|
|
65
66
|
finally {
|
|
66
67
|
await member.shutdown();
|
|
67
68
|
await owner.shutdown();
|
|
68
69
|
}
|
|
69
70
|
});
|
|
70
|
-
|
|
71
|
+
test("refreshRoomMembers re-syncs a member's own local room record from the owner", async () => {
|
|
71
72
|
const { owner, member } = await makeConnectedPair(freshPort());
|
|
72
73
|
try {
|
|
73
74
|
const room = await owner.createRoom({
|
|
@@ -79,24 +80,26 @@ void test("refreshRoomMembers re-syncs a member's own local room record from the
|
|
|
79
80
|
await joinAndAccept(owner, member, room.id);
|
|
80
81
|
// A change on the owner's own side that room.join's own response never carries after the fact -- refreshRoomMembers is the only way member ever learns of it.
|
|
81
82
|
const ownerCopy = await owner.getRoom(room.id);
|
|
82
|
-
|
|
83
|
+
expect(ownerCopy).toBeTruthy();
|
|
84
|
+
if (ownerCopy === undefined)
|
|
85
|
+
throw new Error("expected owner's own copy of the room");
|
|
83
86
|
ownerCopy.description = "renamed after the join";
|
|
84
87
|
const refreshed = await member.refreshRoomMembers(room.id);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
expect(refreshed.description).toBe("renamed after the join");
|
|
89
|
+
expect(refreshed.members.includes(owner.peerId)).toBeTruthy();
|
|
90
|
+
expect(refreshed.members.includes(member.peerId)).toBeTruthy();
|
|
88
91
|
const memberCopy = await member.getRoom(room.id);
|
|
89
|
-
|
|
92
|
+
expect(memberCopy?.description).toBe("renamed after the join");
|
|
90
93
|
}
|
|
91
94
|
finally {
|
|
92
95
|
await member.shutdown();
|
|
93
96
|
await owner.shutdown();
|
|
94
97
|
}
|
|
95
98
|
});
|
|
96
|
-
|
|
99
|
+
test("refreshRoomMembers throws for a DM path -- no Room record exists to refresh", async () => {
|
|
97
100
|
const { owner, member } = await makeConnectedPair(freshPort());
|
|
98
101
|
try {
|
|
99
|
-
await
|
|
102
|
+
await expect(member.refreshRoomMembers(`${owner.peerId}+${member.peerId}`)).rejects.toThrow(/not found/i);
|
|
100
103
|
}
|
|
101
104
|
finally {
|
|
102
105
|
await member.shutdown();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-state-sync.integration.test.js","sourceRoot":"","sources":["../../src/test/room-state-sync.integration.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"room-state-sync.integration.test.js","sourceRoot":"","sources":["../../src/test/room-state-sync.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unit tests for per-room capability token persistence (core/identity-store).
|
|
3
3
|
*/
|
|
4
|
-
import * as assert from "node:assert/strict";
|
|
5
4
|
import * as fs from "node:fs";
|
|
6
5
|
import { tmpdir } from "node:os";
|
|
7
6
|
import path from "node:path";
|
|
8
|
-
import { test } from "
|
|
7
|
+
import { test, expect } from "vitest";
|
|
9
8
|
import { loadOrCreateIdentity, loadRoomTokens, saveRoomToken, deleteRoomToken, releaseIdentityLock, } from "../core/identity-store.js";
|
|
10
9
|
function tempSlot(harness) {
|
|
11
10
|
const dir = fs.mkdtempSync(path.join(tmpdir(), "agent-comms-room-token-test-"));
|
|
@@ -28,60 +27,60 @@ const TOKEN_B = [
|
|
|
28
27
|
];
|
|
29
28
|
const ROOM_A = "aa".repeat(32) + "/general";
|
|
30
29
|
const ROOM_B = "bb".repeat(32) + "/other-room";
|
|
31
|
-
|
|
30
|
+
test("loadRoomTokens returns an empty map before anything is saved", () => {
|
|
32
31
|
const { slot } = tempSlot("pi");
|
|
33
32
|
loadOrCreateIdentity(slot);
|
|
34
|
-
|
|
33
|
+
expect(loadRoomTokens(slot)).toEqual({});
|
|
35
34
|
releaseIdentityLock(slot);
|
|
36
35
|
});
|
|
37
|
-
|
|
36
|
+
test("saveRoomToken persists a token retrievable by loadRoomTokens", () => {
|
|
38
37
|
const { slot } = tempSlot("claude-code");
|
|
39
38
|
loadOrCreateIdentity(slot);
|
|
40
39
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
41
40
|
const tokens = loadRoomTokens(slot);
|
|
42
|
-
|
|
41
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_A);
|
|
43
42
|
releaseIdentityLock(slot);
|
|
44
43
|
});
|
|
45
|
-
|
|
44
|
+
test("saveRoomToken round-trips a token whose payload is null", () => {
|
|
46
45
|
const { slot } = tempSlot("codex");
|
|
47
46
|
loadOrCreateIdentity(slot);
|
|
48
47
|
saveRoomToken(slot, ROOM_B, TOKEN_B);
|
|
49
48
|
const tokens = loadRoomTokens(slot);
|
|
50
|
-
|
|
49
|
+
expect(tokens[ROOM_B]).toEqual(TOKEN_B);
|
|
51
50
|
releaseIdentityLock(slot);
|
|
52
51
|
});
|
|
53
|
-
|
|
52
|
+
test("saveRoomToken for a second room does not disturb the first", () => {
|
|
54
53
|
const { slot } = tempSlot("mcp");
|
|
55
54
|
loadOrCreateIdentity(slot);
|
|
56
55
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
57
56
|
saveRoomToken(slot, ROOM_B, TOKEN_B);
|
|
58
57
|
const tokens = loadRoomTokens(slot);
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_A);
|
|
59
|
+
expect(tokens[ROOM_B]).toEqual(TOKEN_B);
|
|
61
60
|
releaseIdentityLock(slot);
|
|
62
61
|
});
|
|
63
|
-
|
|
62
|
+
test("saveRoomToken overwrites an existing token for the same room", () => {
|
|
64
63
|
const { slot } = tempSlot("opencode");
|
|
65
64
|
loadOrCreateIdentity(slot);
|
|
66
65
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
67
66
|
saveRoomToken(slot, ROOM_A, TOKEN_B);
|
|
68
67
|
const tokens = loadRoomTokens(slot);
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_B);
|
|
69
|
+
expect(Object.keys(tokens).length).toBe(1);
|
|
71
70
|
releaseIdentityLock(slot);
|
|
72
71
|
});
|
|
73
|
-
|
|
72
|
+
test("deleteRoomToken removes only the named room's token", () => {
|
|
74
73
|
const { slot } = tempSlot("user");
|
|
75
74
|
loadOrCreateIdentity(slot);
|
|
76
75
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
77
76
|
saveRoomToken(slot, ROOM_B, TOKEN_B);
|
|
78
77
|
deleteRoomToken(slot, ROOM_A);
|
|
79
78
|
const tokens = loadRoomTokens(slot);
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
expect(ROOM_A in tokens).toBe(false);
|
|
80
|
+
expect(tokens[ROOM_B]).toEqual(TOKEN_B);
|
|
82
81
|
releaseIdentityLock(slot);
|
|
83
82
|
});
|
|
84
|
-
|
|
83
|
+
test("room tokens survive reloading the identity file across a fresh load", () => {
|
|
85
84
|
const { slot } = tempSlot("pi");
|
|
86
85
|
loadOrCreateIdentity(slot);
|
|
87
86
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
@@ -89,16 +88,16 @@ void test("room tokens survive reloading the identity file across a fresh load",
|
|
|
89
88
|
// A fresh process re-loading the same slot.
|
|
90
89
|
loadOrCreateIdentity(slot);
|
|
91
90
|
const tokens = loadRoomTokens(slot);
|
|
92
|
-
|
|
91
|
+
expect(tokens[ROOM_A]).toEqual(TOKEN_A);
|
|
93
92
|
releaseIdentityLock(slot);
|
|
94
93
|
});
|
|
95
|
-
|
|
94
|
+
test("saving a room token does not disturb the persisted key material", () => {
|
|
96
95
|
const { slot } = tempSlot("claude-code");
|
|
97
96
|
const identity = loadOrCreateIdentity(slot);
|
|
98
97
|
saveRoomToken(slot, ROOM_A, TOKEN_A);
|
|
99
98
|
const reloaded = loadOrCreateIdentity(slot);
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
expect(reloaded.privateKey).toBe(identity.privateKey);
|
|
100
|
+
expect(reloaded.certificate).toBe(identity.certificate);
|
|
102
101
|
releaseIdentityLock(slot);
|
|
103
102
|
});
|
|
104
103
|
//# sourceMappingURL=room-token-store.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-token-store.test.js","sourceRoot":"","sources":["../../src/test/room-token-store.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"room-token-store.test.js","sourceRoot":"","sources":["../../src/test/room-token-store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { webcrypto } from "node:crypto";
|
|
2
|
-
import { describe, it } from "
|
|
3
|
-
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
4
3
|
import { createNodeIdentity } from "wire-mesh-core/adapters/node-identity";
|
|
5
4
|
import { deviceIdToHex } from "wire-mesh-core/domain/device-id";
|
|
6
5
|
import { mintCapabilityToken, mintRevocationEntry, } from "wire-mesh-core/domain/tokens";
|
|
@@ -55,7 +54,7 @@ describe("verifyRoomToken", () => {
|
|
|
55
54
|
expectedBearer: member.deviceId,
|
|
56
55
|
roomPath,
|
|
57
56
|
});
|
|
58
|
-
|
|
57
|
+
expect(verdict.ok).toBe(true);
|
|
59
58
|
});
|
|
60
59
|
it("refuses a token rooted at the wrong device for a named room", async () => {
|
|
61
60
|
const owner = await generateEs256Identity();
|
|
@@ -71,9 +70,9 @@ describe("verifyRoomToken", () => {
|
|
|
71
70
|
expectedBearer: member.deviceId,
|
|
72
71
|
roomPath,
|
|
73
72
|
});
|
|
74
|
-
|
|
73
|
+
expect(verdict.ok).toBe(false);
|
|
75
74
|
if (!verdict.ok)
|
|
76
|
-
|
|
75
|
+
expect(verdict.reason).toBe("wrong_chain_root");
|
|
77
76
|
});
|
|
78
77
|
it("accepts a DM token rooted at the verifying identity itself", async () => {
|
|
79
78
|
const me = await generateEs256Identity();
|
|
@@ -88,7 +87,7 @@ describe("verifyRoomToken", () => {
|
|
|
88
87
|
expectedBearer: them.deviceId,
|
|
89
88
|
roomPath,
|
|
90
89
|
});
|
|
91
|
-
|
|
90
|
+
expect(verdict.ok).toBe(true);
|
|
92
91
|
});
|
|
93
92
|
it("refuses a DM token rooted at neither participant nor the verifier", async () => {
|
|
94
93
|
const me = await generateEs256Identity();
|
|
@@ -104,9 +103,9 @@ describe("verifyRoomToken", () => {
|
|
|
104
103
|
expectedBearer: them.deviceId,
|
|
105
104
|
roomPath,
|
|
106
105
|
});
|
|
107
|
-
|
|
106
|
+
expect(verdict.ok).toBe(false);
|
|
108
107
|
if (!verdict.ok)
|
|
109
|
-
|
|
108
|
+
expect(verdict.reason).toBe("wrong_chain_root");
|
|
110
109
|
});
|
|
111
110
|
it("refuses a token scoped to a different room path", async () => {
|
|
112
111
|
const owner = await generateEs256Identity();
|
|
@@ -121,9 +120,9 @@ describe("verifyRoomToken", () => {
|
|
|
121
120
|
expectedBearer: member.deviceId,
|
|
122
121
|
roomPath: otherRoomPath,
|
|
123
122
|
});
|
|
124
|
-
|
|
123
|
+
expect(verdict.ok).toBe(false);
|
|
125
124
|
if (!verdict.ok)
|
|
126
|
-
|
|
125
|
+
expect(verdict.reason).toBe("wrong_scope_path");
|
|
127
126
|
});
|
|
128
127
|
it("refuses a token with an unrelated capability and an unrelated scope kind", async () => {
|
|
129
128
|
const owner = await generateEs256Identity();
|
|
@@ -147,9 +146,9 @@ describe("verifyRoomToken", () => {
|
|
|
147
146
|
expectedBearer: member.deviceId,
|
|
148
147
|
roomPath,
|
|
149
148
|
});
|
|
150
|
-
|
|
149
|
+
expect(verdict.ok).toBe(false);
|
|
151
150
|
if (!verdict.ok)
|
|
152
|
-
|
|
151
|
+
expect(verdict.reason).toBe("wrong_capability");
|
|
153
152
|
});
|
|
154
153
|
it("refuses a token with the wrong capability even when its scope is correctly shaped for the room", async () => {
|
|
155
154
|
const owner = await generateEs256Identity();
|
|
@@ -174,9 +173,9 @@ describe("verifyRoomToken", () => {
|
|
|
174
173
|
expectedBearer: member.deviceId,
|
|
175
174
|
roomPath,
|
|
176
175
|
});
|
|
177
|
-
|
|
176
|
+
expect(verdict.ok).toBe(false);
|
|
178
177
|
if (!verdict.ok)
|
|
179
|
-
|
|
178
|
+
expect(verdict.reason).toBe("wrong_capability");
|
|
180
179
|
});
|
|
181
180
|
it("refuses a token bearing a different device than the authenticated connection", async () => {
|
|
182
181
|
const owner = await generateEs256Identity();
|
|
@@ -191,9 +190,9 @@ describe("verifyRoomToken", () => {
|
|
|
191
190
|
expectedBearer: impostor.deviceId,
|
|
192
191
|
roomPath,
|
|
193
192
|
});
|
|
194
|
-
|
|
193
|
+
expect(verdict.ok).toBe(false);
|
|
195
194
|
if (!verdict.ok)
|
|
196
|
-
|
|
195
|
+
expect(verdict.reason).toBe("bearer_mismatch");
|
|
197
196
|
});
|
|
198
197
|
it("refuses an expired token", async () => {
|
|
199
198
|
const owner = await generateEs256Identity();
|
|
@@ -207,9 +206,9 @@ describe("verifyRoomToken", () => {
|
|
|
207
206
|
expectedBearer: member.deviceId,
|
|
208
207
|
roomPath,
|
|
209
208
|
});
|
|
210
|
-
|
|
209
|
+
expect(verdict.ok).toBe(false);
|
|
211
210
|
if (!verdict.ok)
|
|
212
|
-
|
|
211
|
+
expect(verdict.reason).toBe("expired");
|
|
213
212
|
});
|
|
214
213
|
it("refuses a revoked token", async () => {
|
|
215
214
|
const owner = await generateEs256Identity();
|
|
@@ -231,9 +230,9 @@ describe("verifyRoomToken", () => {
|
|
|
231
230
|
expectedBearer: member.deviceId,
|
|
232
231
|
roomPath,
|
|
233
232
|
});
|
|
234
|
-
|
|
233
|
+
expect(verdict.ok).toBe(false);
|
|
235
234
|
if (!verdict.ok)
|
|
236
|
-
|
|
235
|
+
expect(verdict.reason).toBe("revoked");
|
|
237
236
|
});
|
|
238
237
|
});
|
|
239
238
|
//# sourceMappingURL=room-token-verification.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room-token-verification.test.js","sourceRoot":"","sources":["../../src/test/room-token-verification.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"room-token-verification.test.js","sourceRoot":"","sources":["../../src/test/room-token-verification.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Also covers the append-only history merge: unseen messages are added and read receipts are unioned. These tests exercise the merge seam directly (no transport): the stores never connect, snapshots are exchanged through serialise() / applyStateSync().
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
7
|
-
import { test } from "node:test";
|
|
6
|
+
import { test, expect } from "vitest";
|
|
8
7
|
import { deviceIdFromHex } from "wire-mesh-core/domain/device-id";
|
|
9
8
|
import { createSystemClock } from "wire-mesh-core/adapters/system-clock";
|
|
10
9
|
import { mintCapabilityToken } from "wire-mesh-core/domain/tokens";
|
|
@@ -22,7 +21,7 @@ async function makeStore() {
|
|
|
22
21
|
function snapshotOf(store) {
|
|
23
22
|
return structuredClone(store.serialise());
|
|
24
23
|
}
|
|
25
|
-
|
|
24
|
+
test("a stale holder converges when a fresher snapshot arrives", async () => {
|
|
26
25
|
const a = await makeStore();
|
|
27
26
|
const b = await makeStore();
|
|
28
27
|
const agent = await a.registerAgent({
|
|
@@ -35,13 +34,13 @@ void test("a stale holder converges when a fresher snapshot arrives", async () =
|
|
|
35
34
|
});
|
|
36
35
|
// B holds the pre-rename copy.
|
|
37
36
|
b.applyStateSync(snapshotOf(a));
|
|
38
|
-
|
|
37
|
+
expect((await b.getAgent(agent.id))?.name).toBe("old-name");
|
|
39
38
|
// A renames while B is away; B heals on A's next snapshot.
|
|
40
39
|
await a.updateAgent(agent.id, { name: "new-name" });
|
|
41
40
|
b.applyStateSync(snapshotOf(a));
|
|
42
|
-
|
|
41
|
+
expect((await b.getAgent(agent.id))?.name).toBe("new-name");
|
|
43
42
|
});
|
|
44
|
-
|
|
43
|
+
test("a current holder rejects a stale snapshot instead of regressing", async () => {
|
|
45
44
|
const a = await makeStore();
|
|
46
45
|
const b = await makeStore();
|
|
47
46
|
const agent = await a.registerAgent({
|
|
@@ -55,7 +54,7 @@ void test("a current holder rejects a stale snapshot instead of regressing", asy
|
|
|
55
54
|
// B is current at the post-rename revision.
|
|
56
55
|
await a.updateAgent(agent.id, { name: "new-name" });
|
|
57
56
|
b.applyStateSync(snapshotOf(a));
|
|
58
|
-
|
|
57
|
+
expect((await b.getAgent(agent.id))?.name).toBe("new-name");
|
|
59
58
|
// A returning peer that still holds the pre-rename snapshot cannot regress B, where the old add-only merge kept whatever arrived first.
|
|
60
59
|
const stale = snapshotOf(a);
|
|
61
60
|
const staleAgent = stale.agents[agent.id];
|
|
@@ -64,9 +63,9 @@ void test("a current holder rejects a stale snapshot instead of regressing", asy
|
|
|
64
63
|
staleAgent.name = "old-name";
|
|
65
64
|
staleAgent.version -= 1;
|
|
66
65
|
b.applyStateSync(stale);
|
|
67
|
-
|
|
66
|
+
expect((await b.getAgent(agent.id))?.name).toBe("new-name");
|
|
68
67
|
});
|
|
69
|
-
|
|
68
|
+
test("room membership changes converge and stale member lists are rejected", async () => {
|
|
70
69
|
const a = await makeStore();
|
|
71
70
|
const b = new MeshStore();
|
|
72
71
|
const bSlot = await wireTestTransport(b);
|
|
@@ -96,7 +95,7 @@ void test("room membership changes converge and stale member lists are rejected"
|
|
|
96
95
|
// A holds the room before the join; the joiner lives on B, so the join mutates B's copy and syncs back (one MeshStore is one peer identity, so a second agent cannot be registered on A).
|
|
97
96
|
a.applyStateSync(snapshotOf(b));
|
|
98
97
|
b.applyStateSync(snapshotOf(a));
|
|
99
|
-
|
|
98
|
+
expect((await a.getRoom(roomId))?.members.includes(joiner.id)).toBe(false);
|
|
100
99
|
// joiner.id is B's own peerId (registerAgent's own id is always this.peerId), so this is a real self-join as far as joinRoom's own admission gate is concerned -- give B a token for the room first so the gate sees an already-admitted member and exercises the CRDT membership-merge logic this test actually targets, not a real (and here, transport-free, therefore impossible) wire-level join.
|
|
101
100
|
const bClock = createSystemClock();
|
|
102
101
|
const bIdentity = await toIdentityPort(loadOrCreateIdentity(bSlot));
|
|
@@ -110,16 +109,16 @@ void test("room membership changes converge and stale member lists are rejected"
|
|
|
110
109
|
expires: bClock.now() + 60_000,
|
|
111
110
|
delegationsRemaining: 0,
|
|
112
111
|
});
|
|
113
|
-
|
|
112
|
+
expect(grantVerdict.ok, "expected the fixture grant to mint successfully").toBeTruthy();
|
|
114
113
|
if (grantVerdict.ok)
|
|
115
114
|
saveRoomToken(bSlot, roomId, grantVerdict.token);
|
|
116
115
|
await b.joinRoom(roomId, joiner.id);
|
|
117
116
|
a.applyStateSync(snapshotOf(b));
|
|
118
|
-
|
|
117
|
+
expect((await a.getRoom(roomId))?.members.includes(joiner.id)).toBe(true);
|
|
119
118
|
// The joiner leaves. Unlike the join step above, there is no token-presence gate to skip here: any genuine member always already holds one, so leaveRoom's own self-leave gate (P3.8) always routes joiner.id === b.peerId through a real, and here impossible, wire round trip to the room's owner. Run the leave on A (the room's real owner) instead -- joiner.id !== a.peerId there, so it takes the same pure local CRDT branch the "kicker" test below already exercises -- and let B converge to A's own now-current state, exactly mirroring the join step's own direction reversed.
|
|
120
119
|
await a.leaveRoom(roomId, joiner.id);
|
|
121
120
|
b.applyStateSync(snapshotOf(a));
|
|
122
|
-
|
|
121
|
+
expect((await a.getRoom(roomId))?.members.includes(joiner.id)).toBe(false);
|
|
123
122
|
// A stale member list that still contains them is rejected.
|
|
124
123
|
const stale = snapshotOf(b);
|
|
125
124
|
const staleRoom = stale.rooms[roomId];
|
|
@@ -128,9 +127,9 @@ void test("room membership changes converge and stale member lists are rejected"
|
|
|
128
127
|
staleRoom.members.push(joiner.id);
|
|
129
128
|
staleRoom.version -= 1;
|
|
130
129
|
a.applyStateSync(stale);
|
|
131
|
-
|
|
130
|
+
expect((await a.getRoom(roomId))?.members.includes(joiner.id)).toBe(false);
|
|
132
131
|
});
|
|
133
|
-
|
|
132
|
+
test("history sync adds unseen messages and unions read receipts", async () => {
|
|
134
133
|
const a = await makeStore();
|
|
135
134
|
const b = await makeStore();
|
|
136
135
|
const agent = await a.registerAgent({
|
|
@@ -159,10 +158,10 @@ void test("history sync adds unseen messages and unions read receipts", async ()
|
|
|
159
158
|
history[0].readBy.push("reader-elsewhere");
|
|
160
159
|
b.applyStateSync(fresh);
|
|
161
160
|
const merged = await b.readRoomMessages(roomId);
|
|
162
|
-
|
|
163
|
-
|
|
161
|
+
expect(merged.map((m) => m.content)).toEqual(["one", "two"]);
|
|
162
|
+
expect(merged[0]?.readBy.includes("reader-elsewhere")).toBe(true);
|
|
164
163
|
});
|
|
165
|
-
|
|
164
|
+
test("a kick racing a concurrent join converges with the kick honoured", async () => {
|
|
166
165
|
// Two holders of the same room base: one records X leaving (a kick), the
|
|
167
166
|
// other records X joining, both at the same revision because they mutated
|
|
168
167
|
// concurrently from the same base. Both directions of the sync must
|
|
@@ -200,15 +199,15 @@ void test("a kick racing a concurrent join converges with the kick honoured", as
|
|
|
200
199
|
// Concurrent mutations from the same base: a kick on one holder, a re-join of X recorded on the other.
|
|
201
200
|
await kicker.leaveRoom(roomId, x.id);
|
|
202
201
|
await joiner.joinRoom(roomId, x.id);
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
expect((await kicker.getRoom(roomId))?.members.includes(x.id)).toBe(false);
|
|
203
|
+
expect((await joiner.getRoom(roomId))?.members.includes(x.id)).toBe(true);
|
|
205
204
|
// Exchange both ways: both converge on the kick.
|
|
206
205
|
kicker.applyStateSync(snapshotOf(joiner));
|
|
207
206
|
joiner.applyStateSync(snapshotOf(kicker));
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
expect((await kicker.getRoom(roomId))?.members.includes(x.id)).toBe(false);
|
|
208
|
+
expect((await joiner.getRoom(roomId))?.members.includes(x.id)).toBe(false);
|
|
210
209
|
});
|
|
211
|
-
|
|
210
|
+
test("concurrent joins of different agents both survive the merge", async () => {
|
|
212
211
|
// The property the old version-tie union existed to protect: two peers
|
|
213
212
|
// each record a different agent joining from the same base, and the
|
|
214
213
|
// merged room holds both.
|
|
@@ -256,8 +255,8 @@ void test("concurrent joins of different agents both survive the merge", async (
|
|
|
256
255
|
holderB.applyStateSync(snapshotOf(holderA));
|
|
257
256
|
const mergedA = await holderA.getRoom(roomId);
|
|
258
257
|
const mergedB = await holderB.getRoom(roomId);
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
258
|
+
expect(mergedA?.members.includes(p.id)).toBe(true);
|
|
259
|
+
expect(mergedA?.members.includes(q.id)).toBe(true);
|
|
260
|
+
expect(mergedB?.members).toEqual(mergedA?.members);
|
|
262
261
|
});
|
|
263
262
|
//# sourceMappingURL=state-sync-convergence.test.js.map
|