diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 84bf572d2..850b3c16f 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -324,8 +324,40 @@ export interface IAgentStatus { isInitialized: boolean; } +export interface ISchema { + uri:string; +} +export interface IFields { + path: string[]; +} +export interface IConstraints { + fields: IFields[]; +} + +export interface IInputDescriptors { + + id:string; + name?:string; + purpose?:string; + schema:ISchema[]; + constraints?:IConstraints; + +} + +export interface IProofRequestPresentationDefinition { + id:string; + name: string; + input_descriptors:IInputDescriptors[]; +} + +export interface IPresentationExchange { + presentationDefinition:IProofRequestPresentationDefinition; + +} + interface IProofFormats { - indy: IndyProof; + indy?: IndyProof; + presentationExchange? : IPresentationExchange; } interface IndyProof { diff --git a/apps/api-gateway/src/connection/dtos/connection.dto.ts b/apps/api-gateway/src/connection/dtos/connection.dto.ts index cc8b0303f..0b140f476 100644 --- a/apps/api-gateway/src/connection/dtos/connection.dto.ts +++ b/apps/api-gateway/src/connection/dtos/connection.dto.ts @@ -58,6 +58,12 @@ export class CreateOutOfBandConnectionInvitation { @IsOptional() @IsNotEmpty({ message: 'Please provide recipientKey' }) recipientKey: string; + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide invitation did' }) + invitationDid?: string; orgId; } @@ -125,6 +131,12 @@ export class CreateConnectionDto { @IsOptional() @IsNotEmpty({ message: 'Please provide recipientKey' }) recipientKey: string; + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide invitation did' }) + invitationDid?: string; } export class ConnectionDto { diff --git a/apps/api-gateway/src/verification/dto/request-proof.dto.ts b/apps/api-gateway/src/verification/dto/request-proof.dto.ts index 530e06b7d..e770ecc46 100644 --- a/apps/api-gateway/src/verification/dto/request-proof.dto.ts +++ b/apps/api-gateway/src/verification/dto/request-proof.dto.ts @@ -4,6 +4,7 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Transform, Type } from 'class-transformer'; import { AutoAccept } from '@credebl/enum/enum'; import { IProofFormats } from '../interfaces/verification.interface'; +import { ProofRequestType } from '../enum/verification.enum'; export class ProofRequestAttribute { @@ -68,6 +69,128 @@ class ProofPayload { protocolVersion: string; } +export class Fields { + @ApiProperty() + @IsArray() + @IsNotEmpty({ message: 'path is required.' }) + path: string[]; +} + +export class Constraints { + @ApiProperty({type: () => [Fields]}) + @IsOptional() + @IsNotEmpty({ message: 'Fields are required.' }) + @ValidateNested() + @Type(() => Fields) + fields: Fields[]; +} + + +export class Schema { + @ApiProperty() + @IsNotEmpty({ message: 'uri is required.' }) + @IsString() + uri:string; + +} +export class InputDescriptors { + @ApiProperty() + @IsNotEmpty({ message: 'id is required.' }) + @IsString() + id:string; + + @ApiProperty() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'name is required.' }) + name:string; + + @ApiProperty() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'purpose is required.' }) + purpose:string; + + + @ApiProperty({type: () => [Schema]}) + @IsNotEmpty({ message: 'schema is required.' }) + @ValidateNested() + @Type(() => Schema) + schema:Schema[]; + + + @ApiProperty({type: () => Constraints}) + @IsOptional() + @IsNotEmpty({ message: 'Constraints are required.' }) + @ValidateNested() + @Type(() => Constraints) + constraints:Constraints; + +} + +export class ProofRequestPresentationDefinition { + + @IsString() + @IsNotEmpty({ message: 'id is required.' }) + id: string; + + @IsString() + @IsOptional() + name: string; + + @ApiProperty({type: () => [InputDescriptors]}) + @IsNotEmpty({ message: 'inputDescriptors is required.' }) + @IsArray({ message: 'inputDescriptors must be an array' }) + @IsObject({ each: true }) + @Type(() => InputDescriptors) + @ValidateNested() + // eslint-disable-next-line camelcase + input_descriptors:InputDescriptors[]; +} + +export class ProofRequestAttributeDto { + @ApiProperty({ + 'example': [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: 'string', + schemaId: 'string' + } + ], + type: () => [ProofRequestAttribute] +}) +@IsArray({ message: 'attributes must be in array' }) +@ValidateNested() +@IsObject({ each: true }) +@IsNotEmpty({ message: 'please provide valid attributes' }) +@Type(() => ProofRequestAttribute) +attributes?: ProofRequestAttribute[]; +} + +export class IndyDto { + @ApiProperty({ + 'example': { + 'attributes': [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: 'string', + schemaId: 'string' + } + ] + }, + type: () => [ProofRequestAttributeDto] + }) + @ValidateNested() + @IsObject({ each: true }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + @Type(() => ProofRequestAttributeDto) + indy: ProofRequestAttributeDto; +} + export class RequestProofDto extends ProofPayload { @ApiProperty() @IsString() @@ -77,29 +200,67 @@ export class RequestProofDto extends ProofPayload { connectionId: string; @ApiProperty({ - 'example': [ + 'example': + { + 'indy': [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: 'string', + schemaId: 'string' + } + ] + }, + type: () => [IndyDto] + }) + @IsOptional() + @ValidateNested() + @IsObject({ message: 'ProofFormatDto must be an object' }) + @IsNotEmpty({ message: 'ProofFormatDto must not be empty' }) + @Type(() => IndyDto) + proofFormats?: IndyDto; + + @ApiProperty({ + 'example': { - attributeName: 'attributeName', - condition: '>=', - value: 'predicates', - credDefId: 'string', - schemaId: 'string' - } - ], - type: () => [ProofRequestAttribute] + id: '32f54163-7166-48f1-93d8-ff217bdb0653', + inputDescriptors: [ + { + 'id': 'healthcare_input_1', + 'name': 'Medical History', + 'schema': [ + { + 'uri': 'https://health-schemas.org/1.0.1/medical_history.json' + } + + ], + 'constraints': { + 'fields': [ + { + 'path': ['$.PatientID'] + } + ] + } + } + ] + }, + type: () => [ProofRequestPresentationDefinition] }) - @IsArray({ message: 'attributes must be in array' }) + @IsOptional() @ValidateNested() - @IsObject({ each: true }) - @IsNotEmpty({ message: 'please provide valid attributes' }) - @Type(() => ProofRequestAttribute) - attributes: ProofRequestAttribute[]; + @IsObject({ message: 'presentationDefinition must be an object' }) + @IsNotEmpty({ message: 'presentationDefinition must not be empty' }) + @Type(() => ProofRequestPresentationDefinition) + presentationDefinition?:ProofRequestPresentationDefinition; @ApiPropertyOptional() @IsOptional() @IsString({ message: 'comment must be in string' }) comment: string; + type:ProofRequestType; + orgId: string; @ApiPropertyOptional() @@ -155,85 +316,6 @@ export class OutOfBandRequestProof extends ProofPayload { autoAcceptProof: string; } -export class Fields { - @ApiProperty() - @IsArray() - @IsNotEmpty({ message: 'path is required.' }) - path: string[]; - } - -export class Constraints { - @ApiProperty({type: () => [Fields]}) - @IsOptional() - @IsNotEmpty({ message: 'Fields are required.' }) - @ValidateNested() - @Type(() => Fields) - fields: Fields[]; - } - - -export class Schema { - @ApiProperty() - @IsNotEmpty({ message: 'uri is required.' }) - @IsString() - uri:string; - -} -export class InputDescriptors { - @ApiProperty() - @IsNotEmpty({ message: 'id is required.' }) - @IsString() - id:string; - - @ApiProperty() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'name is required.' }) - name:string; - - @ApiProperty() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'purpose is required.' }) - purpose:string; - - - @ApiProperty({type: () => [Schema]}) - @IsNotEmpty({ message: 'schema is required.' }) - @ValidateNested() - @Type(() => Schema) - schema:Schema[]; - - - @ApiProperty({type: () => Constraints}) - @IsOptional() - @IsNotEmpty({ message: 'Constraints are required.' }) - @ValidateNested() - @Type(() => Constraints) - constraints:Constraints; - -} - -export class ProofRequestPresentationDefinition { - - @IsString() - @IsNotEmpty({ message: 'id is required.' }) - id: string; - - @IsString() - @IsOptional() - name: string; - - @ApiProperty({type: () => [InputDescriptors]}) - @IsNotEmpty({ message: 'inputDescriptors is required.' }) - @IsArray({ message: 'inputDescriptors must be an array' }) - @IsObject({ each: true }) - @Type(() => InputDescriptors) - @ValidateNested() - // eslint-disable-next-line camelcase - input_descriptors:InputDescriptors[]; -} - export class SendProofRequestPayload { @ApiPropertyOptional() diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index af02c9a02..8d2f6a710 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -168,7 +168,10 @@ export class VerificationController { @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - @ApiBody({ type: RequestProofDto }) + @ApiBody({ type: RequestProofDto })@ApiQuery({ + name: 'requestType', + enum: ProofRequestType + }) @ApiBearerAuth() @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.VERIFIER) @@ -176,11 +179,24 @@ export class VerificationController { @Res() res: Response, @User() user: IUserRequest, @Param('orgId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(`Invalid format for orgId`); }})) orgId: string, - @Body() requestProof: RequestProofDto + @Body() requestProof: RequestProofDto, + @Query('requestType') requestType:ProofRequestType = ProofRequestType.INDY ): Promise { - const attributeArray = []; - for (const attrData of requestProof.attributes) { + if (requestType === ProofRequestType.INDY) { + if (!requestProof.proofFormats) { + throw new BadRequestException(`type: ${requestType} requires proofFormats`); + } + } + + if (requestType === ProofRequestType.PRESENTATIONEXCHANGE) { + if (!requestProof.presentationDefinition) { + throw new BadRequestException(`type: ${requestType} requires presentationDefinition`); + } + } + if (requestProof.proofFormats) { + const attributeArray = []; + for (const attrData of requestProof.proofFormats.indy.attributes) { if (0 === attributeArray.length) { attributeArray.push(Object.values(attrData)[0]); } else if (!attributeArray.includes(Object.values(attrData)[0])) { @@ -190,8 +206,10 @@ export class VerificationController { } } + } requestProof.orgId = orgId; + requestProof.type = requestType; const proofData = await this.verificationService.sendProofRequest(requestProof, user); const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, diff --git a/apps/api-gateway/src/verification/verification.service.ts b/apps/api-gateway/src/verification/verification.service.ts index 8a51651b4..4a49f48b8 100644 --- a/apps/api-gateway/src/verification/verification.service.ts +++ b/apps/api-gateway/src/verification/verification.service.ts @@ -7,6 +7,8 @@ import { WebhookPresentationProofDto } from './dto/webhook-proof.dto'; import { IProofPresentationDetails, IProofPresentationList } from '@credebl/common/interfaces/verification.interface'; import { IPresentation, IProofRequest, IProofRequestSearchCriteria } from './interfaces/verification.interface'; import { IProofPresentation } from './interfaces/verification.interface'; +// To do make a similar interface in API-gateway +import { IRequestProof } from 'apps/verification/src/interfaces/verification.interface'; @Injectable() @@ -43,7 +45,25 @@ export class VerificationService extends BaseService { * @param orgId * @returns Requested proof presentation details */ - sendProofRequest(requestProof: RequestProofDto, user: IUserRequest): Promise { + sendProofRequest(requestProofDto: RequestProofDto, user: IUserRequest): Promise { + const requestProof: IRequestProof = { + orgId: requestProofDto.orgId, + type: requestProofDto.type, + comment: requestProofDto.comment, + autoAcceptProof: requestProofDto.autoAcceptProof, + connectionId: requestProofDto.connectionId, + goalCode: requestProofDto.goalCode, + parentThreadId: requestProofDto.parentThreadId, + protocolVersion: requestProofDto.protocolVersion, + willConfirm: requestProofDto.willConfirm + }; + if (requestProofDto.proofFormats) { + requestProof.attributes = requestProofDto.proofFormats.indy.attributes; + } + if (requestProofDto.presentationDefinition) { + requestProof.presentationDefinition = requestProofDto.presentationDefinition; + } + const payload = { requestProof, user }; return this.sendNatsMessage(this.verificationServiceProxy, 'send-proof-request', payload); } diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index 430304f97..e5d461d34 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -49,7 +49,7 @@ export class ConnectionRepository { connectionInvitation: string, agentId: string, orgId: string, - recipientKey: string + invitationDid : string // eslint-disable-next-line camelcase ): Promise { try { @@ -59,7 +59,7 @@ export class ConnectionRepository { agentId, connectionInvitation, multiUse: true, - recipientKey + invitationDid } }); return agentDetails; diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index d5893c249..5776f401a 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -644,7 +644,8 @@ export class ConnectionService { appendedAttachments: appendedAttachments || undefined, routing: routing || undefined, messages: messages || undefined, - recipientKey: recipientKey || undefined + recipientKey: recipientKey || undefined, + invitationDid: invitationDid || undefined }; const createConnectionInvitationFlag = 'connection-invitation'; @@ -661,12 +662,13 @@ export class ConnectionService { connectionInvitationUrl, connectionPayload.multiUseInvitation ); - const recipientsKey = createConnectionInvitation?.response?.recipientKey || recipientKey; + + const invitationsDid = createConnectionInvitation?.response?.invitationDid || invitationDid; const saveConnectionDetails = await this.connectionRepository.saveAgentConnectionInvitations( shortenedUrl, agentId, orgId, - recipientsKey + invitationsDid ); const connectionStorePayload: ConnectionResponseDetail = { id: saveConnectionDetails.id, @@ -679,7 +681,7 @@ export class ConnectionService { lastChangedDateTime: saveConnectionDetails.lastChangedDateTime, lastChangedBy: saveConnectionDetails.lastChangedBy, recordId: createConnectionInvitation.response.outOfBandRecord.id, - recipientKey: saveConnectionDetails.recipientKey + invitationDid: saveConnectionDetails.invitationDid }; return connectionStorePayload; } catch (error) { diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 703e5081b..49f06697a 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -16,6 +16,7 @@ export interface IConnection { handshakeProtocols: string[]; orgId: string; recipientKey?: string; + invitationDid?: string } export interface IUserRequestInterface { userId: string; @@ -265,7 +266,7 @@ export interface ConnectionResponseDetail { lastChangedDateTime: Date; lastChangedBy: number; recordId: string; - recipientKey:string; + invitationDid?: string } export interface ICreateConnectionInvitation { @@ -283,6 +284,7 @@ export interface ICreateConnectionInvitation { appendedAttachments?: object[]; orgId?: string; recipientKey?: string; + invitationDid?: string; } export interface ICreateOutOfbandConnectionInvitation { diff --git a/apps/issuance/src/issuance.repository.ts b/apps/issuance/src/issuance.repository.ts index 1a6256ff4..579c5002e 100644 --- a/apps/issuance/src/issuance.repository.ts +++ b/apps/issuance/src/issuance.repository.ts @@ -72,7 +72,7 @@ export class IssuanceRepository { } - async getRecipientKeyByOrgId(orgId: string): Promise { + async getInvitationDidByOrgId(orgId: string): Promise { try { return this.prisma.agent_invitations.findMany({ where: { @@ -83,7 +83,7 @@ export class IssuanceRepository { } }); } catch (error) { - this.logger.error(`Error in getRecipientKey in issuance repository: ${error.message}`); + this.logger.error(`Error in getInvitationDid in issuance repository: ${error.message}`); throw error; } } diff --git a/apps/issuance/src/issuance.service.ts b/apps/issuance/src/issuance.service.ts index f9d067a00..5ac7e811e 100644 --- a/apps/issuance/src/issuance.service.ts +++ b/apps/issuance/src/issuance.service.ts @@ -183,12 +183,12 @@ export class IssuanceService { } const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); - let recipientKey: string | undefined; + let invitationDid: string | undefined; if (true === reuseConnection) { - const data: agent_invitations[] = await this.issuanceRepository.getRecipientKeyByOrgId(orgId); + const data: agent_invitations[] = await this.issuanceRepository.getInvitationDidByOrgId(orgId); if (data && 0 < data.length) { const [firstElement] = data; - recipientKey = firstElement?.recipientKey ?? undefined; + invitationDid = firstElement?.invitationDid ?? undefined; } } const { agentEndPoint, organisation } = agentDetails; @@ -222,7 +222,7 @@ export class IssuanceService { imageUrl: organisation?.logoUrl || payload?.imageUrl || undefined, label: organisation?.name, comment: comment || '', - recipientKey:recipientKey || undefined + invitationDid:invitationDid || undefined }; } @@ -243,7 +243,7 @@ export class IssuanceService { imageUrl: organisation?.logoUrl || payload?.imageUrl || undefined, label: organisation?.name, comment: comment || '', - recipientKey:recipientKey || undefined + invitationDid:invitationDid || undefined }; } const credentialCreateOfferDetails = await this._outOfBandCredentialOffer(issueData, url, orgId); diff --git a/apps/verification/src/interfaces/verification.interface.ts b/apps/verification/src/interfaces/verification.interface.ts index 11a9b4b79..16c0e41db 100644 --- a/apps/verification/src/interfaces/verification.interface.ts +++ b/apps/verification/src/interfaces/verification.interface.ts @@ -8,13 +8,20 @@ interface IProofRequestAttribute { value?: string; credDefId?: string; schemaId?: string; - credentialName: string; + credentialName?: string; +} + +export enum ProofRequestType { + INDY = 'indy', + PRESENTATIONEXCHANGE = 'presentationExchange' } export interface IRequestProof { orgId: string; connectionId?: string; - attributes: IProofRequestAttribute[]; + attributes?: IProofRequestAttribute[]; + type: ProofRequestType; + presentationDefinition?:IProofRequestPresentationDefinition; comment: string; autoAcceptProof: AutoAccept; protocolVersion?: string; @@ -122,7 +129,8 @@ export interface IPresentationExchange { } export interface IPresentationExchangeProofFormats { - presentationExchange : IPresentationExchange; + presentationExchange? : IPresentationExchange; + indy?: IndyProof } export interface ISendPresentationExchangeProofRequestPayload { protocolVersion: string; @@ -143,7 +151,7 @@ export interface ISendProofRequestPayload { comment?: string; connectionId?: string; proofFormats?: IProofFormats; - autoAcceptProof?: string; + autoAcceptProof?: AutoAccept; label?: string; goalCode?: string; parentThreadId?: string; @@ -152,9 +160,11 @@ export interface ISendProofRequestPayload { emailId?: string[] isShortenUrl?: boolean; type?:string; + orgId?: string; presentationDefinition?:IProofRequestPresentationDefinition; reuseConnection?: boolean; recipientKey?:string; + invitationDid?: string } export interface IWSendProofRequestPayload { @@ -176,7 +186,7 @@ export interface IWSendProofRequestPayload { export interface IProofRequestPayload { url: string; apiKey?: string; - orgId?: string + orgId?: string; proofRequestPayload: ISendProofRequestPayload | ISendPresentationExchangeProofRequestPayload; } diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index b64b24145..1c1bc6125 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -187,7 +187,7 @@ export class VerificationRepository { } // eslint-disable-next-line camelcase - async getRecipientKeyByOrgId(orgId: string): Promise { + async getInvitationDidByOrgId(orgId: string): Promise { try { return this.prisma.agent_invitations.findMany({ where: { @@ -198,7 +198,7 @@ export class VerificationRepository { } }); } catch (error) { - this.logger.error(`Error in getRecipientKey in verification repository: ${error.message}`); + this.logger.error(`Error in getInvitationDid in verification repository: ${error.message}`); throw error; } } diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 2ddeababe..71b0412a3 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -6,7 +6,7 @@ import { IGetAllProofPresentations, IProofRequestSearchCriteria, IGetProofPresen import { VerificationRepository } from './repositories/verification.repository'; import { CommonConstants } from '@credebl/common/common.constant'; import { agent_invitations, org_agents, organisation, presentations } from '@prisma/client'; -import { OrgAgentType } from '@credebl/enum/enum'; +import { AutoAccept, OrgAgentType } from '@credebl/enum/enum'; import { ResponseMessages } from '@credebl/common/response-messages'; import * as QRCode from 'qrcode'; import { OutOfBandVerification } from '../templates/out-of-band-verification.template'; @@ -169,58 +169,57 @@ export class VerificationService { * @param orgId * @returns Requested proof presentation details */ - async sendProofRequest(requestProof: IRequestProof): Promise { + async sendProofRequest(requestProof: ISendProofRequestPayload): Promise { try { const comment = requestProof.comment ? requestProof.comment : ''; - let proofRequestPayload: ISendProofRequestPayload = { - protocolVersion: '', - comment: '', - connectionId: '', - proofFormats: { - indy: { - name: '', - requested_attributes: {}, - requested_predicates: {}, - version: '' - } - }, - autoAcceptProof: '', - label: '', - goalCode: '', - parentThreadId: '', - willConfirm: false - }; + const getAgentDetails = await this.verificationRepository.getAgentEndPoint(requestProof.orgId); - const { requestedAttributes, requestedPredicates } = await this._proofRequestPayload(requestProof); + const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); + const verificationMethodLabel = 'request-proof'; + const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); + + const payload: IProofRequestPayload = { + orgId: requestProof.orgId, + url, + proofRequestPayload: {} + }; - proofRequestPayload = { - protocolVersion: requestProof.protocolVersion ? requestProof.protocolVersion : 'v1', + const proofRequestPayload = { comment, connectionId: requestProof.connectionId, - proofFormats: { - indy: { - name: 'Proof Request', - version: '1.0', - // eslint-disable-next-line camelcase - requested_attributes: requestedAttributes, - // eslint-disable-next-line camelcase - requested_predicates: requestedPredicates - } - }, - autoAcceptProof: requestProof.autoAcceptProof ? requestProof.autoAcceptProof : 'never', + autoAcceptProof: requestProof.autoAcceptProof ? requestProof.autoAcceptProof : AutoAccept.Never, goalCode: requestProof.goalCode || undefined, parentThreadId: requestProof.parentThreadId || undefined, willConfirm: requestProof.willConfirm || undefined }; - const getAgentDetails = await this.verificationRepository.getAgentEndPoint(requestProof.orgId); + if (requestProof.type === ProofRequestType.INDY) { + const { requestedAttributes, requestedPredicates } = await this._proofRequestPayload(requestProof as IRequestProof); + payload.proofRequestPayload = { + protocolVersion: requestProof.protocolVersion ? requestProof.protocolVersion : 'v1', + proofFormats: { + indy: { + name: 'Proof Request', + version: '1.0', + requested_attributes: requestedAttributes, + requested_predicates: requestedPredicates + } + }, + ...proofRequestPayload + }; - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); - const verificationMethodLabel = 'request-proof'; - const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); - - const payload = { orgId: requestProof.orgId, url, proofRequestPayload }; + } else if (requestProof.type === ProofRequestType.PRESENTATIONEXCHANGE) { + payload.proofRequestPayload = { + protocolVersion: requestProof.protocolVersion ? requestProof.protocolVersion : 'v2', + proofFormats: { + presentationExchange: { + presentationDefinition: requestProof.presentationDefinition + } + }, + ...proofRequestPayload + }; + } const getProofPresentationById = await this._sendProofRequest(payload); return getProofPresentationById?.response; @@ -349,22 +348,22 @@ export class VerificationService { // Destructuring 'outOfBandRequestProof' to remove emailId, as it is not used while agent operation const { isShortenUrl, emailId, type, reuseConnection, ...updateOutOfBandRequestProof } = outOfBandRequestProof; - let recipientKey: string | undefined; + let invitationDid: string | undefined; if (true === reuseConnection) { - const data: agent_invitations[] = await this.verificationRepository.getRecipientKeyByOrgId(user.orgId); + const data: agent_invitations[] = await this.verificationRepository.getInvitationDidByOrgId(user.orgId); if (data && 0 < data.length) { const [firstElement] = data; - recipientKey = firstElement?.recipientKey ?? undefined; + invitationDid = firstElement?.invitationDid ?? undefined; } } - outOfBandRequestProof.autoAcceptProof = outOfBandRequestProof.autoAcceptProof || 'always'; + outOfBandRequestProof.autoAcceptProof = outOfBandRequestProof.autoAcceptProof || AutoAccept.Always; let payload: IProofRequestPayload; if (ProofRequestType.INDY === type) { updateOutOfBandRequestProof.protocolVersion = updateOutOfBandRequestProof.protocolVersion || 'v1'; - updateOutOfBandRequestProof.recipientKey = recipientKey || undefined; + updateOutOfBandRequestProof.invitationDid = invitationDid || undefined; payload = { orgId: user.orgId, url, @@ -391,7 +390,7 @@ export class VerificationService { } }, autoAcceptProof:outOfBandRequestProof.autoAcceptProof, - recipientKey:recipientKey || undefined + invitationDid:invitationDid || undefined } }; } diff --git a/libs/common/src/interfaces/agent-service.interface.ts b/libs/common/src/interfaces/agent-service.interface.ts index 235e00210..26613351d 100644 --- a/libs/common/src/interfaces/agent-service.interface.ts +++ b/libs/common/src/interfaces/agent-service.interface.ts @@ -11,6 +11,7 @@ export interface InvitationMessage { }; outOfBandRecord: OutOfBandRecord; recipientKey?:string + invitationDid?: string }; } diff --git a/libs/common/src/interfaces/connection.interface.ts b/libs/common/src/interfaces/connection.interface.ts index 9ff7c4785..996b48c4c 100644 --- a/libs/common/src/interfaces/connection.interface.ts +++ b/libs/common/src/interfaces/connection.interface.ts @@ -31,5 +31,6 @@ export interface IConnectionsListCount { lastChangedDateTime: Date; lastChangedBy: number; recipientKey?:string; + invitationDid?: string } \ No newline at end of file diff --git a/libs/prisma-service/prisma/migrations/20240430114046_add_invitation_did/migration.sql b/libs/prisma-service/prisma/migrations/20240430114046_add_invitation_did/migration.sql new file mode 100644 index 000000000..6afe6c21e --- /dev/null +++ b/libs/prisma-service/prisma/migrations/20240430114046_add_invitation_did/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "agent_invitations" ADD COLUMN "invitationDid" TEXT; diff --git a/libs/prisma-service/prisma/schema.prisma b/libs/prisma-service/prisma/schema.prisma index bd3cbf946..36a639341 100644 --- a/libs/prisma-service/prisma/schema.prisma +++ b/libs/prisma-service/prisma/schema.prisma @@ -198,17 +198,17 @@ model org_agents { } model org_dids { - id String @id @default(uuid()) @db.Uuid - createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @db.Uuid - lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @db.Uuid - orgId String @db.Uuid - isPrimaryDid Boolean - did String @db.VarChar(500) + id String @id @default(uuid()) @db.Uuid + createDateTime DateTime @default(now()) @db.Timestamptz(6) + createdBy String @db.Uuid + lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) + lastChangedBy String @db.Uuid + orgId String @db.Uuid + isPrimaryDid Boolean + did String @db.VarChar(500) didDocument Json - orgAgentId String @db.Uuid - org_agents org_agents @relation(fields: [orgAgentId], references: [id]) + orgAgentId String @db.Uuid + org_agents org_agents @relation(fields: [orgAgentId], references: [id]) } model org_agents_type { @@ -309,6 +309,7 @@ model agent_invitations { org_agents org_agents @relation(fields: [agentId], references: [id]) organisation organisation @relation(fields: [orgId], references: [id]) recipientKey String? + invitationDid String? } model connections {