From 1234b3b81721d8dd8e96f8f0e31c472ffaba5217 Mon Sep 17 00:00:00 2001 From: Francisco Javier Ribo Labrador Date: Mon, 2 Sep 2024 11:44:05 +0200 Subject: [PATCH] fix: improve parseInvitation to handle parsing oob properly either with URL or with parsed object. Signed-off-by: Francisco Javier Ribo Labrador --- src/edge-agent/protocols/ProtocolTypes.ts | 7 ++-- .../invitation/v2/DIDCommInvitationRunner.ts | 42 ++++++++++++------- tests/agent/Agent.test.ts | 36 ++++++++++++++++ 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/src/edge-agent/protocols/ProtocolTypes.ts b/src/edge-agent/protocols/ProtocolTypes.ts index ef037e421..31dc427cb 100644 --- a/src/edge-agent/protocols/ProtocolTypes.ts +++ b/src/edge-agent/protocols/ProtocolTypes.ts @@ -26,10 +26,9 @@ export enum ProtocolType { export function findProtocolTypeByValue(string: string): ProtocolType { const values = Object.values(ProtocolType) as string[]; - for (const value of values) { - if (value === string) { - return ProtocolType[value as keyof typeof ProtocolType]; - } + const validType = values.includes(string) + if (validType) { + return string as ProtocolType } throw new Error("Unknown invitation type error."); } diff --git a/src/edge-agent/protocols/invitation/v2/DIDCommInvitationRunner.ts b/src/edge-agent/protocols/invitation/v2/DIDCommInvitationRunner.ts index 9ffd77f52..f16016921 100644 --- a/src/edge-agent/protocols/invitation/v2/DIDCommInvitationRunner.ts +++ b/src/edge-agent/protocols/invitation/v2/DIDCommInvitationRunner.ts @@ -7,7 +7,7 @@ import { OutOfBandInvitation } from "./OutOfBandInvitation"; import { AttachmentDescriptor } from "../../../../domain"; export class DIDCommInvitationRunner { - constructor(private url: URL) { } + constructor(private url: URL | object) { } private isDIDCommInvitation( type: ProtocolType, @@ -17,11 +17,11 @@ export class DIDCommInvitationRunner { return type === ProtocolType.Didcomminvitation; } - private safeParseBody(body: string, type: ProtocolType): OutOfBandInvitation { + private safeParseBody(body: string | object, type: ProtocolType): OutOfBandInvitation { // eslint-disable-next-line @typescript-eslint/no-explicit-any let parsed: any; try { - parsed = JSON.parse(body); + parsed = typeof body === "string" ? JSON.parse(body) : body } catch (err) { throw new AgentError.UnknownInvitationTypeError(); } @@ -75,19 +75,29 @@ export class DIDCommInvitationRunner { } run(): OutOfBandInvitation { - const components = new URLSearchParams(this.url.search); - if (!components) { - throw new AgentError.InvalidURLError(); - } - const message = components.get("_oob"); - if (!message) { - throw new AgentError.InvalidURLError(); - } - const dataJson = Buffer.from(base64.baseDecode(message)).toString(); - const invitation = this.safeParseBody(dataJson, ProtocolType.Didcomminvitation); - if (invitation.isExpired) { - throw new AgentError.InvitationIsInvalidError('expired') + if (this.url instanceof URL) { + const components = new URLSearchParams(this.url.search); + if (!components) { + throw new AgentError.InvalidURLError(); + } + const message = components.get("_oob"); + if (!message) { + throw new AgentError.InvalidURLError(); + } + const dataJson = Buffer.from(base64.baseDecode(message)).toString(); + const invitation = this.safeParseBody(dataJson, ProtocolType.Didcomminvitation); + if (invitation.isExpired) { + throw new AgentError.InvitationIsInvalidError('expired') + } + return invitation; + + } else { + const invitation = this.safeParseBody(this.url, ProtocolType.Didcomminvitation); + if (invitation.isExpired) { + throw new AgentError.InvitationIsInvalidError('expired') + } + return invitation; } - return invitation + } } diff --git a/tests/agent/Agent.test.ts b/tests/agent/Agent.test.ts index c2ccbd992..bf24ebaf8 100644 --- a/tests/agent/Agent.test.ts +++ b/tests/agent/Agent.test.ts @@ -242,6 +242,42 @@ describe("Agent Tests", () => { ).to.eventually.be.rejectedWith(AgentError.InvitationIsInvalidError); }); + + it("As a developer with a valid invitationMessage I will be sending a presentation with the correct information, but will fail as it is expired.", async () => { + const agentInvitations = (agent as any).agentInvitations; + const agentInvitationsConnection = agentInvitations.connection; + const didHigherFunctions = (agent as any).agentDIDHigherFunctions; + + const did = DID.fromString( + "did:peer:2.Ez6LSms555YhFthn1WV8ciDBpZm86hK9tp83WojJUmxPGk1hZ.Vz6MkmdBjMyB4TS5UbbQw54szm8yvMMf1ftGV2sQVYAxaeWhE.SeyJpZCI6Im5ldy1pZCIsInQiOiJkbSIsInMiOnsidXJpIjoiaHR0cHM6Ly9tZWRpYXRvci5yb290c2lkLmNsb3VkIiwiYSI6WyJkaWRjb21tL3YyIl19fQ" + ); + const validOOB = + "https://my.domain.com/path?_oob=eyJpZCI6IjViMjUwMjIzLWExNDItNDRmYi1hOWJkLWU1MjBlNGI0ZjQzMiIsInR5cGUiOiJodHRwczovL2RpZGNvbW0ub3JnL291dC1vZi1iYW5kLzIuMC9pbnZpdGF0aW9uIiwiZnJvbSI6ImRpZDpwZWVyOjIuRXo2TFNkV0hWQ1BFOHc0NWZETjM4aUh0ZFJ6WGkyTFNqQmRSUjRGTmNOUm12VkNKcy5WejZNa2Z2aUI5S1F1OGlnNVZpeG1HZHM3dmdMNmoyUXNOUGFybkZaanBNQ0E5aHpQLlNleUowSWpvaVpHMGlMQ0p6SWpwN0luVnlhU0k2SW1oMGRIQTZMeTh4T1RJdU1UWTRMakV1TXpjNk9EQTNNQzlrYVdSamIyMXRJaXdpY2lJNlcxMHNJbUVpT2xzaVpHbGtZMjl0YlM5Mk1pSmRmWDAiLCJib2R5Ijp7ImdvYWxfY29kZSI6InByZXNlbnQtdnAiLCJnb2FsIjoiUmVxdWVzdCBwcm9vZiBvZiB2YWNjaW5hdGlvbiBpbmZvcm1hdGlvbiIsImFjY2VwdCI6W119LCJhdHRhY2htZW50cyI6W3siaWQiOiIyYTZmOGM4NS05ZGE3LTRkMjQtOGRhNS0wYzliZDY5ZTBiMDEiLCJtZWRpYV90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsImRhdGEiOnsianNvbiI6eyJpZCI6IjI1NTI5MTBiLWI0NmMtNDM3Yy1hNDdhLTlmODQ5OWI5ZTg0ZiIsInR5cGUiOiJodHRwczovL2RpZGNvbW0uYXRhbGFwcmlzbS5pby9wcmVzZW50LXByb29mLzMuMC9yZXF1ZXN0LXByZXNlbnRhdGlvbiIsImJvZHkiOnsiZ29hbF9jb2RlIjoiUmVxdWVzdCBQcm9vZiBQcmVzZW50YXRpb24iLCJ3aWxsX2NvbmZpcm0iOmZhbHNlLCJwcm9vZl90eXBlcyI6W119LCJhdHRhY2htZW50cyI6W3siaWQiOiJiYWJiNTJmMS05NDUyLTQzOGYtYjk3MC0yZDJjOTFmZTAyNGYiLCJtZWRpYV90eXBlIjoiYXBwbGljYXRpb24vanNvbiIsImRhdGEiOnsianNvbiI6eyJvcHRpb25zIjp7ImNoYWxsZW5nZSI6IjExYzkxNDkzLTAxYjMtNGM0ZC1hYzM2LWIzMzZiYWI1YmRkZiIsImRvbWFpbiI6Imh0dHBzOi8vcHJpc20tdmVyaWZpZXIuY29tIn0sInByZXNlbnRhdGlvbl9kZWZpbml0aW9uIjp7ImlkIjoiMGNmMzQ2ZDItYWY1Ny00Y2E1LTg2Y2EtYTA1NTE1NjZlYzZmIiwiaW5wdXRfZGVzY3JpcHRvcnMiOltdfX19LCJmb3JtYXQiOiJwcmlzbS9qd3QifV0sInRoaWQiOiI1YjI1MDIyMy1hMTQyLTQ0ZmItYTliZC1lNTIwZTRiNGY0MzIiLCJmcm9tIjoiZGlkOnBlZXI6Mi5FejZMU2RXSFZDUEU4dzQ1ZkROMzhpSHRkUnpYaTJMU2pCZFJSNEZOY05SbXZWQ0pzLlZ6Nk1rZnZpQjlLUXU4aWc1Vml4bUdkczd2Z0w2ajJRc05QYXJuRlpqcE1DQTloelAuU2V5SjBJam9pWkcwaUxDSnpJanA3SW5WeWFTSTZJbWgwZEhBNkx5OHhPVEl1TVRZNExqRXVNemM2T0RBM01DOWthV1JqYjIxdElpd2ljaUk2VzEwc0ltRWlPbHNpWkdsa1kyOXRiUzkyTWlKZGZYMCJ9fX1dLCJjcmVhdGVkX3RpbWUiOjE3MjQzMzkxNDQsImV4cGlyZXNfdGltZSI6MTcyNDMzOTQ0NH0"; + + const createPeerDID = sandbox.stub( + didHigherFunctions, + "createNewPeerDID" + ); + const sendMessage = sandbox.stub( + agentInvitationsConnection, + "sendMessage" + ); + const addConnection = sandbox.stub( + agentInvitationsConnection, + "addConnection" + ); + + sandbox.stub(UUIDLib, "uuid").returns("123456-123456-12356-123456"); + + createPeerDID.resolves(did); + sendMessage.resolves(); + addConnection.resolves(); + + expect( + agent.parseInvitation(validOOB) + ).to.eventually.be.rejectedWith(AgentError.InvitationIsInvalidError); + }); + });