Skip to content

Commit

Permalink
fix(oob): support legacy prefix in attachments (#931)
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <[email protected]>
  • Loading branch information
TimoGlastra authored Jul 8, 2022
1 parent f907fe9 commit 82863f3
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 15 deletions.
14 changes: 8 additions & 6 deletions packages/core/src/modules/oob/OutOfBandModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -595,9 +595,10 @@ export class OutOfBandModule {

private async emitWithConnection(connectionRecord: ConnectionRecord, messages: PlaintextMessage[]) {
const supportedMessageTypes = this.dispatcher.supportedMessageTypes
const plaintextMessage = messages.find((message) =>
supportedMessageTypes.find((type) => supportsIncomingMessageType(parseMessageType(message['@type']), type))
)
const plaintextMessage = messages.find((message) => {
const parsedMessageType = parseMessageType(message['@type'])
return supportedMessageTypes.find((type) => supportsIncomingMessageType(parsedMessageType, type))
})

if (!plaintextMessage) {
throw new AriesFrameworkError('There is no message in requests~attach supported by agent.')
Expand All @@ -620,9 +621,10 @@ export class OutOfBandModule {
}

const supportedMessageTypes = this.dispatcher.supportedMessageTypes
const plaintextMessage = messages.find((message) =>
supportedMessageTypes.find((type) => supportsIncomingMessageType(parseMessageType(message['@type']), type))
)
const plaintextMessage = messages.find((message) => {
const parsedMessageType = parseMessageType(message['@type'])
return supportedMessageTypes.find((type) => supportsIncomingMessageType(parsedMessageType, type))
})

if (!plaintextMessage) {
throw new AriesFrameworkError('There is no message in requests~attach supported by agent.')
Expand Down
32 changes: 25 additions & 7 deletions packages/core/src/utils/__tests__/messageType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,28 +128,46 @@ describe('messageType', () => {
const incomingMessageType = parseMessageType('https://didcomm.org/connections/1.0/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(expectedMessageType, incomingMessageType)).toBe(true)
expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(true)
})

test('returns true when the document uri, protocol name, major version all match and the minor version is higher than the expected minor version', () => {
const incomingMessageType = parseMessageType('https://didcomm.org/connections/1.8/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(expectedMessageType, incomingMessageType)).toBe(true)
expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(true)
})

test('returns true when the document uri, protocol name, major version and minor version all match', () => {
const incomingMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(expectedMessageType, incomingMessageType)).toBe(true)
expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(true)
})

test('returns true when the protocol name, major version and minor version all match and the incoming message type is using the legacy did sov prefix', () => {
const incomingMessageType = parseMessageType('did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.4/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(true)
})

test('returns false when the protocol name, major version and minor version all match and the incoming message type is using the legacy did sov prefix but allowLegacyDidSovPrefixMismatch is set to false', () => {
const incomingMessageType = parseMessageType('did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.4/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(
supportsIncomingMessageType(expectedMessageType, incomingMessageType, {
allowLegacyDidSovPrefixMismatch: false,
})
).toBe(false)
})

test('returns false when the major version does not match', () => {
const incomingMessageType = parseMessageType('https://didcomm.org/connections/2.4/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(expectedMessageType, incomingMessageType)).toBe(false)
expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(false)

const incomingMessageType2 = parseMessageType('https://didcomm.org/connections/2.0/request')
const expectedMessageType2 = parseMessageType('https://didcomm.org/connections/1.4/request')
Expand All @@ -161,21 +179,21 @@ describe('messageType', () => {
const incomingMessageType = parseMessageType('https://didcomm.org/connections/1.4/proposal')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(expectedMessageType, incomingMessageType)).toBe(false)
expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(false)
})

test('returns false when the protocol name does not match', () => {
const incomingMessageType = parseMessageType('https://didcomm.org/issue-credential/1.4/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(expectedMessageType, incomingMessageType)).toBe(false)
expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(false)
})

test('returns false when the document uri does not match', () => {
const incomingMessageType = parseMessageType('https://my-protocol.org/connections/1.4/request')
const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')

expect(supportsIncomingMessageType(expectedMessageType, incomingMessageType)).toBe(false)
expect(supportsIncomingMessageType(incomingMessageType, expectedMessageType)).toBe(false)
})
})

Expand Down
21 changes: 19 additions & 2 deletions packages/core/src/utils/messageType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,36 @@ export function parseMessageType(messageType: string): ParsedMessageType {
* - majorVersion
* - messageName
*
* If allowLegacyDidSovPrefixMismatch is true (default) it will allow for the case where the incoming message type still has the legacy
* did:sov:BzCbsNYhMrjHiqZDTUASHg;spec did prefix, but the expected message type does not. This only works for incoming messages with a prefix
* of did:sov:BzCbsNYhMrjHiqZDTUASHg;spec and the expected message type having a prefix value of https:/didcomm.org
*
* @example
* const incomingMessageType = parseMessageType('https://didcomm.org/connections/1.0/request')
* const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.4/request')
*
* // Returns true because the incoming message type is equal to the expected message type, except for
* // the minor version, which is lower
* const isIncomingMessageTypeSupported = supportsIncomingMessageType(incomingMessageType, expectedMessageType)
*
* @example
* const incomingMessageType = parseMessageType('did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/request')
* const expectedMessageType = parseMessageType('https://didcomm.org/connections/1.0/request')
*
* // Returns true because the incoming message type is equal to the expected message type, except for
* // the legacy did sov prefix.
* const isIncomingMessageTypeSupported = supportsIncomingMessageType(incomingMessageType, expectedMessageType)
*/
export function supportsIncomingMessageType(
incomingMessageType: ParsedMessageType,
expectedMessageType: ParsedMessageType
expectedMessageType: ParsedMessageType,
{ allowLegacyDidSovPrefixMismatch = true }: { allowLegacyDidSovPrefixMismatch?: boolean } = {}
) {
const documentUriMatches = expectedMessageType.documentUri === incomingMessageType.documentUri
const incomingDocumentUri = allowLegacyDidSovPrefixMismatch
? replaceLegacyDidSovPrefix(incomingMessageType.documentUri)
: incomingMessageType.documentUri

const documentUriMatches = expectedMessageType.documentUri === incomingDocumentUri
const protocolNameMatches = expectedMessageType.protocolName === incomingMessageType.protocolName
const majorVersionMatches = expectedMessageType.protocolMajorVersion === incomingMessageType.protocolMajorVersion
const messageNameMatches = expectedMessageType.messageName === incomingMessageType.messageName
Expand Down
24 changes: 24 additions & 0 deletions packages/core/tests/oob.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,30 @@ describe('out of band', () => {
expect(aliceCredentialRecord.state).toBe(CredentialState.OfferReceived)
})

test('process credential offer requests with legacy did:sov prefix on message type based on OOB message', async () => {
const { message } = await faberAgent.credentials.createOffer(credentialTemplate)

// we need to override the message type to use the legacy did:sov prefix
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
message.type = message.type.replace('https://didcomm.org', 'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec')
const { outOfBandInvitation } = await faberAgent.oob.createInvitation({
...issueCredentialConfig,
messages: [message],
})

const urlMessage = outOfBandInvitation.toUrl({ domain: 'http://example.com' })

const aliceCredentialRecordPromise = waitForCredentialRecord(aliceAgent, {
state: CredentialState.OfferReceived,
threadId: message.threadId,
})
await aliceAgent.oob.receiveInvitationFromUrl(urlMessage, receiveInvitationConfig)

const aliceCredentialRecord = await aliceCredentialRecordPromise
expect(aliceCredentialRecord.state).toBe(CredentialState.OfferReceived)
})

test('do not process requests when a connection is not ready', async () => {
const eventListener = jest.fn()
aliceAgent.events.on<AgentMessageReceivedEvent>(AgentEventTypes.AgentMessageReceived, eventListener)
Expand Down

0 comments on commit 82863f3

Please sign in to comment.