cojson 0.16.3 → 0.16.5
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 +1 -1
- package/CHANGELOG.md +20 -0
- package/dist/coValue.d.ts +1 -1
- package/dist/coValue.d.ts.map +1 -1
- package/dist/coValue.js.map +1 -1
- package/dist/coValueContentMessage.d.ts +10 -0
- package/dist/coValueContentMessage.d.ts.map +1 -0
- package/dist/coValueContentMessage.js +46 -0
- package/dist/coValueContentMessage.js.map +1 -0
- package/dist/coValueCore/coValueCore.d.ts +6 -10
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +20 -125
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +1 -0
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +14 -27
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/group.d.ts +18 -10
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +237 -67
- package/dist/coValues/group.js.map +1 -1
- package/dist/ids.d.ts +3 -3
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js.map +1 -1
- package/dist/localNode.d.ts +11 -6
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +7 -2
- package/dist/localNode.js.map +1 -1
- package/dist/queue/LocalTransactionsSyncQueue.d.ts +24 -0
- package/dist/queue/LocalTransactionsSyncQueue.d.ts.map +1 -0
- package/dist/queue/LocalTransactionsSyncQueue.js +55 -0
- package/dist/queue/LocalTransactionsSyncQueue.js.map +1 -0
- package/dist/queue/StoreQueue.d.ts +9 -6
- package/dist/queue/StoreQueue.d.ts.map +1 -1
- package/dist/queue/StoreQueue.js +10 -2
- package/dist/queue/StoreQueue.js.map +1 -1
- package/dist/storage/storageAsync.d.ts +11 -3
- package/dist/storage/storageAsync.d.ts.map +1 -1
- package/dist/storage/storageAsync.js +59 -46
- package/dist/storage/storageAsync.js.map +1 -1
- package/dist/storage/storageSync.d.ts +9 -3
- package/dist/storage/storageSync.d.ts.map +1 -1
- package/dist/storage/storageSync.js +48 -35
- package/dist/storage/storageSync.js.map +1 -1
- package/dist/storage/syncUtils.d.ts +2 -1
- package/dist/storage/syncUtils.d.ts.map +1 -1
- package/dist/storage/syncUtils.js +4 -0
- package/dist/storage/syncUtils.js.map +1 -1
- package/dist/storage/types.d.ts +3 -2
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/sync.d.ts +6 -6
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +33 -56
- package/dist/sync.js.map +1 -1
- package/dist/tests/StorageApiAsync.test.d.ts +2 -0
- package/dist/tests/StorageApiAsync.test.d.ts.map +1 -0
- package/dist/tests/StorageApiAsync.test.js +574 -0
- package/dist/tests/StorageApiAsync.test.js.map +1 -0
- package/dist/tests/StorageApiSync.test.d.ts +2 -0
- package/dist/tests/StorageApiSync.test.d.ts.map +1 -0
- package/dist/tests/StorageApiSync.test.js +426 -0
- package/dist/tests/StorageApiSync.test.js.map +1 -0
- package/dist/tests/StoreQueue.test.js +9 -21
- package/dist/tests/StoreQueue.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +18 -8
- package/dist/tests/SyncStateManager.test.js.map +1 -1
- package/dist/tests/group.inheritance.test.js +274 -2
- package/dist/tests/group.inheritance.test.js.map +1 -1
- package/dist/tests/group.removeMember.test.js +152 -1
- package/dist/tests/group.removeMember.test.js.map +1 -1
- package/dist/tests/group.roleOf.test.js +2 -2
- package/dist/tests/group.roleOf.test.js.map +1 -1
- package/dist/tests/group.test.js +81 -3
- package/dist/tests/group.test.js.map +1 -1
- package/dist/tests/sync.auth.test.js +22 -10
- package/dist/tests/sync.auth.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +30 -25
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +12 -6
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +6 -4
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +8 -14
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +31 -14
- package/dist/tests/sync.storageAsync.test.js.map +1 -1
- package/dist/tests/sync.test.js +5 -9
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +31 -1
- package/dist/tests/sync.upload.test.js.map +1 -1
- package/dist/tests/testStorage.d.ts +2 -3
- package/dist/tests/testStorage.d.ts.map +1 -1
- package/dist/tests/testStorage.js +16 -8
- package/dist/tests/testStorage.js.map +1 -1
- package/dist/tests/testUtils.d.ts +4 -0
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +22 -4
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/typeUtils/accountOrAgentIDfromSessionID.d.ts +2 -2
- package/dist/typeUtils/accountOrAgentIDfromSessionID.d.ts.map +1 -1
- package/dist/typeUtils/expectGroup.d.ts.map +1 -1
- package/dist/typeUtils/expectGroup.js +6 -5
- package/dist/typeUtils/expectGroup.js.map +1 -1
- package/package.json +1 -1
- package/src/coValue.ts +1 -4
- package/src/coValueContentMessage.ts +73 -0
- package/src/coValueCore/coValueCore.ts +36 -192
- package/src/coValueCore/verifiedState.ts +28 -35
- package/src/coValues/group.ts +329 -99
- package/src/ids.ts +3 -3
- package/src/localNode.ts +15 -10
- package/src/queue/LocalTransactionsSyncQueue.ts +96 -0
- package/src/queue/StoreQueue.ts +22 -12
- package/src/storage/storageAsync.ts +78 -56
- package/src/storage/storageSync.ts +66 -45
- package/src/storage/syncUtils.ts +9 -1
- package/src/storage/types.ts +6 -5
- package/src/sync.ts +47 -67
- package/src/tests/StorageApiAsync.test.ts +829 -0
- package/src/tests/StorageApiSync.test.ts +628 -0
- package/src/tests/StoreQueue.test.ts +10 -24
- package/src/tests/SyncStateManager.test.ts +22 -21
- package/src/tests/group.inheritance.test.ts +415 -1
- package/src/tests/group.removeMember.test.ts +244 -1
- package/src/tests/group.roleOf.test.ts +2 -2
- package/src/tests/group.test.ts +105 -5
- package/src/tests/sync.auth.test.ts +22 -10
- package/src/tests/sync.load.test.ts +32 -26
- package/src/tests/sync.mesh.test.ts +12 -6
- package/src/tests/sync.peerReconciliation.test.ts +6 -4
- package/src/tests/sync.storage.test.ts +8 -14
- package/src/tests/sync.storageAsync.test.ts +39 -14
- package/src/tests/sync.test.ts +6 -14
- package/src/tests/sync.upload.test.ts +38 -1
- package/src/tests/testStorage.ts +19 -13
- package/src/tests/testUtils.ts +29 -5
- package/src/typeUtils/accountOrAgentIDfromSessionID.ts +2 -2
- package/src/typeUtils/expectGroup.ts +8 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifiedState.js","sourceRoot":"","sources":["../../src/coValueCore/verifiedState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,GAAG,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,
|
|
1
|
+
{"version":3,"file":"verifiedState.js","sourceRoot":"","sources":["../../src/coValueCore/verifiedState.ts"],"names":[],"mappings":"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"}
|
package/dist/coValues/group.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CoID } from "../coValue.js";
|
|
2
|
-
import { AvailableCoValueCore } from "../coValueCore/coValueCore.js";
|
|
3
|
-
import { CoValueUniqueness } from "../coValueCore/verifiedState.js";
|
|
4
|
-
import { CryptoProvider, Encrypted, KeyID, KeySecret, Sealed } from "../crypto/crypto.js";
|
|
1
|
+
import type { CoID } from "../coValue.js";
|
|
2
|
+
import type { AvailableCoValueCore, CoValueCore } from "../coValueCore/coValueCore.js";
|
|
3
|
+
import type { CoValueUniqueness } from "../coValueCore/verifiedState.js";
|
|
4
|
+
import type { CryptoProvider, Encrypted, KeyID, KeySecret, Sealed } from "../crypto/crypto.js";
|
|
5
5
|
import { AgentID, ChildGroupReference, ParentGroupReference } from "../ids.js";
|
|
6
6
|
import { JsonObject } from "../jsonValue.js";
|
|
7
7
|
import { AccountRole, Role } from "../permissions.js";
|
|
@@ -52,6 +52,7 @@ export type GroupShape = {
|
|
|
52
52
|
* */
|
|
53
53
|
export declare class RawGroup<Meta extends JsonObject | null = JsonObject | null> extends RawCoMap<GroupShape, Meta> {
|
|
54
54
|
protected readonly crypto: CryptoProvider;
|
|
55
|
+
_lastReadableKeyId?: KeyID;
|
|
55
56
|
constructor(core: AvailableCoValueCore, options?: {
|
|
56
57
|
ignorePrivateTransactions: boolean;
|
|
57
58
|
});
|
|
@@ -70,8 +71,7 @@ export declare class RawGroup<Meta extends JsonObject | null = JsonObject | null
|
|
|
70
71
|
roleOfInternal(accountID: RawAccountID | AgentID | typeof EVERYONE): Role | undefined;
|
|
71
72
|
getParentGroupFromKey(key: ParentGroupReference, atTime?: number): RawGroup<JsonObject | null> | null;
|
|
72
73
|
getParentGroups(atTime?: number): RawGroup<JsonObject | null>[];
|
|
73
|
-
|
|
74
|
-
getChildGroups(): RawGroup<JsonObject | null>[];
|
|
74
|
+
forEachChildGroup(callback: (child: RawGroup) => void): void;
|
|
75
75
|
/**
|
|
76
76
|
* Returns the role of the current account in the group.
|
|
77
77
|
*
|
|
@@ -93,12 +93,22 @@ export declare class RawGroup<Meta extends JsonObject | null = JsonObject | null
|
|
|
93
93
|
getCurrentReadKeyId(): `key_z${string}` | undefined;
|
|
94
94
|
getMemberKeys(): (RawAccountID | AgentID)[];
|
|
95
95
|
getAllMemberKeysSet(): Set<RawAccountID | `sealer_z${string}/signer_z${string}`>;
|
|
96
|
+
getReadKey(keyID: KeyID): KeySecret | undefined;
|
|
97
|
+
getUncachedReadKey(keyID: KeyID): `keySecret_z${string}` | undefined;
|
|
98
|
+
findValidParentKeys(keyID: KeyID, parentGroup: CoValueCore): {
|
|
99
|
+
id: KeyID;
|
|
100
|
+
secret: KeySecret;
|
|
101
|
+
}[];
|
|
96
102
|
/** @internal */
|
|
97
103
|
rotateReadKey(removedMemberKey?: RawAccountID | AgentID | "everyone"): void;
|
|
98
104
|
/** Detect circular references in group inheritance */
|
|
99
105
|
isSelfExtension(parent: RawGroup): boolean;
|
|
106
|
+
getCurrentReadKey(): {
|
|
107
|
+
secret: `keySecret_z${string}` | undefined;
|
|
108
|
+
id: `key_z${string}`;
|
|
109
|
+
};
|
|
100
110
|
extend(parent: RawGroup, role?: "reader" | "writer" | "admin" | "inherit"): void;
|
|
101
|
-
revokeExtend(parent: RawGroup):
|
|
111
|
+
revokeExtend(parent: RawGroup): void;
|
|
102
112
|
/**
|
|
103
113
|
* Strips the specified member of all roles (preventing future writes in
|
|
104
114
|
* the group and owned values) and rotates the read encryption key for that group
|
|
@@ -106,9 +116,7 @@ export declare class RawGroup<Meta extends JsonObject | null = JsonObject | null
|
|
|
106
116
|
*
|
|
107
117
|
* @category 2. Role changing
|
|
108
118
|
*/
|
|
109
|
-
removeMember(account: RawAccount | ControlledAccountOrAgent | Everyone):
|
|
110
|
-
/** @internal */
|
|
111
|
-
removeMemberInternal(account: RawAccount | ControlledAccountOrAgent | AgentID | Everyone): void;
|
|
119
|
+
removeMember(account: RawAccount | ControlledAccountOrAgent | Everyone): void;
|
|
112
120
|
/**
|
|
113
121
|
* Creates an invite for new members to indirectly join the group,
|
|
114
122
|
* allowing them to grant themselves the specified role with the InviteSecret
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/coValues/group.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/coValues/group.ts"],"names":[],"mappings":"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"}
|
package/dist/coValues/group.js
CHANGED
|
@@ -1,9 +1,50 @@
|
|
|
1
1
|
import { base58 } from "@scure/base";
|
|
2
2
|
import { getChildGroupId, getParentGroupId, isAgentID, isChildGroupReference, isParentGroupReference, } from "../ids.js";
|
|
3
3
|
import { logger } from "../logger.js";
|
|
4
|
+
import { isKeyForKeyField } from "../permissions.js";
|
|
5
|
+
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
4
6
|
import { expectGroup } from "../typeUtils/expectGroup.js";
|
|
7
|
+
import { isAccountID } from "../typeUtils/isAccountID.js";
|
|
5
8
|
import { RawCoMap } from "./coMap.js";
|
|
6
9
|
export const EVERYONE = "everyone";
|
|
10
|
+
// We had a bug on key rotation, where the new read key was not revealed to everyone
|
|
11
|
+
// TODO: remove this when we hit the 0.18.0 release (either the groups are healed or they are not used often, it's a minor issue anyway)
|
|
12
|
+
function healMissingKeyForEveryone(group) {
|
|
13
|
+
const readKeyId = group.get("readKey");
|
|
14
|
+
if (!readKeyId ||
|
|
15
|
+
!canRead(group, EVERYONE) ||
|
|
16
|
+
group.get(`${readKeyId}_for_${EVERYONE}`)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const hasAccessToReadKey = canRead(group, group.core.node.getCurrentAgent().id);
|
|
20
|
+
// If the current account has access to the read key, we can fix the group
|
|
21
|
+
if (hasAccessToReadKey) {
|
|
22
|
+
const secret = group.getReadKey(readKeyId);
|
|
23
|
+
if (secret) {
|
|
24
|
+
group.set(`${readKeyId}_for_${EVERYONE}`, secret, "trusting");
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Fallback to the latest readable key for everyone
|
|
29
|
+
const keys = group
|
|
30
|
+
.keys()
|
|
31
|
+
.filter((key) => key.startsWith("key_") && key.endsWith("_for_everyone"));
|
|
32
|
+
let latestKey = keys[0];
|
|
33
|
+
for (const key of keys) {
|
|
34
|
+
if (!latestKey) {
|
|
35
|
+
latestKey = key;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const keyEntry = group.getRaw(key);
|
|
39
|
+
const latestKeyEntry = group.getRaw(latestKey);
|
|
40
|
+
if (keyEntry && latestKeyEntry && keyEntry.madeAt > latestKeyEntry.madeAt) {
|
|
41
|
+
latestKey = key;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (latestKey) {
|
|
45
|
+
group._lastReadableKeyId = latestKey.replace("_for_everyone", "");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
7
48
|
/** A `Group` is a scope for permissions of its members (`"reader" | "writer" | "admin"`), applying to objects owned by that group.
|
|
8
49
|
*
|
|
9
50
|
* A `Group` object exposes methods for permission management and allows you to create new CoValues owned by that group.
|
|
@@ -29,6 +70,7 @@ export class RawGroup extends RawCoMap {
|
|
|
29
70
|
constructor(core, options) {
|
|
30
71
|
super(core, options);
|
|
31
72
|
this.crypto = core.node.crypto;
|
|
73
|
+
healMissingKeyForEveryone(this);
|
|
32
74
|
}
|
|
33
75
|
/**
|
|
34
76
|
* Returns the current role of a given account.
|
|
@@ -103,42 +145,30 @@ export class RawGroup extends RawCoMap {
|
|
|
103
145
|
}
|
|
104
146
|
return groups;
|
|
105
147
|
}
|
|
106
|
-
|
|
107
|
-
const requests = [];
|
|
108
|
-
const peers = this.core.node.syncManager.getServerPeers();
|
|
109
|
-
for (const key of this.keys()) {
|
|
110
|
-
if (!isChildGroupReference(key)) {
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
const id = getChildGroupId(key);
|
|
114
|
-
const child = this.core.node.getCoValue(id);
|
|
115
|
-
if (child.loadingState === "unknown" ||
|
|
116
|
-
child.loadingState === "unavailable") {
|
|
117
|
-
child.load(peers);
|
|
118
|
-
}
|
|
119
|
-
requests.push(child.waitForAvailableOrUnavailable().then((coValue) => {
|
|
120
|
-
if (!coValue.isAvailable()) {
|
|
121
|
-
throw new Error(`Child group ${child.id} is unavailable`);
|
|
122
|
-
}
|
|
123
|
-
// Recursively load child groups
|
|
124
|
-
return expectGroup(coValue.getCurrentContent()).loadAllChildGroups();
|
|
125
|
-
}));
|
|
126
|
-
}
|
|
127
|
-
return Promise.all(requests);
|
|
128
|
-
}
|
|
129
|
-
getChildGroups() {
|
|
130
|
-
const groups = [];
|
|
148
|
+
forEachChildGroup(callback) {
|
|
131
149
|
for (const key of this.keys()) {
|
|
132
150
|
if (isChildGroupReference(key)) {
|
|
133
151
|
// Check if the child group reference is revoked
|
|
134
152
|
if (this.get(key) === "revoked") {
|
|
135
153
|
continue;
|
|
136
154
|
}
|
|
137
|
-
const
|
|
138
|
-
|
|
155
|
+
const id = getChildGroupId(key);
|
|
156
|
+
const child = this.core.node.getCoValue(id);
|
|
157
|
+
if (child.isAvailable()) {
|
|
158
|
+
callback(expectGroup(child.getCurrentContent()));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
this.core.node.load(id).then((child) => {
|
|
162
|
+
if (child !== "unavailable") {
|
|
163
|
+
callback(expectGroup(child));
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
logger.warn(`Unable to load child group ${id}, skipping`);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
139
170
|
}
|
|
140
171
|
}
|
|
141
|
-
return groups;
|
|
142
172
|
}
|
|
143
173
|
/**
|
|
144
174
|
* Returns the role of the current account in the group.
|
|
@@ -163,7 +193,7 @@ export class RawGroup extends RawCoMap {
|
|
|
163
193
|
if (!(role === "reader" || role === "writer" || role === "writeOnly")) {
|
|
164
194
|
throw new Error("Can't make everyone something other than reader, writer or writeOnly");
|
|
165
195
|
}
|
|
166
|
-
const currentReadKey = this.
|
|
196
|
+
const currentReadKey = this.getCurrentReadKey();
|
|
167
197
|
if (!currentReadKey.secret) {
|
|
168
198
|
throw new Error("Can't add member without read key secret");
|
|
169
199
|
}
|
|
@@ -183,7 +213,7 @@ export class RawGroup extends RawCoMap {
|
|
|
183
213
|
}
|
|
184
214
|
if (role === "writeOnly") {
|
|
185
215
|
if (previousRole === "reader" || previousRole === "writer") {
|
|
186
|
-
this.rotateReadKey();
|
|
216
|
+
this.rotateReadKey("everyone");
|
|
187
217
|
}
|
|
188
218
|
this.delete(`${currentReadKey.id}_for_${EVERYONE}`);
|
|
189
219
|
}
|
|
@@ -214,7 +244,7 @@ export class RawGroup extends RawCoMap {
|
|
|
214
244
|
this.internalCreateWriteOnlyKeyForMember(memberKey, agent);
|
|
215
245
|
}
|
|
216
246
|
else {
|
|
217
|
-
const currentReadKey = this.
|
|
247
|
+
const currentReadKey = this.getCurrentReadKey();
|
|
218
248
|
if (!currentReadKey.secret) {
|
|
219
249
|
throw new Error("Can't add member without read key secret");
|
|
220
250
|
}
|
|
@@ -278,6 +308,9 @@ export class RawGroup extends RawCoMap {
|
|
|
278
308
|
return keys;
|
|
279
309
|
}
|
|
280
310
|
getCurrentReadKeyId() {
|
|
311
|
+
if (this._lastReadableKeyId) {
|
|
312
|
+
return this._lastReadableKeyId;
|
|
313
|
+
}
|
|
281
314
|
const myRole = this.myRole();
|
|
282
315
|
if (myRole === "writeOnly") {
|
|
283
316
|
const accountId = this.core.node.getCurrentAgent().id;
|
|
@@ -312,28 +345,129 @@ export class RawGroup extends RawCoMap {
|
|
|
312
345
|
}
|
|
313
346
|
return memberKeys;
|
|
314
347
|
}
|
|
348
|
+
getReadKey(keyID) {
|
|
349
|
+
const cache = this.core.readKeyCache;
|
|
350
|
+
let key = cache.get(keyID);
|
|
351
|
+
if (!key) {
|
|
352
|
+
key = this.getUncachedReadKey(keyID);
|
|
353
|
+
if (key) {
|
|
354
|
+
cache.set(keyID, key);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return key;
|
|
358
|
+
}
|
|
359
|
+
getUncachedReadKey(keyID) {
|
|
360
|
+
const core = this.core;
|
|
361
|
+
const keyForEveryone = this.get(`${keyID}_for_everyone`);
|
|
362
|
+
if (keyForEveryone) {
|
|
363
|
+
return keyForEveryone;
|
|
364
|
+
}
|
|
365
|
+
// Try to find key revelation for us
|
|
366
|
+
const currentAgentOrAccountID = accountOrAgentIDfromSessionID(core.node.currentSessionID);
|
|
367
|
+
// being careful here to avoid recursion
|
|
368
|
+
const lookupAccountOrAgentID = isAccountID(currentAgentOrAccountID)
|
|
369
|
+
? core.id === currentAgentOrAccountID
|
|
370
|
+
? core.node.crypto.getAgentID(core.node.agentSecret) // in accounts, the read key is revealed for the primitive agent
|
|
371
|
+
: currentAgentOrAccountID // current account ID
|
|
372
|
+
: currentAgentOrAccountID; // current agent ID
|
|
373
|
+
const lastReadyKeyEdit = this.lastEditAt(`${keyID}_for_${lookupAccountOrAgentID}`);
|
|
374
|
+
if (lastReadyKeyEdit?.value) {
|
|
375
|
+
const revealer = lastReadyKeyEdit.by;
|
|
376
|
+
const revealerAgent = core.node
|
|
377
|
+
.resolveAccountAgent(revealer, "Expected to know revealer")
|
|
378
|
+
._unsafeUnwrap({ withStackTrace: true });
|
|
379
|
+
const secret = this.crypto.unseal(lastReadyKeyEdit.value, this.crypto.getAgentSealerSecret(core.node.agentSecret), // being careful here to avoid recursion
|
|
380
|
+
this.crypto.getAgentSealerID(revealerAgent), {
|
|
381
|
+
in: this.id,
|
|
382
|
+
tx: lastReadyKeyEdit.tx,
|
|
383
|
+
});
|
|
384
|
+
if (secret) {
|
|
385
|
+
return secret;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
// Try to find indirect revelation through previousKeys
|
|
389
|
+
for (const co of this.keys()) {
|
|
390
|
+
if (isKeyForKeyField(co) && co.startsWith(keyID)) {
|
|
391
|
+
const encryptingKeyID = co.split("_for_")[1];
|
|
392
|
+
const encryptingKeySecret = this.getReadKey(encryptingKeyID);
|
|
393
|
+
if (!encryptingKeySecret) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
const encryptedPreviousKey = this.get(co);
|
|
397
|
+
const secret = this.crypto.decryptKeySecret({
|
|
398
|
+
encryptedID: keyID,
|
|
399
|
+
encryptingID: encryptingKeyID,
|
|
400
|
+
encrypted: encryptedPreviousKey,
|
|
401
|
+
}, encryptingKeySecret);
|
|
402
|
+
if (secret) {
|
|
403
|
+
return secret;
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
logger.warn(`Encrypting ${encryptingKeyID} key didn't decrypt ${keyID}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// try to find revelation to parent group read keys
|
|
411
|
+
for (const co of this.keys()) {
|
|
412
|
+
if (isParentGroupReference(co)) {
|
|
413
|
+
const parentGroupID = getParentGroupId(co);
|
|
414
|
+
const parentGroup = core.node.expectCoValueLoaded(parentGroupID, "Expected parent group to be loaded");
|
|
415
|
+
const parentKeys = this.findValidParentKeys(keyID, parentGroup);
|
|
416
|
+
for (const parentKey of parentKeys) {
|
|
417
|
+
const revelationForParentKey = this.get(`${keyID}_for_${parentKey.id}`);
|
|
418
|
+
if (revelationForParentKey) {
|
|
419
|
+
const secret = parentGroup.node.crypto.decryptKeySecret({
|
|
420
|
+
encryptedID: keyID,
|
|
421
|
+
encryptingID: parentKey.id,
|
|
422
|
+
encrypted: revelationForParentKey,
|
|
423
|
+
}, parentKey.secret);
|
|
424
|
+
if (secret) {
|
|
425
|
+
return secret;
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
logger.warn(`Encrypting parent ${parentKey.id} key didn't decrypt ${keyID}`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return undefined;
|
|
435
|
+
}
|
|
436
|
+
findValidParentKeys(keyID, parentGroup) {
|
|
437
|
+
const validParentKeys = [];
|
|
438
|
+
for (const co of this.keys()) {
|
|
439
|
+
if (isKeyForKeyField(co) && co.startsWith(keyID)) {
|
|
440
|
+
const encryptingKeyID = co.split("_for_")[1];
|
|
441
|
+
const encryptingKeySecret = parentGroup.getReadKey(encryptingKeyID);
|
|
442
|
+
if (!encryptingKeySecret) {
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
validParentKeys.push({
|
|
446
|
+
id: encryptingKeyID,
|
|
447
|
+
secret: encryptingKeySecret,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return validParentKeys;
|
|
452
|
+
}
|
|
315
453
|
/** @internal */
|
|
316
454
|
rotateReadKey(removedMemberKey) {
|
|
455
|
+
if (removedMemberKey !== EVERYONE && canRead(this, EVERYONE)) {
|
|
456
|
+
// When everyone has access to the group, rotating the key is useless
|
|
457
|
+
// because it would be stored unencrypted and available to everyone
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
317
460
|
const memberKeys = this.getMemberKeys().filter((key) => key !== removedMemberKey);
|
|
318
|
-
const currentlyPermittedReaders = memberKeys.filter((key) =>
|
|
319
|
-
const role = this.get(key);
|
|
320
|
-
return (role === "admin" ||
|
|
321
|
-
role === "writer" ||
|
|
322
|
-
role === "reader" ||
|
|
323
|
-
role === "adminInvite" ||
|
|
324
|
-
role === "writerInvite" ||
|
|
325
|
-
role === "readerInvite");
|
|
326
|
-
});
|
|
461
|
+
const currentlyPermittedReaders = memberKeys.filter((key) => canRead(this, key));
|
|
327
462
|
const writeOnlyMembers = memberKeys.filter((key) => {
|
|
328
463
|
const role = this.get(key);
|
|
329
464
|
return role === "writeOnly" || role === "writeOnlyInvite";
|
|
330
465
|
});
|
|
331
466
|
// Get these early, so we fail fast if they are unavailable
|
|
332
467
|
const parentGroups = this.getParentGroups();
|
|
333
|
-
const
|
|
334
|
-
const maybeCurrentReadKey = this.core.getCurrentReadKey();
|
|
468
|
+
const maybeCurrentReadKey = this.getCurrentReadKey();
|
|
335
469
|
if (!maybeCurrentReadKey.secret) {
|
|
336
|
-
throw new
|
|
470
|
+
throw new NoReadKeyAccessError("Can't rotate read key secret we don't have access to");
|
|
337
471
|
}
|
|
338
472
|
const currentReadKey = {
|
|
339
473
|
id: maybeCurrentReadKey.id,
|
|
@@ -375,7 +509,7 @@ export class RawGroup extends RawCoMap {
|
|
|
375
509
|
* This way the members from the parent groups can still have access to this group
|
|
376
510
|
*/
|
|
377
511
|
for (const parent of parentGroups) {
|
|
378
|
-
const { id: parentReadKeyID, secret: parentReadKeySecret } = parent.
|
|
512
|
+
const { id: parentReadKeyID, secret: parentReadKeySecret } = parent.getCurrentReadKey();
|
|
379
513
|
if (!parentReadKeySecret) {
|
|
380
514
|
// We can't reveal the new child key to the parent group where we don't have access to the parent read key
|
|
381
515
|
// TODO: This will be fixed with: https://github.com/garden-co/jazz/issues/1979
|
|
@@ -390,28 +524,56 @@ export class RawGroup extends RawCoMap {
|
|
|
390
524
|
toEncrypt: newReadKey,
|
|
391
525
|
}).encrypted, "trusting");
|
|
392
526
|
}
|
|
393
|
-
|
|
527
|
+
this.forEachChildGroup((child) => {
|
|
394
528
|
// Since child references are mantained only for the key rotation,
|
|
395
529
|
// circular references are skipped here because it's more performant
|
|
396
530
|
// than always checking for circular references in childs inside the permission checks
|
|
397
531
|
if (child.isSelfExtension(this)) {
|
|
398
|
-
|
|
532
|
+
return;
|
|
399
533
|
}
|
|
400
|
-
|
|
401
|
-
|
|
534
|
+
try {
|
|
535
|
+
child.rotateReadKey(removedMemberKey);
|
|
536
|
+
}
|
|
537
|
+
catch (error) {
|
|
538
|
+
if (error instanceof NoReadKeyAccessError) {
|
|
539
|
+
logger.warn(`Can't rotate read key on child ${child.id} because we don't have access to the read key`);
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
throw error;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
});
|
|
402
546
|
}
|
|
403
547
|
/** Detect circular references in group inheritance */
|
|
404
548
|
isSelfExtension(parent) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
549
|
+
const checkedGroups = new Set();
|
|
550
|
+
const queue = [parent];
|
|
551
|
+
while (true) {
|
|
552
|
+
const current = queue.pop();
|
|
553
|
+
if (!current) {
|
|
554
|
+
return false;
|
|
555
|
+
}
|
|
556
|
+
if (current.id === this.id) {
|
|
411
557
|
return true;
|
|
412
558
|
}
|
|
559
|
+
checkedGroups.add(current.id);
|
|
560
|
+
const parentGroups = current.getParentGroups();
|
|
561
|
+
for (const parent of parentGroups) {
|
|
562
|
+
if (!checkedGroups.has(parent.id)) {
|
|
563
|
+
queue.push(parent);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
413
566
|
}
|
|
414
|
-
|
|
567
|
+
}
|
|
568
|
+
getCurrentReadKey() {
|
|
569
|
+
const keyId = this.getCurrentReadKeyId();
|
|
570
|
+
if (!keyId) {
|
|
571
|
+
throw new Error("No readKey set");
|
|
572
|
+
}
|
|
573
|
+
return {
|
|
574
|
+
secret: this.getReadKey(keyId),
|
|
575
|
+
id: keyId,
|
|
576
|
+
};
|
|
415
577
|
}
|
|
416
578
|
extend(parent, role = "inherit") {
|
|
417
579
|
if (this.isSelfExtension(parent)) {
|
|
@@ -421,8 +583,8 @@ export class RawGroup extends RawCoMap {
|
|
|
421
583
|
throw new Error("To extend a group, the current account must be an admin in the child group");
|
|
422
584
|
}
|
|
423
585
|
const value = role === "inherit" ? "extend" : role;
|
|
424
|
-
this.set(`parent_${parent.id}`, value, "trusting");
|
|
425
586
|
parent.set(`child_${this.id}`, "extend", "trusting");
|
|
587
|
+
this.set(`parent_${parent.id}`, value, "trusting");
|
|
426
588
|
if (parent.myRole() !== "admin" &&
|
|
427
589
|
parent.myRole() !== "writer" &&
|
|
428
590
|
parent.myRole() !== "reader" &&
|
|
@@ -430,11 +592,11 @@ export class RawGroup extends RawCoMap {
|
|
|
430
592
|
// Create a writeOnly key in the parent group to be able to reveal the current child key to the parent group
|
|
431
593
|
parent.internalCreateWriteOnlyKeyForMember(this.core.node.getCurrentAgent().id, this.core.node.getCurrentAgent().currentAgentID());
|
|
432
594
|
}
|
|
433
|
-
|
|
595
|
+
let { id: parentReadKeyID, secret: parentReadKeySecret } = parent.getCurrentReadKey();
|
|
434
596
|
if (!parentReadKeySecret) {
|
|
435
597
|
throw new Error("Can't extend group without parent read key secret");
|
|
436
598
|
}
|
|
437
|
-
const { id: childReadKeyID, secret: childReadKeySecret } = this.
|
|
599
|
+
const { id: childReadKeyID, secret: childReadKeySecret } = this.getCurrentReadKey();
|
|
438
600
|
if (!childReadKeySecret) {
|
|
439
601
|
throw new Error("Can't extend group without child read key secret");
|
|
440
602
|
}
|
|
@@ -449,7 +611,7 @@ export class RawGroup extends RawCoMap {
|
|
|
449
611
|
},
|
|
450
612
|
}).encrypted, "trusting");
|
|
451
613
|
}
|
|
452
|
-
|
|
614
|
+
revokeExtend(parent) {
|
|
453
615
|
if (this.myRole() !== "admin") {
|
|
454
616
|
throw new Error("To unextend a group, the current account must be an admin in the child group");
|
|
455
617
|
}
|
|
@@ -467,7 +629,6 @@ export class RawGroup extends RawCoMap {
|
|
|
467
629
|
this.set(`parent_${parent.id}`, "revoked", "trusting");
|
|
468
630
|
// Set the child key on the parent group to `revoked`
|
|
469
631
|
parent.set(`child_${this.id}`, "revoked", "trusting");
|
|
470
|
-
await this.loadAllChildGroups();
|
|
471
632
|
// Rotate the keys on the child group
|
|
472
633
|
this.rotateReadKey();
|
|
473
634
|
}
|
|
@@ -478,13 +639,7 @@ export class RawGroup extends RawCoMap {
|
|
|
478
639
|
*
|
|
479
640
|
* @category 2. Role changing
|
|
480
641
|
*/
|
|
481
|
-
|
|
482
|
-
// Ensure all child groups are loaded before removing a member
|
|
483
|
-
await this.loadAllChildGroups();
|
|
484
|
-
this.removeMemberInternal(account);
|
|
485
|
-
}
|
|
486
|
-
/** @internal */
|
|
487
|
-
removeMemberInternal(account) {
|
|
642
|
+
removeMember(account) {
|
|
488
643
|
const memberKey = typeof account === "string" ? account : account.id;
|
|
489
644
|
if (this.myRole() === "admin") {
|
|
490
645
|
this.rotateReadKey(memberKey);
|
|
@@ -637,4 +792,19 @@ export function secretSeedFromInviteSecret(inviteSecret) {
|
|
|
637
792
|
}
|
|
638
793
|
return base58.decode(inviteSecret.slice("inviteSecret_z".length));
|
|
639
794
|
}
|
|
795
|
+
const canRead = (group, key) => {
|
|
796
|
+
const role = group.get(key);
|
|
797
|
+
return (role === "admin" ||
|
|
798
|
+
role === "writer" ||
|
|
799
|
+
role === "reader" ||
|
|
800
|
+
role === "adminInvite" ||
|
|
801
|
+
role === "writerInvite" ||
|
|
802
|
+
role === "readerInvite");
|
|
803
|
+
};
|
|
804
|
+
class NoReadKeyAccessError extends Error {
|
|
805
|
+
constructor(message) {
|
|
806
|
+
super(message);
|
|
807
|
+
this.name = "NoReadKeyAccessError";
|
|
808
|
+
}
|
|
809
|
+
}
|
|
640
810
|
//# sourceMappingURL=group.js.map
|