diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 89a2dc570..d25f5a714 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -96,7 +96,7 @@ export class AgentServiceService { this.agentServiceRepository.getAgentTypeDetails(), this.agentServiceRepository.getLedgerDetails(agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]) ]); - + let orgData; if (!user?.userId && agentSpinupDto?.platformAdminEmail) { @@ -158,7 +158,6 @@ export class AgentServiceService { agentSpinupDto.tenant = agentSpinupDto.tenant || false; agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]; - // Invoke function for validate platform configuration this.validatePlatformConfig(platformConfig); @@ -338,13 +337,28 @@ export class AgentServiceService { } async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: ICreateOrgAgent): Promise { - try { + let ledgerIdData = []; + try { + if (agentSpinupDto.method !== DidMethod.KEY && agentSpinupDto.method !== DidMethod.WEB) { + + const { network } = agentSpinupDto; + const ledger = await ledgerName(network); + const ledgerList = await this._getALlLedgerDetails() as unknown as LedgerListResponse; + const isLedgerExist = ledgerList.response.find((existingLedgers) => existingLedgers.name === ledger); + if (!isLedgerExist) { + throw new BadRequestException( + ResponseMessages.agent.error.invalidLedger, + { cause: new Error(), description: ResponseMessages.errorMessages.notFound } + ); + } + + ledgerIdData = await this.agentServiceRepository.getLedgerDetails(ledger); + } /** * Invoke wallet create and provision with agent */ const walletProvision = await this._walletProvision(walletProvisionPayload); - if (!walletProvision?.response) { this.logger.error(`Agent not able to spin-up`); throw new BadRequestException( @@ -354,7 +368,6 @@ export class AgentServiceService { } const agentDetails = walletProvision.response; const agentEndPoint = `${process.env.API_GATEWAY_PROTOCOL}://${agentDetails.agentEndPoint}`; - /** * Socket connection */ @@ -374,11 +387,14 @@ export class AgentServiceService { orgId: orgData.id, walletName: agentSpinupDto.walletName, clientSocketId: agentSpinupDto.clientSocketId, - ledgerId, + method: agentSpinupDto.method, + role: agentSpinupDto.role, + network: agentSpinupDto.network, + keyType: agentSpinupDto.keyType, + ledgerId: ledgerIdData ? ledgerIdData.map(item => item.id) : null, did: agentSpinupDto.did, id: agentProcess?.id }; - /** * Store organization agent details */ @@ -446,7 +462,7 @@ export class AgentServiceService { /** * Organization storage data */ - const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, orgAgentTypeId); + const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, `${orgAgentTypeId}`); /** * Store org agent details */ @@ -460,33 +476,19 @@ export class AgentServiceService { private async _getAgentDid(payload: IStoreOrgAgentDetails): Promise { - const { agentEndPoint, apiKey, ledgerId } = payload; - - //we take this values as static because of latest changes in afj controller to up agent of platform - const platformAgent: IPlatformAgent = { - seed: `${CommonConstants.SEED}`, - keyType: `${CommonConstants.KEYTYPE}`, - method: `${CommonConstants.METHOD}`, - network: `${CommonConstants.NETWORK}`, - role: `${CommonConstants.ROLE}` - }; + const { agentEndPoint, apiKey, ledgerId, seed, keyType, method, network, role, did } = payload; const writeDid = 'write-did'; const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(ledgerId); const agentDidWriteUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_WRITE_DID}`; - return this._retryAgentSpinup(agentDidWriteUrl, apiKey, writeDid, platformAgent); + return this._retryAgentSpinup(agentDidWriteUrl, apiKey, writeDid, seed, keyType, method, network, role, did); + } private async _getDidMethod(payload: IStoreOrgAgentDetails, agentDid: object): Promise { - const getDidDic = 'get-did-doc'; - const platformAgent: IPlatformAgent = { - seed: `${CommonConstants.SEED}`, - keyType: `${CommonConstants.KEYTYPE}`, - method: `${CommonConstants.METHOD}`, - network: `${CommonConstants.NETWORK}`, - role: `${CommonConstants.ROLE}` - }; - const getDidMethodUrl = `${payload.agentEndPoint}${CommonConstants.URL_AGENT_GET_DID}`.replace('#', agentDid['did']); - return this._retryAgentSpinup(getDidMethodUrl, payload.apiKey, getDidDic, platformAgent); + const { agentEndPoint, apiKey, seed, keyType, method, network, role } = payload; + const getDidDoc = 'get-did-doc'; + const getDidMethodUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_GET_DID}/${agentDid['did']}`; + return this._retryAgentSpinup(getDidMethodUrl, apiKey, getDidDoc, seed, keyType, method, network, role, `${agentDid['did']}`); } private _buildStoreOrgAgentData(payload: IStoreOrgAgentDetails, getDidMethod: object, orgAgentTypeId: string): IStoreOrgAgentDetails { @@ -528,20 +530,19 @@ export class AgentServiceService { } - async _retryAgentSpinup(agentUrl: string, apiKey: string, agentApiState: string, payload: IPlatformAgent): Promise { - - const { seed, keyType, method, network, role} = payload; + async _retryAgentSpinup(agentUrl: string, apiKey: string, agentApiState: string, seed: string, keyType: string, method: string, network: string, role: string, did: string): Promise { const retryOptions = { retries: 10 }; try { return retry(async () => { if (agentApiState === 'write-did') { - return this.commonService.httpPost(agentUrl, { seed, keyType, method, network, role}, { headers: { 'authorization': apiKey } }); + return this.commonService.httpPost(agentUrl, { seed, keyType, method, network, role, did}, { headers: { 'authorization': apiKey } }); } else if (agentApiState === 'get-did-doc') { return this.commonService.httpGet(agentUrl, { headers: { 'authorization': apiKey } }); } }, retryOptions); + } catch (error) { throw error; } diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 57070b9ea..31a649be9 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -1,13 +1,20 @@ import { UserRoleOrgPermsDto } from 'apps/api-gateway/src/dtos/user-role-org-perms.dto'; export interface IAgentSpinupDto { - walletName: string; walletPassword: string; seed: string; orgId?: string; orgName?: string; ledgerId?: string[]; + keyType: string; + domain?: string; + privatekey?: string; + endpoint?: string; + role?: string; + network?: string + endorserDid?: string + method: string; did?: string; agentType?: string; transactionApproval?: boolean; @@ -149,23 +156,27 @@ export interface IPlatformConfigDto { } export interface IStoreOrgAgentDetails { - id?: string; - clientSocketId?: string; - agentEndPoint?: string; - apiKey?: string; - seed?: string; - did?: string; - verkey?: string; - isDidPublic?: boolean; - agentSpinUpStatus?: number; - walletName?: string; - agentsTypeId?: string; - orgId?: string; - agentId?: string; - orgAgentTypeId?: string; - tenantId?: string; - ledgerId?: string[]; - agentType?: string; + id?: string; + clientSocketId?: string; + agentEndPoint?: string; + apiKey?: string; + seed?: string; + keyType?: string; + method?: string; + network?: string; + role?: string; + did?: string; + verkey?: string; + isDidPublic?: boolean; + agentSpinUpStatus?: number; + walletName?: string; + agentsTypeId?: string; + orgId?: string; + agentId?: string; + orgAgentTypeId?: string; + tenantId?: string; + ledgerId?: string[]; + agentType?: string; } export interface IStoreOrgAgent { diff --git a/apps/agent-service/src/main.ts b/apps/agent-service/src/main.ts index 15e462947..efafbfbc4 100644 --- a/apps/agent-service/src/main.ts +++ b/apps/agent-service/src/main.ts @@ -32,8 +32,12 @@ async function bootstrap(): Promise { orgName: `${CommonConstants.PLATFORM_ADMIN_ORG}`, platformAdminEmail: process.env.PLATFORM_ADMIN_EMAIL, tenant: true, - ledgerName: [Ledgers.Bcovrin_Testnet, Ledgers.Indicio_Demonet, Ledgers.Indicio_Mainnet, Ledgers.Indicio_Testnet] - }; + ledgerName: [Ledgers.Bcovrin_Testnet, Ledgers.Indicio_Demonet, Ledgers.Indicio_Mainnet, Ledgers.Indicio_Testnet], + keyType: `${CommonConstants.KEYTYPE}`, + method: `${CommonConstants.METHOD}`, + network: `${CommonConstants.NETWORK}`, + role: `${CommonConstants.ROLE}` +}; const agentService = app.get(AgentServiceService); await agentService.walletProvision(agentSpinupPayload, user); diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index ebd4fe8d2..05d28a583 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -37,6 +37,7 @@ import { validateDid } from '@credebl/common/did.validator'; import { CreateWalletDto } from './dto/create-wallet.dto'; const seedLength = 32; + @UseFilters(CustomExceptionFilter) @Controller() @ApiTags('agents') @@ -122,14 +123,6 @@ export class AgentController { @Res() res: Response ): Promise { - if (seedLength !== agentSpinupDto.seed.length) { - this.logger.error(`seed must be at most 32 characters.`); - throw new BadRequestException( - ResponseMessages.agent.error.seedChar, - { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } - ); - } - const regex = new RegExp('^[a-zA-Z0-9]+$'); if (!regex.test(agentSpinupDto.walletName)) { @@ -246,6 +239,14 @@ export class AgentController { validateDid(createDidDto); + if (seedLength !== createDidDto.seed.length) { + this.logger.error(`seed must be at most 32 characters.`); + throw new BadRequestException( + ResponseMessages.agent.error.seedChar, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); + } + const didDetails = await this.agentService.createDid(createDidDto, orgId, user); const finalResponse: IResponse = { diff --git a/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts b/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts index a668a0025..b0cc851d2 100644 --- a/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts @@ -1,19 +1,19 @@ import { trim } from '@credebl/common/cast.helper'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Transform } from 'class-transformer'; -import { IsBoolean, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLength, IsArray } from 'class-validator'; +import { IsBoolean, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLength } from 'class-validator'; +import { CreateDidDto } from './create-did.dto'; const regex = /^[a-zA-Z0-9 ]*$/; -export class AgentSpinupDto { +export class AgentSpinupDto extends CreateDidDto { @ApiProperty() + @MaxLength(25, { message: 'Maximum length for wallet must be 25 characters.' }) + @IsString({ message: 'label must be in string format.' }) @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'walletName is required' }) - @MinLength(2, { message: 'walletName must be at least 2 characters.' }) - @MaxLength(50, { message: 'walletName must be at most 50 characters.' }) - @IsString({ message: 'walletName must be in string format.' }) + @MinLength(2, { message: 'Minimum length for wallet name must be 2 characters.' }) @Matches(regex, { message: 'Wallet name must not contain special characters.' }) @Matches(/^\S*$/, { - message: 'Spaces are not allowed in wallet name' + message: 'Spaces are not allowed in label' }) walletName: string; @@ -23,31 +23,12 @@ export class AgentSpinupDto { @IsNotEmpty({ message: 'Password is required.' }) walletPassword: string; - @ApiProperty({ example: 'dfuhgfklskmjngrjekjfgjjfkoekfdad' }) - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'seed is required' }) - @MaxLength(32, { message: 'seed must be at most 32 characters.' }) - @IsString({ message: 'seed must be in string format.' }) - @Matches(/^\S*$/, { - message: 'Spaces are not allowed in seed' - }) - seed: string; - @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) @IsOptional() @ApiPropertyOptional() @IsString({ message: 'did must be in string format.' }) did?: string; - @ApiProperty({ example: ['6ba7b810-9dad-11d1-80b4-00c04fd430c8'] }) - @IsOptional() - @ApiPropertyOptional() - @IsArray({ message: 'ledgerId must be an array' }) - @IsString({ each: true, message: 'Each ledgerId must be a string' }) - @MaxLength(36, { each: true, message: 'ledgerId must be at most 36 characters.' }) - @IsNotEmpty({ message: 'please provide valid ledgerId' }) - ledgerId?: string[]; - @ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' }) @IsOptional() @ApiPropertyOptional() diff --git a/libs/common/src/common.constant.ts b/libs/common/src/common.constant.ts index 1ce7017a4..b93f0a0d7 100644 --- a/libs/common/src/common.constant.ts +++ b/libs/common/src/common.constant.ts @@ -123,8 +123,7 @@ export enum CommonConstants { // server or agent URL_SERVER_STATUS = '/status', URL_AGENT_WRITE_DID = '/dids/write', - URL_AGENT_GET_DID = '/dids/#', - URL_AGENT_GET_DIDS = '/dids', + URL_AGENT_GET_DID = '/dids', URL_AGENT_GET_ENDPOINT = '/agent', // CREATE KEYS