From a7e015bd490ea890a95cb928584470b2360b1f9f Mon Sep 17 00:00:00 2001 From: Diane Huxley Date: Wed, 1 Nov 2023 15:00:31 -0700 Subject: [PATCH] Test dwn send PermissionsGrant --- packages/api/src/dwn-api.ts | 25 ++++++++++++++++++++++++- packages/api/tests/dwn-api.spec.ts | 26 +++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/packages/api/src/dwn-api.ts b/packages/api/src/dwn-api.ts index 358714b8e..71a202ce7 100644 --- a/packages/api/src/dwn-api.ts +++ b/packages/api/src/dwn-api.ts @@ -29,6 +29,12 @@ export type PermissionsGrantRequest = { message: Omit; } +export type PermissionsGrantResponse = { + permissionsGrant: PermissionsGrant | undefined; + permissionsGrantId: string | undefined; + status: UnionMessageReply['status'] +}; + export type ProtocolsConfigureRequest = { message: Omit; } @@ -101,6 +107,7 @@ export type RecordsWriteRequest = { } export type PermissionGrantRequest = { + target?: string; message?: Omit, 'authorizationSigner'>; } @@ -393,7 +400,14 @@ export class DwnApi { get permissions() { return { - grant: async (request: PermissionsGrantRequest): Promise<{ permissionsGrant: PermissionsGrant, status: UnionMessageReply['status'] }> => { + /** + * Create and store a PermissionsGrant DWN message + * @param request.target The DID whose DWN the PermissionsGrant message will be sent to. If undefined, + * the message will be stored in the local DWN of the connectedDid. + * @param request.message The message options used to create the PermissionsGrant messsage. + * @returns {PermissionsGrantResponse} + */ + grant: async (request: PermissionsGrantRequest): Promise => { const agentRequest = { author : this.connectedDid, messageOptions : request.message, @@ -412,16 +426,25 @@ export class DwnApi { const { message, reply: { status } } = agentResponse; let permissionsGrant: PermissionsGrant | undefined; + let permissionsGrantId: string | undefined; if (200 <= status.code && status.code <= 299) { permissionsGrant = await PermissionsGrant.parse(message as PermissionsGrantMessage); + permissionsGrantId = await Message.getCid(permissionsGrant.message); } return { permissionsGrant, + permissionsGrantId, status, }; }, + /** + * Send an existing PermissionsGrant message to a remote DWN. + * @param target DID whose remote DWN the Permissions message will be sent to. + * @param message The PermissionsGrant message that will be sent. + * @returns {UnionMessageReply['status']} + */ send: async (target: string, message: PermissionsGrant): Promise<{ status: UnionMessageReply['status'] }> => { const { reply: { status } } = await this.agent.sendDwnRequest({ messageType : message.message.descriptor.interface + message.message.descriptor.method, diff --git a/packages/api/tests/dwn-api.spec.ts b/packages/api/tests/dwn-api.spec.ts index 9e22398fd..99cd89400 100644 --- a/packages/api/tests/dwn-api.spec.ts +++ b/packages/api/tests/dwn-api.spec.ts @@ -577,7 +577,7 @@ describe('DwnApi', () => { it('returns a PermissionsGrant that can be invoked', async () => { const { did: bobDid } = await testAgent.createIdentity({ testDwnUrls }); - const { status, permissionsGrant } = await dwn.permissions.grant({ + const { status, permissionsGrant, permissionsGrantId } = await dwn.permissions.grant({ message: { dateExpires : Temporal.Now.instant().toString({ smallestUnit: 'microseconds' }), grantedBy : aliceDid.did, @@ -585,13 +585,14 @@ describe('DwnApi', () => { grantedTo : bobDid.did, scope : { interface : DwnInterfaceName.Records, - method : DwnMethodName.Read, + method : DwnMethodName.Write, } }, }); expect(status.code).to.eq(202); expect(permissionsGrant).not.to.be.undefined; + expect(permissionsGrantId).not.to.be.undefined; // send to Alice's remote DWN const { status: statusSend } = await dwn.permissions.send(aliceDid.did, permissionsGrant); @@ -600,8 +601,27 @@ describe('DwnApi', () => { }); }); - describe('target: did', () => { + describe('target: did', async () => { + it('returns a PermissionsGrant that can be invoked', async () => { + const { did: bobDid } = await testAgent.createIdentity({ testDwnUrls }); + + const { status, permissionsGrant } = await dwn.permissions.grant({ + target : bobDid.did, + message : { + dateExpires : Temporal.Now.instant().toString({ smallestUnit: 'microseconds' }), + grantedBy : aliceDid.did, + grantedFor : aliceDid.did, + grantedTo : bobDid.did, + scope : { + interface : DwnInterfaceName.Records, + method : DwnMethodName.Write, + } + }, + }); + expect(status.code).to.eq(202); + expect(permissionsGrant).not.to.be.undefined; + }); }); }); }); \ No newline at end of file