@enbox/dwn-sdk-js 0.3.9 → 0.4.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/dist/browser.mjs +11 -11
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/generated/precompiled-validators.js +175 -512
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +1 -3
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +1 -17
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-validation.js +1 -1
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
- package/dist/esm/src/core/replication-apply.js +200 -0
- package/dist/esm/src/core/replication-apply.js.map +1 -0
- package/dist/esm/src/dwn.js +212 -0
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +66 -369
- package/dist/esm/src/handlers/messages-sync.js.map +1 -1
- package/dist/esm/src/index.js +1 -1
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/messages-sync.js +0 -11
- package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
- package/dist/esm/tests/core/replication-apply.spec.js +220 -0
- package/dist/esm/tests/core/replication-apply.spec.js.map +1 -0
- package/dist/esm/tests/dwn.spec.js +139 -2
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +1 -684
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +2 -2
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/test-suite.js +0 -2
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/dwn-error.d.ts +1 -3
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/messages-grant-authorization.d.ts +0 -1
- package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/replication-apply.d.ts +93 -0
- package/dist/types/src/core/replication-apply.d.ts.map +1 -0
- package/dist/types/src/dwn.d.ts +22 -1
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-sync.d.ts +10 -54
- package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +3 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-sync.d.ts +0 -3
- package/dist/types/src/interfaces/messages-sync.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +0 -18
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/tests/core/replication-apply.spec.d.ts +2 -0
- package/dist/types/tests/core/replication-apply.spec.d.ts.map +1 -0
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
- package/dist/types/tests/test-suite.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/dwn-error.ts +1 -3
- package/src/core/messages-grant-authorization.ts +1 -31
- package/src/core/protocol-authorization-validation.ts +2 -2
- package/src/core/replication-apply.ts +272 -0
- package/src/dwn.ts +296 -2
- package/src/handlers/messages-sync.ts +92 -585
- package/src/index.ts +3 -4
- package/src/interfaces/messages-sync.ts +8 -25
- package/src/types/messages-types.ts +0 -20
- package/dist/esm/src/sync/records-projection.js +0 -228
- package/dist/esm/src/sync/records-projection.js.map +0 -1
- package/dist/esm/tests/sync/records-projection.spec.js +0 -245
- package/dist/esm/tests/sync/records-projection.spec.js.map +0 -1
- package/dist/types/src/sync/records-projection.d.ts +0 -98
- package/dist/types/src/sync/records-projection.d.ts.map +0 -1
- package/dist/types/tests/sync/records-projection.spec.d.ts +0 -2
- package/dist/types/tests/sync/records-projection.spec.d.ts.map +0 -1
- package/src/sync/records-projection.ts +0 -328
|
@@ -9,7 +9,7 @@ import { TestDataGenerator } from '../utils/test-data-generator.js';
|
|
|
9
9
|
import { TestEventLog } from '../test-event-stream.js';
|
|
10
10
|
import { TestStores } from '../test-stores.js';
|
|
11
11
|
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
|
|
12
|
-
import { DataStream, Dwn, DwnErrorCode, DwnInterfaceName, DwnMethodName, Encoder, PermissionGrant, PermissionsProtocol,
|
|
12
|
+
import { DataStream, Dwn, DwnErrorCode, DwnInterfaceName, DwnMethodName, Encoder, PermissionGrant, PermissionsProtocol, Time } from '../../src/index.js';
|
|
13
13
|
import { DidKey, UniversalResolver } from '@enbox/dids';
|
|
14
14
|
export function testMessagesSyncHandler() {
|
|
15
15
|
describe('MessagesSyncHandler.handle()', () => {
|
|
@@ -232,126 +232,6 @@ export function testMessagesSyncHandler() {
|
|
|
232
232
|
expect(reply.entries).toContain(protocolCid);
|
|
233
233
|
expect(reply.entries).toContain(recordCid);
|
|
234
234
|
});
|
|
235
|
-
it('returns projected record leaves without protocol configs or out-of-path records', async () => {
|
|
236
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
237
|
-
const protocolDefinition = { ...freeForAll, published: true };
|
|
238
|
-
const protocol = protocolDefinition.protocol;
|
|
239
|
-
const { message: protocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
240
|
-
author: alice,
|
|
241
|
-
protocolDefinition,
|
|
242
|
-
});
|
|
243
|
-
expect((await dwn.processMessage(alice.did, protocolMessage)).status.code).toBe(202);
|
|
244
|
-
const { message: postMessage, dataStream: postDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
245
|
-
author: alice,
|
|
246
|
-
protocol,
|
|
247
|
-
protocolPath: 'post',
|
|
248
|
-
schema: protocolDefinition.types.post.schema,
|
|
249
|
-
});
|
|
250
|
-
expect((await dwn.processMessage(alice.did, postMessage, { dataStream: postDataStream })).status.code).toBe(202);
|
|
251
|
-
const { message: attachmentMessage, dataStream: attachmentDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
252
|
-
author: alice,
|
|
253
|
-
protocol,
|
|
254
|
-
protocolPath: 'post/attachment',
|
|
255
|
-
parentContextId: postMessage.contextId,
|
|
256
|
-
});
|
|
257
|
-
expect((await dwn.processMessage(alice.did, attachmentMessage, { dataStream: attachmentDataStream })).status.code).toBe(202);
|
|
258
|
-
const { message } = await MessagesSync.create({
|
|
259
|
-
signer: Jws.createSigner(alice),
|
|
260
|
-
action: 'leaves',
|
|
261
|
-
prefix: '',
|
|
262
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
263
|
-
projectionScopes: [{ protocol, protocolPath: 'post' }],
|
|
264
|
-
});
|
|
265
|
-
const reply = await dwn.processMessage(alice.did, message);
|
|
266
|
-
expect(reply.status.code).toBe(200);
|
|
267
|
-
expect(reply.entries).toEqual([await Message.getCid(postMessage)]);
|
|
268
|
-
expect(reply.entries).not.toContain(await Message.getCid(protocolMessage));
|
|
269
|
-
expect(reply.entries).not.toContain(await Message.getCid(attachmentMessage));
|
|
270
|
-
});
|
|
271
|
-
it('excludes infrastructure protocols from records-primary projection leaves', async () => {
|
|
272
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
273
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
274
|
-
const { message: permissionGrantMessage, dataStream: permissionGrantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
275
|
-
author: alice,
|
|
276
|
-
grantedTo: bob,
|
|
277
|
-
scope: {
|
|
278
|
-
interface: DwnInterfaceName.Messages,
|
|
279
|
-
method: DwnMethodName.Read,
|
|
280
|
-
protocol: 'http://projected-sync-app-protocol',
|
|
281
|
-
},
|
|
282
|
-
});
|
|
283
|
-
expect((await dwn.processMessage(alice.did, permissionGrantMessage, { dataStream: permissionGrantDataStream })).status.code).toBe(202);
|
|
284
|
-
const keyDeliverySchema = 'https://identity.foundation/schemas/key-delivery/context-key';
|
|
285
|
-
const keyDeliveryProtocolDefinition = {
|
|
286
|
-
protocol: KEY_DELIVERY_PROTOCOL_URI,
|
|
287
|
-
published: false,
|
|
288
|
-
types: {
|
|
289
|
-
contextKey: {
|
|
290
|
-
schema: keyDeliverySchema,
|
|
291
|
-
dataFormats: ['application/json'],
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
|
-
structure: {
|
|
295
|
-
contextKey: {},
|
|
296
|
-
},
|
|
297
|
-
};
|
|
298
|
-
const { message: keyDeliveryConfigureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
299
|
-
author: alice,
|
|
300
|
-
protocolDefinition: keyDeliveryProtocolDefinition,
|
|
301
|
-
});
|
|
302
|
-
expect((await dwn.processMessage(alice.did, keyDeliveryConfigureMessage)).status.code).toBe(202);
|
|
303
|
-
const { message: keyDeliveryMessage, dataStream: keyDeliveryDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
304
|
-
author: alice,
|
|
305
|
-
protocol: KEY_DELIVERY_PROTOCOL_URI,
|
|
306
|
-
protocolPath: 'contextKey',
|
|
307
|
-
schema: keyDeliverySchema,
|
|
308
|
-
});
|
|
309
|
-
expect((await dwn.processMessage(alice.did, keyDeliveryMessage, { dataStream: keyDeliveryDataStream })).status.code).toBe(202);
|
|
310
|
-
for (const protocol of [PermissionsProtocol.uri, KEY_DELIVERY_PROTOCOL_URI]) {
|
|
311
|
-
const { message } = await MessagesSync.create({
|
|
312
|
-
signer: Jws.createSigner(alice),
|
|
313
|
-
action: 'leaves',
|
|
314
|
-
prefix: '',
|
|
315
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
316
|
-
projectionScopes: [{ protocol }],
|
|
317
|
-
});
|
|
318
|
-
const reply = await dwn.processMessage(alice.did, message);
|
|
319
|
-
expect(reply.status.code).toBe(200);
|
|
320
|
-
expect(reply.entries).toEqual([]);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
it('returns projected roots from the Records projection algorithm', async () => {
|
|
324
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
325
|
-
const protocolDefinition = { ...freeForAll, published: true };
|
|
326
|
-
const protocol = protocolDefinition.protocol;
|
|
327
|
-
const projectionScopes = [{ protocol, protocolPath: 'post' }];
|
|
328
|
-
const { message: protocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
329
|
-
author: alice,
|
|
330
|
-
protocolDefinition,
|
|
331
|
-
});
|
|
332
|
-
expect((await dwn.processMessage(alice.did, protocolMessage)).status.code).toBe(202);
|
|
333
|
-
const { message: postMessage, dataStream: postDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
334
|
-
author: alice,
|
|
335
|
-
protocol,
|
|
336
|
-
protocolPath: 'post',
|
|
337
|
-
schema: protocolDefinition.types.post.schema,
|
|
338
|
-
});
|
|
339
|
-
expect((await dwn.processMessage(alice.did, postMessage, { dataStream: postDataStream })).status.code).toBe(202);
|
|
340
|
-
const expectedRoot = await RecordsProjection.getRootHex({
|
|
341
|
-
tenant: alice.did,
|
|
342
|
-
messageStore: messageStore,
|
|
343
|
-
scopes: projectionScopes,
|
|
344
|
-
});
|
|
345
|
-
const { message } = await MessagesSync.create({
|
|
346
|
-
signer: Jws.createSigner(alice),
|
|
347
|
-
action: 'root',
|
|
348
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
349
|
-
projectionScopes,
|
|
350
|
-
});
|
|
351
|
-
const reply = await dwn.processMessage(alice.did, message);
|
|
352
|
-
expect(reply.status.code).toBe(200);
|
|
353
|
-
expect(reply.root).toBe(expectedRoot);
|
|
354
|
-
});
|
|
355
235
|
});
|
|
356
236
|
describe('authorization', () => {
|
|
357
237
|
it('returns 401 if tenant is not the author', async () => {
|
|
@@ -770,427 +650,6 @@ export function testMessagesSyncHandler() {
|
|
|
770
650
|
expect(reply.status.detail).toContain(DwnErrorCode.MessagesGrantAuthorizationMismatchedProtocol);
|
|
771
651
|
}
|
|
772
652
|
});
|
|
773
|
-
it('allows projected sync with a matching protocolPath Messages.Read grant', async () => {
|
|
774
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
775
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
776
|
-
const protocolDefinition = { ...freeForAll, published: true };
|
|
777
|
-
const protocol = protocolDefinition.protocol;
|
|
778
|
-
const { message: protocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
779
|
-
author: alice,
|
|
780
|
-
protocolDefinition,
|
|
781
|
-
});
|
|
782
|
-
expect((await dwn.processMessage(alice.did, protocolMessage)).status.code).toBe(202);
|
|
783
|
-
const { message: postMessage, dataStream: postDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
784
|
-
author: alice,
|
|
785
|
-
protocol,
|
|
786
|
-
protocolPath: 'post',
|
|
787
|
-
schema: protocolDefinition.types.post.schema,
|
|
788
|
-
});
|
|
789
|
-
expect((await dwn.processMessage(alice.did, postMessage, { dataStream: postDataStream })).status.code).toBe(202);
|
|
790
|
-
const { message: attachmentMessage, dataStream: attachmentDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
791
|
-
author: alice,
|
|
792
|
-
protocol,
|
|
793
|
-
protocolPath: 'post/attachment',
|
|
794
|
-
parentContextId: postMessage.contextId,
|
|
795
|
-
});
|
|
796
|
-
expect((await dwn.processMessage(alice.did, attachmentMessage, { dataStream: attachmentDataStream })).status.code).toBe(202);
|
|
797
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
798
|
-
author: alice,
|
|
799
|
-
grantedTo: bob,
|
|
800
|
-
scope: {
|
|
801
|
-
interface: DwnInterfaceName.Messages,
|
|
802
|
-
method: DwnMethodName.Read,
|
|
803
|
-
protocol,
|
|
804
|
-
protocolPath: 'post',
|
|
805
|
-
},
|
|
806
|
-
});
|
|
807
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
808
|
-
const { message: diffMsg } = await MessagesSync.create({
|
|
809
|
-
signer: Jws.createSigner(bob),
|
|
810
|
-
action: 'diff',
|
|
811
|
-
hashes: {},
|
|
812
|
-
depth: 2,
|
|
813
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
814
|
-
projectionScopes: [{ protocol, protocolPath: 'post' }],
|
|
815
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
816
|
-
});
|
|
817
|
-
const reply = await dwn.processMessage(alice.did, diffMsg);
|
|
818
|
-
expect(reply.status.code).toBe(200);
|
|
819
|
-
const protocolCid = await Message.getCid(protocolMessage);
|
|
820
|
-
const postCid = await Message.getCid(postMessage);
|
|
821
|
-
const remoteCids = reply.onlyRemote.map(entry => entry.messageCid);
|
|
822
|
-
expect(remoteCids).toContain(postCid);
|
|
823
|
-
expect(remoteCids).not.toContain(protocolCid);
|
|
824
|
-
expect(remoteCids).not.toContain(await Message.getCid(attachmentMessage));
|
|
825
|
-
expect(reply.dependencies).toEqual([{
|
|
826
|
-
dependencyClass: 'protocolsConfigure',
|
|
827
|
-
messageCid: protocolCid,
|
|
828
|
-
message: protocolMessage,
|
|
829
|
-
rootMessageCid: postCid,
|
|
830
|
-
}]);
|
|
831
|
-
});
|
|
832
|
-
it('returns the governing protocol config dependency for projected sync', async () => {
|
|
833
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
834
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
835
|
-
const protocol = 'http://projected-sync-config-history';
|
|
836
|
-
const protocolDefinition = {
|
|
837
|
-
...freeForAll,
|
|
838
|
-
protocol,
|
|
839
|
-
published: true,
|
|
840
|
-
};
|
|
841
|
-
const { message: firstProtocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
842
|
-
author: alice,
|
|
843
|
-
messageTimestamp: '2026-01-01T00:00:00.000000Z',
|
|
844
|
-
protocolDefinition,
|
|
845
|
-
});
|
|
846
|
-
expect((await dwn.processMessage(alice.did, firstProtocolMessage)).status.code).toBe(202);
|
|
847
|
-
const { message: secondProtocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
848
|
-
author: alice,
|
|
849
|
-
messageTimestamp: '2026-01-02T00:00:00.000000Z',
|
|
850
|
-
protocolDefinition,
|
|
851
|
-
});
|
|
852
|
-
expect((await dwn.processMessage(alice.did, secondProtocolMessage)).status.code).toBe(202);
|
|
853
|
-
const { message: postMessage, dataStream: postDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
854
|
-
author: alice,
|
|
855
|
-
dateCreated: '2026-01-03T00:00:00.000000Z',
|
|
856
|
-
messageTimestamp: '2026-01-03T00:00:00.000000Z',
|
|
857
|
-
protocol,
|
|
858
|
-
protocolPath: 'post',
|
|
859
|
-
schema: protocolDefinition.types.post.schema,
|
|
860
|
-
});
|
|
861
|
-
expect((await dwn.processMessage(alice.did, postMessage, { dataStream: postDataStream })).status.code).toBe(202);
|
|
862
|
-
const { message: futureProtocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
863
|
-
author: alice,
|
|
864
|
-
messageTimestamp: '2026-01-04T00:00:00.000000Z',
|
|
865
|
-
protocolDefinition,
|
|
866
|
-
});
|
|
867
|
-
expect((await dwn.processMessage(alice.did, futureProtocolMessage)).status.code).toBe(202);
|
|
868
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
869
|
-
author: alice,
|
|
870
|
-
grantedTo: bob,
|
|
871
|
-
scope: {
|
|
872
|
-
interface: DwnInterfaceName.Messages,
|
|
873
|
-
method: DwnMethodName.Read,
|
|
874
|
-
protocol,
|
|
875
|
-
protocolPath: 'post',
|
|
876
|
-
},
|
|
877
|
-
});
|
|
878
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
879
|
-
const { message: diffMsg } = await MessagesSync.create({
|
|
880
|
-
signer: Jws.createSigner(bob),
|
|
881
|
-
action: 'diff',
|
|
882
|
-
hashes: {},
|
|
883
|
-
depth: 2,
|
|
884
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
885
|
-
projectionScopes: [{ protocol, protocolPath: 'post' }],
|
|
886
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
887
|
-
});
|
|
888
|
-
const reply = await dwn.processMessage(alice.did, diffMsg);
|
|
889
|
-
expect(reply.status.code).toBe(200);
|
|
890
|
-
const postCid = await Message.getCid(postMessage);
|
|
891
|
-
expect(reply.onlyRemote.map(entry => entry.messageCid)).toContain(postCid);
|
|
892
|
-
expect(reply.dependencies.map(entry => entry.messageCid)).not.toContain(await Message.getCid(firstProtocolMessage));
|
|
893
|
-
expect(reply.dependencies.map(entry => entry.messageCid)).not.toContain(await Message.getCid(futureProtocolMessage));
|
|
894
|
-
expect(reply.dependencies).toEqual([
|
|
895
|
-
{
|
|
896
|
-
dependencyClass: 'protocolsConfigure',
|
|
897
|
-
messageCid: await Message.getCid(secondProtocolMessage),
|
|
898
|
-
message: secondProtocolMessage,
|
|
899
|
-
rootMessageCid: postCid,
|
|
900
|
-
},
|
|
901
|
-
]);
|
|
902
|
-
});
|
|
903
|
-
it('returns initial write and protocol config dependencies for projected delete tombstones', async () => {
|
|
904
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
905
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
906
|
-
const protocolDefinition = { ...freeForAll, protocol: 'http://projected-sync-delete-hints', published: true };
|
|
907
|
-
const unrelatedDefinition = { ...freeForAll, protocol: 'http://projected-sync-delete-hints-unrelated', published: true };
|
|
908
|
-
const protocol = protocolDefinition.protocol;
|
|
909
|
-
const { message: protocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
910
|
-
author: alice,
|
|
911
|
-
protocolDefinition,
|
|
912
|
-
});
|
|
913
|
-
expect((await dwn.processMessage(alice.did, protocolMessage)).status.code).toBe(202);
|
|
914
|
-
const { message: unrelatedProtocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
915
|
-
author: alice,
|
|
916
|
-
protocolDefinition: unrelatedDefinition,
|
|
917
|
-
});
|
|
918
|
-
expect((await dwn.processMessage(alice.did, unrelatedProtocolMessage)).status.code).toBe(202);
|
|
919
|
-
const { message: postMessage, dataStream: postDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
920
|
-
author: alice,
|
|
921
|
-
protocol,
|
|
922
|
-
protocolPath: 'post',
|
|
923
|
-
schema: protocolDefinition.types.post.schema,
|
|
924
|
-
});
|
|
925
|
-
expect((await dwn.processMessage(alice.did, postMessage, { dataStream: postDataStream })).status.code).toBe(202);
|
|
926
|
-
const { message: deleteMessage } = await TestDataGenerator.generateRecordsDelete({
|
|
927
|
-
author: alice,
|
|
928
|
-
recordId: postMessage.recordId,
|
|
929
|
-
});
|
|
930
|
-
expect((await dwn.processMessage(alice.did, deleteMessage)).status.code).toBe(202);
|
|
931
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
932
|
-
author: alice,
|
|
933
|
-
grantedTo: bob,
|
|
934
|
-
scope: {
|
|
935
|
-
interface: DwnInterfaceName.Messages,
|
|
936
|
-
method: DwnMethodName.Read,
|
|
937
|
-
protocol,
|
|
938
|
-
protocolPath: 'post',
|
|
939
|
-
},
|
|
940
|
-
});
|
|
941
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
942
|
-
const { message: diffMsg } = await MessagesSync.create({
|
|
943
|
-
signer: Jws.createSigner(bob),
|
|
944
|
-
action: 'diff',
|
|
945
|
-
hashes: {},
|
|
946
|
-
depth: 2,
|
|
947
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
948
|
-
projectionScopes: [{ protocol, protocolPath: 'post' }],
|
|
949
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
950
|
-
});
|
|
951
|
-
const reply = await dwn.processMessage(alice.did, diffMsg);
|
|
952
|
-
expect(reply.status.code).toBe(200);
|
|
953
|
-
const deleteCid = await Message.getCid(deleteMessage);
|
|
954
|
-
const postCid = await Message.getCid(postMessage);
|
|
955
|
-
const protocolCid = await Message.getCid(protocolMessage);
|
|
956
|
-
expect(reply.onlyRemote.map(entry => entry.messageCid)).toEqual([deleteCid]);
|
|
957
|
-
expect(reply.dependencies.map(entry => entry.messageCid)).not.toContain(await Message.getCid(unrelatedProtocolMessage));
|
|
958
|
-
expect(reply.dependencies).toEqual([
|
|
959
|
-
{
|
|
960
|
-
dependencyClass: 'recordsInitialWrite',
|
|
961
|
-
messageCid: postCid,
|
|
962
|
-
message: postMessage,
|
|
963
|
-
rootMessageCid: deleteCid,
|
|
964
|
-
},
|
|
965
|
-
{
|
|
966
|
-
dependencyClass: 'protocolsConfigure',
|
|
967
|
-
messageCid: protocolCid,
|
|
968
|
-
message: protocolMessage,
|
|
969
|
-
rootMessageCid: deleteCid,
|
|
970
|
-
},
|
|
971
|
-
]);
|
|
972
|
-
const initialWriteDependency = reply.dependencies.find(entry => entry.dependencyClass === 'recordsInitialWrite');
|
|
973
|
-
expect(initialWriteDependency.encodedData).toBeUndefined();
|
|
974
|
-
expect('encodedData' in initialWriteDependency.message).toBe(false);
|
|
975
|
-
});
|
|
976
|
-
it('returns composed protocol config dependencies for projected sync', async () => {
|
|
977
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
978
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
979
|
-
const socialDefinition = {
|
|
980
|
-
...freeForAll,
|
|
981
|
-
protocol: 'http://projected-sync-composed-social',
|
|
982
|
-
published: true,
|
|
983
|
-
};
|
|
984
|
-
const profileDefinition = {
|
|
985
|
-
...freeForAll,
|
|
986
|
-
protocol: 'http://projected-sync-composed-profile',
|
|
987
|
-
published: true,
|
|
988
|
-
uses: { social: socialDefinition.protocol },
|
|
989
|
-
};
|
|
990
|
-
const unrelatedDefinition = {
|
|
991
|
-
...freeForAll,
|
|
992
|
-
protocol: 'http://projected-sync-composed-unrelated',
|
|
993
|
-
published: true,
|
|
994
|
-
};
|
|
995
|
-
const { message: socialProtocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
996
|
-
author: alice,
|
|
997
|
-
protocolDefinition: socialDefinition,
|
|
998
|
-
});
|
|
999
|
-
expect((await dwn.processMessage(alice.did, socialProtocolMessage)).status.code).toBe(202);
|
|
1000
|
-
const { message: profileProtocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
1001
|
-
author: alice,
|
|
1002
|
-
protocolDefinition: profileDefinition,
|
|
1003
|
-
});
|
|
1004
|
-
expect((await dwn.processMessage(alice.did, profileProtocolMessage)).status.code).toBe(202);
|
|
1005
|
-
const { message: unrelatedProtocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
1006
|
-
author: alice,
|
|
1007
|
-
protocolDefinition: unrelatedDefinition,
|
|
1008
|
-
});
|
|
1009
|
-
expect((await dwn.processMessage(alice.did, unrelatedProtocolMessage)).status.code).toBe(202);
|
|
1010
|
-
const { message: postMessage, dataStream: postDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
1011
|
-
author: alice,
|
|
1012
|
-
protocol: profileDefinition.protocol,
|
|
1013
|
-
protocolPath: 'post',
|
|
1014
|
-
schema: profileDefinition.types.post.schema,
|
|
1015
|
-
});
|
|
1016
|
-
expect((await dwn.processMessage(alice.did, postMessage, { dataStream: postDataStream })).status.code).toBe(202);
|
|
1017
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
1018
|
-
author: alice,
|
|
1019
|
-
grantedTo: bob,
|
|
1020
|
-
scope: {
|
|
1021
|
-
interface: DwnInterfaceName.Messages,
|
|
1022
|
-
method: DwnMethodName.Read,
|
|
1023
|
-
protocol: profileDefinition.protocol,
|
|
1024
|
-
protocolPath: 'post',
|
|
1025
|
-
},
|
|
1026
|
-
});
|
|
1027
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
1028
|
-
const { message: diffMsg } = await MessagesSync.create({
|
|
1029
|
-
signer: Jws.createSigner(bob),
|
|
1030
|
-
action: 'diff',
|
|
1031
|
-
hashes: {},
|
|
1032
|
-
depth: 2,
|
|
1033
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1034
|
-
projectionScopes: [{ protocol: profileDefinition.protocol, protocolPath: 'post' }],
|
|
1035
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
1036
|
-
});
|
|
1037
|
-
const reply = await dwn.processMessage(alice.did, diffMsg);
|
|
1038
|
-
expect(reply.status.code).toBe(200);
|
|
1039
|
-
const postCid = await Message.getCid(postMessage);
|
|
1040
|
-
expect(reply.onlyRemote.map(entry => entry.messageCid)).toContain(postCid);
|
|
1041
|
-
expect(reply.dependencies.map(entry => entry.messageCid)).not.toContain(await Message.getCid(unrelatedProtocolMessage));
|
|
1042
|
-
expect(reply.dependencies).toEqual([
|
|
1043
|
-
{
|
|
1044
|
-
dependencyClass: 'protocolsConfigure',
|
|
1045
|
-
messageCid: await Message.getCid(profileProtocolMessage),
|
|
1046
|
-
message: profileProtocolMessage,
|
|
1047
|
-
rootMessageCid: postCid,
|
|
1048
|
-
},
|
|
1049
|
-
{
|
|
1050
|
-
dependencyClass: 'protocolsConfigure',
|
|
1051
|
-
messageCid: await Message.getCid(socialProtocolMessage),
|
|
1052
|
-
message: socialProtocolMessage,
|
|
1053
|
-
rootMessageCid: postCid,
|
|
1054
|
-
},
|
|
1055
|
-
]);
|
|
1056
|
-
});
|
|
1057
|
-
it('terminates cyclic composed protocol dependencies for projected sync', async () => {
|
|
1058
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1059
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
1060
|
-
const protocolA = 'http://projected-sync-cycle-a';
|
|
1061
|
-
const protocolB = 'http://projected-sync-cycle-b';
|
|
1062
|
-
const protocolBBaseDefinition = {
|
|
1063
|
-
...freeForAll,
|
|
1064
|
-
protocol: protocolB,
|
|
1065
|
-
published: true,
|
|
1066
|
-
};
|
|
1067
|
-
const protocolADefinition = {
|
|
1068
|
-
...freeForAll,
|
|
1069
|
-
protocol: protocolA,
|
|
1070
|
-
published: true,
|
|
1071
|
-
uses: { b: protocolB },
|
|
1072
|
-
};
|
|
1073
|
-
const protocolBCycleDefinition = {
|
|
1074
|
-
...freeForAll,
|
|
1075
|
-
protocol: protocolB,
|
|
1076
|
-
published: true,
|
|
1077
|
-
uses: { a: protocolA },
|
|
1078
|
-
};
|
|
1079
|
-
const { message: protocolBBaseMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
1080
|
-
author: alice,
|
|
1081
|
-
messageTimestamp: '2026-01-01T00:00:00.000000Z',
|
|
1082
|
-
protocolDefinition: protocolBBaseDefinition,
|
|
1083
|
-
});
|
|
1084
|
-
expect((await dwn.processMessage(alice.did, protocolBBaseMessage)).status.code).toBe(202);
|
|
1085
|
-
const { message: protocolAMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
1086
|
-
author: alice,
|
|
1087
|
-
messageTimestamp: '2026-01-02T00:00:00.000000Z',
|
|
1088
|
-
protocolDefinition: protocolADefinition,
|
|
1089
|
-
});
|
|
1090
|
-
expect((await dwn.processMessage(alice.did, protocolAMessage)).status.code).toBe(202);
|
|
1091
|
-
const { message: protocolBCycleMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
1092
|
-
author: alice,
|
|
1093
|
-
messageTimestamp: '2026-01-03T00:00:00.000000Z',
|
|
1094
|
-
protocolDefinition: protocolBCycleDefinition,
|
|
1095
|
-
});
|
|
1096
|
-
expect((await dwn.processMessage(alice.did, protocolBCycleMessage)).status.code).toBe(202);
|
|
1097
|
-
const { message: postMessage, dataStream: postDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
1098
|
-
author: alice,
|
|
1099
|
-
dateCreated: '2026-01-04T00:00:00.000000Z',
|
|
1100
|
-
messageTimestamp: '2026-01-04T00:00:00.000000Z',
|
|
1101
|
-
protocol: protocolA,
|
|
1102
|
-
protocolPath: 'post',
|
|
1103
|
-
schema: protocolADefinition.types.post.schema,
|
|
1104
|
-
});
|
|
1105
|
-
expect((await dwn.processMessage(alice.did, postMessage, { dataStream: postDataStream })).status.code).toBe(202);
|
|
1106
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
1107
|
-
author: alice,
|
|
1108
|
-
grantedTo: bob,
|
|
1109
|
-
scope: {
|
|
1110
|
-
interface: DwnInterfaceName.Messages,
|
|
1111
|
-
method: DwnMethodName.Read,
|
|
1112
|
-
protocol: protocolA,
|
|
1113
|
-
protocolPath: 'post',
|
|
1114
|
-
},
|
|
1115
|
-
});
|
|
1116
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
1117
|
-
const { message: diffMsg } = await MessagesSync.create({
|
|
1118
|
-
signer: Jws.createSigner(bob),
|
|
1119
|
-
action: 'diff',
|
|
1120
|
-
hashes: {},
|
|
1121
|
-
depth: 2,
|
|
1122
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1123
|
-
projectionScopes: [{ protocol: protocolA, protocolPath: 'post' }],
|
|
1124
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
1125
|
-
});
|
|
1126
|
-
const reply = await dwn.processMessage(alice.did, diffMsg);
|
|
1127
|
-
expect(reply.status.code).toBe(200);
|
|
1128
|
-
const postCid = await Message.getCid(postMessage);
|
|
1129
|
-
const dependencyCids = reply.dependencies.map(entry => entry.messageCid);
|
|
1130
|
-
expect(reply.onlyRemote.map(entry => entry.messageCid)).toContain(postCid);
|
|
1131
|
-
expect(dependencyCids.sort()).toEqual([
|
|
1132
|
-
await Message.getCid(protocolAMessage),
|
|
1133
|
-
await Message.getCid(protocolBCycleMessage),
|
|
1134
|
-
].sort());
|
|
1135
|
-
expect(dependencyCids).not.toContain(await Message.getCid(protocolBBaseMessage));
|
|
1136
|
-
expect(reply.dependencies.every(entry => entry.rootMessageCid === postCid)).toBe(true);
|
|
1137
|
-
});
|
|
1138
|
-
it('rejects projected sync when no grant covers a requested projection scope', async () => {
|
|
1139
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1140
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
1141
|
-
const protocol = 'http://projected-sync-scope-mismatch';
|
|
1142
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
1143
|
-
author: alice,
|
|
1144
|
-
grantedTo: bob,
|
|
1145
|
-
scope: {
|
|
1146
|
-
interface: DwnInterfaceName.Messages,
|
|
1147
|
-
method: DwnMethodName.Read,
|
|
1148
|
-
protocol,
|
|
1149
|
-
protocolPath: 'post',
|
|
1150
|
-
},
|
|
1151
|
-
});
|
|
1152
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
1153
|
-
const { message: syncMsg } = await MessagesSync.create({
|
|
1154
|
-
signer: Jws.createSigner(bob),
|
|
1155
|
-
action: 'root',
|
|
1156
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1157
|
-
projectionScopes: [{ protocol }],
|
|
1158
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
1159
|
-
});
|
|
1160
|
-
const reply = await dwn.processMessage(alice.did, syncMsg);
|
|
1161
|
-
expect(reply.status.code).toBe(401);
|
|
1162
|
-
expect(reply.status.detail).toContain(DwnErrorCode.MessagesGrantAuthorizationProjectionScopeMismatch);
|
|
1163
|
-
});
|
|
1164
|
-
it('rejects projected sync when any requested projection scope is uncovered', async () => {
|
|
1165
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1166
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
1167
|
-
const coveredProtocol = 'http://projected-sync-covered-scope';
|
|
1168
|
-
const uncoveredProtocol = 'http://projected-sync-uncovered-scope';
|
|
1169
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
1170
|
-
author: alice,
|
|
1171
|
-
grantedTo: bob,
|
|
1172
|
-
scope: {
|
|
1173
|
-
interface: DwnInterfaceName.Messages,
|
|
1174
|
-
method: DwnMethodName.Read,
|
|
1175
|
-
protocol: coveredProtocol,
|
|
1176
|
-
protocolPath: 'post',
|
|
1177
|
-
},
|
|
1178
|
-
});
|
|
1179
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
1180
|
-
const { message: syncMsg } = await MessagesSync.create({
|
|
1181
|
-
signer: Jws.createSigner(bob),
|
|
1182
|
-
action: 'root',
|
|
1183
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1184
|
-
projectionScopes: [
|
|
1185
|
-
{ protocol: coveredProtocol, protocolPath: 'post' },
|
|
1186
|
-
{ protocol: uncoveredProtocol, protocolPath: 'post' },
|
|
1187
|
-
],
|
|
1188
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
1189
|
-
});
|
|
1190
|
-
const reply = await dwn.processMessage(alice.did, syncMsg);
|
|
1191
|
-
expect(reply.status.code).toBe(401);
|
|
1192
|
-
expect(reply.status.detail).toContain(DwnErrorCode.MessagesGrantAuthorizationProjectionScopeMismatch);
|
|
1193
|
-
});
|
|
1194
653
|
it('rejects delegated MessagesSync of infrastructure protocols', async () => {
|
|
1195
654
|
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1196
655
|
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
@@ -1256,77 +715,6 @@ export function testMessagesSyncHandler() {
|
|
|
1256
715
|
expect(syncReply.status.detail).toContain(DwnErrorCode.MessagesGrantAuthorizationProtocolSyncInfrastructureProtocol);
|
|
1257
716
|
}
|
|
1258
717
|
}
|
|
1259
|
-
for (const { protocol, grantId } of infrastructureProtocolGrants) {
|
|
1260
|
-
const { message: projectedSyncMessage } = await MessagesSync.create({
|
|
1261
|
-
signer: Jws.createSigner(bob),
|
|
1262
|
-
action: 'diff',
|
|
1263
|
-
hashes: {},
|
|
1264
|
-
depth: 2,
|
|
1265
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1266
|
-
projectionScopes: [{ protocol }],
|
|
1267
|
-
permissionGrantIds: [grantId],
|
|
1268
|
-
});
|
|
1269
|
-
const projectedSyncReply = await dwn.processMessage(alice.did, projectedSyncMessage);
|
|
1270
|
-
expect(projectedSyncReply.status.code).toBe(401);
|
|
1271
|
-
expect(projectedSyncReply.status.detail).toContain(DwnErrorCode.MessagesGrantAuthorizationProjectionInfrastructureProtocol);
|
|
1272
|
-
}
|
|
1273
|
-
});
|
|
1274
|
-
it('allows projected sync with a matching contextId Messages.Read grant', async () => {
|
|
1275
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1276
|
-
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
1277
|
-
const protocolDefinition = { ...freeForAll, published: true };
|
|
1278
|
-
const protocol = protocolDefinition.protocol;
|
|
1279
|
-
const { message: protocolMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
1280
|
-
author: alice,
|
|
1281
|
-
protocolDefinition,
|
|
1282
|
-
});
|
|
1283
|
-
expect((await dwn.processMessage(alice.did, protocolMessage)).status.code).toBe(202);
|
|
1284
|
-
const { message: rootMessage, dataStream: rootDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
1285
|
-
author: alice,
|
|
1286
|
-
protocol,
|
|
1287
|
-
protocolPath: 'post',
|
|
1288
|
-
schema: protocolDefinition.types.post.schema,
|
|
1289
|
-
});
|
|
1290
|
-
expect((await dwn.processMessage(alice.did, rootMessage, { dataStream: rootDataStream })).status.code).toBe(202);
|
|
1291
|
-
const { message: childMessage, dataStream: childDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
1292
|
-
author: alice,
|
|
1293
|
-
protocol,
|
|
1294
|
-
protocolPath: 'post/attachment',
|
|
1295
|
-
parentContextId: rootMessage.contextId,
|
|
1296
|
-
});
|
|
1297
|
-
expect((await dwn.processMessage(alice.did, childMessage, { dataStream: childDataStream })).status.code).toBe(202);
|
|
1298
|
-
const { message: siblingMessage, dataStream: siblingDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
1299
|
-
author: alice,
|
|
1300
|
-
protocol,
|
|
1301
|
-
protocolPath: 'post',
|
|
1302
|
-
schema: protocolDefinition.types.post.schema,
|
|
1303
|
-
});
|
|
1304
|
-
expect((await dwn.processMessage(alice.did, siblingMessage, { dataStream: siblingDataStream })).status.code).toBe(202);
|
|
1305
|
-
const { message: grantMessage, dataStream: grantDataStream } = await TestDataGenerator.generateGrantCreate({
|
|
1306
|
-
author: alice,
|
|
1307
|
-
grantedTo: bob,
|
|
1308
|
-
scope: {
|
|
1309
|
-
interface: DwnInterfaceName.Messages,
|
|
1310
|
-
method: DwnMethodName.Read,
|
|
1311
|
-
protocol,
|
|
1312
|
-
contextId: rootMessage.contextId,
|
|
1313
|
-
},
|
|
1314
|
-
});
|
|
1315
|
-
expect((await dwn.processMessage(alice.did, grantMessage, { dataStream: grantDataStream })).status.code).toBe(202);
|
|
1316
|
-
const { message: syncMsg } = await MessagesSync.create({
|
|
1317
|
-
signer: Jws.createSigner(bob),
|
|
1318
|
-
action: 'leaves',
|
|
1319
|
-
prefix: '',
|
|
1320
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1321
|
-
projectionScopes: [{ protocol, contextId: rootMessage.contextId }],
|
|
1322
|
-
permissionGrantIds: [grantMessage.recordId],
|
|
1323
|
-
});
|
|
1324
|
-
const reply = await dwn.processMessage(alice.did, syncMsg);
|
|
1325
|
-
expect(reply.status.code).toBe(200);
|
|
1326
|
-
expect(reply.entries).toContain(await Message.getCid(rootMessage));
|
|
1327
|
-
expect(reply.entries).toContain(await Message.getCid(childMessage));
|
|
1328
|
-
expect(reply.entries).not.toContain(await Message.getCid(protocolMessage));
|
|
1329
|
-
expect(reply.entries).not.toContain(await Message.getCid(siblingMessage));
|
|
1330
718
|
});
|
|
1331
719
|
it('returns only protocol-scoped diff entries for a delegated protocol grant', async () => {
|
|
1332
720
|
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
@@ -1476,77 +864,6 @@ export function testMessagesSyncHandler() {
|
|
|
1476
864
|
parseStub.restore();
|
|
1477
865
|
}
|
|
1478
866
|
});
|
|
1479
|
-
it('returns 400 when projection scopes are provided without a projection root version', async () => {
|
|
1480
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1481
|
-
const { message } = await MessagesSync.create({
|
|
1482
|
-
signer: Jws.createSigner(alice),
|
|
1483
|
-
action: 'root',
|
|
1484
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1485
|
-
projectionScopes: [{ protocol: 'http://projected-sync-schema' }],
|
|
1486
|
-
});
|
|
1487
|
-
delete message.descriptor.projectionRootVersion;
|
|
1488
|
-
const reply = await dwn.processMessage(alice.did, message);
|
|
1489
|
-
expect(reply.status.code).toBe(400);
|
|
1490
|
-
expect(reply.status.detail).toContain('SchemaValidatorFailure');
|
|
1491
|
-
});
|
|
1492
|
-
it('returns 400 when projection root version is provided without projection scopes', async () => {
|
|
1493
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1494
|
-
const { message } = await MessagesSync.create({
|
|
1495
|
-
signer: Jws.createSigner(alice),
|
|
1496
|
-
action: 'root',
|
|
1497
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1498
|
-
projectionScopes: [{ protocol: 'http://projected-sync-schema' }],
|
|
1499
|
-
});
|
|
1500
|
-
delete message.descriptor.projectionScopes;
|
|
1501
|
-
const reply = await dwn.processMessage(alice.did, message);
|
|
1502
|
-
expect(reply.status.code).toBe(400);
|
|
1503
|
-
expect(reply.status.detail).toContain('SchemaValidatorFailure');
|
|
1504
|
-
});
|
|
1505
|
-
it('returns 400 when projection root version is unsupported', async () => {
|
|
1506
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1507
|
-
const { message } = await MessagesSync.create({
|
|
1508
|
-
signer: Jws.createSigner(alice),
|
|
1509
|
-
action: 'root',
|
|
1510
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1511
|
-
projectionScopes: [{ protocol: 'http://projected-sync-schema' }],
|
|
1512
|
-
});
|
|
1513
|
-
const unsupportedProjectionRootVersion = 'records-primary-scope-root-v2';
|
|
1514
|
-
const descriptor = {
|
|
1515
|
-
...message.descriptor,
|
|
1516
|
-
projectionRootVersion: unsupportedProjectionRootVersion,
|
|
1517
|
-
};
|
|
1518
|
-
const authorization = await Message.createAuthorization({
|
|
1519
|
-
descriptor,
|
|
1520
|
-
signer: Jws.createSigner(alice),
|
|
1521
|
-
});
|
|
1522
|
-
const unsupportedVersionMessage = {
|
|
1523
|
-
...message,
|
|
1524
|
-
descriptor,
|
|
1525
|
-
authorization,
|
|
1526
|
-
};
|
|
1527
|
-
const validateJsonSchemaStub = sinon.stub(Message, 'validateJsonSchema');
|
|
1528
|
-
try {
|
|
1529
|
-
const reply = await dwn.processMessage(alice.did, unsupportedVersionMessage);
|
|
1530
|
-
expect(reply.status.code).toBe(400);
|
|
1531
|
-
expect(reply.status.detail).toContain(DwnErrorCode.MessagesSyncUnsupportedProjectionRootVersion);
|
|
1532
|
-
}
|
|
1533
|
-
finally {
|
|
1534
|
-
validateJsonSchemaStub.restore();
|
|
1535
|
-
}
|
|
1536
|
-
});
|
|
1537
|
-
it('returns 400 when projected sync also specifies a protocol root', async () => {
|
|
1538
|
-
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
1539
|
-
const { message } = await MessagesSync.create({
|
|
1540
|
-
signer: Jws.createSigner(alice),
|
|
1541
|
-
action: 'root',
|
|
1542
|
-
projectionRootVersion: RECORDS_PROJECTION_ROOT_VERSION,
|
|
1543
|
-
projectionScopes: [{ protocol: 'http://projected-sync-schema' }],
|
|
1544
|
-
});
|
|
1545
|
-
message.descriptor.protocol = 'http://projected-sync-schema';
|
|
1546
|
-
const reply = await dwn.processMessage(alice.did, message);
|
|
1547
|
-
expect(reply.status.code).toBe(400);
|
|
1548
|
-
expect(reply.status.detail).toContain('SchemaValidatorFailure');
|
|
1549
|
-
});
|
|
1550
867
|
});
|
|
1551
868
|
describe('diff action', () => {
|
|
1552
869
|
it('returns empty diff when client hashes match server hashes', async () => {
|