From 8c8ba4fea27871e6396cd06c33fcd47591ad914c Mon Sep 17 00:00:00 2001
From: sovrgn <boyan.tsolov@vereign.com>
Date: Thu, 14 Sep 2023 13:57:08 +0300
Subject: [PATCH] feat: decline proof request by providing id

---
 .../src/app/managers/proof.controller.ts      | 52 +++++++++++++++++++
 .../src/askar-nats/event.handler.service.ts   |  7 +++
 libs/askar/src/askar-rest/rest.controller.ts  |  5 ++
 libs/askar/src/askar/agent.service.ts         | 18 +++++++
 .../requests/decline.proof.request.dto.ts     | 10 ++++
 .../responses/decline.proof.response.dto.ts   | 25 +++++++++
 ...ponse.dto.ts => get.proof.response.dto.ts} |  0
 libs/dtos/src/events/dtoToEventTransformer.ts |  5 ++
 libs/dtos/src/events/types.ts                 |  5 +-
 libs/dtos/src/index.ts                        |  4 +-
 10 files changed, 129 insertions(+), 2 deletions(-)
 create mode 100644 libs/dtos/src/dtos/requests/decline.proof.request.dto.ts
 create mode 100644 libs/dtos/src/dtos/responses/decline.proof.response.dto.ts
 rename libs/dtos/src/dtos/responses/{getById.proof.response.dto.ts => get.proof.response.dto.ts} (100%)

diff --git a/apps/gateway/src/app/managers/proof.controller.ts b/apps/gateway/src/app/managers/proof.controller.ts
index 39e6ce4c..a0a94cf9 100644
--- a/apps/gateway/src/app/managers/proof.controller.ts
+++ b/apps/gateway/src/app/managers/proof.controller.ts
@@ -1,11 +1,13 @@
 import { Body, Controller, Get, Post, UseFilters } from "@nestjs/common";
 import {
   AcceptProofRequestDto,
+  DeclineProofRequestDto,
   GatewayAcceptedResponseDto,
   GetProofRequestDto,
   GetSchemaRequestDto,
   IssueProofRequestDto,
   PROOF_ACCEPT,
+  PROOF_DECLINE,
   PROOF_GET,
   PROOF_ISSUE,
   PROOF_LIST,
@@ -239,4 +241,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 b74800e2..3e19339e 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";
 
@@ -121,6 +123,11 @@ export class EventHandlerService {
             );
             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 920e6c75..8227d7dd 100644
--- a/libs/askar/src/askar-rest/rest.controller.ts
+++ b/libs/askar/src/askar-rest/rest.controller.ts
@@ -89,6 +89,11 @@ export class RestController {
     return this.agentService.acceptProof(acceptProofRequestDto);
   }
 
+  @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 cec2d57c..fda46503 100644
--- a/libs/askar/src/askar/agent.service.ts
+++ b/libs/askar/src/askar/agent.service.ts
@@ -18,6 +18,7 @@ import {
   MakeBasicMessageRequestDto,
   MakeBasicMessageResponseDto,
   SchemaNotCreatedError,
+  DeclineProofResponseDto,
 } from "@ocm-engine/dtos";
 import {
   AutoAcceptProof,
@@ -466,6 +467,23 @@ export class AgentService {
     return response;
   };
 
+
+  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 00000000..2b37d7f4
--- /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 00000000..e8e48859
--- /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 8e54294a..91760abc 100644
--- a/libs/dtos/src/events/dtoToEventTransformer.ts
+++ b/libs/dtos/src/events/dtoToEventTransformer.ts
@@ -19,6 +19,8 @@ import { MakeBasicMessageResponseDto } from "../dtos/responses/make.basic.messag
 import { MakeBasicMessageRequestDto } from "../dtos/requests/make.basic.message.request.dto";
 import { AcceptProofRequestDto } from "../dtos/requests/accept.proof.request.dto";
 import { GetProofByIdResponseDto } from "../dtos/responses/getById.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:
@@ -29,6 +31,9 @@ export const makeEvent = (payload: {
     | GetConnectionRequestDto
     | CreateSchemaRequestDto
     | AcceptProofRequestDto
+    | DeclineProofRequestDto
+    | DeclineProofResponseDto
+    | CreateSchemaRequestDto
     | CreateCredentialDefinitionRequsetDto
     | GetProofByIdResponseDto
     | IssueCredentialRequestDto
diff --git a/libs/dtos/src/events/types.ts b/libs/dtos/src/events/types.ts
index 9c60763c..f226768c 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 4a428cb3..ce0ac84a 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";
-- 
GitLab