-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core): add discover features protocol #390
Merged
TimoGlastra
merged 1 commit into
openwallet-foundation:main
from
TimoGlastra:feature/discover-features
Jul 20, 2021
+318
−4
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,5 +49,8 @@ | |
"rimraf": "~3.0.2", | ||
"tslog": "^3.2.0", | ||
"typescript": "~4.3.0" | ||
}, | ||
"resolutions": { | ||
"@types/node": "^15.14.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,25 @@ | ||
import type { AgentMessage } from './AgentMessage' | ||
import type { AgentMessageProcessedEvent } from './Events' | ||
import type { Handler } from './Handler' | ||
import type { InboundMessageContext } from './models/InboundMessageContext' | ||
|
||
import { Lifecycle, scoped } from 'tsyringe' | ||
|
||
import { AriesFrameworkError } from '../error/AriesFrameworkError' | ||
|
||
import { EventEmitter } from './EventEmitter' | ||
import { AgentEventTypes } from './Events' | ||
import { MessageSender } from './MessageSender' | ||
import { TransportService } from './TransportService' | ||
|
||
@scoped(Lifecycle.ContainerScoped) | ||
class Dispatcher { | ||
private handlers: Handler[] = [] | ||
private messageSender: MessageSender | ||
private transportService: TransportService | ||
private eventEmitter: EventEmitter | ||
|
||
public constructor(messageSender: MessageSender, transportService: TransportService) { | ||
public constructor(messageSender: MessageSender, eventEmitter: EventEmitter) { | ||
this.messageSender = messageSender | ||
this.transportService = transportService | ||
this.eventEmitter = eventEmitter | ||
} | ||
|
||
public registerHandler(handler: Handler) { | ||
|
@@ -34,6 +36,15 @@ class Dispatcher { | |
|
||
const outboundMessage = await handler.handle(messageContext) | ||
|
||
// Emit event that allows to hook into received messages | ||
this.eventEmitter.emit<AgentMessageProcessedEvent>({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Really like this addition |
||
type: AgentEventTypes.AgentMessageProcessed, | ||
payload: { | ||
message: messageContext.message, | ||
connection: messageContext.connection, | ||
}, | ||
}) | ||
|
||
if (outboundMessage) { | ||
await this.messageSender.sendMessage(outboundMessage) | ||
} | ||
|
@@ -54,6 +65,12 @@ class Dispatcher { | |
} | ||
} | ||
} | ||
|
||
public get supportedMessageTypes() { | ||
return this.handlers | ||
.reduce<typeof AgentMessage[]>((all, cur) => [...all, ...cur.supportedMessages], []) | ||
.map((m) => m.type) | ||
} | ||
} | ||
|
||
export { Dispatcher } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
packages/core/src/modules/discover-features/DiscoverFeaturesModule.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { Lifecycle, scoped } from 'tsyringe' | ||
|
||
import { Dispatcher } from '../../agent/Dispatcher' | ||
import { MessageSender } from '../../agent/MessageSender' | ||
import { createOutboundMessage } from '../../agent/helpers' | ||
import { ConnectionService } from '../connections/services' | ||
|
||
import { DiscloseMessageHandler, QueryMessageHandler } from './handlers' | ||
import { DiscoverFeaturesService } from './services' | ||
|
||
@scoped(Lifecycle.ContainerScoped) | ||
export class DiscoverFeaturesModule { | ||
private connectionService: ConnectionService | ||
private messageSender: MessageSender | ||
private discoverFeaturesService: DiscoverFeaturesService | ||
|
||
public constructor( | ||
dispatcher: Dispatcher, | ||
connectionService: ConnectionService, | ||
messageSender: MessageSender, | ||
discoverFeaturesService: DiscoverFeaturesService | ||
) { | ||
this.connectionService = connectionService | ||
this.messageSender = messageSender | ||
this.discoverFeaturesService = discoverFeaturesService | ||
this.registerHandlers(dispatcher) | ||
} | ||
|
||
public async queryFeatures(connectionId: string, options: { query: string; comment?: string }) { | ||
const connection = await this.connectionService.getById(connectionId) | ||
|
||
const queryMessage = await this.discoverFeaturesService.createQuery(options) | ||
|
||
const outbound = createOutboundMessage(connection, queryMessage) | ||
await this.messageSender.sendMessage(outbound) | ||
} | ||
|
||
private registerHandlers(dispatcher: Dispatcher) { | ||
dispatcher.registerHandler(new DiscloseMessageHandler()) | ||
dispatcher.registerHandler(new QueryMessageHandler(this.discoverFeaturesService)) | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
packages/core/src/modules/discover-features/__tests__/DiscoverFeaturesService.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import type { Dispatcher } from '../../../agent/Dispatcher' | ||
|
||
import { DiscoverFeaturesQueryMessage } from '../messages' | ||
import { DiscoverFeaturesService } from '../services/DiscoverFeaturesService' | ||
|
||
const supportedMessageTypes = [ | ||
'https://didcomm.org/connections/1.0/invitation', | ||
'https://didcomm.org/connections/1.0/request', | ||
'https://didcomm.org/connections/1.0/response', | ||
'https://didcomm.org/notification/1.0/ack', | ||
'https://didcomm.org/issue-credential/1.0/credential-proposal', | ||
] | ||
|
||
describe('DiscoverFeaturesService', () => { | ||
const discoverFeaturesService = new DiscoverFeaturesService({ supportedMessageTypes } as Dispatcher) | ||
|
||
describe('createDisclose', () => { | ||
it('should return all protocols when query is *', async () => { | ||
const queryMessage = new DiscoverFeaturesQueryMessage({ | ||
query: '*', | ||
}) | ||
|
||
const message = await discoverFeaturesService.createDisclose(queryMessage) | ||
|
||
expect(message.protocols.map((p) => p.protocolId)).toStrictEqual([ | ||
'https://didcomm.org/connections/1.0/', | ||
'https://didcomm.org/notification/1.0/', | ||
'https://didcomm.org/issue-credential/1.0/', | ||
]) | ||
}) | ||
|
||
it('should return only one protocol if the query specifies a specific protocol', async () => { | ||
const queryMessage = new DiscoverFeaturesQueryMessage({ | ||
query: 'https://didcomm.org/connections/1.0/', | ||
}) | ||
|
||
const message = await discoverFeaturesService.createDisclose(queryMessage) | ||
|
||
expect(message.protocols.map((p) => p.protocolId)).toStrictEqual(['https://didcomm.org/connections/1.0/']) | ||
}) | ||
|
||
it('should respect a wild card at the end of the query', async () => { | ||
const queryMessage = new DiscoverFeaturesQueryMessage({ | ||
query: 'https://didcomm.org/connections/*', | ||
}) | ||
|
||
const message = await discoverFeaturesService.createDisclose(queryMessage) | ||
|
||
expect(message.protocols.map((p) => p.protocolId)).toStrictEqual(['https://didcomm.org/connections/1.0/']) | ||
}) | ||
}) | ||
|
||
describe('createQuery', () => { | ||
it('should return a query message with the query and comment', async () => { | ||
const message = await discoverFeaturesService.createQuery({ | ||
query: '*', | ||
comment: 'Hello', | ||
}) | ||
|
||
expect(message.query).toBe('*') | ||
expect(message.comment).toBe('Hello') | ||
}) | ||
}) | ||
}) |
13 changes: 13 additions & 0 deletions
13
packages/core/src/modules/discover-features/handlers/DiscloseMessageHandler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import type { Handler, HandlerInboundMessage } from '../../../agent/Handler' | ||
|
||
import { DiscoverFeaturesDiscloseMessage } from '../messages' | ||
|
||
export class DiscloseMessageHandler implements Handler { | ||
public supportedMessages = [DiscoverFeaturesDiscloseMessage] | ||
|
||
public async handle(inboundMessage: HandlerInboundMessage<DiscloseMessageHandler>) { | ||
// We don't really need to do anything with this at the moment | ||
// The result can be hooked into through the generic message processed event | ||
inboundMessage.assertReadyConnection() | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
packages/core/src/modules/discover-features/handlers/QueryMessageHandler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type { Handler, HandlerInboundMessage } from '../../../agent/Handler' | ||
import type { DiscoverFeaturesService } from '../services/DiscoverFeaturesService' | ||
|
||
import { createOutboundMessage } from '../../../agent/helpers' | ||
import { DiscoverFeaturesQueryMessage } from '../messages' | ||
|
||
export class QueryMessageHandler implements Handler { | ||
private discoverFeaturesService: DiscoverFeaturesService | ||
public supportedMessages = [DiscoverFeaturesQueryMessage] | ||
|
||
public constructor(discoverFeaturesService: DiscoverFeaturesService) { | ||
this.discoverFeaturesService = discoverFeaturesService | ||
} | ||
|
||
public async handle(inboundMessage: HandlerInboundMessage<QueryMessageHandler>) { | ||
const connection = inboundMessage.assertReadyConnection() | ||
|
||
const discloseMessage = await this.discoverFeaturesService.createDisclose(inboundMessage.message) | ||
|
||
return createOutboundMessage(connection, discloseMessage) | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
packages/core/src/modules/discover-features/handlers/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './DiscloseMessageHandler' | ||
export * from './QueryMessageHandler' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './DiscoverFeaturesModule' | ||
export * from './handlers' | ||
export * from './messages' | ||
export * from './services' |
54 changes: 54 additions & 0 deletions
54
packages/core/src/modules/discover-features/messages/DiscoverFeaturesDiscloseMessage.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { Expose, Type } from 'class-transformer' | ||
import { Equals, IsInstance, IsOptional, IsString } from 'class-validator' | ||
|
||
import { AgentMessage } from '../../../agent/AgentMessage' | ||
|
||
export interface DiscloseProtocolOptions { | ||
protocolId: string | ||
roles?: string[] | ||
} | ||
|
||
export class DiscloseProtocol { | ||
public constructor(options: DiscloseProtocolOptions) { | ||
if (options) { | ||
this.protocolId = options.protocolId | ||
this.roles = options.roles | ||
} | ||
} | ||
|
||
@Expose({ name: 'pid' }) | ||
@IsString() | ||
public protocolId!: string | ||
|
||
@IsString({ each: true }) | ||
@IsOptional() | ||
public roles?: string[] | ||
} | ||
|
||
export interface DiscoverFeaturesDiscloseMessageOptions { | ||
id?: string | ||
threadId: string | ||
protocols: DiscloseProtocolOptions[] | ||
} | ||
|
||
export class DiscoverFeaturesDiscloseMessage extends AgentMessage { | ||
public constructor(options: DiscoverFeaturesDiscloseMessageOptions) { | ||
super() | ||
|
||
if (options) { | ||
this.id = options.id ?? this.generateId() | ||
this.protocols = options.protocols.map((p) => new DiscloseProtocol(p)) | ||
this.setThread({ | ||
threadId: options.threadId, | ||
}) | ||
} | ||
} | ||
|
||
@Equals(DiscoverFeaturesDiscloseMessage.type) | ||
public readonly type = DiscoverFeaturesDiscloseMessage.type | ||
public static readonly type = 'https://didcomm.org/discover-features/1.0/disclose' | ||
|
||
@IsInstance(DiscloseProtocol, { each: true }) | ||
@Type(() => DiscloseProtocol) | ||
public protocols!: DiscloseProtocol[] | ||
} |
32 changes: 32 additions & 0 deletions
32
packages/core/src/modules/discover-features/messages/DiscoverFeaturesQueryMessage.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Equals, IsOptional, IsString } from 'class-validator' | ||
|
||
import { AgentMessage } from '../../../agent/AgentMessage' | ||
|
||
export interface DiscoverFeaturesQueryMessageOptions { | ||
id?: string | ||
query: string | ||
comment?: string | ||
} | ||
|
||
export class DiscoverFeaturesQueryMessage extends AgentMessage { | ||
public constructor(options: DiscoverFeaturesQueryMessageOptions) { | ||
super() | ||
|
||
if (options) { | ||
this.id = options.id ?? this.generateId() | ||
this.query = options.query | ||
this.comment = options.comment | ||
} | ||
} | ||
|
||
@Equals(DiscoverFeaturesQueryMessage.type) | ||
public readonly type = DiscoverFeaturesQueryMessage.type | ||
public static readonly type = 'https://didcomm.org/discover-features/1.0/query' | ||
|
||
@IsString() | ||
public query!: string | ||
|
||
@IsString() | ||
@IsOptional() | ||
public comment?: string | ||
} |
2 changes: 2 additions & 0 deletions
2
packages/core/src/modules/discover-features/messages/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './DiscoverFeaturesDiscloseMessage' | ||
export * from './DiscoverFeaturesQueryMessage' |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@types/node v16 was released recently which causes errors with some the types. I'm not sure if it is an error in the types (the error seems weird), so for now we can stick to types of node 15