cojson 0.9.23 → 0.10.0
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/.turbo/turbo-build.log +3 -3
- package/CHANGELOG.md +13 -0
- package/dist/native/coValueState.js +6 -4
- package/dist/native/coValueState.js.map +1 -1
- package/dist/native/coValues/group.js +22 -19
- package/dist/native/coValues/group.js.map +1 -1
- package/dist/native/crypto/WasmCrypto.js +1 -16
- package/dist/native/crypto/WasmCrypto.js.map +1 -1
- package/dist/native/exports.js +2 -0
- package/dist/native/exports.js.map +1 -1
- package/dist/native/permissions.js +10 -5
- package/dist/native/permissions.js.map +1 -1
- package/dist/web/coValueState.js +6 -4
- package/dist/web/coValueState.js.map +1 -1
- package/dist/web/coValues/group.js +22 -19
- package/dist/web/coValues/group.js.map +1 -1
- package/dist/web/crypto/WasmCrypto.js +1 -16
- package/dist/web/crypto/WasmCrypto.js.map +1 -1
- package/dist/web/exports.js +2 -0
- package/dist/web/exports.js.map +1 -1
- package/dist/web/permissions.js +10 -5
- package/dist/web/permissions.js.map +1 -1
- package/package.json +3 -4
- package/src/coValueState.ts +6 -4
- package/src/coValues/group.ts +38 -27
- package/src/crypto/WasmCrypto.ts +3 -17
- package/src/exports.ts +2 -0
- package/src/permissions.ts +15 -3
- package/src/tests/coValueState.test.ts +44 -22
- package/src/tests/group.test.ts +230 -27
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import { describe, expect, test, vi } from "vitest";
|
|
1
|
+
import { beforeEach, describe, expect, onTestFinished, test, vi } from "vitest";
|
|
2
2
|
import { PeerState } from "../PeerState";
|
|
3
3
|
import { CoValueCore } from "../coValueCore";
|
|
4
|
-
import {
|
|
4
|
+
import { CO_VALUE_LOADING_CONFIG, CoValueState } from "../coValueState";
|
|
5
5
|
import { RawCoID } from "../ids";
|
|
6
6
|
import { Peer } from "../sync";
|
|
7
7
|
|
|
8
|
+
const initialMaxRetries = CO_VALUE_LOADING_CONFIG.MAX_RETRIES;
|
|
9
|
+
|
|
10
|
+
function mockMaxRetries(maxRetries: number) {
|
|
11
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES = maxRetries;
|
|
12
|
+
|
|
13
|
+
onTestFinished(() => {
|
|
14
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES = initialMaxRetries;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
mockMaxRetries(5);
|
|
20
|
+
});
|
|
21
|
+
|
|
8
22
|
describe("CoValueState", () => {
|
|
9
23
|
const mockCoValueId = "co_test123" as RawCoID;
|
|
10
24
|
|
|
@@ -92,18 +106,18 @@ describe("CoValueState", () => {
|
|
|
92
106
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
93
107
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
94
108
|
|
|
95
|
-
// Should attempt
|
|
96
|
-
for (let i = 0; i <
|
|
109
|
+
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
110
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
97
111
|
await vi.runAllTimersAsync();
|
|
98
112
|
}
|
|
99
113
|
|
|
100
114
|
await loadPromise;
|
|
101
115
|
|
|
102
116
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
103
|
-
|
|
117
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
104
118
|
);
|
|
105
119
|
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
106
|
-
|
|
120
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
107
121
|
);
|
|
108
122
|
expect(state.state.type).toBe("unavailable");
|
|
109
123
|
await expect(state.getCoValue()).resolves.toBe("unavailable");
|
|
@@ -145,8 +159,8 @@ describe("CoValueState", () => {
|
|
|
145
159
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
146
160
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
147
161
|
|
|
148
|
-
// Should attempt
|
|
149
|
-
for (let i = 0; i <
|
|
162
|
+
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
163
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
150
164
|
await vi.runAllTimersAsync();
|
|
151
165
|
}
|
|
152
166
|
|
|
@@ -154,7 +168,7 @@ describe("CoValueState", () => {
|
|
|
154
168
|
|
|
155
169
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
156
170
|
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
157
|
-
|
|
171
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
158
172
|
);
|
|
159
173
|
expect(state.state.type).toBe("unavailable");
|
|
160
174
|
await expect(state.getCoValue()).resolves.toBe("unavailable");
|
|
@@ -194,8 +208,8 @@ describe("CoValueState", () => {
|
|
|
194
208
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
195
209
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
196
210
|
|
|
197
|
-
// Should attempt
|
|
198
|
-
for (let i = 0; i <
|
|
211
|
+
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
212
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
199
213
|
await vi.runAllTimersAsync();
|
|
200
214
|
}
|
|
201
215
|
|
|
@@ -203,7 +217,7 @@ describe("CoValueState", () => {
|
|
|
203
217
|
|
|
204
218
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
205
219
|
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
206
|
-
|
|
220
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
207
221
|
);
|
|
208
222
|
expect(state.state.type).toBe("unavailable");
|
|
209
223
|
await expect(state.getCoValue()).resolves.toEqual("unavailable");
|
|
@@ -214,6 +228,8 @@ describe("CoValueState", () => {
|
|
|
214
228
|
test("should handle the coValues that become available in between of the retries", async () => {
|
|
215
229
|
vi.useFakeTimers();
|
|
216
230
|
|
|
231
|
+
mockMaxRetries(5);
|
|
232
|
+
|
|
217
233
|
let retries = 0;
|
|
218
234
|
|
|
219
235
|
const peer1 = createMockPeerState(
|
|
@@ -244,8 +260,8 @@ describe("CoValueState", () => {
|
|
|
244
260
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
245
261
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
246
262
|
|
|
247
|
-
// Should attempt
|
|
248
|
-
for (let i = 0; i <
|
|
263
|
+
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
264
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES + 1; i++) {
|
|
249
265
|
await vi.runAllTimersAsync();
|
|
250
266
|
}
|
|
251
267
|
|
|
@@ -278,8 +294,8 @@ describe("CoValueState", () => {
|
|
|
278
294
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
279
295
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
280
296
|
|
|
281
|
-
// Should attempt
|
|
282
|
-
for (let i = 0; i <
|
|
297
|
+
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
298
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
283
299
|
await vi.runAllTimersAsync();
|
|
284
300
|
}
|
|
285
301
|
|
|
@@ -290,7 +306,9 @@ describe("CoValueState", () => {
|
|
|
290
306
|
|
|
291
307
|
await loadPromise;
|
|
292
308
|
|
|
293
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
309
|
+
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
310
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
311
|
+
);
|
|
294
312
|
expect(state.state.type).toBe("available");
|
|
295
313
|
await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
|
|
296
314
|
|
|
@@ -300,6 +318,8 @@ describe("CoValueState", () => {
|
|
|
300
318
|
test("should stop retrying when value becomes available", async () => {
|
|
301
319
|
vi.useFakeTimers();
|
|
302
320
|
|
|
321
|
+
mockMaxRetries(5);
|
|
322
|
+
|
|
303
323
|
let run = 1;
|
|
304
324
|
|
|
305
325
|
const peer1 = createMockPeerState(
|
|
@@ -327,7 +347,7 @@ describe("CoValueState", () => {
|
|
|
327
347
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
328
348
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
329
349
|
|
|
330
|
-
for (let i = 0; i <
|
|
350
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
331
351
|
await vi.runAllTimersAsync();
|
|
332
352
|
}
|
|
333
353
|
await loadPromise;
|
|
@@ -372,7 +392,7 @@ describe("CoValueState", () => {
|
|
|
372
392
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
373
393
|
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
374
394
|
|
|
375
|
-
for (let i = 0; i <
|
|
395
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
376
396
|
await vi.runAllTimersAsync();
|
|
377
397
|
}
|
|
378
398
|
await loadPromise;
|
|
@@ -421,7 +441,7 @@ describe("CoValueState", () => {
|
|
|
421
441
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
422
442
|
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
423
443
|
|
|
424
|
-
for (let i = 0; i <
|
|
444
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
425
445
|
await vi.runAllTimersAsync();
|
|
426
446
|
}
|
|
427
447
|
await loadPromise;
|
|
@@ -449,12 +469,14 @@ describe("CoValueState", () => {
|
|
|
449
469
|
const state = CoValueState.Unknown(mockCoValueId);
|
|
450
470
|
const loadPromise = state.loadFromPeers([peer1]);
|
|
451
471
|
|
|
452
|
-
for (let i = 0; i <
|
|
472
|
+
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES * 2; i++) {
|
|
453
473
|
await vi.runAllTimersAsync();
|
|
454
474
|
}
|
|
455
475
|
await loadPromise;
|
|
456
476
|
|
|
457
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
477
|
+
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
478
|
+
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
479
|
+
);
|
|
458
480
|
|
|
459
481
|
expect(state.state.type).toBe("unavailable");
|
|
460
482
|
await expect(state.getCoValue()).resolves.toEqual("unavailable");
|
package/src/tests/group.test.ts
CHANGED
|
@@ -467,33 +467,6 @@ describe("writeOnly", () => {
|
|
|
467
467
|
expect(mapOnNode3.get("test")).toEqual("Written from a writeOnly member");
|
|
468
468
|
});
|
|
469
469
|
|
|
470
|
-
test("inherited writer roles should work correctly", async () => {
|
|
471
|
-
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
472
|
-
|
|
473
|
-
const group = node1.node.createGroup();
|
|
474
|
-
group.addMember(
|
|
475
|
-
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
476
|
-
"writer",
|
|
477
|
-
);
|
|
478
|
-
|
|
479
|
-
const childGroup = node1.node.createGroup();
|
|
480
|
-
childGroup.extend(group);
|
|
481
|
-
childGroup.addMember(
|
|
482
|
-
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
483
|
-
"writeOnly",
|
|
484
|
-
);
|
|
485
|
-
|
|
486
|
-
const map = childGroup.createMap();
|
|
487
|
-
map.set("test", "Written from the admin");
|
|
488
|
-
|
|
489
|
-
await map.core.waitForSync();
|
|
490
|
-
|
|
491
|
-
const mapOnNode2 = await loadCoValueOrFail(node2.node, map.id);
|
|
492
|
-
|
|
493
|
-
// The writer role should be able to see the edits from the admin
|
|
494
|
-
expect(mapOnNode2.get("test")).toEqual("Written from the admin");
|
|
495
|
-
});
|
|
496
|
-
|
|
497
470
|
test("upgrade to writer roles should work correctly", async () => {
|
|
498
471
|
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
499
472
|
|
|
@@ -528,6 +501,35 @@ describe("writeOnly", () => {
|
|
|
528
501
|
// The writer role should be able to see the edits from the admin
|
|
529
502
|
expect(mapOnNode2.get("test")).toEqual("Written from the writeOnly member");
|
|
530
503
|
});
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
describe("extend", () => {
|
|
507
|
+
test("inherited writer roles should work correctly", async () => {
|
|
508
|
+
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
509
|
+
|
|
510
|
+
const group = node1.node.createGroup();
|
|
511
|
+
group.addMember(
|
|
512
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
513
|
+
"writer",
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
const childGroup = node1.node.createGroup();
|
|
517
|
+
childGroup.extend(group);
|
|
518
|
+
childGroup.addMember(
|
|
519
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
520
|
+
"writeOnly",
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
const map = childGroup.createMap();
|
|
524
|
+
map.set("test", "Written from the admin");
|
|
525
|
+
|
|
526
|
+
await map.core.waitForSync();
|
|
527
|
+
|
|
528
|
+
const mapOnNode2 = await loadCoValueOrFail(node2.node, map.id);
|
|
529
|
+
|
|
530
|
+
// The writer role should be able to see the edits from the admin
|
|
531
|
+
expect(mapOnNode2.get("test")).toEqual("Written from the admin");
|
|
532
|
+
});
|
|
531
533
|
|
|
532
534
|
test("a user should be able to extend a group when his role on the parent group is writer", async () => {
|
|
533
535
|
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
@@ -638,4 +640,205 @@ describe("writeOnly", () => {
|
|
|
638
640
|
|
|
639
641
|
expect(map.get("test")).toEqual("Hello!");
|
|
640
642
|
});
|
|
643
|
+
|
|
644
|
+
test("a writerInvite role should not be inherited", async () => {
|
|
645
|
+
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
646
|
+
|
|
647
|
+
const group = node1.node.createGroup();
|
|
648
|
+
group.addMember(
|
|
649
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
650
|
+
"writerInvite",
|
|
651
|
+
);
|
|
652
|
+
|
|
653
|
+
const childGroup = node1.node.createGroup();
|
|
654
|
+
childGroup.extend(group);
|
|
655
|
+
|
|
656
|
+
expect(childGroup.roleOf(node2.accountID)).toEqual(undefined);
|
|
657
|
+
});
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
describe("extend with role mapping", () => {
|
|
661
|
+
test("mapping to writer should add the ability to write", async () => {
|
|
662
|
+
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
663
|
+
|
|
664
|
+
const group = node1.node.createGroup();
|
|
665
|
+
group.addMember(
|
|
666
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
667
|
+
"reader",
|
|
668
|
+
);
|
|
669
|
+
|
|
670
|
+
const childGroup = node1.node.createGroup();
|
|
671
|
+
childGroup.extend(group, "writer");
|
|
672
|
+
|
|
673
|
+
expect(childGroup.roleOf(node2.accountID)).toEqual("writer");
|
|
674
|
+
|
|
675
|
+
const map = childGroup.createMap();
|
|
676
|
+
map.set("test", "Written from the admin");
|
|
677
|
+
|
|
678
|
+
await map.core.waitForSync();
|
|
679
|
+
|
|
680
|
+
const mapOnNode2 = await loadCoValueOrFail(node2.node, map.id);
|
|
681
|
+
|
|
682
|
+
expect(mapOnNode2.get("test")).toEqual("Written from the admin");
|
|
683
|
+
|
|
684
|
+
mapOnNode2.set("test", "Written from the inherited role");
|
|
685
|
+
expect(mapOnNode2.get("test")).toEqual("Written from the inherited role");
|
|
686
|
+
|
|
687
|
+
await mapOnNode2.core.waitForSync();
|
|
688
|
+
|
|
689
|
+
expect(map.get("test")).toEqual("Written from the inherited role");
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
test("mapping to reader should remove the ability to write", async () => {
|
|
693
|
+
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
694
|
+
|
|
695
|
+
const group = node1.node.createGroup();
|
|
696
|
+
group.addMember(
|
|
697
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
698
|
+
"writer",
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
const childGroup = node1.node.createGroup();
|
|
702
|
+
childGroup.extend(group, "reader");
|
|
703
|
+
|
|
704
|
+
expect(childGroup.roleOf(node2.accountID)).toEqual("reader");
|
|
705
|
+
|
|
706
|
+
const map = childGroup.createMap();
|
|
707
|
+
map.set("test", "Written from the admin");
|
|
708
|
+
|
|
709
|
+
await map.core.waitForSync();
|
|
710
|
+
|
|
711
|
+
const mapOnNode2 = await loadCoValueOrFail(node2.node, map.id);
|
|
712
|
+
|
|
713
|
+
expect(mapOnNode2.get("test")).toEqual("Written from the admin");
|
|
714
|
+
|
|
715
|
+
mapOnNode2.set("test", "Should not be visible");
|
|
716
|
+
|
|
717
|
+
await mapOnNode2.core.waitForSync();
|
|
718
|
+
|
|
719
|
+
expect(map.get("test")).toEqual("Written from the admin");
|
|
720
|
+
expect(mapOnNode2.get("test")).toEqual("Written from the admin");
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
test("mapping to admin should add the ability to add members", async () => {
|
|
724
|
+
const { node1, node2, node3 } = await createThreeConnectedNodes(
|
|
725
|
+
"server",
|
|
726
|
+
"server",
|
|
727
|
+
"server",
|
|
728
|
+
);
|
|
729
|
+
|
|
730
|
+
const group = node1.node.createGroup();
|
|
731
|
+
group.addMember(
|
|
732
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
733
|
+
"reader",
|
|
734
|
+
);
|
|
735
|
+
|
|
736
|
+
const childGroup = node1.node.createGroup();
|
|
737
|
+
childGroup.extend(group, "admin");
|
|
738
|
+
|
|
739
|
+
expect(childGroup.roleOf(node2.accountID)).toEqual("admin");
|
|
740
|
+
|
|
741
|
+
await childGroup.core.waitForSync();
|
|
742
|
+
|
|
743
|
+
const childGroupOnNode2 = await loadCoValueOrFail(
|
|
744
|
+
node2.node,
|
|
745
|
+
childGroup.id,
|
|
746
|
+
);
|
|
747
|
+
|
|
748
|
+
childGroupOnNode2.addMember(
|
|
749
|
+
await loadCoValueOrFail(node2.node, node3.accountID),
|
|
750
|
+
"reader",
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
expect(childGroupOnNode2.roleOf(node3.accountID)).toEqual("reader");
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
test("mapping to reader should remove the ability to add members", async () => {
|
|
757
|
+
const { node1, node2, node3 } = await createThreeConnectedNodes(
|
|
758
|
+
"server",
|
|
759
|
+
"server",
|
|
760
|
+
"server",
|
|
761
|
+
);
|
|
762
|
+
|
|
763
|
+
const group = node1.node.createGroup();
|
|
764
|
+
group.addMember(
|
|
765
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
766
|
+
"admin",
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
const childGroup = node1.node.createGroup();
|
|
770
|
+
childGroup.extend(group, "reader");
|
|
771
|
+
|
|
772
|
+
expect(childGroup.roleOf(node2.accountID)).toEqual("reader");
|
|
773
|
+
|
|
774
|
+
await childGroup.core.waitForSync();
|
|
775
|
+
|
|
776
|
+
const childGroupOnNode2 = await loadCoValueOrFail(
|
|
777
|
+
node2.node,
|
|
778
|
+
childGroup.id,
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
const accountToAdd = await loadCoValueOrFail(node2.node, node3.accountID);
|
|
782
|
+
|
|
783
|
+
expect(() => {
|
|
784
|
+
childGroupOnNode2.addMember(accountToAdd, "reader");
|
|
785
|
+
}).toThrow();
|
|
786
|
+
|
|
787
|
+
expect(childGroupOnNode2.roleOf(node3.accountID)).toEqual(undefined);
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
test("non-inheritable roles should not give access to the child group when role mapping is used", async () => {
|
|
791
|
+
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
792
|
+
|
|
793
|
+
const group = node1.node.createGroup();
|
|
794
|
+
group.addMember(
|
|
795
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
796
|
+
"writeOnly",
|
|
797
|
+
);
|
|
798
|
+
|
|
799
|
+
const childGroup = node1.node.createGroup();
|
|
800
|
+
childGroup.extend(group, "reader");
|
|
801
|
+
|
|
802
|
+
expect(childGroup.roleOf(node2.accountID)).toEqual(undefined);
|
|
803
|
+
|
|
804
|
+
const map = childGroup.createMap();
|
|
805
|
+
map.set("test", "Written from the admin");
|
|
806
|
+
|
|
807
|
+
await map.core.waitForSync();
|
|
808
|
+
|
|
809
|
+
const mapOnNode2 = await loadCoValueOrFail(node2.node, map.id);
|
|
810
|
+
|
|
811
|
+
expect(mapOnNode2.get("test")).toEqual(undefined);
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
test("invite roles should not give write access to the child group when role mapping is used", async () => {
|
|
815
|
+
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
816
|
+
|
|
817
|
+
const group = node1.node.createGroup();
|
|
818
|
+
group.addMember(
|
|
819
|
+
await loadCoValueOrFail(node1.node, node2.accountID),
|
|
820
|
+
"writerInvite",
|
|
821
|
+
);
|
|
822
|
+
|
|
823
|
+
const childGroup = node1.node.createGroup();
|
|
824
|
+
childGroup.extend(group, "writer");
|
|
825
|
+
|
|
826
|
+
expect(childGroup.roleOf(node2.accountID)).toEqual(undefined);
|
|
827
|
+
|
|
828
|
+
const map = childGroup.createMap();
|
|
829
|
+
map.set("test", "Written from the admin");
|
|
830
|
+
|
|
831
|
+
await map.core.waitForSync();
|
|
832
|
+
|
|
833
|
+
const mapOnNode2 = await loadCoValueOrFail(node2.node, map.id);
|
|
834
|
+
|
|
835
|
+
expect(mapOnNode2.get("test")).toEqual("Written from the admin"); // The invite roles have access to the readKey hence can read the values on inherited groups
|
|
836
|
+
|
|
837
|
+
mapOnNode2.set("test", "Should not be visible");
|
|
838
|
+
|
|
839
|
+
await mapOnNode2.core.waitForSync();
|
|
840
|
+
|
|
841
|
+
expect(map.get("test")).toEqual("Written from the admin");
|
|
842
|
+
expect(mapOnNode2.get("test")).toEqual("Written from the admin");
|
|
843
|
+
});
|
|
641
844
|
});
|