cojson 0.0.23 → 0.1.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/README.md +1 -1
- package/dist/account.d.ts +4 -4
- package/dist/account.js +7 -7
- package/dist/account.js.map +1 -1
- package/dist/coValue.d.ts +2 -2
- package/dist/coValue.js +23 -23
- package/dist/coValue.js.map +1 -1
- package/dist/{team.d.ts → group.d.ts} +7 -7
- package/dist/{team.js → group.js} +24 -24
- package/dist/group.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +3 -3
- package/dist/node.js +33 -30
- package/dist/node.js.map +1 -1
- package/dist/permissions.d.ts +3 -3
- package/dist/permissions.js +13 -13
- package/dist/permissions.js.map +1 -1
- package/dist/testUtils.d.ts +8 -8
- package/dist/testUtils.js +19 -19
- package/dist/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/account.test.ts +7 -7
- package/src/account.ts +8 -8
- package/src/coValue.test.ts +5 -5
- package/src/coValue.ts +24 -24
- package/src/{team.ts → group.ts} +31 -31
- package/src/index.ts +4 -4
- package/src/node.ts +40 -36
- package/src/permissions.test.ts +303 -303
- package/src/permissions.ts +16 -16
- package/src/sync.test.ts +74 -74
- package/src/testUtils.ts +19 -19
- package/dist/team.js.map +0 -1
package/src/coValue.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
determineValidTransactions,
|
|
28
28
|
isKeyForKeyField,
|
|
29
29
|
} from "./permissions.js";
|
|
30
|
-
import {
|
|
30
|
+
import { Group, expectGroupContent } from "./group.js";
|
|
31
31
|
import { LocalNode } from "./node.js";
|
|
32
32
|
import { CoValueKnownState, NewContentMessage } from "./sync.js";
|
|
33
33
|
import { RawCoID, SessionID, TransactionID } from "./ids.js";
|
|
@@ -106,10 +106,10 @@ export class CoValue {
|
|
|
106
106
|
this._sessions = internalInitSessions;
|
|
107
107
|
this.node = node;
|
|
108
108
|
|
|
109
|
-
if (header.ruleset.type == "
|
|
109
|
+
if (header.ruleset.type == "ownedByGroup") {
|
|
110
110
|
this.node
|
|
111
|
-
.expectCoValueLoaded(header.ruleset.
|
|
112
|
-
.subscribe((
|
|
111
|
+
.expectCoValueLoaded(header.ruleset.group)
|
|
112
|
+
.subscribe((_groupUpdate) => {
|
|
113
113
|
this._cachedContent = undefined;
|
|
114
114
|
const newContent = this.getCurrentContent();
|
|
115
115
|
for (const listener of this.listeners) {
|
|
@@ -385,8 +385,8 @@ export class CoValue {
|
|
|
385
385
|
}
|
|
386
386
|
|
|
387
387
|
getCurrentReadKey(): { secret: KeySecret | undefined; id: KeyID } {
|
|
388
|
-
if (this.header.ruleset.type === "
|
|
389
|
-
const content =
|
|
388
|
+
if (this.header.ruleset.type === "group") {
|
|
389
|
+
const content = expectGroupContent(this.getCurrentContent());
|
|
390
390
|
|
|
391
391
|
const currentKeyId = content.get("readKey");
|
|
392
392
|
|
|
@@ -400,20 +400,20 @@ export class CoValue {
|
|
|
400
400
|
secret: secret,
|
|
401
401
|
id: currentKeyId,
|
|
402
402
|
};
|
|
403
|
-
} else if (this.header.ruleset.type === "
|
|
403
|
+
} else if (this.header.ruleset.type === "ownedByGroup") {
|
|
404
404
|
return this.node
|
|
405
|
-
.expectCoValueLoaded(this.header.ruleset.
|
|
405
|
+
.expectCoValueLoaded(this.header.ruleset.group)
|
|
406
406
|
.getCurrentReadKey();
|
|
407
407
|
} else {
|
|
408
408
|
throw new Error(
|
|
409
|
-
"Only
|
|
409
|
+
"Only groups or values owned by groups have read secrets"
|
|
410
410
|
);
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
|
|
414
414
|
getReadKey(keyID: KeyID): KeySecret | undefined {
|
|
415
|
-
if (this.header.ruleset.type === "
|
|
416
|
-
const content =
|
|
415
|
+
if (this.header.ruleset.type === "group") {
|
|
416
|
+
const content = expectGroupContent(this.getCurrentContent());
|
|
417
417
|
|
|
418
418
|
// Try to find key revelation for us
|
|
419
419
|
|
|
@@ -477,26 +477,26 @@ export class CoValue {
|
|
|
477
477
|
}
|
|
478
478
|
|
|
479
479
|
return undefined;
|
|
480
|
-
} else if (this.header.ruleset.type === "
|
|
480
|
+
} else if (this.header.ruleset.type === "ownedByGroup") {
|
|
481
481
|
return this.node
|
|
482
|
-
.expectCoValueLoaded(this.header.ruleset.
|
|
482
|
+
.expectCoValueLoaded(this.header.ruleset.group)
|
|
483
483
|
.getReadKey(keyID);
|
|
484
484
|
} else {
|
|
485
485
|
throw new Error(
|
|
486
|
-
"Only
|
|
486
|
+
"Only groups or values owned by groups have read secrets"
|
|
487
487
|
);
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
490
|
|
|
491
|
-
|
|
492
|
-
if (this.header.ruleset.type !== "
|
|
493
|
-
throw new Error("Only values owned by
|
|
491
|
+
getGroup(): Group {
|
|
492
|
+
if (this.header.ruleset.type !== "ownedByGroup") {
|
|
493
|
+
throw new Error("Only values owned by groups have groups");
|
|
494
494
|
}
|
|
495
495
|
|
|
496
|
-
return new
|
|
497
|
-
|
|
496
|
+
return new Group(
|
|
497
|
+
expectGroupContent(
|
|
498
498
|
this.node
|
|
499
|
-
.expectCoValueLoaded(this.header.ruleset.
|
|
499
|
+
.expectCoValueLoaded(this.header.ruleset.group)
|
|
500
500
|
.getCurrentContent()
|
|
501
501
|
),
|
|
502
502
|
this.node
|
|
@@ -553,12 +553,12 @@ export class CoValue {
|
|
|
553
553
|
}
|
|
554
554
|
|
|
555
555
|
getDependedOnCoValues(): RawCoID[] {
|
|
556
|
-
return this.header.ruleset.type === "
|
|
557
|
-
?
|
|
556
|
+
return this.header.ruleset.type === "group"
|
|
557
|
+
? expectGroupContent(this.getCurrentContent())
|
|
558
558
|
.keys()
|
|
559
559
|
.filter((k): k is AccountID => k.startsWith("co_"))
|
|
560
|
-
: this.header.ruleset.type === "
|
|
561
|
-
? [this.header.ruleset.
|
|
560
|
+
: this.header.ruleset.type === "ownedByGroup"
|
|
561
|
+
? [this.header.ruleset.group]
|
|
562
562
|
: [];
|
|
563
563
|
}
|
|
564
564
|
}
|
package/src/{team.ts → group.ts}
RENAMED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import { Role } from "./permissions.js";
|
|
26
26
|
import { base58 } from "@scure/base";
|
|
27
27
|
|
|
28
|
-
export type
|
|
28
|
+
export type GroupContent = {
|
|
29
29
|
profile: CoID<Profile> | null;
|
|
30
30
|
[key: AccountIDOrAgentID]: Role;
|
|
31
31
|
readKey: KeyID;
|
|
@@ -36,34 +36,34 @@ export type TeamContent = {
|
|
|
36
36
|
>;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export function
|
|
39
|
+
export function expectGroupContent(
|
|
40
40
|
content: ContentType
|
|
41
|
-
): CoMap<
|
|
41
|
+
): CoMap<GroupContent, JsonObject | null> {
|
|
42
42
|
if (content.type !== "comap") {
|
|
43
43
|
throw new Error("Expected map");
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
return content as CoMap<
|
|
46
|
+
return content as CoMap<GroupContent, JsonObject | null>;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export class
|
|
50
|
-
|
|
49
|
+
export class Group {
|
|
50
|
+
groupMap: CoMap<GroupContent, JsonObject | null>;
|
|
51
51
|
node: LocalNode;
|
|
52
52
|
|
|
53
53
|
constructor(
|
|
54
|
-
|
|
54
|
+
groupMap: CoMap<GroupContent, JsonObject | null>,
|
|
55
55
|
node: LocalNode
|
|
56
56
|
) {
|
|
57
|
-
this.
|
|
57
|
+
this.groupMap = groupMap;
|
|
58
58
|
this.node = node;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
get id(): CoID<CoMap<
|
|
62
|
-
return this.
|
|
61
|
+
get id(): CoID<CoMap<GroupContent, JsonObject | null>> {
|
|
62
|
+
return this.groupMap.id;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
roleOf(accountID: AccountIDOrAgentID): Role | undefined {
|
|
66
|
-
return this.
|
|
66
|
+
return this.groupMap.get(accountID);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
myRole(): Role | undefined {
|
|
@@ -71,8 +71,8 @@ export class Team {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
addMember(accountID: AccountIDOrAgentID, role: Role) {
|
|
74
|
-
this.
|
|
75
|
-
const currentReadKey = this.
|
|
74
|
+
this.groupMap = this.groupMap.edit((map) => {
|
|
75
|
+
const currentReadKey = this.groupMap.coValue.getCurrentReadKey();
|
|
76
76
|
|
|
77
77
|
if (!currentReadKey.secret) {
|
|
78
78
|
throw new Error("Can't add member without read key secret");
|
|
@@ -80,7 +80,7 @@ export class Team {
|
|
|
80
80
|
|
|
81
81
|
const agent = this.node.resolveAccountAgent(
|
|
82
82
|
accountID,
|
|
83
|
-
"Expected to know agent to add them to
|
|
83
|
+
"Expected to know agent to add them to group"
|
|
84
84
|
);
|
|
85
85
|
|
|
86
86
|
map.set(accountID, role, "trusting");
|
|
@@ -93,11 +93,11 @@ export class Team {
|
|
|
93
93
|
`${currentReadKey.id}_for_${accountID}`,
|
|
94
94
|
seal(
|
|
95
95
|
currentReadKey.secret,
|
|
96
|
-
this.
|
|
96
|
+
this.groupMap.coValue.node.account.currentSealerSecret(),
|
|
97
97
|
getAgentSealerID(agent),
|
|
98
98
|
{
|
|
99
|
-
in: this.
|
|
100
|
-
tx: this.
|
|
99
|
+
in: this.groupMap.coValue.id,
|
|
100
|
+
tx: this.groupMap.coValue.nextTransactionID(),
|
|
101
101
|
}
|
|
102
102
|
),
|
|
103
103
|
"trusting"
|
|
@@ -117,9 +117,9 @@ export class Team {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
rotateReadKey() {
|
|
120
|
-
const currentlyPermittedReaders = this.
|
|
120
|
+
const currentlyPermittedReaders = this.groupMap.keys().filter((key) => {
|
|
121
121
|
if (key.startsWith("co_") || isAgentID(key)) {
|
|
122
|
-
const role = this.
|
|
122
|
+
const role = this.groupMap.get(key);
|
|
123
123
|
return (
|
|
124
124
|
role === "admin" || role === "writer" || role === "reader"
|
|
125
125
|
);
|
|
@@ -128,7 +128,7 @@ export class Team {
|
|
|
128
128
|
}
|
|
129
129
|
}) as AccountIDOrAgentID[];
|
|
130
130
|
|
|
131
|
-
const maybeCurrentReadKey = this.
|
|
131
|
+
const maybeCurrentReadKey = this.groupMap.coValue.getCurrentReadKey();
|
|
132
132
|
|
|
133
133
|
if (!maybeCurrentReadKey.secret) {
|
|
134
134
|
throw new Error(
|
|
@@ -143,7 +143,7 @@ export class Team {
|
|
|
143
143
|
|
|
144
144
|
const newReadKey = newRandomKeySecret();
|
|
145
145
|
|
|
146
|
-
this.
|
|
146
|
+
this.groupMap = this.groupMap.edit((map) => {
|
|
147
147
|
for (const readerID of currentlyPermittedReaders) {
|
|
148
148
|
const reader = this.node.resolveAccountAgent(
|
|
149
149
|
readerID,
|
|
@@ -154,11 +154,11 @@ export class Team {
|
|
|
154
154
|
`${newReadKey.id}_for_${readerID}`,
|
|
155
155
|
seal(
|
|
156
156
|
newReadKey.secret,
|
|
157
|
-
this.
|
|
157
|
+
this.groupMap.coValue.node.account.currentSealerSecret(),
|
|
158
158
|
getAgentSealerID(reader),
|
|
159
159
|
{
|
|
160
|
-
in: this.
|
|
161
|
-
tx: this.
|
|
160
|
+
in: this.groupMap.coValue.id,
|
|
161
|
+
tx: this.groupMap.coValue.nextTransactionID(),
|
|
162
162
|
}
|
|
163
163
|
),
|
|
164
164
|
"trusting"
|
|
@@ -179,7 +179,7 @@ export class Team {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
removeMember(accountID: AccountIDOrAgentID) {
|
|
182
|
-
this.
|
|
182
|
+
this.groupMap = this.groupMap.edit((map) => {
|
|
183
183
|
map.set(accountID, "revoked", "trusting");
|
|
184
184
|
});
|
|
185
185
|
|
|
@@ -194,8 +194,8 @@ export class Team {
|
|
|
194
194
|
.createCoValue({
|
|
195
195
|
type: "comap",
|
|
196
196
|
ruleset: {
|
|
197
|
-
type: "
|
|
198
|
-
|
|
197
|
+
type: "ownedByGroup",
|
|
198
|
+
group: this.groupMap.id,
|
|
199
199
|
},
|
|
200
200
|
meta: meta || null,
|
|
201
201
|
...createdNowUnique(),
|
|
@@ -206,10 +206,10 @@ export class Team {
|
|
|
206
206
|
testWithDifferentAccount(
|
|
207
207
|
account: GeneralizedControlledAccount,
|
|
208
208
|
sessionId: SessionID
|
|
209
|
-
):
|
|
210
|
-
return new
|
|
211
|
-
|
|
212
|
-
this.
|
|
209
|
+
): Group {
|
|
210
|
+
return new Group(
|
|
211
|
+
expectGroupContent(
|
|
212
|
+
this.groupMap.coValue
|
|
213
213
|
.testWithDifferentAccount(account, sessionId)
|
|
214
214
|
.getCurrentContent()
|
|
215
215
|
),
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { connectedPeers } from "./streamUtils.js";
|
|
15
15
|
import { AnonymousControlledAccount, ControlledAccount } from "./account.js";
|
|
16
16
|
import { rawCoIDtoBytes, rawCoIDfromBytes } from "./ids.js";
|
|
17
|
-
import {
|
|
17
|
+
import { Group, expectGroupContent } from "./group.js"
|
|
18
18
|
|
|
19
19
|
import type { SessionID, AgentID } from "./ids.js";
|
|
20
20
|
import type { CoID, ContentType } from "./contentType.js";
|
|
@@ -27,7 +27,7 @@ import type {
|
|
|
27
27
|
ProfileContent,
|
|
28
28
|
Profile,
|
|
29
29
|
} from "./account.js";
|
|
30
|
-
import type { InviteSecret } from "./
|
|
30
|
+
import type { InviteSecret } from "./group.js";
|
|
31
31
|
|
|
32
32
|
type Value = JsonValue | ContentType;
|
|
33
33
|
|
|
@@ -44,7 +44,7 @@ export const cojsonInternals = {
|
|
|
44
44
|
agentSecretFromSecretSeed,
|
|
45
45
|
secretSeedLength,
|
|
46
46
|
shortHashLength,
|
|
47
|
-
|
|
47
|
+
expectGroupContent
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
export {
|
|
@@ -53,7 +53,7 @@ export {
|
|
|
53
53
|
CoMap,
|
|
54
54
|
AnonymousControlledAccount,
|
|
55
55
|
ControlledAccount,
|
|
56
|
-
|
|
56
|
+
Group
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
export type {
|
package/src/node.ts
CHANGED
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
import { CoValue, CoValueHeader, newRandomSessionID } from "./coValue.js";
|
|
13
13
|
import {
|
|
14
14
|
InviteSecret,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
Group,
|
|
16
|
+
GroupContent,
|
|
17
|
+
expectGroupContent,
|
|
18
18
|
secretSeedFromInviteSecret,
|
|
19
|
-
} from "./
|
|
19
|
+
} from "./group.js";
|
|
20
20
|
import { Peer, SyncManager } from "./sync.js";
|
|
21
21
|
import { AgentID, RawCoID, SessionID, isAgentID } from "./ids.js";
|
|
22
22
|
import { CoID, ContentType } from "./contentType.js";
|
|
@@ -151,23 +151,23 @@ export class LocalNode {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
async acceptInvite<T extends ContentType>(
|
|
154
|
-
|
|
154
|
+
groupOrOwnedValueID: CoID<T>,
|
|
155
155
|
inviteSecret: InviteSecret
|
|
156
156
|
): Promise<void> {
|
|
157
|
-
const
|
|
157
|
+
const groupOrOwnedValue = await this.load(groupOrOwnedValueID);
|
|
158
158
|
|
|
159
|
-
if (
|
|
159
|
+
if (groupOrOwnedValue.coValue.header.ruleset.type === "ownedByGroup") {
|
|
160
160
|
return this.acceptInvite(
|
|
161
|
-
|
|
162
|
-
CoMap<
|
|
161
|
+
groupOrOwnedValue.coValue.header.ruleset.group as CoID<
|
|
162
|
+
CoMap<GroupContent>
|
|
163
163
|
>,
|
|
164
164
|
inviteSecret
|
|
165
165
|
);
|
|
166
|
-
} else if (
|
|
167
|
-
throw new Error("Can only accept invites to
|
|
166
|
+
} else if (groupOrOwnedValue.coValue.header.ruleset.type !== "group") {
|
|
167
|
+
throw new Error("Can only accept invites to groups");
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
const
|
|
170
|
+
const group = new Group(expectGroupContent(groupOrOwnedValue), this);
|
|
171
171
|
|
|
172
172
|
const inviteAgentSecret = agentSecretFromSecretSeed(
|
|
173
173
|
secretSeedFromInviteSecret(inviteSecret)
|
|
@@ -175,8 +175,8 @@ export class LocalNode {
|
|
|
175
175
|
const inviteAgentID = getAgentID(inviteAgentSecret);
|
|
176
176
|
|
|
177
177
|
const invitationRole = await new Promise((resolve, reject) => {
|
|
178
|
-
|
|
179
|
-
const role =
|
|
178
|
+
group.groupMap.subscribe((groupMap) => {
|
|
179
|
+
const role = groupMap.get(inviteAgentID);
|
|
180
180
|
if (role) {
|
|
181
181
|
resolve(role);
|
|
182
182
|
}
|
|
@@ -194,7 +194,7 @@ export class LocalNode {
|
|
|
194
194
|
throw new Error("No invitation found");
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
const existingRole =
|
|
197
|
+
const existingRole = group.groupMap.get(this.account.id);
|
|
198
198
|
|
|
199
199
|
if (
|
|
200
200
|
existingRole === "admin" ||
|
|
@@ -204,12 +204,12 @@ export class LocalNode {
|
|
|
204
204
|
return;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
const
|
|
207
|
+
const groupAsInvite = group.testWithDifferentAccount(
|
|
208
208
|
new AnonymousControlledAccount(inviteAgentSecret),
|
|
209
209
|
newRandomSessionID(inviteAgentID)
|
|
210
210
|
);
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
groupAsInvite.addMember(
|
|
213
213
|
this.account.id,
|
|
214
214
|
invitationRole === "adminInvite"
|
|
215
215
|
? "admin"
|
|
@@ -218,8 +218,12 @@ export class LocalNode {
|
|
|
218
218
|
: "reader"
|
|
219
219
|
);
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
group.groupMap.coValue._sessions = groupAsInvite.groupMap.coValue.sessions;
|
|
222
|
+
group.groupMap.coValue._cachedContent = undefined;
|
|
223
|
+
|
|
224
|
+
for (const groupListener of group.groupMap.coValue.listeners) {
|
|
225
|
+
groupListener(group.groupMap.coValue.getCurrentContent());
|
|
226
|
+
}
|
|
223
227
|
}
|
|
224
228
|
|
|
225
229
|
expectCoValueLoaded(id: RawCoID, expectation?: string): CoValue {
|
|
@@ -241,7 +245,7 @@ export class LocalNode {
|
|
|
241
245
|
|
|
242
246
|
expectProfileLoaded(id: AccountID, expectation?: string): Profile {
|
|
243
247
|
const account = this.expectCoValueLoaded(id, expectation);
|
|
244
|
-
const profileID =
|
|
248
|
+
const profileID = expectGroupContent(account.getCurrentContent()).get(
|
|
245
249
|
"profile"
|
|
246
250
|
);
|
|
247
251
|
if (!profileID) {
|
|
@@ -268,12 +272,12 @@ export class LocalNode {
|
|
|
268
272
|
newRandomSessionID(getAgentID(agentSecret))
|
|
269
273
|
);
|
|
270
274
|
|
|
271
|
-
const
|
|
272
|
-
|
|
275
|
+
const accountAsGroup = new Group(
|
|
276
|
+
expectGroupContent(account.getCurrentContent()),
|
|
273
277
|
account.node
|
|
274
278
|
);
|
|
275
279
|
|
|
276
|
-
|
|
280
|
+
accountAsGroup.groupMap.edit((editable) => {
|
|
277
281
|
editable.set(getAgentID(agentSecret), "admin", "trusting");
|
|
278
282
|
|
|
279
283
|
const readKey = newRandomKeySecret();
|
|
@@ -301,7 +305,7 @@ export class LocalNode {
|
|
|
301
305
|
account.node
|
|
302
306
|
);
|
|
303
307
|
|
|
304
|
-
const profile =
|
|
308
|
+
const profile = accountAsGroup.createMap<ProfileContent, ProfileMeta>({
|
|
305
309
|
type: "profile",
|
|
306
310
|
});
|
|
307
311
|
|
|
@@ -309,13 +313,13 @@ export class LocalNode {
|
|
|
309
313
|
editable.set("name", name, "trusting");
|
|
310
314
|
});
|
|
311
315
|
|
|
312
|
-
|
|
316
|
+
accountAsGroup.groupMap.edit((editable) => {
|
|
313
317
|
editable.set("profile", profile.id, "trusting");
|
|
314
318
|
});
|
|
315
319
|
|
|
316
320
|
const accountOnThisNode = this.expectCoValueLoaded(account.id);
|
|
317
321
|
|
|
318
|
-
accountOnThisNode._sessions = {...
|
|
322
|
+
accountOnThisNode._sessions = {...accountAsGroup.groupMap.coValue.sessions};
|
|
319
323
|
accountOnThisNode._cachedContent = undefined;
|
|
320
324
|
|
|
321
325
|
return controlledAccount;
|
|
@@ -330,7 +334,7 @@ export class LocalNode {
|
|
|
330
334
|
|
|
331
335
|
if (
|
|
332
336
|
coValue.header.type !== "comap" ||
|
|
333
|
-
coValue.header.ruleset.type !== "
|
|
337
|
+
coValue.header.ruleset.type !== "group" ||
|
|
334
338
|
!coValue.header.meta ||
|
|
335
339
|
!("type" in coValue.header.meta) ||
|
|
336
340
|
coValue.header.meta.type !== "account"
|
|
@@ -343,22 +347,22 @@ export class LocalNode {
|
|
|
343
347
|
}
|
|
344
348
|
|
|
345
349
|
return new Account(
|
|
346
|
-
coValue.getCurrentContent() as CoMap<
|
|
350
|
+
coValue.getCurrentContent() as CoMap<GroupContent, AccountMeta>,
|
|
347
351
|
this
|
|
348
352
|
).getCurrentAgentID();
|
|
349
353
|
}
|
|
350
354
|
|
|
351
|
-
|
|
352
|
-
const
|
|
355
|
+
createGroup(): Group {
|
|
356
|
+
const groupCoValue = this.createCoValue({
|
|
353
357
|
type: "comap",
|
|
354
|
-
ruleset: { type: "
|
|
358
|
+
ruleset: { type: "group", initialAdmin: this.account.id },
|
|
355
359
|
meta: null,
|
|
356
360
|
...createdNowUnique(),
|
|
357
361
|
});
|
|
358
362
|
|
|
359
|
-
let
|
|
363
|
+
let groupContent = expectGroupContent(groupCoValue.getCurrentContent());
|
|
360
364
|
|
|
361
|
-
|
|
365
|
+
groupContent = groupContent.edit((editable) => {
|
|
362
366
|
editable.set(this.account.id, "admin", "trusting");
|
|
363
367
|
|
|
364
368
|
const readKey = newRandomKeySecret();
|
|
@@ -370,8 +374,8 @@ export class LocalNode {
|
|
|
370
374
|
this.account.currentSealerSecret(),
|
|
371
375
|
this.account.currentSealerID(),
|
|
372
376
|
{
|
|
373
|
-
in:
|
|
374
|
-
tx:
|
|
377
|
+
in: groupCoValue.id,
|
|
378
|
+
tx: groupCoValue.nextTransactionID(),
|
|
375
379
|
}
|
|
376
380
|
),
|
|
377
381
|
"trusting"
|
|
@@ -380,7 +384,7 @@ export class LocalNode {
|
|
|
380
384
|
editable.set("readKey", readKey.id, "trusting");
|
|
381
385
|
});
|
|
382
386
|
|
|
383
|
-
return new
|
|
387
|
+
return new Group(groupContent, this);
|
|
384
388
|
}
|
|
385
389
|
|
|
386
390
|
testWithDifferentAccount(
|