From 8269ff43e49b8415f3327589d8d89d8ad80bd5ea Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 26 Jun 2024 19:36:52 +0530 Subject: [PATCH 1/7] wip: applied validations for network type Signed-off-by: bhavanakarwade --- src/controllers/did/DidController.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/controllers/did/DidController.ts b/src/controllers/did/DidController.ts index a4829722..577bd1d8 100644 --- a/src/controllers/did/DidController.ts +++ b/src/controllers/did/DidController.ts @@ -402,7 +402,13 @@ export class DidController extends Controller { public async handlePolygon(createDidOptions: DidCreate) { // need to discuss try catch logic const { endpoint, network, privatekey } = createDidOptions + + if (!network) { + throw new BadRequestError('Network is required for Polygon method') + } + const networkName = network?.split(':')[1] + if (networkName !== 'mainnet' && networkName !== 'testnet') { throw new BadRequestError('Invalid network type') } From 004fb8ed0b6e75b6aac00f64978a622acf7c2aea Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 27 Jun 2024 11:33:29 +0530 Subject: [PATCH 2/7] refactor: added swagger and route file Signed-off-by: bhavanakarwade --- src/routes/routes.ts | 42 ++--- src/routes/swagger.json | 400 ++++++++++------------------------------ 2 files changed, 116 insertions(+), 326 deletions(-) diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 098ab969..8b74f75a 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -50,6 +50,11 @@ const models: TsoaRoute.Models = { "type": {"dataType":"string","validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "ProofExchangeRecord": { + "dataType": "refAlias", + "type": {"ref":"Record_string.unknown_","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "ProofFormat": { "dataType": "refObject", "properties": { @@ -106,6 +111,17 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "PlaintextMessage": { + "dataType": "refObject", + "properties": { + "@type": {"dataType":"string","required":true}, + "@id": {"dataType":"string","required":true}, + "~thread": {"dataType":"nestedObjectLiteral","nestedProperties":{"pthid":{"dataType":"string"},"thid":{"dataType":"string"}}}, + "messageType": {"dataType":"string","required":true}, + }, + "additionalProperties": {"dataType":"any"}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "CreateProofRequestOobOptions": { "dataType": "refObject", "properties": { @@ -124,17 +140,6 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "PlaintextMessage": { - "dataType": "refObject", - "properties": { - "@type": {"dataType":"string","required":true}, - "@id": {"dataType":"string","required":true}, - "~thread": {"dataType":"nestedObjectLiteral","nestedProperties":{"pthid":{"dataType":"string"},"thid":{"dataType":"string"}}}, - "messageType": {"dataType":"string","required":true}, - }, - "additionalProperties": {"dataType":"any"}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "HandshakeProtocol": { "dataType": "refEnum", "enums": ["https://didcomm.org/didexchange/1.x","https://didcomm.org/connections/1.x"], @@ -1188,8 +1193,6 @@ export function RegisterRoutes(app: Router) { async function ProofController_getProofById(request: ExRequest, response: ExResponse, next: any) { const args: Record = { proofRecordId: {"in":"path","name":"proofRecordId","required":true,"ref":"RecordId"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1226,8 +1229,6 @@ export function RegisterRoutes(app: Router) { async function ProofController_proposeProof(request: ExRequest, response: ExResponse, next: any) { const args: Record = { requestProofProposalOptions: {"in":"body","name":"requestProofProposalOptions","required":true,"ref":"RequestProofProposalOptions"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1264,8 +1265,6 @@ export function RegisterRoutes(app: Router) { async function ProofController_acceptProposal(request: ExRequest, response: ExResponse, next: any) { const args: Record = { acceptProposal: {"in":"body","name":"acceptProposal","required":true,"ref":"AcceptProofProposal"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1302,8 +1301,6 @@ export function RegisterRoutes(app: Router) { async function ProofController_requestProof(request: ExRequest, response: ExResponse, next: any) { const args: Record = { requestProofOptions: {"in":"body","name":"requestProofOptions","required":true,"ref":"RequestProofOptions"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1340,7 +1337,6 @@ export function RegisterRoutes(app: Router) { async function ProofController_createRequest(request: ExRequest, response: ExResponse, next: any) { const args: Record = { createRequestOptions: {"in":"body","name":"createRequestOptions","required":true,"ref":"CreateProofRequestOobOptions"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1378,8 +1374,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { proofRecordId: {"in":"path","name":"proofRecordId","required":true,"dataType":"string"}, request: {"in":"body","name":"request","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"comment":{"dataType":"string"},"filterByNonRevocationRequirements":{"dataType":"boolean"},"filterByPresentationPreview":{"dataType":"boolean"}}}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1416,8 +1410,6 @@ export function RegisterRoutes(app: Router) { async function ProofController_acceptPresentation(request: ExRequest, response: ExResponse, next: any) { const args: Record = { proofRecordId: {"in":"path","name":"proofRecordId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1454,8 +1446,6 @@ export function RegisterRoutes(app: Router) { async function ProofController_proofFormData(request: ExRequest, response: ExResponse, next: any) { const args: Record = { proofRecordId: {"in":"path","name":"proofRecordId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa diff --git a/src/routes/swagger.json b/src/routes/swagger.json index 7dcdff77..7e0ce458 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -16,6 +16,9 @@ "type": "string", "example": "821f9b26-ad04-4f56-89b6-e2ef9c72b36e" }, + "ProofExchangeRecord": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, "ProofFormat": { "properties": { "formatKey": { @@ -220,6 +223,37 @@ "type": "object", "additionalProperties": false }, + "PlaintextMessage": { + "properties": { + "@type": { + "type": "string" + }, + "@id": { + "type": "string" + }, + "~thread": { + "properties": { + "pthid": { + "type": "string" + }, + "thid": { + "type": "string" + } + }, + "type": "object" + }, + "messageType": { + "type": "string" + } + }, + "required": [ + "@type", + "@id", + "messageType" + ], + "type": "object", + "additionalProperties": {} + }, "CreateProofRequestOobOptions": { "properties": { "protocolVersion": { @@ -261,37 +295,6 @@ "type": "object", "additionalProperties": false }, - "PlaintextMessage": { - "properties": { - "@type": { - "type": "string" - }, - "@id": { - "type": "string" - }, - "~thread": { - "properties": { - "pthid": { - "type": "string" - }, - "thid": { - "type": "string" - } - }, - "type": "object" - }, - "messageType": { - "type": "string" - } - }, - "required": [ - "@type", - "@id", - "messageType" - ], - "type": "object", - "additionalProperties": {} - }, "HandshakeProtocol": { "description": "Enum values should be sorted based on order of preference. Values will be\nincluded in this order when creating out of band invitations.", "enum": [ @@ -2695,7 +2698,9 @@ "description": "ProofRecord", "content": { "application/json": { - "schema": {}, + "schema": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, "examples": { "Example 1": { "value": { @@ -2710,42 +2715,6 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Retrieve proof record by proof record id", @@ -2777,7 +2746,9 @@ "description": "ProofRecord", "content": { "application/json": { - "schema": {}, + "schema": { + "$ref": "#/components/schemas/ProofExchangeRecord" + }, "examples": { "Example 1": { "value": { @@ -2792,42 +2763,6 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Initiate a new presentation exchange as prover by sending a presentation proposal request\nto the connection with the specified connection id.", @@ -2860,7 +2795,9 @@ "description": "ProofRecord", "content": { "application/json": { - "schema": {}, + "schema": { + "$ref": "#/components/schemas/ProofExchangeRecord" + }, "examples": { "Example 1": { "value": { @@ -2875,42 +2812,6 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Accept a presentation proposal as verifier by sending an accept proposal message\nto the connection associated with the proof record.", @@ -2943,7 +2844,9 @@ "description": "Ok", "content": { "application/json": { - "schema": {}, + "schema": { + "$ref": "#/components/schemas/ProofExchangeRecord" + }, "examples": { "Example 1": { "value": { @@ -2958,44 +2861,9 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, + "description": "Creates a presentation request bound to existing connection", "tags": [ "Proofs" ], @@ -3023,31 +2891,66 @@ "responses": { "200": { "description": "Ok", - "content": { - "application/json": { - "schema": {} - } - } - }, - "500": { - "description": "", "content": { "application/json": { "schema": { "properties": { - "message": { + "recipientKey": { + "anyOf": [ + { + "properties": { + "recipientKey": {} + }, + "type": "object" + }, + { + "properties": { + "recipientKey": { + "type": "string" + } + }, + "required": [ + "recipientKey" + ], + "type": "object" + } + ] + }, + "outOfBandRecord": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "invitation": { + "$ref": "#/components/schemas/PlaintextMessage" + }, + "invitationUrl": { "type": "string" } }, "required": [ - "message" + "recipientKey", + "outOfBandRecord", + "invitation", + "invitationUrl" ], "type": "object" + }, + "examples": { + "Example 1": { + "value": { + "metadata": {}, + "id": "821f9b26-ad04-4f56-89b6-e2ef9c72b36e", + "createdAt": "2022-01-01T00:00:00.000Z", + "connectionId": "2aecf74c-3073-4f98-9acb-92415d096834", + "threadId": "0019d466-5eea-4269-8c40-031b4896c5b7", + "protocolVersion": "v1" + } + } } } } } }, + "description": "Creates a presentation request not bound to any proposal or existing connection", "tags": [ "Proofs" ], @@ -3077,7 +2980,9 @@ "description": "ProofRecord", "content": { "application/json": { - "schema": {}, + "schema": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, "examples": { "Example 1": { "value": { @@ -3092,42 +2997,6 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Accept a presentation request as prover by sending an accept request message\nto the connection associated with the proof record.", @@ -3180,7 +3049,9 @@ "description": "ProofRecord", "content": { "application/json": { - "schema": {}, + "schema": { + "$ref": "#/components/schemas/ProofExchangeRecord" + }, "examples": { "Example 1": { "value": { @@ -3195,42 +3066,6 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Accept a presentation as prover by sending an accept presentation message\nto the connection associated with the proof record.", @@ -3259,7 +3094,7 @@ "operationId": "ProofFormData", "responses": { "200": { - "description": "Ok", + "description": "ProofRecord", "content": { "application/json": { "schema": {}, @@ -3277,44 +3112,9 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, + "description": "Return proofRecord", "tags": [ "Proofs" ], From 8a72f0fe3495c6da5b991635859ff9e0aa2d9c1d Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Fri, 28 Jun 2024 16:23:31 +0530 Subject: [PATCH 3/7] wip: exception-handling-multi-tenancy Signed-off-by: bhavanakarwade --- .../multi-tenancy/MultiTenancyController.ts | 217 ++++++++---------- src/controllers/types.ts | 5 - src/enums/enum.ts | 6 + 3 files changed, 98 insertions(+), 130 deletions(-) diff --git a/src/controllers/multi-tenancy/MultiTenancyController.ts b/src/controllers/multi-tenancy/MultiTenancyController.ts index cf194528..8650b57c 100644 --- a/src/controllers/multi-tenancy/MultiTenancyController.ts +++ b/src/controllers/multi-tenancy/MultiTenancyController.ts @@ -7,6 +7,7 @@ import type { ConnectionRecordProps, CreateOutOfBandInvitationConfig, CredentialProtocolVersionType, + DidRecord, KeyDidCreateOptions, OutOfBandRecord, PeerDidNumAlgo2CreateOptions, @@ -51,7 +52,9 @@ import { QuestionAnswerRole, QuestionAnswerState } from '@credo-ts/question-answ import axios from 'axios' import * as fs from 'fs' -import { CredentialEnum, DidMethod, Network, Role } from '../../enums/enum' +import { CredentialEnum, DidMethod, Network, NetworkTypes, Role } from '../../enums/enum' +import ErrorHandlingService from '../../errorHandlingService' +import { BadRequestError, InternalServerError, NotFoundError } from '../../errors' import { BCOVRIN_REGISTER_URL, INDICIO_NYM_URL } from '../../utils/util' import { SchemaId, CredentialDefinitionId, RecordId, ProofRecordExample, ConnectionRecordExample } from '../examples' import { @@ -66,6 +69,7 @@ import { WriteTransaction, CreateProofRequestOobOptions, CreateOfferOobOptions, + CreateSchemaInput, } from '../types' import { @@ -98,34 +102,19 @@ export class MultiTenancyController extends Controller { //create wallet @Security('apiKey') @Post('/create-tenant') - public async createTenant( - @Body() createTenantOptions: CreateTenantOptions, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + public async createTenant(@Body() createTenantOptions: CreateTenantOptions) { const { config } = createTenantOptions try { const tenantRecord: TenantRecord = await this.agent.modules.tenants.createTenant({ config }) return tenantRecord } catch (error) { - if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `Tenant not created`, - }) - } - - return internalServerError(500, { message: `Something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @Security('apiKey') @Post('/create-did/:tenantId') - public async createDid( - @Body() createDidOptions: DidCreate, - @Path('tenantId') tenantId: string, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + public async createDid(@Body() createDidOptions: DidCreate, @Path('tenantId') tenantId: string) { let didRes try { if (!createDidOptions.method) { @@ -155,65 +144,53 @@ export class MultiTenancyController extends Controller { break default: - return internalServerError(500, { message: `Invalid method: ${createDidOptions.method}` }) + throw new InternalServerError(`Invalid method: ${createDidOptions.method}`) } didRes = { ...result } return didRes } catch (error) { - if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `Did not created`, - }) - } - - return internalServerError(500, { message: `Something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } private async handleIndy(createDidOptions: DidCreate, tenantId: string) { + const { keyType, seed, network, method } = createDidOptions + let result await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - if (!createDidOptions.keyType) { + if (!keyType) { throw Error('keyType is required') } - if (!createDidOptions.seed) { + if (!seed) { throw Error('Seed is required') } - if (!createDidOptions.network) { + if (!network) { throw Error('For indy method network is required') } - if (createDidOptions.keyType !== KeyType.Ed25519) { + if (keyType !== KeyType.Ed25519) { throw Error('Only ed25519 key type supported') } if (!Network.Bcovrin_Testnet && !Network.Indicio_Demonet && !Network.Indicio_Testnet) { - throw Error(`Invalid network for 'indy' method: ${createDidOptions.network}`) + throw Error(`Invalid network for 'indy' method: ${network}`) } - switch (createDidOptions?.network?.toLowerCase()) { + switch (network?.toLowerCase()) { case Network.Bcovrin_Testnet: - result = await this.handleBcovrin( - createDidOptions, - tenantAgent, - `did:${createDidOptions.method}:${createDidOptions.network}` - ) + result = await this.handleBcovrin(createDidOptions, tenantAgent, `did:${method}:${network}`) break case Network.Indicio_Demonet: case Network.Indicio_Testnet: - result = await this.handleIndicio( - createDidOptions, - tenantAgent, - `did:${createDidOptions.method}:${createDidOptions.network}` - ) + result = await this.handleIndicio(createDidOptions, tenantAgent, `did:${method}:${network}`) break default: - throw new Error(`Invalid network for 'indy' method: ${createDidOptions.network}`) + throw new Error(`Invalid network for 'indy' method: ${network}`) } }) return result @@ -224,40 +201,41 @@ export class MultiTenancyController extends Controller { tenantAgent: TenantAgent, didMethod: string ) { + const { seed, did, network, method, role, endorserDid } = createDidOptions let didDocument - if (!createDidOptions.seed) { + if (!seed) { throw Error('Seed is required') } - if (createDidOptions.did) { - await this.importDid(didMethod, createDidOptions.did, createDidOptions.seed, tenantAgent) + if (did) { + await this.importDid(didMethod, did, seed, tenantAgent) const getDid = await tenantAgent.dids.getCreatedDids({ - method: createDidOptions.method, - did: `did:${createDidOptions.method}:${createDidOptions.network}:${createDidOptions.did}`, + method: method, + did: `did:${method}:${network}:${did}`, }) if (getDid.length > 0) { didDocument = getDid[0].didDocument } return { - did: `${didMethod}:${createDidOptions.did}`, + did: `${didMethod}:${did}`, didDocument: didDocument, } } else { - if (createDidOptions?.role?.toLowerCase() === Role.Endorser) { + if (role?.toLowerCase() === Role.Endorser) { await tenantAgent.wallet.createKey({ - privateKey: TypedArrayEncoder.fromString(createDidOptions.seed), + privateKey: TypedArrayEncoder.fromString(seed), keyType: KeyType.Ed25519, }) const body = { role: 'ENDORSER', alias: 'Alias', - seed: createDidOptions.seed, + seed: seed, } const res = await axios.post(BCOVRIN_REGISTER_URL, body) if (res) { const { did } = res?.data || {} - await this.importDid(didMethod, did, createDidOptions.seed, tenantAgent) + await this.importDid(didMethod, did, seed, tenantAgent) const didRecord = await tenantAgent.dids.getCreatedDids({ method: DidMethod.Indy, did: `did:${DidMethod.Indy}:${Network.Bcovrin_Testnet}:${res.data.did}`, @@ -273,7 +251,7 @@ export class MultiTenancyController extends Controller { } } } else { - if (!createDidOptions.endorserDid) { + if (!endorserDid) { throw Error('endorserDid or role is required') } @@ -281,7 +259,7 @@ export class MultiTenancyController extends Controller { method: DidMethod.Indy, options: { endorserMode: 'external', - endorserDid: createDidOptions.endorserDid ? createDidOptions.endorserDid : '', + endorserDid: endorserDid || '', }, })) as IndyVdrDidCreateResult return { did: didCreateTxResult.didState.did, didDocument: didCreateTxResult.didState.didDocument } @@ -294,27 +272,28 @@ export class MultiTenancyController extends Controller { tenantAgent: TenantAgent, didMethod: string ) { + const { seed, did, method, network, role } = createDidOptions let didDocument - if (!createDidOptions.seed) { + if (!seed) { throw Error('Seed is required') } - if (createDidOptions.did) { - await this.importDid(didMethod, createDidOptions?.did, createDidOptions.seed, tenantAgent) + if (did) { + await this.importDid(didMethod, did, seed, tenantAgent) const getDid = await tenantAgent.dids.getCreatedDids({ - method: createDidOptions.method, - did: `did:${createDidOptions.method}:${createDidOptions.network}:${createDidOptions.did}`, + method: method, + did: `did:${method}:${network}:${did}`, }) if (getDid.length > 0) { didDocument = getDid[0].didDocument } return { - did: `${didMethod}:${createDidOptions.did}`, + did: `${didMethod}:${did}`, didDocument: didDocument, } } else { - if (createDidOptions?.role?.toLowerCase() === Role.Endorser) { + if (role?.toLowerCase() === Role.Endorser) { return await this.handleEndorserCreation(createDidOptions, tenantAgent, didMethod) } else { return await this.handleIndyDidCreation(createDidOptions, tenantAgent) @@ -327,12 +306,13 @@ export class MultiTenancyController extends Controller { tenantAgent: TenantAgent, didMethod: string ) { + const { seed, network } = createDidOptions let didDocument - if (!createDidOptions.seed) { + if (!seed) { throw Error('Seed is required') } const key = await tenantAgent.wallet.createKey({ - privateKey: TypedArrayEncoder.fromString(createDidOptions.seed), + privateKey: TypedArrayEncoder.fromString(seed), keyType: KeyType.Ed25519, }) const buffer = TypedArrayEncoder.fromBase58(key.publicKeyBase58) @@ -340,22 +320,22 @@ export class MultiTenancyController extends Controller { const did = TypedArrayEncoder.toBase58(buffer.slice(0, 16)) let body - if (createDidOptions.network === Network.Indicio_Testnet) { + if (network === Network.Indicio_Testnet) { body = { - network: 'testnet', + network: NetworkTypes.Testnet, did, verkey: TypedArrayEncoder.toBase58(buffer), } - } else if (createDidOptions.network === Network.Indicio_Demonet) { + } else if (network === Network.Indicio_Demonet) { body = { - network: 'demonet', + network: NetworkTypes.Demonet, did, verkey: TypedArrayEncoder.toBase58(buffer), } } const res = await axios.post(INDICIO_NYM_URL, body) if (res.data.statusCode === 200) { - await this.importDid(didMethod, did, createDidOptions.seed, tenantAgent) + await this.importDid(didMethod, did, seed, tenantAgent) const didRecord = await tenantAgent.dids.getCreatedDids({ method: DidMethod.Indy, did: `${didMethod}:${body?.did}`, @@ -387,26 +367,27 @@ export class MultiTenancyController extends Controller { } private async handleKey(createDidOptions: DidCreate, tenantId: string) { + const { seed, keyType } = createDidOptions let didResponse let did: string let didDocument: any await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - if (!createDidOptions.seed) { + if (!seed) { throw Error('Seed is required') } - if (!createDidOptions.keyType) { + if (!keyType) { throw Error('keyType is required') } - if (createDidOptions.keyType !== KeyType.Ed25519 && createDidOptions.keyType !== KeyType.Bls12381g2) { + if (keyType !== KeyType.Ed25519 && keyType !== KeyType.Bls12381g2) { throw Error('Only ed25519 and bls12381g2 key type supported') } if (!createDidOptions.did) { await tenantAgent.wallet.createKey({ keyType: createDidOptions.keyType, - seed: TypedArrayEncoder.fromString(createDidOptions.seed), + seed: TypedArrayEncoder.fromString(seed), }) const didKeyResponse = await tenantAgent.dids.create({ method: DidMethod.Key, @@ -414,7 +395,7 @@ export class MultiTenancyController extends Controller { keyType: KeyType.Ed25519, }, secret: { - privateKey: TypedArrayEncoder.fromString(createDidOptions.seed), + privateKey: TypedArrayEncoder.fromString(seed), }, }) did = `${didKeyResponse.didState.did}` @@ -477,40 +458,41 @@ export class MultiTenancyController extends Controller { } private async handleWeb(createDidOptions: DidCreate, tenantId: string) { + const { domain, keyType, seed, method } = createDidOptions let did let didDocument: any - if (!createDidOptions.domain) { + if (!domain) { throw Error('For web method domain is required') } - if (!createDidOptions.keyType) { + if (!keyType) { throw Error('keyType is required') } - if (createDidOptions.keyType !== KeyType.Ed25519 && createDidOptions.keyType !== KeyType.Bls12381g2) { + if (keyType !== KeyType.Ed25519 && keyType !== KeyType.Bls12381g2) { throw Error('Only ed25519 and bls12381g2 key type supported') } await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - if (!createDidOptions.seed) { + if (!seed) { throw Error('Seed is required') } - did = `did:${createDidOptions.method}:${createDidOptions.domain}` + did = `did:${method}:${domain}` const keyId = `${did}#key-1` const key = await tenantAgent.wallet.createKey({ - keyType: createDidOptions.keyType, - seed: TypedArrayEncoder.fromString(createDidOptions.seed), + keyType: keyType, + seed: TypedArrayEncoder.fromString(seed), }) - if (createDidOptions.keyType === KeyType.Ed25519) { + if (keyType === KeyType.Ed25519) { didDocument = new DidDocumentBuilder(did) .addContext('https://w3id.org/security/suites/ed25519-2018/v1') .addVerificationMethod(getEd25519VerificationKey2018({ key, id: keyId, controller: did })) .addAuthentication(keyId) .build() } - if (createDidOptions.keyType === KeyType.Bls12381g2) { + if (keyType === KeyType.Bls12381g2) { didDocument = new DidDocumentBuilder(did) .addContext('https://w3id.org/security/bbs/v1') .addVerificationMethod(getBls12381G2Key2020({ key, id: keyId, controller: did })) @@ -577,18 +559,18 @@ export class MultiTenancyController extends Controller { @Security('apiKey') @Get('/dids/:tenantId') - public async getDids( - @Path('tenantId') tenantId: string, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + public async getDids(@Path('tenantId') tenantId: string) { try { - let getDids + let getDids: DidRecord[] = [] await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { getDids = await tenantAgent.dids.getCreatedDids() }) + + if (getDids?.length === 0) throw new NotFoundError(`DIDs does not exists for tenantId ${tenantId}`) + return getDids } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -902,37 +884,30 @@ export class MultiTenancyController extends Controller { @Post('/schema/:tenantId') public async createSchema( @Body() - schema: { - issuerId: string - name: string - version: Version - attributes: string[] - endorse?: boolean - endorserDid?: string - }, - @Path('tenantId') tenantId: string, - @Res() forbiddenError: TsoaResponse<400, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + schema: CreateSchemaInput, + @Path('tenantId') tenantId: string ) { + const { issuerId, name, version, attributes, endorserDid, endorse } = schema + let schemaRecord try { await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - if (!schema.endorse) { + if (!endorse) { const { schemaState } = await tenantAgent.modules.anoncreds.registerSchema({ schema: { - issuerId: schema.issuerId, - name: schema.name, - version: schema.version, - attrNames: schema.attributes, + issuerId: issuerId, + name: name, + version: version, + attrNames: attributes, }, options: { endorserMode: 'internal', - endorserDid: schema.issuerId, + endorserDid: issuerId, }, }) - if (!schemaState.schemaId) { - throw Error('SchemaId not found') + if (!schemaState?.schemaId) { + throw new NotFoundError('SchemaId not found') } const indySchemaId = parseIndySchemaId(schemaState.schemaId) @@ -947,20 +922,20 @@ export class MultiTenancyController extends Controller { schemaRecord = schemaState } else { - if (!schema.endorserDid) { - throw new Error('Please provide the endorser DID') + if (!endorserDid) { + throw new BadRequestError('Please provide the endorser DID') } const createSchemaTxResult = await tenantAgent.modules.anoncreds.registerSchema({ options: { endorserMode: 'external', - endorserDid: schema.endorserDid ? schema.endorserDid : '', + endorserDid: endorserDid || '', }, schema: { - attrNames: schema.attributes, - issuerId: schema.issuerId, - name: schema.name, - version: schema.version, + attrNames: attributes, + issuerId: issuerId, + name: name, + version: version, }, }) @@ -970,15 +945,7 @@ export class MultiTenancyController extends Controller { return schemaRecord } catch (error) { - if (error instanceof CredoError) { - if (error.message.includes('UnauthorizedClientRequest')) { - return forbiddenError(400, { - reason: 'this action is not allowed.', - }) - } - } - - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } diff --git a/src/controllers/types.ts b/src/controllers/types.ts index 6c460163..f2fd2d10 100644 --- a/src/controllers/types.ts +++ b/src/controllers/types.ts @@ -302,11 +302,6 @@ export interface DidCreate { export interface CreateTenantOptions { config: Omit - seed?: string - method?: string - role?: string - endorserDid?: string - did?: string } // export type WithTenantAgentCallback = ( diff --git a/src/enums/enum.ts b/src/enums/enum.ts index f6ab7da7..2284e71d 100644 --- a/src/enums/enum.ts +++ b/src/enums/enum.ts @@ -36,6 +36,12 @@ export enum Network { Indicio_Mainnet = 'indicio:mainnet', } +export enum NetworkTypes { + Testnet = 'testnet', + Demonet = 'demonet', + Mainnet = 'mainnet', +} + export enum IndicioAcceptanceMechanism { Wallet_Agreement = 'wallet_agreement', Accept = 'accept', From 3928f0ca09dce0780d794e72a919eff6e364124a Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Fri, 28 Jun 2024 16:25:34 +0530 Subject: [PATCH 4/7] wip: added routes and json file Signed-off-by: bhavanakarwade --- src/routes/routes.ts | 55 +++++----- src/routes/swagger.json | 215 +++++++++------------------------------- 2 files changed, 71 insertions(+), 199 deletions(-) diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 8b74f75a..007ed075 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -152,7 +152,7 @@ const models: TsoaRoute.Models = { // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "KeyType": { "dataType": "refEnum", - "enums": ["ed25519","bls12381g1g2","bls12381g1","bls12381g2","x25519","p256","p384","p521","k256"], + "enums": ["ed25519","bls12381g1g2","bls12381g1","bls12381g2","x25519","p256","p384","p521","k256","secp256k1"], }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "Key": { @@ -377,6 +377,11 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "TenantRecord": { + "dataType": "refAlias", + "type": {"ref":"Record_string.unknown_","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "Pick_TenantConfig.Exclude_keyofTenantConfig.walletConfig__": { "dataType": "refAlias", "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"label":{"dataType":"string","required":true},"connectionImageUrl":{"dataType":"string"}},"validators":{}}, @@ -391,11 +396,6 @@ const models: TsoaRoute.Models = { "dataType": "refObject", "properties": { "config": {"ref":"Omit_TenantConfig.walletConfig_","required":true}, - "seed": {"dataType":"string"}, - "method": {"dataType":"string"}, - "role": {"dataType":"string"}, - "endorserDid": {"dataType":"string"}, - "did": {"dataType":"string"}, }, "additionalProperties": false, }, @@ -428,6 +428,11 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidRecord": { + "dataType": "refAlias", + "type": {"ref":"Record_string.unknown_","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "DidNymTransaction": { "dataType": "refObject", "properties": { @@ -476,6 +481,19 @@ const models: TsoaRoute.Models = { "type": {"dataType":"string","validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "CreateSchemaInput": { + "dataType": "refObject", + "properties": { + "issuerId": {"dataType":"string","required":true}, + "name": {"dataType":"string","required":true}, + "version": {"ref":"Version","required":true}, + "attributes": {"dataType":"array","array":{"dataType":"string"},"required":true}, + "endorse": {"dataType":"boolean"}, + "endorserDid": {"dataType":"string"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "SchemaMetadata": { "dataType": "refObject", "properties": { @@ -767,11 +785,6 @@ const models: TsoaRoute.Models = { "type": {"dataType":"string","validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "DidRecord": { - "dataType": "refAlias", - "type": {"ref":"Record_string.unknown_","validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "AnonCredsSchema": { "dataType": "refObject", "properties": { @@ -861,19 +874,6 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "CreateSchemaInput": { - "dataType": "refObject", - "properties": { - "issuerId": {"dataType":"string","required":true}, - "name": {"dataType":"string","required":true}, - "version": {"ref":"Version","required":true}, - "attributes": {"dataType":"array","array":{"dataType":"string"},"required":true}, - "endorse": {"dataType":"boolean"}, - "endorserDid": {"dataType":"string"}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "AnonCredsCredentialDefinition": { "dataType": "refObject", "properties": { @@ -1958,8 +1958,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_createTenant(request: ExRequest, response: ExResponse, next: any) { const args: Record = { createTenantOptions: {"in":"body","name":"createTenantOptions","required":true,"ref":"CreateTenantOptions"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1997,8 +1995,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { createDidOptions: {"in":"body","name":"createDidOptions","required":true,"ref":"DidCreate"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2035,7 +2031,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_getDids(request: ExRequest, response: ExResponse, next: any) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2456,7 +2451,7 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_createSchema(request: ExRequest, response: ExResponse, next: any) { const args: Record = { - schema: {"in":"body","name":"schema","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"endorserDid":{"dataType":"string"},"endorse":{"dataType":"boolean"},"attributes":{"dataType":"array","array":{"dataType":"string"},"required":true},"version":{"ref":"Version","required":true},"name":{"dataType":"string","required":true},"issuerId":{"dataType":"string","required":true}}}, + schema: {"in":"body","name":"schema","required":true,"ref":"CreateSchemaInput"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, forbiddenError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, diff --git a/src/routes/swagger.json b/src/routes/swagger.json index 7e0ce458..cea42fe4 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -316,7 +316,8 @@ "p256", "p384", "p521", - "k256" + "k256", + "secp256k1" ], "type": "string" }, @@ -854,6 +855,9 @@ "type": "object", "additionalProperties": false }, + "TenantRecord": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, "Pick_TenantConfig.Exclude_keyofTenantConfig.walletConfig__": { "properties": { "label": { @@ -877,21 +881,6 @@ "properties": { "config": { "$ref": "#/components/schemas/Omit_TenantConfig.walletConfig_" - }, - "seed": { - "type": "string" - }, - "method": { - "type": "string" - }, - "role": { - "type": "string" - }, - "endorserDid": { - "type": "string" - }, - "did": { - "type": "string" } }, "required": [ @@ -952,6 +941,9 @@ "type": "object", "additionalProperties": false }, + "DidRecord": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, "DidNymTransaction": { "properties": { "did": { @@ -1110,6 +1102,39 @@ "type": "string", "example": "1.0.0" }, + "CreateSchemaInput": { + "properties": { + "issuerId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "$ref": "#/components/schemas/Version" + }, + "attributes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "endorse": { + "type": "boolean" + }, + "endorserDid": { + "type": "string" + } + }, + "required": [ + "issuerId", + "name", + "version", + "attributes" + ], + "type": "object", + "additionalProperties": false + }, "SchemaMetadata": { "properties": { "did": { @@ -1803,9 +1828,6 @@ "type": "string", "example": "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL" }, - "DidRecord": { - "$ref": "#/components/schemas/Record_string.unknown_" - }, "AnonCredsSchema": { "properties": { "issuerId": { @@ -2019,39 +2041,6 @@ "type": "object", "additionalProperties": false }, - "CreateSchemaInput": { - "properties": { - "issuerId": { - "type": "string" - }, - "name": { - "type": "string" - }, - "version": { - "$ref": "#/components/schemas/Version" - }, - "attributes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "endorse": { - "type": "boolean" - }, - "endorserDid": { - "type": "string" - } - }, - "required": [ - "issuerId", - "name", - "version", - "attributes" - ], - "type": "object", - "additionalProperties": false - }, "AnonCredsCredentialDefinition": { "properties": { "issuerId": { @@ -4321,44 +4310,10 @@ "responses": { "200": { "description": "Ok", - "content": { - "application/json": { - "schema": {} - } - } - }, - "404": { - "description": "", "content": { "application/json": { "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" + "$ref": "#/components/schemas/TenantRecord" } } } @@ -4396,42 +4351,6 @@ "schema": {} } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -4470,26 +4389,13 @@ "responses": { "200": { "description": "Ok", - "content": { - "application/json": { - "schema": {} - } - } - }, - "500": { - "description": "", "content": { "application/json": { "schema": { - "properties": { - "message": { - "type": "string" - } + "items": { + "$ref": "#/components/schemas/DidRecord" }, - "required": [ - "message" - ], - "type": "object" + "type": "array" } } } @@ -5276,36 +5182,7 @@ "content": { "application/json": { "schema": { - "properties": { - "endorserDid": { - "type": "string" - }, - "endorse": { - "type": "boolean" - }, - "attributes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "version": { - "$ref": "#/components/schemas/Version" - }, - "name": { - "type": "string" - }, - "issuerId": { - "type": "string" - } - }, - "required": [ - "attributes", - "version", - "name", - "issuerId" - ], - "type": "object" + "$ref": "#/components/schemas/CreateSchemaInput" } } } From 8ffac891d58ff8656e3d6212f7b0db3408687faa Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Fri, 28 Jun 2024 16:36:39 +0530 Subject: [PATCH 5/7] refactor: added routes and json files Signed-off-by: bhavanakarwade --- src/routes/routes.ts | 2 -- src/routes/swagger.json | 36 ------------------------------------ 2 files changed, 38 deletions(-) diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 007ed075..048bf0c0 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -2453,8 +2453,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { schema: {"in":"body","name":"schema","required":true,"ref":"CreateSchemaInput"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - forbiddenError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa diff --git a/src/routes/swagger.json b/src/routes/swagger.json index cea42fe4..ebc2329a 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -5121,42 +5121,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ From e384e9aefbfbf6563e6da105b902d19998b769cf Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 3 Jul 2024 15:38:44 +0530 Subject: [PATCH 6/7] wip: error handling for multitenancy controller Signed-off-by: bhavanakarwade --- .../multi-tenancy/MultiTenancyController.ts | 482 +++++++------- src/controllers/types.ts | 3 +- src/enums/enum.ts | 5 + src/errors/errors.ts | 8 + src/routes/routes.ts | 50 +- src/routes/swagger.json | 619 +----------------- 6 files changed, 277 insertions(+), 890 deletions(-) diff --git a/src/controllers/multi-tenancy/MultiTenancyController.ts b/src/controllers/multi-tenancy/MultiTenancyController.ts index 8650b57c..e19bc50f 100644 --- a/src/controllers/multi-tenancy/MultiTenancyController.ts +++ b/src/controllers/multi-tenancy/MultiTenancyController.ts @@ -7,7 +7,6 @@ import type { ConnectionRecordProps, CreateOutOfBandInvitationConfig, CredentialProtocolVersionType, - DidRecord, KeyDidCreateOptions, OutOfBandRecord, PeerDidNumAlgo2CreateOptions, @@ -25,12 +24,10 @@ import { getUnqualifiedCredentialDefinitionId, parseIndyCredentialDefinitionId, parseIndySchemaId, - AnonCredsError, } from '@credo-ts/anoncreds' import { AcceptCredentialOfferOptions, Agent, - CredoError, ConnectionRepository, CredentialRepository, CredentialState, @@ -52,9 +49,16 @@ import { QuestionAnswerRole, QuestionAnswerState } from '@credo-ts/question-answ import axios from 'axios' import * as fs from 'fs' -import { CredentialEnum, DidMethod, Network, NetworkTypes, Role } from '../../enums/enum' +import { CredentialEnum, DidMethod, EndorserMode, Network, NetworkTypes, Role, SchemaError } from '../../enums/enum' import ErrorHandlingService from '../../errorHandlingService' -import { BadRequestError, InternalServerError, NotFoundError } from '../../errors' +import { ENDORSER_DID_NOT_PRESENT } from '../../errorMessages' +import { + BadRequestError, + InternalServerError, + NotFoundError, + PaymentRequiredError, + UnprocessableEntityError, +} from '../../errors' import { BCOVRIN_REGISTER_URL, INDICIO_NYM_URL } from '../../utils/util' import { SchemaId, CredentialDefinitionId, RecordId, ProofRecordExample, ConnectionRecordExample } from '../examples' import { @@ -86,6 +90,7 @@ import { Path, Example, Security, + Response, } from 'tsoa' @Tags('MultiTenancy') @@ -259,7 +264,7 @@ export class MultiTenancyController extends Controller { method: DidMethod.Indy, options: { endorserMode: 'external', - endorserDid: endorserDid || '', + endorserDid: endorserDid, }, })) as IndyVdrDidCreateResult return { did: didCreateTxResult.didState.did, didDocument: didCreateTxResult.didState.didDocument } @@ -561,13 +566,10 @@ export class MultiTenancyController extends Controller { @Get('/dids/:tenantId') public async getDids(@Path('tenantId') tenantId: string) { try { - let getDids: DidRecord[] = [] + let getDids await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { getDids = await tenantAgent.dids.getCreatedDids() }) - - if (getDids?.length === 0) throw new NotFoundError(`DIDs does not exists for tenantId ${tenantId}`) - return getDids } catch (error) { throw ErrorHandlingService.handle(error) @@ -576,11 +578,7 @@ export class MultiTenancyController extends Controller { @Security('apiKey') @Post('/transactions/set-endorser-role/:tenantId') - public async didNymTransaction( - @Path('tenantId') tenantId: string, - @Body() didNymTransaction: DidNymTransaction, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + public async didNymTransaction(@Path('tenantId') tenantId: string, @Body() didNymTransaction: DidNymTransaction) { let didCreateSubmitResult try { await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { @@ -601,7 +599,7 @@ export class MultiTenancyController extends Controller { return didCreateSubmitResult } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -609,9 +607,7 @@ export class MultiTenancyController extends Controller { @Post('/transactions/endorse/:tenantId') public async endorserTransaction( @Path('tenantId') tenantId: string, - @Body() endorserTransaction: EndorserTransaction, - @Res() internalServerError: TsoaResponse<500, { message: string }>, - @Res() forbiddenError: TsoaResponse<400, { reason: string }> + @Body() endorserTransaction: EndorserTransaction ) { let signedTransaction try { @@ -624,42 +620,32 @@ export class MultiTenancyController extends Controller { return { signedTransaction } } catch (error) { - if (error instanceof CredoError) { - if (error.message.includes('UnauthorizedClientRequest')) { - return forbiddenError(400, { - reason: 'this action is not allowed.', - }) - } - } - - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @Example(ConnectionRecordExample) @Security('apiKey') @Get('/connections/:connectionId/:tenantId') - public async getConnectionById( - @Path('tenantId') tenantId: string, - @Path('connectionId') connectionId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }> - ) { - let connectionRecord - await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - const connection = await tenantAgent.connections.findById(connectionId) + public async getConnectionById(@Path('tenantId') tenantId: string, @Path('connectionId') connectionId: RecordId) { + try { + let connectionRecord + await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { + const connection = await tenantAgent.connections.findById(connectionId) - if (!connection) - return notFoundError(404, { reason: `connection with connection id "${connectionId}" not found.` }) - connectionRecord = connection.toJSON() - }) + if (!connection) throw new NotFoundError(`connection with connection id "${connectionId}" not found.`) + connectionRecord = connection.toJSON() + }) - return connectionRecord + return connectionRecord + } catch (error) { + throw ErrorHandlingService.handle(error) + } } @Security('apiKey') @Post('/create-invitation/:tenantId') public async createInvitation( - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Path('tenantId') tenantId: string, @Body() config?: Omit & RecipientKeyOption // Remove routing property from type ) { @@ -687,6 +673,10 @@ export class MultiTenancyController extends Controller { }, }) invitationDid = did.didState.did + + if (!invitationDid) { + throw new InternalServerError('Error in creating invitationDid') + } } outOfBandRecord = await tenantAgent.oob.createInvitation({ ...config, invitationDid }) @@ -703,14 +693,13 @@ export class MultiTenancyController extends Controller { invitationDid: config?.invitationDid ? '' : invitationDid, } } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @Security('apiKey') @Post('/create-legacy-invitation/:tenantId') public async createLegacyInvitation( - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Path('tenantId') tenantId: string, @Body() config?: Omit & RecipientKeyOption // props removed because of issues with serialization @@ -745,7 +734,7 @@ export class MultiTenancyController extends Controller { return getInvitation } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -753,8 +742,7 @@ export class MultiTenancyController extends Controller { @Post('/receive-invitation/:tenantId') public async receiveInvitation( @Body() invitationRequest: ReceiveInvitationProps, - @Path('tenantId') tenantId: string, - @Res() internalServerError: TsoaResponse<500, { message: string }> + @Path('tenantId') tenantId: string ) { let receiveInvitationRes try { @@ -770,7 +758,7 @@ export class MultiTenancyController extends Controller { return receiveInvitationRes } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -778,8 +766,7 @@ export class MultiTenancyController extends Controller { @Post('/receive-invitation-url/:tenantId') public async receiveInvitationFromUrl( @Body() invitationRequest: ReceiveInvitationByUrlProps, - @Path('tenantId') tenantId: string, - @Res() internalServerError: TsoaResponse<500, { message: string }> + @Path('tenantId') tenantId: string ) { let receiveInvitationUrl try { @@ -794,20 +781,15 @@ export class MultiTenancyController extends Controller { connectionRecord: connectionRecord?.toJSON(), } }) - return receiveInvitationUrl } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @Security('apiKey') @Get('/oob/:invitationId/:tenantId') - public async getAllOutOfBandRecords( - @Path('tenantId') tenantId: string, - @Res() internalServerError: TsoaResponse<500, { message: string }>, - @Path('invitationId') invitationId?: string - ) { + public async getAllOutOfBandRecords(@Path('tenantId') tenantId: string, @Path('invitationId') invitationId?: string) { let outOfBandRecordsRes try { await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { @@ -821,7 +803,7 @@ export class MultiTenancyController extends Controller { return outOfBandRecordsRes } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -829,7 +811,6 @@ export class MultiTenancyController extends Controller { @Get('/connections/:tenantId') public async getAllConnections( @Path('tenantId') tenantId: string, - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Query('outOfBandId') outOfBandId?: string, @Query('alias') alias?: string, @Query('state') state?: DidExchangeState, @@ -844,7 +825,6 @@ export class MultiTenancyController extends Controller { connectionRecord = await tenantAgent.connections.findAllByOutOfBandId(outOfBandId) } else { const connectionRepository = tenantAgent.dependencyManager.resolve(ConnectionRepository) - const connections = await connectionRepository.findByQuery(tenantAgent.context, { alias, myDid, @@ -853,31 +833,34 @@ export class MultiTenancyController extends Controller { state, }) + if (connections.length === 0) { + throw new NotFoundError('connection records not found') + } connectionRecord = connections.map((c: any) => c.toJSON()) } }) return connectionRecord } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @Get('/url/:tenantId/:invitationId') - public async getInvitation( - @Path('invitationId') invitationId: string, - @Path('tenantId') tenantId: string, - @Res() notFoundError: TsoaResponse<404, { reason: string }> - ) { - let invitationJson - await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - const outOfBandRecord = await tenantAgent.oob.findByCreatedInvitationId(invitationId) + public async getInvitation(@Path('invitationId') invitationId: string, @Path('tenantId') tenantId: string) { + try { + let invitationJson + await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { + const outOfBandRecord = await tenantAgent.oob.findByCreatedInvitationId(invitationId) - if (!outOfBandRecord || outOfBandRecord.state !== 'await-response') - return notFoundError(404, { reason: `connection with invitationId "${invitationId}" not found.` }) + if (!outOfBandRecord || outOfBandRecord.state !== 'await-response') + throw new NotFoundError(`connection with invitationId "${invitationId}" not found.`) - invitationJson = outOfBandRecord.outOfBandInvitation.toJSON({ useDidSovPrefixWhereAllowed: true }) - }) - return invitationJson + invitationJson = outOfBandRecord.outOfBandInvitation.toJSON({ useDidSovPrefixWhereAllowed: true }) + }) + return invitationJson + } catch (error) { + throw ErrorHandlingService.handle(error) + } } @Security('apiKey') @@ -887,63 +870,66 @@ export class MultiTenancyController extends Controller { schema: CreateSchemaInput, @Path('tenantId') tenantId: string ) { - const { issuerId, name, version, attributes, endorserDid, endorse } = schema - - let schemaRecord try { - await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - if (!endorse) { - const { schemaState } = await tenantAgent.modules.anoncreds.registerSchema({ - schema: { - issuerId: issuerId, - name: name, - version: version, - attrNames: attributes, - }, - options: { - endorserMode: 'internal', - endorserDid: issuerId, - }, - }) + let createSchemaTxResult: any + const { issuerId, name, version, attributes, endorserDid, endorse } = schema - if (!schemaState?.schemaId) { - throw new NotFoundError('SchemaId not found') - } + await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { + const schemaPayload = { + issuerId, + name, + version, + attrNames: attributes, + } - const indySchemaId = parseIndySchemaId(schemaState.schemaId) - const getSchemaId = await getUnqualifiedSchemaId( - indySchemaId.namespaceIdentifier, - indySchemaId.schemaName, - indySchemaId.schemaVersion - ) - if (schemaState.state === CredentialEnum.Finished) { - schemaState.schemaId = getSchemaId - } + const options = { + endorserMode: '', + endorserDid: '', + } - schemaRecord = schemaState + if (!endorse) { + options.endorserMode = EndorserMode.Internal + options.endorserDid = issuerId } else { if (!endorserDid) { - throw new BadRequestError('Please provide the endorser DID') + throw new BadRequestError(ENDORSER_DID_NOT_PRESENT) } - - const createSchemaTxResult = await tenantAgent.modules.anoncreds.registerSchema({ - options: { - endorserMode: 'external', - endorserDid: endorserDid || '', - }, - schema: { - attrNames: attributes, - issuerId: issuerId, - name: name, - version: version, - }, - }) - - schemaRecord = createSchemaTxResult + options.endorserMode = EndorserMode.External + options.endorserDid = endorserDid } + + createSchemaTxResult = await tenantAgent.modules.anoncreds.registerSchema({ + schema: schemaPayload, + options: options, + }) }) + if (createSchemaTxResult?.schemaState.state === CredentialEnum.Failed) { + throw new InternalServerError(`Schema creation failed. Reason: ${createSchemaTxResult?.schemaState.reason}`) + } + + if (createSchemaTxResult?.schemaState.state === CredentialEnum.Wait) { + this.setStatus(202) + return createSchemaTxResult + } - return schemaRecord + if (createSchemaTxResult?.schemaState.state === CredentialEnum.Action) { + return createSchemaTxResult + } + + if (createSchemaTxResult.schemaState.state === CredentialEnum.Finished) { + // TODO: Return uniform response for both Internally and Externally endorsed Schemas + if (!endorse) { + const indySchemaId = parseIndySchemaId(createSchemaTxResult.schemaState.schemaId as string) + const getSchemaUnqualifiedId = await getUnqualifiedSchemaId( + indySchemaId.namespaceIdentifier, + indySchemaId.schemaName, + indySchemaId.schemaVersion + ) + createSchemaTxResult.schemaState.schemaId = getSchemaUnqualifiedId + return createSchemaTxResult.schemaState + } + return createSchemaTxResult + } } catch (error) { throw ErrorHandlingService.handle(error) } @@ -958,13 +944,12 @@ export class MultiTenancyController extends Controller { schemaName: string schema: { [key: string]: any } }, - @Path('tenantId') tenantId: string, - @Res() internalServerError: TsoaResponse<500, { message: string }> + @Path('tenantId') tenantId: string ): Promise { try { const { did, schemaName, schema } = createSchemaRequest if (!did || !schemaName || !schema) { - throw Error('One or more parameters are empty or undefined.') + throw new BadRequestError('One or more parameters are empty or undefined.') } const schemaResponse = await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { @@ -974,23 +959,24 @@ export class MultiTenancyController extends Controller { schema, }) }) - if (schemaResponse.schemaState?.state === 'failed') { + if (schemaResponse.schemaState?.state === CredentialEnum.Failed) { const reason = schemaResponse.schemaState?.reason?.toLowerCase() if (reason && reason.includes('insufficient') && reason.includes('funds')) { - throw new Error('Insufficient funds to the address, Please add funds to perform this operation') + throw new PaymentRequiredError( + 'Insufficient funds to the address, Please add funds to perform this operation' + ) } else { - throw new Error(schemaResponse.schemaState?.reason) + throw new InternalServerError(schemaResponse.schemaState?.reason) } } - const configFileData = fs.readFileSync('config.json', 'utf-8') const config = JSON.parse(configFileData) if (!config.schemaFileServerURL) { - throw new Error('Please provide valid schema file server URL') + throw new UnprocessableEntityError('Please provide valid schema file server URL') } if (!schemaResponse?.schemaId) { - throw new Error('Invalid schema response') + throw new InternalServerError('Error in getting schema response') } const schemaPayload: SchemaMetadata = { schemaUrl: config.schemaFileServerURL + schemaResponse?.schemaId, @@ -1001,7 +987,7 @@ export class MultiTenancyController extends Controller { return schemaPayload } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -1010,28 +996,20 @@ export class MultiTenancyController extends Controller { public async getPolygonW3CSchemaById( @Path('tenantId') tenantId: string, @Path('did') did: string, - @Path('schemaId') schemaId: string, - @Res() internalServerError: TsoaResponse<500, { message: string }>, - @Res() badRequestError: TsoaResponse<400, { reason: string }>, - @Res() forbiddenError: TsoaResponse<401, { reason: string }> - ): Promise { - if (!tenantId || !did || !schemaId) { - return badRequestError(400, { reason: 'Missing or invalid parameters.' }) - } - + @Path('schemaId') schemaId: string + ) { try { + let schemaDetails + + if (!tenantId || !did || !schemaId) { + throw new BadRequestError('Missing or invalid parameters.') + } await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - return tenantAgent.modules.polygon.getSchemaById(did, schemaId) + schemaDetails = await tenantAgent.modules.polygon.getSchemaById(did, schemaId) }) + return schemaDetails } catch (error) { - if (error instanceof CredoError) { - if (error.message.includes('UnauthorizedClientRequest')) { - return forbiddenError(401, { - reason: 'this action is not allowed.', - }) - } - } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -1039,8 +1017,6 @@ export class MultiTenancyController extends Controller { @Post('/transactions/write/:tenantId') public async writeSchemaAndCredDefOnLedger( @Path('tenantId') tenantId: string, - @Res() forbiddenError: TsoaResponse<400, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Body() writeTransaction: WriteTransaction ) { @@ -1063,14 +1039,7 @@ export class MultiTenancyController extends Controller { throw new Error('Please provide valid schema or credential-def!') } } catch (error) { - if (error instanceof CredoError) { - if (error.message.includes('UnauthorizedClientRequest')) { - return forbiddenError(400, { - reason: 'this action is not allowed.', - }) - } - } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @@ -1165,45 +1134,32 @@ export class MultiTenancyController extends Controller { @Security('apiKey') @Get('/schema/:schemaId/:tenantId') - public async getSchemaById( - @Path('schemaId') schemaId: SchemaId, - @Path('tenantId') tenantId: string, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() forbiddenError: TsoaResponse<403, { reason: string }>, - @Res() badRequestError: TsoaResponse<400, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { - let getSchema + public async getSchemaById(@Path('schemaId') schemaId: SchemaId, @Path('tenantId') tenantId: string) { + let schemBySchemaId try { await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - getSchema = await tenantAgent.modules.anoncreds.getSchema(schemaId) + schemBySchemaId = await tenantAgent.modules.anoncreds.getSchema(schemaId) + + if ( + schemBySchemaId?.resolutionMetadata?.error === SchemaError.NotFound || + schemBySchemaId?.resolutionMetadata?.error === SchemaError.UnSupportedAnonCredsMethod + ) { + throw new NotFoundError( + schemBySchemaId?.resolutionMetadata?.message || `schema details with schema id "${schemaId}" not found.` + ) + } }) - return getSchema + return schemBySchemaId } catch (error) { - if (error instanceof AnonCredsError && error.message === 'IndyError(LedgerNotFound): LedgerNotFound') { - return notFoundError(404, { - reason: `schema definition with schemaId "${schemaId}" not found.`, - }) - } else if (error instanceof AnonCredsError && error.cause instanceof AnonCredsError) { - if ((error.cause.cause, 'LedgerInvalidTransaction')) { - return forbiddenError(403, { - reason: `schema definition with schemaId "${schemaId}" can not be returned.`, - }) - } - if ((error.cause.cause, 'CommonInvalidStructure')) { - return badRequestError(400, { - reason: `schemaId "${schemaId}" has invalid structure.`, - }) - } - } - - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw ErrorHandlingService.handle(error) } } @Security('apiKey') @Post('/credential-definition/:tenantId') + @Response(200, 'Action required') + @Response(202, 'Wait for action to complete') public async createCredentialDefinition( @Body() credentialDefinitionRequest: { @@ -1213,74 +1169,80 @@ export class MultiTenancyController extends Controller { endorse?: boolean endorserDid?: string }, - @Path('tenantId') tenantId: string, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + @Path('tenantId') tenantId: string ) { - let credentialDefinitionRecord try { + let registerCredentialDefinitionResult: any + const { issuerId, schemaId, tag, endorse, endorserDid } = credentialDefinitionRequest await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { credentialDefinitionRequest.endorse = credentialDefinitionRequest.endorse ? credentialDefinitionRequest.endorse : false - if (!credentialDefinitionRequest.endorse) { - const { credentialDefinitionState } = await tenantAgent.modules.anoncreds.registerCredentialDefinition({ - credentialDefinition: { - issuerId: credentialDefinitionRequest.issuerId, - schemaId: credentialDefinitionRequest.schemaId, - tag: credentialDefinitionRequest.tag, - }, - options: { - // TODO: update this later - supportRevocation: false, - }, - }) - - if (!credentialDefinitionState?.credentialDefinitionId) { - throw new Error('Credential Definition Id not found') - } - const indyCredDefId = parseIndyCredentialDefinitionId(credentialDefinitionState.credentialDefinitionId) - const getCredentialDefinitionId = await getUnqualifiedCredentialDefinitionId( - indyCredDefId.namespaceIdentifier, - indyCredDefId.schemaSeqNo, - indyCredDefId.tag - ) - if (credentialDefinitionState.state === CredentialEnum.Finished) { - credentialDefinitionState.credentialDefinitionId = getCredentialDefinitionId - } + const credDef = { + issuerId, + schemaId, + tag, + // TODO: Need to check this + // type: 'CL', + } + const credentialDefinitionPayload = { + credentialDefinition: credDef, + options: { + endorserMode: '', + endorserDid: '', + // TODO: update this later + supportRevocation: false, + }, + } - credentialDefinitionRecord = credentialDefinitionState + if (!endorse) { + credentialDefinitionPayload.options.endorserMode = EndorserMode.Internal + credentialDefinitionPayload.options.endorserDid = issuerId } else { - const createCredDefTxResult = await tenantAgent.modules.anoncreds.registerCredentialDefinition({ - credentialDefinition: { - issuerId: credentialDefinitionRequest.issuerId, - tag: credentialDefinitionRequest.tag, - schemaId: credentialDefinitionRequest.schemaId, - // TODO: Need to check this - // type: 'CL', - }, - options: { - // TODO: update this later - supportRevocation: false, - endorserMode: 'external', - endorserDid: credentialDefinitionRequest.endorserDid ? credentialDefinitionRequest.endorserDid : '', - }, - }) - - credentialDefinitionRecord = createCredDefTxResult + if (!endorserDid) { + throw new BadRequestError(ENDORSER_DID_NOT_PRESENT) + } + credentialDefinitionPayload.options.endorserMode = EndorserMode.External + credentialDefinitionPayload.options.endorserDid = endorserDid } + + registerCredentialDefinitionResult = await tenantAgent.modules.anoncreds.registerCredentialDefinition( + credentialDefinitionPayload + ) }) - return credentialDefinitionRecord - } catch (error) { - if (error instanceof notFoundError) { - return notFoundError(404, { - reason: `schema with schemaId "${credentialDefinitionRequest.schemaId}" not found.`, - }) + if (registerCredentialDefinitionResult?.credentialDefinitionState.state === CredentialEnum.Failed) { + throw new InternalServerError('Falied to register credef on ledger') } - return internalServerError(500, { message: `something went wrong: ${error}` }) + if (registerCredentialDefinitionResult?.credentialDefinitionState.state === CredentialEnum.Wait) { + // The request has been accepted for processing, but the processing has not been completed. + this.setStatus(202) + return registerCredentialDefinitionResult + } + + if (registerCredentialDefinitionResult?.credentialDefinitionState.state === CredentialEnum.Action) { + return registerCredentialDefinitionResult + } + // TODO: Return uniform response for both Internally and Externally endorsed Schemas + if (!endorse) { + const indyCredDefId = parseIndyCredentialDefinitionId( + registerCredentialDefinitionResult?.credentialDefinitionState.credentialDefinitionId as string + ) + + const getCredentialDefinitionId = await getUnqualifiedCredentialDefinitionId( + indyCredDefId.namespaceIdentifier, + indyCredDefId.schemaSeqNo, + indyCredDefId.tag + ) + + registerCredentialDefinitionResult.credentialDefinitionState.credentialDefinitionId = getCredentialDefinitionId + return registerCredentialDefinitionResult?.credentialDefinitionState + } + return registerCredentialDefinitionResult + } catch (error) { + throw ErrorHandlingService.handle(error) } } @@ -1288,32 +1250,30 @@ export class MultiTenancyController extends Controller { @Get('/credential-definition/:credentialDefinitionId/:tenantId') public async getCredentialDefinitionById( @Path('credentialDefinitionId') credentialDefinitionId: CredentialDefinitionId, - @Path('tenantId') tenantId: string, - @Res() badRequestError: TsoaResponse<400, { reason: string }>, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + @Path('tenantId') tenantId: string ) { - let getCredDef + let credentialDefinitionResult: any try { await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { - getCredDef = await tenantAgent.modules.anoncreds.getCredentialDefinition(credentialDefinitionId) + credentialDefinitionResult = await tenantAgent.modules.anoncreds.getCredentialDefinition(credentialDefinitionId) }) - return getCredDef - } catch (error) { - if (error instanceof CredoError && error.message === 'IndyError(LedgerNotFound): LedgerNotFound') { - return notFoundError(404, { - reason: `credential definition with credentialDefinitionId "${credentialDefinitionId}" not found.`, - }) - } else if (error instanceof AnonCredsError && error.cause instanceof CredoError) { - if ((error.cause.cause, 'CommonInvalidStructure')) { - return badRequestError(400, { - reason: `credentialDefinitionId "${credentialDefinitionId}" has invalid structure.`, - }) - } + if (credentialDefinitionResult.resolutionMetadata?.error === 'notFound') { + throw new NotFoundError(credentialDefinitionResult.resolutionMetadata.message) } + const error = credentialDefinitionResult.resolutionMetadata?.error - return internalServerError(500, { message: `something went wrong: ${error}` }) + if (error === 'invalid' || error === 'unsupportedAnonCredsMethod') { + throw new BadRequestError(credentialDefinitionResult.resolutionMetadata.message) + } + + if (error !== undefined || credentialDefinitionResult.credentialDefinition === undefined) { + throw new InternalServerError(credentialDefinitionResult.resolutionMetadata.message) + } + + return credentialDefinitionResult + } catch (error) { + throw ErrorHandlingService.handle(error) } } diff --git a/src/controllers/types.ts b/src/controllers/types.ts index f2fd2d10..f945fbfd 100644 --- a/src/controllers/types.ts +++ b/src/controllers/types.ts @@ -1,4 +1,5 @@ import type { RecordId, Version } from './examples' +import type { CustomHandshakeProtocol } from '../enums/enum' import type { AnonCredsCredentialFormat, LegacyIndyCredentialFormat } from '@credo-ts/anoncreds' import type { AutoAcceptCredential, @@ -205,7 +206,7 @@ export interface OutOfBandInvitationSchema { goalCode?: string goal?: string accept?: string[] - handshake_protocols?: HandshakeProtocol[] + handshake_protocols?: CustomHandshakeProtocol[] services: Array imageUrl?: string } diff --git a/src/enums/enum.ts b/src/enums/enum.ts index 2284e71d..6468e3af 100644 --- a/src/enums/enum.ts +++ b/src/enums/enum.ts @@ -66,3 +66,8 @@ export enum HttpStatusCode { NotFound = 404, InternalServerError = 500, } + +export declare enum CustomHandshakeProtocol { + DidExchange = 'https://didcomm.org/didexchange/1.1', + Connections = 'https://didcomm.org/connections/1.0', +} diff --git a/src/errors/errors.ts b/src/errors/errors.ts index ad271015..a39b5e29 100644 --- a/src/errors/errors.ts +++ b/src/errors/errors.ts @@ -33,6 +33,12 @@ class UnauthorizedError extends BaseError { } } +class PaymentRequiredError extends BaseError { + public constructor(message: string = 'Payment Required') { + super(message, 402) + } +} + class ForbiddenError extends BaseError { public constructor(message: string = 'Forbidden') { super(message, 403) @@ -83,6 +89,7 @@ const errorMap: Record BaseError> = { LedgerInvalidTransactionError, CommonInvalidStructureError, UnauthorizedError, + PaymentRequiredError, ForbiddenError, ConflictError, RecordDuplicateError, @@ -97,6 +104,7 @@ export { LedgerInvalidTransactionError, CommonInvalidStructureError, UnauthorizedError, + PaymentRequiredError, ForbiddenError, ConflictError, BaseError, diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 048bf0c0..4871ff30 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -293,6 +293,11 @@ const models: TsoaRoute.Models = { "additionalProperties": {"dataType":"any"}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "CustomHandshakeProtocol": { + "dataType": "refEnum", + "enums": ["https://didcomm.org/didexchange/1.1","https://didcomm.org/connections/1.0"], + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "OutOfBandDidCommService": { "dataType": "refObject", "properties": { @@ -315,7 +320,7 @@ const models: TsoaRoute.Models = { "goalCode": {"dataType":"string"}, "goal": {"dataType":"string"}, "accept": {"dataType":"array","array":{"dataType":"string"}}, - "handshake_protocols": {"dataType":"array","array":{"dataType":"refEnum","ref":"HandshakeProtocol"}}, + "handshake_protocols": {"dataType":"array","array":{"dataType":"refEnum","ref":"CustomHandshakeProtocol"}}, "services": {"dataType":"array","array":{"dataType":"union","subSchemas":[{"ref":"OutOfBandDidCommService"},{"dataType":"string"}]},"required":true}, "imageUrl": {"dataType":"string"}, }, @@ -428,11 +433,6 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "DidRecord": { - "dataType": "refAlias", - "type": {"ref":"Record_string.unknown_","validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "DidNymTransaction": { "dataType": "refObject", "properties": { @@ -785,6 +785,11 @@ const models: TsoaRoute.Models = { "type": {"dataType":"string","validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidRecord": { + "dataType": "refAlias", + "type": {"ref":"Record_string.unknown_","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "AnonCredsSchema": { "dataType": "refObject", "properties": { @@ -1481,7 +1486,6 @@ export function RegisterRoutes(app: Router) { async function Polygon_createKeyPair(request: ExRequest, response: ExResponse, next: any) { const args: Record = { - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1518,8 +1522,6 @@ export function RegisterRoutes(app: Router) { async function Polygon_createSchema(request: ExRequest, response: ExResponse, next: any) { const args: Record = { createSchemaRequest: {"in":"body","name":"createSchemaRequest","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"schema":{"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"},"required":true},"schemaName":{"dataType":"string","required":true},"did":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, - badRequestError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1556,8 +1558,6 @@ export function RegisterRoutes(app: Router) { async function Polygon_estimateTransaction(request: ExRequest, response: ExResponse, next: any) { const args: Record = { estimateTransactionRequest: {"in":"body","name":"estimateTransactionRequest","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"transaction":{"dataType":"any","required":true},"operation":{"dataType":"any","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, - badRequestError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -1595,8 +1595,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { did: {"in":"path","name":"did","required":true,"dataType":"string"}, schemaId: {"in":"path","name":"schemaId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, - forbiddenError: {"in":"res","name":"401","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2068,7 +2066,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, didNymTransaction: {"in":"body","name":"didNymTransaction","required":true,"ref":"DidNymTransaction"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2106,8 +2103,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, endorserTransaction: {"in":"body","name":"endorserTransaction","required":true,"ref":"EndorserTransaction"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, - forbiddenError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2145,7 +2140,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, connectionId: {"in":"path","name":"connectionId","required":true,"ref":"RecordId"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2181,7 +2175,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_createInvitation(request: ExRequest, response: ExResponse, next: any) { const args: Record = { - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, config: {"in":"body","name":"config","dataType":"intersection","subSchemas":[{"ref":"Omit_CreateOutOfBandInvitationConfig.routing_"},{"ref":"RecipientKeyOption"}]}, }; @@ -2219,7 +2212,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_createLegacyInvitation(request: ExRequest, response: ExResponse, next: any) { const args: Record = { - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, config: {"in":"body","name":"config","dataType":"intersection","subSchemas":[{"ref":"Omit_CreateOutOfBandInvitationConfig.routing-or-appendedAttachments-or-messages_"},{"ref":"RecipientKeyOption"}]}, }; @@ -2259,7 +2251,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { invitationRequest: {"in":"body","name":"invitationRequest","required":true,"ref":"ReceiveInvitationProps"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2297,7 +2288,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { invitationRequest: {"in":"body","name":"invitationRequest","required":true,"ref":"ReceiveInvitationByUrlProps"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2334,7 +2324,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_getAllOutOfBandRecords(request: ExRequest, response: ExResponse, next: any) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, invitationId: {"in":"path","name":"invitationId","required":true,"dataType":"string"}, }; @@ -2372,7 +2361,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_getAllConnections(request: ExRequest, response: ExResponse, next: any) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, outOfBandId: {"in":"query","name":"outOfBandId","dataType":"string"}, alias: {"in":"query","name":"alias","dataType":"string"}, state: {"in":"query","name":"state","ref":"DidExchangeState"}, @@ -2415,7 +2403,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { invitationId: {"in":"path","name":"invitationId","required":true,"dataType":"string"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2490,7 +2477,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { createSchemaRequest: {"in":"body","name":"createSchemaRequest","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"schema":{"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"},"required":true},"schemaName":{"dataType":"string","required":true},"did":{"dataType":"string","required":true}}}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2529,9 +2515,6 @@ export function RegisterRoutes(app: Router) { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, did: {"in":"path","name":"did","required":true,"dataType":"string"}, schemaId: {"in":"path","name":"schemaId","required":true,"dataType":"string"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, - badRequestError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - forbiddenError: {"in":"res","name":"401","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2568,8 +2551,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_writeSchemaAndCredDefOnLedger(request: ExRequest, response: ExResponse, next: any) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - forbiddenError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, writeTransaction: {"in":"body","name":"writeTransaction","required":true,"ref":"WriteTransaction"}, }; @@ -2608,10 +2589,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { schemaId: {"in":"path","name":"schemaId","required":true,"ref":"SchemaId"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - forbiddenError: {"in":"res","name":"403","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - badRequestError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2649,8 +2626,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { credentialDefinitionRequest: {"in":"body","name":"credentialDefinitionRequest","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"endorserDid":{"dataType":"string"},"endorse":{"dataType":"boolean"},"tag":{"dataType":"string","required":true},"schemaId":{"dataType":"string","required":true},"issuerId":{"dataType":"string","required":true}}}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -2688,9 +2663,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { credentialDefinitionId: {"in":"path","name":"credentialDefinitionId","required":true,"ref":"CredentialDefinitionId"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - badRequestError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa diff --git a/src/routes/swagger.json b/src/routes/swagger.json index ebc2329a..53ceef78 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -629,6 +629,13 @@ "type": "object", "additionalProperties": {} }, + "CustomHandshakeProtocol": { + "enum": [ + "https://didcomm.org/didexchange/1.1", + "https://didcomm.org/connections/1.0" + ], + "type": "string" + }, "OutOfBandDidCommService": { "properties": { "id": { @@ -693,7 +700,7 @@ }, "handshake_protocols": { "items": { - "$ref": "#/components/schemas/HandshakeProtocol" + "$ref": "#/components/schemas/CustomHandshakeProtocol" }, "type": "array" }, @@ -941,9 +948,6 @@ "type": "object", "additionalProperties": false }, - "DidRecord": { - "$ref": "#/components/schemas/Record_string.unknown_" - }, "DidNymTransaction": { "properties": { "did": { @@ -1828,6 +1832,9 @@ "type": "string", "example": "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL" }, + "DidRecord": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, "AnonCredsSchema": { "properties": { "issuerId": { @@ -3153,24 +3160,6 @@ } } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Create Secp256k1 key pair for polygon DID", @@ -3196,42 +3185,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Create polygon based W3C schema", @@ -3285,42 +3238,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Estimate transaction", @@ -3364,42 +3281,6 @@ "schema": {} } } - }, - "401": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Fetch schema details", @@ -4391,12 +4272,7 @@ "description": "Ok", "content": { "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/DidRecord" - }, - "type": "array" - } + "schema": {} } } } @@ -4432,24 +4308,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -4488,42 +4346,14 @@ "responses": { "200": { "description": "Ok", - "content": { - "application/json": { - "schema": {} - } - } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", "content": { "application/json": { "schema": { "properties": { - "message": { - "type": "string" - } + "signedTransaction": {} }, "required": [ - "message" + "signedTransaction" ], "type": "object" } @@ -4591,24 +4421,6 @@ } } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -4645,24 +4457,28 @@ "responses": { "200": { "description": "Ok", - "content": { - "application/json": { - "schema": {} - } - } - }, - "500": { - "description": "", "content": { "application/json": { "schema": { "properties": { - "message": { + "invitationDid": { + "type": "string" + }, + "outOfBandRecord": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "invitation": { + "$ref": "#/components/schemas/PlaintextMessage" + }, + "invitationUrl": { "type": "string" } }, "required": [ - "message" + "invitationDid", + "outOfBandRecord", + "invitation", + "invitationUrl" ], "type": "object" } @@ -4718,24 +4534,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -4786,24 +4584,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -4847,24 +4627,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -4908,24 +4670,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -4967,24 +4711,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -5066,24 +4792,6 @@ "schema": {} } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -5166,24 +4874,6 @@ } } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -5245,60 +4935,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "401": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -5348,42 +4984,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -5427,78 +5027,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "403": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -5541,41 +5069,8 @@ } } }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } + "202": { + "description": "Wait for action to complete" } }, "tags": [ @@ -5641,60 +5136,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ From 1fd362691167978b5fb365651c56f6830d67b14d Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 3 Jul 2024 16:46:05 +0530 Subject: [PATCH 7/7] fix: resolved conflicts Signed-off-by: bhavanakarwade --- .../multi-tenancy/MultiTenancyController.ts | 10 +- src/routes/routes.ts | 11 - src/routes/swagger.json | 198 +----------------- 3 files changed, 4 insertions(+), 215 deletions(-) diff --git a/src/controllers/multi-tenancy/MultiTenancyController.ts b/src/controllers/multi-tenancy/MultiTenancyController.ts index 2f84d1cd..16a9b2dc 100644 --- a/src/controllers/multi-tenancy/MultiTenancyController.ts +++ b/src/controllers/multi-tenancy/MultiTenancyController.ts @@ -195,7 +195,7 @@ export class MultiTenancyController extends Controller { break default: - throw new Error(`Invalid network for 'indy' method: ${network}`) + throw new BadRequestError(`Invalid network for 'indy' method: ${network}`) } }) return result @@ -832,10 +832,6 @@ export class MultiTenancyController extends Controller { theirLabel, state, }) - - if (connections.length === 0) { - throw new NotFoundError('connection records not found') - } connectionRecord = connections.map((c: any) => c.toJSON()) } }) @@ -1258,12 +1254,12 @@ export class MultiTenancyController extends Controller { credentialDefinitionResult = await tenantAgent.modules.anoncreds.getCredentialDefinition(credentialDefinitionId) }) - if (credentialDefinitionResult.resolutionMetadata?.error === 'notFound') { + if (credentialDefinitionResult.resolutionMetadata?.error === SchemaError.NotFound) { throw new NotFoundError(credentialDefinitionResult.resolutionMetadata.message) } const error = credentialDefinitionResult.resolutionMetadata?.error - if (error === 'invalid' || error === 'unsupportedAnonCredsMethod') { + if (error === 'invalid' || error === SchemaError.UnSupportedAnonCredsMethod) { throw new BadRequestError(credentialDefinitionResult.resolutionMetadata.message) } diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 4871ff30..b38556ea 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -3163,8 +3163,6 @@ export function RegisterRoutes(app: Router) { async function MultiTenancyController_deleteTenantById(request: ExRequest, response: ExResponse, next: any) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -3202,7 +3200,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, didOptions: {"in":"body","name":"didOptions","required":true,"ref":"DidCreate"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -3240,7 +3237,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, didOptions: {"in":"body","name":"didOptions","required":true,"ref":"DidCreate"}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -3319,8 +3315,6 @@ export function RegisterRoutes(app: Router) { connectionId: {"in":"path","name":"connectionId","required":true,"ref":"RecordId"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, config: {"in":"body","name":"config","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"detail":{"dataType":"string"},"validResponses":{"dataType":"array","array":{"dataType":"refObject","ref":"ValidResponse"},"required":true},"question":{"dataType":"string","required":true}}}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -3359,8 +3353,6 @@ export function RegisterRoutes(app: Router) { id: {"in":"path","name":"id","required":true,"ref":"RecordId"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, request: {"in":"body","name":"request","required":true,"ref":"Record_response.string_"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -3398,7 +3390,6 @@ export function RegisterRoutes(app: Router) { const args: Record = { id: {"in":"path","name":"id","required":true,"ref":"RecordId"}, tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, - notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -3506,8 +3497,6 @@ export function RegisterRoutes(app: Router) { async function EndorserTransactionController_writeSchemaAndCredDefOnLedger(request: ExRequest, response: ExResponse, next: any) { const args: Record = { - forbiddenError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, - internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, writeTransaction: {"in":"body","name":"writeTransaction","required":true,"ref":"WriteTransaction"}, }; diff --git a/src/routes/swagger.json b/src/routes/swagger.json index 53ceef78..5ac2eceb 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -6077,44 +6077,10 @@ "responses": { "200": { "description": "Ok", - "content": { - "application/json": { - "schema": {} - } - } - }, - "404": { - "description": "", "content": { "application/json": { "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" + "$ref": "#/components/schemas/Record_string.any_" } } } @@ -6151,24 +6117,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -6212,24 +6160,6 @@ "schema": {} } } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [ @@ -6349,42 +6279,6 @@ "schema": {} } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Send a question to a connection", @@ -6457,42 +6351,6 @@ "schema": {} } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "description": "Send a answer to question", @@ -6547,24 +6405,6 @@ "schema": {} } } - }, - "404": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } } }, "description": "Retrieve question answer record by id", @@ -6687,42 +6527,6 @@ "schema": {} } } - }, - "400": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "reason": { - "type": "string" - } - }, - "required": [ - "reason" - ], - "type": "object" - } - } - } - }, - "500": { - "description": "", - "content": { - "application/json": { - "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" - } - } - } } }, "tags": [