Skip to content

Commit

Permalink
feat(routing): support did:key in RFC0211 (openwallet-foundation#950)
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <[email protected]>
  • Loading branch information
TimoGlastra authored Jul 15, 2022
1 parent f48f3c1 commit dc45c01
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { injectable } from '../../../plugins'
import { JsonTransformer } from '../../../utils'
import { ConnectionService } from '../../connections/services/ConnectionService'
import { Key } from '../../dids'
import { didKeyToVerkey } from '../../dids/helpers'
import { ProblemReportError } from '../../problem-reports'
import { RoutingEventTypes } from '../RoutingEvents'
import { RoutingProblemReportReason } from '../error'
Expand Down Expand Up @@ -112,7 +113,10 @@ export class MediationRecipientService {

// Update record
mediationRecord.endpoint = messageContext.message.endpoint
mediationRecord.routingKeys = messageContext.message.routingKeys

// According to RFC 0211 keys should be a did key, but base58 encoded verkey was used before
// RFC was accepted. This converts the key to a public key base58 if it is a did key.
mediationRecord.routingKeys = messageContext.message.routingKeys.map(didKeyToVerkey)
return await this.updateState(mediationRecord, MediationState.Granted)
}

Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/modules/routing/services/MediatorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AriesFrameworkError } from '../../../error'
import { inject, injectable } from '../../../plugins'
import { JsonTransformer } from '../../../utils/JsonTransformer'
import { Wallet } from '../../../wallet/Wallet'
import { didKeyToVerkey } from '../../dids/helpers'
import { RoutingEventTypes } from '../RoutingEvents'
import {
KeylistUpdateAction,
Expand Down Expand Up @@ -118,13 +119,18 @@ export class MediatorService {
recipientKey: update.recipientKey,
result: KeylistUpdateResult.NoChange,
})

// According to RFC 0211 key should be a did key, but base58 encoded verkey was used before
// RFC was accepted. This converts the key to a public key base58 if it is a did key.
const publicKeyBase58 = didKeyToVerkey(update.recipientKey)

if (update.action === KeylistUpdateAction.add) {
mediationRecord.addRecipientKey(update.recipientKey)
mediationRecord.addRecipientKey(publicKeyBase58)
updated.result = KeylistUpdateResult.Success

keylist.push(updated)
} else if (update.action === KeylistUpdateAction.remove) {
const success = mediationRecord.removeRecipientKey(update.recipientKey)
const success = mediationRecord.removeRecipientKey(publicKeyBase58)
updated.result = success ? KeylistUpdateResult.Success : KeylistUpdateResult.NoChange
keylist.push(updated)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ import { ConnectionRepository } from '../../../connections/repository/Connection
import { ConnectionService } from '../../../connections/services/ConnectionService'
import { Key } from '../../../dids'
import { DidRepository } from '../../../dids/repository/DidRepository'
import { DeliveryRequestMessage, MessageDeliveryMessage, MessagesReceivedMessage, StatusMessage } from '../../messages'
import {
DeliveryRequestMessage,
MediationGrantMessage,
MessageDeliveryMessage,
MessagesReceivedMessage,
StatusMessage,
} from '../../messages'
import { MediationRole, MediationState } from '../../models'
import { MediationRecord } from '../../repository/MediationRecord'
import { MediationRepository } from '../../repository/MediationRepository'
Expand Down Expand Up @@ -93,6 +99,38 @@ describe('MediationRecipientService', () => {
)
})

describe('processMediationGrant', () => {
test('should process base58 encoded routing keys', async () => {
mediationRecord.state = MediationState.Requested
const mediationGrant = new MediationGrantMessage({
endpoint: 'http://agent.com:8080',
routingKeys: ['79CXkde3j8TNuMXxPdV7nLUrT2g7JAEjH5TreyVY7GEZ'],
threadId: 'threadId',
})

const messageContext = new InboundMessageContext(mediationGrant, { connection: mockConnection })

await mediationRecipientService.processMediationGrant(messageContext)

expect(mediationRecord.routingKeys).toEqual(['79CXkde3j8TNuMXxPdV7nLUrT2g7JAEjH5TreyVY7GEZ'])
})

test('should process did:key encoded routing keys', async () => {
mediationRecord.state = MediationState.Requested
const mediationGrant = new MediationGrantMessage({
endpoint: 'http://agent.com:8080',
routingKeys: ['did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th'],
threadId: 'threadId',
})

const messageContext = new InboundMessageContext(mediationGrant, { connection: mockConnection })

await mediationRecipientService.processMediationGrant(messageContext)

expect(mediationRecord.routingKeys).toEqual(['8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K'])
})
})

describe('createStatusRequest', () => {
it('creates a status request message', async () => {
const statusRequestMessage = await mediationRecipientService.createStatusRequest(mediationRecord, {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { getAgentConfig, getMockConnection, mockFunction } from '../../../../../tests/helpers'
import { EventEmitter } from '../../../../agent/EventEmitter'
import { InboundMessageContext } from '../../../../agent/models/InboundMessageContext'
import { IndyWallet } from '../../../../wallet/IndyWallet'
import { DidExchangeState } from '../../../connections'
import { KeylistUpdateAction, KeylistUpdateMessage } from '../../messages'
import { MediationRole, MediationState } from '../../models'
import { MediationRecord } from '../../repository'
import { MediationRepository } from '../../repository/MediationRepository'
import { MediatorRoutingRepository } from '../../repository/MediatorRoutingRepository'
import { MediatorService } from '../MediatorService'

const agentConfig = getAgentConfig('MediatorService')

jest.mock('../../repository/MediationRepository')
const MediationRepositoryMock = MediationRepository as jest.Mock<MediationRepository>

jest.mock('../../repository/MediatorRoutingRepository')
const MediatorRoutingRepositoryMock = MediatorRoutingRepository as jest.Mock<MediatorRoutingRepository>

jest.mock('../../../../wallet/IndyWallet')
const WalletMock = IndyWallet as jest.Mock<IndyWallet>

const mediationRepository = new MediationRepositoryMock()
const mediatorRoutingRepository = new MediatorRoutingRepositoryMock()

const wallet = new WalletMock()

const mediatorService = new MediatorService(
mediationRepository,
mediatorRoutingRepository,
agentConfig,
wallet,
new EventEmitter(agentConfig)
)

const mockConnection = getMockConnection({
state: DidExchangeState.Completed,
})

describe('MediatorService', () => {
describe('processKeylistUpdateRequest', () => {
test('processes base58 encoded recipient keys', async () => {
const mediationRecord = new MediationRecord({
connectionId: 'connectionId',
role: MediationRole.Mediator,
state: MediationState.Granted,
threadId: 'threadId',
recipientKeys: ['8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K'],
})

mockFunction(mediationRepository.getByConnectionId).mockResolvedValue(mediationRecord)

const keyListUpdate = new KeylistUpdateMessage({
updates: [
{
action: KeylistUpdateAction.add,
recipientKey: '79CXkde3j8TNuMXxPdV7nLUrT2g7JAEjH5TreyVY7GEZ',
},
{
action: KeylistUpdateAction.remove,
recipientKey: '8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K',
},
],
})

const messageContext = new InboundMessageContext(keyListUpdate, { connection: mockConnection })
await mediatorService.processKeylistUpdateRequest(messageContext)

expect(mediationRecord.recipientKeys).toEqual(['79CXkde3j8TNuMXxPdV7nLUrT2g7JAEjH5TreyVY7GEZ'])
})

test('processes did:key encoded recipient keys', async () => {
const mediationRecord = new MediationRecord({
connectionId: 'connectionId',
role: MediationRole.Mediator,
state: MediationState.Granted,
threadId: 'threadId',
recipientKeys: ['8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K'],
})

mockFunction(mediationRepository.getByConnectionId).mockResolvedValue(mediationRecord)

const keyListUpdate = new KeylistUpdateMessage({
updates: [
{
action: KeylistUpdateAction.add,
recipientKey: 'did:key:z6MkkbTaLstV4fwr1rNf5CSxdS2rGbwxi3V5y6NnVFTZ2V1w',
},
{
action: KeylistUpdateAction.remove,
recipientKey: 'did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th',
},
],
})

const messageContext = new InboundMessageContext(keyListUpdate, { connection: mockConnection })
await mediatorService.processKeylistUpdateRequest(messageContext)

expect(mediationRecord.recipientKeys).toEqual(['79CXkde3j8TNuMXxPdV7nLUrT2g7JAEjH5TreyVY7GEZ'])
})
})
})

0 comments on commit dc45c01

Please sign in to comment.