cojson 0.0.24 → 0.1.1
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 +41 -39
- 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 +48 -46
- 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,32 +151,32 @@ 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)
|
|
174
174
|
);
|
|
175
175
|
const inviteAgentID = getAgentID(inviteAgentSecret);
|
|
176
176
|
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
const role =
|
|
177
|
+
const inviteRole = await new Promise((resolve, reject) => {
|
|
178
|
+
group.groupMap.subscribe((groupMap) => {
|
|
179
|
+
const role = groupMap.get(inviteAgentID);
|
|
180
180
|
if (role) {
|
|
181
181
|
resolve(role);
|
|
182
182
|
}
|
|
@@ -184,45 +184,47 @@ export class LocalNode {
|
|
|
184
184
|
setTimeout(
|
|
185
185
|
() =>
|
|
186
186
|
reject(
|
|
187
|
-
new Error("Couldn't find
|
|
187
|
+
new Error("Couldn't find invite before timeout")
|
|
188
188
|
),
|
|
189
189
|
1000
|
|
190
190
|
);
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
-
if (!
|
|
194
|
-
throw new Error("No
|
|
193
|
+
if (!inviteRole) {
|
|
194
|
+
throw new Error("No invite 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" ||
|
|
201
|
-
(existingRole === "writer" &&
|
|
201
|
+
(existingRole === "writer" && inviteRole === "writerInvite") ||
|
|
202
|
+
(existingRole === "writer" && inviteRole === "reader") ||
|
|
203
|
+
(existingRole === "reader" && inviteRole === "readerInvite")
|
|
202
204
|
) {
|
|
203
|
-
console.debug("Not accepting invite that would downgrade role");
|
|
205
|
+
console.debug("Not accepting invite that would replace or downgrade role");
|
|
204
206
|
return;
|
|
205
207
|
}
|
|
206
208
|
|
|
207
|
-
const
|
|
209
|
+
const groupAsInvite = group.testWithDifferentAccount(
|
|
208
210
|
new AnonymousControlledAccount(inviteAgentSecret),
|
|
209
211
|
newRandomSessionID(inviteAgentID)
|
|
210
212
|
);
|
|
211
213
|
|
|
212
|
-
|
|
214
|
+
groupAsInvite.addMember(
|
|
213
215
|
this.account.id,
|
|
214
|
-
|
|
216
|
+
inviteRole === "adminInvite"
|
|
215
217
|
? "admin"
|
|
216
|
-
:
|
|
218
|
+
: inviteRole === "writerInvite"
|
|
217
219
|
? "writer"
|
|
218
220
|
: "reader"
|
|
219
221
|
);
|
|
220
222
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
group.groupMap.coValue._sessions = groupAsInvite.groupMap.coValue.sessions;
|
|
224
|
+
group.groupMap.coValue._cachedContent = undefined;
|
|
223
225
|
|
|
224
|
-
for (const
|
|
225
|
-
|
|
226
|
+
for (const groupListener of group.groupMap.coValue.listeners) {
|
|
227
|
+
groupListener(group.groupMap.coValue.getCurrentContent());
|
|
226
228
|
}
|
|
227
229
|
}
|
|
228
230
|
|
|
@@ -245,7 +247,7 @@ export class LocalNode {
|
|
|
245
247
|
|
|
246
248
|
expectProfileLoaded(id: AccountID, expectation?: string): Profile {
|
|
247
249
|
const account = this.expectCoValueLoaded(id, expectation);
|
|
248
|
-
const profileID =
|
|
250
|
+
const profileID = expectGroupContent(account.getCurrentContent()).get(
|
|
249
251
|
"profile"
|
|
250
252
|
);
|
|
251
253
|
if (!profileID) {
|
|
@@ -272,12 +274,12 @@ export class LocalNode {
|
|
|
272
274
|
newRandomSessionID(getAgentID(agentSecret))
|
|
273
275
|
);
|
|
274
276
|
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
+
const accountAsGroup = new Group(
|
|
278
|
+
expectGroupContent(account.getCurrentContent()),
|
|
277
279
|
account.node
|
|
278
280
|
);
|
|
279
281
|
|
|
280
|
-
|
|
282
|
+
accountAsGroup.groupMap.edit((editable) => {
|
|
281
283
|
editable.set(getAgentID(agentSecret), "admin", "trusting");
|
|
282
284
|
|
|
283
285
|
const readKey = newRandomKeySecret();
|
|
@@ -305,7 +307,7 @@ export class LocalNode {
|
|
|
305
307
|
account.node
|
|
306
308
|
);
|
|
307
309
|
|
|
308
|
-
const profile =
|
|
310
|
+
const profile = accountAsGroup.createMap<ProfileContent, ProfileMeta>({
|
|
309
311
|
type: "profile",
|
|
310
312
|
});
|
|
311
313
|
|
|
@@ -313,13 +315,13 @@ export class LocalNode {
|
|
|
313
315
|
editable.set("name", name, "trusting");
|
|
314
316
|
});
|
|
315
317
|
|
|
316
|
-
|
|
318
|
+
accountAsGroup.groupMap.edit((editable) => {
|
|
317
319
|
editable.set("profile", profile.id, "trusting");
|
|
318
320
|
});
|
|
319
321
|
|
|
320
322
|
const accountOnThisNode = this.expectCoValueLoaded(account.id);
|
|
321
323
|
|
|
322
|
-
accountOnThisNode._sessions = {...
|
|
324
|
+
accountOnThisNode._sessions = {...accountAsGroup.groupMap.coValue.sessions};
|
|
323
325
|
accountOnThisNode._cachedContent = undefined;
|
|
324
326
|
|
|
325
327
|
return controlledAccount;
|
|
@@ -334,7 +336,7 @@ export class LocalNode {
|
|
|
334
336
|
|
|
335
337
|
if (
|
|
336
338
|
coValue.header.type !== "comap" ||
|
|
337
|
-
coValue.header.ruleset.type !== "
|
|
339
|
+
coValue.header.ruleset.type !== "group" ||
|
|
338
340
|
!coValue.header.meta ||
|
|
339
341
|
!("type" in coValue.header.meta) ||
|
|
340
342
|
coValue.header.meta.type !== "account"
|
|
@@ -347,22 +349,22 @@ export class LocalNode {
|
|
|
347
349
|
}
|
|
348
350
|
|
|
349
351
|
return new Account(
|
|
350
|
-
coValue.getCurrentContent() as CoMap<
|
|
352
|
+
coValue.getCurrentContent() as CoMap<GroupContent, AccountMeta>,
|
|
351
353
|
this
|
|
352
354
|
).getCurrentAgentID();
|
|
353
355
|
}
|
|
354
356
|
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
+
createGroup(): Group {
|
|
358
|
+
const groupCoValue = this.createCoValue({
|
|
357
359
|
type: "comap",
|
|
358
|
-
ruleset: { type: "
|
|
360
|
+
ruleset: { type: "group", initialAdmin: this.account.id },
|
|
359
361
|
meta: null,
|
|
360
362
|
...createdNowUnique(),
|
|
361
363
|
});
|
|
362
364
|
|
|
363
|
-
let
|
|
365
|
+
let groupContent = expectGroupContent(groupCoValue.getCurrentContent());
|
|
364
366
|
|
|
365
|
-
|
|
367
|
+
groupContent = groupContent.edit((editable) => {
|
|
366
368
|
editable.set(this.account.id, "admin", "trusting");
|
|
367
369
|
|
|
368
370
|
const readKey = newRandomKeySecret();
|
|
@@ -374,8 +376,8 @@ export class LocalNode {
|
|
|
374
376
|
this.account.currentSealerSecret(),
|
|
375
377
|
this.account.currentSealerID(),
|
|
376
378
|
{
|
|
377
|
-
in:
|
|
378
|
-
tx:
|
|
379
|
+
in: groupCoValue.id,
|
|
380
|
+
tx: groupCoValue.nextTransactionID(),
|
|
379
381
|
}
|
|
380
382
|
),
|
|
381
383
|
"trusting"
|
|
@@ -384,7 +386,7 @@ export class LocalNode {
|
|
|
384
386
|
editable.set("readKey", readKey.id, "trusting");
|
|
385
387
|
});
|
|
386
388
|
|
|
387
|
-
return new
|
|
389
|
+
return new Group(groupContent, this);
|
|
388
390
|
}
|
|
389
391
|
|
|
390
392
|
testWithDifferentAccount(
|