Skip to content
Snippets Groups Projects
Commit eab760e2 authored by Steffen Schulze's avatar Steffen Schulze
Browse files

Merge branch 'receive-invitation' into 'main'

feat(ssi-abstraction): create and receive invitation

See merge request eclipse/xfsc/ocm/ocm-engine!20
parents 60de971a 945ae033
No related branches found
No related tags found
No related merge requests found
import { DidDocument } from '@aries-framework/core';
import { EventDidsPublicDid, EventDidsResolve } from '../didEvents.js';
import { EventDidsResolve } from '../didEvents.js';
describe('Did Events', () => {
it('should return module', () => {
jest.requireActual('../didEvents');
});
it.skip('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', () => {
const doc = new DidDocument({ id: 'did:my:id' });
const event = new EventDidsResolve(doc, 'tenantId');
......
......@@ -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 class EventDidcommConnectionsCreateWithSelf extends BaseEvent<ConnectionRecord> {
public static token = 'didcomm.connections.createWithSelf';
......
......@@ -9,6 +9,10 @@ import {
EventDidcommConnectionsGetByIdInput,
EventDidcommConnectionsCreateWithSelfInput,
EventDidcommConnectionsBlockInput,
EventDidcommConnectionsCreateInvitation,
EventDidcommConnectionsCreateInvitationInput,
EventDidcommConnectionsReceiveInvitationFromUrl,
EventDidcommConnectionsReceiveInvitationFromUrlInput,
} from '@ocm/shared';
import { ConnectionsService } from './connections.service.js';
......@@ -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)
public async createConnectionWithSelf(
options: EventDidcommConnectionsCreateWithSelfInput,
......
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AgentModule } from '../agent.module.js';
......@@ -6,7 +7,7 @@ import { ConnectionsController } from './connections.controller.js';
import { ConnectionsService } from './connections.service.js';
@Module({
imports: [AgentModule],
imports: [AgentModule, ConfigModule],
providers: [ConnectionsService],
controllers: [ConnectionsController],
})
......
......@@ -5,9 +5,11 @@ import type {
} from '@aries-framework/core';
import type {
EventDidcommConnectionsBlockInput,
EventDidcommConnectionsCreateInvitationInput,
EventDidcommConnectionsCreateWithSelfInput,
EventDidcommConnectionsGetAllInput,
EventDidcommConnectionsGetByIdInput,
EventDidcommConnectionsReceiveInvitationFromUrlInput,
} from '@ocm/shared';
import {
......@@ -17,6 +19,7 @@ import {
} from '@aries-framework/core';
import { isDid } from '@aries-framework/core/build/utils/did.js';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { MetadataTokens } from '../../common/constants.js';
import { AgentService } from '../agent.service.js';
......@@ -29,6 +32,7 @@ export class ConnectionsService {
public constructor(
agentService: AgentService,
private withTenantService: WithTenantService,
private configService: ConfigService,
) {
this.agent = agentService.agent;
}
......@@ -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({
tenantId,
}: EventDidcommConnectionsCreateWithSelfInput): Promise<ConnectionRecord> {
......
......@@ -5,8 +5,11 @@ import type {
EventDidcommConnectionsCreateWithSelfInput,
EventDidcommConnectionsGetByIdInput,
EventDidcommConnectionsBlockInput,
EventDidcommConnectionsReceiveInvitationFromUrlInput,
EventDidcommConnectionsCreateInvitationInput,
} from '@ocm/shared';
import { ConnectionRecord } from '@aries-framework/core';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { Test } from '@nestjs/testing';
import {
......@@ -14,6 +17,8 @@ import {
EventDidcommConnectionsGetAll,
EventDidcommConnectionsCreateWithSelf,
EventDidcommConnectionsBlock,
EventDidcommConnectionsReceiveInvitationFromUrl,
EventDidcommConnectionsCreateInvitation,
} from '@ocm/shared';
import { firstValueFrom } from 'rxjs';
......@@ -86,6 +91,53 @@ describe('Connections', () => {
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 () => {
const response$ = client.send<
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