From 3b5cf5503fcd4c61032f9e15e7d6ebd1079d8c3c 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 |  7 ++-
 libs/dtos/src/events/types.ts                 |  5 +-
 libs/dtos/src/index.ts                        |  4 +-
 10 files changed, 129 insertions(+), 4 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 e8f5f424..f3df78b6 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 64ea45ed..b384d766 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 9677b511..023783a6 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 3250ad2a..72359aa5 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 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 a0165c28..8365ac1b 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 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