diff --git a/apps/gateway/src/app/managers/proof.controller.ts b/apps/gateway/src/app/managers/proof.controller.ts index e8f5f4248f73bdf1495d2199ef7f4b8c423679ca..f3df78b61f836c0c63964f9acbefff6c23c86a83 100644 --- a/apps/gateway/src/app/managers/proof.controller.ts +++ b/apps/gateway/src/app/managers/proof.controller.ts @@ -9,11 +9,13 @@ import { } from "@nestjs/common"; import { AcceptProofRequestDto, + DeclineProofRequestDto, GatewayAcceptedResponseDto, GetProofRequestDto, GetSchemaRequestDto, IssueProofRequestDto, PROOF_ACCEPT, + PROOF_DECLINE, PROOF_GET, PROOF_ISSUE, PROOF_LIST, @@ -250,4 +252,54 @@ export class ProofController { }, }); } + + + @Post("/credentials/proof/:proof_record_id/decline") + @ApiResponse({ + status: 200, + description: + "Request is accepted for execution, the response id will match the event id received from the web socket", + type: GatewayAcceptedResponseDto, + }) + @ApiInternalServerErrorResponse({ + description: + "Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:1919", + }, + }, + }, + }, + }, + }) + @ApiOperation({ + summary: "Decline a proof request.", + description: + "Method to decline a proof request by id. Status - request-receive. The id of the response will be matched when you receive event from the websocket", + tags: ["Credentials Proof Decline Request Id"], + }) + declineProofRequest(@Param("proof_record_id") proofRecordId: string) { + const data = new DeclineProofRequestDto(); + data.proofRecordId = proofRecordId; + + return this.pmClient.sendPayload<DeclineProofRequestDto>({ + pattern: "proofs", + payload: { + source: "/credentials/proof/:proof_record_id/decline", + data, + type: PROOF_DECLINE, + }, + }); + } } diff --git a/libs/askar/src/askar-nats/event.handler.service.ts b/libs/askar/src/askar-nats/event.handler.service.ts index 64ea45ed779bf27bae1ceafefe4f2f9d160fbe84..b384d7660f5980c8dd8e137135a1cb05896f6cb5 100644 --- a/libs/askar/src/askar-nats/event.handler.service.ts +++ b/libs/askar/src/askar-nats/event.handler.service.ts @@ -21,6 +21,7 @@ import { IssueCredentialRequestDto, IssueProofRequestDto, MakeBasicMessageRequestDto, + DeclineProofRequestDto, MESSAGE_MAKE, PROOF_ACCEPT, PROOF_ISSUE, @@ -30,6 +31,7 @@ import { SCHEMA_GET, SCHEMA_LIST, GetProofRequestDto, + PROOF_DECLINE, } from "@ocm-engine/dtos"; import asyncRetry from "async-retry"; @@ -120,6 +122,11 @@ export class EventHandlerService { data = await this.agentService.acceptProof(dto.proofRecordId); break; + case PROOF_DECLINE: + dto = event.data as DeclineProofRequestDto; + data = await this.agentService.declineProofRequest(dto.proofRecordId); + break; + case MESSAGE_MAKE: dto = event.data as MakeBasicMessageRequestDto; data = await this.agentService.sendMessage(dto); diff --git a/libs/askar/src/askar-rest/rest.controller.ts b/libs/askar/src/askar-rest/rest.controller.ts index 9677b5117887cd46440440ed65597b8e747c83f3..023783a692ca2f12a7c6fdf2c84257c4a6a2e0e5 100644 --- a/libs/askar/src/askar-rest/rest.controller.ts +++ b/libs/askar/src/askar-rest/rest.controller.ts @@ -88,6 +88,11 @@ export class RestController { return this.agentService.acceptProof(proofRecordId); } + @Post(`/credential/proof/:proof_record_id/decline`) + declineProofRequest(@Param("proof_record_id") proofRecordId: string) { + return this.agentService.declineProofRequest(proofRecordId); + } + @Post("/resolve") resolve(@Body("did") did: string) { return this.agentService.resolve(did); diff --git a/libs/askar/src/askar/agent.service.ts b/libs/askar/src/askar/agent.service.ts index 3250ad2aef5390cff04f2861436ae4321da978db..72359aa5e6bc227a159ca324d2b213215168f654 100644 --- a/libs/askar/src/askar/agent.service.ts +++ b/libs/askar/src/askar/agent.service.ts @@ -17,6 +17,7 @@ import { MakeBasicMessageRequestDto, MakeBasicMessageResponseDto, SchemaNotCreatedError, + DeclineProofResponseDto, } from "@ocm-engine/dtos"; import { CredentialState, @@ -341,6 +342,23 @@ export class AgentService { return t; }; + + declineProofRequest = async (proofRecordId: string) => { + const resultFromDecline = await this.askar.agent.proofs.declineRequest({ + proofRecordId, + // sendProblemReport: false, // REVIEW: do we have a use case for this key? + }) + + const declineResponse = new DeclineProofResponseDto(); + declineResponse.proofId = resultFromDecline.id; + declineResponse.connectionId = resultFromDecline.connectionId; + declineResponse.state = resultFromDecline.state; + declineResponse.updatedAt = resultFromDecline.updatedAt; + declineResponse.createdAt = resultFromDecline.createdAt; + + return declineResponse; + }; + resolve = async (did: string) => { return this.askar.agent.dids.resolve(did); }; diff --git a/libs/dtos/src/dtos/requests/decline.proof.request.dto.ts b/libs/dtos/src/dtos/requests/decline.proof.request.dto.ts new file mode 100644 index 0000000000000000000000000000000000000000..2b37d7f4d915c4c193426f7c04d7d1db1ca80da4 --- /dev/null +++ b/libs/dtos/src/dtos/requests/decline.proof.request.dto.ts @@ -0,0 +1,10 @@ +import { IsBoolean, IsNotEmpty, IsString } from "class-validator"; + +export class DeclineProofRequestDto { + @IsString() + @IsNotEmpty() + proofRecordId: string; + + @IsBoolean() + sendProblemReport?: boolean; +} \ No newline at end of file diff --git a/libs/dtos/src/dtos/responses/decline.proof.response.dto.ts b/libs/dtos/src/dtos/responses/decline.proof.response.dto.ts new file mode 100644 index 0000000000000000000000000000000000000000..e8e4885995ca4ff29db1dc4ac39b0bd8183389d3 --- /dev/null +++ b/libs/dtos/src/dtos/responses/decline.proof.response.dto.ts @@ -0,0 +1,25 @@ +import { + IsDateString, + IsNotEmpty, + IsString +} from "class-validator"; + +export class DeclineProofResponseDto { + @IsString() + @IsNotEmpty() + proofId: string; + + @IsString() + connectionId?: string; + + @IsString() + @IsNotEmpty() + state: string; + + @IsDateString() + updatedAt?: Date; + + @IsNotEmpty() + @IsDateString() + createdAt: Date; +} \ No newline at end of file diff --git a/libs/dtos/src/dtos/responses/getById.proof.response.dto.ts b/libs/dtos/src/dtos/responses/get.proof.response.dto.ts similarity index 100% rename from libs/dtos/src/dtos/responses/getById.proof.response.dto.ts rename to libs/dtos/src/dtos/responses/get.proof.response.dto.ts diff --git a/libs/dtos/src/events/dtoToEventTransformer.ts b/libs/dtos/src/events/dtoToEventTransformer.ts index a0165c281c718a4b749603426e826cf0e28d2d15..8365ac1b1600e83f6c5fbea1cac3fa4f911295d2 100644 --- a/libs/dtos/src/events/dtoToEventTransformer.ts +++ b/libs/dtos/src/events/dtoToEventTransformer.ts @@ -17,7 +17,9 @@ import { IssueProofRequestDto } from "../dtos/requests/issue.proof.request.dto"; import { AcceptCredentialOfferRequestDto } from "../dtos/requests/accept.credential.offer.request.dto"; import { MakeBasicMessageResponseDto } from "../dtos/responses/make.basic.message.response.dto"; import { MakeBasicMessageRequestDto } from "../dtos/requests/make.basic.message.request.dto"; -import { GetProofByIdResponseDto } from "../dtos/responses/getById.proof.response.dto"; +import { GetProofByIdResponseDto } from "../dtos/responses/get.proof.response.dto"; +import { DeclineProofRequestDto } from '../dtos/requests/decline.proof.request.dto'; +import { DeclineProofResponseDto } from "../dtos/responses/decline.proof.response.dto"; export const makeEvent = (payload: { data: @@ -26,7 +28,8 @@ export const makeEvent = (payload: { | AcceptCredentialOfferRequestDto | CreateInvitationResponseDto | GetConnectionRequestDto - | CreateSchemaRequestDto + | DeclineProofRequestDto + | DeclineProofResponseDto | CreateSchemaRequestDto | CreateCredentialDefinitionRequsetDto | GetProofByIdResponseDto diff --git a/libs/dtos/src/events/types.ts b/libs/dtos/src/events/types.ts index 9c60763ca771bb9b70642d8aae83615cd82d5128..f226768c0a49887a8e3d4d1e9352301176f59d01 100644 --- a/libs/dtos/src/events/types.ts +++ b/libs/dtos/src/events/types.ts @@ -52,18 +52,21 @@ export type ProofEvent = | "proofs.list" | "proofs.accept" | "proofs.issue" - | "proofs.get"; + | "proofs.get" + | "proofs.decline" export const PROOF_LIST = "proofs.list"; export const PROOF_GET = "proofs.get" export const PROOF_ACCEPT = "proofs.accept"; export const PROOF_ISSUE = "proofs.issue"; +export const PROOF_DECLINE = "proofs.decline" export const PROOF_EVENTS: ProofEvent[] = [ PROOF_ACCEPT, PROOF_LIST, PROOF_ISSUE, PROOF_GET, + PROOF_DECLINE, ]; export type BasicMessageEvent = "messages.make"; diff --git a/libs/dtos/src/index.ts b/libs/dtos/src/index.ts index 4a428cb3f3326f5d6767fd39fc59eccd1b1993be..ce0ac84aac42b0426913d8f6ed022b7e085fc050 100644 --- a/libs/dtos/src/index.ts +++ b/libs/dtos/src/index.ts @@ -9,6 +9,7 @@ export * from "./dtos/requests/accept.credential.offer.request.dto"; export * from "./dtos/requests/accept.proof.request.dto"; export * from "./dtos/requests/make.basic.message.request.dto"; export * from "./dtos/requests/get.proof.request.dto"; +export * from "./dtos/requests/decline.proof.request.dto"; export * from "./dtos/responses/create.invitation.response.dto"; export * from "./dtos/responses/accept.invitation.response.dto"; @@ -18,7 +19,8 @@ export * from "./dtos/responses/issue.credential.response.dto"; export * from "./dtos/responses/issue.proof.response.dto"; export * from "./dtos/responses/gateway.accepted.response.dto"; export * from "./dtos/responses/make.basic.message.response.dto"; -export * from "./dtos/responses/getById.proof.response.dto"; +export * from "./dtos/responses/get.proof.response.dto"; +export * from "./dtos/responses/decline.proof.response.dto"; export * from "./errors/connection.not.found.error"; export * from "./errors/schema.not.created.error";