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

fix(ssi): do not register did by default but make it an event


Signed-off-by: default avatarBerend Sliedrecht <berend@animo.id>
parent 7c96c9c3
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !15. Comments created here will be created in the context of that merge request.
Showing
with 678 additions and 137 deletions
import type { BaseEventInput } from './baseEvents.js';
import type { AnonCredsCredentialDefinition } from '@aries-framework/anoncreds';
import { BaseEvent } from './baseEvents.js';
export type CredentialDefinitionWithId = AnonCredsCredentialDefinition & {
credentialDefinitionId: string;
};
export type EventAnonCredsCredentialDefinitionsGetAllInput = BaseEventInput;
export class EventAnonCredsCredentialDefinitionsGetAll extends BaseEvent<
Array<CredentialDefinitionWithId>
> {
public static token = 'anoncreds.credentialDefinitions.getAll';
public get instance() {
return this.data;
}
public static fromEvent(e: EventAnonCredsCredentialDefinitionsGetAll) {
return new EventAnonCredsCredentialDefinitionsGetAll(
e.data,
e.tenantId,
e.id,
e.type,
e.timestamp,
);
}
}
export type EventAnonCredsCredentialDefinitionsGetByIdInput = BaseEventInput<{
credentialDefinitionId: string;
}>;
export class EventAnonCredsCredentialDefinitionsGetById extends BaseEvent<CredentialDefinitionWithId | null> {
public static token = 'anoncreds.credentialDefinitions.getById';
public get instance() {
return this.data;
}
public static fromEvent(e: EventAnonCredsCredentialDefinitionsGetById) {
return new EventAnonCredsCredentialDefinitionsGetById(
e.data,
e.tenantId,
e.id,
e.type,
e.timestamp,
);
}
}
export type EventAnonCredsCredentialDefinitionsRegisterInput = BaseEventInput<{
schemaId: string;
tag: string;
issuerDid: string;
}>;
export class EventAnonCredsCredentialDefinitionsRegister extends BaseEvent<CredentialDefinitionWithId> {
public static token = 'anoncreds.credentialDefinitions.register';
public get instance() {
return this.data;
}
public static fromEvent(e: EventAnonCredsCredentialDefinitionsRegister) {
return new EventAnonCredsCredentialDefinitionsRegister(
e.data,
e.tenantId,
e.id,
e.type,
e.timestamp,
);
}
}
...@@ -4,44 +4,36 @@ import { DidDocument, JsonTransformer } from '@aries-framework/core'; ...@@ -4,44 +4,36 @@ import { DidDocument, JsonTransformer } from '@aries-framework/core';
import { BaseEvent } from './baseEvents.js'; import { BaseEvent } from './baseEvents.js';
/** export type EventDidsResolveInput = BaseEventInput<{ did: string }>;
* export class EventDidsResolve extends BaseEvent<DidDocument> {
* @todo: this should be removed as it is a weird event that should not be needed public static token = 'dids.resolve';
*
*/
export type EventDidsPublicDidInput = BaseEventInput;
/**
*
* @todo: this should be removed as it is a weird event that should not be needed
*
*/
export class EventDidsPublicDid extends BaseEvent<DidDocument> {
public static token = 'dids.publicDid';
public get instance() { public get instance() {
return JsonTransformer.fromJSON(this.data, DidDocument); return JsonTransformer.fromJSON(this.data, DidDocument);
} }
public static fromEvent(e: EventDidsPublicDid) { public static fromEvent(e: EventDidsResolve) {
return new EventDidsPublicDid( return new EventDidsResolve(e.data, e.tenantId, e.id, e.type, e.timestamp);
e.data,
e.tenantId,
e.id,
e.type,
e.timestamp,
);
} }
} }
export type EventDidsResolveInput = BaseEventInput<{ did: string }>; export type EventDidsRegisterIndyFromSeedInput = BaseEventInput<{
export class EventDidsResolve extends BaseEvent<DidDocument> { seed: string;
public static token = 'dids.resolve'; }>;
export class EventDidsRegisterIndyFromSeed extends BaseEvent<Array<string>> {
public static token = 'dids.register.indy.fromSeed';
public get instance() { public get instance() {
return JsonTransformer.fromJSON(this.data, DidDocument); return this.data;
} }
public static fromEvent(e: EventDidsResolve) { public static fromEvent(e: EventDidsRegisterIndyFromSeed) {
return new EventDidsResolve(e.data, e.tenantId, e.id, e.type, e.timestamp); return new EventDidsRegisterIndyFromSeed(
e.data,
e.tenantId,
e.id,
e.type,
e.timestamp,
);
} }
} }
...@@ -8,3 +8,4 @@ export * from './events/connectionEvents.js'; ...@@ -8,3 +8,4 @@ export * from './events/connectionEvents.js';
export * from './events/didEvents.js'; export * from './events/didEvents.js';
export * from './events/tenantEvents.js'; export * from './events/tenantEvents.js';
export * from './events/schemaEvents.js'; export * from './events/schemaEvents.js';
export * from './events/credentialDefinitionEvents.js';
...@@ -16,11 +16,9 @@ import { ...@@ -16,11 +16,9 @@ import {
JwkDidResolver, JwkDidResolver,
KeyDidRegistrar, KeyDidRegistrar,
KeyDidResolver, KeyDidResolver,
KeyType,
LogLevel, LogLevel,
PeerDidRegistrar, PeerDidRegistrar,
PeerDidResolver, PeerDidResolver,
TypedArrayEncoder,
WebDidResolver, WebDidResolver,
} from '@aries-framework/core'; } from '@aries-framework/core';
import { import {
...@@ -40,7 +38,6 @@ import { logger } from '@ocm/shared'; ...@@ -40,7 +38,6 @@ import { logger } from '@ocm/shared';
import { LEDGERS } from '../config/ledger.js'; import { LEDGERS } from '../config/ledger.js';
import { registerPublicDids } from './ledger/register.js';
import { AgentLogger } from './logger.js'; import { AgentLogger } from './logger.js';
export type AppAgent = Agent<AgentService['modules']>; export type AppAgent = Agent<AgentService['modules']>;
...@@ -127,7 +124,7 @@ export class AgentService implements OnApplicationShutdown { ...@@ -127,7 +124,7 @@ export class AgentService implements OnApplicationShutdown {
}; };
} }
public get ledgers() { private get ledgers() {
const ledgerIds = this.configService.get('agent.ledgerIds'); const ledgerIds = this.configService.get('agent.ledgerIds');
if (!ledgerIds || ledgerIds.length < 1 || ledgerIds[0] === '') { if (!ledgerIds || ledgerIds.length < 1 || ledgerIds[0] === '') {
...@@ -153,41 +150,8 @@ export class AgentService implements OnApplicationShutdown { ...@@ -153,41 +150,8 @@ export class AgentService implements OnApplicationShutdown {
}); });
} }
private async registerPublicDid() {
const { publicDidSeed, ledgerIds } = this.configService.get('agent');
if (!publicDidSeed) {
logger.info('No public did seed provided, skipping registration');
return;
}
if (!ledgerIds || ledgerIds.length < 1 || ledgerIds[0] === '') {
return;
}
const registeredPublicDidResponses = await registerPublicDids({
alias: this.config.label,
ledgerIds,
seed: publicDidSeed,
});
for (const publicDidResponse of registeredPublicDidResponses) {
await this.agent.dids.import({
overwrite: true,
did: publicDidResponse.did,
privateKeys: [
{
keyType: KeyType.Ed25519,
privateKey: TypedArrayEncoder.fromString(publicDidSeed),
},
],
});
}
}
public async onModuleInit() { public async onModuleInit() {
await this.agent.initialize(); await this.agent.initialize();
await this.registerPublicDid();
logger.info('Agent initialized'); logger.info('Agent initialized');
} }
......
import type { AnonCredsCredentialDefinition } from '@aries-framework/anoncreds';
import { Test } from '@nestjs/testing';
import { mockConfigModule } from '../../../config/__tests__/mockConfig.js';
import { AgentModule } from '../../agent.module.js';
import { CredentialDefinitionsController } from '../credentialDefinitions.controller.js';
import { CredentialDefinitionsService } from '../credentialDefinitions.service.js';
describe('CredentialDefinitionsController', () => {
let credentialDefinitionsController: CredentialDefinitionsController;
let credentialDefinitionsService: CredentialDefinitionsService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [mockConfigModule(), AgentModule],
controllers: [CredentialDefinitionsController],
providers: [CredentialDefinitionsService],
}).compile();
credentialDefinitionsService = moduleRef.get(CredentialDefinitionsService);
credentialDefinitionsController = moduleRef.get(
CredentialDefinitionsController,
);
});
describe('get all', () => {
it('should get all the registered credentialDefinitions of the agent', async () => {
const result: Array<AnonCredsCredentialDefinition> = [];
jest
.spyOn(credentialDefinitionsService, 'getAll')
.mockResolvedValue(result);
const event = await credentialDefinitionsController.getAll({
tenantId: 'some-id',
});
expect(event.data).toStrictEqual(result);
});
});
describe('get by id', () => {
it('should get a credentialDefinition by id', async () => {
const result: AnonCredsCredentialDefinition | null = null;
jest
.spyOn(credentialDefinitionsService, 'getById')
.mockResolvedValue(result);
const event = await credentialDefinitionsController.getById({
credentialDefinitionId: 'id',
tenantId: 'some-id',
});
expect(event.data).toStrictEqual(result);
});
});
describe('register credentialDefinition', () => {
it('should register a credentialDefinition on a ledger', async () => {
const result: AnonCredsCredentialDefinition = {
tag: 'some-tag',
type: 'CL',
issuerId: 'did:indy:issuer',
schemaId: 'schemaid:123:default',
value: {
primary: {},
},
};
jest
.spyOn(credentialDefinitionsService, 'register')
.mockResolvedValue(result);
const event = await credentialDefinitionsController.register({
tenantId: 'some-tenant-id',
tag: 'some-tag',
issuerDid: 'did:indy:issuer',
schemaId: 'schemaid:123:default',
});
expect(event.data).toStrictEqual(result);
});
});
});
import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
import {
EventAnonCredsCredentialDefinitionsGetAll,
EventAnonCredsCredentialDefinitionsGetAllInput,
EventAnonCredsCredentialDefinitionsGetById,
EventAnonCredsCredentialDefinitionsGetByIdInput,
EventAnonCredsCredentialDefinitionsRegister,
EventAnonCredsCredentialDefinitionsRegisterInput,
} from '@ocm/shared';
import { CredentialDefinitionsService } from './credentialDefinitions.service.js';
@Controller('credentialDefinitions')
export class CredentialDefinitionsController {
public constructor(
private credentialDefinitionsService: CredentialDefinitionsService,
) {}
@MessagePattern(EventAnonCredsCredentialDefinitionsGetAll.token)
public async getAll(
options: EventAnonCredsCredentialDefinitionsGetAllInput,
): Promise<EventAnonCredsCredentialDefinitionsGetAll> {
return new EventAnonCredsCredentialDefinitionsGetAll(
await this.credentialDefinitionsService.getAll(options),
options.tenantId,
);
}
@MessagePattern(EventAnonCredsCredentialDefinitionsGetById.token)
public async getById(
options: EventAnonCredsCredentialDefinitionsGetByIdInput,
): Promise<EventAnonCredsCredentialDefinitionsGetById> {
return new EventAnonCredsCredentialDefinitionsGetById(
await this.credentialDefinitionsService.getById(options),
options.tenantId,
);
}
@MessagePattern(EventAnonCredsCredentialDefinitionsRegister.token)
public async register(
options: EventAnonCredsCredentialDefinitionsRegisterInput,
): Promise<EventAnonCredsCredentialDefinitionsRegister> {
return new EventAnonCredsCredentialDefinitionsRegister(
await this.credentialDefinitionsService.register(options),
options.tenantId,
);
}
}
import { Module } from '@nestjs/common';
import { AgentModule } from '../agent.module.js';
import { CredentialDefinitionsController } from './credentialDefinitions.controller.js';
import { CredentialDefinitionsService } from './credentialDefinitions.service.js';
@Module({
imports: [AgentModule],
providers: [CredentialDefinitionsService],
controllers: [CredentialDefinitionsController],
})
export class CredentialDefinitionsModule {}
import type { AnonCredsCredentialDefinition } from '@aries-framework/anoncreds';
import type { IndyVdrRegisterCredentialDefinitionOptions } from '@aries-framework/indy-vdr';
import type {
EventAnonCredsCredentialDefinitionsGetAllInput,
EventAnonCredsCredentialDefinitionsGetByIdInput,
EventAnonCredsCredentialDefinitionsRegisterInput,
} from '@ocm/shared';
import { Injectable } from '@nestjs/common';
import { WithTenantService } from '../withTenantService.js';
@Injectable()
export class CredentialDefinitionsService {
public withTenantService: WithTenantService;
public constructor(withTenantService: WithTenantService) {
this.withTenantService = withTenantService;
}
public async getAll({
tenantId,
}: EventAnonCredsCredentialDefinitionsGetAllInput): Promise<
Array<AnonCredsCredentialDefinition>
> {
return this.withTenantService.invoke(tenantId, async (t) =>
(await t.modules.anoncreds.getCreatedCredentialDefinitions({})).map(
(r) => r.credentialDefinition,
),
);
}
public async getById({
tenantId,
credentialDefinitionId,
}: EventAnonCredsCredentialDefinitionsGetByIdInput): Promise<AnonCredsCredentialDefinition | null> {
return this.withTenantService.invoke(tenantId, async (t) => {
const { credentialDefinition } =
await t.modules.anoncreds.getCredentialDefinition(
credentialDefinitionId,
);
return credentialDefinition ?? null;
});
}
public async register({
tenantId,
schemaId,
issuerDid,
tag,
}: EventAnonCredsCredentialDefinitionsRegisterInput): Promise<
AnonCredsCredentialDefinition & { credentialDefinitionId: string }
> {
return this.withTenantService.invoke(tenantId, async (t) => {
const { credentialDefinitionState } =
await t.modules.anoncreds.registerCredentialDefinition<IndyVdrRegisterCredentialDefinitionOptions>(
{
credentialDefinition: {
issuerId: issuerDid,
type: 'CL',
schemaId,
tag,
},
options: {
endorserMode: 'internal',
endorserDid: issuerDid,
},
},
);
if (credentialDefinitionState.state !== 'finished') {
throw new Error(
`Error registering credentialDefinition: ${
credentialDefinitionState.state === 'failed'
? credentialDefinitionState.reason
: 'Not Finished'
}`,
);
}
return {
credentialDefinitionId:
credentialDefinitionState.credentialDefinitionId,
...credentialDefinitionState.credentialDefinition,
};
});
}
}
...@@ -34,4 +34,20 @@ describe('DidsController', () => { ...@@ -34,4 +34,20 @@ describe('DidsController', () => {
expect(event.data).toStrictEqual(result); expect(event.data).toStrictEqual(result);
}); });
}); });
describe('register indy did from seed', () => {
it('should register an indy did from seed', async () => {
const result = ['did:indy:bcovrin:test:mock'];
jest
.spyOn(didsService, 'registerDidIndyFromSeed')
.mockResolvedValue(result);
const event = await didsController.registerFromSeed({
seed: 'random-secure-seed',
tenantId: 'some-id',
});
expect(event.data).toStrictEqual(result);
});
});
}); });
import { Controller } from '@nestjs/common'; import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices'; import { MessagePattern } from '@nestjs/microservices';
import { import {
EventDidsPublicDid, EventDidsRegisterIndyFromSeed,
EventDidsPublicDidInput, EventDidsRegisterIndyFromSeedInput,
EventDidsResolve, EventDidsResolve,
EventDidsResolveInput, EventDidsResolveInput,
} from '@ocm/shared'; } from '@ocm/shared';
...@@ -13,10 +13,10 @@ import { DidsService } from './dids.service.js'; ...@@ -13,10 +13,10 @@ import { DidsService } from './dids.service.js';
export class DidsController { export class DidsController {
public constructor(private didsService: DidsService) {} public constructor(private didsService: DidsService) {}
@MessagePattern(EventDidsPublicDid.token) @MessagePattern(EventDidsRegisterIndyFromSeed.token)
public async publicDid(options: EventDidsPublicDidInput) { public async registerFromSeed(options: EventDidsRegisterIndyFromSeedInput) {
return new EventDidsPublicDid( return new EventDidsRegisterIndyFromSeed(
await this.didsService.getPublicDid(options), await this.didsService.registerDidIndyFromSeed(options),
options.tenantId, options.tenantId,
); );
} }
......
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 { DidsController } from './dids.controller.js'; ...@@ -6,7 +7,7 @@ import { DidsController } from './dids.controller.js';
import { DidsService } from './dids.service.js'; import { DidsService } from './dids.service.js';
@Module({ @Module({
imports: [AgentModule ], imports: [AgentModule, ConfigModule],
providers: [DidsService], providers: [DidsService],
controllers: [DidsController], controllers: [DidsController],
}) })
......
import type { import type { EventDidsResolveInput } from '@ocm/shared';
EventDidsPublicDidInput,
EventDidsResolveInput,
} from '@ocm/shared';
import { KeyType, TypedArrayEncoder } from '@aries-framework/core';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { registerPublicDids } from '../ledger/register.js';
import { WithTenantService } from '../withTenantService.js'; import { WithTenantService } from '../withTenantService.js';
@Injectable() @Injectable()
export class DidsService { export class DidsService {
public withTenantService: WithTenantService; private withTenantService: WithTenantService;
private configService: ConfigService;
public constructor(withTenantService: WithTenantService) { public constructor(
withTenantService: WithTenantService,
configService: ConfigService,
) {
this.withTenantService = withTenantService; this.withTenantService = withTenantService;
this.configService = configService;
} }
public async resolve({ did, tenantId }: EventDidsResolveInput) { public async resolve({ did, tenantId }: EventDidsResolveInput) {
...@@ -34,26 +39,35 @@ export class DidsService { ...@@ -34,26 +39,35 @@ export class DidsService {
}); });
} }
public async getPublicDid({ tenantId }: EventDidsPublicDidInput) { public async registerDidIndyFromSeed({
return this.withTenantService.invoke(tenantId, async (t) => { tenantId,
const dids = await t.dids.getCreatedDids({ method: 'indy' }); seed,
if (dids.length === 0) { }: {
throw new Error('No registered public DIDs'); tenantId: string;
} seed: string;
}): Promise<Array<string>> {
const ledgerIds = this.configService.get('agent.ledgerIds');
if (dids.length > 1) { const registeredPublicDidResponses = await registerPublicDids({
throw new Error('Multiple public DIDs found'); ledgerIds,
} seed,
});
const didRecord = dids[0]; for (const publicDidResponse of registeredPublicDidResponses) {
await this.withTenantService.invoke(tenantId, (t) =>
t.dids.import({
overwrite: true,
did: publicDidResponse.did,
privateKeys: [
{
keyType: KeyType.Ed25519,
privateKey: TypedArrayEncoder.fromString(seed),
},
],
}),
);
}
if (!didRecord.didDocument) { return registeredPublicDidResponses.map((r) => r.did);
throw new Error(
'A public DID was found, but did not include a DID Document',
);
}
return didRecord.didDocument;
});
} }
} }
...@@ -6,14 +6,12 @@ import axios from 'axios'; ...@@ -6,14 +6,12 @@ import axios from 'axios';
import { LEDGERS } from '../../config/ledger.js'; import { LEDGERS } from '../../config/ledger.js';
type RegisterPublicDidOptions = { type RegisterPublicDidOptions = {
alias: string;
ledgerIds: Array<LedgerIds>; ledgerIds: Array<LedgerIds>;
seed: string; seed: string;
}; };
type LedgerRegistrationBody = { type LedgerRegistrationBody = {
role?: 'ENDORSER'; role?: 'ENDORSER';
alias?: string;
seed: string; seed: string;
}; };
...@@ -25,7 +23,6 @@ type RegisterPublicDidResponse = { ...@@ -25,7 +23,6 @@ type RegisterPublicDidResponse = {
export const registerPublicDids = async ({ export const registerPublicDids = async ({
ledgerIds, ledgerIds,
alias,
seed, seed,
}: RegisterPublicDidOptions): Promise<Array<RegisterPublicDidResponse>> => { }: RegisterPublicDidOptions): Promise<Array<RegisterPublicDidResponse>> => {
const responses: Array<RegisterPublicDidResponse> = []; const responses: Array<RegisterPublicDidResponse> = [];
...@@ -36,7 +33,6 @@ export const registerPublicDids = async ({ ...@@ -36,7 +33,6 @@ export const registerPublicDids = async ({
const body: LedgerRegistrationBody = { const body: LedgerRegistrationBody = {
role: 'ENDORSER', role: 'ENDORSER',
alias,
seed, seed,
}; };
......
...@@ -7,7 +7,7 @@ import { AgentModule } from '../../agent.module.js'; ...@@ -7,7 +7,7 @@ import { AgentModule } from '../../agent.module.js';
import { SchemasController } from '../schemas.controller.js'; import { SchemasController } from '../schemas.controller.js';
import { SchemasService } from '../schemas.service.js'; import { SchemasService } from '../schemas.service.js';
describe('ConnectionsController', () => { describe('SchemassController', () => {
let schemasController: SchemasController; let schemasController: SchemasController;
let schemasService: SchemasService; let schemasService: SchemasService;
......
...@@ -42,7 +42,9 @@ export class SchemasService { ...@@ -42,7 +42,9 @@ export class SchemasService {
version, version,
issuerDid, issuerDid,
attributeNames, attributeNames,
}: EventAnonCredsSchemasRegisterInput): Promise<AnonCredsSchema> { }: EventAnonCredsSchemasRegisterInput): Promise<
AnonCredsSchema & { schemaId: string }
> {
return this.withTenantService.invoke(tenantId, async (t) => { return this.withTenantService.invoke(tenantId, async (t) => {
const { schemaState } = const { schemaState } =
await t.modules.anoncreds.registerSchema<IndyVdrRegisterSchemaOptions>({ await t.modules.anoncreds.registerSchema<IndyVdrRegisterSchemaOptions>({
...@@ -53,7 +55,7 @@ export class SchemasService { ...@@ -53,7 +55,7 @@ export class SchemasService {
attrNames: attributeNames, attrNames: attributeNames,
}, },
options: { options: {
endorserMode: 'external', endorserMode: 'internal',
endorserDid: issuerDid, endorserDid: issuerDid,
}, },
}); });
...@@ -66,7 +68,7 @@ export class SchemasService { ...@@ -66,7 +68,7 @@ export class SchemasService {
); );
} }
return schemaState.schema; return { schemaId: schemaState.schemaId, ...schemaState.schema };
}); });
} }
} }
...@@ -6,6 +6,8 @@ import { HealthController } from '@ocm/shared'; ...@@ -6,6 +6,8 @@ import { HealthController } from '@ocm/shared';
import { AgentModule } from './agent/agent.module.js'; import { AgentModule } from './agent/agent.module.js';
import { ConnectionsModule } from './agent/connections/connections.module.js'; import { ConnectionsModule } from './agent/connections/connections.module.js';
import { CredentialDefinitionsModule } from './agent/credentialDefinitions/credentialDefinitions.module.js';
import { SchemasModule } from './agent/schemas/schemas.module.js';
import { TenantsModule } from './agent/tenants/tenants.module.js'; import { TenantsModule } from './agent/tenants/tenants.module.js';
import { config } from './config/config.js'; import { config } from './config/config.js';
import { validationSchema } from './config/validation.js'; import { validationSchema } from './config/validation.js';
...@@ -20,7 +22,10 @@ import { validationSchema } from './config/validation.js'; ...@@ -20,7 +22,10 @@ import { validationSchema } from './config/validation.js';
}), }),
AgentModule, AgentModule,
ConnectionsModule, ConnectionsModule,
SchemasModule,
CredentialDefinitionsModule,
DidsModule, DidsModule,
SchemasModule,
TenantsModule, TenantsModule,
], ],
controllers: [HealthController], controllers: [HealthController],
......
...@@ -5,7 +5,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; ...@@ -5,7 +5,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
import { validationSchema } from '../validation.js'; import { validationSchema } from '../validation.js';
const mockConfig = (port: number = 3001): AppConfig => ({ const mockConfig = (port: number = 3001, withLedger = false): AppConfig => ({
agentHost: '', agentHost: '',
port: 3000, port: 3000,
jwtSecret: '', jwtSecret: '',
...@@ -16,19 +16,19 @@ const mockConfig = (port: number = 3001): AppConfig => ({ ...@@ -16,19 +16,19 @@ const mockConfig = (port: number = 3001): AppConfig => ({
name: 'my-test-agent', name: 'my-test-agent',
walletId: utils.uuid(), walletId: utils.uuid(),
walletKey: 'some-key', walletKey: 'some-key',
ledgerIds: [], ledgerIds: withLedger ? ['BCOVRIN_TEST'] : [],
host: 'http://localhost', host: 'http://localhost',
inboundPort: port, inboundPort: port,
path: '', path: '',
publicDidSeed: '', publicDidSeed: withLedger ? '12312367897123300000000000000000' : '',
autoAcceptConnection: true, autoAcceptConnection: true,
autoAcceptCredential: AutoAcceptCredential.ContentApproved, autoAcceptCredential: AutoAcceptCredential.ContentApproved,
}, },
}); });
export const mockConfigModule = (port: number = 3000) => export const mockConfigModule = (port: number = 3000, withLedger = false) =>
ConfigModule.forRoot({ ConfigModule.forRoot({
load: [() => mockConfig(port)], load: [() => mockConfig(port, withLedger)],
validationSchema, validationSchema,
}); });
......
import type { INestApplication } from '@nestjs/common';
import type { ClientProxy } from '@nestjs/microservices';
import type {
EventAnonCredsCredentialDefinitionsGetAllInput,
EventAnonCredsCredentialDefinitionsGetByIdInput,
EventAnonCredsCredentialDefinitionsRegisterInput,
} from '@ocm/shared';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { Test } from '@nestjs/testing';
import {
EventAnonCredsCredentialDefinitionsGetById,
EventAnonCredsCredentialDefinitionsGetAll,
EventAnonCredsCredentialDefinitionsRegister,
} from '@ocm/shared';
import { firstValueFrom } from 'rxjs';
import { AgentModule } from '../src/agent/agent.module.js';
import { CredentialDefinitionsModule } from '../src/agent/credentialDefinitions/credentialDefinitions.module.js';
import { DidsModule } from '../src/agent/dids/dids.module.js';
import { DidsService } from '../src/agent/dids/dids.service.js';
import { SchemasModule } from '../src/agent/schemas/schemas.module.js';
import { SchemasService } from '../src/agent/schemas/schemas.service.js';
import { TenantsModule } from '../src/agent/tenants/tenants.module.js';
import { TenantsService } from '../src/agent/tenants/tenants.service.js';
import { mockConfigModule } from '../src/config/__tests__/mockConfig.js';
describe('CredentialDefinitions', () => {
const TOKEN = 'CREDENTIAL_DEFINITIONS_CLIENT_SERVICE';
let app: INestApplication;
let client: ClientProxy;
let tenantId: string;
let issuerDid: string;
let schemaId: string;
beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
mockConfigModule(3004, true),
AgentModule,
SchemasModule,
CredentialDefinitionsModule,
TenantsModule,
DidsModule,
ClientsModule.register([{ name: TOKEN, transport: Transport.NATS }]),
],
}).compile();
app = moduleRef.createNestApplication();
app.connectMicroservice({ transport: Transport.NATS });
await app.startAllMicroservices();
await app.init();
client = app.get(TOKEN);
await client.connect();
const tenantsService = app.get(TenantsService);
const { id } = await tenantsService.create(TOKEN);
tenantId = id;
const didsService = app.get(DidsService);
const [did] = await didsService.registerDidIndyFromSeed({
tenantId,
seed: '12312367897123300000000000000000',
});
issuerDid = did;
const schemaService = app.get(SchemasService);
const { schemaId: sid } = await schemaService.register({
issuerDid,
tenantId,
name: 'test-schema-name',
version: `1.${new Date().getTime()}`,
attributeNames: ['none'],
});
schemaId = sid;
});
afterAll(async () => {
await app.close();
client.close();
});
it(EventAnonCredsCredentialDefinitionsGetAll.token, async () => {
const response$ = client.send<
EventAnonCredsCredentialDefinitionsGetAll,
EventAnonCredsCredentialDefinitionsGetAllInput
>(EventAnonCredsCredentialDefinitionsGetAll.token, { tenantId });
const response = await firstValueFrom(response$);
const eventInstance =
EventAnonCredsCredentialDefinitionsGetAll.fromEvent(response);
expect(eventInstance.instance).toEqual(expect.arrayContaining([]));
});
it(EventAnonCredsCredentialDefinitionsGetById.token, async () => {
const response$ = client.send<
EventAnonCredsCredentialDefinitionsGetById,
EventAnonCredsCredentialDefinitionsGetByIdInput
>(EventAnonCredsCredentialDefinitionsGetById.token, {
tenantId,
credentialDefinitionId: 'some-id',
});
const response = await firstValueFrom(response$);
const eventInstance =
EventAnonCredsCredentialDefinitionsGetById.fromEvent(response);
expect(eventInstance.instance).toEqual(null);
});
it(EventAnonCredsCredentialDefinitionsRegister.token, async () => {
const tag = `tag:${new Date().getTime()}`;
const response$ = client.send<
EventAnonCredsCredentialDefinitionsRegister,
EventAnonCredsCredentialDefinitionsRegisterInput
>(EventAnonCredsCredentialDefinitionsRegister.token, {
tenantId,
schemaId,
issuerDid,
tag,
});
const response = await firstValueFrom(response$);
const eventInstance =
EventAnonCredsCredentialDefinitionsRegister.fromEvent(response);
expect(eventInstance.instance).toMatchObject({
schemaId,
tag,
issuerId: issuerDid,
type: 'CL',
});
});
});
import type { INestApplication } from '@nestjs/common'; import type { INestApplication } from '@nestjs/common';
import type { ClientProxy } from '@nestjs/microservices'; import type { ClientProxy } from '@nestjs/microservices';
import type { import type {
EventDidsRegisterIndyFromSeedInput,
EventDidsResolveInput, EventDidsResolveInput,
EventDidsPublicDidInput,
} from '@ocm/shared'; } from '@ocm/shared';
import { DidDocument } 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 { EventDidsResolve, EventDidsPublicDid } from '@ocm/shared'; import { EventDidsRegisterIndyFromSeed, EventDidsResolve } from '@ocm/shared';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { AgentModule } from '../src/agent/agent.module.js'; import { AgentModule } from '../src/agent/agent.module.js';
import { DidsModule } from '../src/agent/dids/dids.module.js'; import { DidsModule } from '../src/agent/dids/dids.module.js';
import { DidsService } from '../src/agent/dids/dids.service.js';
import { TenantsModule } from '../src/agent/tenants/tenants.module.js'; import { TenantsModule } from '../src/agent/tenants/tenants.module.js';
import { TenantsService } from '../src/agent/tenants/tenants.service.js'; import { TenantsService } from '../src/agent/tenants/tenants.service.js';
import { mockConfigModule } from '../src/config/__tests__/mockConfig.js'; import { mockConfigModule } from '../src/config/__tests__/mockConfig.js';
const mockDidDocument = {
context: ['https://w3id.org/did/v1'],
id: 'did:indy:bcovrin:test:7KuDTpQh3GJ7Gp6kErpWvM',
verificationMethod: [
{
id: 'did:indy:bcovrin:test:7KuDTpQh3GJ7Gp6kErpWvM#verkey',
type: 'Ed25519VerificationKey2018',
controller: 'did:indy:bcovrin:test:7KuDTpQh3GJ7Gp6kErpWvM',
publicKeyBase58: '4SySYXQUtuK26zfC7RpQpWYMThfbXphUf8LWyXXmxyTX',
},
],
authentication: ['did:indy:bcovrin:test:7KuDTpQh3GJ7Gp6kErpWvM#verkey'],
};
describe('Dids', () => { describe('Dids', () => {
const TOKEN = 'DIDS_CLIENT_SERVICE'; const TOKEN = 'DIDS_CLIENT_SERVICE';
let app: INestApplication; let app: INestApplication;
...@@ -39,12 +23,9 @@ describe('Dids', () => { ...@@ -39,12 +23,9 @@ describe('Dids', () => {
let tenantId: string; let tenantId: string;
beforeAll(async () => { beforeAll(async () => {
jest
.spyOn(DidsService.prototype, 'getPublicDid')
.mockResolvedValue(new DidDocument(mockDidDocument));
const moduleRef = await Test.createTestingModule({ const moduleRef = await Test.createTestingModule({
imports: [ imports: [
mockConfigModule(3005), mockConfigModule(3005, true),
AgentModule, AgentModule,
DidsModule, DidsModule,
TenantsModule, TenantsModule,
...@@ -72,16 +53,21 @@ describe('Dids', () => { ...@@ -72,16 +53,21 @@ describe('Dids', () => {
client.close(); client.close();
}); });
it(EventDidsPublicDid.token, async () => { it(EventDidsRegisterIndyFromSeed.token, async () => {
const response$ = client.send<EventDidsPublicDid, EventDidsPublicDidInput>( const response$ = client.send<
EventDidsPublicDid.token, EventDidsRegisterIndyFromSeed,
{ tenantId }, EventDidsRegisterIndyFromSeedInput
); >(EventDidsRegisterIndyFromSeed.token, {
seed: '12312367897123300000000000000000',
tenantId,
});
const response = await firstValueFrom(response$); const response = await firstValueFrom(response$);
const eventInstance = EventDidsPublicDid.fromEvent(response); const eventInstance = EventDidsRegisterIndyFromSeed.fromEvent(response);
expect(eventInstance.instance).toMatchObject(mockDidDocument); expect(eventInstance.instance).toMatchObject(
expect.arrayContaining(['did:indy:bcovrin:test:9MMeff63VnCpogD2FWfKnJ']),
);
}); });
it(EventDidsResolve.token, async () => { it(EventDidsResolve.token, async () => {
......
import type { INestApplication } from '@nestjs/common';
import type { ClientProxy } from '@nestjs/microservices';
import type {
EventAnonCredsSchemasGetAllInput,
EventAnonCredsSchemasGetByIdInput,
EventAnonCredsSchemasRegisterInput,
} from '@ocm/shared';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { Test } from '@nestjs/testing';
import {
EventAnonCredsSchemasGetAll,
EventAnonCredsSchemasGetById,
EventAnonCredsSchemasRegister,
} from '@ocm/shared';
import { firstValueFrom } from 'rxjs';
import { AgentModule } from '../src/agent/agent.module.js';
import { DidsModule } from '../src/agent/dids/dids.module.js';
import { DidsService } from '../src/agent/dids/dids.service.js';
import { SchemasModule } from '../src/agent/schemas/schemas.module.js';
import { TenantsModule } from '../src/agent/tenants/tenants.module.js';
import { TenantsService } from '../src/agent/tenants/tenants.service.js';
import { mockConfigModule } from '../src/config/__tests__/mockConfig.js';
describe('Schemas', () => {
const TOKEN = 'SCHEMAS_CLIENT_SERVICE';
let app: INestApplication;
let client: ClientProxy;
let tenantId: string;
let issuerDid: string;
beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
mockConfigModule(3004, true),
AgentModule,
SchemasModule,
TenantsModule,
DidsModule,
ClientsModule.register([{ name: TOKEN, transport: Transport.NATS }]),
],
}).compile();
app = moduleRef.createNestApplication();
app.connectMicroservice({ transport: Transport.NATS });
await app.startAllMicroservices();
await app.init();
client = app.get(TOKEN);
await client.connect();
const ts = app.get(TenantsService);
const { id } = await ts.create(TOKEN);
tenantId = id;
const ds = app.get(DidsService);
const [did] = await ds.registerDidIndyFromSeed({
tenantId,
seed: '12312367897123300000000000000000',
});
issuerDid = did;
});
afterAll(async () => {
await app.close();
client.close();
});
it(EventAnonCredsSchemasGetAll.token, async () => {
const response$ = client.send<
EventAnonCredsSchemasGetAll,
EventAnonCredsSchemasGetAllInput
>(EventAnonCredsSchemasGetAll.token, { tenantId });
const response = await firstValueFrom(response$);
const eventInstance = EventAnonCredsSchemasGetAll.fromEvent(response);
expect(eventInstance.instance).toEqual(expect.arrayContaining([]));
});
it(EventAnonCredsSchemasGetById.token, async () => {
const response$ = client.send<
EventAnonCredsSchemasGetById,
EventAnonCredsSchemasGetByIdInput
>(EventAnonCredsSchemasGetById.token, { tenantId, schemaId: 'some-id' });
const response = await firstValueFrom(response$);
const eventInstance = EventAnonCredsSchemasGetById.fromEvent(response);
expect(eventInstance.instance).toEqual(null);
});
it(EventAnonCredsSchemasRegister.token, async () => {
const version = `1.${new Date().getTime()}`;
const attributeNames = ['names', 'age'];
const name = 'my-schema';
const response$ = client.send<
EventAnonCredsSchemasRegister,
EventAnonCredsSchemasRegisterInput
>(EventAnonCredsSchemasRegister.token, {
tenantId,
name,
version,
issuerDid,
attributeNames,
});
const response = await firstValueFrom(response$);
const eventInstance = EventAnonCredsSchemasRegister.fromEvent(response);
expect(eventInstance.instance).toMatchObject({
attrNames: attributeNames,
issuerId: issuerDid,
name,
version,
});
});
});
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