cojson 0.18.0 → 0.18.2
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 +14 -0
- package/dist/coValueCore/branching.d.ts +36 -0
- package/dist/coValueCore/branching.d.ts.map +1 -0
- package/dist/coValueCore/branching.js +122 -0
- package/dist/coValueCore/branching.js.map +1 -0
- package/dist/coValueCore/coValueCore.d.ts +71 -5
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +162 -53
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/decodeTransactionChangesAndMeta.d.ts +3 -0
- package/dist/coValueCore/decodeTransactionChangesAndMeta.d.ts.map +1 -0
- package/dist/coValueCore/decodeTransactionChangesAndMeta.js +59 -0
- package/dist/coValueCore/decodeTransactionChangesAndMeta.js.map +1 -0
- package/dist/coValueCore/utils.d.ts.map +1 -1
- package/dist/coValueCore/utils.js +3 -0
- package/dist/coValueCore/utils.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValues/coList.d.ts +3 -3
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +4 -7
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +3 -3
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +6 -6
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.d.ts +3 -3
- package/dist/coValues/coStream.d.ts.map +1 -1
- package/dist/coValues/coStream.js +4 -4
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js.map +1 -1
- package/dist/jsonStringify.d.ts +1 -0
- package/dist/jsonStringify.d.ts.map +1 -1
- package/dist/jsonStringify.js +8 -0
- package/dist/jsonStringify.js.map +1 -1
- package/dist/localNode.d.ts +6 -0
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +27 -0
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.d.ts +2 -7
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +75 -71
- package/dist/permissions.js.map +1 -1
- package/dist/tests/branching.test.d.ts +2 -0
- package/dist/tests/branching.test.d.ts.map +1 -0
- package/dist/tests/branching.test.js +287 -0
- package/dist/tests/branching.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +2 -3
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/group.removeMember.test.js +63 -116
- package/dist/tests/group.removeMember.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +36 -0
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +39 -3
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +39 -3
- package/dist/tests/sync.upload.test.js.map +1 -1
- package/package.json +2 -2
- package/src/coValueCore/branching.ts +198 -0
- package/src/coValueCore/coValueCore.ts +255 -72
- package/src/coValueCore/decodeTransactionChangesAndMeta.ts +81 -0
- package/src/coValueCore/utils.ts +4 -0
- package/src/coValueCore/verifiedState.ts +1 -1
- package/src/coValues/coList.ts +8 -10
- package/src/coValues/coMap.ts +8 -11
- package/src/coValues/coStream.ts +7 -8
- package/src/ids.ts +4 -1
- package/src/jsonStringify.ts +8 -0
- package/src/localNode.ts +40 -0
- package/src/permissions.ts +83 -90
- package/src/tests/branching.test.ts +425 -0
- package/src/tests/coValueCore.test.ts +2 -3
- package/src/tests/group.removeMember.test.ts +116 -214
- package/src/tests/sync.load.test.ts +48 -0
- package/src/tests/sync.storage.test.ts +54 -3
- package/src/tests/sync.upload.test.ts +53 -3
package/src/permissions.ts
CHANGED
|
@@ -77,10 +77,7 @@ function logPermissionError(
|
|
|
77
77
|
logger.debug("Permission error: " + message, attributes);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
export function determineValidTransactions(
|
|
81
|
-
coValue: CoValueCore,
|
|
82
|
-
knownTransactions?: CoValueKnownState["sessions"],
|
|
83
|
-
): { txID: TransactionID; tx: Transaction }[] {
|
|
80
|
+
export function determineValidTransactions(coValue: CoValueCore) {
|
|
84
81
|
if (!coValue.isAvailable()) {
|
|
85
82
|
throw new Error("determineValidTransactions CoValue is not available");
|
|
86
83
|
}
|
|
@@ -91,8 +88,7 @@ export function determineValidTransactions(
|
|
|
91
88
|
throw new Error("Group must have initialAdmin");
|
|
92
89
|
}
|
|
93
90
|
|
|
94
|
-
|
|
95
|
-
.validTransactions;
|
|
91
|
+
determineValidTransactionsForGroup(coValue, initialAdmin);
|
|
96
92
|
} else if (coValue.verified.header.ruleset.type === "ownedByGroup") {
|
|
97
93
|
const groupContent = expectGroup(
|
|
98
94
|
coValue.node
|
|
@@ -107,58 +103,44 @@ export function determineValidTransactions(
|
|
|
107
103
|
throw new Error("Group must be a map");
|
|
108
104
|
}
|
|
109
105
|
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const knownTransactionsForSession = knownTransactions?.[sessionID] ?? -1;
|
|
106
|
+
for (const tx of coValue.verifiedTransactions) {
|
|
107
|
+
if (tx.isValidated) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
115
110
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
111
|
+
tx.isValidated = true;
|
|
112
|
+
const wasValid = tx.isValid;
|
|
120
113
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
114
|
+
const groupAtTime = groupContent.atTime(tx.madeAt);
|
|
115
|
+
const effectiveTransactor = agentInAccountOrMemberInGroup(
|
|
116
|
+
tx.author,
|
|
117
|
+
groupAtTime,
|
|
118
|
+
);
|
|
126
119
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
if (!effectiveTransactor) {
|
|
121
|
+
tx.isValid = false;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
130
124
|
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
const transactorRoleAtTxTime =
|
|
126
|
+
groupAtTime.roleOfInternal(effectiveTransactor);
|
|
133
127
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
128
|
+
if (
|
|
129
|
+
transactorRoleAtTxTime !== "admin" &&
|
|
130
|
+
transactorRoleAtTxTime !== "writer" &&
|
|
131
|
+
transactorRoleAtTxTime !== "writeOnly"
|
|
132
|
+
) {
|
|
133
|
+
tx.isValid = false;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
141
136
|
|
|
142
|
-
|
|
143
|
-
});
|
|
137
|
+
tx.isValid = true;
|
|
144
138
|
}
|
|
145
|
-
|
|
146
|
-
return validTransactions;
|
|
147
139
|
} else if (coValue.verified.header.ruleset.type === "unsafeAllowAll") {
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const knownTransactionsForSession = knownTransactions?.[sessionID] ?? -1;
|
|
152
|
-
|
|
153
|
-
sessionLog.transactions.forEach((tx, txIndex) => {
|
|
154
|
-
if (knownTransactionsForSession >= txIndex) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
validTransactions.push({ txID: { sessionID, txIndex }, tx });
|
|
159
|
-
});
|
|
140
|
+
for (const tx of coValue.verifiedTransactions) {
|
|
141
|
+
tx.isValid = true;
|
|
142
|
+
tx.isValidated = true;
|
|
160
143
|
}
|
|
161
|
-
return validTransactions;
|
|
162
144
|
} else {
|
|
163
145
|
throw new Error(
|
|
164
146
|
"Unknown ruleset type " +
|
|
@@ -228,22 +210,9 @@ function determineValidTransactionsForGroup(
|
|
|
228
210
|
coValue: CoValueCore,
|
|
229
211
|
initialAdmin: RawAccountID | AgentID,
|
|
230
212
|
extendChain?: Set<CoValueCore["id"]>,
|
|
231
|
-
): {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
txIndex: number;
|
|
235
|
-
tx: Transaction;
|
|
236
|
-
}[] = [];
|
|
237
|
-
|
|
238
|
-
for (const [sessionID, sessionLog] of coValue.verified?.sessions.entries() ??
|
|
239
|
-
[]) {
|
|
240
|
-
sessionLog.transactions.forEach((tx, txIndex) => {
|
|
241
|
-
allTransactionsSorted.push({ sessionID, txIndex, tx });
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
allTransactionsSorted.sort((a, b) => {
|
|
246
|
-
return a.tx.madeAt - b.tx.madeAt;
|
|
213
|
+
): { memberState: MemberState } {
|
|
214
|
+
coValue.verifiedTransactions.sort((a, b) => {
|
|
215
|
+
return a.madeAt - b.madeAt;
|
|
247
216
|
});
|
|
248
217
|
|
|
249
218
|
const memberState: MemberState = {};
|
|
@@ -252,15 +221,16 @@ function determineValidTransactionsForGroup(
|
|
|
252
221
|
|
|
253
222
|
const writeKeys = new Set<string>();
|
|
254
223
|
|
|
255
|
-
for (const
|
|
256
|
-
const transactor =
|
|
224
|
+
for (const transaction of coValue.verifiedTransactions) {
|
|
225
|
+
const transactor = transaction.author;
|
|
226
|
+
|
|
227
|
+
transaction.isValidated = true;
|
|
228
|
+
|
|
229
|
+
const tx = transaction.tx;
|
|
257
230
|
|
|
258
231
|
if (tx.privacy === "private") {
|
|
259
232
|
if (memberState[transactor] === "admin") {
|
|
260
|
-
|
|
261
|
-
txID: { sessionID, txIndex },
|
|
262
|
-
tx,
|
|
263
|
-
});
|
|
233
|
+
transaction.isValid = true;
|
|
264
234
|
continue;
|
|
265
235
|
} else {
|
|
266
236
|
logPermissionError(
|
|
@@ -270,16 +240,20 @@ function determineValidTransactionsForGroup(
|
|
|
270
240
|
}
|
|
271
241
|
}
|
|
272
242
|
|
|
273
|
-
let changes;
|
|
243
|
+
let changes = transaction.changes;
|
|
274
244
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
245
|
+
if (!changes) {
|
|
246
|
+
try {
|
|
247
|
+
changes = parseJSON(tx.changes);
|
|
248
|
+
transaction.changes = changes;
|
|
249
|
+
} catch (e) {
|
|
250
|
+
logPermissionError("Invalid JSON in transaction", {
|
|
251
|
+
id: coValue.id,
|
|
252
|
+
tx,
|
|
253
|
+
});
|
|
254
|
+
transaction.hasInvalidChanges = true;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
283
257
|
}
|
|
284
258
|
|
|
285
259
|
const change = changes[0] as
|
|
@@ -292,29 +266,33 @@ function determineValidTransactionsForGroup(
|
|
|
292
266
|
|
|
293
267
|
if (changes.length !== 1) {
|
|
294
268
|
logPermissionError("Group transaction must have exactly one change");
|
|
269
|
+
transaction.isValid = false;
|
|
295
270
|
continue;
|
|
296
271
|
}
|
|
297
272
|
|
|
298
273
|
if (change.op !== "set") {
|
|
299
274
|
logPermissionError("Group transaction must set a role or readKey");
|
|
275
|
+
transaction.isValid = false;
|
|
300
276
|
continue;
|
|
301
277
|
}
|
|
302
278
|
|
|
303
279
|
if (change.key === "readKey") {
|
|
304
280
|
if (memberState[transactor] !== "admin") {
|
|
305
281
|
logPermissionError("Only admins can set readKeys");
|
|
282
|
+
transaction.isValid = false;
|
|
306
283
|
continue;
|
|
307
284
|
}
|
|
308
285
|
|
|
309
|
-
|
|
286
|
+
transaction.isValid = true;
|
|
310
287
|
continue;
|
|
311
288
|
} else if (change.key === "profile") {
|
|
312
289
|
if (memberState[transactor] !== "admin") {
|
|
313
290
|
logPermissionError("Only admins can set profile");
|
|
291
|
+
transaction.isValid = false;
|
|
314
292
|
continue;
|
|
315
293
|
}
|
|
316
294
|
|
|
317
|
-
|
|
295
|
+
transaction.isValid = true;
|
|
318
296
|
continue;
|
|
319
297
|
} else if (change.key === "root") {
|
|
320
298
|
if (memberState[transactor] !== "admin") {
|
|
@@ -322,7 +300,7 @@ function determineValidTransactionsForGroup(
|
|
|
322
300
|
continue;
|
|
323
301
|
}
|
|
324
302
|
|
|
325
|
-
|
|
303
|
+
transaction.isValid = true;
|
|
326
304
|
continue;
|
|
327
305
|
} else if (
|
|
328
306
|
isKeyForKeyField(change.key) ||
|
|
@@ -337,15 +315,17 @@ function determineValidTransactionsForGroup(
|
|
|
337
315
|
!isOwnWriteKeyRevelation(change.key, transactor, writeOnlyKeys)
|
|
338
316
|
) {
|
|
339
317
|
logPermissionError("Only admins can reveal keys");
|
|
318
|
+
transaction.isValid = false;
|
|
340
319
|
continue;
|
|
341
320
|
}
|
|
342
321
|
|
|
343
322
|
// TODO: check validity of agents who the key is revealed to?
|
|
344
|
-
|
|
323
|
+
transaction.isValid = true;
|
|
345
324
|
continue;
|
|
346
325
|
} else if (isParentExtension(change.key)) {
|
|
347
326
|
if (memberState[transactor] !== "admin") {
|
|
348
327
|
logPermissionError("Only admins can set parent extensions");
|
|
328
|
+
transaction.isValid = false;
|
|
349
329
|
continue;
|
|
350
330
|
}
|
|
351
331
|
|
|
@@ -364,13 +344,14 @@ function determineValidTransactionsForGroup(
|
|
|
364
344
|
logPermissionError(
|
|
365
345
|
"Circular extend detected, dropping the transaction",
|
|
366
346
|
);
|
|
347
|
+
transaction.isValid = false;
|
|
367
348
|
continue;
|
|
368
349
|
}
|
|
369
350
|
|
|
370
|
-
|
|
351
|
+
transaction.isValid = true;
|
|
371
352
|
continue;
|
|
372
353
|
} else if (isChildExtension(change.key)) {
|
|
373
|
-
|
|
354
|
+
transaction.isValid = true;
|
|
374
355
|
continue;
|
|
375
356
|
} else if (isWriteKeyForMember(change.key)) {
|
|
376
357
|
const memberKey = getAccountOrAgentFromWriteKeyForMember(change.key);
|
|
@@ -381,6 +362,7 @@ function determineValidTransactionsForGroup(
|
|
|
381
362
|
memberKey !== transactor
|
|
382
363
|
) {
|
|
383
364
|
logPermissionError("Only admins can set writeKeys");
|
|
365
|
+
transaction.isValid = false;
|
|
384
366
|
continue;
|
|
385
367
|
}
|
|
386
368
|
|
|
@@ -398,12 +380,13 @@ function determineValidTransactionsForGroup(
|
|
|
398
380
|
logPermissionError(
|
|
399
381
|
"Write key already exists and can't be overridden by invite",
|
|
400
382
|
);
|
|
383
|
+
transaction.isValid = false;
|
|
401
384
|
continue;
|
|
402
385
|
}
|
|
403
386
|
|
|
404
387
|
writeKeys.add(change.key);
|
|
405
388
|
|
|
406
|
-
|
|
389
|
+
transaction.isValid = true;
|
|
407
390
|
continue;
|
|
408
391
|
}
|
|
409
392
|
|
|
@@ -422,6 +405,7 @@ function determineValidTransactionsForGroup(
|
|
|
422
405
|
change.value !== "writeOnlyInvite"
|
|
423
406
|
) {
|
|
424
407
|
logPermissionError("Group transaction must set a valid role");
|
|
408
|
+
transaction.isValid = false;
|
|
425
409
|
continue;
|
|
426
410
|
}
|
|
427
411
|
|
|
@@ -437,6 +421,7 @@ function determineValidTransactionsForGroup(
|
|
|
437
421
|
logPermissionError(
|
|
438
422
|
"Everyone can only be set to reader, writer, writeOnly or revoked",
|
|
439
423
|
);
|
|
424
|
+
transaction.isValid = false;
|
|
440
425
|
continue;
|
|
441
426
|
}
|
|
442
427
|
|
|
@@ -450,7 +435,9 @@ function determineValidTransactionsForGroup(
|
|
|
450
435
|
const currentAccountId = coValue.node.getCurrentAccountOrAgentID();
|
|
451
436
|
|
|
452
437
|
const isSelfRevoke =
|
|
453
|
-
currentAccountId === change.key &&
|
|
438
|
+
currentAccountId === change.key &&
|
|
439
|
+
transactor === currentAccountId &&
|
|
440
|
+
change.value === "revoked";
|
|
454
441
|
|
|
455
442
|
if (!isFirstSelfAppointment && !isSelfRevoke) {
|
|
456
443
|
if (memberState[transactor] === "admin") {
|
|
@@ -460,41 +447,47 @@ function determineValidTransactionsForGroup(
|
|
|
460
447
|
assignedRole !== "admin"
|
|
461
448
|
) {
|
|
462
449
|
logPermissionError("Admins can only demote themselves.");
|
|
450
|
+
transaction.isValid = false;
|
|
463
451
|
continue;
|
|
464
452
|
}
|
|
465
453
|
} else if (memberState[transactor] === "adminInvite") {
|
|
466
454
|
if (change.value !== "admin") {
|
|
467
455
|
logPermissionError("AdminInvites can only create admins.");
|
|
456
|
+
transaction.isValid = false;
|
|
468
457
|
continue;
|
|
469
458
|
}
|
|
470
459
|
} else if (memberState[transactor] === "writerInvite") {
|
|
471
460
|
if (change.value !== "writer") {
|
|
472
461
|
logPermissionError("WriterInvites can only create writers.");
|
|
462
|
+
transaction.isValid = false;
|
|
473
463
|
continue;
|
|
474
464
|
}
|
|
475
465
|
} else if (memberState[transactor] === "readerInvite") {
|
|
476
466
|
if (change.value !== "reader") {
|
|
477
467
|
logPermissionError("ReaderInvites can only create reader.");
|
|
468
|
+
transaction.isValid = false;
|
|
478
469
|
continue;
|
|
479
470
|
}
|
|
480
471
|
} else if (memberState[transactor] === "writeOnlyInvite") {
|
|
481
472
|
if (change.value !== "writeOnly") {
|
|
482
473
|
logPermissionError("WriteOnlyInvites can only create writeOnly.");
|
|
474
|
+
transaction.isValid = false;
|
|
483
475
|
continue;
|
|
484
476
|
}
|
|
485
477
|
} else {
|
|
486
478
|
logPermissionError(
|
|
487
479
|
"Group transaction must be made by current admin or invite",
|
|
488
480
|
);
|
|
481
|
+
transaction.isValid = false;
|
|
489
482
|
continue;
|
|
490
483
|
}
|
|
491
484
|
}
|
|
492
485
|
|
|
493
486
|
memberState[affectedMember] = change.value;
|
|
494
|
-
|
|
487
|
+
transaction.isValid = true;
|
|
495
488
|
}
|
|
496
489
|
|
|
497
|
-
return {
|
|
490
|
+
return { memberState };
|
|
498
491
|
}
|
|
499
492
|
|
|
500
493
|
function agentInAccountOrMemberInGroup(
|