Skip to content
Snippets Groups Projects
Commit c0d6281a authored by Berend Sliedrecht's avatar Berend Sliedrecht
Browse files

feat(ssi-abstraction): create and receive invitation


Signed-off-by: default avatarBerend Sliedrecht <berend@animo.id>
parent 45595e8d
No related branches found
No related tags found
No related merge requests found
import { DidDocument } from '@aries-framework/core'; import { DidDocument } from '@aries-framework/core';
import { EventDidsPublicDid, EventDidsResolve } from '../didEvents.js'; import { EventDidsResolve } from '../didEvents.js';
describe('Did Events', () => { describe('Did Events', () => {
it('should return module', () => { it('should return module', () => {
jest.requireActual('../didEvents'); jest.requireActual('../didEvents');
}); });
it('should create get public did event', () => {
const doc = new DidDocument({ id: 'did:web:123.com' });
const event = new EventDidsPublicDid(doc, 'tenantId');
expect(typeof event.id).toStrictEqual('string');
expect(event.type).toStrictEqual('EventDidsPublicDid');
expect(event.timestamp).toBeInstanceOf(Date);
expect(event.instance).toMatchObject(doc);
});
it('should create did resolve event', () => { it('should create did resolve event', () => {
const doc = new DidDocument({ id: 'did:my:id' }); const doc = new DidDocument({ id: 'did:my:id' });
const event = new EventDidsResolve(doc, 'tenantId'); const event = new EventDidsResolve(doc, 'tenantId');
......
...@@ -48,6 +48,51 @@ export class EventDidcommConnectionsGetById extends BaseEvent<ConnectionRecord | ...@@ -48,6 +48,51 @@ export class EventDidcommConnectionsGetById extends BaseEvent<ConnectionRecord |
} }
} }
export type EventDidcommConnectionsCreateInvitationInput = BaseEventInput;
export class EventDidcommConnectionsCreateInvitation extends BaseEvent<{
invitationUrl: string;
}> {
public static token = 'didcomm.connections.createInvitation';
public get instance() {
return this.data;
}
public static fromEvent(e: EventDidcommConnectionsCreateInvitation) {
return new EventDidcommConnectionsCreateInvitation(
e.data,
e.tenantId,
e.id,
e.type,
e.timestamp,
);
}
}
export type EventDidcommConnectionsReceiveInvitationFromUrlInput =
BaseEventInput<{
invitationUrl: string;
}>;
export class EventDidcommConnectionsReceiveInvitationFromUrl extends BaseEvent<ConnectionRecord | null> {
public static token = 'didcomm.connections.receiveInvitationFromUrl';
public get instance() {
return this.data
? JsonTransformer.fromJSON(this.data, ConnectionRecord)
: null;
}
public static fromEvent(e: EventDidcommConnectionsReceiveInvitationFromUrl) {
return new EventDidcommConnectionsReceiveInvitationFromUrl(
e.data,
e.tenantId,
e.id,
e.type,
e.timestamp,
);
}
}
export type EventDidcommConnectionsCreateWithSelfInput = BaseEventInput; export type EventDidcommConnectionsCreateWithSelfInput = BaseEventInput;
export class EventDidcommConnectionsCreateWithSelf extends BaseEvent<ConnectionRecord> { export class EventDidcommConnectionsCreateWithSelf extends BaseEvent<ConnectionRecord> {
public static token = 'didcomm.connections.createWithSelf'; public static token = 'didcomm.connections.createWithSelf';
......
...@@ -9,6 +9,10 @@ import { ...@@ -9,6 +9,10 @@ import {
EventDidcommConnectionsGetByIdInput, EventDidcommConnectionsGetByIdInput,
EventDidcommConnectionsCreateWithSelfInput, EventDidcommConnectionsCreateWithSelfInput,
EventDidcommConnectionsBlockInput, EventDidcommConnectionsBlockInput,
EventDidcommConnectionsCreateInvitation,
EventDidcommConnectionsCreateInvitationInput,
EventDidcommConnectionsReceiveInvitationFromUrl,
EventDidcommConnectionsReceiveInvitationFromUrlInput,
} from '@ocm/shared'; } from '@ocm/shared';
import { ConnectionsService } from './connections.service.js'; import { ConnectionsService } from './connections.service.js';
...@@ -37,6 +41,26 @@ export class ConnectionsController { ...@@ -37,6 +41,26 @@ export class ConnectionsController {
); );
} }
@MessagePattern(EventDidcommConnectionsCreateInvitation.token)
public async createInvitation(
options: EventDidcommConnectionsCreateInvitationInput,
): Promise<EventDidcommConnectionsCreateInvitation> {
return new EventDidcommConnectionsCreateInvitation(
await this.connectionsService.createInvitation(options),
options.tenantId,
);
}
@MessagePattern(EventDidcommConnectionsReceiveInvitationFromUrl.token)
public async receiveInvitationFromUrl(
options: EventDidcommConnectionsReceiveInvitationFromUrlInput,
): Promise<EventDidcommConnectionsReceiveInvitationFromUrl> {
return new EventDidcommConnectionsReceiveInvitationFromUrl(
await this.connectionsService.receiveInvitationFromUrl(options),
options.tenantId,
);
}
@MessagePattern(EventDidcommConnectionsCreateWithSelf.token) @MessagePattern(EventDidcommConnectionsCreateWithSelf.token)
public async createConnectionWithSelf( public async createConnectionWithSelf(
options: EventDidcommConnectionsCreateWithSelfInput, options: EventDidcommConnectionsCreateWithSelfInput,
......
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AgentModule } from '../agent.module.js'; import { AgentModule } from '../agent.module.js';
...@@ -6,7 +7,7 @@ import { ConnectionsController } from './connections.controller.js'; ...@@ -6,7 +7,7 @@ import { ConnectionsController } from './connections.controller.js';
import { ConnectionsService } from './connections.service.js'; import { ConnectionsService } from './connections.service.js';
@Module({ @Module({
imports: [AgentModule], imports: [AgentModule, ConfigModule],
providers: [ConnectionsService], providers: [ConnectionsService],
controllers: [ConnectionsController], controllers: [ConnectionsController],
}) })
......
...@@ -5,9 +5,11 @@ import type { ...@@ -5,9 +5,11 @@ import type {
} from '@aries-framework/core'; } from '@aries-framework/core';
import type { import type {
EventDidcommConnectionsBlockInput, EventDidcommConnectionsBlockInput,
EventDidcommConnectionsCreateInvitationInput,
EventDidcommConnectionsCreateWithSelfInput, EventDidcommConnectionsCreateWithSelfInput,
EventDidcommConnectionsGetAllInput, EventDidcommConnectionsGetAllInput,
EventDidcommConnectionsGetByIdInput, EventDidcommConnectionsGetByIdInput,
EventDidcommConnectionsReceiveInvitationFromUrlInput,
} from '@ocm/shared'; } from '@ocm/shared';
import { import {
...@@ -17,6 +19,7 @@ import { ...@@ -17,6 +19,7 @@ import {
} from '@aries-framework/core'; } from '@aries-framework/core';
import { isDid } from '@aries-framework/core/build/utils/did.js'; import { isDid } from '@aries-framework/core/build/utils/did.js';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { MetadataTokens } from '../../common/constants.js'; import { MetadataTokens } from '../../common/constants.js';
import { AgentService } from '../agent.service.js'; import { AgentService } from '../agent.service.js';
...@@ -29,6 +32,7 @@ export class ConnectionsService { ...@@ -29,6 +32,7 @@ export class ConnectionsService {
public constructor( public constructor(
agentService: AgentService, agentService: AgentService,
private withTenantService: WithTenantService, private withTenantService: WithTenantService,
private configService: ConfigService,
) { ) {
this.agent = agentService.agent; this.agent = agentService.agent;
} }
...@@ -84,6 +88,47 @@ export class ConnectionsService { ...@@ -84,6 +88,47 @@ export class ConnectionsService {
}); });
} }
public async createInvitation({
tenantId,
}: EventDidcommConnectionsCreateInvitationInput): Promise<{
invitationUrl: string;
}> {
const host = this.configService.get<string>('agent.host');
if (!host) {
throw new Error(
'Could not get the `agentHost` from the config. This is required to create an invitation',
);
}
return this.withTenantService.invoke(tenantId, async (t) => {
const { outOfBandInvitation } = await t.oob.createInvitation();
return {
invitationUrl: outOfBandInvitation.toUrl({
domain: host,
}),
};
});
}
public async receiveInvitationFromUrl({
tenantId,
invitationUrl,
}: EventDidcommConnectionsReceiveInvitationFromUrlInput): Promise<ConnectionRecord> {
return this.withTenantService.invoke(tenantId, async (t) => {
const { connectionRecord } =
await t.oob.receiveInvitationFromUrl(invitationUrl);
if (!connectionRecord) {
throw new Error(
'Invitation did not establish a connection. Is it a connection invitation?',
);
}
return connectionRecord;
});
}
public async createConnectionWithSelf({ public async createConnectionWithSelf({
tenantId, tenantId,
}: EventDidcommConnectionsCreateWithSelfInput): Promise<ConnectionRecord> { }: EventDidcommConnectionsCreateWithSelfInput): Promise<ConnectionRecord> {
......
...@@ -5,8 +5,11 @@ import type { ...@@ -5,8 +5,11 @@ import type {
EventDidcommConnectionsCreateWithSelfInput, EventDidcommConnectionsCreateWithSelfInput,
EventDidcommConnectionsGetByIdInput, EventDidcommConnectionsGetByIdInput,
EventDidcommConnectionsBlockInput, EventDidcommConnectionsBlockInput,
EventDidcommConnectionsReceiveInvitationFromUrlInput,
EventDidcommConnectionsCreateInvitationInput,
} from '@ocm/shared'; } from '@ocm/shared';
import { ConnectionRecord } from '@aries-framework/core';
import { ClientsModule, Transport } from '@nestjs/microservices'; import { ClientsModule, Transport } from '@nestjs/microservices';
import { Test } from '@nestjs/testing'; import { Test } from '@nestjs/testing';
import { import {
...@@ -14,6 +17,8 @@ import { ...@@ -14,6 +17,8 @@ import {
EventDidcommConnectionsGetAll, EventDidcommConnectionsGetAll,
EventDidcommConnectionsCreateWithSelf, EventDidcommConnectionsCreateWithSelf,
EventDidcommConnectionsBlock, EventDidcommConnectionsBlock,
EventDidcommConnectionsReceiveInvitationFromUrl,
EventDidcommConnectionsCreateInvitation,
} from '@ocm/shared'; } from '@ocm/shared';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
...@@ -86,6 +91,53 @@ describe('Connections', () => { ...@@ -86,6 +91,53 @@ describe('Connections', () => {
expect(eventInstance.instance).toBeNull(); expect(eventInstance.instance).toBeNull();
}); });
it(EventDidcommConnectionsCreateInvitation.token, async () => {
const response$ = client.send<
EventDidcommConnectionsCreateInvitation,
EventDidcommConnectionsCreateInvitationInput
>(EventDidcommConnectionsCreateInvitation.token, {
tenantId,
});
const response = await firstValueFrom(response$);
const eventInstance =
EventDidcommConnectionsCreateInvitation.fromEvent(response);
expect(eventInstance.instance).toMatchObject({
invitationUrl: expect.any(String),
});
});
it(EventDidcommConnectionsReceiveInvitationFromUrl.token, async () => {
const createInvitationResponse$ = client.send<
EventDidcommConnectionsCreateInvitation,
EventDidcommConnectionsCreateInvitationInput
>(EventDidcommConnectionsCreateInvitation.token, {
tenantId,
});
const createInvitationResponse = await firstValueFrom(
createInvitationResponse$,
);
const createInvitationEventInstance =
EventDidcommConnectionsCreateInvitation.fromEvent(
createInvitationResponse,
);
const { invitationUrl } = createInvitationEventInstance.instance;
const response$ = client.send<
EventDidcommConnectionsReceiveInvitationFromUrl,
EventDidcommConnectionsReceiveInvitationFromUrlInput
>(EventDidcommConnectionsReceiveInvitationFromUrl.token, {
invitationUrl,
tenantId,
});
const response = await firstValueFrom(response$);
const eventInstance =
EventDidcommConnectionsReceiveInvitationFromUrl.fromEvent(response);
expect(eventInstance.instance).toBeInstanceOf(ConnectionRecord);
});
it(EventDidcommConnectionsCreateWithSelf.token, async () => { it(EventDidcommConnectionsCreateWithSelf.token, async () => {
const response$ = client.send< const response$ = client.send<
EventDidcommConnectionsCreateWithSelf, EventDidcommConnectionsCreateWithSelf,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment