@enbox/dwn-sdk-js 0.4.2 → 0.4.3

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.
Files changed (37) hide show
  1. package/dist/browser.mjs +3 -3
  2. package/dist/browser.mjs.map +3 -3
  3. package/dist/esm/generated/precompiled-validators.js +1065 -2160
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/grant-authorization.js +14 -1
  6. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  7. package/dist/esm/src/types/permission-types.js.map +1 -1
  8. package/dist/esm/tests/core/grant-authorization.spec.js +82 -4
  9. package/dist/esm/tests/core/grant-authorization.spec.js.map +1 -1
  10. package/dist/esm/tests/core/records-grant-authorization.spec.js +22 -5
  11. package/dist/esm/tests/core/records-grant-authorization.spec.js.map +1 -1
  12. package/dist/esm/tests/features/author-delegated-grant.spec.js +134 -10
  13. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  14. package/dist/esm/tests/features/permissions.spec.js +6 -6
  15. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  16. package/dist/esm/tests/handlers/records-count.spec.js +2 -2
  17. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  18. package/dist/esm/tests/handlers/records-query.spec.js +2 -2
  19. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  20. package/dist/esm/tests/handlers/records-read.spec.js +8 -2
  21. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  22. package/dist/esm/tests/handlers/records-subscribe.spec.js +2 -2
  23. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  24. package/dist/esm/tests/protocols/permission-request.spec.js +4 -4
  25. package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
  26. package/dist/esm/tests/protocols/permissions.spec.js +35 -2
  27. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  28. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  29. package/dist/types/src/core/grant-authorization.d.ts +2 -1
  30. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  31. package/dist/types/src/types/permission-types.d.ts +4 -1
  32. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  33. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  34. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  35. package/package.json +1 -1
  36. package/src/core/grant-authorization.ts +18 -1
  37. package/src/types/permission-types.ts +4 -1
@@ -62,7 +62,8 @@ export class GrantAuthorization {
62
62
  * Verify that the `interface` and `method` grant scopes match the incoming message.
63
63
  *
64
64
  * For the Messages interface, a `Read` scope is treated as a unified scope that also authorizes
65
- * `Query`, `Subscribe`, and `Sync` operations.
65
+ * `Query` and `Subscribe` operations. For Records, `Read` is likewise the canonical read-like
66
+ * scope and authorizes `Read`, `Query`, `Subscribe`, and `Count` operations.
66
67
  *
67
68
  * @throws {DwnError} if the `interface` and `method` of the incoming message do not match the scope of the permission grant.
68
69
  */
@@ -82,6 +83,18 @@ export class GrantAuthorization {
82
83
  }
83
84
  return;
84
85
  }
86
+ // Records.Read is the only valid read-like Records scope and covers Read, Query,
87
+ // Subscribe, and Count operations. Reject malformed Records Query/Subscribe/Count
88
+ // grants instead of treating them as compatible with the canonical Read scope.
89
+ if (dwnInterface === DwnInterfaceName.Records) {
90
+ const readLikeMethods = [DwnMethodName.Read, DwnMethodName.Query, DwnMethodName.Subscribe, DwnMethodName.Count];
91
+ if (readLikeMethods.includes(dwnMethod)) {
92
+ if (permissionGrant.scope.method !== DwnMethodName.Read) {
93
+ throw new DwnError(DwnErrorCode.GrantAuthorizationMethodMismatch, `records read-like permission grant must have method 'Read', got '${permissionGrant.scope.method}' for grant ${permissionGrant.id}`);
94
+ }
95
+ return;
96
+ }
97
+ }
85
98
  if (dwnMethod !== permissionGrant.scope.method) {
86
99
  throw new DwnError(DwnErrorCode.GrantAuthorizationMethodMismatch, `DWN Method of incoming message is outside the scope of permission grant with ID ${permissionGrant.id}`);
87
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"grant-authorization.js","sourceRoot":"","sources":["../../../../src/core/grant-authorization.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"grant-authorization.js","sourceRoot":"","sources":["../../../../src/core/grant-authorization.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"permission-types.js","sourceRoot":"","sources":["../../../../src/types/permission-types.ts"],"names":[],"mappings":"AAqHA,MAAM,CAAN,IAAY,8BAGX;AAHD,WAAY,8BAA8B;IACxC,uDAAqB,CAAA;IACrB,2DAAyB,CAAA;AAC3B,CAAC,EAHW,8BAA8B,KAA9B,8BAA8B,QAGzC"}
1
+ {"version":3,"file":"permission-types.js","sourceRoot":"","sources":["../../../../src/types/permission-types.ts"],"names":[],"mappings":"AAwHA,MAAM,CAAN,IAAY,8BAGX;AAHD,WAAY,8BAA8B;IACxC,uDAAqB,CAAA;IACrB,2DAAyB,CAAA;AAC3B,CAAC,EAHW,8BAA8B,KAA9B,8BAA8B,QAGzC"}
@@ -32,7 +32,59 @@ describe('GrantAuthorization', () => {
32
32
  validationStateReader: validationStateReader,
33
33
  })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
34
34
  });
35
- it('should not treat Records Read grants as unified query grants', async () => {
35
+ it('allows Records Read grants to authorize read-like record methods', async () => {
36
+ const mockGrant = {
37
+ id: 'grant-records-read',
38
+ grantor: 'did:example:grantor',
39
+ grantee: 'did:example:grantee',
40
+ dateGranted: '2020-01-01T00:00:00.000Z',
41
+ dateExpires: '2040-01-01T00:00:00.000Z',
42
+ scope: { interface: 'Records', method: 'Read', protocol: 'https://proto.example' },
43
+ };
44
+ for (const method of ['Read', 'Query', 'Subscribe', 'Count']) {
45
+ const mockMessage = {
46
+ descriptor: {
47
+ interface: 'Records',
48
+ method,
49
+ messageTimestamp: '2025-01-01T00:00:00.000Z',
50
+ },
51
+ };
52
+ await expect(GrantAuthorization.performBaseValidation({
53
+ incomingMessage: mockMessage,
54
+ expectedGrantor: 'did:example:grantor',
55
+ expectedGrantee: 'did:example:grantee',
56
+ permissionGrant: mockGrant,
57
+ validationStateReader: validationStateReader,
58
+ })).resolves.toBeUndefined();
59
+ }
60
+ });
61
+ it('rejects Records Write grants for read-like record methods', async () => {
62
+ const mockGrant = {
63
+ id: 'grant-records-write',
64
+ grantor: 'did:example:grantor',
65
+ grantee: 'did:example:grantee',
66
+ dateGranted: '2020-01-01T00:00:00.000Z',
67
+ dateExpires: '2040-01-01T00:00:00.000Z',
68
+ scope: { interface: 'Records', method: 'Write', protocol: 'https://proto.example' },
69
+ };
70
+ for (const method of ['Read', 'Query', 'Subscribe', 'Count']) {
71
+ const mockMessage = {
72
+ descriptor: {
73
+ interface: 'Records',
74
+ method,
75
+ messageTimestamp: '2025-01-01T00:00:00.000Z',
76
+ },
77
+ };
78
+ await expect(GrantAuthorization.performBaseValidation({
79
+ incomingMessage: mockMessage,
80
+ expectedGrantor: 'did:example:grantor',
81
+ expectedGrantee: 'did:example:grantee',
82
+ permissionGrant: mockGrant,
83
+ validationStateReader: validationStateReader,
84
+ })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
85
+ }
86
+ });
87
+ it('rejects grants scoped to a different DWN interface', async () => {
36
88
  const mockGrant = {
37
89
  id: 'grant-records-read',
38
90
  grantor: 'did:example:grantor',
@@ -43,8 +95,8 @@ describe('GrantAuthorization', () => {
43
95
  };
44
96
  const mockMessage = {
45
97
  descriptor: {
46
- interface: 'Records',
47
- method: 'Query',
98
+ interface: 'Messages',
99
+ method: 'Read',
48
100
  messageTimestamp: '2025-01-01T00:00:00.000Z',
49
101
  },
50
102
  };
@@ -54,7 +106,33 @@ describe('GrantAuthorization', () => {
54
106
  expectedGrantee: 'did:example:grantee',
55
107
  permissionGrant: mockGrant,
56
108
  validationStateReader: validationStateReader,
57
- })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
109
+ })).rejects.toThrow(DwnErrorCode.GrantAuthorizationInterfaceMismatch);
110
+ });
111
+ it('rejects read-like Records grants that do not use method Read', async () => {
112
+ for (const method of ['Query', 'Subscribe', 'Count']) {
113
+ const mockGrant = {
114
+ id: `grant-records-${method.toLowerCase()}`,
115
+ grantor: 'did:example:grantor',
116
+ grantee: 'did:example:grantee',
117
+ dateGranted: '2020-01-01T00:00:00.000Z',
118
+ dateExpires: '2040-01-01T00:00:00.000Z',
119
+ scope: { interface: 'Records', method, protocol: 'https://proto.example' },
120
+ };
121
+ const mockMessage = {
122
+ descriptor: {
123
+ interface: 'Records',
124
+ method,
125
+ messageTimestamp: '2025-01-01T00:00:00.000Z',
126
+ },
127
+ };
128
+ await expect(GrantAuthorization.performBaseValidation({
129
+ incomingMessage: mockMessage,
130
+ expectedGrantor: 'did:example:grantor',
131
+ expectedGrantee: 'did:example:grantee',
132
+ permissionGrant: mockGrant,
133
+ validationStateReader: validationStateReader,
134
+ })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
135
+ }
58
136
  });
59
137
  });
60
138
  });
@@ -1 +1 @@
1
- {"version":3,"file":"grant-authorization.spec.js","sourceRoot":"","sources":["../../../../tests/core/grant-authorization.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAClD,MAAM,qBAAqB,GAAG;YAC5B,0BAA0B,EAAE,KAAK,IAAkB,EAAE,CAAC,SAAS;SAChE,CAAC;QAEF,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,iEAAiE;YACjE,sCAAsC;YACtC,MAAM,SAAS,GAAG;gBAChB,EAAE,EAAY,iBAAiB;gBAC/B,OAAO,EAAO,qBAAqB;gBACnC,OAAO,EAAO,qBAAqB;gBACnC,WAAW,EAAG,0BAA0B;gBACxC,WAAW,EAAG,0BAA0B;gBACxC,KAAK,EAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,uBAAuB,EAAE;aAC3F,CAAC;YAEF,MAAM,WAAW,GAAG;gBAClB,UAAU,EAAE;oBACV,SAAS,EAAU,UAAU;oBAC7B,MAAM,EAAa,MAAM;oBACzB,gBAAgB,EAAG,0BAA0B;iBAC9C;aACF,CAAC;YAEF,MAAM,MAAM,CACV,kBAAkB,CAAC,qBAAqB,CAAC;gBACvC,eAAe,EAAS,WAAkB;gBAC1C,eAAe,EAAS,qBAAqB;gBAC7C,eAAe,EAAS,qBAAqB;gBAC7C,eAAe,EAAS,SAAgB;gBACxC,qBAAqB,EAAG,qBAA4B;aACrD,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,gCAAgC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,SAAS,GAAG;gBAChB,EAAE,EAAY,oBAAoB;gBAClC,OAAO,EAAO,qBAAqB;gBACnC,OAAO,EAAO,qBAAqB;gBACnC,WAAW,EAAG,0BAA0B;gBACxC,WAAW,EAAG,0BAA0B;gBACxC,KAAK,EAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,uBAAuB,EAAE;aAC1F,CAAC;YAEF,MAAM,WAAW,GAAG;gBAClB,UAAU,EAAE;oBACV,SAAS,EAAU,SAAS;oBAC5B,MAAM,EAAa,OAAO;oBAC1B,gBAAgB,EAAG,0BAA0B;iBAC9C;aACF,CAAC;YAEF,MAAM,MAAM,CACV,kBAAkB,CAAC,qBAAqB,CAAC;gBACvC,eAAe,EAAS,WAAkB;gBAC1C,eAAe,EAAS,qBAAqB;gBAC7C,eAAe,EAAS,qBAAqB;gBAC7C,eAAe,EAAS,SAAgB;gBACxC,qBAAqB,EAAG,qBAA4B;aACrD,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,gCAAgC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"grant-authorization.spec.js","sourceRoot":"","sources":["../../../../tests/core/grant-authorization.spec.ts"],"names":[],"mappings":"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"}
@@ -57,7 +57,7 @@ describe('RecordsGrantAuthorization', () => {
57
57
  incomingMessage: makeIncomingMessage(method, filter),
58
58
  expectedGrantor: grantor,
59
59
  expectedGrantee: grantee,
60
- permissionGrant: makePermissionGrant(method, grantScope),
60
+ permissionGrant: makePermissionGrant(DwnMethodName.Read, grantScope),
61
61
  validationStateReader,
62
62
  })).rejects.toThrow(DwnErrorCode.RecordsGrantAuthorizationQueryOrSubscribeProtocolScopeMismatch);
63
63
  }
@@ -90,7 +90,7 @@ describe('RecordsGrantAuthorization', () => {
90
90
  }),
91
91
  expectedGrantor: grantor,
92
92
  expectedGrantee: grantee,
93
- permissionGrant: makePermissionGrant(DwnMethodName.Query, {
93
+ permissionGrant: makePermissionGrant(DwnMethodName.Read, {
94
94
  protocol,
95
95
  protocolPath: 'thread/message',
96
96
  }),
@@ -101,17 +101,34 @@ describe('RecordsGrantAuthorization', () => {
101
101
  await expectQueryOrSubscribeScopeMismatch(DwnMethodName.Query, { protocol, protocolPath: 'thread/message' }, { protocol, protocolPath: 'thread/reaction' });
102
102
  await expectQueryOrSubscribeScopeMismatch(DwnMethodName.Subscribe, { protocol, contextId: 'root' }, { protocol, contextId: 'rootEVIL' });
103
103
  });
104
- it('allows protocol-scoped query and count filters', async () => {
105
- for (const method of [DwnMethodName.Query, DwnMethodName.Count]) {
104
+ it('allows protocol-scoped query, subscribe, and count filters with a Records.Read grant', async () => {
105
+ for (const method of [DwnMethodName.Query, DwnMethodName.Subscribe, DwnMethodName.Count]) {
106
106
  await expect(RecordsGrantAuthorization.authorizeQueryOrSubscribe({
107
107
  incomingMessage: makeIncomingMessage(method, { protocol }),
108
108
  expectedGrantor: grantor,
109
109
  expectedGrantee: grantee,
110
- permissionGrant: makePermissionGrant(method, { protocol }),
110
+ permissionGrant: makePermissionGrant(DwnMethodName.Read, { protocol }),
111
111
  validationStateReader,
112
112
  })).resolves.toBeUndefined();
113
113
  }
114
114
  });
115
+ it('rejects read-like Records grants that do not use method Read', async () => {
116
+ const cases = [
117
+ [DwnMethodName.Query, DwnMethodName.Query],
118
+ [DwnMethodName.Subscribe, DwnMethodName.Subscribe],
119
+ [DwnMethodName.Count, DwnMethodName.Count],
120
+ [DwnMethodName.Write, DwnMethodName.Query],
121
+ ];
122
+ for (const [grantMethod, incomingMethod] of cases) {
123
+ await expect(RecordsGrantAuthorization.authorizeQueryOrSubscribe({
124
+ incomingMessage: makeIncomingMessage(incomingMethod, { protocol }),
125
+ expectedGrantor: grantor,
126
+ expectedGrantee: grantee,
127
+ permissionGrant: makePermissionGrant(grantMethod, { protocol }),
128
+ validationStateReader,
129
+ })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
130
+ }
131
+ });
115
132
  });
116
133
  });
117
134
  //# sourceMappingURL=records-grant-authorization.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"records-grant-authorization.spec.js","sourceRoot":"","sources":["../../../../tests/core/records-grant-authorization.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"records-grant-authorization.spec.js","sourceRoot":"","sources":["../../../../tests/core/records-grant-authorization.spec.ts"],"names":[],"mappings":"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"}
@@ -356,14 +356,14 @@ export function testAuthorDelegatedGrant() {
356
356
  });
357
357
  const chatRecordReply = await dwn.processMessage(bob.did, chatRecord.message, { dataStream: chatRecord.dataStream });
358
358
  expect(chatRecordReply.status.code).toBe(202);
359
- // Alice creates a delegated query grant for device X to act as Alice.
359
+ // Alice creates a delegated read grant for device X to perform read-like operations as Alice.
360
360
  const queryGrantForDeviceX = await PermissionsProtocol.createGrant({
361
361
  delegated: true, // this is a delegated grant
362
362
  dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
363
363
  grantedTo: deviceX.did,
364
364
  scope: {
365
365
  interface: DwnInterfaceName.Records,
366
- method: DwnMethodName.Query,
366
+ method: DwnMethodName.Read,
367
367
  protocol
368
368
  },
369
369
  signer: Jws.createSigner(alice)
@@ -454,6 +454,130 @@ export function testAuthorDelegatedGrant() {
454
454
  expect(recordsReadByCarolReply.status.code).toBe(400);
455
455
  expect(recordsQueryByCarolReply.status.detail).toContain(DwnErrorCode.RecordsAuthorDelegatedGrantGrantedToAndOwnerSignatureMismatch);
456
456
  });
457
+ it('should scope author-delegated read-like grants to the matching context subtree', async () => {
458
+ const alice = await TestDataGenerator.generateDidKeyPersona();
459
+ const deviceX = await TestDataGenerator.generateDidKeyPersona();
460
+ const bob = await TestDataGenerator.generateDidKeyPersona();
461
+ const protocolDefinition = threadRoleProtocolDefinition;
462
+ const protocol = threadRoleProtocolDefinition.protocol;
463
+ const protocolsConfig = await TestDataGenerator.generateProtocolsConfigure({
464
+ author: bob,
465
+ protocolDefinition
466
+ });
467
+ const protocolsConfigureReply = await dwn.processMessage(bob.did, protocolsConfig.message);
468
+ expect(protocolsConfigureReply.status.code).toBe(202);
469
+ const threadRecord = await TestDataGenerator.generateRecordsWrite({
470
+ author: bob,
471
+ protocol: protocolDefinition.protocol,
472
+ protocolPath: 'thread',
473
+ });
474
+ const threadRoleReply = await dwn.processMessage(bob.did, threadRecord.message, { dataStream: threadRecord.dataStream });
475
+ expect(threadRoleReply.status.code).toBe(202);
476
+ const participantRoleRecord = await TestDataGenerator.generateRecordsWrite({
477
+ author: bob,
478
+ recipient: alice.did,
479
+ protocol: protocolDefinition.protocol,
480
+ protocolPath: 'thread/participant',
481
+ parentContextId: threadRecord.message.contextId,
482
+ data: new TextEncoder().encode('Alice is my friend'),
483
+ });
484
+ const participantRoleReply = await dwn.processMessage(bob.did, participantRoleRecord.message, { dataStream: participantRoleRecord.dataStream });
485
+ expect(participantRoleReply.status.code).toBe(202);
486
+ const chatRecord = await TestDataGenerator.generateRecordsWrite({
487
+ author: bob,
488
+ protocol: protocolDefinition.protocol,
489
+ protocolPath: 'thread/chat',
490
+ parentContextId: threadRecord.message.contextId,
491
+ });
492
+ const chatRecordReply = await dwn.processMessage(bob.did, chatRecord.message, { dataStream: chatRecord.dataStream });
493
+ expect(chatRecordReply.status.code).toBe(202);
494
+ const contextScopedReadGrant = await PermissionsProtocol.createGrant({
495
+ delegated: true,
496
+ dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
497
+ grantedTo: deviceX.did,
498
+ scope: {
499
+ interface: DwnInterfaceName.Records,
500
+ method: DwnMethodName.Read,
501
+ protocol,
502
+ contextId: threadRecord.message.contextId,
503
+ },
504
+ signer: Jws.createSigner(alice)
505
+ });
506
+ const matchingQuery = await RecordsQuery.create({
507
+ signer: Jws.createSigner(deviceX),
508
+ delegatedGrant: contextScopedReadGrant.dataEncodedMessage,
509
+ protocolRole: 'thread/participant',
510
+ filter: {
511
+ protocol,
512
+ contextId: threadRecord.message.contextId,
513
+ protocolPath: 'thread/chat'
514
+ }
515
+ });
516
+ const matchingQueryReply = await dwn.processMessage(bob.did, matchingQuery.message);
517
+ expect(matchingQueryReply.status.code).toBe(200);
518
+ expect(matchingQueryReply.entries?.map(entry => entry.recordId)).toEqual([chatRecord.message.recordId]);
519
+ const mismatchingContextId = `${threadRecord.message.contextId}EVIL`;
520
+ const mismatchingQuery = await RecordsQuery.create({
521
+ signer: Jws.createSigner(deviceX),
522
+ delegatedGrant: contextScopedReadGrant.dataEncodedMessage,
523
+ protocolRole: 'thread/participant',
524
+ filter: {
525
+ protocol,
526
+ contextId: mismatchingContextId,
527
+ protocolPath: 'thread/chat'
528
+ }
529
+ });
530
+ const mismatchingQueryReply = await dwn.processMessage(bob.did, mismatchingQuery.message);
531
+ expect(mismatchingQueryReply.status.code).toBe(401);
532
+ expect(mismatchingQueryReply.status.detail).toContain(DwnErrorCode.RecordsGrantAuthorizationQueryOrSubscribeProtocolScopeMismatch);
533
+ const mismatchingSubscribe = await RecordsSubscribe.create({
534
+ signer: Jws.createSigner(deviceX),
535
+ delegatedGrant: contextScopedReadGrant.dataEncodedMessage,
536
+ protocolRole: 'thread/participant',
537
+ filter: {
538
+ protocol,
539
+ contextId: mismatchingContextId,
540
+ protocolPath: 'thread/chat'
541
+ }
542
+ });
543
+ const mismatchingSubscribeReply = await dwn.processMessage(bob.did, mismatchingSubscribe.message);
544
+ expect(mismatchingSubscribeReply.status.code).toBe(401);
545
+ expect(mismatchingSubscribeReply.status.detail).toContain(DwnErrorCode.RecordsGrantAuthorizationQueryOrSubscribeProtocolScopeMismatch);
546
+ const subscriptionChatRecords = new Set();
547
+ const captureChatRecords = async (msg) => {
548
+ if (msg.type !== 'event') {
549
+ return;
550
+ }
551
+ const recordId = msg.event.message.recordId;
552
+ subscriptionChatRecords.add(recordId);
553
+ };
554
+ const matchingSubscribe = await RecordsSubscribe.create({
555
+ signer: Jws.createSigner(deviceX),
556
+ delegatedGrant: contextScopedReadGrant.dataEncodedMessage,
557
+ protocolRole: 'thread/participant',
558
+ filter: {
559
+ protocol,
560
+ contextId: threadRecord.message.contextId,
561
+ protocolPath: 'thread/chat'
562
+ }
563
+ });
564
+ const matchingSubscribeReply = await dwn.processMessage(bob.did, matchingSubscribe.message, {
565
+ subscriptionHandler: captureChatRecords
566
+ });
567
+ expect(matchingSubscribeReply.status.code).toBe(200);
568
+ const subscribedChatRecord = await TestDataGenerator.generateRecordsWrite({
569
+ author: bob,
570
+ protocol: protocolDefinition.protocol,
571
+ protocolPath: 'thread/chat',
572
+ parentContextId: threadRecord.message.contextId,
573
+ });
574
+ const subscribedChatRecordReply = await dwn.processMessage(bob.did, subscribedChatRecord.message, { dataStream: subscribedChatRecord.dataStream });
575
+ expect(subscribedChatRecordReply.status.code).toBe(202);
576
+ await Poller.pollUntilSuccessOrTimeout(async () => {
577
+ expect(subscriptionChatRecords.has(subscribedChatRecord.message.recordId)).toBe(true);
578
+ });
579
+ await matchingSubscribeReply.subscription?.close();
580
+ });
457
581
  it('should only allow correct entity invoking an author-delegated grant to subscribe', async () => {
458
582
  // scenario:
459
583
  // 1. Bob installs a chat protocol and creates a thread, adding Alice as a participant.
@@ -496,14 +620,14 @@ export function testAuthorDelegatedGrant() {
496
620
  });
497
621
  const participantRoleReply = await dwn.processMessage(bob.did, participantRoleRecord.message, { dataStream: participantRoleRecord.dataStream });
498
622
  expect(participantRoleReply.status.code).toBe(202);
499
- // Alice creates a delegated subscribe grant for device X to act as Alice.
623
+ // Alice creates a delegated read grant for device X to subscribe as Alice.
500
624
  const subscribeGrantForDeviceX = await PermissionsProtocol.createGrant({
501
625
  delegated: true, // this is a delegated grant
502
626
  dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
503
627
  grantedTo: deviceX.did,
504
628
  scope: {
505
629
  interface: DwnInterfaceName.Records,
506
- method: DwnMethodName.Subscribe,
630
+ method: DwnMethodName.Read,
507
631
  protocol
508
632
  },
509
633
  signer: Jws.createSigner(alice)
@@ -803,7 +927,7 @@ export function testAuthorDelegatedGrant() {
803
927
  it('should not allow entity using a non-delegated grant as an author-delegated grant to invoke query', async () => {
804
928
  // scenario:
805
929
  // 1. Bob has the message protocol installed
806
- // 2. Alice creates a non-delegated query grant for device X
930
+ // 2. Alice creates a non-delegated read grant for device X
807
931
  // 3. Verify that device X cannot query Bob's DWN as Alice using the non-delegated grant
808
932
  const alice = await TestDataGenerator.generateDidKeyPersona();
809
933
  const bob = await TestDataGenerator.generateDidKeyPersona();
@@ -824,7 +948,7 @@ export function testAuthorDelegatedGrant() {
824
948
  grantedTo: deviceX.did,
825
949
  scope: {
826
950
  interface: DwnInterfaceName.Records,
827
- method: DwnMethodName.Query,
951
+ method: DwnMethodName.Read,
828
952
  protocol
829
953
  },
830
954
  signer: Jws.createSigner(alice)
@@ -995,14 +1119,14 @@ export function testAuthorDelegatedGrant() {
995
1119
  const chatRecordReply = await dwn.processMessage(bob.did, chatRecord.message, { dataStream: chatRecord.dataStream });
996
1120
  expect(chatRecordReply.status.code).toBe(202);
997
1121
  // 2. Alice creates a delegated grant for device X to act as her for a protocol that is NOT chat protocol
998
- // Alice creates a delegated query grant for device X to act as Alice but not for chat protocol
1122
+ // Alice creates a delegated read grant for device X to query as Alice but not for chat protocol
999
1123
  const queryGrantForDeviceX = await PermissionsProtocol.createGrant({
1000
1124
  delegated: true, // this is a delegated grant
1001
1125
  dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
1002
1126
  grantedTo: deviceX.did,
1003
1127
  scope: {
1004
1128
  interface: DwnInterfaceName.Records,
1005
- method: DwnMethodName.Query,
1129
+ method: DwnMethodName.Read,
1006
1130
  protocol: 'some-other-protocol'
1007
1131
  },
1008
1132
  signer: Jws.createSigner(alice)
@@ -1019,14 +1143,14 @@ export function testAuthorDelegatedGrant() {
1019
1143
  },
1020
1144
  signer: Jws.createSigner(alice)
1021
1145
  });
1022
- // Alice creates a delegated subscribe grant for device X to act as Alice but not for chat protocol
1146
+ // Alice creates a delegated read grant for device X to subscribe as Alice but not for chat protocol
1023
1147
  const subscribeGrantForDeviceX = await PermissionsProtocol.createGrant({
1024
1148
  delegated: true, // this is a delegated grant
1025
1149
  dateExpires: Time.createOffsetTimestamp({ seconds: 100 }),
1026
1150
  grantedTo: deviceX.did,
1027
1151
  scope: {
1028
1152
  interface: DwnInterfaceName.Records,
1029
- method: DwnMethodName.Subscribe,
1153
+ method: DwnMethodName.Read,
1030
1154
  protocol: 'some-other-protocol'
1031
1155
  },
1032
1156
  signer: Jws.createSigner(alice)