From db7f963d758ebe9c2c122a0fb33abb4c1b1b13e2 Mon Sep 17 00:00:00 2001 From: pallavicoder Date: Fri, 24 Nov 2023 11:45:11 +0530 Subject: [PATCH 001/107] feat:added api key into ecosystem service Signed-off-by: pallavicoder --- .../src/agent-service.service.ts | 14 + .../repositories/agent-service.repository.ts | 19 + apps/ecosystem/src/ecosystem.service.ts | 16 +- libs/common/src/common.service.ts | 10 +- libs/common/src/response-messages/index.ts | 3 +- package-lock.json | 1708 +++++++++++++++-- 6 files changed, 1607 insertions(+), 163 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index b012c672d..0a59b1a36 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -1071,5 +1071,19 @@ export class AgentServiceService { throw new RpcException(error); } } + async getOrgAgentApiKey(orgId: string): Promise { + try { + const orgAgentApiKey = await this.agentServiceRepository.getAgentApiKey(orgId); + + if (!orgAgentApiKey) { + throw new NotFoundException(ResponseMessages.agent.error.apiKeyNotExist); + } + return orgAgentApiKey; + + } catch (error) { + this.logger.error(`Agent health details : ${JSON.stringify(error)}`); + throw error; + } + } } diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 02d3e5cb2..732cf5825 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -299,4 +299,23 @@ export class AgentServiceRepository { throw error; } } + + + async getAgentApiKey(orgId: string): Promise { + try { + + const agent = await this.prisma.org_agents.findFirst({ + where: { + orgId + } + }); + + return agent.apiKey; + + } catch (error) { + + this.logger.error(`[getAgentApiKey] - get api key: ${JSON.stringify(error)}`); + throw error; + } + } } \ No newline at end of file diff --git a/apps/ecosystem/src/ecosystem.service.ts b/apps/ecosystem/src/ecosystem.service.ts index 969c05e7c..e0b2ddc47 100644 --- a/apps/ecosystem/src/ecosystem.service.ts +++ b/apps/ecosystem/src/ecosystem.service.ts @@ -19,7 +19,7 @@ import { GetAllSchemaList, GetEndorsementsPayload } from '../interfaces/endorsem import { CommonConstants } from '@credebl/common/common.constant'; // eslint-disable-next-line camelcase import { credential_definition, org_agents, platform_config, schema, user } from '@prisma/client'; - +import { getAgentApiKey } from '@credebl/common/common.service'; @Injectable() export class EcosystemService { @@ -416,7 +416,7 @@ export class EcosystemService { const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemMemberDetails.orgAgentTypeId); const url = await this.getAgentUrl(orgAgentType, ecosystemMemberDetails.agentEndPoint, endorsementTransactionType.SCHEMA, ecosystemMemberDetails.tenantId); - + const apiKey = await getAgentApiKey(orgId); const attributeArray = requestSchemaPayload.attributes.map(item => item.attributeName); const schemaTransactionPayload = { @@ -428,7 +428,7 @@ export class EcosystemService { issuerId: ecosystemMemberDetails.orgDid }; - const schemaTransactionRequest: SchemaMessage = await this._requestSchemaEndorsement(schemaTransactionPayload, url, platformConfig?.sgApiKey); + const schemaTransactionRequest: SchemaMessage = await this._requestSchemaEndorsement(schemaTransactionPayload, url, apiKey); const schemaTransactionResponse = { endorserDid: ecosystemLeadAgentDetails.orgDid, @@ -497,7 +497,7 @@ export class EcosystemService { const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemMemberDetails.orgAgentTypeId); const url = await this.getAgentUrl(orgAgentType, ecosystemMemberDetails.agentEndPoint, endorsementTransactionType.CREDENTIAL_DEFINITION, ecosystemMemberDetails.tenantId); - + const apiKey = await getAgentApiKey(orgId); const credDefTransactionPayload = { endorserDid: ecosystemLeadAgentDetails.orgDid, endorse: requestCredDefPayload.endorse, @@ -506,7 +506,7 @@ export class EcosystemService { issuerId: ecosystemMemberDetails.orgDid }; - const credDefTransactionRequest: CredDefMessage = await this._requestCredDeffEndorsement(credDefTransactionPayload, url, platformConfig?.sgApiKey); + const credDefTransactionRequest: CredDefMessage = await this._requestCredDeffEndorsement(credDefTransactionPayload, url, apiKey); if ('failed' === credDefTransactionRequest.message.credentialDefinitionState.state) { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.requestCredDefTransaction); @@ -619,21 +619,21 @@ export class EcosystemService { const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemLeadAgentDetails?.orgAgentTypeId); const url = await this.getAgentUrl(orgAgentType, ecosystemLeadAgentDetails.agentEndPoint, endorsementTransactionType.SIGN, ecosystemLeadAgentDetails?.tenantId); - + const apiKey = await getAgentApiKey(ecosystemLeadDetails.orgId); const jsonString = endorsementTransactionPayload.requestPayload.toString(); const payload = { transaction: jsonString, endorserDid: endorsementTransactionPayload.endorserDid }; - const schemaTransactionRequest: SignedTransactionMessage = await this._signTransaction(payload, url, platformConfig.sgApiKey); + const schemaTransactionRequest: SignedTransactionMessage = await this._signTransaction(payload, url, apiKey); if (!schemaTransactionRequest) { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.signRequestError); } const ecosystemDetails = await this.ecosystemRepository.getEcosystemDetails(ecosystemId); - + if (!ecosystemDetails) { throw new NotFoundException(ResponseMessages.ecosystem.error.ecosystemNotFound); } diff --git a/libs/common/src/common.service.ts b/libs/common/src/common.service.ts index 0c2a0a602..507e22c51 100644 --- a/libs/common/src/common.service.ts +++ b/libs/common/src/common.service.ts @@ -13,13 +13,14 @@ import { HttpService } from '@nestjs/axios/dist'; import { ResponseService } from '@credebl/response'; import { readFileSync } from 'fs'; import { RpcException } from '@nestjs/microservices'; +import { AgentServiceService } from '../../../apps/agent-service/src/agent-service.service'; @Injectable() export class CommonService { private readonly logger = new Logger('CommonService'); result: ResponseService = new ResponseService(); - - constructor(private readonly httpService: HttpService) { } + agentServiceService :AgentServiceService ; + constructor(private readonly httpService: HttpService ) { } async httpPost(url: string, payload?: any, apiKey?: any) { try { @@ -390,4 +391,9 @@ export class CommonService { throw new BadRequestException('Invalid Credentials'); } } + + async getAgentApiKey(orgId: string): Promise { + const apiKey = await this.agentServiceService.getOrgAgentApiKey(orgId); + return apiKey; + } } diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 22606bf8c..0a36098df 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -149,7 +149,8 @@ export const ResponseMessages = { notAbleToSpinUpAgent: 'Agent not able to spin-up', alreadySpinUp: 'Agent already spin-up', agentUrl: 'Agent url not exist', - agentNotExists: 'Agent not spinned up for this organization' + agentNotExists: 'Agent not spinned up for this organization', + apiKeyNotExist:'Api key is not found' } }, connection: { diff --git a/package-lock.json b/package-lock.json index 970155b11..b8281f8f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,6 +51,7 @@ "generate-password": "^1.7.0", "helmet": "^7.0.0", "html-pdf": "^3.0.1", + "html-to-image": "^1.11.11", "json2csv": "^5.0.7", "jsonwebtoken": "^9.0.1", "jwks-rsa": "^3.0.1", @@ -61,6 +62,7 @@ "nats": "^2.15.1", "nestjs-supabase-auth": "^1.0.9", "nestjs-typeorm-paginate": "^4.0.4", + "node-html-to-image": "^4.0.0", "node-qpdf2": "^2.0.0", "papaparse": "^5.4.1", "passport": "^0.6.0", @@ -69,6 +71,7 @@ "path": "^0.12.7", "pdfkit": "^0.13.0", "pg": "^8.11.2", + "puppeteer": "^21.5.0", "qrcode": "^1.5.3", "qs": "^6.11.2", "reflect-metadata": "^0.1.13", @@ -257,7 +260,6 @@ "version": "7.22.10", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", - "dev": true, "dependencies": { "@babel/highlight": "^7.22.10", "chalk": "^2.4.2" @@ -270,7 +272,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -282,7 +283,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -296,7 +296,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -304,14 +303,12 @@ "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -320,7 +317,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -329,7 +325,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -557,7 +552,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -589,7 +583,6 @@ "version": "7.22.10", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.4.2", @@ -603,7 +596,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -615,7 +607,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -629,7 +620,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -637,14 +627,12 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -653,7 +641,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -662,7 +649,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -2338,6 +2324,67 @@ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e.tgz", "integrity": "sha512-owZqbY/wucbr65bXJ/ljrHPgQU5xXTSkmcE/JcbqE1kusuAXV/TLN3/exmz21SZ5rJ7WDkyk70J2G/n68iogbQ==" }, + "node_modules/@puppeteer/browsers": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.8.0.tgz", + "integrity": "sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==", + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.3.1", + "tar-fs": "3.0.4", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=16.3.0" + } + }, + "node_modules/@puppeteer/browsers/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/@puppeteer/browsers/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@puppeteer/browsers/node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/@sendgrid/client": { "version": "7.7.0", "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", @@ -2490,6 +2537,11 @@ "tslib": "^2.4.0" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -2900,6 +2952,15 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.3.0.tgz", @@ -3669,6 +3730,17 @@ "node": ">=0.8" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -3821,6 +3893,11 @@ "node": ">= 6" } }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, "node_modules/babel-jest": { "version": "29.6.2", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", @@ -3944,6 +4021,14 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/basic-ftp": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", + "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bcrypt": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", @@ -4232,7 +4317,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "optional": true, "engines": { "node": "*" } @@ -4372,7 +4456,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -4496,6 +4579,18 @@ "node": ">=6.0" } }, + "node_modules/chromium-bidi": { + "version": "0.4.33", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.33.tgz", + "integrity": "sha512-IxoFM5WGQOIAd95qrSXzJUv4eXIrh+RvU3rwwqIiwYuvfE7U/Llj4fejbsJnjJMUYCuGtVQsY2gv7oGl4aTNSQ==", + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "9.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -4947,6 +5042,14 @@ "node": ">=12.0.0" } }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5001,6 +5104,14 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", + "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", + "engines": { + "node": ">= 14" + } + }, "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -5132,6 +5243,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5187,6 +5311,11 @@ "node": ">=8" } }, + "node_modules/devtools-protocol": { + "version": "0.0.1203626", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1203626.tgz", + "integrity": "sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==" + }, "node_modules/dezalgo": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", @@ -5350,7 +5479,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -5420,7 +5548,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -5606,6 +5733,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint": { "version": "8.47.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", @@ -6150,7 +6306,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -6187,7 +6342,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -6196,7 +6350,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6467,6 +6620,11 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -6522,7 +6680,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "optional": true, "dependencies": { "pend": "~1.2.0" } @@ -6989,6 +7146,49 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-uri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", + "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.0", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/get-uri/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/get-uri/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -7119,6 +7319,34 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7297,6 +7525,11 @@ "phantomjs-prebuilt": "^2.1.16" } }, + "node_modules/html-to-image": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", + "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" + }, "node_modules/http_ece": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.1.0.tgz", @@ -7323,6 +7556,29 @@ "node": ">= 0.8" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -7430,7 +7686,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7555,6 +7810,11 @@ "url": "https://opencollective.com/ioredis" } }, + "node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -7594,8 +7854,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-bigint": { "version": "1.0.4", @@ -8648,8 +8907,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -8682,8 +8940,7 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema": { "version": "0.4.0", @@ -8928,8 +9185,7 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lint-staged": { "version": "13.3.0", @@ -9695,6 +9951,11 @@ "node": ">=8" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -9706,6 +9967,11 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -9832,8 +10098,7 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/nestjs-supabase-auth": { "version": "1.0.9", @@ -9849,6 +10114,14 @@ "typeorm": "^0.3.0" } }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -9925,62 +10198,282 @@ "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-qpdf2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-qpdf2/-/node-qpdf2-2.0.0.tgz", - "integrity": "sha512-Xoxe53XsEriaVLWJTl3YtHE54qaZnO2GeoNKKALLy6cKUAjYZuFlTaNCcsVkfoIbZv2YYWuggeuqhTQ1XPbvgw==", - "engines": { - "node": ">=10.17.0" + "node_modules/node-html-to-image": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-html-to-image/-/node-html-to-image-4.0.0.tgz", + "integrity": "sha512-lB8fkRleAKG4afJ2Wr7qJzIA5+//ue9OEoz+BMxQsowriGKR8sf4j4lK/pIXKakYwf/3aZHoDUNgOXuJ4HOzYA==", + "dependencies": { + "handlebars": "4.7.8", + "puppeteer": "21.0.1", + "puppeteer-cluster": "^0.23.0" } }, - "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "node_modules/node-html-to-image/node_modules/@puppeteer/browsers": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.5.0.tgz", + "integrity": "sha512-za318PweGINh5LnHSph7C4xhs0tmRjCD8EPpzcKlw4nzSPhnULj+LTG3+TGefZvW1ti5gjw2JkdQvQsivBeZlg==", "dependencies": { - "abbrev": "1" + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.3.0", + "tar-fs": "3.0.4", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" }, "bin": { - "nopt": "bin/nopt.js" + "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">=6" + "node": ">=16.3.0" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, + "node_modules/node-html-to-image/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 14" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, + "node_modules/node-html-to-image/node_modules/chromium-bidi": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.20.tgz", + "integrity": "sha512-ruHgVZFEv00mAQMz1tQjfjdG63jiPWrQPF6HLlX2ucqLqVTJoWngeBEKHaJ6n1swV/HSvgnBNbtTRIlcVyW3Fw==", "dependencies": { - "path-key": "^3.0.0" + "mitt": "3.0.1" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "devtools-protocol": "*" } }, - "node_modules/npmlog": { + "node_modules/node-html-to-image/node_modules/cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/node-html-to-image/node_modules/devtools-protocol": { + "version": "0.0.1147663", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", + "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==" + }, + "node_modules/node-html-to-image/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/node-html-to-image/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/node-html-to-image/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/node-html-to-image/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/node-html-to-image/node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/node-html-to-image/node_modules/proxy-agent": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", + "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/node-html-to-image/node_modules/puppeteer": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.0.1.tgz", + "integrity": "sha512-KTjmSdPZ6bMkq3EbAzAUhcB3gMDXvdwd6912rxG9hNtjwRJzHSA568vh6vIbO2WQeNmozRdt1LtiUMLSWfeMrg==", + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "1.5.0", + "cosmiconfig": "8.2.0", + "puppeteer-core": "21.0.1" + }, + "engines": { + "node": ">=16.3.0" + } + }, + "node_modules/node-html-to-image/node_modules/puppeteer-core": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.0.1.tgz", + "integrity": "sha512-E8eWLGhaZZpa7dYe/58qGX7SLb4mTg42NP5M7B+ibPrncgNjTOQa9x1sFIlTn1chF/BmoZqOcMIvwuxcb/9XzQ==", + "dependencies": { + "@puppeteer/browsers": "1.5.0", + "chromium-bidi": "0.4.20", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1147663", + "ws": "8.13.0" + }, + "engines": { + "node": ">=16.3.0" + } + }, + "node_modules/node-html-to-image/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/node-html-to-image/node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-qpdf2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-qpdf2/-/node-qpdf2-2.0.0.tgz", + "integrity": "sha512-Xoxe53XsEriaVLWJTl3YtHE54qaZnO2GeoNKKALLy6cKUAjYZuFlTaNCcsVkfoIbZv2YYWuggeuqhTQ1XPbvgw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", @@ -10247,6 +10740,60 @@ "node": ">=6" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "dependencies": { + "degenerator": "^5.0.0", + "ip": "^1.1.8", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/packet-reader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", @@ -10266,7 +10813,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -10278,7 +10824,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -10428,7 +10973,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -10452,8 +10996,7 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "optional": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/performance-now": { "version": "2.1.0", @@ -10904,11 +11447,59 @@ "node": ">= 0.10" } }, + "node_modules/proxy-agent": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", + "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "peer": true + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/pseudomap": { "version": "1.0.2", @@ -10925,7 +11516,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -10940,6 +11530,92 @@ "node": ">=6" } }, + "node_modules/puppeteer": { + "version": "21.5.2", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.5.2.tgz", + "integrity": "sha512-BaAGJOq8Fl6/cck6obmwaNLksuY0Bg/lIahCLhJPGXBFUD2mCffypa4A592MaWnDcye7eaHmSK9yot0pxctY8A==", + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "1.8.0", + "cosmiconfig": "8.3.6", + "puppeteer-core": "21.5.2" + }, + "engines": { + "node": ">=16.13.2" + } + }, + "node_modules/puppeteer-cluster": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/puppeteer-cluster/-/puppeteer-cluster-0.23.0.tgz", + "integrity": "sha512-108terIWDzPrQopmoYSPd5yDoy3FGJ2dNnoGMkGYPs6xtkdhgaECwpfZkzaRToMQPZibUOz0/dSSGgPEdXEhkQ==", + "dependencies": { + "debug": "^4.3.3" + }, + "peerDependencies": { + "puppeteer": ">=1.5.0" + } + }, + "node_modules/puppeteer-core": { + "version": "21.5.2", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.5.2.tgz", + "integrity": "sha512-v4T0cWnujSKs+iEfmb8ccd7u4/x8oblEyKqplqKnJ582Kw8PewYAWvkH4qUWhitN3O2q9RF7dzkvjyK5HbzjLA==", + "dependencies": { + "@puppeteer/browsers": "1.8.0", + "chromium-bidi": "0.4.33", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1203626", + "ws": "8.14.2" + }, + "engines": { + "node": ">=16.13.2" + } + }, + "node_modules/puppeteer-core/node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/puppeteer/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/pure-rand": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", @@ -11125,6 +11801,11 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11431,7 +12112,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -11840,6 +12520,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/socket.io": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.1.tgz", @@ -11891,6 +12580,48 @@ "node": ">=10.0.0" } }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", + "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks/node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -12023,6 +12754,15 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.15.5", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.5.tgz", + "integrity": "sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -12359,6 +13099,26 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/tar/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -12505,8 +13265,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tiny-inflate": { "version": "1.0.3", @@ -13088,6 +13847,18 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/uid": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", @@ -13114,6 +13885,38 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/unfetch": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", @@ -13229,6 +14032,11 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" }, + "node_modules/urlpattern-polyfill": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", + "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==" + }, "node_modules/urlsafe-base64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", @@ -13705,6 +14513,11 @@ "node": ">=8.12.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -13865,7 +14678,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "optional": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -13999,7 +14811,6 @@ "version": "7.22.10", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", - "dev": true, "requires": { "@babel/highlight": "^7.22.10", "chalk": "^2.4.2" @@ -14009,7 +14820,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -14018,7 +14828,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -14029,7 +14838,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -14037,26 +14845,22 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -14234,8 +15038,7 @@ "@babel/helper-validator-identifier": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" }, "@babel/helper-validator-option": { "version": "7.22.5", @@ -14258,7 +15061,6 @@ "version": "7.22.10", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.4.2", @@ -14269,7 +15071,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -14278,7 +15079,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -14289,7 +15089,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -14297,26 +15096,22 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -15457,6 +16252,46 @@ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e.tgz", "integrity": "sha512-owZqbY/wucbr65bXJ/ljrHPgQU5xXTSkmcE/JcbqE1kusuAXV/TLN3/exmz21SZ5rJ7WDkyk70J2G/n68iogbQ==" }, + "@puppeteer/browsers": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.8.0.tgz", + "integrity": "sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==", + "requires": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.3.1", + "tar-fs": "3.0.4", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "dependencies": { + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + } + } + }, "@sendgrid/client": { "version": "7.7.0", "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", @@ -15599,6 +16434,11 @@ "tslib": "^2.4.0" } }, + "@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -16009,6 +16849,15 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.3.0.tgz", @@ -16583,6 +17432,14 @@ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "optional": true }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "requires": { + "tslib": "^2.0.1" + } + }, "async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -16718,6 +17575,11 @@ } } }, + "b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, "babel-jest": { "version": "29.6.2", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", @@ -16803,6 +17665,11 @@ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" }, + "basic-ftp": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", + "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==" + }, "bcrypt": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", @@ -17016,8 +17883,7 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "optional": true + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" }, "buffer-equal-constant-time": { "version": "1.0.1", @@ -17124,8 +17990,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { "version": "5.3.1", @@ -17200,6 +18065,15 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, + "chromium-bidi": { + "version": "0.4.33", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.33.tgz", + "integrity": "sha512-IxoFM5WGQOIAd95qrSXzJUv4eXIrh+RvU3rwwqIiwYuvfE7U/Llj4fejbsJnjJMUYCuGtVQsY2gv7oGl4aTNSQ==", + "requires": { + "mitt": "3.0.1", + "urlpattern-polyfill": "9.0.0" + } + }, "ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -17543,6 +18417,14 @@ "luxon": "^3.2.1" } }, + "cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "requires": { + "node-fetch": "^2.6.12" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -17585,6 +18467,11 @@ "assert-plus": "^1.0.0" } }, + "data-uri-to-buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", + "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==" + }, "date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -17675,6 +18562,16 @@ "object-keys": "^1.1.1" } }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -17711,6 +18608,11 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, + "devtools-protocol": { + "version": "0.0.1203626", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1203626.tgz", + "integrity": "sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==" + }, "dezalgo": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", @@ -17846,7 +18748,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -17906,7 +18807,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -18061,6 +18961,25 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, "eslint": { "version": "8.47.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", @@ -18423,8 +19342,7 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.5.0", @@ -18447,14 +19365,12 @@ "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "etag": { "version": "1.8.1", @@ -18685,6 +19601,11 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -18737,7 +19658,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "optional": true, "requires": { "pend": "~1.2.0" } @@ -19084,6 +20004,42 @@ "get-intrinsic": "^1.1.1" } }, + "get-uri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", + "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.0", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -19180,6 +20136,25 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -19298,6 +20273,11 @@ "phantomjs-prebuilt": "^2.1.16" } }, + "html-to-image": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz", + "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" + }, "http_ece": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.1.0.tgz", @@ -19318,6 +20298,25 @@ "toidentifier": "1.0.1" } }, + "http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -19386,7 +20385,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -19477,6 +20475,11 @@ "standard-as-callback": "^2.1.0" } }, + "ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -19504,8 +20507,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-bigint": { "version": "1.0.4", @@ -20275,8 +21277,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "4.1.0", @@ -20300,8 +21301,7 @@ "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema": { "version": "0.4.0", @@ -20503,8 +21503,7 @@ "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "lint-staged": { "version": "13.3.0", @@ -21031,6 +22030,11 @@ } } }, + "mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -21039,6 +22043,11 @@ "minimist": "^1.2.6" } }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -21135,8 +22144,7 @@ "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "nestjs-supabase-auth": { "version": "1.0.9", @@ -21149,6 +22157,11 @@ "integrity": "sha512-arinWDc78wPV/EYWMmLYyeMSE5Lae1FHWD/2QpOdTmHaOVqK4PYf19EqZBqT9gbbPugkNW9JAMz3G2WmvSgR/A==", "requires": {} }, + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" + }, "next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -21201,6 +22214,160 @@ "integrity": "sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==", "optional": true }, + "node-html-to-image": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-html-to-image/-/node-html-to-image-4.0.0.tgz", + "integrity": "sha512-lB8fkRleAKG4afJ2Wr7qJzIA5+//ue9OEoz+BMxQsowriGKR8sf4j4lK/pIXKakYwf/3aZHoDUNgOXuJ4HOzYA==", + "requires": { + "handlebars": "4.7.8", + "puppeteer": "21.0.1", + "puppeteer-cluster": "^0.23.0" + }, + "dependencies": { + "@puppeteer/browsers": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.5.0.tgz", + "integrity": "sha512-za318PweGINh5LnHSph7C4xhs0tmRjCD8EPpzcKlw4nzSPhnULj+LTG3+TGefZvW1ti5gjw2JkdQvQsivBeZlg==", + "requires": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.3.0", + "tar-fs": "3.0.4", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + } + }, + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "chromium-bidi": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.20.tgz", + "integrity": "sha512-ruHgVZFEv00mAQMz1tQjfjdG63jiPWrQPF6HLlX2ucqLqVTJoWngeBEKHaJ6n1swV/HSvgnBNbtTRIlcVyW3Fw==", + "requires": { + "mitt": "3.0.1" + } + }, + "cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "requires": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + } + }, + "devtools-protocol": { + "version": "0.0.1147663", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", + "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==" + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "proxy-agent": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", + "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", + "requires": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.1" + } + }, + "puppeteer": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.0.1.tgz", + "integrity": "sha512-KTjmSdPZ6bMkq3EbAzAUhcB3gMDXvdwd6912rxG9hNtjwRJzHSA568vh6vIbO2WQeNmozRdt1LtiUMLSWfeMrg==", + "requires": { + "@puppeteer/browsers": "1.5.0", + "cosmiconfig": "8.2.0", + "puppeteer-core": "21.0.1" + } + }, + "puppeteer-core": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.0.1.tgz", + "integrity": "sha512-E8eWLGhaZZpa7dYe/58qGX7SLb4mTg42NP5M7B+ibPrncgNjTOQa9x1sFIlTn1chF/BmoZqOcMIvwuxcb/9XzQ==", + "requires": { + "@puppeteer/browsers": "1.5.0", + "chromium-bidi": "0.4.20", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1147663", + "ws": "8.13.0" + } + }, + "ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "requires": {} + }, + "yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + } + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -21427,6 +22594,50 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + } + } + }, + "pac-resolver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "requires": { + "degenerator": "^5.0.0", + "ip": "^1.1.8", + "netmask": "^2.0.2" + } + }, "packet-reader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", @@ -21446,7 +22657,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" } @@ -21455,7 +22665,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -21569,8 +22778,7 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "pause": { "version": "0.0.1", @@ -21591,8 +22799,7 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "optional": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "performance-now": { "version": "2.1.0", @@ -21920,11 +23127,49 @@ "ipaddr.js": "1.9.1" } }, + "proxy-agent": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", + "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "requires": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + } + } + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "peer": true + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "pseudomap": { "version": "1.0.2", @@ -21941,7 +23186,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -21953,6 +23197,58 @@ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "devOptional": true }, + "puppeteer": { + "version": "21.5.2", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.5.2.tgz", + "integrity": "sha512-BaAGJOq8Fl6/cck6obmwaNLksuY0Bg/lIahCLhJPGXBFUD2mCffypa4A592MaWnDcye7eaHmSK9yot0pxctY8A==", + "requires": { + "@puppeteer/browsers": "1.8.0", + "cosmiconfig": "8.3.6", + "puppeteer-core": "21.5.2" + }, + "dependencies": { + "cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "requires": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + } + } + } + }, + "puppeteer-cluster": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/puppeteer-cluster/-/puppeteer-cluster-0.23.0.tgz", + "integrity": "sha512-108terIWDzPrQopmoYSPd5yDoy3FGJ2dNnoGMkGYPs6xtkdhgaECwpfZkzaRToMQPZibUOz0/dSSGgPEdXEhkQ==", + "requires": { + "debug": "^4.3.3" + } + }, + "puppeteer-core": { + "version": "21.5.2", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.5.2.tgz", + "integrity": "sha512-v4T0cWnujSKs+iEfmb8ccd7u4/x8oblEyKqplqKnJ582Kw8PewYAWvkH4qUWhitN3O2q9RF7dzkvjyK5HbzjLA==", + "requires": { + "@puppeteer/browsers": "1.8.0", + "chromium-bidi": "0.4.33", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1203626", + "ws": "8.14.2" + }, + "dependencies": { + "ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "requires": {} + } + } + }, "pure-rand": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", @@ -22076,6 +23372,11 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -22317,8 +23618,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "resolve.exports": { "version": "2.0.2", @@ -22618,6 +23918,11 @@ } } }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, "socket.io": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.1.tgz", @@ -22660,6 +23965,42 @@ "debug": "~4.3.1" } }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "dependencies": { + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + } + } + }, + "socks-proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", + "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "requires": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + } + } + }, "source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -22766,6 +24107,15 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" }, + "streamx": { + "version": "2.15.5", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.5.tgz", + "integrity": "sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==", + "requires": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -23024,6 +24374,26 @@ } } }, + "tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "requires": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "requires": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "terser": { "version": "5.19.2", "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", @@ -23121,8 +24491,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "tiny-inflate": { "version": "1.0.3", @@ -23469,6 +24838,12 @@ "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", "devOptional": true }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true + }, "uid": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", @@ -23489,6 +24864,26 @@ "which-boxed-primitive": "^1.0.2" } }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, "unfetch": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", @@ -23580,6 +24975,11 @@ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" }, + "urlpattern-polyfill": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", + "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==" + }, "urlsafe-base64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", @@ -23964,6 +25364,11 @@ } } }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -24071,7 +25476,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "optional": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" From 2a5a3068470dfe9bda316d5084f00937f8aa9a83 Mon Sep 17 00:00:00 2001 From: pallavicoder Date: Fri, 24 Nov 2023 12:09:42 +0530 Subject: [PATCH 002/107] feat:added api key inside sign transaction Signed-off-by: pallavicoder --- apps/ecosystem/src/ecosystem.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/ecosystem/src/ecosystem.service.ts b/apps/ecosystem/src/ecosystem.service.ts index e0b2ddc47..7ec0f4ba5 100644 --- a/apps/ecosystem/src/ecosystem.service.ts +++ b/apps/ecosystem/src/ecosystem.service.ts @@ -834,15 +834,15 @@ export class EcosystemService { const ecosystemMemberDetails = await this.getEcosystemMemberDetails(endorsementTransactionPayload); const ecosystemLeadAgentDetails = await this.getEcosystemLeadAgentDetails(ecosystemId); - const platformConfig = await this.getPlatformConfig(); + const agentEndPoint = ecosystemLeadAgentEndPoint ? ecosystemLeadAgentEndPoint : ecosystemMemberDetails.agentEndPoint; const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemMemberDetails?.orgAgentTypeId); const url = await this.getAgentUrl(orgAgentType, agentEndPoint, endorsementTransactionType.SUBMIT, ecosystemMemberDetails?.tenantId); const payload = await this.submitTransactionPayload(endorsementTransactionPayload, ecosystemMemberDetails, ecosystemLeadAgentDetails); - - const submitTransactionRequest = await this._submitTransaction(payload, url, platformConfig.sgApiKey); + const apiKey = await getAgentApiKey(endorsementTransactionPayload.ecosystemOrgs.orgId); + const submitTransactionRequest = await this._submitTransaction(payload, url, apiKey); if ('failed' === submitTransactionRequest['message'].state) { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.sumbitTransaction); From 659f74dae2e6bc694f847b4be81da33d8a8cd44e Mon Sep 17 00:00:00 2001 From: Moulika Kulkarni Date: Wed, 13 Dec 2023 19:49:43 +0530 Subject: [PATCH 003/107] refactor:API response Signed-off-by: Moulika Kulkarni --- .../organization/organization.controller.ts | 2 +- .../src/organization/organization.service.ts | 35 +++-- .../interfaces/organization.interface.ts | 121 +++++++++++++++++- .../repositories/organization.repository.ts | 38 +++--- .../src/organization.controller.ts | 28 ++-- apps/organization/src/organization.service.ts | 26 ++-- apps/user/interfaces/user.interface.ts | 50 +++++++- apps/user/repositories/user.repository.ts | 64 +++++---- apps/user/src/user.controller.ts | 4 +- apps/user/src/user.service.ts | 3 +- .../interfaces/org-roles.interface.ts | 9 ++ libs/org-roles/repositories/index.ts | 6 +- libs/org-roles/src/org-roles.service.ts | 5 +- 13 files changed, 292 insertions(+), 99 deletions(-) create mode 100644 libs/org-roles/interfaces/org-roles.interface.ts diff --git a/apps/api-gateway/src/organization/organization.controller.ts b/apps/api-gateway/src/organization/organization.controller.ts index 865ec93ef..c82779f58 100644 --- a/apps/api-gateway/src/organization/organization.controller.ts +++ b/apps/api-gateway/src/organization/organization.controller.ts @@ -119,7 +119,7 @@ export class OrganizationController { @ApiParam({ name: 'orgSlug', type: String, - required: false + required: true }) async getPublicProfile(@Param('orgSlug') orgSlug: string, @Res() res: Response): Promise { const userData = await this.organizationService.getPublicProfile(orgSlug); diff --git a/apps/api-gateway/src/organization/organization.service.ts b/apps/api-gateway/src/organization/organization.service.ts index c1d44ac64..ddf56b908 100644 --- a/apps/api-gateway/src/organization/organization.service.ts +++ b/apps/api-gateway/src/organization/organization.service.ts @@ -9,6 +9,12 @@ import { BulkSendInvitationDto } from './dtos/send-invitation.dto'; import { UpdateUserRolesDto } from './dtos/update-user-roles.dto'; import { UpdateOrganizationDto } from './dtos/update-organization-dto'; import { GetAllUsersDto } from '../user/dto/get-all-users.dto'; +// eslint-disable-next-line camelcase +import { Org_roles } from 'libs/org-roles/interfaces/org-roles.interface'; +import { organisation } from '@prisma/client'; +// eslint-disable-next-line camelcase +import { GetOrgs, OrgInvitationsPagination, getOrgById, organization_dashboard } from 'apps/organization/interfaces/organization.interface'; +import { OrgUsers } from 'apps/user/interfaces/user.interface'; @Injectable() export class OrganizationService extends BaseService { @@ -21,7 +27,7 @@ export class OrganizationService extends BaseService { * @param createOrgDto * @returns Organization creation Success */ - async createOrganization(createOrgDto: CreateOrganizationDto, userId: string): Promise { + async createOrganization(createOrgDto: CreateOrganizationDto, userId: string): Promise { const payload = { createOrgDto, userId }; return this.sendNats(this.serviceProxy, 'create-organization', payload); } @@ -31,7 +37,7 @@ export class OrganizationService extends BaseService { * @param updateOrgDto * @returns Organization update Success */ - async updateOrganization(updateOrgDto: UpdateOrganizationDto, userId: string, orgId: string): Promise { + async updateOrganization(updateOrgDto: UpdateOrganizationDto, userId: string, orgId: string): Promise { const payload = { updateOrgDto, userId, orgId }; return this.sendNats(this.serviceProxy, 'update-organization', payload); } @@ -41,7 +47,8 @@ export class OrganizationService extends BaseService { * @param * @returns Organizations details */ - async getOrganizations(getAllOrgsDto: GetAllOrganizationsDto, userId: string): Promise<{ response: object }> { + // eslint-disable-next-line camelcase + async getOrganizations(getAllOrgsDto: GetAllOrganizationsDto, userId: string): Promise<{ response: Org_roles[] }> { const payload = { userId, ...getAllOrgsDto }; return this.sendNats(this.serviceProxy, 'get-organizations', payload); } @@ -51,12 +58,12 @@ export class OrganizationService extends BaseService { * @param * @returns Public organizations list */ - async getPublicOrganizations(getAllOrgsDto: GetAllOrganizationsDto): Promise<{ response: object }> { + async getPublicOrganizations(getAllOrgsDto: GetAllOrganizationsDto): Promise<{ response: GetOrgs }> { const payload = { ...getAllOrgsDto }; return this.sendNats(this.serviceProxy, 'get-public-organizations', payload); } - async getPublicProfile(orgSlug: string): Promise<{ response: object }> { + async getPublicProfile(orgSlug: string): Promise<{ response: getOrgById }> { const payload = { orgSlug }; try { return this.sendNats(this.serviceProxy, 'get-organization-public-profile', payload); @@ -70,7 +77,7 @@ export class OrganizationService extends BaseService { * @param orgId * @returns Organization get Success */ - async getOrganization(orgId: string, userId: string): Promise<{ response: object }> { + async getOrganization(orgId: string, userId: string): Promise<{ response: getOrgById }> { const payload = { orgId, userId }; return this.sendNats(this.serviceProxy, 'get-organization-by-id', payload); } @@ -83,13 +90,14 @@ export class OrganizationService extends BaseService { async getInvitationsByOrgId( orgId: string, getAllInvitationsDto: GetAllSentInvitationsDto - ): Promise<{ response: object }> { + ): Promise<{ response: OrgInvitationsPagination }> { const { pageNumber, pageSize, search } = getAllInvitationsDto; const payload = { orgId, pageNumber, pageSize, search }; return this.sendNats(this.serviceProxy, 'get-invitations-by-orgId', payload); } - async getOrganizationDashboard(orgId: string, userId: string): Promise<{ response: object }> { + // eslint-disable-next-line camelcase + async getOrganizationDashboard(orgId: string, userId: string): Promise<{ response: organization_dashboard }> { const payload = { orgId, userId }; return this.sendNats(this.serviceProxy, 'get-organization-dashboard', payload); } @@ -99,7 +107,8 @@ export class OrganizationService extends BaseService { * @param * @returns get organization roles */ - async getOrgRoles(): Promise { + // eslint-disable-next-line camelcase + async getOrgRoles(): Promise { const payload = {}; return this.sendNats(this.serviceProxy, 'get-org-roles', payload); } @@ -109,7 +118,7 @@ export class OrganizationService extends BaseService { * @param sendInvitationDto * @returns Organization invitation creation Success */ - async createInvitation(bulkInvitationDto: BulkSendInvitationDto, userId: string, userEmail: string): Promise { + async createInvitation(bulkInvitationDto: BulkSendInvitationDto, userId: string, userEmail: string): Promise { const payload = { bulkInvitationDto, userId, userEmail }; return this.sendNats(this.serviceProxy, 'send-invitation', payload); } @@ -128,7 +137,7 @@ export class OrganizationService extends BaseService { async getOrgUsers( orgId: string, getAllUsersDto: GetAllUsersDto - ): Promise<{ response: object }> { + ): Promise<{ response: OrgUsers }> { const { pageNumber, pageSize, search } = getAllUsersDto; const payload = { orgId, pageNumber, pageSize, search }; @@ -137,7 +146,7 @@ export class OrganizationService extends BaseService { async getOgPofile( orgId: string - ): Promise<{ response: object }> { + ): Promise<{ response: organisation }> { const payload = { orgId }; return this.sendNats(this.serviceProxy, 'fetch-organization-profile', payload); @@ -145,7 +154,7 @@ export class OrganizationService extends BaseService { async deleteOrganization( orgId: number - ): Promise<{ response: object }> { + ): Promise<{ response: boolean }> { const payload = { orgId }; return this.sendNats(this.serviceProxy, 'delete-organization', payload); diff --git a/apps/organization/interfaces/organization.interface.ts b/apps/organization/interfaces/organization.interface.ts index 7781994e0..7a36b3aa5 100644 --- a/apps/organization/interfaces/organization.interface.ts +++ b/apps/organization/interfaces/organization.interface.ts @@ -6,12 +6,6 @@ export interface IUserOrgRoles { orgRole: OrgRole } -export interface OrgRole { - id: string - name: string - description: string -} - export interface IUpdateOrganization { name: string; description?: string; @@ -27,4 +21,119 @@ export interface IUpdateOrganization { export interface OrgAgent { url: string; apiKey: string; +} + +export interface Org_Role { + id: string; + name: string; + description: string; + orgSlug: string; + logoUrl: string; + website: string; + publicProfile: boolean; + schema: Schema[]; + org_agents: OrgAgents; + userOrgRoles: UserOrgRole; +} + +export interface getOrgById { + id: string; + name: string; + description: string; + orgSlug: string; + logoUrl: string; + website: string; + publicProfile: boolean; + schema: Schema[]; + org_agents: OrgAgents[]; +} + +interface Schema { + id: string; + name: string; +} + +interface OrgAgents { + agent_invitations: AgentInvitation[]; + ledgers: Ledgers; + org_agent_type: Org_agent_type; +} + +interface AgentInvitation { + id: string; + connectionInvitation: string; + multiUse: boolean; +} + +export interface UserOrgRole { + user: string; + orgRole: string; +} + +interface Org_agent_type { + id: string; + createDateTime: Date; + lastChangedDateTime: Date; + agent: string; +} + +interface Ledgers { + id: string; + name: string; + networkType: string +} + +export interface GetOrgs { + totalPages:number; + organizations : AllOrganizations[]; +} + +interface AllOrganizations { + id: string, + name: string, + description: string, + logoUrl: string, + orgSlug: string, + userOrgRoles: UserOrgRoles[]; +} + +interface UserOrgRoles { + id: string, + orgRole :OrgRole; +} + +export interface OrgRole { + id: string + name: string + description: string +} + +export interface OrgInvitationsPagination { + totalPages: number; + invitations: Invitation[]; +} + +interface Invitation { + id: string, + orgId: string, + email: string, + userId: string, + status: string, + orgRoles: string[], + createDateTime: Date, + createdBy:string, + organisation: OrganizationPagination; +} + +interface OrganizationPagination { + id: string; + name: string; + logoUrl: string; +} + +export interface organization_dashboard { + usersCount: number, + schemasCount: number, + credentialsCount: number, + presentationsCount:number } \ No newline at end of file diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index 5e56ceb56..af29cffd6 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -6,7 +6,7 @@ import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { org_agents, org_invitations, user_org_roles } from '@prisma/client'; import { CreateOrganizationDto } from '../dtos/create-organization.dto'; -import { IUpdateOrganization } from '../interfaces/organization.interface'; +import { GetOrgs, IUpdateOrganization, OrgInvitationsPagination, getOrgById, organization_dashboard } from '../interfaces/organization.interface'; import { InternalServerErrorException } from '@nestjs/common'; import { Invitation } from '@credebl/enum/enum'; import { PrismaService } from '@credebl/prisma-service'; @@ -204,21 +204,29 @@ export class OrganizationRepository { } } - async getOrgInvitationsPagination(queryObject: object, pageNumber: number, pageSize: number): Promise { + async getOrgInvitationsPagination(queryObject: object, pageNumber: number, pageSize: number): Promise { try { const result = await this.prisma.$transaction([ this.prisma.org_invitations.findMany({ where: { ...queryObject }, - include: { + select: { + id: true, + orgId: true, + email: true, + userId: true, + status: true, + createDateTime: true, + createdBy: true, organisation: { select: { id: true, name: true, logoUrl: true } - } + }, + orgRoles: true }, take: pageSize, skip: (pageNumber - 1) * pageSize, @@ -244,7 +252,7 @@ export class OrganizationRepository { } } - async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search = ''): Promise { + async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search = ''): Promise { try { const query = { orgId, @@ -261,7 +269,7 @@ export class OrganizationRepository { } } - async getOrganization(queryObject: object): Promise { + async getOrganization(queryObject: object): Promise { try { return this.prisma.organisation.findFirst({ where: { @@ -283,20 +291,19 @@ export class OrganizationRepository { }, org_agents: { select: { - orgDid: true, id: true, + orgDid: true, walletName: true, + agentEndPoint: true, agentSpinUpStatus: true, agentsTypeId: true, + orgAgentTypeId: true, createDateTime: true, - orgAgentTypeId:true, agent_invitations: { select: { id: true, connectionInvitation: true, - multiUse: true, - createDateTime: true, - lastChangedDateTime:true + multiUse: true } }, org_agent_type: true, @@ -317,7 +324,7 @@ export class OrganizationRepository { } } - async getOrgDashboard(orgId: string): Promise { + async getOrgDashboard(orgId: string): Promise { const query = { where: { @@ -413,7 +420,7 @@ export class OrganizationRepository { filterOptions: object, pageNumber: number, pageSize: number - ): Promise { + ): Promise { try { const sortByName = 'asc'; const result = await this.prisma.$transaction([ @@ -433,7 +440,8 @@ export class OrganizationRepository { orgRole: { select: { id: true, - name: true + name: true, + description: true } } }, @@ -447,7 +455,7 @@ export class OrganizationRepository { skip: (pageNumber - 1) * pageSize, orderBy: { name: sortByName - + } }), this.prisma.organisation.count({ diff --git a/apps/organization/src/organization.controller.ts b/apps/organization/src/organization.controller.ts index f77ef73ee..27393172c 100644 --- a/apps/organization/src/organization.controller.ts +++ b/apps/organization/src/organization.controller.ts @@ -6,7 +6,11 @@ import { Body } from '@nestjs/common'; import { CreateOrganizationDto } from '../dtos/create-organization.dto'; import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; -import { IUpdateOrganization } from '../interfaces/organization.interface'; +// eslint-disable-next-line camelcase +import { GetOrgs, IUpdateOrganization, OrgInvitationsPagination, getOrgById, organization_dashboard } from '../interfaces/organization.interface'; +import { organisation } from '@prisma/client'; +// eslint-disable-next-line camelcase +import { Org_roles } from 'libs/org-roles/interfaces/org-roles.interface'; @Controller() export class OrganizationController { @@ -20,7 +24,7 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'create-organization' }) - async createOrganization(@Body() payload: { createOrgDto: CreateOrganizationDto; userId: string }): Promise { + async createOrganization(@Body() payload: { createOrgDto: CreateOrganizationDto; userId: string }): Promise { return this.organizationService.createOrganization(payload.createOrgDto, payload.userId); } @@ -31,7 +35,7 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'update-organization' }) - async updateOrganization(payload: { updateOrgDto: IUpdateOrganization; userId: string, orgId: string }): Promise { + async updateOrganization(payload: { updateOrgDto: IUpdateOrganization; userId: string, orgId: string }): Promise { return this.organizationService.updateOrganization(payload.updateOrgDto, payload.userId, payload.orgId); } @@ -43,7 +47,7 @@ export class OrganizationController { @MessagePattern({ cmd: 'get-organizations' }) async getOrganizations( @Body() payload: { userId: string; pageNumber: number; pageSize: number; search: string } - ): Promise { + ): Promise { const { userId, pageNumber, pageSize, search } = payload; return this.organizationService.getOrganizations(userId, pageNumber, pageSize, search); } @@ -56,7 +60,7 @@ export class OrganizationController { @MessagePattern({ cmd: 'get-public-organizations' }) async getPublicOrganizations( @Body() payload: { pageNumber: number; pageSize: number; search: string } - ): Promise { + ): Promise { const { pageNumber, pageSize, search } = payload; return this.organizationService.getPublicOrganizations(pageNumber, pageSize, search); } @@ -67,12 +71,12 @@ export class OrganizationController { * @returns Get created organization details */ @MessagePattern({ cmd: 'get-organization-by-id' }) - async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise { + async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise { return this.organizationService.getOrganization(payload.orgId); } @MessagePattern({ cmd: 'get-organization-public-profile' }) - async getPublicProfile(payload: { orgSlug }): Promise { + async getPublicProfile(payload: { orgSlug }): Promise { return this.organizationService.getPublicProfile(payload); } @@ -84,7 +88,7 @@ export class OrganizationController { @MessagePattern({ cmd: 'get-invitations-by-orgId' }) async getInvitationsByOrgId( @Body() payload: { orgId: string; pageNumber: number; pageSize: number; search: string } - ): Promise { + ): Promise { return this.organizationService.getInvitationsByOrgId( payload.orgId, payload.pageNumber, @@ -99,7 +103,8 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'get-org-roles' }) - async getOrgRoles(): Promise { + // eslint-disable-next-line camelcase + async getOrgRoles(): Promise { return this.organizationService.getOrgRoles(); } @@ -150,12 +155,13 @@ export class OrganizationController { } @MessagePattern({ cmd: 'get-organization-dashboard' }) - async getOrgDashboard(payload: { orgId: string; userId: string }): Promise { + // eslint-disable-next-line camelcase + async getOrgDashboard(payload: { orgId: string; userId: string }): Promise { return this.organizationService.getOrgDashboard(payload.orgId); } @MessagePattern({ cmd: 'fetch-organization-profile' }) - async getOgPofile(payload: { orgId: string }): Promise { + async getOgPofile(payload: { orgId: string }): Promise { return this.organizationService.getOgPofile(payload.orgId); } diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index d5755864e..fc2129d1c 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -1,5 +1,5 @@ // eslint-disable-next-line camelcase -import { organisation, org_roles, user } from '@prisma/client'; +import { organisation, user } from '@prisma/client'; import { Injectable, Logger, ConflictException, InternalServerErrorException, HttpException } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; import { CommonService } from '@credebl/common'; @@ -18,10 +18,13 @@ import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; import { NotFoundException } from '@nestjs/common'; import { Invitation, OrgAgentType } from '@credebl/enum/enum'; -import { IUpdateOrganization, OrgAgent } from '../interfaces/organization.interface'; +// eslint-disable-next-line camelcase +import { GetOrgs, IUpdateOrganization, OrgAgent, OrgInvitationsPagination, getOrgById, organization_dashboard } from '../interfaces/organization.interface'; import { UserActivityService } from '@credebl/user-activity'; import { CommonConstants } from '@credebl/common/common.constant'; import { map } from 'rxjs/operators'; +// eslint-disable-next-line camelcase +import { Org_roles } from 'libs/org-roles/interfaces/org-roles.interface'; @Injectable() export class OrganizationService { constructor( @@ -119,7 +122,7 @@ export class OrganizationService { * @returns Get created organizations details */ // eslint-disable-next-line camelcase - async getOrganizations(userId: string, pageNumber: number, pageSize: number, search: string): Promise { + async getOrganizations(userId: string, pageNumber: number, pageSize: number, search: string): Promise { try { const query = { @@ -155,7 +158,7 @@ export class OrganizationService { * @returns Get public organizations details */ // eslint-disable-next-line camelcase - async getPublicOrganizations(pageNumber: number, pageSize: number, search: string): Promise { + async getPublicOrganizations(pageNumber: number, pageSize: number, search: string): Promise { try { const query = { @@ -181,7 +184,7 @@ export class OrganizationService { } } - async getPublicProfile(payload: { orgSlug: string }): Promise { + async getPublicProfile(payload: { orgSlug: string }): Promise { const { orgSlug } = payload; try { @@ -195,7 +198,7 @@ export class OrganizationService { throw new NotFoundException(ResponseMessages.organisation.error.profileNotFound); } - const credentials = await this.organizationRepository.getCredDefByOrg(organizationDetails['id']); + const credentials = await this.organizationRepository.getCredDefByOrg(organizationDetails.id); organizationDetails['credential_definitions'] = credentials; return organizationDetails; @@ -211,7 +214,7 @@ export class OrganizationService { * @returns Get created organization details */ // eslint-disable-next-line camelcase - async getOrganization(orgId: string): Promise { + async getOrganization(orgId: string): Promise { try { const query = { @@ -232,11 +235,11 @@ export class OrganizationService { * @returns Get created invitation details */ // eslint-disable-next-line camelcase - async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { + async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { try { const getOrganization = await this.organizationRepository.getInvitationsByOrgId(orgId, pageNumber, pageSize, search); for await (const item of getOrganization['invitations']) { - const getOrgRoles = await this.orgRoleService.getOrgRolesByIds(item.orgRoles); + const getOrgRoles = await this.orgRoleService.getOrgRolesByIds(item['orgRoles']); (item['orgRoles'] as object) = getOrgRoles; }; return getOrganization; @@ -253,7 +256,7 @@ export class OrganizationService { */ // eslint-disable-next-line camelcase - async getOrgRoles(): Promise { + async getOrgRoles(): Promise< Org_roles[]> { try { return this.orgRoleService.getOrgRoles(); } catch (error) { @@ -478,7 +481,8 @@ export class OrganizationService { } } - async getOrgDashboard(orgId: string): Promise { + // eslint-disable-next-line camelcase + async getOrgDashboard(orgId: string): Promise { try { return this.organizationRepository.getOrgDashboard(orgId); } catch (error) { diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index a4f1d9cb3..8a36e64b8 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -72,4 +72,52 @@ export interface ShareUserCertificateI { export interface Attribute { [key: string]: string; label: string - } \ No newline at end of file + } + + export interface OrgUsers { + totalPages: number, + users: org_users[] + } + + interface org_users { + id: string; + username: string; + email: string; + firstName: string; + lastName: string; + isEmailVerified: boolean; + userOrgRoles: UserOrgRoles[]; + } + + interface UserOrgRoles { + id: string; + orgId: string; + orgRoleId: string; + orgRole: OrgRole; + organisation: Organization + } + + interface OrgRole { + id: string; + name: string, + description: string + } + + interface Organization { + id: string, + name: string, + description: string, + orgSlug: string, + logoUrl: string, + org_agents: OrgAgents[]; + } + + interface OrgAgents { + id: string, + orgDid: string, + walletName: string, + agentSpinUpStatus: number, + agentsTypeId: string, + createDateTime: Date, + orgAgentTypeId:string + } diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index faa8cf0a6..8cf752347 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -2,6 +2,7 @@ import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { + OrgUsers, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, @@ -213,36 +214,15 @@ export class UserRepository { } ] }, - select: { - id: true, - username: true, - email: true, - firstName: true, - lastName: true, - profileImg: true, - publicProfile: true, - isEmailVerified: true, - clientId: true, - clientSecret: true, - supabaseUserId: true, + include: { userOrgRoles: { include: { - orgRole: true, - organisation: { - include: { - // eslint-disable-next-line camelcase - org_agents: { - include: { - // eslint-disable-next-line camelcase - agents_type: true - } - } - } + orgRole: { } } } } - }); + }); } async findUserForPublicProfile(queryOptions: UserQueryOptions): Promise { @@ -350,7 +330,7 @@ export class UserRepository { pageNumber: number, pageSize: number, filterOptions?: object - ): Promise { + ): Promise { const result = await this.prisma.$transaction([ this.prisma.user.findMany({ where: { @@ -363,23 +343,39 @@ export class UserRepository { firstName: true, lastName: true, isEmailVerified: true, - clientId: true, - clientSecret: true, - supabaseUserId: true, userOrgRoles: { where: { ...filterOptions // Additional filtering conditions if needed }, - include: { - orgRole: true, + select: { + id: true, + orgId: true, + orgRoleId: true, + orgRole: { + select: { + id: true, + name: true, + description: true + } + }, organisation: { - include: { + select: { + id: true, + name: true, + description: true, + orgSlug: true, + logoUrl: true, // eslint-disable-next-line camelcase org_agents: { - include: { - // eslint-disable-next-line camelcase - agents_type: true + select: { + id: true, + orgDid: true, + walletName: true, + agentSpinUpStatus: true, + agentsTypeId: true, + createDateTime: true, + orgAgentTypeId:true } } } diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 7803982eb..3c642e1d0 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, UserEmailVerificationDto, UserI, userInfo } from '../interfaces/user.interface'; +import { AddPasskeyDetails, OrgUsers, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, UserEmailVerificationDto, UserI, userInfo } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { Controller } from '@nestjs/common'; @@ -103,7 +103,7 @@ export class UserController { * @returns organization users list */ @MessagePattern({ cmd: 'fetch-organization-user' }) - async getOrganizationUsers(payload: { orgId: string, pageNumber: number, pageSize: number, search: string }): Promise { + async getOrganizationUsers(payload: { orgId: string, pageNumber: number, pageSize: number, search: string }): Promise { return this.userService.getOrgUsers(payload.orgId, payload.pageNumber, payload.pageSize, payload.search); } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 9ae0ec698..dca7ad199 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -30,6 +30,7 @@ import { AddPasskeyDetails, Attribute, InvitationsI, + OrgUsers, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, @@ -675,7 +676,7 @@ export class UserService { * @param orgId * @returns users list */ - async getOrgUsers(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { + async getOrgUsers(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { try { const query = { userOrgRoles: { diff --git a/libs/org-roles/interfaces/org-roles.interface.ts b/libs/org-roles/interfaces/org-roles.interface.ts new file mode 100644 index 000000000..ce87e0d2f --- /dev/null +++ b/libs/org-roles/interfaces/org-roles.interface.ts @@ -0,0 +1,9 @@ +export interface Org_roles { + id: string; + name: string; + description: string; + createDateTime: Date; + createdBy: string; + lastChangedDateTime: Date; + lastChangedBy: string; +} \ No newline at end of file diff --git a/libs/org-roles/repositories/index.ts b/libs/org-roles/repositories/index.ts index 863b7fbe8..b4a3287dd 100644 --- a/libs/org-roles/repositories/index.ts +++ b/libs/org-roles/repositories/index.ts @@ -4,6 +4,8 @@ import { PrismaService } from '@credebl/prisma-service'; // eslint-disable-next-line camelcase import { org_roles } from '@prisma/client'; import { OrgRoles } from '../enums'; +// eslint-disable-next-line camelcase +import { Org_roles } from '../interfaces/org-roles.interface'; @Injectable() export class OrgRolesRepository { @@ -24,9 +26,9 @@ export class OrgRolesRepository { } } - + // eslint-disable-next-line camelcase - async getOrgRoles(): Promise { + async getOrgRoles(): Promise { try { const roleDetails = await this.prisma.org_roles.findMany(); const filteredRoles = roleDetails.filter(role => role.name !== OrgRoles.PLATFORM_ADMIN); diff --git a/libs/org-roles/src/org-roles.service.ts b/libs/org-roles/src/org-roles.service.ts index b48315ad9..7ee6895e5 100644 --- a/libs/org-roles/src/org-roles.service.ts +++ b/libs/org-roles/src/org-roles.service.ts @@ -3,7 +3,8 @@ import { Logger } from '@nestjs/common'; import { OrgRolesRepository } from '../repositories'; // eslint-disable-next-line camelcase import { org_roles } from '@prisma/client'; - +// eslint-disable-next-line camelcase +import { Org_roles } from '../interfaces/org-roles.interface'; @Injectable() export class OrgRolesService { @@ -15,7 +16,7 @@ export class OrgRolesService { } // eslint-disable-next-line camelcase - async getOrgRoles(): Promise { + async getOrgRoles(): Promise< Org_roles[]> { return this.orgRoleRepository.getOrgRoles(); } From 3dfffa24dd36459c6fb261df9e42cad8bd15e973 Mon Sep 17 00:00:00 2001 From: Moulika Kulkarni Date: Thu, 14 Dec 2023 12:35:15 +0530 Subject: [PATCH 004/107] refactor:API response Signed-off-by: Moulika Kulkarni --- .../src/organization/organization.service.ts | 21 ++++++-------- .../interfaces/organization.interface.ts | 4 +-- .../repositories/organization.repository.ts | 8 ++--- .../src/organization.controller.ts | 18 +++++------- apps/organization/src/organization.service.ts | 29 +++++++++---------- .../interfaces/org-roles.interface.ts | 2 +- libs/org-roles/repositories/index.ts | 6 ++-- libs/org-roles/src/org-roles.service.ts | 6 ++-- 8 files changed, 40 insertions(+), 54 deletions(-) diff --git a/apps/api-gateway/src/organization/organization.service.ts b/apps/api-gateway/src/organization/organization.service.ts index ddf56b908..3c61914e2 100644 --- a/apps/api-gateway/src/organization/organization.service.ts +++ b/apps/api-gateway/src/organization/organization.service.ts @@ -9,11 +9,9 @@ import { BulkSendInvitationDto } from './dtos/send-invitation.dto'; import { UpdateUserRolesDto } from './dtos/update-user-roles.dto'; import { UpdateOrganizationDto } from './dtos/update-organization-dto'; import { GetAllUsersDto } from '../user/dto/get-all-users.dto'; -// eslint-disable-next-line camelcase -import { Org_roles } from 'libs/org-roles/interfaces/org-roles.interface'; +import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; import { organisation } from '@prisma/client'; -// eslint-disable-next-line camelcase -import { GetOrgs, OrgInvitationsPagination, getOrgById, organization_dashboard } from 'apps/organization/interfaces/organization.interface'; +import { GetOrgById, GetOrgs, OrgInvitationsPagination, OrganizationDashboard } from 'apps/organization/interfaces/organization.interface'; import { OrgUsers } from 'apps/user/interfaces/user.interface'; @Injectable() @@ -47,8 +45,8 @@ export class OrganizationService extends BaseService { * @param * @returns Organizations details */ - // eslint-disable-next-line camelcase - async getOrganizations(getAllOrgsDto: GetAllOrganizationsDto, userId: string): Promise<{ response: Org_roles[] }> { + + async getOrganizations(getAllOrgsDto: GetAllOrganizationsDto, userId: string): Promise<{ response: GetOrgs}> { const payload = { userId, ...getAllOrgsDto }; return this.sendNats(this.serviceProxy, 'get-organizations', payload); } @@ -63,7 +61,7 @@ export class OrganizationService extends BaseService { return this.sendNats(this.serviceProxy, 'get-public-organizations', payload); } - async getPublicProfile(orgSlug: string): Promise<{ response: getOrgById }> { + async getPublicProfile(orgSlug: string): Promise<{ response: GetOrgById }> { const payload = { orgSlug }; try { return this.sendNats(this.serviceProxy, 'get-organization-public-profile', payload); @@ -77,7 +75,7 @@ export class OrganizationService extends BaseService { * @param orgId * @returns Organization get Success */ - async getOrganization(orgId: string, userId: string): Promise<{ response: getOrgById }> { + async getOrganization(orgId: string, userId: string): Promise<{ response: GetOrgById }> { const payload = { orgId, userId }; return this.sendNats(this.serviceProxy, 'get-organization-by-id', payload); } @@ -96,8 +94,7 @@ export class OrganizationService extends BaseService { return this.sendNats(this.serviceProxy, 'get-invitations-by-orgId', payload); } - // eslint-disable-next-line camelcase - async getOrganizationDashboard(orgId: string, userId: string): Promise<{ response: organization_dashboard }> { + async getOrganizationDashboard(orgId: string, userId: string): Promise<{ response: OrganizationDashboard }> { const payload = { orgId, userId }; return this.sendNats(this.serviceProxy, 'get-organization-dashboard', payload); } @@ -107,8 +104,8 @@ export class OrganizationService extends BaseService { * @param * @returns get organization roles */ - // eslint-disable-next-line camelcase - async getOrgRoles(): Promise { + + async getOrgRoles(): Promise { const payload = {}; return this.sendNats(this.serviceProxy, 'get-org-roles', payload); } diff --git a/apps/organization/interfaces/organization.interface.ts b/apps/organization/interfaces/organization.interface.ts index 7a36b3aa5..9d8659433 100644 --- a/apps/organization/interfaces/organization.interface.ts +++ b/apps/organization/interfaces/organization.interface.ts @@ -36,7 +36,7 @@ export interface Org_Role { userOrgRoles: UserOrgRole; } -export interface getOrgById { +export interface GetOrgById { id: string; name: string; description: string; @@ -131,7 +131,7 @@ interface OrganizationPagination { logoUrl: string; } -export interface organization_dashboard { +export interface OrganizationDashboard { usersCount: number, schemasCount: number, credentialsCount: number, diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index af29cffd6..c271658b2 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -6,7 +6,7 @@ import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { org_agents, org_invitations, user_org_roles } from '@prisma/client'; import { CreateOrganizationDto } from '../dtos/create-organization.dto'; -import { GetOrgs, IUpdateOrganization, OrgInvitationsPagination, getOrgById, organization_dashboard } from '../interfaces/organization.interface'; +import { GetOrgById, GetOrgs, IUpdateOrganization, OrgInvitationsPagination, OrganizationDashboard } from '../interfaces/organization.interface'; import { InternalServerErrorException } from '@nestjs/common'; import { Invitation } from '@credebl/enum/enum'; import { PrismaService } from '@credebl/prisma-service'; @@ -176,7 +176,7 @@ export class OrganizationRepository { pageNumber: number, pageSize: number, search = '' - ): Promise { + ): Promise { this.logger.log(search); const query = { @@ -269,7 +269,7 @@ export class OrganizationRepository { } } - async getOrganization(queryObject: object): Promise { + async getOrganization(queryObject: object): Promise { try { return this.prisma.organisation.findFirst({ where: { @@ -324,7 +324,7 @@ export class OrganizationRepository { } } - async getOrgDashboard(orgId: string): Promise { + async getOrgDashboard(orgId: string): Promise { const query = { where: { diff --git a/apps/organization/src/organization.controller.ts b/apps/organization/src/organization.controller.ts index 27393172c..6cfb41469 100644 --- a/apps/organization/src/organization.controller.ts +++ b/apps/organization/src/organization.controller.ts @@ -6,11 +6,9 @@ import { Body } from '@nestjs/common'; import { CreateOrganizationDto } from '../dtos/create-organization.dto'; import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; -// eslint-disable-next-line camelcase -import { GetOrgs, IUpdateOrganization, OrgInvitationsPagination, getOrgById, organization_dashboard } from '../interfaces/organization.interface'; +import { GetOrgById, GetOrgs, IUpdateOrganization, OrgInvitationsPagination, OrganizationDashboard } from '../interfaces/organization.interface'; import { organisation } from '@prisma/client'; -// eslint-disable-next-line camelcase -import { Org_roles } from 'libs/org-roles/interfaces/org-roles.interface'; +import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; @Controller() export class OrganizationController { @@ -71,12 +69,12 @@ export class OrganizationController { * @returns Get created organization details */ @MessagePattern({ cmd: 'get-organization-by-id' }) - async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise { + async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise { return this.organizationService.getOrganization(payload.orgId); } @MessagePattern({ cmd: 'get-organization-public-profile' }) - async getPublicProfile(payload: { orgSlug }): Promise { + async getPublicProfile(payload: { orgSlug }): Promise { return this.organizationService.getPublicProfile(payload); } @@ -103,8 +101,7 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'get-org-roles' }) - // eslint-disable-next-line camelcase - async getOrgRoles(): Promise { + async getOrgRoles(): Promise { return this.organizationService.getOrgRoles(); } @@ -123,7 +120,7 @@ export class OrganizationController { @MessagePattern({ cmd: 'fetch-user-invitations' }) async fetchUserInvitation( @Body() payload: { email: string; status: string; pageNumber: number; pageSize: number; search: string } - ): Promise { + ): Promise { return this.organizationService.fetchUserInvitation( payload.email, payload.status, @@ -155,8 +152,7 @@ export class OrganizationController { } @MessagePattern({ cmd: 'get-organization-dashboard' }) - // eslint-disable-next-line camelcase - async getOrgDashboard(payload: { orgId: string; userId: string }): Promise { + async getOrgDashboard(payload: { orgId: string; userId: string }): Promise { return this.organizationService.getOrgDashboard(payload.orgId); } diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index fc2129d1c..a1012fd0b 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -18,13 +18,11 @@ import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; import { NotFoundException } from '@nestjs/common'; import { Invitation, OrgAgentType } from '@credebl/enum/enum'; -// eslint-disable-next-line camelcase -import { GetOrgs, IUpdateOrganization, OrgAgent, OrgInvitationsPagination, getOrgById, organization_dashboard } from '../interfaces/organization.interface'; +import { GetOrgById, GetOrgs, IUpdateOrganization, OrgAgent, OrgInvitationsPagination, OrganizationDashboard } from '../interfaces/organization.interface'; import { UserActivityService } from '@credebl/user-activity'; import { CommonConstants } from '@credebl/common/common.constant'; import { map } from 'rxjs/operators'; -// eslint-disable-next-line camelcase -import { Org_roles } from 'libs/org-roles/interfaces/org-roles.interface'; +import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; @Injectable() export class OrganizationService { constructor( @@ -121,7 +119,7 @@ export class OrganizationService { * @param * @returns Get created organizations details */ - // eslint-disable-next-line camelcase + async getOrganizations(userId: string, pageNumber: number, pageSize: number, search: string): Promise { try { @@ -157,7 +155,7 @@ export class OrganizationService { * @param * @returns Get public organizations details */ - // eslint-disable-next-line camelcase + async getPublicOrganizations(pageNumber: number, pageSize: number, search: string): Promise { try { @@ -184,7 +182,7 @@ export class OrganizationService { } } - async getPublicProfile(payload: { orgSlug: string }): Promise { + async getPublicProfile(payload: { orgSlug: string }): Promise { const { orgSlug } = payload; try { @@ -213,8 +211,8 @@ export class OrganizationService { * @param orgId Registration Details * @returns Get created organization details */ - // eslint-disable-next-line camelcase - async getOrganization(orgId: string): Promise { + + async getOrganization(orgId: string): Promise { try { const query = { @@ -234,7 +232,7 @@ export class OrganizationService { * @param orgId Registration Details * @returns Get created invitation details */ - // eslint-disable-next-line camelcase + async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { try { const getOrganization = await this.organizationRepository.getInvitationsByOrgId(orgId, pageNumber, pageSize, search); @@ -255,8 +253,8 @@ export class OrganizationService { * @returns */ - // eslint-disable-next-line camelcase - async getOrgRoles(): Promise< Org_roles[]> { + + async getOrgRoles(): Promise< IOrgRoles[]> { try { return this.orgRoleService.getOrgRoles(); } catch (error) { @@ -312,7 +310,7 @@ export class OrganizationService { * @returns createInvitation */ - // eslint-disable-next-line camelcase + async createInvitation(bulkInvitationDto: BulkSendInvitationDto, userId: string, userEmail: string): Promise { const { invitations, orgId } = bulkInvitationDto; @@ -400,7 +398,7 @@ export class OrganizationService { return false; } - async fetchUserInvitation(email: string, status: string, pageNumber: number, pageSize: number, search = ''): Promise { + async fetchUserInvitation(email: string, status: string, pageNumber: number, pageSize: number, search = ''): Promise { try { return this.organizationRepository.getAllOrgInvitations(email, status, pageNumber, pageSize, search); } catch (error) { @@ -481,8 +479,7 @@ export class OrganizationService { } } - // eslint-disable-next-line camelcase - async getOrgDashboard(orgId: string): Promise { + async getOrgDashboard(orgId: string): Promise { try { return this.organizationRepository.getOrgDashboard(orgId); } catch (error) { diff --git a/libs/org-roles/interfaces/org-roles.interface.ts b/libs/org-roles/interfaces/org-roles.interface.ts index ce87e0d2f..b170d93af 100644 --- a/libs/org-roles/interfaces/org-roles.interface.ts +++ b/libs/org-roles/interfaces/org-roles.interface.ts @@ -1,4 +1,4 @@ -export interface Org_roles { +export interface IOrgRoles { id: string; name: string; description: string; diff --git a/libs/org-roles/repositories/index.ts b/libs/org-roles/repositories/index.ts index b4a3287dd..0488fd24e 100644 --- a/libs/org-roles/repositories/index.ts +++ b/libs/org-roles/repositories/index.ts @@ -4,8 +4,7 @@ import { PrismaService } from '@credebl/prisma-service'; // eslint-disable-next-line camelcase import { org_roles } from '@prisma/client'; import { OrgRoles } from '../enums'; -// eslint-disable-next-line camelcase -import { Org_roles } from '../interfaces/org-roles.interface'; +import { IOrgRoles } from '../interfaces/org-roles.interface'; @Injectable() export class OrgRolesRepository { @@ -27,8 +26,7 @@ export class OrgRolesRepository { } - // eslint-disable-next-line camelcase - async getOrgRoles(): Promise { + async getOrgRoles(): Promise { try { const roleDetails = await this.prisma.org_roles.findMany(); const filteredRoles = roleDetails.filter(role => role.name !== OrgRoles.PLATFORM_ADMIN); diff --git a/libs/org-roles/src/org-roles.service.ts b/libs/org-roles/src/org-roles.service.ts index 7ee6895e5..a7ce01cdf 100644 --- a/libs/org-roles/src/org-roles.service.ts +++ b/libs/org-roles/src/org-roles.service.ts @@ -3,8 +3,7 @@ import { Logger } from '@nestjs/common'; import { OrgRolesRepository } from '../repositories'; // eslint-disable-next-line camelcase import { org_roles } from '@prisma/client'; -// eslint-disable-next-line camelcase -import { Org_roles } from '../interfaces/org-roles.interface'; +import { IOrgRoles } from '../interfaces/org-roles.interface'; @Injectable() export class OrgRolesService { @@ -15,8 +14,7 @@ export class OrgRolesService { return this.orgRoleRepository.getRole(roleName); } - // eslint-disable-next-line camelcase - async getOrgRoles(): Promise< Org_roles[]> { + async getOrgRoles(): Promise< IOrgRoles[]> { return this.orgRoleRepository.getOrgRoles(); } From 5278e317a6194046aa55e0a657c667798da3c6f4 Mon Sep 17 00:00:00 2001 From: Moulika Kulkarni Date: Thu, 14 Dec 2023 12:54:31 +0530 Subject: [PATCH 005/107] refactor:API response Signed-off-by: Moulika Kulkarni --- .../interfaces/organization.interface.ts | 18 +++--------------- apps/user/interfaces/user.interface.ts | 4 ++-- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/apps/organization/interfaces/organization.interface.ts b/apps/organization/interfaces/organization.interface.ts index 9d8659433..9a6d40dd8 100644 --- a/apps/organization/interfaces/organization.interface.ts +++ b/apps/organization/interfaces/organization.interface.ts @@ -23,20 +23,8 @@ export interface OrgAgent { apiKey: string; } -export interface Org_Role { - id: string; - name: string; - description: string; - orgSlug: string; - logoUrl: string; - website: string; - publicProfile: boolean; - schema: Schema[]; - org_agents: OrgAgents; - userOrgRoles: UserOrgRole; -} -export interface GetOrgById { +export interface GetOrgById { id: string; name: string; description: string; @@ -56,7 +44,7 @@ interface Schema { interface OrgAgents { agent_invitations: AgentInvitation[]; ledgers: Ledgers; - org_agent_type: Org_agent_type; + org_agent_type: OrgAgentType; } interface AgentInvitation { @@ -70,7 +58,7 @@ export interface UserOrgRole { orgRole: string; } -interface Org_agent_type { +interface OrgAgentType { id: string; createDateTime: Date; lastChangedDateTime: Date; diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index 8a36e64b8..bf7c8d02c 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -76,10 +76,10 @@ export interface Attribute { export interface OrgUsers { totalPages: number, - users: org_users[] + users: OrgUser[] } - interface org_users { + interface OrgUser { id: string; username: string; email: string; From e4dd8e65b024aec218447e16ef2648fedf75f7e4 Mon Sep 17 00:00:00 2001 From: pallavicoder Date: Tue, 19 Dec 2023 16:06:38 +0530 Subject: [PATCH 006/107] chore:solved merged conflicts Signed-off-by: pallavicoder --- .gitignore | 5 +- Dockerfiles/Dockerfile.agnet-provisioning | 3 +- .../src/agent-provisioning.service.ts | 7 +- .../agent-provisioning.interfaces.ts | 1 + .../src/agent-service.controller.ts | 153 +++-- .../agent-service/src/agent-service.module.ts | 17 +- .../src/agent-service.service.ts | 138 +++-- .../src/interface/agent-service.interface.ts | 6 +- apps/agent-service/src/main.ts | 1 + .../repositories/agent-service.repository.ts | 577 +++++++++--------- .../agent-service/agent-service.controller.ts | 5 +- .../api-gateway/src/agent/agent.controller.ts | 18 +- .../dtos/accept-reject-invitations.dto.ts | 3 + .../src/ecosystem/dtos/edit-ecosystem-dto.ts | 3 + .../src/ecosystem/dtos/request-schema.dto.ts | 4 + .../src/ecosystem/ecosystem.controller.ts | 80 +-- .../src/ecosystem/ecosystem.service.ts | 48 +- .../src/issuance/dtos/issuance.dto.ts | 2 + .../src/issuance/issuance.controller.ts | 8 +- .../src/issuance/issuance.service.ts | 6 +- .../verification/verification.controller.ts | 14 +- apps/connection/src/connection.module.ts | 6 +- apps/connection/src/connection.repository.ts | 2 + apps/connection/src/connection.service.ts | 57 +- .../accept-reject-ecosysteminvitation.dto.ts | 1 + .../dtos/update-ecosystemOrgs.dto.ts | 2 + .../interfaces/ecosystem.interfaces.ts | 28 +- apps/ecosystem/src/ecosystem.controller.ts | 168 +++-- apps/ecosystem/src/ecosystem.module.ts | 13 +- apps/ecosystem/src/ecosystem.repository.ts | 36 +- apps/ecosystem/src/ecosystem.service.ts | 575 ++++++++++------- .../interfaces/issuance.interfaces.ts | 8 + apps/issuance/src/issuance.controller.ts | 6 +- apps/issuance/src/issuance.repository.ts | 17 +- apps/issuance/src/issuance.service.ts | 83 ++- .../credential-definition.module.ts | 5 +- .../credential-definition.service.ts | 42 +- .../create-credential-definition.interface.ts | 1 + .../credential-definition.repository.ts | 3 +- apps/ledger/src/schema/schema.module.ts | 5 +- apps/ledger/src/schema/schema.service.ts | 43 +- .../dtos/create-organization.dto.ts | 3 + .../interfaces/organization.interface.ts | 4 +- .../repositories/organization.repository.ts | 12 +- apps/organization/src/organization.module.ts | 5 +- apps/organization/src/organization.service.ts | 36 +- .../repositories/user-device.repository.ts | 4 +- .../repositories/verification.repository.ts | 2 + apps/verification/src/verification.module.ts | 5 +- apps/verification/src/verification.service.ts | 86 ++- libs/common/src/common.constant.ts | 5 +- libs/common/src/common.service.ts | 17 +- libs/common/src/response-messages/index.ts | 2 +- .../migration.sql | 220 +++++++ .../migration.sql | 10 + .../migration.sql | 10 + .../migration.sql | 10 + libs/prisma-service/prisma/schema.prisma | 194 +++--- libs/prisma-service/prisma/seed.ts | 9 +- libs/user-activity/repositories/index.ts | 4 +- 60 files changed, 1867 insertions(+), 971 deletions(-) create mode 100644 libs/prisma-service/prisma/migrations/20231123154918_uuid_createdby_upadatedby/migration.sql create mode 100644 libs/prisma-service/prisma/migrations/20231123161550_removed_createdby_ecosystem_roles/migration.sql create mode 100644 libs/prisma-service/prisma/migrations/20231123162120_removed_createdby_user/migration.sql create mode 100644 libs/prisma-service/prisma/migrations/20231123180959_removed_createdby_user_credentials/migration.sql diff --git a/.gitignore b/.gitignore index b40d5736d..97e7de8a4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,7 @@ dist sonar-project.properties .scannerwork/* coverage -libs/prisma-service/prisma/data/credebl-master-table.json \ No newline at end of file +libs/prisma-service/prisma/data/credebl-master-table.json +uploadedFles/exports +uploadedFles/import +uploadedFles/export \ No newline at end of file diff --git a/Dockerfiles/Dockerfile.agnet-provisioning b/Dockerfiles/Dockerfile.agnet-provisioning index fce2766bb..fffb90839 100644 --- a/Dockerfiles/Dockerfile.agnet-provisioning +++ b/Dockerfiles/Dockerfile.agnet-provisioning @@ -33,8 +33,7 @@ RUN mkdir -p ./agent-provisioning/AFJ/agent-config COPY --from=build /app/dist/apps/agent-provisioning/ ./dist/apps/agent-provisioning/ COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/apps/agent-provisioning/AFJ/scripts ./agent-provisioning/AFJ/scripts - - +COPY --from=build /app/apps/agent-provisioning/AFJ/port-files ./agent-provisioning/AFJ/port-file # Set permissions RUN chmod +x /app/agent-provisioning/AFJ/scripts/start_agent.sh diff --git a/apps/agent-provisioning/src/agent-provisioning.service.ts b/apps/agent-provisioning/src/agent-provisioning.service.ts index a0163741c..447e71e55 100644 --- a/apps/agent-provisioning/src/agent-provisioning.service.ts +++ b/apps/agent-provisioning/src/agent-provisioning.service.ts @@ -22,13 +22,10 @@ export class AgentProvisioningService { async walletProvision(payload: IWalletProvision): Promise { try { - const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, afjVersion, tenant, indyLedger } = payload; - + const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, afjVersion, tenant, indyLedger, apiKey} = payload; if (agentType === AgentType.AFJ) { // The wallet provision command is used to invoke a shell script - const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP - } ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${afjVersion} ${indyLedger} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`; - + const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${afjVersion} ${indyLedger} ${apiKey} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`; const spinUpResponse: object = new Promise(async (resolve) => { await exec(walletProvision, async (err, stdout, stderr) => { diff --git a/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts b/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts index 105dd6bb6..5f18b6cbb 100644 --- a/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts +++ b/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts @@ -20,6 +20,7 @@ export interface IWalletProvision { protocol: string; afjVersion: string; tenant: boolean; + apiKey?:string; } export interface IAgentSpinUp { diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 9fc94f190..51cef3f3f 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -1,140 +1,217 @@ import { Controller } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; import { AgentServiceService } from './agent-service.service'; -import { GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAgentSpinupDto, IIssuanceCreateOffer, ITenantCredDef, ITenantDto, ITenantSchema, OutOfBandCredentialOffer } from './interface/agent-service.interface'; +import { + GetCredDefAgentRedirection, + GetSchemaAgentRedirection, + IAgentSpinupDto, + IIssuanceCreateOffer, + ITenantCredDef, + ITenantDto, + ITenantSchema, + OutOfBandCredentialOffer +} from './interface/agent-service.interface'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; @Controller() export class AgentServiceController { - constructor(private readonly agentServiceService: AgentServiceService) { } + constructor(private readonly agentServiceService: AgentServiceService) {} + + //DONE @MessagePattern({ cmd: 'agent-spinup' }) - async walletProvision(payload: { agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface }): Promise { + async walletProvision(payload: { agentSpinupDto: IAgentSpinupDto; user: IUserRequestInterface }): Promise { return this.agentServiceService.walletProvision(payload.agentSpinupDto, payload.user); } + + //DONE @MessagePattern({ cmd: 'create-tenant' }) - async createTenant(payload: { createTenantDto: ITenantDto, user: IUserRequestInterface }): Promise<{ + async createTenant(payload: { createTenantDto: ITenantDto; user: IUserRequestInterface }): Promise<{ agentSpinupStatus: number; }> { return this.agentServiceService.createTenant(payload.createTenantDto, payload.user); } + //DONE @MessagePattern({ cmd: 'agent-create-schema' }) async createSchema(payload: ITenantSchema): Promise { return this.agentServiceService.createSchema(payload); } + //DONE @MessagePattern({ cmd: 'agent-get-schema' }) async getSchemaById(payload: GetSchemaAgentRedirection): Promise { return this.agentServiceService.getSchemaById(payload); } + //DONE @MessagePattern({ cmd: 'agent-create-credential-definition' }) async createCredentialDefinition(payload: ITenantCredDef): Promise { - return this.agentServiceService.createCredentialDefinition(payload); } + // DONE @MessagePattern({ cmd: 'agent-get-credential-definition' }) async getCredentialDefinitionById(payload: GetCredDefAgentRedirection): Promise { return this.agentServiceService.getCredentialDefinitionById(payload); } - + //DONE @MessagePattern({ cmd: 'agent-create-connection-legacy-invitation' }) - async createLegacyConnectionInvitation(payload: { connectionPayload: IConnectionDetails, url: string, apiKey: string }): Promise { - - return this.agentServiceService.createLegacyConnectionInvitation(payload.connectionPayload, payload.url, payload.apiKey); - } - + async createLegacyConnectionInvitation(payload: { + connectionPayload: IConnectionDetails; + url: string; + apiKey: string; + }): Promise { + return this.agentServiceService.createLegacyConnectionInvitation( + payload.connectionPayload, + payload.url, + payload.apiKey + ); + } + +//DONE @MessagePattern({ cmd: 'agent-send-credential-create-offer' }) - async sendCredentialCreateOffer(payload: { issueData: IIssuanceCreateOffer, url: string, apiKey: string }): Promise { + async sendCredentialCreateOffer(payload: { + issueData: IIssuanceCreateOffer; + url: string; + apiKey: string; + }): Promise { return this.agentServiceService.sendCredentialCreateOffer(payload.issueData, payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-get-all-issued-credentials' }) - async getIssueCredentials(payload: { url: string, apiKey: string }): Promise { + async getIssueCredentials(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.getIssueCredentials(payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-get-issued-credentials-by-credentialDefinitionId' }) - async getIssueCredentialsbyCredentialRecordId(payload: { url: string, apiKey: string }): Promise { + async getIssueCredentialsbyCredentialRecordId(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.getIssueCredentialsbyCredentialRecordId(payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-get-proof-presentations' }) - async getProofPresentations(payload: { url: string, apiKey: string }): Promise { + async getProofPresentations(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.getProofPresentations(payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-get-proof-presentation-by-id' }) - async getProofPresentationById(payload: { url: string, apiKey: string }): Promise { + async getProofPresentationById(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.getProofPresentationById(payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-send-proof-request' }) - async sendProofRequest(payload: { proofRequestPayload: ISendProofRequestPayload, url: string, apiKey: string }): Promise { + async sendProofRequest(payload: { + proofRequestPayload: ISendProofRequestPayload; + url: string; + apiKey: string; + }): Promise { return this.agentServiceService.sendProofRequest(payload.proofRequestPayload, payload.url, payload.apiKey); } - +//DONE @MessagePattern({ cmd: 'agent-verify-presentation' }) - async verifyPresentation(payload: { url: string, apiKey: string }): Promise { + async verifyPresentation(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.verifyPresentation(payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-get-all-connections' }) - async getConnections(payload: { url: string, apiKey: string }): Promise { + async getConnections(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.getConnections(payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-get-connections-by-connectionId' }) - async getConnectionsByconnectionId(payload: { url: string, apiKey: string }): Promise { + async getConnectionsByconnectionId(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.getConnectionsByconnectionId(payload.url, payload.apiKey); } + +//Needs to check @MessagePattern({ cmd: 'agent-health' }) - async getAgentHealth(payload: { user: user, orgId: string }): Promise { - return this.agentServiceService.getAgentHealthDetails(payload.orgId); + async getAgentHealth(payload: { user: user; orgId: string, apiKey: string; }): Promise { + return this.agentServiceService.getAgentHealthDetails(payload.orgId, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-send-out-of-band-proof-request' }) - async sendOutOfBandProofRequest(payload: { proofRequestPayload: ISendProofRequestPayload, url: string, apiKey: string }): Promise { + async sendOutOfBandProofRequest(payload: { + proofRequestPayload: ISendProofRequestPayload; + url: string; + apiKey: string; + }): Promise { return this.agentServiceService.sendOutOfBandProofRequest(payload.proofRequestPayload, payload.url, payload.apiKey); } + //DONE @MessagePattern({ cmd: 'agent-proof-form-data' }) - async getProofFormData(payload: { url: string, apiKey: string }): Promise { - + async getProofFormData(payload: { url: string; apiKey: string }): Promise { return this.agentServiceService.getProofFormData(payload.url, payload.apiKey); } @MessagePattern({ cmd: 'agent-schema-endorsement-request' }) - async schemaEndorsementRequest(payload: { url: string, apiKey: string, requestSchemaPayload: object }): Promise { + async schemaEndorsementRequest(payload: { + url: string; + apiKey: string; + requestSchemaPayload: object; + }): Promise { return this.agentServiceService.schemaEndorsementRequest(payload.url, payload.apiKey, payload.requestSchemaPayload); } @MessagePattern({ cmd: 'agent-credDef-endorsement-request' }) - async credDefEndorsementRequest(payload: { url: string, apiKey: string, requestSchemaPayload: object }): Promise { - return this.agentServiceService.credDefEndorsementRequest(payload.url, payload.apiKey, payload.requestSchemaPayload); - } - + async credDefEndorsementRequest(payload: { + url: string; + apiKey: string; + requestSchemaPayload: object; + }): Promise { + return this.agentServiceService.credDefEndorsementRequest( + payload.url, + payload.apiKey, + payload.requestSchemaPayload + ); + } + + //DONE @MessagePattern({ cmd: 'agent-sign-transaction' }) - async signTransaction(payload: { url: string, apiKey: string, signEndorsementPayload: object }): Promise { + async signTransaction(payload: { url: string; apiKey: string; signEndorsementPayload: object }): Promise { return this.agentServiceService.signTransaction(payload.url, payload.apiKey, payload.signEndorsementPayload); } + + //DONE @MessagePattern({ cmd: 'agent-submit-transaction' }) - async submitTransaction(payload: { url: string, apiKey: string, submitEndorsementPayload: object }): Promise { + async submitTransaction(payload: { url: string; apiKey: string; submitEndorsementPayload: object }): Promise { return this.agentServiceService.sumbitTransaction(payload.url, payload.apiKey, payload.submitEndorsementPayload); } + //DONE @MessagePattern({ cmd: 'agent-out-of-band-credential-offer' }) - async outOfBandCredentialOffer(payload: { outOfBandIssuancePayload: OutOfBandCredentialOffer, url: string, apiKey: string }): Promise { - return this.agentServiceService.outOfBandCredentialOffer(payload.outOfBandIssuancePayload, payload.url, payload.apiKey); - } - + async outOfBandCredentialOffer(payload: { + outOfBandIssuancePayload: OutOfBandCredentialOffer; + url: string; + apiKey: string; + }): Promise { + return this.agentServiceService.outOfBandCredentialOffer( + payload.outOfBandIssuancePayload, + payload.url, + payload.apiKey + ); + } + + //DONE @MessagePattern({ cmd: 'delete-wallet' }) - async deleteWallet(payload: { url, apiKey }): Promise { + async deleteWallet(payload: { url; apiKey }): Promise { return this.agentServiceService.deleteWallet(payload.url, payload.apiKey); } + + @MessagePattern({ cmd: 'get-org-agent-api-key' }) + async getOrgAgentApiKey(payload: { orgId: string }): Promise { + return this.agentServiceService.getOrgAgentApiKey(payload.orgId); + } + } diff --git a/apps/agent-service/src/agent-service.module.ts b/apps/agent-service/src/agent-service.module.ts index b51014f93..1526c466c 100644 --- a/apps/agent-service/src/agent-service.module.ts +++ b/apps/agent-service/src/agent-service.module.ts @@ -8,7 +8,7 @@ import { AgentServiceRepository } from './repositories/agent-service.repository' import { ConfigModule } from '@nestjs/config'; import { ConnectionService } from 'apps/connection/src/connection.service'; import { ConnectionRepository } from 'apps/connection/src/connection.repository'; - +import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ ConfigModule.forRoot(), @@ -21,9 +21,18 @@ import { ConnectionRepository } from 'apps/connection/src/connection.repository' } } ]), - CommonModule + CommonModule, + CacheModule.register() ], controllers: [AgentServiceController], - providers: [AgentServiceService, AgentServiceRepository, PrismaService, Logger, ConnectionService, ConnectionRepository] + providers: [ + AgentServiceService, + AgentServiceRepository, + PrismaService, + Logger, + ConnectionService, + ConnectionRepository + ], + exports: [AgentServiceService, AgentServiceRepository, AgentServiceModule] }) -export class AgentServiceModule { } +export class AgentServiceModule {} diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 0a59b1a36..3cd49f581 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -11,7 +11,8 @@ import { Injectable, InternalServerErrorException, Logger, - NotFoundException + NotFoundException, + forwardRef } from '@nestjs/common'; import { ClientProxy, RpcException } from '@nestjs/microservices'; import * as dotenv from 'dotenv'; @@ -31,6 +32,8 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { Socket, io } from 'socket.io-client'; import { WebSocketGateway } from '@nestjs/websockets'; import * as retry from 'async-retry'; +import { Cache } from 'cache-manager'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; @Injectable() @WebSocketGateway() @@ -42,8 +45,8 @@ export class AgentServiceService { private readonly agentServiceRepository: AgentServiceRepository, private readonly commonService: CommonService, private readonly connectionService: ConnectionService, - @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy - + @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy, + @Inject(CACHE_MANAGER) private cacheService: Cache ) { } async ReplaceAt(input, search, replace, start, end): Promise { @@ -130,7 +133,8 @@ export class AgentServiceService { async walletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise<{ agentSpinupStatus: number }> { let agentProcess: org_agents; try { - this.processWalletProvision(agentSpinupDto, user, agentProcess); + + this.processWalletProvision(agentSpinupDto, user); const agentStatusResponse = { agentSpinupStatus: AgentSpinUpStatus.PROCESSED }; @@ -142,7 +146,11 @@ export class AgentServiceService { } } - private async processWalletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface, agentProcess: org_agents): Promise { + private async processWalletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise { + let platformAdminUser; + let userId: string; + let agentProcess: org_agents; + try { const [getOrgAgent, platformConfig, getAgentType, ledgerIdData, orgData] = await Promise.all([ this.agentServiceRepository.getAgentDetails(agentSpinupDto.orgId), @@ -151,11 +159,21 @@ export class AgentServiceService { this.agentServiceRepository.getLedgerDetails(agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]), this.agentServiceRepository.getOrgDetails(agentSpinupDto.orgId) ]); - + if (!user?.userId && agentSpinupDto?.platformAdminEmail) { + + platformAdminUser = await this.agentServiceRepository.getPlatfomAdminUser(agentSpinupDto?.platformAdminEmail); + userId = platformAdminUser?.id; + } else { + userId = user?.userId; + } + agentSpinupDto.ledgerId = agentSpinupDto.ledgerId?.length ? agentSpinupDto.ledgerId : ledgerIdData.map(ledger => ledger.id); const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); - if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { + // throw new BadRequestException('Your wallet has already been created.'); + await this.getOrgAgentApiKey(agentSpinupDto.orgId); + const data = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.debug(`API key from cache==============:::${data}`); throw new BadRequestException('Your wallet has already been created.'); } @@ -171,6 +189,10 @@ export class AgentServiceService { } } + + // TODO Add logic to generate API key + agentSpinupDto.apiKey = "eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc"; + agentSpinupDto.agentType = agentSpinupDto.agentType || getAgentType; agentSpinupDto.tenant = agentSpinupDto.tenant || false; agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]; @@ -180,17 +202,20 @@ export class AgentServiceService { const externalIp = platformConfig?.externalIp; const controllerIp = platformConfig?.lastInternalId !== 'false' ? platformConfig?.lastInternalId : ''; const apiEndpoint = platformConfig?.apiEndpoint; - + const apiKey = "eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc"; + const walletProvisionPayload = await this.prepareWalletProvisionPayload(agentSpinupDto, externalIp, apiEndpoint, controllerIp, ledgerDetails, platformConfig, orgData); + const socket: Socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); this.emitAgentSpinupInitiatedEvent(agentSpinupDto, socket); const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; /* eslint-disable no-param-reassign */ - agentProcess = await this.createOrgAgent(agentSpinUpStatus); - this.validateAgentProcess(agentProcess); + agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId, apiKey); - this._agentSpinup(walletProvisionPayload, agentSpinupDto, platformConfig?.sgApiKey, orgData, user, socket, agentSpinupDto.ledgerId, agentProcess); + + this.validateAgentProcess(agentProcess); + this._agentSpinup(walletProvisionPayload, agentSpinupDto, apiKey, orgData, user, socket, agentSpinupDto.ledgerId, agentProcess); } catch (error) { this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess); @@ -276,7 +301,8 @@ export class AgentServiceService { indyLedger: escapedJsonString, afjVersion: process.env.AFJ_VERSION || '', protocol: process.env.AGENT_PROTOCOL || '', - tenant: agentSpinupDto.tenant || false + tenant: agentSpinupDto.tenant || false, + apiKey:agentSpinupDto.apiKey }; return walletProvisionPayload; @@ -294,9 +320,9 @@ export class AgentServiceService { return socket; } - async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus): Promise { + async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus, userId: string, apiKey:string): Promise { try { - const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus); + const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, userId, apiKey); this.logger.log(`Organization agent created with status: ${agentSpinUpStatus}`); return agentProcess; } catch (error) { @@ -331,6 +357,7 @@ export class AgentServiceService { async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: org_agents): Promise { try { + const walletProvision = await this._walletProvision(walletProvisionPayload); if (!walletProvision?.response) { @@ -409,6 +436,7 @@ export class AgentServiceService { } } + private async _getAgentDid(payload: IStoreOrgAgentDetails): Promise { const { agentEndPoint, apiKey, seed, ledgerId, did } = payload; const writeDid = 'write-did'; @@ -467,9 +495,11 @@ export class AgentServiceService { try { return retry(async () => { if (agentApiState === 'write-did') { - return this.commonService.httpPost(agentUrl, { seed, method: indyNamespace, did }, { headers: { 'x-api-key': apiKey } }); + // return this.commonService.httpPost(agentUrl, { seed, method: indyNamespace, did }, { headers: { 'authorization': apiKey } }); + // eslint-disable-next-line object-shorthand + return this.commonService.httpPost(agentUrl, { seed, method: indyNamespace, did }, { headers: { 'authorization': apiKey } }); } else if (agentApiState === 'get-did-doc') { - return this.commonService.httpGet(agentUrl, { headers: { 'x-api-key': apiKey } }); + return this.commonService.httpGet(agentUrl, { headers: { 'authorization': apiKey } }); } }, retryOptions); } catch (error) { @@ -567,10 +597,12 @@ export class AgentServiceService { const ledgerIdData = await this.agentServiceRepository.getLedgerDetails(Ledgers.Indicio_Demonet); const ledgerIds = ledgerIdData.map(ledger => ledger.id); - + payload.ledgerId = !payload.ledgerId || 0 === payload.ledgerId?.length ? ledgerIds : payload.ledgerId; const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; - agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus); + //TODO take API key from API gereration function + const apiKey = "eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc"; + agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user.id, apiKey); const platformAdminSpinnedUp = await this.getPlatformAdminAndNotify(payload.clientSocketId); @@ -653,11 +685,11 @@ export class AgentServiceService { method: ledgerIds.indyNamespace }; - const apiKey = ''; + const apiKey = 'eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc'; const tenantDetails = await this.commonService.httpPost( `${platformAdminSpinnedUp.org_agents[0].agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_TENANT}`, createTenantOptions, - { headers: { 'x-api-key': apiKey } } + { headers: { 'authorization': apiKey } } ); this.logger.debug(`API Response Data: ${JSON.stringify(tenantDetails)}`); @@ -703,7 +735,7 @@ export class AgentServiceService { name: payload.name, issuerId: payload.issuerId }; - schemaResponse = await this.commonService.httpPost(url, schemaPayload, { headers: { 'x-api-key': payload.apiKey } }) + schemaResponse = await this.commonService.httpPost(url, schemaPayload, { headers: { 'authorization': payload.apiKey } }) .then(async (schema) => { this.logger.debug(`API Response Data: ${JSON.stringify(schema)}`); return schema; @@ -718,7 +750,7 @@ export class AgentServiceService { name: payload.payload.name, issuerId: payload.payload.issuerId }; - schemaResponse = await this.commonService.httpPost(url, schemaPayload, { headers: { 'x-api-key': payload.apiKey } }) + schemaResponse = await this.commonService.httpPost(url, schemaPayload, { headers: { 'authorization': payload.apiKey } }) .then(async (schema) => { this.logger.debug(`API Response Data: ${JSON.stringify(schema)}`); return schema; @@ -746,7 +778,7 @@ export class AgentServiceService { } else if (OrgAgentType.SHARED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SHAGENT_GET_SCHEMA}`.replace('@', `${payload.payload.schemaId}`).replace('#', `${payload.tenantId}`); - schemaResponse = await this.commonService.httpGet(url, { headers: { 'x-api-key': payload.apiKey } }) + schemaResponse = await this.commonService.httpGet(url, { headers: { 'authorization': payload.apiKey } }) .then(async (schema) => { this.logger.debug(`API Response Data: ${JSON.stringify(schema)}`); return schema; @@ -772,7 +804,7 @@ export class AgentServiceService { issuerId: payload.issuerId }; - credDefResponse = await this.commonService.httpPost(url, credDefPayload, { headers: { 'x-api-key': payload.apiKey } }) + credDefResponse = await this.commonService.httpPost(url, credDefPayload, { headers: { 'authorization': payload.apiKey } }) .then(async (credDef) => { this.logger.debug(`API Response Data: ${JSON.stringify(credDef)}`); return credDef; @@ -785,7 +817,7 @@ export class AgentServiceService { schemaId: payload.payload.schemaId, issuerId: payload.payload.issuerId }; - credDefResponse = await this.commonService.httpPost(url, credDefPayload, { headers: { 'x-api-key': payload.apiKey } }) + credDefResponse = await this.commonService.httpPost(url, credDefPayload, { headers: { 'authorization': payload.apiKey } }) .then(async (credDef) => { this.logger.debug(`API Response Data: ${JSON.stringify(credDef)}`); return credDef; @@ -813,7 +845,7 @@ export class AgentServiceService { } else if (OrgAgentType.SHARED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SHAGENT_GET_CRED_DEF}`.replace('@', `${payload.payload.credentialDefinitionId}`).replace('#', `${payload.tenantId}`); - credDefResponse = await this.commonService.httpGet(url, { headers: { 'x-api-key': payload.apiKey } }) + credDefResponse = await this.commonService.httpGet(url, { headers: { 'authorization': payload.apiKey } }) .then(async (credDef) => { this.logger.debug(`API Response Data: ${JSON.stringify(credDef)}`); return credDef; @@ -829,8 +861,9 @@ export class AgentServiceService { async createLegacyConnectionInvitation(connectionPayload: IConnectionDetails, url: string, apiKey: string): Promise { try { + const data = await this.commonService - .httpPost(url, connectionPayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, connectionPayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return data; @@ -843,7 +876,7 @@ export class AgentServiceService { async sendCredentialCreateOffer(issueData: IIssuanceCreateOffer, url: string, apiKey: string): Promise { try { const data = await this.commonService - .httpPost(url, issueData, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, issueData, { headers: { 'authorization': apiKey } }) .then(async response => response); return data; } catch (error) { @@ -854,7 +887,7 @@ export class AgentServiceService { async getProofPresentations(url: string, apiKey: string): Promise { try { const getProofPresentationsData = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .httpGet(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return getProofPresentationsData; @@ -867,7 +900,7 @@ export class AgentServiceService { async getIssueCredentials(url: string, apiKey: string): Promise { try { const data = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .httpGet(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return data; } catch (error) { @@ -878,7 +911,7 @@ export class AgentServiceService { async getProofPresentationById(url: string, apiKey: string): Promise { try { const getProofPresentationById = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .httpGet(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return getProofPresentationById; } catch (error) { @@ -890,7 +923,7 @@ export class AgentServiceService { async getIssueCredentialsbyCredentialRecordId(url: string, apiKey: string): Promise { try { const data = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .httpGet(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return data; } catch (error) { @@ -902,7 +935,7 @@ export class AgentServiceService { async sendProofRequest(proofRequestPayload: ISendProofRequestPayload, url: string, apiKey: string): Promise { try { const sendProofRequest = await this.commonService - .httpPost(url, proofRequestPayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, proofRequestPayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return sendProofRequest; } catch (error) { @@ -914,7 +947,7 @@ export class AgentServiceService { async verifyPresentation(url: string, apiKey: string): Promise { try { const verifyPresentation = await this.commonService - .httpPost(url, '', { headers: { 'x-api-key': apiKey } }) + .httpPost(url, '', { headers: { 'authorization': apiKey } }) .then(async response => response); return verifyPresentation; } catch (error) { @@ -926,7 +959,7 @@ export class AgentServiceService { async getConnections(url: string, apiKey: string): Promise { try { const data = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .httpGet(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return data; } catch (error) { @@ -938,7 +971,7 @@ export class AgentServiceService { async getConnectionsByconnectionId(url: string, apiKey: string): Promise { try { const data = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .httpGet(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return data; @@ -948,16 +981,25 @@ export class AgentServiceService { } } - async getAgentHealthDetails(orgId: string): Promise { + async getAgentHealthDetails(orgId: string, apiKey: string): Promise { try { const orgAgentDetails: org_agents = await this.agentServiceRepository.getOrgAgentDetails(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this.getOrgAgentApiKey(orgId); + } + if (apiKey === undefined || null) { + apiKey = await this.getOrgAgentApiKey(orgId); + } + if (!orgAgentDetails) { throw new NotFoundException(ResponseMessages.agent.error.agentNotExists); } if (orgAgentDetails.agentEndPoint) { const data = await this.commonService - .httpGet(`${orgAgentDetails.agentEndPoint}/agent`, { headers: { 'x-api-key': '' } }) + .httpGet(`${orgAgentDetails.agentEndPoint}/agent`, { headers: { 'authorization': apiKey } }) .then(async response => response); return data; } else { @@ -973,7 +1015,7 @@ export class AgentServiceService { async sendOutOfBandProofRequest(proofRequestPayload: ISendProofRequestPayload, url: string, apiKey: string): Promise { try { const sendProofRequest = await this.commonService - .httpPost(url, proofRequestPayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, proofRequestPayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return sendProofRequest; } catch (error) { @@ -985,7 +1027,7 @@ export class AgentServiceService { async getProofFormData(url: string, apiKey: string): Promise { try { const getProofFormData = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .httpGet(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return getProofFormData; } catch (error) { @@ -997,7 +1039,7 @@ export class AgentServiceService { async schemaEndorsementRequest(url: string, apiKey: string, requestSchemaPayload: object): Promise { try { const schemaRequest = await this.commonService - .httpPost(url, requestSchemaPayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, requestSchemaPayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return schemaRequest; } catch (error) { @@ -1009,7 +1051,7 @@ export class AgentServiceService { async credDefEndorsementRequest(url: string, apiKey: string, requestSchemaPayload: object): Promise { try { const credDefRequest = await this.commonService - .httpPost(url, requestSchemaPayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, requestSchemaPayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return credDefRequest; } catch (error) { @@ -1021,7 +1063,7 @@ export class AgentServiceService { async signTransaction(url: string, apiKey: string, signEndorsementPayload: object): Promise { try { const signEndorsementTransaction = await this.commonService - .httpPost(url, signEndorsementPayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, signEndorsementPayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return signEndorsementTransaction; @@ -1035,7 +1077,7 @@ export class AgentServiceService { try { const signEndorsementTransaction = await this.commonService - .httpPost(url, submitEndorsementPayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, submitEndorsementPayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return signEndorsementTransaction; @@ -1048,7 +1090,7 @@ export class AgentServiceService { async outOfBandCredentialOffer(outOfBandIssuancePayload: OutOfBandCredentialOffer, url: string, apiKey: string): Promise { try { const sendOutOfbandCredentialOffer = await this.commonService - .httpPost(url, outOfBandIssuancePayload, { headers: { 'x-api-key': apiKey } }) + .httpPost(url, outOfBandIssuancePayload, { headers: { 'authorization': apiKey } }) .then(async response => response); return sendOutOfbandCredentialOffer; } catch (error) { @@ -1063,7 +1105,7 @@ export class AgentServiceService { ): Promise { try { const deleteWallet = await this.commonService - .httpDelete(url, { headers: { 'x-api-key': apiKey } }) + .httpDelete(url, { headers: { 'authorization': apiKey } }) .then(async response => response); return deleteWallet; } catch (error) { @@ -1071,13 +1113,15 @@ export class AgentServiceService { throw new RpcException(error); } } + async getOrgAgentApiKey(orgId: string): Promise { try { const orgAgentApiKey = await this.agentServiceRepository.getAgentApiKey(orgId); - + if (!orgAgentApiKey) { throw new NotFoundException(ResponseMessages.agent.error.apiKeyNotExist); } + await this.cacheService.set(CommonConstants.CACHE_APIKEY_KEY, orgAgentApiKey, CommonConstants.CACHE_TTL_SECONDS); return orgAgentApiKey; } catch (error) { diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 3b89f5872..2d792c7ee 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -14,6 +14,8 @@ export interface IAgentSpinupDto { clientSocketId?: string tenant?: boolean; ledgerName?: string[]; + platformAdminEmail?: string; + apiKey?:string; } export interface OutOfBandCredentialOffer { @@ -121,6 +123,7 @@ export interface IWalletProvision { afjVersion: string; protocol: string; tenant: boolean; + apiKey?:string; } export interface IPlatformConfigDto { @@ -161,7 +164,8 @@ export interface IConnectionDetails { } export interface IUserRequestInterface { - userId: string; + userId?: string; + id?: string; email: string; orgId: string; agentEndPoint?: string; diff --git a/apps/agent-service/src/main.ts b/apps/agent-service/src/main.ts index b750e60ca..4a7a4e545 100644 --- a/apps/agent-service/src/main.ts +++ b/apps/agent-service/src/main.ts @@ -30,6 +30,7 @@ async function bootstrap(): Promise { walletPassword: process.env.PLATFORM_WALLET_PASSWORD, seed: process.env.PLATFORM_SEED, orgName: `${CommonConstants.PLATFORM_ADMIN_ORG}`, + platformAdminEmail: process.env.PLATFORM_ADMIN_EMAIL, tenant: true, ledgerName: [Ledgers.Bcovrin_Testnet, Ledgers.Indicio_Demonet, Ledgers.Indicio_Mainnet, Ledgers.Indicio_Testnet] }; diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 732cf5825..71adc3d50 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -1,321 +1,346 @@ import { PrismaService } from '@credebl/prisma-service'; import { Injectable, Logger } from '@nestjs/common'; // eslint-disable-next-line camelcase -import { Prisma, ledgers, org_agents, organisation, platform_config } from '@prisma/client'; +import { Prisma, ledgers, org_agents, organisation, platform_config, user } from '@prisma/client'; import { IStoreOrgAgentDetails } from '../interface/agent-service.interface'; import { AgentType } from '@credebl/enum/enum'; @Injectable() export class AgentServiceRepository { - constructor(private readonly prisma: PrismaService, private readonly logger: Logger) { } - - /** - * Get platform config details - * @returns - */ - // eslint-disable-next-line camelcase - async getPlatformConfigDetails(): Promise { - try { - - return this.prisma.platform_config.findFirst(); - - } catch (error) { - this.logger.error(`[getPlatformConfigDetails] - error: ${JSON.stringify(error)}`); - throw error; - } + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger + ) {} + + /** + * Get platform config details + * @returns + */ + // eslint-disable-next-line camelcase + async getPlatformConfigDetails(): Promise { + try { + return this.prisma.platform_config.findFirst(); + } catch (error) { + this.logger.error(`[getPlatformConfigDetails] - error: ${JSON.stringify(error)}`); + throw error; } - - /** - * Get genesis url - * @param id - * @returns - */ - async getGenesisUrl(ledgerId: string[]): Promise { - try { - - const genesisData = await this.prisma.ledgers.findMany({ - where: { - id: { - in: ledgerId - } - } - }); - - return genesisData; - } catch (error) { - this.logger.error(`[getGenesisUrl] - get genesis URL: ${JSON.stringify(error)}`); - throw error; + } + + /** + * Get genesis url + * @param id + * @returns + */ + async getGenesisUrl(ledgerId: string[]): Promise { + try { + const genesisData = await this.prisma.ledgers.findMany({ + where: { + id: { + in: ledgerId + } } - } + }); - /** - * Get organization details - * @param id - * @returns - */ - async getOrgDetails(id: string): Promise { - try { - - const oranizationDetails = await this.prisma.organisation.findFirst({ - where: { - id - } - }); - return oranizationDetails; - } catch (error) { - this.logger.error(`[getOrgDetails] - get organization details: ${JSON.stringify(error)}`); - throw error; - } + return genesisData; + } catch (error) { + this.logger.error(`[getGenesisUrl] - get genesis URL: ${JSON.stringify(error)}`); + throw error; } - - // eslint-disable-next-line camelcase - async createOrgAgent(agentSpinUpStatus: number): Promise { - try { - - return this.prisma.org_agents.create({ - data: { - agentSpinUpStatus - } - }); - } catch (error) { - this.logger.error(`[createOrgAgent] - create agent details: ${JSON.stringify(error)}`); - throw error; + } + + /** + * Get organization details + * @param id + * @returns + */ + async getOrgDetails(id: string): Promise { + try { + const oranizationDetails = await this.prisma.organisation.findFirst({ + where: { + id } + }); + return oranizationDetails; + } catch (error) { + this.logger.error(`[getOrgDetails] - get organization details: ${JSON.stringify(error)}`); + throw error; } - - // eslint-disable-next-line camelcase - async removeOrgAgent(id: string): Promise { - try { - - return this.prisma.org_agents.delete({ - where: { - id - } - }); - } catch (error) { - this.logger.error(`[removeOrgAgent] - remove org agent details: ${JSON.stringify(error)}`); - throw error; + } + + // eslint-disable-next-line camelcase + async createOrgAgent(agentSpinUpStatus: number, userId: string, apiKey: string): Promise { + try { + return this.prisma.org_agents.create({ + data: { + agentSpinUpStatus, + createdBy: userId, + lastChangedBy: userId, + apiKey } + }); + } catch (error) { + this.logger.error(`[createOrgAgent] - create agent details: ${JSON.stringify(error)}`); + throw error; } - - /** - * Store agent details - * @param storeAgentDetails - * @returns - */ - // eslint-disable-next-line camelcase - async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { - try { - - return this.prisma.org_agents.update({ - where: { - id: storeOrgAgentDetails.id - }, - data: { - orgDid: storeOrgAgentDetails.did, - verkey: storeOrgAgentDetails.verkey, - isDidPublic: storeOrgAgentDetails.isDidPublic, - agentSpinUpStatus: storeOrgAgentDetails.agentSpinUpStatus, - walletName: storeOrgAgentDetails.walletName, - agentsTypeId: storeOrgAgentDetails.agentsTypeId, - orgId: storeOrgAgentDetails.orgId, - agentEndPoint: storeOrgAgentDetails.agentEndPoint, - agentId: storeOrgAgentDetails.agentId ? storeOrgAgentDetails.agentId : null, - orgAgentTypeId: storeOrgAgentDetails.orgAgentTypeId ? storeOrgAgentDetails.orgAgentTypeId : null, - tenantId: storeOrgAgentDetails.tenantId ? storeOrgAgentDetails.tenantId : null, - ledgerId: storeOrgAgentDetails.ledgerId[0] - } - }); - } catch (error) { - this.logger.error(`[storeAgentDetails] - store agent details: ${JSON.stringify(error)}`); - throw error; + } + + // eslint-disable-next-line camelcase + async removeOrgAgent(id: string): Promise { + try { + return this.prisma.org_agents.delete({ + where: { + id } + }); + } catch (error) { + this.logger.error(`[removeOrgAgent] - remove org agent details: ${JSON.stringify(error)}`); + throw error; } - - /** - * Get agent details - * @param orgId - * @returns - */ - // eslint-disable-next-line camelcase - async getAgentDetails(orgId: string): Promise { - try { - - const x = await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); - - return x; - - } catch (error) { - - this.logger.error(`[getAgentDetails] - get agent details: ${JSON.stringify(error)}`); - throw error; + } + + /** + * Store agent details + * @param storeAgentDetails + * @returns + */ + // eslint-disable-next-line camelcase + async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { + try { + return this.prisma.org_agents.update({ + where: { + id: storeOrgAgentDetails.id + }, + data: { + orgDid: storeOrgAgentDetails.did, + verkey: storeOrgAgentDetails.verkey, + isDidPublic: storeOrgAgentDetails.isDidPublic, + agentSpinUpStatus: storeOrgAgentDetails.agentSpinUpStatus, + walletName: storeOrgAgentDetails.walletName, + agentsTypeId: storeOrgAgentDetails.agentsTypeId, + orgId: storeOrgAgentDetails.orgId, + agentEndPoint: storeOrgAgentDetails.agentEndPoint, + agentId: storeOrgAgentDetails.agentId ? storeOrgAgentDetails.agentId : null, + orgAgentTypeId: storeOrgAgentDetails.orgAgentTypeId ? storeOrgAgentDetails.orgAgentTypeId : null, + tenantId: storeOrgAgentDetails.tenantId ? storeOrgAgentDetails.tenantId : null, + ledgerId: storeOrgAgentDetails.ledgerId[0] } + }); + } catch (error) { + this.logger.error(`[storeAgentDetails] - store agent details: ${JSON.stringify(error)}`); + throw error; } + } + + /** + * Get agent details + * @param orgId + * @returns + */ + // eslint-disable-next-line camelcase + async getAgentDetails(orgId: string): Promise { + try { + const x = await this.prisma.org_agents.findFirst({ + where: { + orgId + } + }); - // eslint-disable-next-line camelcase - async platformAdminAgent(platformOrg: string): Promise { - const platformAdminSpinnedUp = await this.prisma.organisation.findFirst({ - where: { - name: platformOrg - }, - include: { - // eslint-disable-next-line camelcase - org_agents: true - } - }); - return platformAdminSpinnedUp; + return x; + } catch (error) { + this.logger.error(`[getAgentDetails] - get agent details: ${JSON.stringify(error)}`); + throw error; } - - /** - * Get agent details - * @param orgId - * @returns Agent health details - */ - // eslint-disable-next-line camelcase - async getOrgAgentDetails(orgId: string): Promise { - try { - const oranizationAgentDetails = await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); - return oranizationAgentDetails; - } catch (error) { - this.logger.error(`[getAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); - throw error; + } + + // eslint-disable-next-line camelcase + async platformAdminAgent(platformOrg: string): Promise { + const platformAdminSpinnedUp = await this.prisma.organisation.findFirst({ + where: { + name: platformOrg + }, + include: { + // eslint-disable-next-line camelcase + org_agents: true + } + }); + return platformAdminSpinnedUp; + } + + /** + * Get agent details + * @param orgId + * @returns Agent health details + */ + // eslint-disable-next-line camelcase + async getOrgAgentDetails(orgId: string): Promise { + try { + const oranizationAgentDetails = await this.prisma.org_agents.findFirst({ + where: { + orgId } + }); + return oranizationAgentDetails; + } catch (error) { + this.logger.error(`[getOrgAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); + throw error; } + } - async getAgentTypeDetails(): Promise { - try { - const { id } = await this.prisma.agents_type.findFirst({ - where: { - agent: AgentType.AFJ - } - }); - return id; - } catch (error) { - this.logger.error(`[getAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); - throw error; + async getAgentTypeDetails(): Promise { + try { + const { id } = await this.prisma.agents_type.findFirst({ + where: { + agent: AgentType.AFJ } + }); + return id; + } catch (error) { + this.logger.error(`[getAgentTypeDetails] - get org agent health details: ${JSON.stringify(error)}`); + throw error; } + } + + async getLedgerDetails(name: string[] | string): Promise< + { + id: string; + createDateTime: Date; + lastChangedDateTime: Date; + name: string; + networkType: string; + poolConfig: string; + isActive: boolean; + networkString: string; + registerDIDEndpoint: string; + registerDIDPayload: Prisma.JsonValue; + indyNamespace: string; + }[] + > { + try { + let whereClause; + + if (Array.isArray(name)) { + whereClause = { + name: { + in: name + } + }; + } else { + whereClause = { + name + }; + } + + const ledgersDetails = await this.prisma.ledgers.findMany({ + where: whereClause + }); + return ledgersDetails; + } catch (error) { + this.logger.error(`[getLedgerDetails] - get ledger details: ${JSON.stringify(error)}`); + throw error; + } + } - async getLedgerDetails(name: string[] | string): Promise<{ - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - registerDIDEndpoint: string; - registerDIDPayload: Prisma.JsonValue; - indyNamespace: string; - }[]> { - try { - let whereClause; - - if (Array.isArray(name)) { - whereClause = { - name: { - in: name - } - }; - } else { - whereClause = { - name - }; - } - - const ledgersDetails = await this.prisma.ledgers.findMany({ - where: whereClause - }); - return ledgersDetails; - } catch (error) { - this.logger.error(`[getLedgerDetails] - get ledger details: ${JSON.stringify(error)}`); - throw error; + async getOrgAgentTypeDetails(agentType: string): Promise { + try { + const { id } = await this.prisma.org_agents_type.findFirst({ + where: { + agent: agentType } + }); + return id; + } catch (error) { + this.logger.error(`[getOrgAgentTypeDetails] - get org agent type details: ${JSON.stringify(error)}`); + throw error; } + } - async getOrgAgentTypeDetails(agentType: string): Promise { - try { - const { id } = await this.prisma.org_agents_type.findFirst({ - where: { - agent: agentType - } - }); - return id; - } catch (error) { - this.logger.error(`[getOrgAgentTypeDetails] - get org agent type details: ${JSON.stringify(error)}`); - throw error; + async getPlatfomOrg(orgName: string): Promise { + try { + const { id } = await this.prisma.organisation.findFirst({ + where: { + name: orgName } + }); + return id; + } catch (error) { + this.logger.error(`[getPlatfomOrg] - get platform org details: ${JSON.stringify(error)}`); + throw error; } + } - async getPlatfomOrg(orgName: string): Promise { - try { - const { id } = await this.prisma.organisation.findFirst({ - where: { - name: orgName - } - }); - return id; - } catch (error) { - this.logger.error(`[getPlatfomOrg] - get platform org details: ${JSON.stringify(error)}`); - throw error; + async getPlatfomAdminUser(platformAdminUserEmail: string): Promise { + try { + const platformAdminUser = await this.prisma.user.findUnique({ + where: { + email: platformAdminUserEmail } + }); + return platformAdminUser; + } catch (error) { + this.logger.error(`[getPlatfomAdminUser] - get platform admin user: ${JSON.stringify(error)}`); + throw error; } + } - async getAgentType(id: string): Promise { - try { - const { agent } = await this.prisma.agents_type.findUnique({ - where: { - id - } - }); - return agent; - } catch (error) { - this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); - throw error; + async getAgentType(id: string): Promise { + try { + const { agent } = await this.prisma.agents_type.findUnique({ + where: { + id } + }); + return agent; + } catch (error) { + this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); + throw error; } + } - async getAgentTypeId(agentType: string): Promise { - try { - const { id } = await this.prisma.agents_type.findFirst({ - where: { - agent: agentType - } - }); - return id; - } catch (error) { - this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); - throw error; + async getAgentTypeId(agentType: string): Promise { + try { + const { id } = await this.prisma.agents_type.findFirst({ + where: { + agent: agentType } + }); + return id; + } catch (error) { + this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); + throw error; } + } - - async getAgentApiKey(orgId: string): Promise { - try { - - const agent = await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); - - return agent.apiKey; - - } catch (error) { - - this.logger.error(`[getAgentApiKey] - get api key: ${JSON.stringify(error)}`); - throw error; + async getAgentApiKey(orgId: string): Promise { + try { + const agent = await this.prisma.org_agents.findFirst({ + where: { + orgId } + }); + + return agent.apiKey; + } catch (error) { + this.logger.error(`[getAgentApiKey] - get api key: ${JSON.stringify(error)}`); + throw error; } -} \ No newline at end of file + } + + // async storeAgentApikey( + // apiKey:string + // ): Promise { + // try { + + // return await this.prisma.org_agents.update({ + // data: { + // apiKey + // }, + // where: { + + // } + // }); + // } catch (error) { + // this.logger.error(`error: ${JSON.stringify(error)}`); + // throw error; + // } + // } +} diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index 21b12133b..dcb33d9fb 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -15,7 +15,6 @@ import { Param } from '@nestjs/common'; import { ApiTags, ApiResponse, ApiOperation, ApiUnauthorizedResponse, ApiForbiddenResponse, ApiBearerAuth } from '@nestjs/swagger'; -import { GetUser } from '../authz/decorators/get-user.decorator'; import { AuthGuard } from '@nestjs/passport'; import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; import { ApiResponseDto } from '../dtos/apiResponse.dto'; @@ -81,7 +80,7 @@ export class AgentController { async agentSpinup( @Body() agentSpinupDto: AgentSpinupDto, @Param('orgId') orgId: string, - @GetUser() user: user, + @User() user: user, @Res() res: Response ): Promise>> { @@ -121,7 +120,7 @@ export class AgentController { async createTenant( @Param('orgId') orgId: string, @Body() createTenantDto: CreateTenantDto, - @GetUser() user: user, + @User() user: user, @Res() res: Response ): Promise { diff --git a/apps/api-gateway/src/agent/agent.controller.ts b/apps/api-gateway/src/agent/agent.controller.ts index 1007c9e14..111d98d75 100644 --- a/apps/api-gateway/src/agent/agent.controller.ts +++ b/apps/api-gateway/src/agent/agent.controller.ts @@ -16,7 +16,6 @@ import { } from '@nestjs/common'; import { AgentService } from './agent.service'; import { ApiTags, ApiResponse, ApiOperation, ApiQuery, ApiBearerAuth, ApiParam, ApiUnauthorizedResponse, ApiForbiddenResponse, ApiExcludeEndpoint } from '@nestjs/swagger'; -import { GetUser } from '../authz/decorators/get-user.decorator'; import { AuthGuard } from '@nestjs/passport'; import { WalletDetailsDto } from '../dtos/wallet-details.dto'; import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; @@ -28,6 +27,7 @@ import { ApiResponseDto } from '../dtos/apiResponse.dto'; import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import { CommonService } from '@credebl/common'; import { IUserRequestInterface } from '../interfaces/IUserRequestInterface'; +import { User } from '../authz/decorators/user.decorator'; @ApiBearerAuth() @Controller('agent') @@ -57,7 +57,7 @@ export class AgentController { @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) getAllDid( - @GetUser() user: any, + @User() user: any, @Query('_public') _public: boolean, @Query('verkey') verkey: string, @Query('did') did: string @@ -80,7 +80,7 @@ export class AgentController { @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) createLocalDid( - @GetUser() user: any + @User() user: any ): Promise { this.logger.log(`**** Create Local Did...`); return this.agentService.createLocalDid(user); @@ -105,7 +105,7 @@ export class AgentController { @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) walletProvision( @Body() walletUserDetails: WalletDetailsDto, - @GetUser() user: object + @User() user: object ): Promise { this.logger.log(`**** Spin up the agent...${JSON.stringify(walletUserDetails)}`); @@ -131,7 +131,7 @@ export class AgentController { @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) getPublicDid( - @GetUser() user: any + @User() user: any ): Promise { this.logger.log(`**** Fetch public Did...`); return this.agentService.getPublicDid(user); @@ -151,7 +151,7 @@ export class AgentController { @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) assignPublicDid( @Param('id') id: number, - @GetUser() user: any + @User() user: any ): Promise { this.logger.log(`**** Assign public DID...`); this.logger.log(`user: ${user.orgId} == id: ${Number(id)}`); @@ -182,7 +182,7 @@ export class AgentController { @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) registerNym( @Param('id') id: string, - @GetUser() user: IUserRequestInterface + @User() user: IUserRequestInterface ): Promise { this.logger.log(`user: ${typeof user.orgId} == id: ${typeof Number(id)}`); @@ -221,7 +221,7 @@ export class AgentController { @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) - getAgentServerStatus(@GetUser() user: any): Promise { + getAgentServerStatus(@User() user: any): Promise { this.logger.log(`**** getPlatformConfig called...`); return this.agentService.getAgentServerStatus(user); } @@ -262,7 +262,7 @@ export class AgentController { @Query('search_text') search_text: string, @Query('sortValue') sortValue: any, @Query('status') status: any, - @GetUser() user: any + @User() user: any ): Promise { this.logger.log(`status: ${typeof status} ${status}`); diff --git a/apps/api-gateway/src/ecosystem/dtos/accept-reject-invitations.dto.ts b/apps/api-gateway/src/ecosystem/dtos/accept-reject-invitations.dto.ts index ee70759c4..57fa80731 100644 --- a/apps/api-gateway/src/ecosystem/dtos/accept-reject-invitations.dto.ts +++ b/apps/api-gateway/src/ecosystem/dtos/accept-reject-invitations.dto.ts @@ -33,4 +33,7 @@ export class AcceptRejectEcosystemInvitationDto { @IsEnum(Invitation) status: Invitation.ACCEPTED | Invitation.REJECTED; + userId?: string; + + } \ No newline at end of file diff --git a/apps/api-gateway/src/ecosystem/dtos/edit-ecosystem-dto.ts b/apps/api-gateway/src/ecosystem/dtos/edit-ecosystem-dto.ts index 917761bd6..dc0fd4231 100644 --- a/apps/api-gateway/src/ecosystem/dtos/edit-ecosystem-dto.ts +++ b/apps/api-gateway/src/ecosystem/dtos/edit-ecosystem-dto.ts @@ -40,5 +40,8 @@ export class EditEcosystemDto { @IsOptional() @IsNotEmpty({ message: 'autoEndorsement should be boolean value' }) autoEndorsement = false; + + userId?: string; + } \ No newline at end of file diff --git a/apps/api-gateway/src/ecosystem/dtos/request-schema.dto.ts b/apps/api-gateway/src/ecosystem/dtos/request-schema.dto.ts index 202857f57..641a16168 100644 --- a/apps/api-gateway/src/ecosystem/dtos/request-schema.dto.ts +++ b/apps/api-gateway/src/ecosystem/dtos/request-schema.dto.ts @@ -46,6 +46,8 @@ export class RequestSchemaDto { @IsOptional() endorse?: boolean; + userId?: string; + } export class SchemaDetails { @@ -76,6 +78,8 @@ export class RequestCredDefDto { @IsString({ message: 'tag must be a string.' }) tag: string; + userId?: string; + @ApiProperty() @IsString({ message: 'schemaId must be a string.' }) schemaId: string; diff --git a/apps/api-gateway/src/ecosystem/ecosystem.controller.ts b/apps/api-gateway/src/ecosystem/ecosystem.controller.ts index 602b160e1..af7427033 100644 --- a/apps/api-gateway/src/ecosystem/ecosystem.controller.ts +++ b/apps/api-gateway/src/ecosystem/ecosystem.controller.ts @@ -297,8 +297,10 @@ export class EcosystemController { async createNewEcosystem( @Body() createOrgDto: CreateEcosystemDto, @Param('orgId') orgId: string, + @User() user: user, @Res() res: Response): Promise { createOrgDto.orgId = orgId; + createOrgDto.userId = user.id; await this.ecosystemService.createEcosystem(createOrgDto); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, @@ -314,7 +316,8 @@ export class EcosystemController { @ApiBearerAuth() @EcosystemsRoles(EcosystemRoles.ECOSYSTEM_MEMBER) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER) - async requestSchemaTransaction(@Body() requestSchemaPayload: RequestSchemaDto, @Param('orgId') orgId: string, @Param('ecosystemId') ecosystemId: string, @Res() res: Response): Promise { + async requestSchemaTransaction(@Body() requestSchemaPayload: RequestSchemaDto, @Param('orgId') orgId: string, @Param('ecosystemId') ecosystemId: string, @Res() res: Response, @User() user: user): Promise { + requestSchemaPayload.userId = user.id; await this.ecosystemService.schemaEndorsementRequest(requestSchemaPayload, orgId, ecosystemId); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, @@ -331,7 +334,8 @@ export class EcosystemController { @ApiBearerAuth() @EcosystemsRoles(EcosystemRoles.ECOSYSTEM_MEMBER) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER) - async requestCredDefTransaction(@Body() requestCredDefPayload: RequestCredDefDto, @Param('orgId') orgId: string, @Param('ecosystemId') ecosystemId: string, @Res() res: Response): Promise { + async requestCredDefTransaction(@Body() requestCredDefPayload: RequestCredDefDto, @Param('orgId') orgId: string, @Param('ecosystemId') ecosystemId: string, @Res() res: Response, @User() user: user): Promise { + requestCredDefPayload.userId = user.id; await this.ecosystemService.credDefEndorsementRequest(requestCredDefPayload, orgId, ecosystemId); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, @@ -364,7 +368,7 @@ export class EcosystemController { @EcosystemsRoles(EcosystemRoles.ECOSYSTEM_MEMBER) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER) async SumbitEndorsementRequests(@Param('endorsementId') endorsementId: string, @Param('ecosystemId') ecosystemId: string, @Param('orgId') orgId: string, @Res() res: Response): Promise { - await this.ecosystemService.submitTransaction(endorsementId, ecosystemId); + await this.ecosystemService.submitTransaction(endorsementId, ecosystemId, orgId); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.ecosystem.success.submit @@ -393,13 +397,13 @@ export class EcosystemController { @Param('ecosystemId') ecosystemId: string, @Param('orgId') orgId: string, @User() user: user, @Res() res: Response): Promise { - + // const userId = `a1614521-02c3-493f-97e5-9e8ac1c25682`; // const userEmail = `pallavicoder10@yopmail.com`; - + bulkInvitationDto.ecosystemId = ecosystemId; - + await this.ecosystemService.createInvitation(bulkInvitationDto, user.id, user.email); const finalResponse: IResponseType = { @@ -454,7 +458,7 @@ export class EcosystemController { async acceptRejectEcosystemInvitaion(@Body() acceptRejectEcosystemInvitation: AcceptRejectEcosystemInvitationDto, @Param('orgId') orgId: string, @Param('invitationId') invitationId: string, @User() user: user, @Res() res: Response): Promise { acceptRejectEcosystemInvitation.orgId = orgId; acceptRejectEcosystemInvitation.invitationId = invitationId; - + acceptRejectEcosystemInvitation.userId = user.id; const invitationRes = await this.ecosystemService.acceptRejectEcosystemInvitaion(acceptRejectEcosystemInvitation, user.email); const finalResponse: IResponseType = { @@ -476,7 +480,9 @@ export class EcosystemController { @Body() editEcosystemDto: EditEcosystemDto, @Param('ecosystemId') ecosystemId: string, @Param('orgId') orgId: string, + @User() user: user, @Res() res: Response): Promise { + editEcosystemDto.userId = user.id; await this.ecosystemService.editEcosystem(editEcosystemDto, ecosystemId); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, @@ -485,36 +491,36 @@ export class EcosystemController { return res.status(HttpStatus.OK).json(finalResponse); } - - /** - * - * @param declineEndorsementTransactionRequest - * - * @param res - * @returns endorsement transaction status - */ - @Put('/:ecosystemId/:orgId/transactions/:endorsementId') - @ApiOperation({ - summary: 'Decline Endorsement Request By Lead', - description: 'Decline Endorsement Request By Lead' - }) - @UseGuards(AuthGuard('jwt'), EcosystemRolesGuard, OrgRolesGuard) - @ApiBearerAuth() - @EcosystemsRoles(EcosystemRoles.ECOSYSTEM_LEAD) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) - async declineEndorsementRequestByLead( - @Param('ecosystemId') ecosystemId: string, - @Param('endorsementId') endorsementId: string, - @Param('orgId') orgId: string, - @Res() res: Response - ): Promise { - await this.ecosystemService.declineEndorsementRequestByLead(ecosystemId, endorsementId, orgId); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.ecosystem.success.DeclineEndorsementTransaction - }; - return res.status(HttpStatus.OK).json(finalResponse); - } + + /** + * + * @param declineEndorsementTransactionRequest + * + * @param res + * @returns endorsement transaction status + */ + @Put('/:ecosystemId/:orgId/transactions/:endorsementId') + @ApiOperation({ + summary: 'Decline Endorsement Request By Lead', + description: 'Decline Endorsement Request By Lead' + }) + @UseGuards(AuthGuard('jwt'), EcosystemRolesGuard, OrgRolesGuard) + @ApiBearerAuth() + @EcosystemsRoles(EcosystemRoles.ECOSYSTEM_LEAD) + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) + async declineEndorsementRequestByLead( + @Param('ecosystemId') ecosystemId: string, + @Param('endorsementId') endorsementId: string, + @Param('orgId') orgId: string, + @Res() res: Response + ): Promise { + await this.ecosystemService.declineEndorsementRequestByLead(ecosystemId, endorsementId, orgId); + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.ecosystem.success.DeclineEndorsementTransaction + }; + return res.status(HttpStatus.OK).json(finalResponse); + } @Delete('/:ecosystemId/:orgId/invitations/:invitationId') diff --git a/apps/api-gateway/src/ecosystem/ecosystem.service.ts b/apps/api-gateway/src/ecosystem/ecosystem.service.ts index 5db865d82..db5555393 100644 --- a/apps/api-gateway/src/ecosystem/ecosystem.service.ts +++ b/apps/api-gateway/src/ecosystem/ecosystem.service.ts @@ -34,7 +34,7 @@ export class EcosystemService extends BaseService { * @param editEcosystemDto * @returns Ecosystem creation success */ - async editEcosystem(editEcosystemDto: EditEcosystemDto, ecosystemId:string): Promise { + async editEcosystem(editEcosystemDto: EditEcosystemDto, ecosystemId: string): Promise { const payload = { editEcosystemDto, ecosystemId }; return this.sendNats(this.serviceProxy, 'edit-ecosystem', payload); } @@ -59,16 +59,19 @@ export class EcosystemService extends BaseService { return this.sendNats(this.serviceProxy, 'get-ecosystem-dashboard-details', payload); } - /** - * - * @param bulkInvitationDto - * @param userId - * @returns + * + * @param bulkInvitationDto + * @param userId + * @returns */ - async createInvitation(bulkInvitationDto: BulkEcosystemInvitationDto, userId: string, userEmail: string): Promise { + async createInvitation( + bulkInvitationDto: BulkEcosystemInvitationDto, + userId: string, + userEmail: string + ): Promise { const payload = { bulkInvitationDto, userId, userEmail }; - + return this.sendNats(this.serviceProxy, 'send-ecosystem-invitation', payload); } @@ -109,10 +112,7 @@ export class EcosystemService extends BaseService { return this.sendNats(this.serviceProxy, 'get-ecosystem-invitations', payload); } - - async deleteEcosystemInvitations( - invitationId: string - ): Promise { + async deleteEcosystemInvitations(invitationId: string): Promise { const payload = { invitationId }; return this.sendNats(this.serviceProxy, 'delete-ecosystem-invitations', payload); } @@ -124,11 +124,7 @@ export class EcosystemService extends BaseService { return this.sendNats(this.serviceProxy, 'accept-reject-ecosystem-invitations', payload); } - - async fetchEcosystemOrg( - ecosystemId: string, - orgId: string - ): Promise<{ response: object }> { + async fetchEcosystemOrg(ecosystemId: string, orgId: string): Promise<{ response: object }> { const payload = { ecosystemId, orgId }; return this.sendNats(this.serviceProxy, 'fetch-ecosystem-org-data', payload); } @@ -153,13 +149,20 @@ export class EcosystemService extends BaseService { return this.sendNats(this.serviceProxy, 'get-all-ecosystem-schemas', payload); } - - async schemaEndorsementRequest(requestSchemaPayload: RequestSchemaDto, orgId: string, ecosystemId: string): Promise { + async schemaEndorsementRequest( + requestSchemaPayload: RequestSchemaDto, + orgId: string, + ecosystemId: string + ): Promise { const payload = { requestSchemaPayload, orgId, ecosystemId }; return this.sendNats(this.serviceProxy, 'schema-endorsement-request', payload); } - async credDefEndorsementRequest(requestCredDefPayload: RequestCredDefDto, orgId: string, ecosystemId: string): Promise { + async credDefEndorsementRequest( + requestCredDefPayload: RequestCredDefDto, + orgId: string, + ecosystemId: string + ): Promise { const payload = { requestCredDefPayload, orgId, ecosystemId }; return this.sendNats(this.serviceProxy, 'credDef-endorsement-request', payload); } @@ -169,8 +172,8 @@ export class EcosystemService extends BaseService { return this.sendNats(this.serviceProxy, 'sign-endorsement-transaction', payload); } - async submitTransaction(endorsementId: string, ecosystemId: string): Promise { - const payload = { endorsementId, ecosystemId }; + async submitTransaction(endorsementId: string, ecosystemId: string, orgId: string): Promise { + const payload = { endorsementId, ecosystemId, orgId }; return this.sendNats(this.serviceProxy, 'sumbit-endorsement-transaction', payload); } @@ -187,5 +190,4 @@ export class EcosystemService extends BaseService { const payload = { ecosystemId, endorsementId, orgId }; return this.sendNats(this.serviceProxy, 'decline-endorsement-transaction', payload); } - } diff --git a/apps/api-gateway/src/issuance/dtos/issuance.dto.ts b/apps/api-gateway/src/issuance/dtos/issuance.dto.ts index 05126aa74..fba865b58 100644 --- a/apps/api-gateway/src/issuance/dtos/issuance.dto.ts +++ b/apps/api-gateway/src/issuance/dtos/issuance.dto.ts @@ -212,4 +212,6 @@ export class ClientDetails { @Type(() => String) clientId = ''; + userId?: string; + } \ No newline at end of file diff --git a/apps/api-gateway/src/issuance/issuance.controller.ts b/apps/api-gateway/src/issuance/issuance.controller.ts index d9bcca393..715b34db1 100644 --- a/apps/api-gateway/src/issuance/issuance.controller.ts +++ b/apps/api-gateway/src/issuance/issuance.controller.ts @@ -53,6 +53,9 @@ import { AwsService } from '@credebl/aws'; import { FileInterceptor } from '@nestjs/platform-express'; import { v4 as uuidv4 } from 'uuid'; import { RpcException } from '@nestjs/microservices'; +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { user } from '@prisma/client'; + @Controller() @UseFilters(CustomExceptionFilter) @ApiTags('credentials') @@ -350,8 +353,9 @@ export class IssuanceController { summary: 'bulk issue credential', description: 'bulk issue credential' }) - async issueBulkCredentials(@Param('requestId') requestId: string, @Param('orgId') orgId: string, @Res() res: Response, @Body() clientDetails: ClientDetails): Promise { - const bulkIssunaceDetails = await this.issueCredentialService.issueBulkCredential(requestId, orgId, clientDetails.clientId); + async issueBulkCredentials(@Param('requestId') requestId: string, @Param('orgId') orgId: string, @Res() res: Response, @Body() clientDetails: ClientDetails, @User() user: user): Promise { + clientDetails.userId = user.id; + const bulkIssunaceDetails = await this.issueCredentialService.issueBulkCredential(requestId, orgId, clientDetails); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.bulkIssuance, diff --git a/apps/api-gateway/src/issuance/issuance.service.ts b/apps/api-gateway/src/issuance/issuance.service.ts index ef156673c..6f32c6cb2 100644 --- a/apps/api-gateway/src/issuance/issuance.service.ts +++ b/apps/api-gateway/src/issuance/issuance.service.ts @@ -3,7 +3,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { FileParameter, IssuanceDto, IssueCredentialDto, OutOfBandCredentialDto, PreviewFileDetails } from './dtos/issuance.dto'; +import { ClientDetails, FileParameter, IssuanceDto, IssueCredentialDto, OutOfBandCredentialDto, PreviewFileDetails } from './dtos/issuance.dto'; import { FileExportResponse, RequestPayload } from './interfaces'; @Injectable() @@ -109,8 +109,8 @@ export class IssuanceService extends BaseService { return this.sendNats(this.issuanceProxy, 'issued-file-data', payload); } - async issueBulkCredential(requestId: string, orgId: string, clientId: string): Promise<{ response: object }> { - const payload = { requestId, orgId, clientId }; + async issueBulkCredential(requestId: string, orgId: string, clientDetails: ClientDetails): Promise<{ response: object }> { + const payload = { requestId, orgId, clientDetails }; return this.sendNats(this.issuanceProxy, 'issue-bulk-credentials', payload); } diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index a43ccdd77..28c668bf5 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -17,7 +17,6 @@ import { ApiResponseDto } from '../dtos/apiResponse.dto'; import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import { OutOfBandRequestProof, RequestProof } from './dto/request-proof.dto'; -import { GetUser } from '../authz/decorators/get-user.decorator'; import { VerificationService } from './verification.service'; import IResponseType from '@credebl/common/interfaces/response.interface'; import { Response } from 'express'; @@ -30,6 +29,7 @@ import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { WebhookPresentationProof } from './dto/webhook-proof.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; import { ImageServiceService } from '@credebl/image-service'; +import { User } from '../authz/decorators/user.decorator'; @UseFilters(CustomExceptionFilter) @Controller() @@ -69,7 +69,7 @@ export class VerificationController { @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) async getProofFormData( @Res() res: Response, - @GetUser() user: IUserRequest, + @User() user: IUserRequest, @Param('proofId') id: string, @Param('orgId') orgId: string ): Promise { @@ -102,7 +102,7 @@ export class VerificationController { @ApiBearerAuth() async getProofPresentationById( @Res() res: Response, - @GetUser() user: IUserRequest, + @User() user: IUserRequest, @Param('proofId') id: string, @Param('orgId') orgId: string ): Promise { @@ -137,7 +137,7 @@ export class VerificationController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) async getProofPresentations( @Res() res: Response, - @GetUser() user: IUserRequest, + @User() user: IUserRequest, @Param('orgId') orgId: string, @Query('threadId') threadId: string ): Promise { @@ -170,7 +170,7 @@ export class VerificationController { @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.VERIFIER) async sendPresentationRequest( @Res() res: Response, - @GetUser() user: IUserRequest, + @User() user: IUserRequest, @Param('orgId') orgId: string, @Body() requestProof: RequestProof ): Promise { @@ -209,7 +209,7 @@ export class VerificationController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) async verifyPresentation( @Res() res: Response, - @GetUser() user: IUserRequest, + @User() user: IUserRequest, @Param('proofId') id: string, @Param('orgId') orgId: string ): Promise { @@ -242,7 +242,7 @@ export class VerificationController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) async sendOutOfBandPresentationRequest( @Res() res: Response, - @GetUser() user: IUserRequest, + @User() user: IUserRequest, @Body() outOfBandRequestProof: OutOfBandRequestProof, @Param('orgId') orgId: string ): Promise { diff --git a/apps/connection/src/connection.module.ts b/apps/connection/src/connection.module.ts index e9cc372a8..2fbfe8dc1 100644 --- a/apps/connection/src/connection.module.ts +++ b/apps/connection/src/connection.module.ts @@ -1,3 +1,4 @@ +/* eslint-disable array-bracket-spacing */ import { Logger, Module } from '@nestjs/common'; import { ConnectionController } from './connection.controller'; import { ConnectionService } from './connection.service'; @@ -5,7 +6,7 @@ import { ClientsModule, Transport } from '@nestjs/microservices'; import { CommonModule } from '@credebl/common'; import { ConnectionRepository } from './connection.repository'; import { PrismaService } from '@credebl/prisma-service'; - +import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ ClientsModule.register([ @@ -18,7 +19,8 @@ import { PrismaService } from '@credebl/prisma-service'; } ]), - CommonModule + CommonModule, + CacheModule.register() ], controllers: [ConnectionController], providers: [ConnectionService, ConnectionRepository, PrismaService, Logger] diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index 27e1ddb35..38331f0c7 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -112,6 +112,8 @@ export class ConnectionRepository { create: { createDateTime, lastChangedDateTime, + createdBy: orgId, + lastChangedBy: orgId, connectionId, state, orgDid, diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 6aec955fa..6076097d0 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -21,8 +21,9 @@ import { ConnectionRepository } from './connection.repository'; import { ResponseMessages } from '@credebl/common/response-messages'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { OrgAgentType } from '@credebl/enum/enum'; -import { platform_config } from '@prisma/client'; - +// import { platform_config } from '@prisma/client'; +import { Cache } from 'cache-manager'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; @Injectable() export class ConnectionService { @@ -31,7 +32,8 @@ export class ConnectionService { private readonly commonService: CommonService, @Inject('NATS_CLIENT') private readonly connectionServiceProxy: ClientProxy, private readonly connectionRepository: ConnectionRepository, - private readonly logger: Logger + private readonly logger: Logger, + @Inject(CACHE_MANAGER) private cacheService: Cache ) { } /** @@ -53,7 +55,7 @@ export class ConnectionService { const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); - const platformConfig: platform_config = await this.connectionRepository.getPlatformConfigDetails(); + // const platformConfig: platform_config = await this.connectionRepository.getPlatformConfigDetails(); const { agentEndPoint, id, organisation } = agentDetails; const agentId = id; if (!agentDetails) { @@ -76,8 +78,14 @@ export class ConnectionService { const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); const url = await this.getAgentUrl(orgAgentType, agentEndPoint, agentDetails?.tenantId); - const apiKey = platformConfig?.sgApiKey; + // const apiKey = platformConfig?.sgApiKey; + const apiKey = await this._getOrgAgentApiKey(orgId); + // let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + // this.logger.log(`cachedApiKey----getConnections,${apiKey}`); + //if(!apiKey || apiKey === null || apiKey === undefined) { + // apiKey = await this._getOrgAgentApiKey(orgId); + // } const createConnectionInvitation = await this._createConnectionInvitation(connectionPayload, url, apiKey); const invitationObject = createConnectionInvitation?.message?.invitation['@id']; @@ -193,7 +201,7 @@ export class ConnectionService { try { const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); - const platformConfig: platform_config = await this.connectionRepository.getPlatformConfigDetails(); + // const platformConfig: platform_config = await this.connectionRepository.getPlatformConfigDetails(); const { agentEndPoint } = agentDetails; if (!agentDetails) { @@ -228,7 +236,14 @@ export class ConnectionService { url = `${url + appendParams + element}=${params[element]}`; } }); - const apiKey = platformConfig?.sgApiKey; + + + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----getConnections,${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const connectionsDetails = await this._getAllConnections(url, apiKey); return connectionsDetails?.response; } catch (error) { @@ -279,7 +294,7 @@ export class ConnectionService { const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); - const platformConfig: platform_config = await this.connectionRepository.getPlatformConfigDetails(); + // const platformConfig: platform_config = await this.connectionRepository.getPlatformConfigDetails(); const { agentEndPoint } = agentDetails; if (!agentDetails) { @@ -298,7 +313,13 @@ export class ConnectionService { throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound); } - const apiKey = platformConfig?.sgApiKey; + + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----getConnectionsById,${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const createConnectionInvitation = await this._getConnectionsByConnectionId(url, apiKey); return createConnectionInvitation?.response; } catch (error) { @@ -375,4 +396,22 @@ export class ConnectionService { } } + + async _getOrgAgentApiKey(orgId: string): Promise { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = { orgId }; + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const message = await this.connectionServiceProxy.send(pattern, payload).toPromise(); + return message; + } catch (error) { + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException({ + status: error.status, + error: error.message + }, error.status); + } + } } + diff --git a/apps/ecosystem/dtos/accept-reject-ecosysteminvitation.dto.ts b/apps/ecosystem/dtos/accept-reject-ecosysteminvitation.dto.ts index 789408777..cf885b6cb 100644 --- a/apps/ecosystem/dtos/accept-reject-ecosysteminvitation.dto.ts +++ b/apps/ecosystem/dtos/accept-reject-ecosysteminvitation.dto.ts @@ -6,4 +6,5 @@ export class AcceptRejectEcosystemInvitationDto { status: Invitation; orgName: string; orgDid: string; + userId?: string; } diff --git a/apps/ecosystem/dtos/update-ecosystemOrgs.dto.ts b/apps/ecosystem/dtos/update-ecosystemOrgs.dto.ts index f87298807..d8e1dd41e 100644 --- a/apps/ecosystem/dtos/update-ecosystemOrgs.dto.ts +++ b/apps/ecosystem/dtos/update-ecosystemOrgs.dto.ts @@ -5,4 +5,6 @@ export class updateEcosystemOrgsDto { status: string; ecosystemId: string; ecosystemRoleId: string; + createdBy?: string; + lastChangedBy?: string; } \ No newline at end of file diff --git a/apps/ecosystem/interfaces/ecosystem.interfaces.ts b/apps/ecosystem/interfaces/ecosystem.interfaces.ts index b28dfe280..64ec9adb8 100644 --- a/apps/ecosystem/interfaces/ecosystem.interfaces.ts +++ b/apps/ecosystem/interfaces/ecosystem.interfaces.ts @@ -1,4 +1,4 @@ -import { Prisma } from "@prisma/client"; +import { Prisma } from '@prisma/client'; export interface AttributeValue { attributeName: string; schemaDataType: string; @@ -6,7 +6,8 @@ export interface AttributeValue { } export interface RequestSchemaEndorsement { - orgId: string + orgId: string; + userId?: string; name: string; version: string; attributes: AttributeValue[]; @@ -14,16 +15,17 @@ export interface RequestSchemaEndorsement { } export interface RequestCredDeffEndorsement { - schemaId: string + schemaId: string; tag: string; endorse?: boolean; schemaDetails?: object; + userId?: string; } export interface IAttributeValue { attributeName: string; schemaDataType: string; - displayName: string + displayName: string; } export interface SchemaTransactionPayload { @@ -79,6 +81,7 @@ export interface SchemaTransactionResponse { requestPayload: string; status: string; ecosystemOrgId: string; + userId?: string; } export interface SignedTransactionMessage { @@ -93,7 +96,7 @@ export interface EndorsementTransactionPayload { authorDid: string; requestPayload: string; responsePayload: string; - requestBody: Prisma.JsonValue + requestBody: Prisma.JsonValue; status: string; ecosystemOrgId: string; createDateTime: Date; @@ -129,7 +132,6 @@ export interface submitTransactionPayload { credentialDefinition?: CredentialDefinitionPayload; } - export interface SaveSchema { name: string; version: string; @@ -149,6 +151,7 @@ export interface saveCredDef { credentialDefinitionId: string; revocable: boolean; createdBy: string; + lastChangedBy: string; orgId: string; schemaId: string; } @@ -161,7 +164,7 @@ export interface EndorsementTransactionPayloadDetails { responsePayload: string; type: string; createDateTime: Date; - createdBy:string; + createdBy: string; lastChangedDateTime: Date; lastChangedBy: string; deletedAt: Date | null; @@ -190,5 +193,12 @@ export interface CreateEcosystem { orgId?: string; - autoEndorsement: boolean -} \ No newline at end of file + autoEndorsement: boolean; +} + +export interface TransactionPayload { + endorsementId: string; + ecosystemId: string; + ecosystemLeadAgentEndPoint?: string; + orgId?: string; +} diff --git a/apps/ecosystem/src/ecosystem.controller.ts b/apps/ecosystem/src/ecosystem.controller.ts index 8dc75f5b3..09dff889d 100644 --- a/apps/ecosystem/src/ecosystem.controller.ts +++ b/apps/ecosystem/src/ecosystem.controller.ts @@ -12,7 +12,7 @@ import { RequestCredDeffEndorsement, RequestSchemaEndorsement } from '../interfa @Controller() export class EcosystemController { - constructor(private readonly ecosystemService: EcosystemService) { } + constructor(private readonly ecosystemService: EcosystemService) {} private readonly logger = new Logger('EcosystemController'); /** @@ -32,7 +32,7 @@ export class EcosystemController { * @returns Get updated ecosystem details */ @MessagePattern({ cmd: 'edit-ecosystem' }) - async editEcosystem(@Body() payload: { editEcosystemDto, ecosystemId }): Promise { + async editEcosystem(@Body() payload: { editEcosystemDto; ecosystemId }): Promise { return this.ecosystemService.editEcosystem(payload.editEcosystemDto, payload.ecosystemId); } @@ -42,9 +42,7 @@ export class EcosystemController { * @returns Get all ecosystem details */ @MessagePattern({ cmd: 'get-all-ecosystem' }) - async getAllEcosystems( - @Body() payload: { orgId: string } - ): Promise { + async getAllEcosystems(@Body() payload: { orgId: string }): Promise { return this.ecosystemService.getAllEcosystem(payload); } @@ -53,19 +51,17 @@ export class EcosystemController { * @returns Get ecosystem dashboard details */ @MessagePattern({ cmd: 'get-ecosystem-dashboard-details' }) - async getEcosystemDashboardDetails( - payload: { ecosystemId: string; orgId: string }): Promise { + async getEcosystemDashboardDetails(payload: { ecosystemId: string; orgId: string }): Promise { return this.ecosystemService.getEcosystemDashboardDetails(payload.ecosystemId); } - /** * Description: get ecosystem invitations * @returns Get sent invitation details */ @MessagePattern({ cmd: 'get-ecosystem-invitations' }) async getEcosystemInvitations( - @Body() payload: { userEmail: string, status: string; pageNumber: number; pageSize: number; search: string } + @Body() payload: { userEmail: string; status: string; pageNumber: number; pageSize: number; search: string } ): Promise { return this.ecosystemService.getEcosystemInvitations( payload.userEmail, @@ -82,23 +78,21 @@ export class EcosystemController { * @returns ecosystem members list */ @MessagePattern({ cmd: 'fetch-ecosystem-members' }) - async getEcosystemMembers( - @Body() payload: EcosystemMembersPayload - ): Promise { - return this.ecosystemService.getEcoystemMembers( - payload - ); + async getEcosystemMembers(@Body() payload: EcosystemMembersPayload): Promise { + return this.ecosystemService.getEcoystemMembers(payload); } /** - * - * @param payload + * + * @param payload * @returns Sent ecosystem invitations status */ @MessagePattern({ cmd: 'send-ecosystem-invitation' }) - async createInvitation( - payload: { bulkInvitationDto: BulkSendInvitationDto; userId: string, userEmail: string } - ): Promise { + async createInvitation(payload: { + bulkInvitationDto: BulkSendInvitationDto; + userId: string; + userEmail: string; + }): Promise { return this.ecosystemService.createInvitation(payload.bulkInvitationDto, payload.userId, payload.userEmail); } @@ -114,117 +108,107 @@ export class EcosystemController { return this.ecosystemService.acceptRejectEcosystemInvitations(payload.acceptRejectInvitation); } - @MessagePattern({ cmd: 'get-sent-invitations-ecosystemId' }) - async getInvitationsByOrgId( - @Body() payload: FetchInvitationsPayload - ): Promise { - return this.ecosystemService.getInvitationsByEcosystemId( - payload - ); + async getInvitationsByOrgId(@Body() payload: FetchInvitationsPayload): Promise { + return this.ecosystemService.getInvitationsByEcosystemId(payload); } @MessagePattern({ cmd: 'get-endorsement-transactions' }) - async getEndorsementTransactions( - @Body() payload: GetEndorsementsPayload - ): Promise { - return this.ecosystemService.getEndorsementTransactions( - payload - ); + async getEndorsementTransactions(@Body() payload: GetEndorsementsPayload): Promise { + return this.ecosystemService.getEndorsementTransactions(payload); } - @MessagePattern({ cmd: 'get-all-ecosystem-schemas' }) - async getAllEcosystemSchemas( - @Body() payload: GetEndorsementsPayload - ): Promise { - return this.ecosystemService.getAllEcosystemSchemas( - payload - ); + async getAllEcosystemSchemas(@Body() payload: GetEndorsementsPayload): Promise { + return this.ecosystemService.getAllEcosystemSchemas(payload); } @MessagePattern({ cmd: 'delete-ecosystem-invitations' }) - async deleteInvitation( - @Body() payload: { invitationId: string } - ): Promise { - return this.ecosystemService.deleteEcosystemInvitations( - payload.invitationId - ); + async deleteInvitation(@Body() payload: { invitationId: string }): Promise { + return this.ecosystemService.deleteEcosystemInvitations(payload.invitationId); } @MessagePattern({ cmd: 'fetch-ecosystem-org-data' }) - async fetchEcosystemOrg( - @Body() payload: { ecosystemId: string, orgId: string } - ): Promise { - return this.ecosystemService.fetchEcosystemOrg( - payload - ); + async fetchEcosystemOrg(@Body() payload: { ecosystemId: string; orgId: string }): Promise { + return this.ecosystemService.fetchEcosystemOrg(payload); } /** - * - * @param payload - * @returns Schema endorsement request - */ + * + * @param payload + * @returns Schema endorsement request + */ @MessagePattern({ cmd: 'schema-endorsement-request' }) - async schemaEndorsementRequest(payload: { requestSchemaPayload: RequestSchemaEndorsement; orgId: string, ecosystemId: string } - ): Promise { - return this.ecosystemService.requestSchemaEndorsement(payload.requestSchemaPayload, payload.orgId, payload.ecosystemId); + async schemaEndorsementRequest(payload: { + requestSchemaPayload: RequestSchemaEndorsement; + orgId: string; + ecosystemId: string; + }): Promise { + return this.ecosystemService.requestSchemaEndorsement( + payload.requestSchemaPayload, + payload.orgId, + payload.ecosystemId + ); } /** - * - * @param payload - * @returns Schema endorsement request - */ + * + * @param payload + * @returns Schema endorsement request + */ @MessagePattern({ cmd: 'credDef-endorsement-request' }) - async credDefEndorsementRequest(payload: { requestCredDefPayload: RequestCredDeffEndorsement; orgId: string; ecosystemId: string } - ): Promise { - return this.ecosystemService.requestCredDeffEndorsement(payload.requestCredDefPayload, payload.orgId, payload.ecosystemId); + async credDefEndorsementRequest(payload: { + requestCredDefPayload: RequestCredDeffEndorsement; + orgId: string; + ecosystemId: string; + }): Promise { + return this.ecosystemService.requestCredDeffEndorsement( + payload.requestCredDefPayload, + payload.orgId, + payload.ecosystemId + ); } /** - * - * @param payload - * @returns sign endorsement request - */ + * + * @param payload + * @returns sign endorsement request + */ @MessagePattern({ cmd: 'sign-endorsement-transaction' }) - async signTransaction(payload: { endorsementId: string, ecosystemId: string } - ): Promise { + async signTransaction(payload: { endorsementId: string; ecosystemId: string }): Promise { return this.ecosystemService.signTransaction(payload.endorsementId, payload.ecosystemId); } /** - * - * @param payload - * @returns submit endorsement request - */ + * + * @param payload + * @returns submit endorsement request + */ @MessagePattern({ cmd: 'sumbit-endorsement-transaction' }) - async submitTransaction(payload: { endorsementId: string, ecosystemId: string } - ): Promise { - return this.ecosystemService.submitTransaction(payload.endorsementId, payload.ecosystemId); + async submitTransaction(payload: { endorsementId: string; ecosystemId: string; orgId: string }): Promise { + return this.ecosystemService.submitTransaction({ + endorsementId: payload.endorsementId, + ecosystemId: payload.ecosystemId, + orgId: payload.orgId + }); } /** - * - * @param payload - * @returns auto sign and submit endorsement request - */ + * + * @param payload + * @returns auto sign and submit endorsement request + */ @MessagePattern({ cmd: 'auto-endorsement-transaction' }) async autoSignAndSubmitTransaction(): Promise { return this.ecosystemService.autoSignAndSubmitTransaction(); } /** - * - * @param payload - * @returns Declien Endorsement Transaction status - */ + * + * @param payload + * @returns Declien Endorsement Transaction status + */ @MessagePattern({ cmd: 'decline-endorsement-transaction' }) - async declineEndorsementRequestByLead(payload: { - ecosystemId: string, endorsementId: string - }): Promise { + async declineEndorsementRequestByLead(payload: { ecosystemId: string; endorsementId: string }): Promise { return this.ecosystemService.declineEndorsementRequestByLead(payload.ecosystemId, payload.endorsementId); } - - } diff --git a/apps/ecosystem/src/ecosystem.module.ts b/apps/ecosystem/src/ecosystem.module.ts index 17bec847f..1d26e6c3c 100644 --- a/apps/ecosystem/src/ecosystem.module.ts +++ b/apps/ecosystem/src/ecosystem.module.ts @@ -2,10 +2,14 @@ import { Logger, Module } from '@nestjs/common'; import { EcosystemController } from './ecosystem.controller'; import { EcosystemService } from './ecosystem.service'; import { ClientsModule, Transport } from '@nestjs/microservices'; -import { CommonModule } from '@credebl/common'; +import { CommonModule} from '@credebl/common'; import { EcosystemRepository } from './ecosystem.repository'; import { PrismaService } from '@credebl/prisma-service'; - +import { AgentServiceService } from 'apps/agent-service/src/agent-service.service'; +import { AgentServiceRepository } from 'apps/agent-service/src/repositories/agent-service.repository'; +import { ConnectionService } from 'apps/connection/src/connection.service'; +import { ConnectionRepository } from 'apps/connection/src/connection.repository'; +import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ ClientsModule.register([ @@ -18,9 +22,10 @@ import { PrismaService } from '@credebl/prisma-service'; } ]), - CommonModule + CommonModule, + CacheModule.register() ], controllers: [EcosystemController], - providers: [EcosystemService, PrismaService, Logger, EcosystemRepository] + providers: [EcosystemService, PrismaService, Logger, EcosystemRepository, AgentServiceService, AgentServiceRepository, ConnectionService, ConnectionRepository] }) export class EcosystemModule { } diff --git a/apps/ecosystem/src/ecosystem.repository.ts b/apps/ecosystem/src/ecosystem.repository.ts index 19810f69f..4dae01570 100644 --- a/apps/ecosystem/src/ecosystem.repository.ts +++ b/apps/ecosystem/src/ecosystem.repository.ts @@ -35,7 +35,9 @@ export class EcosystemRepository { description, tags, autoEndorsement, - logoUrl: logo + logoUrl: logo, + createdBy: userId, + lastChangedBy: userId } }); let ecosystemUser; @@ -43,7 +45,9 @@ export class EcosystemRepository { ecosystemUser = await prisma.ecosystem_users.create({ data: { userId: String(userId), - ecosystemId: createdEcosystem.id + ecosystemId: createdEcosystem.id, + createdBy: userId, + lastChangedBy: userId } }); } @@ -62,7 +66,9 @@ export class EcosystemRepository { ecosystemRoleId: ecosystemRoleDetails.id, orgName, orgDid, - deploymentMode: DeploymentModeType.PROVIDER_HOSTED + deploymentMode: DeploymentModeType.PROVIDER_HOSTED, + createdBy: userId, + lastChangedBy: userId } }); } @@ -84,7 +90,7 @@ export class EcosystemRepository { // eslint-disable-next-line camelcase async updateEcosystemById(createEcosystemDto, ecosystemId): Promise { try { - const { name, description, tags, logo, autoEndorsement } = createEcosystemDto; + const { name, description, tags, logo, autoEndorsement, userId } = createEcosystemDto; const editEcosystem = await this.prisma.ecosystem.update({ where: { id: ecosystemId }, data: { @@ -92,7 +98,8 @@ export class EcosystemRepository { description, autoEndorsement, tags, - logoUrl: logo + logoUrl: logo, + lastChangedBy: userId } }); return editEcosystem; @@ -360,7 +367,7 @@ export class EcosystemRepository { // eslint-disable-next-line camelcase async updateEcosystemOrgs(createEcosystemOrgsDto: updateEcosystemOrgsDto): Promise { try { - const { orgId, status, ecosystemRoleId, ecosystemId, orgName, orgDid } = createEcosystemOrgsDto; + const { orgId, status, ecosystemRoleId, ecosystemId, orgName, orgDid, createdBy, lastChangedBy } = createEcosystemOrgsDto; return this.prisma.ecosystem_orgs.create({ data: { @@ -370,7 +377,9 @@ export class EcosystemRepository { ecosystemRoleId, orgName, orgDid, - deploymentMode: DeploymentModeType.PROVIDER_HOSTED + deploymentMode: DeploymentModeType.PROVIDER_HOSTED, + createdBy, + lastChangedBy } }); } catch (error) { @@ -400,7 +409,9 @@ export class EcosystemRepository { userId, ecosystem: { connect: { id: ecosystemId } }, status: EcosystemInvitationStatus.PENDING, - orgId: '' + orgId: '', + createdBy: userId, + lastChangedBy: userId } }); } catch (error) { @@ -747,7 +758,7 @@ export class EcosystemRepository { type: endorsementTransactionType ): Promise { try { - const { endorserDid, authorDid, requestPayload, status, ecosystemOrgId } = schemaTransactionResponse; + const { endorserDid, authorDid, requestPayload, status, ecosystemOrgId, userId } = schemaTransactionResponse; return await this.prisma.endorsement_transaction.create({ data: { endorserDid, @@ -758,7 +769,9 @@ export class EcosystemRepository { responsePayload: '', type, requestBody, - resourceId: '' + resourceId: '', + createdBy: userId, + lastChangedBy: userId } }); } catch (error) { @@ -938,7 +951,7 @@ export class EcosystemRepository { // eslint-disable-next-line camelcase async saveCredDef(credDefResult: saveCredDef): Promise { try { - const { schemaLedgerId, tag, credentialDefinitionId, revocable, createdBy, orgId, schemaId } = credDefResult; + const { schemaLedgerId, tag, credentialDefinitionId, revocable, createdBy, lastChangedBy, orgId, schemaId } = credDefResult; const saveResult = await this.prisma.credential_definition.create({ data: { schemaLedgerId, @@ -946,6 +959,7 @@ export class EcosystemRepository { credentialDefinitionId, revocable, createdBy, + lastChangedBy, orgId, schemaId } diff --git a/apps/ecosystem/src/ecosystem.service.ts b/apps/ecosystem/src/ecosystem.service.ts index 7ec0f4ba5..fc1c14da0 100644 --- a/apps/ecosystem/src/ecosystem.service.ts +++ b/apps/ecosystem/src/ecosystem.service.ts @@ -1,6 +1,15 @@ /* eslint-disable prefer-destructuring */ // eslint-disable-next-line camelcase -import { ConflictException, ForbiddenException, HttpException, Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; +import { + ConflictException, + ForbiddenException, + HttpException, + Inject, + Injectable, + InternalServerErrorException, + Logger, + NotFoundException +} from '@nestjs/common'; import { EcosystemRepository } from './ecosystem.repository'; import { ResponseMessages } from '@credebl/common/response-messages'; import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; @@ -11,25 +20,46 @@ import { EmailDto } from '@credebl/common/dtos/email.dto'; import { sendEmail } from '@credebl/common/send-grid-helper-file'; import { AcceptRejectEcosystemInvitationDto } from '../dtos/accept-reject-ecosysteminvitation.dto'; import { EcosystemConfigSettings, Invitation, OrgAgentType } from '@credebl/enum/enum'; -import { EcosystemOrgStatus, EcosystemRoles, endorsementTransactionStatus, endorsementTransactionType } from '../enums/ecosystem.enum'; +import { + EcosystemOrgStatus, + EcosystemRoles, + endorsementTransactionStatus, + endorsementTransactionType +} from '../enums/ecosystem.enum'; import { FetchInvitationsPayload } from '../interfaces/invitations.interface'; import { EcosystemMembersPayload } from '../interfaces/ecosystemMembers.interface'; -import { CreateEcosystem, CredDefMessage, RequestCredDeffEndorsement, RequestSchemaEndorsement, SaveSchema, SchemaMessage, SignedTransactionMessage, saveCredDef, submitTransactionPayload } from '../interfaces/ecosystem.interfaces'; +import { + CreateEcosystem, + CredDefMessage, + RequestCredDeffEndorsement, + RequestSchemaEndorsement, + SaveSchema, + SchemaMessage, + SignedTransactionMessage, + TransactionPayload, + saveCredDef, + submitTransactionPayload +} from '../interfaces/ecosystem.interfaces'; import { GetAllSchemaList, GetEndorsementsPayload } from '../interfaces/endorsements.interface'; import { CommonConstants } from '@credebl/common/common.constant'; // eslint-disable-next-line camelcase import { credential_definition, org_agents, platform_config, schema, user } from '@prisma/client'; -import { getAgentApiKey } from '@credebl/common/common.service'; - +// import { CommonService } from '@credebl/common/common.service'; +import { updateEcosystemOrgsDto } from '../dtos/update-ecosystemOrgs.dto'; +import { AgentServiceService } from 'apps/agent-service/src/agent-service.service'; +import { Cache } from 'cache-manager'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; @Injectable() export class EcosystemService { constructor( @Inject('NATS_CLIENT') private readonly ecosystemServiceProxy: ClientProxy, private readonly ecosystemRepository: EcosystemRepository, private readonly logger: Logger, - private readonly prisma: PrismaService - - ) { } + private readonly prisma: PrismaService, + // private readonly agentAuthService: AgentAuthService + private readonly agentServiceService: AgentServiceService, + @Inject(CACHE_MANAGER) private cacheService: Cache + ) {} /** * @@ -39,14 +69,15 @@ export class EcosystemService { // eslint-disable-next-line camelcase async createEcosystem(createEcosystemDto: CreateEcosystem): Promise { - const ecosystemExist = await this.ecosystemRepository.checkEcosystemNameExist(createEcosystemDto.name); if (ecosystemExist) { throw new ConflictException(ResponseMessages.ecosystem.error.exists); } - const isMultiEcosystemEnabled = await this.ecosystemRepository.getSpecificEcosystemConfig(EcosystemConfigSettings.MULTI_ECOSYSTEM); + const isMultiEcosystemEnabled = await this.ecosystemRepository.getSpecificEcosystemConfig( + EcosystemConfigSettings.MULTI_ECOSYSTEM + ); if (isMultiEcosystemEnabled && 'false' === isMultiEcosystemEnabled.value) { const ecoOrganizationList = await this.ecosystemRepository.checkEcosystemOrgs(createEcosystemDto.orgId); @@ -64,12 +95,11 @@ export class EcosystemService { return createEcosystem; } - /** - * - * @param editEcosystemDto - * @returns - */ + * + * @param editEcosystemDto + * @returns + */ // eslint-disable-next-line camelcase async editEcosystem(editEcosystemDto, ecosystemId): Promise { @@ -112,9 +142,7 @@ export class EcosystemService { } }; - const ecosystemDetails = await this.ecosystemRepository.fetchEcosystemOrg( - query - ); + const ecosystemDetails = await this.ecosystemRepository.fetchEcosystemOrg(query); const dashboardDetails = { ecosystem: ecosystemDetails['ecosystem'], @@ -135,19 +163,21 @@ export class EcosystemService { } /** - * Description: get an ecosystem invitation - * @returns Get sent ecosystem invitation details - */ + * Description: get an ecosystem invitation + * @returns Get sent ecosystem invitation details + */ // eslint-disable-next-line camelcase - async getEcosystemInvitations(userEmail: string, status: string, pageNumber: number, pageSize: number, search: string): Promise { - + async getEcosystemInvitations( + userEmail: string, + status: string, + pageNumber: number, + pageSize: number, + search: string + ): Promise { try { const query = { - AND: [ - { email: userEmail }, - { status: { contains: search, mode: 'insensitive' } } - ] + AND: [{ email: userEmail }, { status: { contains: search, mode: 'insensitive' } }] }; return await this.ecosystemRepository.getEcosystemInvitationsPagination(query, pageNumber, pageSize); @@ -157,17 +187,15 @@ export class EcosystemService { } } - /** - * - * @param bulkInvitationDto - * @param userId - * @returns + * + * @param bulkInvitationDto + * @param userId + * @returns */ async createInvitation(bulkInvitationDto: BulkSendInvitationDto, userId: string, userEmail: string): Promise { const { invitations, ecosystemId } = bulkInvitationDto; - try { const ecosystemDetails = await this.ecosystemRepository.getEcosystemDetails(ecosystemId); @@ -189,7 +217,6 @@ export class EcosystemService { } return ResponseMessages.ecosystem.success.createInvitation; } catch (error) { - this.logger.error(`In send Invitation : ${JSON.stringify(error)}`); throw new RpcException(error.response ? error.response : error); } @@ -203,17 +230,21 @@ export class EcosystemService { */ async acceptRejectEcosystemInvitations(acceptRejectInvitation: AcceptRejectEcosystemInvitationDto): Promise { try { - const isMultiEcosystemEnabled = await this.ecosystemRepository.getSpecificEcosystemConfig(EcosystemConfigSettings.MULTI_ECOSYSTEM); - if (isMultiEcosystemEnabled - && 'false' === isMultiEcosystemEnabled.value - && acceptRejectInvitation.status !== Invitation.REJECTED) { + const isMultiEcosystemEnabled = await this.ecosystemRepository.getSpecificEcosystemConfig( + EcosystemConfigSettings.MULTI_ECOSYSTEM + ); + if ( + isMultiEcosystemEnabled && + 'false' === isMultiEcosystemEnabled.value && + acceptRejectInvitation.status !== Invitation.REJECTED + ) { const checkOrganization = await this.ecosystemRepository.checkEcosystemOrgs(acceptRejectInvitation.orgId); if (0 < checkOrganization.length) { throw new ConflictException(ResponseMessages.ecosystem.error.ecosystemOrgAlready); - }; + } } - const { orgId, status, invitationId, orgName, orgDid } = acceptRejectInvitation; + const { orgId, status, invitationId, orgName, orgDid, userId } = acceptRejectInvitation; const invitation = await this.ecosystemRepository.getEcosystemInvitationById(invitationId); if (!invitation) { @@ -230,28 +261,43 @@ export class EcosystemService { } const ecosystemRole = await this.ecosystemRepository.getEcosystemRole(EcosystemRoles.ECOSYSTEM_MEMBER); - const updateEcosystemOrgs = await this.updatedEcosystemOrgs(orgId, orgName, orgDid, invitation.ecosystemId, ecosystemRole.id); + const updateEcosystemOrgs = await this.updatedEcosystemOrgs( + orgId, + orgName, + orgDid, + invitation.ecosystemId, + ecosystemRole.id, + userId + ); if (!updateEcosystemOrgs) { throw new NotFoundException(ResponseMessages.ecosystem.error.orgsNotUpdate); } return ResponseMessages.ecosystem.success.invitationAccept; - } catch (error) { this.logger.error(`acceptRejectEcosystemInvitations: ${error}`); throw new RpcException(error.response ? error.response : error); } } - async updatedEcosystemOrgs(orgId: string, orgName: string, orgDid: string, ecosystemId: string, ecosystemRoleId: string): Promise { + async updatedEcosystemOrgs( + orgId: string, + orgName: string, + orgDid: string, + ecosystemId: string, + ecosystemRoleId: string, + userId: string + ): Promise { try { - const data = { + const data: updateEcosystemOrgsDto = { orgId, status: EcosystemOrgStatus.ACTIVE, ecosystemId, ecosystemRoleId, orgName, - orgDid + orgDid, + createdBy: userId, + lastChangedBy: userId }; return await this.ecosystemRepository.updateEcosystemOrgs(data); } catch (error) { @@ -261,19 +307,17 @@ export class EcosystemService { } /** - * - * @param payload + * + * @param payload * @returns Updated invitation response */ async updateEcosystemInvitation(invitationId: string, orgId: string, status: string): Promise { try { - const data = { status, orgId: String(orgId) }; return this.ecosystemRepository.updateEcosystemInvitation(invitationId, data); - } catch (error) { this.logger.error(`In updateOrgInvitation : ${error}`); throw new RpcException(error.response ? error.response : error); @@ -281,17 +325,13 @@ export class EcosystemService { } /** - * - * @param email - * @param ecosystemId + * + * @param email + * @param ecosystemId * @returns Returns boolean status for invitation */ - async checkInvitationExist( - email: string, - ecosystemId: string - ): Promise { + async checkInvitationExist(email: string, ecosystemId: string): Promise { try { - const query = { email, ecosystemId @@ -322,16 +362,12 @@ export class EcosystemService { } /** - * - * @param email - * @param ecosystemName - * @returns Send invitation mail + * + * @param email + * @param ecosystemName + * @returns Send invitation mail */ - async sendInviteEmailTemplate( - email: string, - ecosystemName: string, - isUserExist: boolean - ): Promise { + async sendInviteEmailTemplate(email: string, ecosystemName: string, isUserExist: boolean): Promise { const platformConfigData = await this.prisma.platform_config.findMany(); const urlEmailTemplate = new EcosystemInviteTemplate(); @@ -373,15 +409,25 @@ export class EcosystemService { } /** - * - * @param RequestSchemaEndorsement - * @returns + * + * @param RequestSchemaEndorsement + * @returns */ - async requestSchemaEndorsement(requestSchemaPayload: RequestSchemaEndorsement, orgId: string, ecosystemId: string): Promise { + async requestSchemaEndorsement( + requestSchemaPayload: RequestSchemaEndorsement, + orgId: string, + ecosystemId: string + ): Promise { try { const getEcosystemLeadDetails = await this.ecosystemRepository.getEcosystemLeadDetails(ecosystemId); - const [schemaRequestExist, ecosystemMemberDetails, platformConfig, ecosystemLeadAgentDetails, getEcosystemOrgDetailsByOrgId] = await Promise.all([ + const [ + schemaRequestExist, + ecosystemMemberDetails, + platformConfig, + ecosystemLeadAgentDetails, + getEcosystemOrgDetailsByOrgId + ] = await Promise.all([ this.ecosystemRepository.findRecordsByNameAndVersion(requestSchemaPayload?.name, requestSchemaPayload?.version), this.ecosystemRepository.getAgentDetails(orgId), this.ecosystemRepository.getPlatformConfigDetails(), @@ -410,14 +456,18 @@ export class EcosystemService { } if (!getEcosystemOrgDetailsByOrgId) { - throw new NotFoundException(ResponseMessages.ecosystem.error.ecosystemOrgNotFound); } const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemMemberDetails.orgAgentTypeId); - const url = await this.getAgentUrl(orgAgentType, ecosystemMemberDetails.agentEndPoint, endorsementTransactionType.SCHEMA, ecosystemMemberDetails.tenantId); - const apiKey = await getAgentApiKey(orgId); - const attributeArray = requestSchemaPayload.attributes.map(item => item.attributeName); + const url = await this.getAgentUrl( + orgAgentType, + ecosystemMemberDetails.agentEndPoint, + endorsementTransactionType.SCHEMA, + ecosystemMemberDetails.tenantId + ); + const apiKey = await this.agentServiceService.getOrgAgentApiKey(orgId); + const attributeArray = requestSchemaPayload.attributes.map((item) => item.attributeName); const schemaTransactionPayload = { endorserDid: ecosystemLeadAgentDetails.orgDid, @@ -428,42 +478,60 @@ export class EcosystemService { issuerId: ecosystemMemberDetails.orgDid }; - const schemaTransactionRequest: SchemaMessage = await this._requestSchemaEndorsement(schemaTransactionPayload, url, apiKey); + const schemaTransactionRequest: SchemaMessage = await this._requestSchemaEndorsement( + schemaTransactionPayload, + url, + apiKey + ); const schemaTransactionResponse = { endorserDid: ecosystemLeadAgentDetails.orgDid, authorDid: ecosystemMemberDetails.orgDid, requestPayload: schemaTransactionRequest.message.schemaState.schemaRequest, status: endorsementTransactionStatus.REQUESTED, - ecosystemOrgId: getEcosystemOrgDetailsByOrgId.id + ecosystemOrgId: getEcosystemOrgDetailsByOrgId.id, + userId: requestSchemaPayload.userId }; - if ('failed' === schemaTransactionRequest.message.schemaState.state) { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.requestSchemaTransaction); } - return this.ecosystemRepository.storeTransactionRequest(schemaTransactionResponse, requestSchemaPayload, endorsementTransactionType.SCHEMA); + return this.ecosystemRepository.storeTransactionRequest( + schemaTransactionResponse, + requestSchemaPayload, + endorsementTransactionType.SCHEMA + ); } catch (error) { this.logger.error(`In request schema endorsement : ${JSON.stringify(error)}`); if (error && error?.status && error?.status?.message && error?.status?.message?.error) { throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, + message: error?.status?.message?.error?.reason + ? error?.status?.message?.error?.reason + : error?.status?.message?.error, statusCode: error?.status?.code }); - } else { throw new RpcException(error.response ? error.response : error); } } } - async requestCredDeffEndorsement(requestCredDefPayload: RequestCredDeffEndorsement, orgId: string, ecosystemId: string): Promise { + async requestCredDeffEndorsement( + requestCredDefPayload: RequestCredDeffEndorsement, + orgId: string, + ecosystemId: string + ): Promise { try { - const getEcosystemLeadDetails = await this.ecosystemRepository.getEcosystemLeadDetails(ecosystemId); - const [credDefRequestExist, ecosystemMemberDetails, platformConfig, ecosystemLeadAgentDetails, getEcosystemOrgDetailsByOrgId] = await Promise.all([ + const [ + credDefRequestExist, + ecosystemMemberDetails, + platformConfig, + ecosystemLeadAgentDetails, + getEcosystemOrgDetailsByOrgId + ] = await Promise.all([ this.ecosystemRepository.findRecordsByCredDefTag(requestCredDefPayload?.tag), this.ecosystemRepository.getAgentDetails(orgId), this.ecosystemRepository.getPlatformConfigDetails(), @@ -496,8 +564,13 @@ export class EcosystemService { } const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemMemberDetails.orgAgentTypeId); - const url = await this.getAgentUrl(orgAgentType, ecosystemMemberDetails.agentEndPoint, endorsementTransactionType.CREDENTIAL_DEFINITION, ecosystemMemberDetails.tenantId); - const apiKey = await getAgentApiKey(orgId); + const url = await this.getAgentUrl( + orgAgentType, + ecosystemMemberDetails.agentEndPoint, + endorsementTransactionType.CREDENTIAL_DEFINITION, + ecosystemMemberDetails.tenantId + ); + const apiKey = await this.agentServiceService.getOrgAgentApiKey(orgId); const credDefTransactionPayload = { endorserDid: ecosystemLeadAgentDetails.orgDid, endorse: requestCredDefPayload.endorse, @@ -506,7 +579,11 @@ export class EcosystemService { issuerId: ecosystemMemberDetails.orgDid }; - const credDefTransactionRequest: CredDefMessage = await this._requestCredDeffEndorsement(credDefTransactionPayload, url, apiKey); + const credDefTransactionRequest: CredDefMessage = await this._requestCredDeffEndorsement( + credDefTransactionPayload, + url, + apiKey + ); if ('failed' === credDefTransactionRequest.message.credentialDefinitionState.state) { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.requestCredDefTransaction); @@ -524,32 +601,39 @@ export class EcosystemService { authorDid: ecosystemMemberDetails.orgDid, requestPayload: credDefTransactionRequest.message.credentialDefinitionState.credentialDefinitionRequest, status: endorsementTransactionStatus.REQUESTED, - ecosystemOrgId: getEcosystemOrgDetailsByOrgId.id + ecosystemOrgId: getEcosystemOrgDetailsByOrgId.id, + userId: requestCredDefPayload.userId }; - return this.ecosystemRepository.storeTransactionRequest(schemaTransactionResponse, requestCredDefPayload, endorsementTransactionType.CREDENTIAL_DEFINITION); + return this.ecosystemRepository.storeTransactionRequest( + schemaTransactionResponse, + requestCredDefPayload, + endorsementTransactionType.CREDENTIAL_DEFINITION + ); } catch (error) { this.logger.error(`In request cred-def endorsement: ${JSON.stringify(error)}`); if (error && error?.status && error?.status?.message && error?.status?.message?.error) { throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, + message: error?.status?.message?.error?.reason + ? error?.status?.message?.error?.reason + : error?.status?.message?.error, statusCode: error?.status?.code }); - } else { throw new RpcException(error.response ? error.response : error); } } } - - async getInvitationsByEcosystemId( - payload: FetchInvitationsPayload - ): Promise { + async getInvitationsByEcosystemId(payload: FetchInvitationsPayload): Promise { try { - const { ecosystemId, pageNumber, pageSize, search } = payload; - const ecosystemInvitations = await this.ecosystemRepository.getInvitationsByEcosystemId(ecosystemId, pageNumber, pageSize, search); + const ecosystemInvitations = await this.ecosystemRepository.getInvitationsByEcosystemId( + ecosystemId, + pageNumber, + pageSize, + search + ); return ecosystemInvitations; } catch (error) { this.logger.error(`In getInvitationsByEcosystemId : ${JSON.stringify(error)}`); @@ -567,10 +651,13 @@ export class EcosystemService { return { message }; } catch (error) { this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException({ - status: error.status, - error: error.message - }, error.status); + throw new HttpException( + { + status: error.status, + error: error.message + }, + error.status + ); } } @@ -584,10 +671,13 @@ export class EcosystemService { return { message }; } catch (error) { this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException({ - status: error.status, - error: error.message - }, error.status); + throw new HttpException( + { + status: error.status, + error: error.message + }, + error.status + ); } } @@ -618,8 +708,19 @@ export class EcosystemService { } const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemLeadAgentDetails?.orgAgentTypeId); - const url = await this.getAgentUrl(orgAgentType, ecosystemLeadAgentDetails.agentEndPoint, endorsementTransactionType.SIGN, ecosystemLeadAgentDetails?.tenantId); - const apiKey = await getAgentApiKey(ecosystemLeadDetails.orgId); + const url = await this.getAgentUrl( + orgAgentType, + ecosystemLeadAgentDetails.agentEndPoint, + endorsementTransactionType.SIGN, + ecosystemLeadAgentDetails?.tenantId + ); + // const apiKey = await this.agentServiceService.getOrgAgentApiKey(ecosystemLeadDetails.orgId); + // const apiKey = await this._getOrgAgentApiKey(ecosystemLeadDetails.orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(ecosystemLeadDetails.orgId); + } const jsonString = endorsementTransactionPayload.requestPayload.toString(); const payload = { transaction: jsonString, @@ -633,20 +734,26 @@ export class EcosystemService { } const ecosystemDetails = await this.ecosystemRepository.getEcosystemDetails(ecosystemId); - + if (!ecosystemDetails) { throw new NotFoundException(ResponseMessages.ecosystem.error.ecosystemNotFound); } - const updateSignedTransaction = await this.ecosystemRepository.updateTransactionDetails(endorsementId, schemaTransactionRequest.message.signedTransaction); + const updateSignedTransaction = await this.ecosystemRepository.updateTransactionDetails( + endorsementId, + schemaTransactionRequest.message.signedTransaction + ); if (!updateSignedTransaction) { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.updateTransactionError); } if (updateSignedTransaction && true === ecosystemDetails.autoEndorsement) { - - const submitTxn = await this.submitTransaction(endorsementId, ecosystemId, ecosystemLeadAgentDetails.agentEndPoint); + const submitTxn = await this.submitTransaction({ + endorsementId, + ecosystemId, + ecosystemLeadAgentEndPoint: ecosystemLeadAgentDetails.agentEndPoint + }); if (!submitTxn) { await this.ecosystemRepository.updateTransactionStatus(endorsementId, endorsementTransactionStatus.REQUESTED); throw new InternalServerErrorException(ResponseMessages.ecosystem.error.sumbitTransaction); @@ -659,10 +766,11 @@ export class EcosystemService { this.logger.error(`In sign transaction: ${JSON.stringify(error)}`); if (error && error?.status && error?.status?.message && error?.status?.message?.error) { throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, + message: error?.status?.message?.error?.reason + ? error?.status?.message?.error?.reason + : error?.status?.message?.error, statusCode: error?.status?.code }); - } else { throw new RpcException(error.response ? error.response : error); } @@ -670,12 +778,10 @@ export class EcosystemService { } /** - * - * @returns Ecosystem members list - */ - async getEcoystemMembers( - payload: EcosystemMembersPayload - ): Promise { + * + * @returns Ecosystem members list + */ + async getEcoystemMembers(payload: EcosystemMembersPayload): Promise { try { const { ecosystemId, pageNumber, pageSize, search } = payload; return await this.ecosystemRepository.findEcosystemMembers(ecosystemId, pageNumber, pageSize, search); @@ -688,18 +794,17 @@ export class EcosystemService { async deleteEcosystemInvitations(invitationId: string): Promise { try { return await this.ecosystemRepository.deleteInvitations(invitationId); - } catch (error) { this.logger.error(`In error deleteEcosystemInvitation: ${JSON.stringify(error)}`); throw new RpcException(error.response ? error.response : error); } } /** - * Description: Store shortening URL - * @param signEndorsementPayload - * @param url - * @returns sign message - */ + * Description: Store shortening URL + * @param signEndorsementPayload + * @param url + * @returns sign message + */ async _signTransaction(signEndorsementPayload: object, url: string, apiKey: string): Promise { const pattern = { cmd: 'agent-sign-transaction' }; const payload = { signEndorsementPayload, url, apiKey }; @@ -710,10 +815,13 @@ export class EcosystemService { return { message }; } catch (error) { this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException({ - status: error.status, - error: error.message - }, error.status); + throw new HttpException( + { + status: error.status, + error: error.message + }, + error.status + ); } } @@ -734,7 +842,11 @@ export class EcosystemService { return this.ecosystemRepository.getPlatformConfigDetails(); } - async submitTransactionPayload(endorsementTransactionPayload, ecosystemMemberDetails, ecosystemLeadAgentDetails): Promise { + async submitTransactionPayload( + endorsementTransactionPayload, + ecosystemMemberDetails, + ecosystemLeadAgentDetails + ): Promise { const parsedRequestPayload = JSON.parse(endorsementTransactionPayload.responsePayload); const jsonString = endorsementTransactionPayload.responsePayload.toString(); const payload: submitTransactionPayload = { @@ -750,7 +862,6 @@ export class EcosystemService { issuerId: ecosystemMemberDetails.orgDid }; } else if (endorsementTransactionPayload.type === endorsementTransactionType.CREDENTIAL_DEFINITION) { - payload.credentialDefinition = { tag: parsedRequestPayload.operation.tag, issuerId: ecosystemMemberDetails.orgDid, @@ -763,7 +874,11 @@ export class EcosystemService { return payload; } - async handleSchemaSubmission(endorsementTransactionPayload, ecosystemMemberDetails, submitTransactionRequest): Promise { + async handleSchemaSubmission( + endorsementTransactionPayload, + ecosystemMemberDetails, + submitTransactionRequest + ): Promise { const regex = /[^:]+$/; const match = ecosystemMemberDetails.orgDid.match(regex); let extractedDidValue; @@ -771,7 +886,6 @@ export class EcosystemService { if (match) { // eslint-disable-next-line prefer-destructuring extractedDidValue = match[0]; - } const saveSchemaPayload: SaveSchema = { name: endorsementTransactionPayload.requestBody['name'], @@ -793,8 +907,15 @@ export class EcosystemService { } // eslint-disable-next-line camelcase - async handleCredDefSubmission(endorsementTransactionPayload, ecosystemMemberDetails, submitTransactionRequest): Promise { - const schemaDetails = await this.ecosystemRepository.getSchemaDetailsById(endorsementTransactionPayload.requestBody['schemaId']); + async handleCredDefSubmission( + endorsementTransactionPayload, + ecosystemMemberDetails, + submitTransactionRequest + // eslint-disable-next-line camelcase + ): Promise { + const schemaDetails = await this.ecosystemRepository.getSchemaDetailsById( + endorsementTransactionPayload.requestBody['schemaId'] + ); if (!schemaDetails) { throw new NotFoundException(ResponseMessages.ecosystem.error.schemaNotFound); @@ -806,6 +927,7 @@ export class EcosystemService { credentialDefinitionId: submitTransactionRequest['message'].credentialDefinitionId, revocable: false, createdBy: endorsementTransactionPayload.ecosystemOrgs.orgId, + lastChangedBy: endorsementTransactionPayload.ecosystemOrgs.orgId, orgId: ecosystemMemberDetails.orgId, schemaId: schemaDetails.id }; @@ -821,9 +943,13 @@ export class EcosystemService { return this.ecosystemRepository.updateTransactionStatus(endorsementId, endorsementTransactionStatus.SUBMITED); } - async submitTransaction(endorsementId, ecosystemId, ecosystemLeadAgentEndPoint?): Promise { + async submitTransaction(transactionPayload: TransactionPayload): Promise { try { - const endorsementTransactionPayload = await this.ecosystemRepository.getEndorsementTransactionById(endorsementId, endorsementTransactionStatus.SIGNED); + const { endorsementId, ecosystemId, ecosystemLeadAgentEndPoint, orgId} = transactionPayload; + const endorsementTransactionPayload = await this.ecosystemRepository.getEndorsementTransactionById( + endorsementId, + endorsementTransactionStatus.SIGNED + ); if (!endorsementTransactionPayload) { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.invalidTransaction); } @@ -834,14 +960,29 @@ export class EcosystemService { const ecosystemMemberDetails = await this.getEcosystemMemberDetails(endorsementTransactionPayload); const ecosystemLeadAgentDetails = await this.getEcosystemLeadAgentDetails(ecosystemId); - - const agentEndPoint = ecosystemLeadAgentEndPoint ? ecosystemLeadAgentEndPoint : ecosystemMemberDetails.agentEndPoint; + const agentEndPoint = ecosystemLeadAgentEndPoint + ? ecosystemLeadAgentEndPoint + : ecosystemMemberDetails.agentEndPoint; const orgAgentType = await this.ecosystemRepository.getOrgAgentType(ecosystemMemberDetails?.orgAgentTypeId); - const url = await this.getAgentUrl(orgAgentType, agentEndPoint, endorsementTransactionType.SUBMIT, ecosystemMemberDetails?.tenantId); - const payload = await this.submitTransactionPayload(endorsementTransactionPayload, ecosystemMemberDetails, ecosystemLeadAgentDetails); - const apiKey = await getAgentApiKey(endorsementTransactionPayload.ecosystemOrgs.orgId); + const url = await this.getAgentUrl( + orgAgentType, + agentEndPoint, + endorsementTransactionType.SUBMIT, + ecosystemMemberDetails?.tenantId + ); + const payload = await this.submitTransactionPayload( + endorsementTransactionPayload, + ecosystemMemberDetails, + ecosystemLeadAgentDetails + ); + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const submitTransactionRequest = await this._submitTransaction(payload, url, apiKey); if ('failed' === submitTransactionRequest['message'].state) { @@ -851,59 +992,71 @@ export class EcosystemService { await this.updateTransactionStatus(endorsementId); if (endorsementTransactionPayload.type === endorsementTransactionType.SCHEMA) { - - const updateSchemaId = await this._updateResourceId(endorsementId, endorsementTransactionType.SCHEMA, submitTransactionRequest); + const updateSchemaId = await this._updateResourceId( + endorsementId, + endorsementTransactionType.SCHEMA, + submitTransactionRequest + ); if (!updateSchemaId) { - throw new InternalServerErrorException(ResponseMessages.ecosystem.error.updateSchemaId); } - return this.handleSchemaSubmission(endorsementTransactionPayload, ecosystemMemberDetails, submitTransactionRequest); + return this.handleSchemaSubmission( + endorsementTransactionPayload, + ecosystemMemberDetails, + submitTransactionRequest + ); } else if (endorsementTransactionPayload.type === endorsementTransactionType.CREDENTIAL_DEFINITION) { - if ('undefined' === submitTransactionRequest['message'].credentialDefinitionId.split(':')[3]) { - const ecosystemDetails = await this.ecosystemRepository.getEcosystemDetails(ecosystemId); if (true === ecosystemDetails.autoEndorsement) { - - await this.ecosystemRepository.updateTransactionStatus(endorsementId, endorsementTransactionStatus.REQUESTED); + await this.ecosystemRepository.updateTransactionStatus( + endorsementId, + endorsementTransactionStatus.REQUESTED + ); } else { - await this.ecosystemRepository.updateTransactionStatus(endorsementId, endorsementTransactionStatus.SIGNED); } throw new InternalServerErrorException(ResponseMessages.ecosystem.error.sumbitTransaction); } - const updateCredDefId = await this._updateResourceId(endorsementId, endorsementTransactionType.CREDENTIAL_DEFINITION, submitTransactionRequest); + const updateCredDefId = await this._updateResourceId( + endorsementId, + endorsementTransactionType.CREDENTIAL_DEFINITION, + submitTransactionRequest + ); if (!updateCredDefId) { - throw new InternalServerErrorException(ResponseMessages.ecosystem.error.updateCredDefId); } - return this.handleCredDefSubmission(endorsementTransactionPayload, ecosystemMemberDetails, submitTransactionRequest); + return this.handleCredDefSubmission( + endorsementTransactionPayload, + ecosystemMemberDetails, + submitTransactionRequest + ); } } catch (error) { this.logger.error(`In submit transaction: ${JSON.stringify(error)}`); if (error && error?.status && error?.status?.message && error?.status?.message?.error) { throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, + message: error?.status?.message?.error?.reason + ? error?.status?.message?.error?.reason + : error?.status?.message?.error, statusCode: error?.status?.code }); - } else { throw new RpcException(error.response ? error.response : error); } } } - /** - * Description: Store shortening URL - * @param signEndorsementPayload - * @param url - * @returns sign message - */ + * Description: Store shortening URL + * @param signEndorsementPayload + * @param url + * @returns sign message + */ async _submitTransaction(submitEndorsementPayload: object, url: string, apiKey: string): Promise { const pattern = { cmd: 'agent-submit-transaction' }; const payload = { submitEndorsementPayload, url, apiKey }; @@ -914,14 +1067,21 @@ export class EcosystemService { return { message }; } catch (error) { this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException({ - status: error.status, - error: error.message - }, error.status); + throw new HttpException( + { + status: error.status, + error: error.message + }, + error.status + ); } } - async _updateResourceId(endorsementId: string, transactionType: endorsementTransactionType, transactionDetails: object): Promise { + async _updateResourceId( + endorsementId: string, + transactionType: endorsementTransactionType, + transactionDetails: object + ): Promise { try { // eslint-disable-next-line prefer-destructuring const message = transactionDetails['message']; @@ -929,10 +1089,15 @@ export class EcosystemService { throw new InternalServerErrorException(ResponseMessages.ecosystem.error.invalidMessage); } - const resourceId = message[transactionType === endorsementTransactionType.SCHEMA ? 'schemaId' : 'credentialDefinitionId']; + const resourceId = + message[transactionType === endorsementTransactionType.SCHEMA ? 'schemaId' : 'credentialDefinitionId']; if (!resourceId) { - throw new Error(`${ResponseMessages.ecosystem.error.invalidTransactionMessage} Missing "${transactionType === endorsementTransactionType.SCHEMA ? 'schemaId' : 'credentialDefinitionId'}" property.`); + throw new Error( + `${ResponseMessages.ecosystem.error.invalidTransactionMessage} Missing "${ + transactionType === endorsementTransactionType.SCHEMA ? 'schemaId' : 'credentialDefinitionId' + }" property.` + ); } return await this.ecosystemRepository.updateResourse(endorsementId, resourceId); @@ -941,13 +1106,7 @@ export class EcosystemService { } } - - async getAgentUrl( - orgAgentTypeId: string, - agentEndPoint: string, - type: string, - tenantId?: string - ): Promise { + async getAgentUrl(orgAgentTypeId: string, agentEndPoint: string, type: string, tenantId?: string): Promise { try { let url; @@ -989,34 +1148,26 @@ export class EcosystemService { } } - async fetchEcosystemOrg( - payload: { ecosystemId: string, orgId: string } - ): Promise { - + async fetchEcosystemOrg(payload: { ecosystemId: string; orgId: string }): Promise { const isEcosystemEnabled = await this.checkEcosystemEnableFlag(); if (!isEcosystemEnabled) { throw new ForbiddenException(ResponseMessages.ecosystem.error.ecosystemNotEnabled); } - return this.ecosystemRepository.fetchEcosystemOrg( - payload - ); + return this.ecosystemRepository.fetchEcosystemOrg(payload); } /** - * + * * @returns Returns ecosystem flag from settings */ - async checkEcosystemEnableFlag( - ): Promise { - const ecosystemDetails = await this.prisma.ecosystem_config.findFirst( - { - where: { - key: 'enableEcosystem' - } + async checkEcosystemEnableFlag(): Promise { + const ecosystemDetails = await this.prisma.ecosystem_config.findFirst({ + where: { + key: 'enableEcosystem' } - ); + }); if ('true' === ecosystemDetails.value) { return true; @@ -1028,7 +1179,6 @@ export class EcosystemService { async getEndorsementTransactions(payload: GetEndorsementsPayload): Promise { const { ecosystemId, orgId, pageNumber, pageSize, search, type } = payload; try { - const queryEcoOrgs = { ecosystemId, orgId @@ -1061,13 +1211,11 @@ export class EcosystemService { } } - async getAllEcosystemSchemas(ecosystemSchemas: GetAllSchemaList): Promise { try { - const response = await this.ecosystemRepository.getAllEcosystemSchemasDetails(ecosystemSchemas); this.logger.error(`In error getAllEcosystemSchemas1: ${JSON.stringify(response)}`); - const schemasDetails = response?.schemasResult.map(schemaAttributeItem => { + const schemasDetails = response?.schemasResult.map((schemaAttributeItem) => { const attributes = JSON.parse(schemaAttributeItem.attributes); return { ...schemaAttributeItem, attributes }; }); @@ -1090,12 +1238,11 @@ export class EcosystemService { } /** - * @returns EndorsementTransaction Status message - */ + * @returns EndorsementTransaction Status message + */ async autoSignAndSubmitTransaction(): Promise { try { - return await this.ecosystemRepository.updateAutoSignAndSubmitTransaction(); } catch (error) { this.logger.error(`error in decline endorsement request: ${error}`); @@ -1104,16 +1251,15 @@ export class EcosystemService { } /** - * - * @param ecosystemId - * @param endorsementId - * @param orgId - * @returns EndorsementTransactionRequest Status message - */ + * + * @param ecosystemId + * @param endorsementId + * @param orgId + * @returns EndorsementTransactionRequest Status message + */ async declineEndorsementRequestByLead(ecosystemId: string, endorsementId: string): Promise { try { - return await this.ecosystemRepository.updateEndorsementRequestStatus(ecosystemId, endorsementId); } catch (error) { this.logger.error(`error in decline endorsement request: ${error}`); @@ -1121,4 +1267,21 @@ export class EcosystemService { } } + + async _getOrgAgentApiKey(orgId: string): Promise { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = { orgId }; + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const message = await this.ecosystemServiceProxy.send(pattern, payload).toPromise(); + return message; + } catch (error) { + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException({ + status: error.status, + error: error.message + }, error.status); + } + } } diff --git a/apps/issuance/interfaces/issuance.interfaces.ts b/apps/issuance/interfaces/issuance.interfaces.ts index 5f564afff..3b1804b5b 100644 --- a/apps/issuance/interfaces/issuance.interfaces.ts +++ b/apps/issuance/interfaces/issuance.interfaces.ts @@ -101,4 +101,12 @@ export interface FileUploadData { error?: string; detailError?: string; jobId: string; +} + +export interface ClientDetails { + + clientId: string; + + userId?: string; + } \ No newline at end of file diff --git a/apps/issuance/src/issuance.controller.ts b/apps/issuance/src/issuance.controller.ts index bb8ffb649..e538fe2c4 100644 --- a/apps/issuance/src/issuance.controller.ts +++ b/apps/issuance/src/issuance.controller.ts @@ -1,6 +1,6 @@ import { Controller, Logger } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; -import { IIssuance, IIssuanceWebhookInterface, IIssueCredentials, IIssueCredentialsDefinitions, ImportFileDetails, OutOfBandCredentialOffer, PreviewRequest } from '../interfaces/issuance.interfaces'; +import { ClientDetails, IIssuance, IIssuanceWebhookInterface, IIssueCredentials, IIssueCredentialsDefinitions, ImportFileDetails, OutOfBandCredentialOffer, PreviewRequest } from '../interfaces/issuance.interfaces'; import { IssuanceService } from './issuance.service'; @Controller() @@ -87,8 +87,8 @@ export class IssuanceController { @MessagePattern({ cmd: 'issue-bulk-credentials' }) - async issueBulkCredentials(payload: { requestId: string, orgId: string, clientId: string }): Promise { - return this.issuanceService.issueBulkCredential(payload.requestId, payload.orgId, payload.clientId); + async issueBulkCredentials(payload: { requestId: string, orgId: string, clientDetails: ClientDetails }): Promise { + return this.issuanceService.issueBulkCredential(payload.requestId, payload.orgId, payload.clientDetails); } @MessagePattern({ cmd: 'retry-bulk-credentials' }) diff --git a/apps/issuance/src/issuance.repository.ts b/apps/issuance/src/issuance.repository.ts index 23cd07404..f9faeab40 100644 --- a/apps/issuance/src/issuance.repository.ts +++ b/apps/issuance/src/issuance.repository.ts @@ -56,7 +56,7 @@ export class IssuanceRepository { threadId }, update: { - lastChangedBy: `${orgId}`, + lastChangedBy: orgId, createDateTime, threadId, protocolVersion, @@ -65,7 +65,8 @@ export class IssuanceRepository { }, create: { createDateTime, - lastChangedBy: `${orgId}`, + lastChangedBy: orgId, + createdBy: orgId, connectionId, threadId, protocolVersion, @@ -199,7 +200,7 @@ export class IssuanceRepository { } } - async saveFileUploadDetails(fileUploadPayload): Promise { + async saveFileUploadDetails(fileUploadPayload, userId: string): Promise { try { const { name, status, upload_type, orgId } = fileUploadPayload; return this.prisma.file_upload.create({ @@ -207,7 +208,9 @@ export class IssuanceRepository { name: String(name), orgId: String(orgId), status, - upload_type + upload_type, + createdBy: userId, + lastChangedBy: userId } }); @@ -394,7 +397,7 @@ export class IssuanceRepository { } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-unused-vars - async saveFileDetails(fileData) { + async saveFileDetails(fileData, userId: string) { try { const { credential_data, schemaId, credDefId, status, isError, fileUploadId } = fileData; return this.prisma.file_data.create({ @@ -404,7 +407,9 @@ export class IssuanceRepository { credDefId, status, fileUploadId, - isError + isError, + createdBy: userId, + lastChangedBy: userId } }); diff --git a/apps/issuance/src/issuance.service.ts b/apps/issuance/src/issuance.service.ts index bb8870085..1013facb9 100644 --- a/apps/issuance/src/issuance.service.ts +++ b/apps/issuance/src/issuance.service.ts @@ -8,9 +8,9 @@ import { CommonConstants } from '@credebl/common/common.constant'; import { ResponseMessages } from '@credebl/common/response-messages'; import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs'; -import { FileUploadData, ICredentialAttributesInterface, ImportFileDetails, OutOfBandCredentialOfferPayload, PreviewRequest, SchemaDetails } from '../interfaces/issuance.interfaces'; +import { ClientDetails, FileUploadData, ICredentialAttributesInterface, ImportFileDetails, OutOfBandCredentialOfferPayload, PreviewRequest, SchemaDetails } from '../interfaces/issuance.interfaces'; import { OrgAgentType } from '@credebl/enum/enum'; -import { platform_config } from '@prisma/client'; +// import { platform_config } from '@prisma/client'; import * as QRCode from 'qrcode'; import { OutOfBandIssuance } from '../templates/out-of-band-issuance.template'; import { EmailDto } from '@credebl/common/dtos/email.dto'; @@ -29,6 +29,7 @@ import { FileUploadStatus, FileUploadType } from 'apps/api-gateway/src/enum'; import { AwsService } from '@credebl/aws'; import { io } from 'socket.io-client'; + @Injectable() export class IssuanceService { private readonly logger = new Logger('IssueCredentialService'); @@ -40,15 +41,15 @@ export class IssuanceService { private readonly outOfBandIssuance: OutOfBandIssuance, private readonly emailData: EmailDto, private readonly awsService: AwsService, - @InjectQueue('bulk-issuance') private bulkIssuanceQueue: Queue - + @InjectQueue('bulk-issuance') private bulkIssuanceQueue: Queue, + @Inject(CACHE_MANAGER) private cacheService: Cache ) { } async sendCredentialCreateOffer(orgId: string, user: IUserRequest, credentialDefinitionId: string, comment: string, connectionId: string, attributes: object[]): Promise { try { const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); - const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); + // const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); const { agentEndPoint } = agentDetails; if (!agentDetails) { @@ -59,7 +60,14 @@ export class IssuanceService { const issuanceMethodLabel = 'create-offer'; const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId); - const apiKey = platformConfig?.sgApiKey; + // const apiKey = platformConfig?.sgApiKey; + // let apiKey = await this._getOrgAgentApiKey(orgId); + + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const issueData = { protocolVersion: 'v1', connectionId, @@ -95,7 +103,7 @@ export class IssuanceService { try { const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); // eslint-disable-next-line camelcase - const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); + // const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); const { agentEndPoint } = agentDetails; if (!agentDetails) { @@ -106,7 +114,15 @@ export class IssuanceService { const issuanceMethodLabel = 'create-offer-oob'; const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId); - const apiKey = platformConfig?.sgApiKey; + // const apiKey = platformConfig?.sgApiKey; + + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } + const issueData = { connectionId, credentialFormats: { @@ -177,7 +193,7 @@ export class IssuanceService { async getIssueCredentials(user: IUserRequest, threadId: string, connectionId: string, state: string, orgId: string): Promise { try { const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); - const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); + // const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); const { agentEndPoint } = agentDetails; if (!agentDetails) { @@ -200,7 +216,13 @@ export class IssuanceService { url = `${url + appendParams + element}=${params[element]}`; } }); - const apiKey = platformConfig?.sgApiKey; + // const apiKey = platformConfig?.sgApiKey; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const issueCredentialsDetails = await this._getIssueCredentials(url, apiKey); return issueCredentialsDetails?.response; } catch (error) { @@ -234,7 +256,7 @@ export class IssuanceService { try { const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); - const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); + // const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); const { agentEndPoint } = agentDetails; if (!agentDetails) { @@ -245,7 +267,13 @@ export class IssuanceService { const issuanceMethodLabel = 'get-issue-credential-by-credential-id'; const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId, credentialRecordId); - const apiKey = platformConfig?.sgApiKey; + // const apiKey = platformConfig?.sgApiKey; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const createConnectionInvitation = await this._getIssueCredentialsbyCredentialRecordId(url, apiKey); return createConnectionInvitation?.response; } catch (error) { @@ -316,7 +344,13 @@ export class IssuanceService { throw new NotFoundException(ResponseMessages.issuance.error.organizationNotFound); } - const { apiKey } = agentDetails; + // const { apiKey } = agentDetails; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const errors = []; const emailPromises = []; @@ -738,7 +772,7 @@ export class IssuanceService { return new Promise(resolve => setTimeout(resolve, ms)); } - async issueBulkCredential(requestId: string, orgId: string, clientId: string): Promise { + async issueBulkCredential(requestId: string, orgId: string, clientDetails: ClientDetails): Promise { const fileUpload: { lastChangedDateTime: Date; name?: string; @@ -780,7 +814,7 @@ export class IssuanceService { fileUpload.name = parsedPrimeDetails.fileName; } - respFileUpload = await this.issuanceRepository.saveFileUploadDetails(fileUpload); + respFileUpload = await this.issuanceRepository.saveFileUploadDetails(fileUpload, clientDetails.userId); const saveFileDetailsPromises = parsedData.map(async (element) => { const credentialPayload = { @@ -791,7 +825,7 @@ export class IssuanceService { isError: false, fileUploadId: respFileUpload.id }; - return this.issuanceRepository.saveFileDetails(credentialPayload); + return this.issuanceRepository.saveFileDetails(credentialPayload, clientDetails.userId); }); // Wait for all saveFileDetails operations to complete @@ -808,7 +842,7 @@ export class IssuanceService { const payload = { data: element.credential_data, fileUploadId: element.fileUploadId, - clientId, + clientId: clientDetails.clientId, cacheId: requestId, credentialDefinitionId: element.credDefId, schemaLedgerId: element.schemaId, @@ -871,6 +905,9 @@ export class IssuanceService { await this.delay(500); // Wait for 0.5 secends this.processIssuanceData(payload); + if (0 === respFile.length) { + return FileUploadStatus.completed; + } } catch (error) { // Handle errors if needed this.logger.error(`Error processing issuance data: ${error}`); @@ -1038,4 +1075,16 @@ export class IssuanceService { } } + async _getOrgAgentApiKey(orgId: string): Promise { + try { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = {orgId }; + const message = await this.natsCall(pattern, payload); + return String(message); + } catch (error) { + this.logger.error(`[_getOrgAgentApiKey] [NATS call]- error in getOrgApiKey : ${JSON.stringify(error)}`); + throw error; + } + } + } diff --git a/apps/ledger/src/credential-definition/credential-definition.module.ts b/apps/ledger/src/credential-definition/credential-definition.module.ts index 11d80f2e4..82a47b1bb 100644 --- a/apps/ledger/src/credential-definition/credential-definition.module.ts +++ b/apps/ledger/src/credential-definition/credential-definition.module.ts @@ -7,7 +7,7 @@ import { CredentialDefinitionRepository } from './repositories/credential-defini import { CredentialDefinitionService } from './credential-definition.service'; import { HttpModule } from '@nestjs/axios'; import { PrismaService } from '@credebl/prisma-service'; - +import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ ClientsModule.register([ @@ -20,7 +20,8 @@ import { PrismaService } from '@credebl/prisma-service'; } ]), HttpModule, - CommonModule + CommonModule, + CacheModule.register() ], providers: [ CredentialDefinitionService, diff --git a/apps/ledger/src/credential-definition/credential-definition.service.ts b/apps/ledger/src/credential-definition/credential-definition.service.ts index 418a2ab5b..9364f6286 100644 --- a/apps/ledger/src/credential-definition/credential-definition.service.ts +++ b/apps/ledger/src/credential-definition/credential-definition.service.ts @@ -15,12 +15,15 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { CreateCredDefAgentRedirection, CredDefSchema, GetCredDefAgentRedirection } from './interfaces/credential-definition.interface'; import { map } from 'rxjs/operators'; import { OrgAgentType } from '@credebl/enum/enum'; - +import { Cache } from 'cache-manager'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; +import { CommonConstants } from '@credebl/common/common.constant'; @Injectable() export class CredentialDefinitionService extends BaseService { constructor( private readonly credentialDefinitionRepository: CredentialDefinitionRepository, - @Inject('NATS_CLIENT') private readonly credDefServiceProxy: ClientProxy + @Inject('NATS_CLIENT') private readonly credDefServiceProxy: ClientProxy, + @Inject(CACHE_MANAGER) private cacheService: Cache ) { super('CredentialDefinitionService'); @@ -33,7 +36,12 @@ export class CredentialDefinitionService extends BaseService { // eslint-disable-next-line yoda const did = credDef.orgDid?.split(':').length >= 4 ? credDef.orgDid : orgDid; const getAgentDetails = await this.credentialDefinitionRepository.getAgentType(credDef.orgId); - const apiKey = ''; + // const apiKey = await this._getOrgAgentApiKey(credDef.orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(credDef.orgId); + } const { userId } = user.selectedOrg; credDef.tag = credDef.tag.trim(); const dbResult: credential_definition = await this.credentialDefinitionRepository.getByAttribute( @@ -87,6 +95,7 @@ export class CredentialDefinitionService extends BaseService { issuerId: '', revocable: credDef.revocable, createdBy: `0`, + lastChangedBy: `0`, orgId: '0', schemaId: '0', credentialDefinitionId: '' @@ -101,6 +110,7 @@ export class CredentialDefinitionService extends BaseService { credDefData.revocable = credDef.revocable; credDefData.schemaId = schemaDetails.id; credDefData.createdBy = userId; + credDefData.lastChangedBy = userId; } else if ('finished' === response.credentialDefinition.state) { credDefData.tag = response.credentialDefinition.credentialDefinition.tag; credDefData.schemaLedgerId = response.credentialDefinition.credentialDefinition.schemaId; @@ -110,6 +120,7 @@ export class CredentialDefinitionService extends BaseService { credDefData.revocable = credDef.revocable; credDefData.schemaId = schemaDetails.id; credDefData.createdBy = userId; + credDefData.lastChangedBy = userId; } const credDefResponse = await this.credentialDefinitionRepository.saveCredentialDefinition(credDefData); return credDefResponse; @@ -167,8 +178,13 @@ export class CredentialDefinitionService extends BaseService { const { agentEndPoint } = await this.credentialDefinitionRepository.getAgentDetailsByOrgId(String(orgId)); const getAgentDetails = await this.credentialDefinitionRepository.getAgentType(String(orgId)); const orgAgentType = await this.credentialDefinitionRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId); - const apiKey = ''; - let credDefResponse; + // const apiKey = await this._getOrgAgentApiKey(String(orgId)); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(String(orgId)); + } + let credDefResponse; if (OrgAgentType.DEDICATED === orgAgentType) { const getSchemaPayload = { credentialDefinitionId, @@ -313,4 +329,20 @@ export class CredentialDefinitionService extends BaseService { } } + async _getOrgAgentApiKey(orgId: string): Promise { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = { orgId }; + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const message = await this.credDefServiceProxy.send(pattern, payload).toPromise(); + return message; + } catch (error) { + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException({ + status: error.status, + error: error.message + }, error.status); + } + } } \ No newline at end of file diff --git a/apps/ledger/src/credential-definition/interfaces/create-credential-definition.interface.ts b/apps/ledger/src/credential-definition/interfaces/create-credential-definition.interface.ts index fd51c3e80..7067508a5 100644 --- a/apps/ledger/src/credential-definition/interfaces/create-credential-definition.interface.ts +++ b/apps/ledger/src/credential-definition/interfaces/create-credential-definition.interface.ts @@ -32,6 +32,7 @@ export interface CredDefPayload { schemaLedgerId?: string; orgId?: string; createdBy?: string; + lastChangedBy?: string; autoIssue?: boolean; revocable?: boolean; orgDid?: string; diff --git a/apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts b/apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts index 29022bbce..2f9de26cb 100644 --- a/apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts +++ b/apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts @@ -27,7 +27,8 @@ export class CredentialDefinitionRepository { tag: credDef.tag, credentialDefinitionId: credDef.credentialDefinitionId, revocable: credDef.revocable, - createdBy: credDef.userId, + createdBy: credDef.createdBy, + lastChangedBy: credDef.lastChangedBy, orgId: credDef.orgId, schemaId: credDef.schemaId } diff --git a/apps/ledger/src/schema/schema.module.ts b/apps/ledger/src/schema/schema.module.ts index d4e409750..d818727ea 100644 --- a/apps/ledger/src/schema/schema.module.ts +++ b/apps/ledger/src/schema/schema.module.ts @@ -7,7 +7,7 @@ import { SchemaRepository } from './repositories/schema.repository'; import { SchemaService } from './schema.service'; import { HttpModule } from '@nestjs/axios'; import { PrismaService } from '@credebl/prisma-service'; - +import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ ClientsModule.register([ @@ -21,7 +21,8 @@ import { PrismaService } from '@credebl/prisma-service'; ]), HttpModule, - CommonModule + CommonModule, + CacheModule.register() ], providers: [ SchemaService, diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index 666b4fe56..a5853ae41 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -17,12 +17,15 @@ import { IUserRequestInterface } from './interfaces/schema.interface'; import { CreateSchemaAgentRedirection, GetSchemaAgentRedirection } from './schema.interface'; import { map } from 'rxjs/operators'; import { OrgAgentType } from '@credebl/enum/enum'; - +import { Cache } from 'cache-manager'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; +import { CommonConstants } from '@credebl/common/common.constant'; @Injectable() export class SchemaService extends BaseService { constructor( private readonly schemaRepository: SchemaRepository, - @Inject('NATS_CLIENT') private readonly schemaServiceProxy: ClientProxy + @Inject('NATS_CLIENT') private readonly schemaServiceProxy: ClientProxy, + @Inject(CACHE_MANAGER) private cacheService: Cache ) { super('SchemaService'); } @@ -32,7 +35,13 @@ export class SchemaService extends BaseService { user: IUserRequestInterface, orgId: string ): Promise { - const apiKey = ''; + // const apiKey = ''; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } const { userId } = user.selectedOrg; try { const schemaExists = await this.schemaRepository.schemaExists( @@ -231,7 +240,14 @@ export class SchemaService extends BaseService { const { agentEndPoint } = await this.schemaRepository.getAgentDetailsByOrgId(orgId); const getAgentDetails = await this.schemaRepository.getAgentType(orgId); const orgAgentType = await this.schemaRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId); - const apiKey = ''; + // const apiKey = ''; + + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } let schemaResponse; if (OrgAgentType.DEDICATED === orgAgentType) { const getSchemaPayload = { @@ -433,4 +449,23 @@ export class SchemaService extends BaseService { throw new RpcException(error.response ? error.response : error); } } + + async _getOrgAgentApiKey(orgId: string): Promise { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = { orgId }; + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const message = await this.schemaServiceProxy.send(pattern, payload).toPromise(); + return message; + } catch (error) { + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException({ + status: error.status, + error: error.message + }, error.status); + } + } + + } diff --git a/apps/organization/dtos/create-organization.dto.ts b/apps/organization/dtos/create-organization.dto.ts index 2d4d1a588..0897f9a30 100644 --- a/apps/organization/dtos/create-organization.dto.ts +++ b/apps/organization/dtos/create-organization.dto.ts @@ -7,6 +7,9 @@ export class CreateOrganizationDto { logo?: string; website?: string; orgSlug?:string; + createdBy?:string; + updatedBy?:string; + lastChangedBy?:string; } export class CreateUserRoleOrgDto { diff --git a/apps/organization/interfaces/organization.interface.ts b/apps/organization/interfaces/organization.interface.ts index dc7dac155..7781994e0 100644 --- a/apps/organization/interfaces/organization.interface.ts +++ b/apps/organization/interfaces/organization.interface.ts @@ -19,7 +19,9 @@ export interface IUpdateOrganization { logo?: string; website?: string; orgSlug?: string; - isPublic?:boolean + isPublic?:boolean; + userId?: string; + } export interface OrgAgent { diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index 8a768016f..22549d8ac 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -56,8 +56,9 @@ export class OrganizationRepository { description: createOrgDto.description, website: createOrgDto.website, orgSlug: createOrgDto.orgSlug, - publicProfile: true - + publicProfile: true, + createdBy: createOrgDto.createdBy, + lastChangedBy: createOrgDto.lastChangedBy } }); } catch (error) { @@ -84,7 +85,8 @@ export class OrganizationRepository { description: updateOrgDto.description, website: updateOrgDto.website, orgSlug: updateOrgDto.orgSlug, - publicProfile: updateOrgDto.isPublic + publicProfile: updateOrgDto.isPublic, + lastChangedBy: updateOrgDto.userId } }); } catch (error) { @@ -138,7 +140,9 @@ export class OrganizationRepository { user: { connect: { id: userId } }, organisation: { connect: { id: orgId } }, orgRoles: orgRoleId, - status: Invitation.PENDING + status: Invitation.PENDING, + createdBy: userId, + lastChangedBy: userId } }); } catch (error) { diff --git a/apps/organization/src/organization.module.ts b/apps/organization/src/organization.module.ts index 07612f636..38fc68e60 100644 --- a/apps/organization/src/organization.module.ts +++ b/apps/organization/src/organization.module.ts @@ -13,7 +13,7 @@ import { UserActivityService } from '@credebl/user-activity'; import { UserOrgRolesRepository } from 'libs/user-org-roles/repositories'; import { UserOrgRolesService } from '@credebl/user-org-roles'; import { UserRepository } from 'apps/user/repositories/user.repository'; - +import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ ClientsModule.register([ @@ -25,7 +25,8 @@ import { UserRepository } from 'apps/user/repositories/user.repository'; } } ]), - CommonModule + CommonModule, + CacheModule.register() ], controllers: [OrganizationController], providers: [ diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index 6656f625b..d64e52a62 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -22,6 +22,8 @@ import { IUpdateOrganization, OrgAgent } from '../interfaces/organization.interf import { UserActivityService } from '@credebl/user-activity'; import { CommonConstants } from '@credebl/common/common.constant'; import { map } from 'rxjs/operators'; +import { Cache } from 'cache-manager'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; @Injectable() export class OrganizationService { constructor( @@ -32,7 +34,8 @@ export class OrganizationService { private readonly orgRoleService: OrgRolesService, private readonly userOrgRoleService: UserOrgRolesService, private readonly userActivityService: UserActivityService, - private readonly logger: Logger + private readonly logger: Logger, + @Inject(CACHE_MANAGER) private cacheService: Cache ) { } /** @@ -52,6 +55,8 @@ export class OrganizationService { const orgSlug = this.createOrgSlug(createOrgDto.name); createOrgDto.orgSlug = orgSlug; + createOrgDto.createdBy = userId; + createOrgDto.lastChangedBy = userId; const organizationDetails = await this.organizationRepository.createOrganization(createOrgDto); @@ -101,7 +106,7 @@ export class OrganizationService { const orgSlug = await this.createOrgSlug(updateOrgDto.name); updateOrgDto.orgSlug = orgSlug; - + updateOrgDto.userId = userId; const organizationDetails = await this.organizationRepository.updateOrganization(updateOrgDto); await this.userActivityService.createActivity(userId, organizationDetails.id, `${organizationDetails.name} organization updated`, 'Organization details updated successfully'); return organizationDetails; @@ -501,7 +506,12 @@ export class OrganizationService { async deleteOrganization(orgId: string): Promise { try { const getAgent = await this.organizationRepository.getAgentEndPoint(orgId); - + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } let url; if (getAgent.orgAgentTypeId === OrgAgentType.DEDICATED) { url = `${getAgent.agentEndPoint}${CommonConstants.URL_DELETE_WALLET}`; @@ -512,7 +522,7 @@ export class OrganizationService { const payload = { url, - apiKey: getAgent.apiKey + apiKey }; const deleteWallet = await this._deleteWallet(payload); @@ -561,4 +571,22 @@ export class OrganizationService { throw error; } } + + + async _getOrgAgentApiKey(orgId: string): Promise { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = { orgId }; + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const message = await this.organizationServiceProxy.send(pattern, payload).toPromise(); + return message; + } catch (error) { + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException({ + status: error.status, + error: error.message + }, error.status); + } + } } \ No newline at end of file diff --git a/apps/user/repositories/user-device.repository.ts b/apps/user/repositories/user-device.repository.ts index 674a659dd..ff21863a4 100644 --- a/apps/user/repositories/user-device.repository.ts +++ b/apps/user/repositories/user-device.repository.ts @@ -50,7 +50,9 @@ export class UserDevicesRepository { const saveResponse = await this.prisma.user_devices.create({ data: { devices: newDevice, - userId:String(userId) + userId:String(userId), + createdBy: userId, + lastChangedBy: userId } }); diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index ae0d68e6a..895e01a96 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -51,6 +51,8 @@ export class VerificationRepository { }, create: { connectionId: proofPresentationPayload.connectionId, + createdBy: id, + lastChangedBy: id, state: proofPresentationPayload.state, threadId: proofPresentationPayload.threadId, isVerified: proofPresentationPayload.isVerified, diff --git a/apps/verification/src/verification.module.ts b/apps/verification/src/verification.module.ts index d42ce109b..80bd34c43 100644 --- a/apps/verification/src/verification.module.ts +++ b/apps/verification/src/verification.module.ts @@ -7,7 +7,7 @@ import { VerificationRepository } from './repositories/verification.repository'; import { PrismaService } from '@credebl/prisma-service'; import { OutOfBandVerification } from '../templates/out-of-band-verification.template'; import { EmailDto } from '@credebl/common/dtos/email.dto'; - +import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ ClientsModule.register([ @@ -20,7 +20,8 @@ import { EmailDto } from '@credebl/common/dtos/email.dto'; } ]), - CommonModule + CommonModule, + CacheModule.register() ], controllers: [VerificationController], providers: [VerificationService, VerificationRepository, PrismaService, Logger, OutOfBandVerification, EmailDto] diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 5a1e1c474..34021130b 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -12,7 +12,8 @@ import * as QRCode from 'qrcode'; import { OutOfBandVerification } from '../templates/out-of-band-verification.template'; import { EmailDto } from '@credebl/common/dtos/email.dto'; import { sendEmail } from '@credebl/common/send-grid-helper-file'; - +import { Cache } from 'cache-manager'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; @Injectable() export class VerificationService { @@ -22,7 +23,8 @@ export class VerificationService { @Inject('NATS_CLIENT') private readonly verificationServiceProxy: ClientProxy, private readonly verificationRepository: VerificationRepository, private readonly outOfBandVerification: OutOfBandVerification, - private readonly emailData: EmailDto + private readonly emailData: EmailDto, + @Inject(CACHE_MANAGER) private cacheService: Cache ) { } @@ -44,8 +46,13 @@ export class VerificationService { } else { url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); } - - const payload = { apiKey: getAgentDetails.apiKey, url }; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } + const payload = { apiKey, url }; const getProofPresentationsDetails = await this._getProofPresentations(payload); return getProofPresentationsDetails?.response; @@ -113,8 +120,13 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const verificationMethodLabel = 'get-proof-presentation-by-id'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); - - const payload = { apiKey: '', url }; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } + const payload = { apiKey, url }; const getProofPresentationById = await this._getProofPresentationById(payload); return getProofPresentationById?.response; @@ -217,8 +229,13 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const verificationMethodLabel = 'request-proof'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); - - const payload = { apiKey: '', url, proofRequestPayload }; + // const apiKey = await this._getOrgAgentApiKey(requestProof.orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(requestProof.orgId); + } + const payload = { apiKey, url, proofRequestPayload }; const getProofPresentationById = await this._sendProofRequest(payload); return getProofPresentationById?.response; @@ -286,8 +303,13 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); - - const payload = { apiKey: '', url }; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } + const payload = { apiKey, url }; const getProofPresentationById = await this._verifyPresentation(payload); return getProofPresentationById?.response; } catch (error) { @@ -374,10 +396,15 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const verificationMethodLabel = 'create-request-out-of-band'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); - + // const apiKey = await this._getOrgAgentApiKey(outOfBandRequestProof.orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(outOfBandRequestProof.orgId); + } const payload: IProofRequestPayload = { - apiKey: '', + apiKey, url, proofRequestPayload: { protocolVersion, @@ -442,6 +469,13 @@ export class VerificationService { async sendOutOfBandProofRequest(payload: IProofRequestPayload, email: string, getAgentDetails: org_agents, organizationDetails: organisation): Promise { + // const apiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); + } + payload.apiKey = apiKey; const getProofPresentation = await this._sendOutOfBandProofRequest(payload); if (!getProofPresentation) { @@ -710,8 +744,13 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); - - const payload = { apiKey: '', url }; + // const apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } + const payload = { apiKey, url }; const getProofPresentationById = await this._getProofFormData(payload); if (!getProofPresentationById?.response?.presentation) { @@ -848,4 +887,23 @@ export class VerificationService { throw error; } } + + + async _getOrgAgentApiKey(orgId: string): Promise { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = { orgId }; + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const message = await this.verificationServiceProxy.send(pattern, payload).toPromise(); + return message; + } catch (error) { + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException({ + status: error.status, + error: error.message + }, error.status); + } + } + } diff --git a/libs/common/src/common.constant.ts b/libs/common/src/common.constant.ts index d94cf5380..a42c07424 100644 --- a/libs/common/src/common.constant.ts +++ b/libs/common/src/common.constant.ts @@ -295,7 +295,10 @@ export enum CommonConstants { TRANSACTION_MULTITENANT_SIGN = '/multi-tenancy/transactions/endorse/#', TRANSACTION_MULTITENANT_SUMBIT = '/multi-tenancy/transactions/write/#', - + + //CacheInfo +CACHE_APIKEY_KEY = "apiKey", +CACHE_TTL_SECONDS = 3600 } export const postgresqlErrorCodes = []; diff --git a/libs/common/src/common.service.ts b/libs/common/src/common.service.ts index 507e22c51..e0f790d51 100644 --- a/libs/common/src/common.service.ts +++ b/libs/common/src/common.service.ts @@ -1,3 +1,9 @@ +/* eslint-disable arrow-body-style */ +/* eslint-disable implicit-arrow-linebreak */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable space-in-parens */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import * as CryptoJS from 'crypto-js'; import { @@ -11,16 +17,13 @@ import { import { CommonConstants } from './common.constant'; import { HttpService } from '@nestjs/axios/dist'; import { ResponseService } from '@credebl/response'; -import { readFileSync } from 'fs'; -import { RpcException } from '@nestjs/microservices'; -import { AgentServiceService } from '../../../apps/agent-service/src/agent-service.service'; @Injectable() export class CommonService { private readonly logger = new Logger('CommonService'); result: ResponseService = new ResponseService(); - agentServiceService :AgentServiceService ; - constructor(private readonly httpService: HttpService ) { } + + constructor(private readonly httpService: HttpService) { } async httpPost(url: string, payload?: any, apiKey?: any) { try { @@ -392,8 +395,4 @@ export class CommonService { } } - async getAgentApiKey(orgId: string): Promise { - const apiKey = await this.agentServiceService.getOrgAgentApiKey(orgId); - return apiKey; - } } diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 0a36098df..dd1edd948 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -58,7 +58,7 @@ export const ResponseMessages = { getOrgDashboard: 'Organization dashboard details fetched', getOrganizations: 'Organizations details fetched successfully', updateUserRoles: 'User roles updated successfully', - delete: 'Organization deleted successfully', + delete: 'Organization deleted successfully' }, error: { exists: 'An organization name is already exist', diff --git a/libs/prisma-service/prisma/migrations/20231123154918_uuid_createdby_upadatedby/migration.sql b/libs/prisma-service/prisma/migrations/20231123154918_uuid_createdby_upadatedby/migration.sql new file mode 100644 index 000000000..4b48dbd61 --- /dev/null +++ b/libs/prisma-service/prisma/migrations/20231123154918_uuid_createdby_upadatedby/migration.sql @@ -0,0 +1,220 @@ +/* + Warnings: + + - You are about to drop the column `createdBy` on the `agents` table. All the data in the column will be lost. + - You are about to drop the column `lastChangedBy` on the `agents` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `agents_type` table. All the data in the column will be lost. + - You are about to drop the column `lastChangedBy` on the `agents_type` table. All the data in the column will be lost. + - The `orgId` column on the `credential_definition` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - The `orgId` column on the `file_upload` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - You are about to drop the column `createdBy` on the `ledgers` table. All the data in the column will be lost. + - You are about to drop the column `lastChangedBy` on the `ledgers` table. All the data in the column will be lost. + - You are about to drop the column `createdBy` on the `org_agents_type` table. All the data in the column will be lost. + - You are about to drop the column `lastChangedBy` on the `org_agents_type` table. All the data in the column will be lost. + - The `ledgerId` column on the `schema` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - Changed the type of `orgId` on the `agent_invitations` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `connections` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `connections` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `credential_definition` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `credential_definition` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `schemaId` on the `credential_definition` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `credentials` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `credentials` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `ecosystem` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `ecosystem` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `ecosystem_invitations` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `ecosystem_invitations` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `ecosystem_orgs` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `ecosystem_orgs` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `ecosystem_roles` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `ecosystem_roles` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `ecosystem_users` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `ecosystem_users` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `endorsement_transaction` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `endorsement_transaction` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `file_data` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `file_data` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `file_upload` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `file_upload` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `org_agents` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Added the required column `lastChangedBy` to the `org_agents` table without a default value. This is not possible if the table is not empty. + - Changed the type of `createdBy` on the `org_invitations` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `org_invitations` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `organisation` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `organisation` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `presentations` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `presentations` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `schema` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `schema` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `user` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `user` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `user_activity` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `user_activity` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `user_credentials` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `user_credentials` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `createdBy` on the `user_devices` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `lastChangedBy` on the `user_devices` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + +*/ +-- AlterTable +ALTER TABLE "agent_invitations" DROP COLUMN "orgId", +ADD COLUMN "orgId" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "agents" DROP COLUMN "createdBy", +DROP COLUMN "lastChangedBy"; + +-- AlterTable +ALTER TABLE "agents_type" DROP COLUMN "createdBy", +DROP COLUMN "lastChangedBy"; + +-- AlterTable +ALTER TABLE "connections" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "credential_definition" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL, +DROP COLUMN "schemaId", +ADD COLUMN "schemaId" UUID NOT NULL, +DROP COLUMN "orgId", +ADD COLUMN "orgId" UUID; + +-- AlterTable +ALTER TABLE "credentials" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "ecosystem" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "ecosystem_invitations" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "ecosystem_orgs" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "ecosystem_roles" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "ecosystem_users" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "endorsement_transaction" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "file_data" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "file_upload" DROP COLUMN "orgId", +ADD COLUMN "orgId" UUID, +DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "ledgers" DROP COLUMN "createdBy", +DROP COLUMN "lastChangedBy"; + +-- AlterTable +ALTER TABLE "org_agents" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "org_agents_type" DROP COLUMN "createdBy", +DROP COLUMN "lastChangedBy"; + +-- AlterTable +ALTER TABLE "org_invitations" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "organisation" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "presentations" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "schema" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL, +DROP COLUMN "ledgerId", +ADD COLUMN "ledgerId" UUID; + +-- AlterTable +ALTER TABLE "user" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "user_activity" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "user_credentials" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AlterTable +ALTER TABLE "user_devices" DROP COLUMN "createdBy", +ADD COLUMN "createdBy" UUID NOT NULL, +DROP COLUMN "lastChangedBy", +ADD COLUMN "lastChangedBy" UUID NOT NULL; + +-- AddForeignKey +ALTER TABLE "schema" ADD CONSTRAINT "schema_ledgerId_fkey" FOREIGN KEY ("ledgerId") REFERENCES "ledgers"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "credential_definition" ADD CONSTRAINT "credential_definition_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "organisation"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "credential_definition" ADD CONSTRAINT "credential_definition_schemaId_fkey" FOREIGN KEY ("schemaId") REFERENCES "schema"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "agent_invitations" ADD CONSTRAINT "agent_invitations_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "organisation"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "file_upload" ADD CONSTRAINT "file_upload_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "organisation"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/libs/prisma-service/prisma/migrations/20231123161550_removed_createdby_ecosystem_roles/migration.sql b/libs/prisma-service/prisma/migrations/20231123161550_removed_createdby_ecosystem_roles/migration.sql new file mode 100644 index 000000000..30fe2963b --- /dev/null +++ b/libs/prisma-service/prisma/migrations/20231123161550_removed_createdby_ecosystem_roles/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `createdBy` on the `ecosystem_roles` table. All the data in the column will be lost. + - You are about to drop the column `lastChangedBy` on the `ecosystem_roles` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "ecosystem_roles" DROP COLUMN "createdBy", +DROP COLUMN "lastChangedBy"; diff --git a/libs/prisma-service/prisma/migrations/20231123162120_removed_createdby_user/migration.sql b/libs/prisma-service/prisma/migrations/20231123162120_removed_createdby_user/migration.sql new file mode 100644 index 000000000..101ce886f --- /dev/null +++ b/libs/prisma-service/prisma/migrations/20231123162120_removed_createdby_user/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `createdBy` on the `user` table. All the data in the column will be lost. + - You are about to drop the column `lastChangedBy` on the `user` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "user" DROP COLUMN "createdBy", +DROP COLUMN "lastChangedBy"; diff --git a/libs/prisma-service/prisma/migrations/20231123180959_removed_createdby_user_credentials/migration.sql b/libs/prisma-service/prisma/migrations/20231123180959_removed_createdby_user_credentials/migration.sql new file mode 100644 index 000000000..e010b6d60 --- /dev/null +++ b/libs/prisma-service/prisma/migrations/20231123180959_removed_createdby_user_credentials/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `createdBy` on the `user_credentials` table. All the data in the column will be lost. + - You are about to drop the column `lastChangedBy` on the `user_credentials` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "user_credentials" DROP COLUMN "createdBy", +DROP COLUMN "lastChangedBy"; diff --git a/libs/prisma-service/prisma/schema.prisma b/libs/prisma-service/prisma/schema.prisma index 6bf7b2a10..f3747dca8 100644 --- a/libs/prisma-service/prisma/schema.prisma +++ b/libs/prisma-service/prisma/schema.prisma @@ -11,9 +11,7 @@ datasource db { model user { id String @id(map: "PK_cace4a159ff9f2512dd42373760") @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") firstName String? @db.VarChar(500) lastName String? @db.VarChar(500) email String? @unique(map: "UQ_e12875dfb3b1d92d7d7c5377e22") @db.VarChar(500) @@ -41,9 +39,9 @@ model user_activity { action String details String createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) organisation organisation @relation(fields: [orgId], references: [id]) user user @relation(fields: [userId], references: [id]) @@ -54,9 +52,7 @@ model user_credentials { imageUrl String? credentialId String @unique createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") deletedAt DateTime? @db.Timestamp(6) } @@ -83,33 +79,36 @@ model user_org_roles { } model organisation { - id String @id @default(uuid()) @db.Uuid - createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") - lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") - name String? @db.VarChar(500) - description String? @db.VarChar(500) - orgSlug String? @unique - logoUrl String? - website String? @db.VarChar - publicProfile Boolean @default(false) - connections connections[] - credentials credentials[] - org_agents org_agents[] - orgInvitations org_invitations[] - presentations presentations[] - schema schema[] - user_activities user_activity[] - userOrgRoles user_org_roles[] + id String @id @default(uuid()) @db.Uuid + createDateTime DateTime @default(now()) @db.Timestamptz(6) + createdBy String @db.Uuid + lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) + lastChangedBy String @db.Uuid + name String? @db.VarChar(500) + description String? @db.VarChar(500) + orgSlug String? @unique + logoUrl String? + website String? @db.VarChar + publicProfile Boolean @default(false) + connections connections[] + credentials credentials[] + org_agents org_agents[] + orgInvitations org_invitations[] + presentations presentations[] + schema schema[] + user_activities user_activity[] + userOrgRoles user_org_roles[] + agent_invitations agent_invitations[] + credential_definition credential_definition[] + file_upload file_upload[] } model org_invitations { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) userId String @db.Uuid orgId String @db.Uuid @@ -123,9 +122,9 @@ model org_invitations { model user_devices { id String @id(map: "PK_c9e7e648903a9e537347aba4371") @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid devices Json? @default("[]") credentialId String? @unique(map: "UQ_7c903f5e362fe8fd3d3edba17b5") @db.VarChar deviceFriendlyName String? @db.VarChar @@ -154,9 +153,9 @@ model platform_config { model org_agents { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String? @default("1") + lastChangedBy String @db.Uuid orgDid String? @db.VarChar verkey String? @db.VarChar agentEndPoint String? @db.VarChar @@ -182,9 +181,7 @@ model org_agents { model org_agents_type { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") agent String @db.VarChar(500) org_agents org_agents[] } @@ -192,9 +189,7 @@ model org_agents_type { model agents_type { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") agent String @db.VarChar(500) org_agents org_agents[] } @@ -202,9 +197,7 @@ model agents_type { model ledgers { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") name String @db.VarChar networkType String @db.VarChar poolConfig String @db.VarChar @@ -214,47 +207,50 @@ model ledgers { registerDIDPayload Json? indyNamespace String? @db.VarChar org_agents org_agents[] + schema schema[] } model agents { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") name String org_agents org_agents[] } model schema { - id String @id(map: "PK_c9e7e648903a9e537347aba4372") @default(uuid()) @db.Uuid - createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") - lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") - name String @db.VarChar - version String @db.VarChar - attributes String - schemaLedgerId String @db.VarChar - publisherDid String @db.VarChar - ledgerId String @default("1") - issuerId String @db.VarChar - orgId String @db.Uuid - organisation organisation @relation(fields: [orgId], references: [id]) + id String @id(map: "PK_c9e7e648903a9e537347aba4372") @default(uuid()) @db.Uuid + createDateTime DateTime @default(now()) @db.Timestamptz(6) + createdBy String @db.Uuid + lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) + lastChangedBy String @db.Uuid + name String @db.VarChar + version String @db.VarChar + attributes String + schemaLedgerId String @db.VarChar + publisherDid String @db.VarChar + issuerId String @db.VarChar + orgId String @db.Uuid + organisation organisation @relation(fields: [orgId], references: [id]) + ledgers ledgers? @relation(fields: [ledgerId], references: [id]) + ledgerId String? @db.Uuid + credential_definition credential_definition[] } model credential_definition { - id String @id(map: "PK_c9e7e648903a9e537347aba4373") @default(uuid()) @db.Uuid - createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") - lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") - credentialDefinitionId String @db.VarChar - tag String @db.VarChar - schemaLedgerId String @db.VarChar - schemaId String @default("1") - orgId String @default("1") - revocable Boolean @default(false) + id String @id(map: "PK_c9e7e648903a9e537347aba4373") @default(uuid()) @db.Uuid + createDateTime DateTime @default(now()) @db.Timestamptz(6) + createdBy String @db.Uuid + lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) + lastChangedBy String @db.Uuid + credentialDefinitionId String @db.VarChar + tag String @db.VarChar + schemaLedgerId String @db.VarChar + schemaId String @db.Uuid + revocable Boolean @default(false) + organisation organisation? @relation(fields: [orgId], references: [id]) + orgId String? @db.Uuid + schema schema @relation(fields: [schemaId], references: [id]) } model shortening_url { @@ -265,24 +261,25 @@ model shortening_url { } model agent_invitations { - id String @id @default(uuid()) @db.Uuid - orgId String @default("1") - agentId String @db.Uuid + id String @id @default(uuid()) @db.Uuid + orgId String @db.Uuid + agentId String @db.Uuid connectionInvitation String multiUse Boolean - createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy Int @default(1) - lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy Int @default(1) - org_agents org_agents @relation(fields: [agentId], references: [id]) + createDateTime DateTime @default(now()) @db.Timestamptz(6) + createdBy Int @default(1) + lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) + lastChangedBy Int @default(1) + org_agents org_agents @relation(fields: [agentId], references: [id]) + organisation organisation @relation(fields: [orgId], references: [id]) } model connections { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid connectionId String @unique state String orgDid String @@ -296,9 +293,9 @@ model connections { model credentials { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid connectionId String? threadId String @unique protocolVersion String? @@ -310,9 +307,9 @@ model credentials { model presentations { id String @id @default(uuid()) @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid connectionId String? state String? threadId String @unique @@ -326,9 +323,7 @@ model ecosystem_roles { name String @unique description String createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") deletedAt DateTime? @db.Timestamp(6) ecosystemOrgs ecosystem_orgs[] } @@ -339,9 +334,9 @@ model ecosystem { description String tags String createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) logoUrl String? autoEndorsement Boolean @default(false) @@ -358,9 +353,9 @@ model ecosystem_invitations { userId String orgId String createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) ecosystem ecosystem @relation(fields: [ecosystemId], references: [id]) } @@ -370,9 +365,9 @@ model ecosystem_users { userId String ecosystemId String @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) ecosystem ecosystem @relation(fields: [ecosystemId], references: [id]) } @@ -387,9 +382,9 @@ model ecosystem_orgs { ecosystemId String @db.Uuid ecosystemRoleId String @db.Uuid createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) ecosystem ecosystem @relation(fields: [ecosystemId], references: [id]) ecosystemRole ecosystem_roles @relation(fields: [ecosystemRoleId], references: [id]) @@ -404,9 +399,9 @@ model endorsement_transaction { responsePayload String type String? createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) status String ecosystemOrgId String @db.Uuid @@ -427,17 +422,18 @@ model ecosystem_config { } model file_upload { - id String @id @default(uuid()) @db.Uuid + id String @id @default(uuid()) @db.Uuid name String? status String? upload_type String? - orgId String @default("1") - createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") - lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") - deletedAt DateTime? @db.Timestamp(6) + createDateTime DateTime @default(now()) @db.Timestamptz(6) + createdBy String @db.Uuid + lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) + lastChangedBy String @db.Uuid + deletedAt DateTime? @db.Timestamp(6) file_data file_data[] + organisation organisation? @relation(fields: [orgId], references: [id]) + orgId String? @db.Uuid } model file_data { @@ -447,9 +443,9 @@ model file_data { error String? detailError String? createDateTime DateTime @default(now()) @db.Timestamptz(6) - createdBy String @default("1") + createdBy String @db.Uuid lastChangedDateTime DateTime @default(now()) @db.Timestamptz(6) - lastChangedBy String @default("1") + lastChangedBy String @db.Uuid deletedAt DateTime? @db.Timestamp(6) fileUploadId String @db.Uuid fileUpload file_upload @relation(fields: [fileUploadId], references: [id]) diff --git a/libs/prisma-service/prisma/seed.ts b/libs/prisma-service/prisma/seed.ts index 9073aa268..e81b282e3 100644 --- a/libs/prisma-service/prisma/seed.ts +++ b/libs/prisma-service/prisma/seed.ts @@ -6,6 +6,7 @@ import { CommonConstants } from '../../common/src/common.constant'; const prisma = new PrismaClient(); const logger = new Logger('Init seed DB'); +let platformUserId = ''; const configData = fs.readFileSync(`${process.env.PWD}/prisma/data/credebl-master-table.json`, 'utf8'); const createPlatformConfig = async (): Promise => { @@ -63,10 +64,14 @@ const createOrgAgentTypes = async (): Promise => { const createPlatformUser = async (): Promise => { try { const { platformAdminData } = JSON.parse(configData); + platformAdminData.email = process.env.PLATFORM_ADMIN_EMAIL; + platformAdminData.username = process.env.PLATFORM_ADMIN_EMAIL; const platformUser = await prisma.user.create({ data: platformAdminData }); + platformUserId = platformUser.id; + logger.log(platformUser); } catch (e) { logger.error('An error occurred seeding platformUser:', e); @@ -77,6 +82,8 @@ const createPlatformUser = async (): Promise => { const createPlatformOrganization = async (): Promise => { try { const { platformAdminOrganizationData } = JSON.parse(configData); + platformAdminOrganizationData.createdBy = platformUserId; + platformAdminOrganizationData.lastChangedBy = platformUserId; const platformOrganization = await prisma.organisation.create({ data: platformAdminOrganizationData }); @@ -166,8 +173,8 @@ async function main(): Promise { await createPlatformConfig(); await createOrgRoles(); await createAgentTypes(); - await createPlatformOrganization(); await createPlatformUser(); + await createPlatformOrganization(); await createPlatformUserOrgRoles(); await createOrgAgentTypes(); await createLedger(); diff --git a/libs/user-activity/repositories/index.ts b/libs/user-activity/repositories/index.ts index 6fda9ef29..ed616ca69 100644 --- a/libs/user-activity/repositories/index.ts +++ b/libs/user-activity/repositories/index.ts @@ -15,7 +15,9 @@ export class UserActivityRepository { userId, orgId, action, - details + details, + createdBy: userId, + lastChangedBy: userId } }); } From f6423d21275d854448901e5acd9ac1b548c864dc Mon Sep 17 00:00:00 2001 From: Nishad Date: Tue, 19 Dec 2023 20:37:50 +0530 Subject: [PATCH 007/107] worked on the POST API of create schema refactoring Signed-off-by: Nishad --- apps/api-gateway/common/exception-handler.ts | 10 ++-- .../src/authz/guards/org-roles.guard.ts | 5 +- .../api-gateway/src/dtos/create-schema.dto.ts | 35 +++++++++----- .../src/schema/schema.controller.ts | 24 +--------- apps/api-gateway/src/schema/schema.service.ts | 2 +- .../src/schema/interfaces/schema.interface.ts | 6 +++ .../schema/repositories/schema.repository.ts | 18 ++++--- apps/ledger/src/schema/schema.controller.ts | 14 ++++-- apps/ledger/src/schema/schema.service.ts | 47 ++++++++++++------- libs/common/src/cast.helper.ts | 2 +- libs/common/src/response-messages/index.ts | 11 ++++- 11 files changed, 100 insertions(+), 74 deletions(-) diff --git a/apps/api-gateway/common/exception-handler.ts b/apps/api-gateway/common/exception-handler.ts index b8a21f30a..afaf5f4ea 100644 --- a/apps/api-gateway/common/exception-handler.ts +++ b/apps/api-gateway/common/exception-handler.ts @@ -64,9 +64,9 @@ export class CustomExceptionFilter extends BaseExceptionFilter { if (Array.isArray(exception['response'].message)) { errorResponse = { statusCode: exception['statusCode'] ? exception['statusCode'] : status, - message: exception.message ? exception.message : 'Internal server error', - error: exception['response'].message - ? exception['response'].message + message: exception['response'].message ? exception['response'].message : 'Internal server error', + error: exception['response'].error + ? exception['response'].error : exception['response'] ? exception['response'] : 'Internal server error' @@ -79,8 +79,8 @@ export class CustomExceptionFilter extends BaseExceptionFilter { : exception['response'] ? exception['response'] : 'Internal server error', - error: exception['response'].message - ? exception['response'].message + error: exception['response'].error + ? exception['response'].error : exception['response'] ? exception['response'] : 'Internal server error' diff --git a/apps/api-gateway/src/authz/guards/org-roles.guard.ts b/apps/api-gateway/src/authz/guards/org-roles.guard.ts index 803a7a229..45e9e50f1 100644 --- a/apps/api-gateway/src/authz/guards/org-roles.guard.ts +++ b/apps/api-gateway/src/authz/guards/org-roles.guard.ts @@ -1,4 +1,4 @@ -import { CanActivate, ExecutionContext, Logger } from '@nestjs/common'; +import { CanActivate, ExecutionContext, ForbiddenException, Logger } from '@nestjs/common'; import { HttpException } from '@nestjs/common'; import { HttpStatus } from '@nestjs/common'; @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { OrgRoles } from 'libs/org-roles/enums'; import { ROLES_KEY } from '../decorators/roles.decorator'; import { Reflector } from '@nestjs/core'; +import { ResponseMessages } from '@credebl/common/response-messages'; @Injectable() export class OrgRolesGuard implements CanActivate { @@ -40,7 +41,7 @@ export class OrgRolesGuard implements CanActivate { }); if (!specificOrg) { - throw new HttpException('Organization does not match', HttpStatus.FORBIDDEN); + throw new ForbiddenException(ResponseMessages.organisation.error.orgNotFound, { cause: new Error(), description: ResponseMessages.errorMessages.forbidden }); } user.selectedOrg = specificOrg; diff --git a/apps/api-gateway/src/dtos/create-schema.dto.ts b/apps/api-gateway/src/dtos/create-schema.dto.ts index c776de70e..cc956644a 100644 --- a/apps/api-gateway/src/dtos/create-schema.dto.ts +++ b/apps/api-gateway/src/dtos/create-schema.dto.ts @@ -1,36 +1,45 @@ -import { IsArray, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { IsArray, IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Transform, Type } from 'class-transformer'; +import { trim } from '@credebl/common/cast.helper'; class AttributeValue { + @ApiProperty() @IsString() + @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'attributeName is required.' }) - @Transform(({ value }) => value.trim()) attributeName: string; + @ApiProperty() @IsString() + @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'schemaDataType is required.' }) schemaDataType: string; + @ApiProperty() @IsString() + @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'displayName is required.' }) displayName: string; } export class CreateSchemaDto { @ApiProperty() - @IsString({ message: 'schema version must be a string' }) - @IsNotEmpty({ message: 'please provide valid schema version' }) + @IsString({ message: 'Schema version must be a string' }) + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'schemaVersion is required' }) schemaVersion: string; @ApiProperty() - @IsString({ message: 'schema name must be a string' }) - @IsNotEmpty({ message: 'please provide valid schema name' }) + @IsString({ message: 'schemaName should be string.' }) + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'schemaName is required' }) schemaName: string; @ApiProperty({ + type: [AttributeValue], 'example': [ { attributeName: 'name', @@ -39,14 +48,18 @@ export class CreateSchemaDto { } ] }) - @IsArray({ message: 'attributes must be an array' }) - @IsNotEmpty({ message: 'please provide valid attributes' }) + @IsArray({ message: 'Attributes must be an array' }) + @IsNotEmpty({ message: 'attributes are required' }) + @ValidateNested({ each: true }) + @Type(() => AttributeValue) attributes: AttributeValue[]; orgId: string; - @ApiProperty() + @ApiPropertyOptional() + @Transform(({ value }) => trim(value)) @IsOptional() + @IsNotEmpty({ message: 'orgDid should not be empty' }) @IsString({ message: 'orgDid must be a string' }) orgDid: string; } diff --git a/apps/api-gateway/src/schema/schema.controller.ts b/apps/api-gateway/src/schema/schema.controller.ts index f69f3d068..9a536b007 100644 --- a/apps/api-gateway/src/schema/schema.controller.ts +++ b/apps/api-gateway/src/schema/schema.controller.ts @@ -38,7 +38,6 @@ export class SchemaController { summary: 'Get schema information from the ledger using its schema ID.', description: 'Get schema information from the ledger using its schema ID.' }) - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) async getSchemaById( @Res() res: Response, @@ -174,31 +173,12 @@ export class SchemaController { @ApiResponse({ status: 201, description: 'Success', type: ApiResponseDto }) async createSchema(@Res() res: Response, @Body() schema: CreateSchemaDto, @Param('orgId') orgId: string, @User() user: IUserRequestInterface): Promise { - schema.attributes.forEach((attribute) => { - if (attribute.hasOwnProperty('attributeName') && attribute.hasOwnProperty('schemaDataType') && attribute.hasOwnProperty('displayName')) { - if (attribute.hasOwnProperty('attributeName') && '' === attribute?.attributeName) { - throw new BadRequestException('Attribute must not be empty'); - } else if (attribute.hasOwnProperty('attributeName') && '' === attribute?.attributeName?.trim()) { - throw new BadRequestException('Attributes should not contain space'); - } else if (attribute.hasOwnProperty('schemaDataType') && '' === attribute?.schemaDataType) { - throw new BadRequestException('Schema Data Type should not contain space'); - } else if (attribute.hasOwnProperty('schemaDataType') && '' === attribute?.schemaDataType?.trim()) { - throw new BadRequestException('Schema Data Type should not contain space'); - } else if (attribute.hasOwnProperty('displayName') && '' === attribute?.displayName) { - throw new BadRequestException('Display Name Type should not contain space'); - } - } else { - throw new BadRequestException('Please provide a valid attributes'); - } - }); - schema.orgId = orgId; - const schemaDetails = await this.appService.createSchema(schema, user, schema.orgId); + const schemaCreate = await this.appService.createSchema(schema, user, schema.orgId); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, - message: 'Schema created successfully', - data: schemaDetails.response + message: schemaCreate.response }; return res.status(HttpStatus.CREATED).json(finalResponse); } diff --git a/apps/api-gateway/src/schema/schema.service.ts b/apps/api-gateway/src/schema/schema.service.ts index 84a2854b5..c3d0b710f 100644 --- a/apps/api-gateway/src/schema/schema.service.ts +++ b/apps/api-gateway/src/schema/schema.service.ts @@ -13,7 +13,7 @@ export class SchemaService extends BaseService { ) { super(`Schema Service`); } createSchema(schema: CreateSchemaDto, user: IUserRequestInterface, orgId: string): Promise<{ - response: object; + response: string; }> { const payload = { schema, user, orgId }; return this.sendNats(this.schemaServiceProxy, 'create-schema', payload); diff --git a/apps/ledger/src/schema/interfaces/schema.interface.ts b/apps/ledger/src/schema/interfaces/schema.interface.ts index 60122decd..c2f8eb05d 100644 --- a/apps/ledger/src/schema/interfaces/schema.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema.interface.ts @@ -38,4 +38,10 @@ export interface IOrgAgentInterface { walletName: string; agentsTypeId: string; orgId: string; +} + +export interface AgentDetails { + orgDid: string; + agentEndPoint: string; + tenantId: string } \ No newline at end of file diff --git a/apps/ledger/src/schema/repositories/schema.repository.ts b/apps/ledger/src/schema/repositories/schema.repository.ts index aa55d1652..f822025b8 100644 --- a/apps/ledger/src/schema/repositories/schema.repository.ts +++ b/apps/ledger/src/schema/repositories/schema.repository.ts @@ -1,9 +1,10 @@ /* eslint-disable camelcase */ -import { BadRequestException, Injectable, Logger } from '@nestjs/common'; +import { ConflictException, Injectable, Logger } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; import { ledgers, org_agents, org_agents_type, organisation, schema } from '@prisma/client'; import { ISchema, ISchemaSearchCriteria } from '../interfaces/schema-payload.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; +import { AgentDetails } from '../interfaces/schema.interface'; @Injectable() export class SchemaRepository { @@ -21,9 +22,10 @@ export class SchemaRepository { ); const schemaLength = 0; - if (schema.length !== schemaLength) { - throw new BadRequestException( - ResponseMessages.schema.error.exists + if (schema.length !== schemaLength) { + throw new ConflictException( + ResponseMessages.schema.error.exists, + { cause: new Error(), description: ResponseMessages.errorMessages.conflict } ); } const saveResult = await this.prisma.schema.create({ @@ -124,11 +126,7 @@ export class SchemaRepository { } } - async getAgentDetailsByOrgId(orgId: string): Promise<{ - orgDid: string; - agentEndPoint: string; - tenantId: string - }> { + async getAgentDetailsByOrgId(orgId: string): Promise { try { const schemasResult = await this.prisma.org_agents.findFirst({ where: { @@ -288,7 +286,7 @@ export class SchemaRepository { } } - async getLedgerByLedger(LedgerName: string): Promise { + async getLedgerByNamespace(LedgerName: string): Promise { try { return this.prisma.ledgers.findFirst({ where: { diff --git a/apps/ledger/src/schema/schema.controller.ts b/apps/ledger/src/schema/schema.controller.ts index 6683ce899..1498de554 100644 --- a/apps/ledger/src/schema/schema.controller.ts +++ b/apps/ledger/src/schema/schema.controller.ts @@ -1,8 +1,9 @@ -import { Controller } from '@nestjs/common'; +import { BadRequestException, Controller } from '@nestjs/common'; import { SchemaService } from './schema.service'; import { MessagePattern } from '@nestjs/microservices'; import { ISchema, ISchemaCredDeffSearchInterface, ISchemaSearchInterface } from './interfaces/schema-payload.interface'; import { schema } from '@prisma/client'; +import { ResponseMessages } from '@credebl/common/response-messages'; @Controller('schema') @@ -10,9 +11,16 @@ export class SchemaController { constructor(private readonly schemaService: SchemaService) { } @MessagePattern({ cmd: 'create-schema' }) - async createSchema(payload: ISchema): Promise { + async createSchema(payload: ISchema): Promise { const { schema, user, orgId } = payload; - return this.schemaService.createSchema(schema, user, orgId); + const schemaData = this.schemaService.createSchema(schema, user, orgId); + if (!schemaData) { + throw new BadRequestException( + ResponseMessages.schema.error.invalidData, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); + } + return ResponseMessages.schema.success.create; } @MessagePattern({ cmd: 'get-schema-by-id' }) diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index 0086fde1a..7f179f449 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -43,7 +43,10 @@ export class SchemaService extends BaseService { if (0 !== schemaExists.length) { this.logger.error(ResponseMessages.schema.error.exists); - throw new ConflictException(ResponseMessages.schema.error.exists); + throw new ConflictException( + ResponseMessages.schema.error.exists, + { cause: new Error(), description: ResponseMessages.errorMessages.conflict } + ); } if (null !== schema || schema !== undefined) { @@ -54,14 +57,16 @@ export class SchemaService extends BaseService { schemaVersionIndexOf ) { throw new NotAcceptableException( - ResponseMessages.schema.error.invalidVersion + ResponseMessages.schema.error.invalidVersion, + { cause: new Error(), description: ResponseMessages.errorMessages.notAcceptable } ); } const schemaAttributeLength = 0; if (schema.attributes.length === schemaAttributeLength) { - throw new NotAcceptableException( - ResponseMessages.schema.error.insufficientAttributes + throw new NotAcceptableException( + ResponseMessages.schema.error.insufficientAttributes, + { cause: new Error(), description: ResponseMessages.errorMessages.notAcceptable } ); } else if (schema.attributes.length > schemaAttributeLength) { @@ -77,7 +82,10 @@ export class SchemaService extends BaseService { .filter((value, index, element) => element.indexOf(value) !== index); if (0 < duplicateAttributeNames.length) { - throw new ConflictException(ResponseMessages.schema.error.uniqueAttributesnames); + throw new ConflictException( + ResponseMessages.schema.error.uniqueAttributesnames, + { cause: new Error(), description: ResponseMessages.errorMessages.conflict } + ); } const attributeDisplayNamesLowerCase = trimmedAttributes.map(attribute => attribute.displayName.toLocaleLowerCase()); @@ -85,7 +93,10 @@ export class SchemaService extends BaseService { .filter((value, index, element) => element.indexOf(value) !== index); if (0 < duplicateAttributeDisplayNames.length) { - throw new ConflictException(ResponseMessages.schema.error.uniqueAttributesDisplaynames); + throw new ConflictException( + ResponseMessages.schema.error.uniqueAttributesDisplaynames, + { cause: new Error(), description: ResponseMessages.errorMessages.conflict } + ); } schema.schemaName = schema.schemaName.trim(); @@ -133,7 +144,7 @@ export class SchemaService extends BaseService { const responseObj = JSON.parse(JSON.stringify(schemaResponseFromAgentService.response)); const indyNamespace = `${did.split(':')[2]}:${did.split(':')[3]}`; - const getLedgerId = await this.schemaRepository.getLedgerByLedger(indyNamespace); + const getLedgerId = await this.schemaRepository.getLedgerByNamespace(indyNamespace); const schemaDetails: ISchema = { schema: { schemaName: '', attributes: [], schemaVersion: '', id: '' }, createdBy: `0`, @@ -178,23 +189,23 @@ export class SchemaService extends BaseService { return saveResponse; } else { - throw new NotFoundException(ResponseMessages.schema.error.notCreated); + throw new NotFoundException( + ResponseMessages.schema.error.notCreated, + { cause: new Error(), description: ResponseMessages.errorMessages.notFound } + ); } } else { - throw new RpcException( - new BadRequestException( - ResponseMessages.schema.error.emptyData - ) + throw new BadRequestException( + ResponseMessages.schema.error.emptyData, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } ); } - } else { - throw new RpcException( - new BadRequestException( - ResponseMessages.schema.error.emptyData - ) + } else { + throw new BadRequestException( + ResponseMessages.schema.error.emptyData, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } ); } - } catch (error) { this.logger.error( `[createSchema] - outer Error: ${JSON.stringify(error)}` diff --git a/libs/common/src/cast.helper.ts b/libs/common/src/cast.helper.ts index 5ade7f52f..4b886c1ef 100644 --- a/libs/common/src/cast.helper.ts +++ b/libs/common/src/cast.helper.ts @@ -9,7 +9,7 @@ export function toLowerCase(value: string): string { } export function trim(value: string): string { - return value.trim(); + if ('string' === typeof value) { return value.trim(); } } export function toDate(value: string): Date { diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index c45eb1181..0d7c9b2ec 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -68,7 +68,8 @@ export const ResponseMessages = { userNotFound: 'User not found for the given organization', updateUserRoles: 'Unable to update user roles', deleteOrg: 'Organization not found', - notFound: 'Organization agent not found' + notFound: 'Organization agent not found', + orgNotFound: 'Organization not found' } }, @@ -103,6 +104,7 @@ export const ResponseMessages = { }, error: { invalidSchemaId: 'Invalid schema Id provided.', + invalidData: 'Invalid data provided.', nameNotEmpty: 'Schema name is required', versionNotEmpty: 'Schema version is required', invalidVersion: 'Invalid schema version provided.', @@ -292,5 +294,12 @@ export const ResponseMessages = { mismatchedAttributes: 'Schema attributes are mismatched in the file header.', fileDetailsNotFound: 'File details not found.' } + }, + errorMessages: { + forbidden: 'Forbidden Resource', + badRequest: 'Bad Request', + conflict: 'Conflict', + notAcceptable: 'Not Acceptable', + notFound: 'Not Found' } }; \ No newline at end of file From c02c5b0cc2c9beb69c1a9c7e169fc2b29c1754e4 Mon Sep 17 00:00:00 2001 From: Nishad Date: Wed, 20 Dec 2023 13:57:30 +0530 Subject: [PATCH 008/107] Handled negative scenarios for create schema Signed-off-by: Nishad --- apps/ledger/src/schema/schema.controller.ts | 10 ++-------- apps/ledger/src/schema/schema.service.ts | 9 +-------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/apps/ledger/src/schema/schema.controller.ts b/apps/ledger/src/schema/schema.controller.ts index 1498de554..1b790ef81 100644 --- a/apps/ledger/src/schema/schema.controller.ts +++ b/apps/ledger/src/schema/schema.controller.ts @@ -1,4 +1,4 @@ -import { BadRequestException, Controller } from '@nestjs/common'; +import { Controller } from '@nestjs/common'; import { SchemaService } from './schema.service'; import { MessagePattern } from '@nestjs/microservices'; import { ISchema, ISchemaCredDeffSearchInterface, ISchemaSearchInterface } from './interfaces/schema-payload.interface'; @@ -13,13 +13,7 @@ export class SchemaController { @MessagePattern({ cmd: 'create-schema' }) async createSchema(payload: ISchema): Promise { const { schema, user, orgId } = payload; - const schemaData = this.schemaService.createSchema(schema, user, orgId); - if (!schemaData) { - throw new BadRequestException( - ResponseMessages.schema.error.invalidData, - { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } - ); - } + await this.schemaService.createSchema(schema, user, orgId); return ResponseMessages.schema.success.create; } diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index 7f179f449..4d054f48c 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -210,15 +210,8 @@ export class SchemaService extends BaseService { this.logger.error( `[createSchema] - outer Error: ${JSON.stringify(error)}` ); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { - throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, - statusCode: error?.status?.code - }); - } else { - throw new RpcException(error.response ? error.response : error); - } + throw new RpcException(error.response ? error.response : error); } } From bbc844e99277015451afcdfd280b8ad4da2752f2 Mon Sep 17 00:00:00 2001 From: Nishad Date: Wed, 20 Dec 2023 14:07:47 +0530 Subject: [PATCH 009/107] cosmetic changes Signed-off-by: Nishad --- apps/api-gateway/src/dtos/create-schema.dto.ts | 12 ++++++------ apps/api-gateway/src/schema/schema.controller.ts | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/api-gateway/src/dtos/create-schema.dto.ts b/apps/api-gateway/src/dtos/create-schema.dto.ts index cc956644a..7b83fbd9f 100644 --- a/apps/api-gateway/src/dtos/create-schema.dto.ts +++ b/apps/api-gateway/src/dtos/create-schema.dto.ts @@ -9,31 +9,31 @@ class AttributeValue { @ApiProperty() @IsString() @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'attributeName is required.' }) + @IsNotEmpty({ message: 'attributeName is required' }) attributeName: string; @ApiProperty() @IsString() @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'schemaDataType is required.' }) + @IsNotEmpty({ message: 'schemaDataType is required' }) schemaDataType: string; @ApiProperty() @IsString() @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'displayName is required.' }) + @IsNotEmpty({ message: 'displayName is required' }) displayName: string; } export class CreateSchemaDto { @ApiProperty() - @IsString({ message: 'Schema version must be a string' }) + @IsString({ message: 'schemaVersion must be a string' }) @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'schemaVersion is required' }) schemaVersion: string; @ApiProperty() - @IsString({ message: 'schemaName should be string.' }) + @IsString({ message: 'schemaName must be a string' }) @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'schemaName is required' }) schemaName: string; @@ -48,7 +48,7 @@ export class CreateSchemaDto { } ] }) - @IsArray({ message: 'Attributes must be an array' }) + @IsArray({ message: 'attributes must be an array' }) @IsNotEmpty({ message: 'attributes are required' }) @ValidateNested({ each: true }) @Type(() => AttributeValue) diff --git a/apps/api-gateway/src/schema/schema.controller.ts b/apps/api-gateway/src/schema/schema.controller.ts index 9a536b007..036b188e5 100644 --- a/apps/api-gateway/src/schema/schema.controller.ts +++ b/apps/api-gateway/src/schema/schema.controller.ts @@ -174,11 +174,11 @@ export class SchemaController { async createSchema(@Res() res: Response, @Body() schema: CreateSchemaDto, @Param('orgId') orgId: string, @User() user: IUserRequestInterface): Promise { schema.orgId = orgId; - const schemaCreate = await this.appService.createSchema(schema, user, schema.orgId); + const schemaDetails = await this.appService.createSchema(schema, user, schema.orgId); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, - message: schemaCreate.response + message: schemaDetails.response }; return res.status(HttpStatus.CREATED).json(finalResponse); } From ccbb68170c9cfa1b83bad3a08140716f2db8b869 Mon Sep 17 00:00:00 2001 From: Moulika Kulkarni Date: Wed, 20 Dec 2023 15:41:52 +0530 Subject: [PATCH 010/107] refactor:API response Signed-off-by: Moulika Kulkarni --- .../organization/organization.controller.ts | 44 +++++++------- .../src/organization/organization.service.ts | 29 ++++----- .../interfaces/organization.interface.ts | 60 ++++++++++--------- .../repositories/organization.repository.ts | 18 +++--- .../src/organization.controller.ts | 24 ++++---- apps/organization/src/organization.service.ts | 25 ++++---- 6 files changed, 105 insertions(+), 95 deletions(-) diff --git a/apps/api-gateway/src/organization/organization.controller.ts b/apps/api-gateway/src/organization/organization.controller.ts index c82779f58..16ba7f5df 100644 --- a/apps/api-gateway/src/organization/organization.controller.ts +++ b/apps/api-gateway/src/organization/organization.controller.ts @@ -41,10 +41,10 @@ export class OrganizationController { @Get('/profile/:orgId') @ApiOperation({ summary: 'Organization Profile', description: 'Update an organization' }) @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) - async getOgPofile(@Param('orgId') orgId: string, @Res() res: Response): Promise { + async getOgPofile(@Param('orgId') orgId: string, @Res() res: Response): Promise { const orgProfile = await this.organizationService.getOgPofile(orgId); - const base64Data = orgProfile.response["logoUrl"]; + const base64Data = orgProfile['logoUrl']; const getImageBuffer = await this.imageServiceService.getBase64Image(base64Data); res.setHeader('Content-Type', 'image/png'); @@ -76,13 +76,13 @@ export class OrganizationController { type: String, required: false }) - async get(@Query() getAllUsersDto: GetAllOrganizationsDto, @Res() res: Response): Promise { + async get(@Query() getAllUsersDto: GetAllOrganizationsDto, @Res() res: Response): Promise { const users = await this.organizationService.getPublicOrganizations(getAllUsersDto); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrganizations, - data: users.response + data: users }; return res.status(HttpStatus.OK).json(finalResponse); @@ -96,7 +96,7 @@ export class OrganizationController { @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() - async getOrgRoles(@Res() res: Response): Promise { + async getOrgRoles(@Res() res: Response): Promise { const orgRoles = await this.organizationService.getOrgRoles(); @@ -121,13 +121,13 @@ export class OrganizationController { type: String, required: true }) - async getPublicProfile(@Param('orgSlug') orgSlug: string, @Res() res: Response): Promise { + async getPublicProfile(@Param('orgSlug') orgSlug: string, @Res() res: Response): Promise { const userData = await this.organizationService.getPublicProfile(orgSlug); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.fetchProfile, - data: userData.response + data: userData }; return res.status(HttpStatus.OK).json(finalResponse); @@ -141,14 +141,14 @@ export class OrganizationController { @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() - async getOrganizationDashboard(@Param('orgId') orgId: string, @Res() res: Response, @User() reqUser: user): Promise { + async getOrganizationDashboard(@Param('orgId') orgId: string, @Res() res: Response, @User() reqUser: user): Promise { const getOrganization = await this.organizationService.getOrganizationDashboard(orgId, reqUser.id); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrgDashboard, - data: getOrganization.response + data: getOrganization }; return res.status(HttpStatus.OK).json(finalResponse); @@ -175,14 +175,14 @@ export class OrganizationController { required: false }) @Roles(OrgRoles.OWNER, OrgRoles.SUPER_ADMIN, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) - async getInvitationsByOrgId(@Param('orgId') orgId: string, @Query() getAllInvitationsDto: GetAllSentInvitationsDto, @Res() res: Response): Promise { + async getInvitationsByOrgId(@Param('orgId') orgId: string, @Query() getAllInvitationsDto: GetAllSentInvitationsDto, @Res() res: Response): Promise { const getInvitationById = await this.organizationService.getInvitationsByOrgId(orgId, getAllInvitationsDto); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getInvitation, - data: getInvitationById.response + data: getInvitationById }; return res.status(HttpStatus.OK).json(finalResponse); @@ -211,14 +211,14 @@ export class OrganizationController { type: String, required: false }) - async getOrganizations(@Query() getAllOrgsDto: GetAllOrganizationsDto, @Res() res: Response, @User() reqUser: user): Promise { + async getOrganizations(@Query() getAllOrgsDto: GetAllOrganizationsDto, @Res() res: Response, @User() reqUser: user): Promise { const getOrganizations = await this.organizationService.getOrganizations(getAllOrgsDto, reqUser.id); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrganizations, - data: getOrganizations.response + data: getOrganizations }; return res.status(HttpStatus.OK).json(finalResponse); @@ -230,14 +230,14 @@ export class OrganizationController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @ApiBearerAuth() @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) - async getOrganization(@Param('orgId') orgId: string, @Res() res: Response, @User() reqUser: user): Promise { + async getOrganization(@Param('orgId') orgId: string, @Res() res: Response, @User() reqUser: user): Promise { const getOrganization = await this.organizationService.getOrganization(orgId, reqUser.id); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrganization, - data: getOrganization.response + data: getOrganization }; return res.status(HttpStatus.OK).json(finalResponse); @@ -271,12 +271,12 @@ export class OrganizationController { type: String, required: false }) - async getOrganizationUsers(@User() user: IUserRequestInterface, @Query() getAllUsersDto: GetAllUsersDto, @Param('orgId') orgId: string, @Res() res: Response): Promise { + async getOrganizationUsers(@User() user: IUserRequestInterface, @Query() getAllUsersDto: GetAllUsersDto, @Param('orgId') orgId: string, @Res() res: Response): Promise { const users = await this.organizationService.getOrgUsers(orgId, getAllUsersDto); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchUsers, - data: users?.response + data: users }; return res.status(HttpStatus.OK).json(finalResponse); @@ -287,7 +287,7 @@ export class OrganizationController { @ApiResponse({ status: 201, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() - async createOrganization(@Body() createOrgDto: CreateOrganizationDto, @Res() res: Response, @User() reqUser: user): Promise { + async createOrganization(@Body() createOrgDto: CreateOrganizationDto, @Res() res: Response, @User() reqUser: user): Promise { await this.organizationService.createOrganization(createOrgDto, reqUser.id); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, @@ -305,7 +305,7 @@ export class OrganizationController { @Roles(OrgRoles.OWNER, OrgRoles.SUPER_ADMIN, OrgRoles.ADMIN) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @ApiBearerAuth() - async createInvitation(@Body() bulkInvitationDto: BulkSendInvitationDto, @Param('orgId') orgId: string, @User() user: user, @Res() res: Response): Promise { + async createInvitation(@Body() bulkInvitationDto: BulkSendInvitationDto, @Param('orgId') orgId: string, @User() user: user, @Res() res: Response): Promise { bulkInvitationDto.orgId = orgId; await this.organizationService.createInvitation(bulkInvitationDto, user.id, user.email); @@ -325,7 +325,7 @@ export class OrganizationController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) @ApiOperation({ summary: 'Update user roles', description: 'update user roles' }) - async updateUserRoles(@Body() updateUserDto: UpdateUserRolesDto, @Param('orgId') orgId: string, @Param('userId') userId: string, @Res() res: Response): Promise { + async updateUserRoles(@Body() updateUserDto: UpdateUserRolesDto, @Param('orgId') orgId: string, @Param('userId') userId: string, @Res() res: Response): Promise { updateUserDto.orgId = orgId; updateUserDto.userId = userId; @@ -345,7 +345,7 @@ export class OrganizationController { @ApiBearerAuth() @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - async updateOrganization(@Body() updateOrgDto: UpdateOrganizationDto, @Param('orgId') orgId: string, @Res() res: Response, @User() reqUser: user): Promise { + async updateOrganization(@Body() updateOrgDto: UpdateOrganizationDto, @Param('orgId') orgId: string, @Res() res: Response, @User() reqUser: user): Promise { updateOrgDto.orgId = orgId; await this.organizationService.updateOrganization(updateOrgDto, reqUser.id, orgId); @@ -362,7 +362,7 @@ export class OrganizationController { @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) @ApiBearerAuth() @UseGuards(AuthGuard('jwt')) - async deleteOrganization(@Param('orgId') orgId: number, @Res() res: Response): Promise { + async deleteOrganization(@Param('orgId') orgId: number, @Res() res: Response): Promise { await this.organizationService.deleteOrganization(orgId); diff --git a/apps/api-gateway/src/organization/organization.service.ts b/apps/api-gateway/src/organization/organization.service.ts index 3c61914e2..48b2e6a6d 100644 --- a/apps/api-gateway/src/organization/organization.service.ts +++ b/apps/api-gateway/src/organization/organization.service.ts @@ -11,8 +11,8 @@ import { UpdateOrganizationDto } from './dtos/update-organization-dto'; import { GetAllUsersDto } from '../user/dto/get-all-users.dto'; import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; import { organisation } from '@prisma/client'; -import { GetOrgById, GetOrgs, OrgInvitationsPagination, OrganizationDashboard } from 'apps/organization/interfaces/organization.interface'; -import { OrgUsers } from 'apps/user/interfaces/user.interface'; +import { IGetOrgById, IGetOrgs, IOrgInvitationsPagination, IOrganizationDashboard } from 'apps/organization/interfaces/organization.interface'; +import { IOrgUsers } from 'apps/user/interfaces/user.interface'; @Injectable() export class OrganizationService extends BaseService { @@ -46,22 +46,23 @@ export class OrganizationService extends BaseService { * @returns Organizations details */ - async getOrganizations(getAllOrgsDto: GetAllOrganizationsDto, userId: string): Promise<{ response: GetOrgs}> { + async getOrganizations(getAllOrgsDto: GetAllOrganizationsDto, userId: string): Promise { const payload = { userId, ...getAllOrgsDto }; - return this.sendNats(this.serviceProxy, 'get-organizations', payload); + const fetchOrgs = await this.sendNats(this.serviceProxy, 'get-organizations', payload); + return fetchOrgs; } - + /** * * @param * @returns Public organizations list */ - async getPublicOrganizations(getAllOrgsDto: GetAllOrganizationsDto): Promise<{ response: GetOrgs }> { + async getPublicOrganizations(getAllOrgsDto: GetAllOrganizationsDto): Promise { const payload = { ...getAllOrgsDto }; return this.sendNats(this.serviceProxy, 'get-public-organizations', payload); } - async getPublicProfile(orgSlug: string): Promise<{ response: GetOrgById }> { + async getPublicProfile(orgSlug: string): Promise { const payload = { orgSlug }; try { return this.sendNats(this.serviceProxy, 'get-organization-public-profile', payload); @@ -75,7 +76,7 @@ export class OrganizationService extends BaseService { * @param orgId * @returns Organization get Success */ - async getOrganization(orgId: string, userId: string): Promise<{ response: GetOrgById }> { + async getOrganization(orgId: string, userId: string): Promise { const payload = { orgId, userId }; return this.sendNats(this.serviceProxy, 'get-organization-by-id', payload); } @@ -88,13 +89,13 @@ export class OrganizationService extends BaseService { async getInvitationsByOrgId( orgId: string, getAllInvitationsDto: GetAllSentInvitationsDto - ): Promise<{ response: OrgInvitationsPagination }> { + ): Promise { const { pageNumber, pageSize, search } = getAllInvitationsDto; const payload = { orgId, pageNumber, pageSize, search }; return this.sendNats(this.serviceProxy, 'get-invitations-by-orgId', payload); } - async getOrganizationDashboard(orgId: string, userId: string): Promise<{ response: OrganizationDashboard }> { + async getOrganizationDashboard(orgId: string, userId: string): Promise { const payload = { orgId, userId }; return this.sendNats(this.serviceProxy, 'get-organization-dashboard', payload); } @@ -126,7 +127,7 @@ export class OrganizationService extends BaseService { * @param userId * @returns User roles update response */ - async updateUserRoles(updateUserDto: UpdateUserRolesDto, userId: string): Promise<{ response: boolean }> { + async updateUserRoles(updateUserDto: UpdateUserRolesDto, userId: string): Promise { const payload = { orgId: updateUserDto.orgId, roleIds: updateUserDto.orgRoleId, userId }; return this.sendNats(this.serviceProxy, 'update-user-roles', payload); } @@ -134,7 +135,7 @@ export class OrganizationService extends BaseService { async getOrgUsers( orgId: string, getAllUsersDto: GetAllUsersDto - ): Promise<{ response: OrgUsers }> { + ): Promise { const { pageNumber, pageSize, search } = getAllUsersDto; const payload = { orgId, pageNumber, pageSize, search }; @@ -143,7 +144,7 @@ export class OrganizationService extends BaseService { async getOgPofile( orgId: string - ): Promise<{ response: organisation }> { + ): Promise { const payload = { orgId }; return this.sendNats(this.serviceProxy, 'fetch-organization-profile', payload); @@ -151,7 +152,7 @@ export class OrganizationService extends BaseService { async deleteOrganization( orgId: number - ): Promise<{ response: boolean }> { + ): Promise { const payload = { orgId }; return this.sendNats(this.serviceProxy, 'delete-organization', payload); diff --git a/apps/organization/interfaces/organization.interface.ts b/apps/organization/interfaces/organization.interface.ts index 9a6d40dd8..804b27b65 100644 --- a/apps/organization/interfaces/organization.interface.ts +++ b/apps/organization/interfaces/organization.interface.ts @@ -3,7 +3,7 @@ export interface IUserOrgRoles { userId: string orgRoleId: string orgId: string | null, - orgRole: OrgRole + orgRole: IOrgRole } export interface IUpdateOrganization { @@ -18,13 +18,13 @@ export interface IUpdateOrganization { } -export interface OrgAgent { +export interface IOrgAgent { url: string; apiKey: string; } -export interface GetOrgById { +export interface IGetOrgById { id: string; name: string; description: string; @@ -32,76 +32,76 @@ export interface GetOrgById { logoUrl: string; website: string; publicProfile: boolean; - schema: Schema[]; - org_agents: OrgAgents[]; + schema: ISchema[]; + org_agents: IOrgAgents[]; } -interface Schema { +interface ISchema { id: string; name: string; } -interface OrgAgents { - agent_invitations: AgentInvitation[]; - ledgers: Ledgers; - org_agent_type: OrgAgentType; +interface IOrgAgents { + agent_invitations: IAgentInvitation[]; + ledgers: ILedgers; + org_agent_type: IOrgAgentType; } -interface AgentInvitation { +interface IAgentInvitation { id: string; connectionInvitation: string; multiUse: boolean; } -export interface UserOrgRole { +export interface IUserOrgRole { user: string; orgRole: string; } -interface OrgAgentType { +interface IOrgAgentType { id: string; createDateTime: Date; lastChangedDateTime: Date; agent: string; } -interface Ledgers { +interface ILedgers { id: string; name: string; networkType: string } -export interface GetOrgs { +export interface IGetOrgs { totalPages:number; - organizations : AllOrganizations[]; + organizations : IAllOrganizations[]; } -interface AllOrganizations { +interface IAllOrganizations { id: string, name: string, description: string, logoUrl: string, orgSlug: string, - userOrgRoles: UserOrgRoles[]; + userOrgRoles: IUserOrganizationRoles[]; } -interface UserOrgRoles { +interface IUserOrganizationRoles { id: string, - orgRole :OrgRole; + orgRole :IOrgRole; } -export interface OrgRole { +export interface IOrgRole { id: string name: string description: string } -export interface OrgInvitationsPagination { +export interface IOrgInvitationsPagination { totalPages: number; - invitations: Invitation[]; + invitations: IInvitation[]; } -interface Invitation { +interface IInvitation { id: string, orgId: string, email: string, @@ -110,18 +110,24 @@ interface Invitation { orgRoles: string[], createDateTime: Date, createdBy:string, - organisation: OrganizationPagination; + organisation: IOrganizationPagination; } -interface OrganizationPagination { +interface IOrganizationPagination { id: string; name: string; logoUrl: string; } -export interface OrganizationDashboard { +export interface IOrganizationDashboard { usersCount: number, schemasCount: number, credentialsCount: number, presentationsCount:number +} + +export interface Payload { + pageNumber: number; + pageSize: number; + search: string; } \ No newline at end of file diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index c271658b2..d7b3fdb15 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -6,7 +6,7 @@ import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { org_agents, org_invitations, user_org_roles } from '@prisma/client'; import { CreateOrganizationDto } from '../dtos/create-organization.dto'; -import { GetOrgById, GetOrgs, IUpdateOrganization, OrgInvitationsPagination, OrganizationDashboard } from '../interfaces/organization.interface'; +import { IGetOrgById, IGetOrgs, IOrgInvitationsPagination, IOrganizationDashboard, IUpdateOrganization } from '../interfaces/organization.interface'; import { InternalServerErrorException } from '@nestjs/common'; import { Invitation } from '@credebl/enum/enum'; import { PrismaService } from '@credebl/prisma-service'; @@ -49,7 +49,7 @@ export class OrganizationRepository { async createOrganization(createOrgDto: CreateOrganizationDto): Promise { try { - return this.prisma.organisation.create({ + const orgData = this.prisma.organisation.create({ data: { name: createOrgDto.name, logoUrl: createOrgDto.logo, @@ -61,6 +61,7 @@ export class OrganizationRepository { lastChangedBy: createOrgDto.lastChangedBy } }); + return orgData; } catch (error) { this.logger.error(`error: ${JSON.stringify(error)}`); throw new InternalServerErrorException(error); @@ -176,7 +177,7 @@ export class OrganizationRepository { pageNumber: number, pageSize: number, search = '' - ): Promise { + ): Promise { this.logger.log(search); const query = { @@ -204,7 +205,7 @@ export class OrganizationRepository { } } - async getOrgInvitationsPagination(queryObject: object, pageNumber: number, pageSize: number): Promise { + async getOrgInvitationsPagination(queryObject: object, pageNumber: number, pageSize: number): Promise { try { const result = await this.prisma.$transaction([ this.prisma.org_invitations.findMany({ @@ -252,7 +253,7 @@ export class OrganizationRepository { } } - async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search = ''): Promise { + async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search = ''): Promise { try { const query = { orgId, @@ -269,7 +270,7 @@ export class OrganizationRepository { } } - async getOrganization(queryObject: object): Promise { + async getOrganization(queryObject: object): Promise { try { return this.prisma.organisation.findFirst({ where: { @@ -316,6 +317,7 @@ export class OrganizationRepository { } } } + } }); } catch (error) { @@ -324,7 +326,7 @@ export class OrganizationRepository { } } - async getOrgDashboard(orgId: string): Promise { + async getOrgDashboard(orgId: string): Promise { const query = { where: { @@ -420,7 +422,7 @@ export class OrganizationRepository { filterOptions: object, pageNumber: number, pageSize: number - ): Promise { + ): Promise { try { const sortByName = 'asc'; const result = await this.prisma.$transaction([ diff --git a/apps/organization/src/organization.controller.ts b/apps/organization/src/organization.controller.ts index 6cfb41469..7e37b7dd5 100644 --- a/apps/organization/src/organization.controller.ts +++ b/apps/organization/src/organization.controller.ts @@ -6,7 +6,7 @@ import { Body } from '@nestjs/common'; import { CreateOrganizationDto } from '../dtos/create-organization.dto'; import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; -import { GetOrgById, GetOrgs, IUpdateOrganization, OrgInvitationsPagination, OrganizationDashboard } from '../interfaces/organization.interface'; +import { IGetOrgById, IGetOrgs, IOrgInvitationsPagination, IOrganizationDashboard, IUpdateOrganization, Payload } from '../interfaces/organization.interface'; import { organisation } from '@prisma/client'; import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; @@ -44,8 +44,8 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'get-organizations' }) async getOrganizations( - @Body() payload: { userId: string; pageNumber: number; pageSize: number; search: string } - ): Promise { + @Body() payload: { userId: string} & Payload + ): Promise { const { userId, pageNumber, pageSize, search } = payload; return this.organizationService.getOrganizations(userId, pageNumber, pageSize, search); } @@ -57,8 +57,8 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'get-public-organizations' }) async getPublicOrganizations( - @Body() payload: { pageNumber: number; pageSize: number; search: string } - ): Promise { + @Body() payload: Payload + ): Promise { const { pageNumber, pageSize, search } = payload; return this.organizationService.getPublicOrganizations(pageNumber, pageSize, search); } @@ -69,12 +69,12 @@ export class OrganizationController { * @returns Get created organization details */ @MessagePattern({ cmd: 'get-organization-by-id' }) - async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise { + async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise { return this.organizationService.getOrganization(payload.orgId); } @MessagePattern({ cmd: 'get-organization-public-profile' }) - async getPublicProfile(payload: { orgSlug }): Promise { + async getPublicProfile(payload: { orgSlug }): Promise { return this.organizationService.getPublicProfile(payload); } @@ -85,8 +85,8 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'get-invitations-by-orgId' }) async getInvitationsByOrgId( - @Body() payload: { orgId: string; pageNumber: number; pageSize: number; search: string } - ): Promise { + @Body() payload: { orgId: string } & Payload + ): Promise { return this.organizationService.getInvitationsByOrgId( payload.orgId, payload.pageNumber, @@ -119,8 +119,8 @@ export class OrganizationController { @MessagePattern({ cmd: 'fetch-user-invitations' }) async fetchUserInvitation( - @Body() payload: { email: string; status: string; pageNumber: number; pageSize: number; search: string } - ): Promise { + @Body() payload: { email: string; status: string } & Payload + ): Promise { return this.organizationService.fetchUserInvitation( payload.email, payload.status, @@ -152,7 +152,7 @@ export class OrganizationController { } @MessagePattern({ cmd: 'get-organization-dashboard' }) - async getOrgDashboard(payload: { orgId: string; userId: string }): Promise { + async getOrgDashboard(payload: { orgId: string; userId: string }): Promise { return this.organizationService.getOrgDashboard(payload.orgId); } diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index a1012fd0b..f15bc040c 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -18,7 +18,7 @@ import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; import { NotFoundException } from '@nestjs/common'; import { Invitation, OrgAgentType } from '@credebl/enum/enum'; -import { GetOrgById, GetOrgs, IUpdateOrganization, OrgAgent, OrgInvitationsPagination, OrganizationDashboard } from '../interfaces/organization.interface'; +import { IGetOrgById, IGetOrgs, IOrgInvitationsPagination, IOrganizationDashboard, IUpdateOrganization, IOrgAgent } from '../interfaces/organization.interface'; import { UserActivityService } from '@credebl/user-activity'; import { CommonConstants } from '@credebl/common/common.constant'; import { map } from 'rxjs/operators'; @@ -120,7 +120,7 @@ export class OrganizationService { * @returns Get created organizations details */ - async getOrganizations(userId: string, pageNumber: number, pageSize: number, search: string): Promise { + async getOrganizations(userId: string, pageNumber: number, pageSize: number, search: string): Promise { try { const query = { @@ -137,12 +137,13 @@ export class OrganizationService { userId }; - return this.organizationRepository.getOrganizations( + const getOrgs = await this.organizationRepository.getOrganizations( query, filterOptions, pageNumber, pageSize ); + return getOrgs; } catch (error) { this.logger.error(`In fetch getOrganizations : ${JSON.stringify(error)}`); @@ -156,7 +157,7 @@ export class OrganizationService { * @returns Get public organizations details */ - async getPublicOrganizations(pageNumber: number, pageSize: number, search: string): Promise { + async getPublicOrganizations(pageNumber: number, pageSize: number, search: string): Promise { try { const query = { @@ -182,7 +183,7 @@ export class OrganizationService { } } - async getPublicProfile(payload: { orgSlug: string }): Promise { + async getPublicProfile(payload: { orgSlug: string }): Promise { const { orgSlug } = payload; try { @@ -196,8 +197,8 @@ export class OrganizationService { throw new NotFoundException(ResponseMessages.organisation.error.profileNotFound); } - const credentials = await this.organizationRepository.getCredDefByOrg(organizationDetails.id); - organizationDetails['credential_definitions'] = credentials; + const credDefs = await this.organizationRepository.getCredDefByOrg(organizationDetails.id); + organizationDetails['credential_definitions'] = credDefs; return organizationDetails; } catch (error) { @@ -212,7 +213,7 @@ export class OrganizationService { * @returns Get created organization details */ - async getOrganization(orgId: string): Promise { + async getOrganization(orgId: string): Promise { try { const query = { @@ -233,7 +234,7 @@ export class OrganizationService { * @returns Get created invitation details */ - async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { + async getInvitationsByOrgId(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { try { const getOrganization = await this.organizationRepository.getInvitationsByOrgId(orgId, pageNumber, pageSize, search); for await (const item of getOrganization['invitations']) { @@ -398,7 +399,7 @@ export class OrganizationService { return false; } - async fetchUserInvitation(email: string, status: string, pageNumber: number, pageSize: number, search = ''): Promise { + async fetchUserInvitation(email: string, status: string, pageNumber: number, pageSize: number, search = ''): Promise { try { return this.organizationRepository.getAllOrgInvitations(email, status, pageNumber, pageSize, search); } catch (error) { @@ -479,7 +480,7 @@ export class OrganizationService { } } - async getOrgDashboard(orgId: string): Promise { + async getOrgDashboard(orgId: string): Promise { try { return this.organizationRepository.getOrgDashboard(orgId); } catch (error) { @@ -535,7 +536,7 @@ export class OrganizationService { } } - async _deleteWallet(payload: OrgAgent): Promise<{ + async _deleteWallet(payload: IOrgAgent): Promise<{ response; }> { try { From 57d054de1667a8b70c54275da215a2148e8a527d Mon Sep 17 00:00:00 2001 From: Moulika Kulkarni Date: Wed, 20 Dec 2023 15:43:35 +0530 Subject: [PATCH 011/107] refactor:API response Signed-off-by: Moulika Kulkarni --- apps/user/interfaces/user.interface.ts | 15 ++++++++++++++- apps/user/repositories/user.repository.ts | 4 ++-- apps/user/src/user.controller.ts | 4 ++-- apps/user/src/user.service.ts | 4 ++-- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index bf7c8d02c..0ecf339b9 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -74,7 +74,7 @@ export interface Attribute { label: string } - export interface OrgUsers { + export interface IOrgUsers { totalPages: number, users: OrgUser[] } @@ -121,3 +121,16 @@ export interface Attribute { createDateTime: Date, orgAgentTypeId:string } + + export interface Payload { + pageNumber: number; + pageSize: number; + search: string; + } + + // export interface OrgUsersPayload { + // orgId: string; + // pageNumber: number; + // pageSize: number; + // search: string; + // } diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index 8cf752347..a76988d73 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -2,7 +2,7 @@ import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { - OrgUsers, + IOrgUsers, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, @@ -330,7 +330,7 @@ export class UserRepository { pageNumber: number, pageSize: number, filterOptions?: object - ): Promise { + ): Promise { const result = await this.prisma.$transaction([ this.prisma.user.findMany({ where: { diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 1470ddf0b..f7f2ca6d4 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, OrgUsers, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, UserEmailVerificationDto, UserI, userInfo } from '../interfaces/user.interface'; +import { AddPasskeyDetails, IOrgUsers, Payload, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, UserEmailVerificationDto, UserI, userInfo } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { Controller } from '@nestjs/common'; @@ -103,7 +103,7 @@ export class UserController { * @returns organization users list */ @MessagePattern({ cmd: 'fetch-organization-user' }) - async getOrganizationUsers(payload: { orgId: string, pageNumber: number, pageSize: number, search: string }): Promise { + async getOrganizationUsers(payload: {orgId:string} & Payload): Promise { return this.userService.getOrgUsers(payload.orgId, payload.pageNumber, payload.pageSize, payload.search); } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index dca7ad199..7fe731971 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -29,8 +29,8 @@ import { user } from '@prisma/client'; import { AddPasskeyDetails, Attribute, + IOrgUsers, InvitationsI, - OrgUsers, PlatformSettingsI, ShareUserCertificateI, UpdateUserProfile, @@ -676,7 +676,7 @@ export class UserService { * @param orgId * @returns users list */ - async getOrgUsers(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { + async getOrgUsers(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { try { const query = { userOrgRoles: { From 368aa9a0d78c49ff00de9a1e030f6091ab6b9893 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Wed, 20 Dec 2023 18:23:01 +0530 Subject: [PATCH 012/107] Added the token and store on the database Signed-off-by: KulkarniShashank --- .../AFJ/scripts/start_agent.sh | 23 +++++-- .../src/agent-provisioning.service.ts | 12 +++- .../src/agent-service.service.ts | 69 ++++++++++--------- .../repositories/agent-service.repository.ts | 12 ++-- apps/ecosystem/src/ecosystem.repository.ts | 2 - 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/apps/agent-provisioning/AFJ/scripts/start_agent.sh b/apps/agent-provisioning/AFJ/scripts/start_agent.sh index 4a793ea12..f8aea1778 100755 --- a/apps/agent-provisioning/AFJ/scripts/start_agent.sh +++ b/apps/agent-provisioning/AFJ/scripts/start_agent.sh @@ -76,7 +76,7 @@ else mkdir ${PWD}/apps/agent-provisioning/AFJ/endpoints fi -docker build . -t $AFJ_VERSION -f apps/agent-provisioning/AFJ/afj-controller/Dockerfile +# docker build . -t $AFJ_VERSION -f apps/agent-provisioning/AFJ/afj-controller/Dockerfile AGENT_ENDPOINT="${PROTOCOL}://${EXTERNAL_IP}:${INBOUND_PORT}" @@ -152,7 +152,7 @@ if [ $? -eq 0 ]; then echo "container-name::::::${CONTAINER_NAME}" echo "file-name::::::$FILE_NAME" - docker-compose -f $FILE_NAME --project-name ${AGENCY}_${CONTAINER_NAME} up -d + docker compose -f ${FILE_NAME} up -d if [ $? -eq 0 ]; then n=0 @@ -177,10 +177,25 @@ if [ $? -eq 0 ]; then done echo "Creating agent config" + + # Capture the logs from the container + container_logs=$(docker logs $(docker ps -q --filter "name=${AGENCY}_${CONTAINER_NAME}")) + + # Extract the token from the logs using grep and awk (modify the pattern as needed) + token=$(echo "$container_logs" | grep -oE 'token [^ ]+' | awk '{print $2}') + + # Print the extracted token + echo "Token: $token" + cat <>${PWD}/endpoints/${AGENCY}_${CONTAINER_NAME}.json { - "CONTROLLER_ENDPOINT":"${EXTERNAL_IP}:${ADMIN_PORT}", - "AGENT_ENDPOINT" : "${INTERNAL_IP}:${ADMIN_PORT}" + "CONTROLLER_ENDPOINT":"${EXTERNAL_IP}:${ADMIN_PORT}" + } +EOF + + cat <>${PWD}/token/${AGENCY}_${CONTAINER_NAME}.json + { + "token" : "$token" } EOF echo "Agent config created" diff --git a/apps/agent-provisioning/src/agent-provisioning.service.ts b/apps/agent-provisioning/src/agent-provisioning.service.ts index 447e71e55..7dc510df5 100644 --- a/apps/agent-provisioning/src/agent-provisioning.service.ts +++ b/apps/agent-provisioning/src/agent-provisioning.service.ts @@ -22,7 +22,7 @@ export class AgentProvisioningService { async walletProvision(payload: IWalletProvision): Promise { try { - const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, afjVersion, tenant, indyLedger, apiKey} = payload; + const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, afjVersion, tenant, indyLedger, apiKey } = payload; if (agentType === AgentType.AFJ) { // The wallet provision command is used to invoke a shell script const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${afjVersion} ${indyLedger} ${apiKey} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`; @@ -33,8 +33,14 @@ export class AgentProvisioningService { if (stderr) { this.logger.log(`shell script error: ${stderr}`); } - const agentEndPoint: string = await fs.readFileSync(`${process.env.PWD}${process.env.AFJ_AGENT_ENDPOINT_PATH}${orgId}_${containerName}.json`, 'utf8'); - resolve(agentEndPoint); + + const agentEndPoint = await fs.readFileSync(`${process.cwd()}${process.env.AFJ_AGENT_ENDPOINT_PATH}${orgId}_${containerName}.json`, 'utf8'); + const agentToken = await fs.readFileSync(`${process.cwd()}${process.env.AFJ_AGENT_TOKEN_PATH}${orgId}_${containerName}.json`, 'utf8'); + + resolve({ + agentEndPoint: JSON.parse(agentEndPoint).CONTROLLER_ENDPOINT, + agentToken: JSON.parse(agentToken).token + }); }); }); return spinUpResponse; diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 5843d80cb..b9d80ae24 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -172,10 +172,9 @@ export class AgentServiceService { agentSpinupDto.ledgerId = agentSpinupDto.ledgerId?.length ? agentSpinupDto.ledgerId : ledgerIdData.map(ledger => ledger.id); const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { - // throw new BadRequestException('Your wallet has already been created.'); + await this.getOrgAgentApiKey(agentSpinupDto.orgId); const data = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.debug(`API key from cache==============:::${data}`); throw new BadRequestException('Your wallet has already been created.'); } @@ -191,10 +190,6 @@ export class AgentServiceService { } } - - // TODO Add logic to generate API key - agentSpinupDto.apiKey = "eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc"; - agentSpinupDto.agentType = agentSpinupDto.agentType || getAgentType; agentSpinupDto.tenant = agentSpinupDto.tenant || false; agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]; @@ -204,20 +199,18 @@ export class AgentServiceService { const externalIp = platformConfig?.externalIp; const controllerIp = platformConfig?.lastInternalId !== 'false' ? platformConfig?.lastInternalId : ''; const apiEndpoint = platformConfig?.apiEndpoint; - const apiKey = "eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc"; - + const walletProvisionPayload = await this.prepareWalletProvisionPayload(agentSpinupDto, externalIp, apiEndpoint, controllerIp, ledgerDetails, platformConfig, orgData); const socket: Socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); this.emitAgentSpinupInitiatedEvent(agentSpinupDto, socket); const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; - /* eslint-disable no-param-reassign */ - agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId, apiKey); + agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId); + - this.validateAgentProcess(agentProcess); - this._agentSpinup(walletProvisionPayload, agentSpinupDto, apiKey, orgData, user, socket, agentSpinupDto.ledgerId, agentProcess); + this._agentSpinup(walletProvisionPayload, agentSpinupDto, orgData, user, socket, agentSpinupDto.ledgerId, agentProcess); } catch (error) { this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess); @@ -304,7 +297,7 @@ export class AgentServiceService { afjVersion: process.env.AFJ_VERSION || '', protocol: process.env.AGENT_PROTOCOL || '', tenant: agentSpinupDto.tenant || false, - apiKey:agentSpinupDto.apiKey + apiKey: agentSpinupDto.apiKey }; return walletProvisionPayload; @@ -322,9 +315,9 @@ export class AgentServiceService { return socket; } - async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus, userId: string, apiKey:string): Promise { + async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus, userId: string): Promise { try { - const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, userId, apiKey); + const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, userId); this.logger.log(`Organization agent created with status: ${agentSpinUpStatus}`); return agentProcess; } catch (error) { @@ -357,7 +350,7 @@ export class AgentServiceService { } } - async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: org_agents): Promise { + async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: org_agents): Promise { try { const walletProvision = await this._walletProvision(walletProvisionPayload); @@ -365,10 +358,8 @@ export class AgentServiceService { if (!walletProvision?.response) { throw new BadRequestException('Agent not able to spin-up'); } - - const agentDetails = JSON.parse(walletProvision.response); - - const agentEndPoint = `${process.env.API_GATEWAY_PROTOCOL}://${agentDetails.CONTROLLER_ENDPOINT}`; + const agentDetails = walletProvision.response; + const agentEndPoint = `${process.env.API_GATEWAY_PROTOCOL}://${agentDetails.agentEndPoint}`; const socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); @@ -381,7 +372,7 @@ export class AgentServiceService { const agentPayload: IStoreOrgAgentDetails = { agentEndPoint, seed: agentSpinupDto.seed, - apiKey: orgApiKey, + apiKey: agentDetails.agentToken, agentsTypeId: agentSpinupDto?.agentType, orgId: orgData.id, walletName: agentSpinupDto.walletName, @@ -394,6 +385,19 @@ export class AgentServiceService { const storeAgentDetails = await this._storeOrgAgentDetails(agentPayload); if (storeAgentDetails) { + + const filePath = `${process.cwd()}${process.env.AFJ_AGENT_TOKEN_PATH}${orgData.id}_${orgData.name.split(' ').join('_')}.json`; + if (agentDetails?.agentToken) { + fs.unlink(filePath, (err) => { + if (err) { + this.logger.error(`Error removing file: ${err.message}`); + throw new InternalServerErrorException(err.message); + } else { + this.logger.log(`File ${filePath} has been removed successfully`); + } + }); + } + if (agentSpinupDto.clientSocketId) { socket.emit('did-publish-process-completed', { clientId: agentSpinupDto.clientSocketId }); } @@ -438,7 +442,7 @@ export class AgentServiceService { } } - + private async _getAgentDid(payload: IStoreOrgAgentDetails): Promise { const { agentEndPoint, apiKey, seed, ledgerId, did } = payload; const writeDid = 'write-did'; @@ -466,7 +470,8 @@ export class AgentServiceService { agentId: payload.agentId, orgAgentTypeId, ledgerId: payload.ledgerId, - id: payload.id + id: payload.id, + apiKey: payload.apiKey }; } @@ -497,8 +502,6 @@ export class AgentServiceService { try { return retry(async () => { if (agentApiState === 'write-did') { - // return this.commonService.httpPost(agentUrl, { seed, method: indyNamespace, did }, { headers: { 'authorization': apiKey } }); - // eslint-disable-next-line object-shorthand return this.commonService.httpPost(agentUrl, { seed, method: indyNamespace, did }, { headers: { 'authorization': apiKey } }); } else if (agentApiState === 'get-did-doc') { return this.commonService.httpGet(agentUrl, { headers: { 'authorization': apiKey } }); @@ -603,8 +606,7 @@ export class AgentServiceService { payload.ledgerId = !payload.ledgerId || 0 === payload.ledgerId?.length ? ledgerIds : payload.ledgerId; const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; //TODO take API key from API gereration function - const apiKey = "eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc"; - agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user.id, apiKey); + agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user.id); const platformAdminSpinnedUp = await this.getPlatformAdminAndNotify(payload.clientSocketId); @@ -687,11 +689,10 @@ export class AgentServiceService { method: ledgerIds.indyNamespace }; - const apiKey = 'eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwMDgzNzY3OSwiaWF0IjoxNzAwODM3Njc5fQ.bJlL2_QiNSzEMn3C-M0gLdQqa2wIzFY7WZMov6iBiyc'; const tenantDetails = await this.commonService.httpPost( `${platformAdminSpinnedUp.org_agents[0].agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_TENANT}`, createTenantOptions, - { headers: { 'authorization': apiKey } } + { headers: { 'authorization': platformAdminSpinnedUp.org_agents[0].apiKey } } ); this.logger.debug(`API Response Data: ${JSON.stringify(tenantDetails)}`); @@ -986,16 +987,16 @@ export class AgentServiceService { async getAgentHealthDetails(orgId: string, apiKey: string): Promise { try { const orgAgentDetails: org_agents = await this.agentServiceRepository.getOrgAgentDetails(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this.getOrgAgentApiKey(orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this.getOrgAgentApiKey(orgId); } if (apiKey === undefined || null) { apiKey = await this.getOrgAgentApiKey(orgId); } - + if (!orgAgentDetails) { throw new NotFoundException(ResponseMessages.agent.error.agentNotExists); } @@ -1119,7 +1120,7 @@ export class AgentServiceService { async getOrgAgentApiKey(orgId: string): Promise { try { const orgAgentApiKey = await this.agentServiceRepository.getAgentApiKey(orgId); - + if (!orgAgentApiKey) { throw new NotFoundException(ResponseMessages.agent.error.apiKeyNotExist); } diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 71adc3d50..a7420fceb 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -68,14 +68,13 @@ export class AgentServiceRepository { } // eslint-disable-next-line camelcase - async createOrgAgent(agentSpinUpStatus: number, userId: string, apiKey: string): Promise { + async createOrgAgent(agentSpinUpStatus: number, userId: string): Promise { try { return this.prisma.org_agents.create({ data: { agentSpinUpStatus, createdBy: userId, - lastChangedBy: userId, - apiKey + lastChangedBy: userId } }); } catch (error) { @@ -122,7 +121,8 @@ export class AgentServiceRepository { agentId: storeOrgAgentDetails.agentId ? storeOrgAgentDetails.agentId : null, orgAgentTypeId: storeOrgAgentDetails.orgAgentTypeId ? storeOrgAgentDetails.orgAgentTypeId : null, tenantId: storeOrgAgentDetails.tenantId ? storeOrgAgentDetails.tenantId : null, - ledgerId: storeOrgAgentDetails.ledgerId[0] + ledgerId: storeOrgAgentDetails.ledgerId[0], + apiKey: storeOrgAgentDetails.apiKey } }); } catch (error) { @@ -139,13 +139,13 @@ export class AgentServiceRepository { // eslint-disable-next-line camelcase async getAgentDetails(orgId: string): Promise { try { - const x = await this.prisma.org_agents.findFirst({ + const getAgentDetails = await this.prisma.org_agents.findFirst({ where: { orgId } }); - return x; + return getAgentDetails; } catch (error) { this.logger.error(`[getAgentDetails] - get agent details: ${JSON.stringify(error)}`); throw error; diff --git a/apps/ecosystem/src/ecosystem.repository.ts b/apps/ecosystem/src/ecosystem.repository.ts index f6ceeb140..090583dbf 100644 --- a/apps/ecosystem/src/ecosystem.repository.ts +++ b/apps/ecosystem/src/ecosystem.repository.ts @@ -65,8 +65,6 @@ export class EcosystemRepository { status: EcosystemOrgStatus.ACTIVE, ecosystemId: createdEcosystem.id, ecosystemRoleId: ecosystemRoleDetails.id, - orgName, - orgDid, deploymentMode: DeploymentModeType.PROVIDER_HOSTED, createdBy: userId, lastChangedBy: userId From 47f347d99b0ac8bbfa6d0f5afd37fbd3c9aeaae4 Mon Sep 17 00:00:00 2001 From: Nishad Date: Wed, 20 Dec 2023 18:32:01 +0530 Subject: [PATCH 013/107] handled agent errors in the schema service Signed-off-by: Nishad --- .../src/agent-service.service.ts | 14 ++- apps/api-gateway/common/exception-handler.ts | 107 +++++------------- apps/api-gateway/common/interface.ts | 6 + apps/ledger/src/schema/schema.service.ts | 23 ++-- libs/common/src/response-messages/index.ts | 9 +- 5 files changed, 66 insertions(+), 93 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 8659486c1..6088a7cce 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -720,6 +720,12 @@ export class AgentServiceService { .then(async (schema) => { this.logger.debug(`API Response Data: ${JSON.stringify(schema)}`); return schema; + }) + .catch(error => { + throw new InternalServerErrorException( + ResponseMessages.agent.error.agentDown, + { cause: new Error(), description: ResponseMessages.errorMessages.serverError } + ); }); } else if (OrgAgentType.SHARED === payload.agentType) { @@ -735,12 +741,18 @@ export class AgentServiceService { .then(async (schema) => { this.logger.debug(`API Response Data: ${JSON.stringify(schema)}`); return schema; + }) + .catch(error => { + throw new InternalServerErrorException( + ResponseMessages.agent.error.agentDown, + { cause: new Error(), description: ResponseMessages.errorMessages.serverError } + ); }); } return schemaResponse; } catch (error) { this.logger.error(`Error in creating schema: ${error}`); - throw error; + throw new RpcException(error.response ? error.response : error); } } diff --git a/apps/api-gateway/common/exception-handler.ts b/apps/api-gateway/common/exception-handler.ts index afaf5f4ea..df5928a20 100644 --- a/apps/api-gateway/common/exception-handler.ts +++ b/apps/api-gateway/common/exception-handler.ts @@ -1,6 +1,7 @@ import { Catch, ArgumentsHost, HttpException, HttpStatus, Logger } from '@nestjs/common'; import { BaseExceptionFilter } from '@nestjs/core'; -import { isArray } from 'class-validator'; +import { ExceptionResponse } from './interface'; +import { ResponseMessages } from '@credebl/common/response-messages'; @Catch() export class CustomExceptionFilter extends BaseExceptionFilter { @@ -8,93 +9,41 @@ export class CustomExceptionFilter extends BaseExceptionFilter { catch(exception: HttpException, host: ArgumentsHost): void { const ctx = host.switchToHttp(); const response = ctx.getResponse(); - + + let errorResponse; let status = HttpStatus.INTERNAL_SERVER_ERROR; - if (exception instanceof HttpException) { - status = exception.getStatus(); - } - + this.logger.error(`exception ::: ${JSON.stringify(exception)}`); - if ("Cannot read properties of undefined (reading 'response')" === exception.message) { - exception.message = 'Oops! Something went wrong. Please try again'; - } - - let errorResponse; - if (isArray(exception)) { + if (!exception || '{}' === JSON.stringify(exception)) { errorResponse = { statusCode: status, - message: exception[0], - error: exception[0] - }; - } else if (exception && exception['statusCode'] === HttpStatus.INTERNAL_SERVER_ERROR) { - if (exception.message && exception.message['message']) { - errorResponse = { - statusCode: status, - message: exception.message['message'], - error: exception.message['message'] - }; - } else { - errorResponse = { - statusCode: status, - message: 'Oops! Something went wrong. Please try again', - error: 'Oops! Something went wrong. Please try again' - }; - } - } else if ( - exception && - exception['error'] && - exception['error'].message && - (exception['error'].statusCode || exception['error'].code) - ) { - const statusCode = exception['error'].statusCode || exception['error'].code || status; - errorResponse = { - statusCode, - message: exception['error'].message || 'Internal server error', - error: exception['error'].message || 'Internal server error' - }; - } else if (exception && exception['statusCode'] === undefined && status === HttpStatus.INTERNAL_SERVER_ERROR) { - errorResponse = { - statusCode: status, - message: 'Oops! Something went wrong. Please try again', - error: 'Oops! Something went wrong. Please try again' + message: 'Something went wrong!', + error: ResponseMessages.errorMessages.serverError }; + } + if (exception instanceof HttpException) { + status = exception.getStatus(); + } + + let exceptionResponse: ExceptionResponse; + + if (exception['response']) { + exceptionResponse = exception['response']; } else { - if (exception && exception['response'] && exception.message) { - if (Array.isArray(exception['response'].message)) { - errorResponse = { - statusCode: exception['statusCode'] ? exception['statusCode'] : status, - message: exception['response'].message ? exception['response'].message : 'Internal server error', - error: exception['response'].error - ? exception['response'].error - : exception['response'] - ? exception['response'] - : 'Internal server error' - }; - } else { - errorResponse = { - statusCode: exception['statusCode'] ? exception['statusCode'] : status, - message: exception['response'].message - ? exception['response'].message - : exception['response'] - ? exception['response'] - : 'Internal server error', - error: exception['response'].error - ? exception['response'].error - : exception['response'] - ? exception['response'] - : 'Internal server error' - }; - } - } else if (exception && exception.message) { - errorResponse = { - statusCode: exception['statusCode'] ? exception['statusCode'] : status, - message: exception.message || 'Internal server error', - error: exception.message || 'Internal server error' - }; - } + exceptionResponse = exception as unknown as ExceptionResponse; } + errorResponse = { + statusCode: exceptionResponse.statusCode ? exceptionResponse.statusCode : status, + message: exceptionResponse.message + ? exceptionResponse.message + : 'Something went wrong!', + error: exceptionResponse.error + ? exceptionResponse.error + : ResponseMessages.errorMessages.serverError + }; + response.status(errorResponse.statusCode).json(errorResponse); } } \ No newline at end of file diff --git a/apps/api-gateway/common/interface.ts b/apps/api-gateway/common/interface.ts index a64429f45..d3869d75f 100644 --- a/apps/api-gateway/common/interface.ts +++ b/apps/api-gateway/common/interface.ts @@ -4,3 +4,9 @@ export interface ResponseType { data?: Record | string; error?: Record | string; } + +export interface ExceptionResponse { + message: string | string[] + error: string + statusCode: number +} diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index 4d054f48c..ca848b0da 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -100,7 +100,14 @@ export class SchemaService extends BaseService { } schema.schemaName = schema.schemaName.trim(); - const { agentEndPoint, orgDid } = await this.schemaRepository.getAgentDetailsByOrgId(orgId); + const agentDetails = await this.schemaRepository.getAgentDetailsByOrgId(orgId); + if (!agentDetails) { + throw new NotFoundException( + ResponseMessages.schema.error.agentDetailsNotFound, + { cause: new Error(), description: ResponseMessages.errorMessages.notFound } + ); + } + const { agentEndPoint, orgDid } = agentDetails; const getAgentDetails = await this.schemaRepository.getAgentType(orgId); // eslint-disable-next-line yoda const did = schema.orgDid?.split(':').length >= 4 ? schema.orgDid : orgDid; @@ -218,7 +225,6 @@ export class SchemaService extends BaseService { async _createSchema(payload: CreateSchemaAgentRedirection): Promise<{ response: string; }> { - try { const pattern = { cmd: 'agent-create-schema' }; @@ -231,18 +237,15 @@ export class SchemaService extends BaseService { })) ).toPromise() .catch(error => { - this.logger.error(`Catch : ${JSON.stringify(error)}`); + this.logger.error(`Error in creating schema : ${JSON.stringify(error)}`); throw new HttpException( { - status: error.statusCode, - error: error.message + status: error.statusCode, + error: error.error, + message: error.message }, error.error); }); - return schemaResponse; - } catch (error) { - this.logger.error(`Error in creating schema : ${JSON.stringify(error)}`); - throw error; - } + return schemaResponse; } diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 0d7c9b2ec..02a92385e 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -117,7 +117,8 @@ export const ResponseMessages = { notFound: 'Schema records not found', schemaIdNotFound: 'SchemaLedgerId not found', credentialDefinitionNotFound: 'No credential definition exist', - notStoredCredential: 'User credential not stored' + notStoredCredential: 'User credential not stored', + agentDetailsNotFound: 'Agent details not found' } }, credentialDefinition: { @@ -154,7 +155,8 @@ export const ResponseMessages = { notAbleToSpinUpAgent: 'Agent not able to spin-up', alreadySpinUp: 'Agent already spin-up', agentUrl: 'Agent url not exist', - agentNotExists: 'Agent not spinned up for this organization' + agentNotExists: 'Agent not spinned up for this organization', + agentDown: 'Agent is down or not spinned up' } }, connection: { @@ -300,6 +302,7 @@ export const ResponseMessages = { badRequest: 'Bad Request', conflict: 'Conflict', notAcceptable: 'Not Acceptable', - notFound: 'Not Found' + notFound: 'Not Found', + serverError: 'Internal Server error' } }; \ No newline at end of file From 781884a4cdf5aa780a1778fdc01e1ff6922b151c Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 21 Dec 2023 17:34:56 +0530 Subject: [PATCH 014/107] refactor:fetch user profile api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 7 +++- apps/api-gateway/src/user/user.service.ts | 5 ++- apps/user/interfaces/user.interface.ts | 39 +++++++++++++++----- apps/user/repositories/user.repository.ts | 6 +-- apps/user/src/user.controller.ts | 4 +- apps/user/src/user.service.ts | 4 +- 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 9cf602c33..2c1b696bc 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -15,6 +15,7 @@ import { import { UserService } from './user.service'; import { ApiBearerAuth, + ApiExcludeEndpoint, ApiForbiddenResponse, ApiOperation, ApiParam, @@ -69,6 +70,7 @@ export class UserController { * @returns Users list of organization */ @Get('/public-profiles') + @ApiExcludeEndpoint() @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) @ApiOperation({ summary: 'Get users list', description: 'Get users list.' }) @ApiQuery({ @@ -102,6 +104,7 @@ export class UserController { } @Get('public-profiles/:username') + @ApiExcludeEndpoint() @ApiOperation({ summary: 'Fetch user details', description: 'Fetch user details' @@ -130,13 +133,13 @@ export class UserController { }) @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() - async getProfile(@User() reqUser: user, @Res() res: Response): Promise { + async getProfile(@User() reqUser: user, @Res() res: Response): Promise { const userData = await this.userService.getProfile(reqUser.id); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchProfile, - data: userData.response + data: userData }; return res.status(HttpStatus.OK).json(finalResponse); diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index e6e98658e..266c96372 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -9,6 +9,7 @@ import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; import { AddPasskeyDetails } from './dto/add-user.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; +import { UsersProfile } from 'apps/user/interfaces/user.interface'; @Injectable() export class UserService extends BaseService { @@ -16,9 +17,9 @@ export class UserService extends BaseService { super('User Service'); } - async getProfile(id: string): Promise<{ response: object }> { + async getProfile(id: string): Promise { const payload = { id }; - return this.sendNats(this.serviceProxy, 'get-user-profile', payload); + return this.sendNatsMessage(this.serviceProxy, 'get-user-profile', payload); } async getPublicProfile(username: string): Promise<{ response: object }> { diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index 5ce80c6eb..c0446e58f 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -23,14 +23,35 @@ export interface Organisation { } export interface UsersProfile { - id?: string; - username?: string; - email?: string; - firstName?: string; - lastName?: string; - supabaseUserId?: string; - userOrgRoles?: object; - } + id?: string; + username?: string; + email?: string; + firstName?: string; + lastName?: string; + supabaseUserId?: string; + userOrgRoles?: UserOrgRole[]; +} + +interface UserOrgRole { + id: string; + userId: string; + orgRoleId: string; + orgId: string; + orgRole: { + id: string; + name: string; + description: string; + }; + organisation: { + id: string; + name: string; + description: string; + orgSlug: string; + logoUrl: string; + website: string; + publicProfile: boolean; + }; +} export interface OrgInvitations { id: string; @@ -48,7 +69,7 @@ export interface UsersProfile { username?: string; } - export interface userInfo { + export interface UserInfo { email: string; password: string; firstName: string; diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index 513c534df..ce4d23eca 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -9,7 +9,7 @@ import { UserCredentials, UserEmailVerificationDto, UsersProfile, - userInfo + UserInfo } from '../interfaces/user.interface'; import { InternalServerErrorException } from '@nestjs/common'; @@ -254,7 +254,7 @@ export class UserRepository { }); } - async findUserForPublicProfile(queryOptions: UserQueryOptions): Promise { + async findUserForPublicProfile(queryOptions: UserQueryOptions): Promise { return this.prisma.user.findFirst({ where: { publicProfile: true, @@ -330,7 +330,7 @@ export class UserRepository { * @returns Updates user details */ // eslint-disable-next-line camelcase - async updateUserInfo(email: string, userInfo: userInfo): Promise { + async updateUserInfo(email: string, userInfo: UserInfo): Promise { try { const updateUserDetails = await this.prisma.user.update({ where: { diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 4d349587b..cd51eeb54 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, CheckUserDetails, PlatformSettings, ShareUserCertificate, UserInvitations, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, userInfo, UsersProfile } from '../interfaces/user.interface'; +import { AddPasskeyDetails, CheckUserDetails, PlatformSettings, ShareUserCertificate, UserInvitations, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, UserInfo, UsersProfile } from '../interfaces/user.interface'; import {IOrgUsers, Payload} from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; @@ -126,7 +126,7 @@ export class UserController { return this.userService.checkUserExist(payload.userEmail); } @MessagePattern({ cmd: 'add-user' }) - async addUserDetailsInKeyCloak(payload: { userInfo: userInfo }): Promise { + async addUserDetailsInKeyCloak(payload: { userInfo: UserInfo }): Promise { return this.userService.createUserForToken(payload.userInfo); } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 21a0f5e0d..36e1d260f 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -38,7 +38,7 @@ import { UpdateUserProfile, UserCredentials, UserEmailVerificationDto, - userInfo, + UserInfo, UsersProfile } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; @@ -208,7 +208,7 @@ export class UserService { } } - async createUserForToken(userInfo: userInfo): Promise { + async createUserForToken(userInfo: UserInfo): Promise { try { const { email } = userInfo; if (!userInfo.email) { From d6cae269a36ef976b2ca21d1a226840683077e9c Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 21 Dec 2023 20:18:59 +0530 Subject: [PATCH 015/107] tested flow with token and checked cache Signed-off-by: KulkarniShashank --- Dockerfiles/Dockerfile.agnet-provisioning | 4 +- .../AFJ/scripts/start_agent.sh | 2 + .../src/agent-service.service.ts | 45 ++++++++--- .../repositories/agent-service.repository.ts | 33 ++++---- apps/ecosystem/src/ecosystem.module.ts | 6 +- apps/ecosystem/src/ecosystem.service.ts | 9 +-- apps/issuance/src/issuance.service.ts | 57 +++++++------ apps/ledger/src/schema/schema.service.ts | 79 ++++++++++--------- libs/common/src/common.constant.ts | 2 +- 9 files changed, 130 insertions(+), 107 deletions(-) diff --git a/Dockerfiles/Dockerfile.agnet-provisioning b/Dockerfiles/Dockerfile.agnet-provisioning index fffb90839..134846452 100644 --- a/Dockerfiles/Dockerfile.agnet-provisioning +++ b/Dockerfiles/Dockerfile.agnet-provisioning @@ -28,12 +28,12 @@ RUN npm install -g pnpm RUN mkdir -p ./agent-provisioning/AFJ/endpoints RUN mkdir -p ./agent-provisioning/AFJ/agent-config - +RUN mkdir -p ./agent-provisioning/AFJ/port-file # Copy the compiled code COPY --from=build /app/dist/apps/agent-provisioning/ ./dist/apps/agent-provisioning/ COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/apps/agent-provisioning/AFJ/scripts ./agent-provisioning/AFJ/scripts -COPY --from=build /app/apps/agent-provisioning/AFJ/port-files ./agent-provisioning/AFJ/port-file +COPY --from=build /app/apps/agent-provisioning/AFJ/port-file ./agent-provisioning/AFJ/port-file # Set permissions RUN chmod +x /app/agent-provisioning/AFJ/scripts/start_agent.sh diff --git a/apps/agent-provisioning/AFJ/scripts/start_agent.sh b/apps/agent-provisioning/AFJ/scripts/start_agent.sh index f8aea1778..1c6412f00 100755 --- a/apps/agent-provisioning/AFJ/scripts/start_agent.sh +++ b/apps/agent-provisioning/AFJ/scripts/start_agent.sh @@ -1,3 +1,5 @@ +#!/bin/bash + START_TIME=$(date +%s) AGENCY=$1 diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index b9d80ae24..56a69e914 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -173,7 +173,6 @@ export class AgentServiceService { const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { - await this.getOrgAgentApiKey(agentSpinupDto.orgId); const data = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); throw new BadRequestException('Your wallet has already been created.'); } @@ -987,14 +986,18 @@ export class AgentServiceService { async getAgentHealthDetails(orgId: string, apiKey: string): Promise { try { const orgAgentDetails: org_agents = await this.agentServiceRepository.getOrgAgentDetails(orgId); - let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this.getOrgAgentApiKey(orgId); - } - if (apiKey === undefined || null) { - apiKey = await this.getOrgAgentApiKey(orgId); + let agentApiKey; + if (orgAgentDetails) { + + agentApiKey = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + if (!agentApiKey || null === agentApiKey || undefined === agentApiKey) { + agentApiKey = await this.getOrgAgentApiKey(orgId); + } + + if (agentApiKey === undefined || null) { + agentApiKey = await this.getOrgAgentApiKey(orgId); + } } if (!orgAgentDetails) { @@ -1002,7 +1005,7 @@ export class AgentServiceService { } if (orgAgentDetails.agentEndPoint) { const data = await this.commonService - .httpGet(`${orgAgentDetails.agentEndPoint}/agent`, { headers: { 'authorization': apiKey } }) + .httpGet(`${orgAgentDetails.agentEndPoint}/agent`, { headers: { 'authorization': agentApiKey } }) .then(async response => response); return data; } else { @@ -1119,16 +1122,32 @@ export class AgentServiceService { async getOrgAgentApiKey(orgId: string): Promise { try { + let agentApiKey; const orgAgentApiKey = await this.agentServiceRepository.getAgentApiKey(orgId); - if (!orgAgentApiKey) { + const orgAgentId = await this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.SHARED); + if (orgAgentApiKey?.orgAgentTypeId === orgAgentId) { + const platformAdminSpinnedUp = await this.agentServiceRepository.platformAdminAgent(CommonConstants.PLATFORM_ADMIN_ORG); + + const [orgAgentData] = platformAdminSpinnedUp.org_agents; + const { apiKey } = orgAgentData; + if (!platformAdminSpinnedUp) { + throw new InternalServerErrorException('Agent not able to spin-up'); + } + + agentApiKey = apiKey; + } else { + agentApiKey = orgAgentApiKey?.apiKey; + } + + if (!agentApiKey) { throw new NotFoundException(ResponseMessages.agent.error.apiKeyNotExist); } - await this.cacheService.set(CommonConstants.CACHE_APIKEY_KEY, orgAgentApiKey, CommonConstants.CACHE_TTL_SECONDS); - return orgAgentApiKey; + await this.cacheService.set(CommonConstants.CACHE_APIKEY_KEY, agentApiKey, CommonConstants.CACHE_TTL_SECONDS); + return agentApiKey; } catch (error) { - this.logger.error(`Agent health details : ${JSON.stringify(error)}`); + this.logger.error(`Agent api key details : ${JSON.stringify(error)}`); throw error; } } diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index a7420fceb..2f09299c9 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -10,7 +10,7 @@ export class AgentServiceRepository { constructor( private readonly prisma: PrismaService, private readonly logger: Logger - ) {} + ) { } /** * Get platform config details @@ -174,12 +174,14 @@ export class AgentServiceRepository { // eslint-disable-next-line camelcase async getOrgAgentDetails(orgId: string): Promise { try { - const oranizationAgentDetails = await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); - return oranizationAgentDetails; + if (orgId) { + const oranizationAgentDetails = await this.prisma.org_agents.findFirst({ + where: { + orgId + } + }); + return oranizationAgentDetails; + } } catch (error) { this.logger.error(`[getOrgAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); throw error; @@ -310,15 +312,18 @@ export class AgentServiceRepository { } } - async getAgentApiKey(orgId: string): Promise { + // eslint-disable-next-line camelcase + async getAgentApiKey(orgId: string): Promise { try { - const agent = await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); + if (orgId) { + const agent = await this.prisma.org_agents.findFirst({ + where: { + orgId + } + }); + return agent; + } - return agent.apiKey; } catch (error) { this.logger.error(`[getAgentApiKey] - get api key: ${JSON.stringify(error)}`); throw error; diff --git a/apps/ecosystem/src/ecosystem.module.ts b/apps/ecosystem/src/ecosystem.module.ts index 285078c20..1f11e9f7d 100644 --- a/apps/ecosystem/src/ecosystem.module.ts +++ b/apps/ecosystem/src/ecosystem.module.ts @@ -5,10 +5,6 @@ import { ClientsModule, Transport } from '@nestjs/microservices'; import { CommonModule} from '@credebl/common'; import { EcosystemRepository } from './ecosystem.repository'; import { PrismaService } from '@credebl/prisma-service'; -import { AgentServiceService } from 'apps/agent-service/src/agent-service.service'; -import { AgentServiceRepository } from 'apps/agent-service/src/repositories/agent-service.repository'; -import { ConnectionService } from 'apps/connection/src/connection.service'; -import { ConnectionRepository } from 'apps/connection/src/connection.repository'; import { CacheModule } from '@nestjs/cache-manager'; import { getNatsOptions } from '@credebl/common/nats.config'; @@ -26,6 +22,6 @@ import { getNatsOptions } from '@credebl/common/nats.config'; CacheModule.register() ], controllers: [EcosystemController], - providers: [EcosystemService, PrismaService, Logger, EcosystemRepository, AgentServiceService, AgentServiceRepository, ConnectionService, ConnectionRepository] + providers: [EcosystemService, PrismaService, Logger, EcosystemRepository] }) export class EcosystemModule { } diff --git a/apps/ecosystem/src/ecosystem.service.ts b/apps/ecosystem/src/ecosystem.service.ts index ddc268770..d4ac164a8 100644 --- a/apps/ecosystem/src/ecosystem.service.ts +++ b/apps/ecosystem/src/ecosystem.service.ts @@ -36,7 +36,6 @@ import { CommonConstants } from '@credebl/common/common.constant'; // eslint-disable-next-line camelcase import { credential_definition, org_agents, platform_config, schema, user } from '@prisma/client'; // import { CommonService } from '@credebl/common/common.service'; -import { AgentServiceService } from 'apps/agent-service/src/agent-service.service'; import { Cache } from 'cache-manager'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; import { updateEcosystemOrgsDto } from '../dtos/update-ecosystemOrgs.dto'; @@ -49,8 +48,6 @@ export class EcosystemService { private readonly ecosystemRepository: EcosystemRepository, private readonly logger: Logger, private readonly prisma: PrismaService, - // private readonly agentAuthService: AgentAuthService - private readonly agentServiceService: AgentServiceService, @Inject(CACHE_MANAGER) private cacheService: Cache ) {} @@ -614,7 +611,7 @@ export class EcosystemService { endorsementTransactionType.SCHEMA, ecosystemMemberDetails.tenantId ); - const apiKey = await this.agentServiceService.getOrgAgentApiKey(orgId); + const apiKey = await this._getOrgAgentApiKey(orgId); const attributeArray = requestSchemaPayload.attributes.map((item) => item.attributeName); const schemaTransactionPayload = { @@ -718,7 +715,7 @@ export class EcosystemService { endorsementTransactionType.CREDENTIAL_DEFINITION, ecosystemMemberDetails.tenantId ); - const apiKey = await this.agentServiceService.getOrgAgentApiKey(orgId); + const apiKey = await this._getOrgAgentApiKey(orgId); const credDefTransactionPayload = { endorserDid: ecosystemLeadAgentDetails.orgDid, endorse: requestCredDefPayload.endorse, @@ -862,8 +859,6 @@ export class EcosystemService { endorsementTransactionType.SIGN, ecosystemLeadAgentDetails?.tenantId ); - // const apiKey = await this.agentServiceService.getOrgAgentApiKey(ecosystemLeadDetails.orgId); - // const apiKey = await this._getOrgAgentApiKey(ecosystemLeadDetails.orgId); let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { diff --git a/apps/issuance/src/issuance.service.ts b/apps/issuance/src/issuance.service.ts index c6a371ff9..5eae522d5 100644 --- a/apps/issuance/src/issuance.service.ts +++ b/apps/issuance/src/issuance.service.ts @@ -64,11 +64,11 @@ export class IssuanceService { // const apiKey = platformConfig?.sgApiKey; // let apiKey = await this._getOrgAgentApiKey(orgId); - - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + + let apiKey; + apiKey = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const issueData = { protocolVersion: 'v1', @@ -119,10 +119,11 @@ export class IssuanceService { // const apiKey = platformConfig?.sgApiKey; // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey; + apiKey = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey---${apiKey}`); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const issueData = { @@ -236,7 +237,7 @@ export class IssuanceService { } = { totalItems: getIssuedCredentialsList.issuedCredentialsCount, hasNextPage: - issuedCredentialsSearchCriteria.pageSize * issuedCredentialsSearchCriteria.pageNumber < getIssuedCredentialsList.issuedCredentialsCount, + issuedCredentialsSearchCriteria.pageSize * issuedCredentialsSearchCriteria.pageNumber < getIssuedCredentialsList.issuedCredentialsCount, hasPreviousPage: 1 < issuedCredentialsSearchCriteria.pageNumber, nextPage: Number(issuedCredentialsSearchCriteria.pageNumber) + 1, previousPage: issuedCredentialsSearchCriteria.pageNumber - 1, @@ -289,10 +290,10 @@ export class IssuanceService { // const apiKey = platformConfig?.sgApiKey; // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const createConnectionInvitation = await this._getIssueCredentialsbyCredentialRecordId(url, apiKey); return createConnectionInvitation?.response; @@ -363,10 +364,10 @@ export class IssuanceService { // const { apiKey } = agentDetails; // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const errors = []; @@ -383,8 +384,7 @@ export class IssuanceService { } }, autoAcceptCredential: 'always', - comment, - label: organizationDetails?.name + comment }; const credentialCreateOfferDetails = await this._outOfBandCredentialOffer(outOfBandIssuancePayload, url, apiKey); @@ -444,7 +444,7 @@ export class IssuanceService { if (credentialOffer) { - for (let i = 0; i < credentialOffer.length; i += Number(process.env.OOB_BATCH_SIZE)) { + for (let i = 0; i < credentialOffer.length; i += Number(process.env.OOB_BATCH_SIZE)) { const batch = credentialOffer.slice(i, i + Number(process.env.OOB_BATCH_SIZE)); // Process each batch in parallel @@ -1092,15 +1092,20 @@ export class IssuanceService { } } - async _getOrgAgentApiKey(orgId: string): Promise { + async _getOrgAgentApiKey(orgId: string): Promise { + const pattern = { cmd: 'get-org-agent-api-key' }; + const payload = { orgId }; + try { - const pattern = { cmd: 'get-org-agent-api-key' }; - const payload = {orgId }; - const message = await this.natsCall(pattern, payload); - return String(message); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const message = await this.issuanceServiceProxy.send(pattern, payload).toPromise(); + return message; } catch (error) { - this.logger.error(`[_getOrgAgentApiKey] [NATS call]- error in getOrgApiKey : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException({ + status: error.status, + error: error.message + }, error.status); } } diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index d8ba11490..645fb4733 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -37,27 +37,26 @@ export class SchemaService extends BaseService { ): Promise { // const apiKey = ''; // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const { userId } = user.selectedOrg; try { - + const schemaExists = await this.schemaRepository.schemaExists( schema.schemaName, schema.schemaVersion - ); - - if (0 !== schemaExists.length) { - this.logger.error(ResponseMessages.schema.error.exists); - throw new ConflictException(ResponseMessages.schema.error.exists); - } - - if (null !== schema || schema !== undefined) { - const schemaVersionIndexOf = -1; - if ( + ); + + if (0 !== schemaExists.length) { + this.logger.error(ResponseMessages.schema.error.exists); + throw new ConflictException(ResponseMessages.schema.error.exists); + } + + if (null !== schema || schema !== undefined) { + const schemaVersionIndexOf = -1; + if ( isNaN(parseFloat(schema.schemaVersion)) || schema.schemaVersion.toString().indexOf('.') === schemaVersionIndexOf @@ -71,31 +70,31 @@ export class SchemaService extends BaseService { if (schema.attributes.length === schemaAttributeLength) { throw new NotAcceptableException( ResponseMessages.schema.error.insufficientAttributes - ); - } else if (schema.attributes.length > schemaAttributeLength) { - - const trimmedAttributes = schema.attributes.map(attribute => ({ - attributeName: attribute.attributeName.trim(), - schemaDataType: attribute.schemaDataType, - displayName: attribute.displayName.trim() - })); + ); + } else if (schema.attributes.length > schemaAttributeLength) { + const trimmedAttributes = schema.attributes.map(attribute => ({ + attributeName: attribute.attributeName.trim(), + schemaDataType: attribute.schemaDataType, + displayName: attribute.displayName.trim() + })); - const attributeNamesLowerCase = trimmedAttributes.map(attribute => attribute.attributeName.toLowerCase()); - const duplicateAttributeNames = attributeNamesLowerCase - .filter((value, index, element) => element.indexOf(value) !== index); - if (0 < duplicateAttributeNames.length) { + const attributeNamesLowerCase = trimmedAttributes.map(attribute => attribute.attributeName.toLowerCase()); + const duplicateAttributeNames = attributeNamesLowerCase + .filter((value, index, element) => element.indexOf(value) !== index); + + if (0 < duplicateAttributeNames.length) { throw new ConflictException(ResponseMessages.schema.error.uniqueAttributesnames); - } + } - const attributeDisplayNamesLowerCase = trimmedAttributes.map(attribute => attribute.displayName.toLocaleLowerCase()); - const duplicateAttributeDisplayNames = attributeDisplayNamesLowerCase - .filter((value, index, element) => element.indexOf(value) !== index); + const attributeDisplayNamesLowerCase = trimmedAttributes.map(attribute => attribute.displayName.toLocaleLowerCase()); + const duplicateAttributeDisplayNames = attributeDisplayNamesLowerCase + .filter((value, index, element) => element.indexOf(value) !== index); - if (0 < duplicateAttributeDisplayNames.length) { + if (0 < duplicateAttributeDisplayNames.length) { throw new ConflictException(ResponseMessages.schema.error.uniqueAttributesDisplaynames); - } + } schema.schemaName = schema.schemaName.trim(); const { agentEndPoint, orgDid } = await this.schemaRepository.getAgentDetailsByOrgId(orgId); @@ -258,12 +257,13 @@ export class SchemaService extends BaseService { const orgAgentType = await this.schemaRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId); // const apiKey = ''; - // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + let apiKey; + apiKey = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); + } + let schemaResponse; if (OrgAgentType.DEDICATED === orgAgentType) { const getSchemaPayload = { @@ -280,7 +280,8 @@ export class SchemaService extends BaseService { method: 'getSchemaById', payload: { schemaId }, agentType: OrgAgentType.SHARED, - agentEndPoint + agentEndPoint, + apiKey }; schemaResponse = await this._getSchemaById(getSchemaPayload); } diff --git a/libs/common/src/common.constant.ts b/libs/common/src/common.constant.ts index a42c07424..82ec264d8 100644 --- a/libs/common/src/common.constant.ts +++ b/libs/common/src/common.constant.ts @@ -298,7 +298,7 @@ export enum CommonConstants { //CacheInfo CACHE_APIKEY_KEY = "apiKey", -CACHE_TTL_SECONDS = 3600 +CACHE_TTL_SECONDS = 604800 } export const postgresqlErrorCodes = []; From 23f6ed7328b4286b4caec6698e3f674e7fa24311 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 21 Dec 2023 20:39:11 +0530 Subject: [PATCH 016/107] refactor:users activity api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 4 ++-- apps/api-gateway/src/user/user.service.ts | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 2c1b696bc..48c8eef9a 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -177,13 +177,13 @@ export class UserController { @Query('limit') limit: number, @Res() res: Response, @User() reqUser: user - ): Promise { + ): Promise { const userDetails = await this.userService.getUserActivities(reqUser.id, limit); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.userActivity, - data: userDetails.response + data: userDetails }; return res.status(HttpStatus.OK).json(finalResponse); diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index 266c96372..a077afc19 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -10,6 +10,7 @@ import { AddPasskeyDetails } from './dto/add-user.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; import { UsersProfile } from 'apps/user/interfaces/user.interface'; +import { UsersActivity } from 'libs/user-activity/interface'; @Injectable() export class UserService extends BaseService { @@ -78,9 +79,9 @@ export class UserService extends BaseService { return this.sendNats(this.serviceProxy, 'check-user-exist', payload); } - async getUserActivities(userId: string, limit: number): Promise<{ response: object }> { + async getUserActivities(userId: string, limit: number): Promise { const payload = { userId, limit }; - return this.sendNats(this.serviceProxy, 'get-user-activity', payload); + return this.sendNatsMessage(this.serviceProxy, 'get-user-activity', payload); } async addPasskey(userEmail: string, userInfo: AddPasskeyDetails): Promise<{ response: string }> { From 3dd3ee293778686739bb42ea3f02c349518a4ea7 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 21 Dec 2023 23:19:30 +0530 Subject: [PATCH 017/107] refactor: catch webhook connection response api Signed-off-by: bhavanakarwade --- .../src/connection/connection.controller.ts | 13 +++--- .../src/connection/connection.service.ts | 10 ++-- .../src/connection/dtos/connection.dto.ts | 46 ++++++++----------- apps/connection/src/connection.controller.ts | 4 +- apps/connection/src/connection.repository.ts | 4 +- apps/connection/src/connection.service.ts | 4 +- .../src/interfaces/connection.interfaces.ts | 2 +- 7 files changed, 35 insertions(+), 48 deletions(-) diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 850355101..4ee43c1e6 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -155,7 +155,6 @@ export class ConnectionController { } - /** * Catch connection webhook responses. * @Body connectionDto @@ -163,20 +162,20 @@ export class ConnectionController { * @param res */ - @Post('wh/:id/connections/') + @Post('wh/:orgId/connections/') @ApiExcludeEndpoint() @ApiOperation({ summary: 'Catch connection webhook responses', description: 'Callback URL for connection' }) - @ApiResponse({ status: 200, description: 'Success', type: AuthTokenResponse }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: AuthTokenResponse }) async getConnectionWebhook( @Body() connectionDto: ConnectionDto, - @Param('id') id: string, + @Param('orgId') orgId: string, @Res() res: Response - ): Promise { - this.logger.debug(`connectionDto ::: ${JSON.stringify(connectionDto)} ${id}`); - const connectionData = await this.connectionService.getConnectionWebhook(connectionDto, id); + ): Promise { + this.logger.debug(`connectionDto ::: ${JSON.stringify(connectionDto)} ${orgId}`); + const connectionData = await this.connectionService.getConnectionWebhook(connectionDto, orgId); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.connection.success.create, diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 214a5c013..db42137d7 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -37,12 +37,10 @@ export class ConnectionService extends BaseService { getConnectionWebhook( connectionDto: ConnectionDto, - id: string - ): Promise<{ - response: object; - }> { - const payload = { connectionDto, orgId: id }; - return this.sendNats(this.connectionServiceProxy, 'webhook-get-connection', payload); + orgId: string + ): Promise { + const payload = { connectionDto, orgId }; + return this.sendNatsMessage(this.connectionServiceProxy, 'webhook-get-connection', payload); } getUrl(referenceId: string): Promise<{ diff --git a/apps/api-gateway/src/connection/dtos/connection.dto.ts b/apps/api-gateway/src/connection/dtos/connection.dto.ts index fe225792b..a34401728 100644 --- a/apps/api-gateway/src/connection/dtos/connection.dto.ts +++ b/apps/api-gateway/src/connection/dtos/connection.dto.ts @@ -1,16 +1,18 @@ import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class CreateConnectionDto { @ApiProperty() @IsOptional() - @IsString({ message: 'alias must be a string' }) @IsNotEmpty({ message: 'please provide valid alias' }) + @IsString({ message: 'alias must be a string' }) + @IsNotEmpty({ message: 'please provide valid alias' }) alias: string; @ApiProperty() @IsOptional() - @IsString({ message: 'label must be a string' }) @IsNotEmpty({ message: 'please provide valid label' }) + @IsString({ message: 'label must be a string' }) + @IsNotEmpty({ message: 'please provide valid label' }) label: string; @ApiProperty() @@ -34,67 +36,55 @@ export class CreateConnectionDto { } export class ConnectionDto { - @ApiProperty() - @IsOptional() - _tags?: object; - - @ApiProperty() - @IsOptional() - metadata: object; - - @ApiProperty() - @IsOptional() - connectionTypes: object[]; - - @ApiProperty() + @ApiPropertyOptional() @IsOptional() id: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() createdAt: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() did: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() theirDid: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() theirLabel: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() state: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() role: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() autoAcceptConnection: boolean; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() threadId: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() protocol: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() outOfBandId: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() updatedAt: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() contextCorrelationId: string; } \ No newline at end of file diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 3bb9a2572..8dcd8c02f 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -2,8 +2,8 @@ import { Controller } from '@nestjs/common'; // Import the common service in the import { ConnectionService } from './connection.service'; // Import the common service in connection module import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package import { + ConnectionInterface, IConnection, - IConnectionInterface, IFetchConnectionById, IFetchConnectionInterface } from './interfaces/connection.interfaces'; @@ -38,7 +38,7 @@ export class ConnectionController { * @returns Callback URL for connection and created connections details */ @MessagePattern({ cmd: 'webhook-get-connection' }) - async getConnectionWebhook(payload: IConnectionInterface): Promise { + async getConnectionWebhook(payload: ConnectionInterface): Promise { return this.connectionService.getConnectionWebhook(payload); } diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index 2465982c6..b4e4e60f5 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; // eslint-disable-next-line camelcase import { agent_invitations, org_agents, platform_config, shortening_url } from '@prisma/client'; -import { IConnectionInterface, IConnectionSearchCriteria, OrgAgent } from './interfaces/connection.interfaces'; +import { ConnectionInterface, IConnectionSearchCriteria, OrgAgent } from './interfaces/connection.interfaces'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; // import { OrgAgent } from './interfaces/connection.interfaces'; @Injectable() @@ -93,7 +93,7 @@ export class ConnectionRepository { * @returns Get connection details */ // eslint-disable-next-line camelcase - async saveConnectionWebhook(payload: IConnectionInterface): Promise { + async saveConnectionWebhook(payload: ConnectionInterface): Promise { try { let organisationId: string; diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index c613768e3..0ef2b5268 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -5,8 +5,8 @@ import { HttpException, Inject, Injectable, Logger, NotFoundException } from '@n import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs'; import { + ConnectionInterface, ConnectionInvitationResponse, - IConnectionInterface, IConnectionSearchCriteria, IUserRequestInterface } from './interfaces/connection.interfaces'; @@ -113,7 +113,7 @@ export class ConnectionService { * @param user * @returns Connection legacy invitation URL */ - async getConnectionWebhook(payload: IConnectionInterface): Promise { + async getConnectionWebhook(payload: ConnectionInterface): Promise { try { const saveConnectionDetails = await this.connectionRepository.saveConnectionWebhook(payload); return saveConnectionDetails; diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 2bbedae60..0f9ae6038 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -51,7 +51,7 @@ export interface IOrgAgentInterface { orgId: string; } -export class IConnectionInterface { +export class ConnectionInterface { connectionDto: ConnectionPayload; orgId: string; } From 8de74f0d74424fada81ce2e0d08f9c84e4ebbe17 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 21 Dec 2023 23:44:05 +0530 Subject: [PATCH 018/107] refactor interface names Signed-off-by: bhavanakarwade --- apps/connection/src/connection.controller.ts | 4 ++-- apps/connection/src/connection.repository.ts | 4 ++-- apps/connection/src/connection.service.ts | 4 ++-- apps/connection/src/interfaces/connection.interfaces.ts | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 8dcd8c02f..900600e71 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -2,7 +2,7 @@ import { Controller } from '@nestjs/common'; // Import the common service in the import { ConnectionService } from './connection.service'; // Import the common service in connection module import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package import { - ConnectionInterface, + Connection, IConnection, IFetchConnectionById, IFetchConnectionInterface @@ -38,7 +38,7 @@ export class ConnectionController { * @returns Callback URL for connection and created connections details */ @MessagePattern({ cmd: 'webhook-get-connection' }) - async getConnectionWebhook(payload: ConnectionInterface): Promise { + async getConnectionWebhook(payload: Connection): Promise { return this.connectionService.getConnectionWebhook(payload); } diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index b4e4e60f5..fe7ed215d 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; // eslint-disable-next-line camelcase import { agent_invitations, org_agents, platform_config, shortening_url } from '@prisma/client'; -import { ConnectionInterface, IConnectionSearchCriteria, OrgAgent } from './interfaces/connection.interfaces'; +import { Connection, IConnectionSearchCriteria, OrgAgent } from './interfaces/connection.interfaces'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; // import { OrgAgent } from './interfaces/connection.interfaces'; @Injectable() @@ -93,7 +93,7 @@ export class ConnectionRepository { * @returns Get connection details */ // eslint-disable-next-line camelcase - async saveConnectionWebhook(payload: ConnectionInterface): Promise { + async saveConnectionWebhook(payload: Connection): Promise { try { let organisationId: string; diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 0ef2b5268..239f7ef92 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -5,7 +5,7 @@ import { HttpException, Inject, Injectable, Logger, NotFoundException } from '@n import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs'; import { - ConnectionInterface, + Connection, ConnectionInvitationResponse, IConnectionSearchCriteria, IUserRequestInterface @@ -113,7 +113,7 @@ export class ConnectionService { * @param user * @returns Connection legacy invitation URL */ - async getConnectionWebhook(payload: ConnectionInterface): Promise { + async getConnectionWebhook(payload: Connection): Promise { try { const saveConnectionDetails = await this.connectionRepository.saveConnectionWebhook(payload); return saveConnectionDetails; diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 0f9ae6038..92183bef8 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -51,7 +51,7 @@ export interface IOrgAgentInterface { orgId: string; } -export class ConnectionInterface { +export class Connection { connectionDto: ConnectionPayload; orgId: string; } From b4f8d979ad523045b638e83fee0a54643293ba93 Mon Sep 17 00:00:00 2001 From: Nishad Date: Fri, 22 Dec 2023 19:02:11 +0530 Subject: [PATCH 019/107] worked on the fetch schemas by org Signed-off-by: Nishad --- .../src/interfaces/ISchemaSearch.interface.ts | 6 +-- .../src/platform/platform.controller.ts | 8 ++-- .../src/platform/platform.service.ts | 4 +- .../src/schema/dtos/get-all-schema.dto.ts | 24 +++++++--- .../src/schema/schema.controller.ts | 44 ++++++------------- apps/api-gateway/src/schema/schema.service.ts | 9 ++-- apps/ledger/src/schema/enum/schema.enum.ts | 11 +++++ .../interfaces/schema-payload.interface.ts | 6 +-- .../src/schema/interfaces/schema.interface.ts | 19 +++++++- .../schema/repositories/schema.repository.ts | 32 +++++--------- apps/ledger/src/schema/schema.controller.ts | 29 +++--------- apps/ledger/src/schema/schema.service.ts | 38 +++++----------- .../common/src/interfaces/schema.interface.ts | 23 ++++++++++ libs/common/src/response-messages/index.ts | 3 +- 14 files changed, 130 insertions(+), 126 deletions(-) create mode 100644 apps/ledger/src/schema/enum/schema.enum.ts create mode 100644 libs/common/src/interfaces/schema.interface.ts diff --git a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts index 13e0c77e6..1714c1654 100644 --- a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts @@ -1,11 +1,11 @@ import { IUserRequestInterface } from '../schema/interfaces'; -export interface ISchemaSearchInterface { +export interface ISchemaSearchPayload { ledgerId?: string; pageNumber: number; pageSize: number; - sorting: string; - sortByValue: string; + sortField: string; + sortBy: string; searchByText: string; user?: IUserRequestInterface } diff --git a/apps/api-gateway/src/platform/platform.controller.ts b/apps/api-gateway/src/platform/platform.controller.ts index 7f11d05e9..1de4f4aa5 100644 --- a/apps/api-gateway/src/platform/platform.controller.ts +++ b/apps/api-gateway/src/platform/platform.controller.ts @@ -6,7 +6,7 @@ import { GetAllSchemaByPlatformDto } from '../schema/dtos/get-all-schema.dto'; import { IUserRequestInterface } from '../interfaces/IUserRequestInterface'; import { User } from '../authz/decorators/user.decorator'; import { Response } from 'express'; -import { ISchemaSearchInterface } from '../interfaces/ISchemaSearch.interface'; +import { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; import IResponseType from '@credebl/common/interfaces/response.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; @@ -34,13 +34,13 @@ export class PlatformController { @User() user: IUserRequestInterface ): Promise { const { ledgerId, pageSize, searchByText, pageNumber, sorting, sortByValue } = getAllSchemaDto; - const schemaSearchCriteria: ISchemaSearchInterface = { + const schemaSearchCriteria: ISchemaSearchPayload = { ledgerId, pageNumber, searchByText, pageSize, - sorting, - sortByValue + sortField: sorting, + sortBy: sortByValue }; const schemasResponse = await this.platformService.getAllSchema(schemaSearchCriteria, user); const finalResponse: IResponseType = { diff --git a/apps/api-gateway/src/platform/platform.service.ts b/apps/api-gateway/src/platform/platform.service.ts index 1d91103ca..7f03786f8 100644 --- a/apps/api-gateway/src/platform/platform.service.ts +++ b/apps/api-gateway/src/platform/platform.service.ts @@ -1,7 +1,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; import { BaseService } from '../../../../libs/service/base.service'; -import { ISchemaSearchInterface } from '../interfaces/ISchemaSearch.interface'; +import { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; import { IUserRequestInterface } from '../interfaces/IUserRequestInterface'; @Injectable() @@ -12,7 +12,7 @@ export class PlatformService extends BaseService { super('PlatformService'); } - async getAllSchema(schemaSearchCriteria: ISchemaSearchInterface, user: IUserRequestInterface): Promise<{ + async getAllSchema(schemaSearchCriteria: ISchemaSearchPayload, user: IUserRequestInterface): Promise<{ response: object; }> { const schemaSearch = { schemaSearchCriteria, user }; diff --git a/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts b/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts index c0e955d43..7e8739636 100644 --- a/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts +++ b/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts @@ -2,8 +2,10 @@ /* eslint-disable camelcase */ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { SortValue } from '../../enum'; -import { Type } from 'class-transformer'; -import { IsOptional } from 'class-validator'; +import { Transform, Type } from 'class-transformer'; +import { IsEnum, IsOptional } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper'; +import { SortFields } from 'apps/ledger/src/schema/enum/schema.enum'; export class GetAllSchemaDto { @ApiProperty({ required: false }) @@ -12,6 +14,7 @@ export class GetAllSchemaDto { @ApiProperty({ required: false }) @IsOptional() + @Transform(({ value }) => trim(value)) @Type(() => String) searchByText: string = ''; @@ -19,13 +22,22 @@ export class GetAllSchemaDto { @IsOptional() pageSize: number = 10; - @ApiProperty({ required: false }) + @ApiProperty({ + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() - sorting: string = 'id'; + @IsEnum(SortFields) + sortField: string = SortFields.CREATED_DATE_TIME; - @ApiProperty({ required: false }) + @ApiProperty({ + enum: [SortValue.DESC, SortValue.ASC], + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() - sortByValue: string = SortValue.DESC; + @IsEnum(SortValue) + sortBy: string = SortValue.DESC; } export class GetCredentialDefinitionBySchemaIdDto { diff --git a/apps/api-gateway/src/schema/schema.controller.ts b/apps/api-gateway/src/schema/schema.controller.ts index 036b188e5..7d0fee4a0 100644 --- a/apps/api-gateway/src/schema/schema.controller.ts +++ b/apps/api-gateway/src/schema/schema.controller.ts @@ -10,7 +10,7 @@ import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import IResponseType from '@credebl/common/interfaces/response.interface'; import { Response } from 'express'; import { User } from '../authz/decorators/user.decorator'; -import { ICredDeffSchemaSearchInterface, ISchemaSearchInterface } from '../interfaces/ISchemaSearch.interface'; +import { ICredDeffSchemaSearchInterface, ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { GetAllSchemaDto, GetCredentialDefinitionBySchemaIdDto } from './dtos/get-all-schema.dto'; import { OrgRoles } from 'libs/org-roles/enums'; @@ -19,6 +19,7 @@ import { IUserRequestInterface } from './interfaces'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { CreateSchemaDto } from '../dtos/create-schema.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; +import { SortFields } from 'apps/ledger/src/schema/enum/schema.enum'; @UseFilters(CustomExceptionFilter) @Controller('orgs') @@ -102,63 +103,44 @@ export class SchemaController { message: ResponseMessages.schema.success.fetch, data: credentialDefinitionList.response }; + return res.status(HttpStatus.OK).json(finalResponse); } @Get('/:orgId/schemas') @ApiOperation({ - summary: 'Get all schemas by org id.', + summary: 'Schemas by org id.', description: 'Get all schemas by org id.' }) @ApiQuery({ - name: 'pageNumber', - type: Number, - required: false - }) - @ApiQuery({ - name: 'searchByText', - type: String, - required: false - }) - @ApiQuery({ - name: 'pageSize', - type: Number, - required: false - }) - @ApiQuery({ - name: 'sorting', - type: String, - required: false - }) - @ApiQuery({ - name: 'sortByValue', - type: String, + name: 'sortField', + enum: SortFields, required: false }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getSchemas( @Query() getAllSchemaDto: GetAllSchemaDto, @Param('orgId') orgId: string, @Res() res: Response, @User() user: IUserRequestInterface - ): Promise { + ): Promise { - const { pageSize, searchByText, pageNumber, sorting, sortByValue } = getAllSchemaDto; - const schemaSearchCriteria: ISchemaSearchInterface = { + const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllSchemaDto; + const schemaSearchCriteria: ISchemaSearchPayload = { pageNumber, searchByText, pageSize, - sorting, - sortByValue + sortField, + sortBy }; const schemasResponse = await this.appService.getSchemas(schemaSearchCriteria, user, orgId); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.schema.success.fetch, - data: schemasResponse.response + data: schemasResponse }; return res.status(HttpStatus.OK).json(finalResponse); } diff --git a/apps/api-gateway/src/schema/schema.service.ts b/apps/api-gateway/src/schema/schema.service.ts index c3d0b710f..6ac010521 100644 --- a/apps/api-gateway/src/schema/schema.service.ts +++ b/apps/api-gateway/src/schema/schema.service.ts @@ -2,8 +2,9 @@ import { Injectable, Inject } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; import { BaseService } from '../../../../libs/service/base.service'; import { CreateSchemaDto } from '../dtos/create-schema.dto'; -import { ICredDeffSchemaSearchInterface, ISchemaSearchInterface } from '../interfaces/ISchemaSearch.interface'; +import { ICredDeffSchemaSearchInterface, ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; import { IUserRequestInterface } from './interfaces'; +import { ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; @Injectable() export class SchemaService extends BaseService { @@ -26,11 +27,9 @@ export class SchemaService extends BaseService { return this.sendNats(this.schemaServiceProxy, 'get-schema-by-id', payload); } - getSchemas(schemaSearchCriteria: ISchemaSearchInterface, user: IUserRequestInterface, orgId: string): Promise<{ - response: object; - }> { + getSchemas(schemaSearchCriteria: ISchemaSearchPayload, user: IUserRequestInterface, orgId: string): Promise { const schemaSearch = { schemaSearchCriteria, user, orgId }; - return this.sendNats(this.schemaServiceProxy, 'get-schemas', schemaSearch); + return this.sendNatsMessage(this.schemaServiceProxy, 'get-schemas', schemaSearch); } getcredDeffListBySchemaId(schemaId: string, schemaSearchCriteria: ICredDeffSchemaSearchInterface, user: IUserRequestInterface, orgId: string): Promise<{ diff --git a/apps/ledger/src/schema/enum/schema.enum.ts b/apps/ledger/src/schema/enum/schema.enum.ts new file mode 100644 index 000000000..6a7f716d9 --- /dev/null +++ b/apps/ledger/src/schema/enum/schema.enum.ts @@ -0,0 +1,11 @@ + + +export enum SortFields { + ID = 'id', + CREATED_DATE_TIME = 'createDateTime', + NAME = 'name', + VERSION = 'version', + LEDGER_ID = 'schemaLedgerId', + PUBLISHER_DID = 'publisherDid', + ISSUER_ID = 'issuerId' +} \ No newline at end of file diff --git a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts index 35f59ea71..353bb2a55 100644 --- a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts @@ -41,7 +41,7 @@ export interface ISchemaPayload { schemaSortBy?: string; } -export interface ISchemaSearchInterface { +export interface ISchemaSearchPayload { schemaSearchCriteria: ISchemaSearchCriteria, user: IUserRequestInterface, orgId: string @@ -51,8 +51,8 @@ export interface ISchemaSearchCriteria { ledgerId?: string; pageNumber: number; pageSize: number; - sorting: string; - sortByValue: string; + sortField: string; + sortBy: string; searchByText: string; user: IUserRequestInterface } diff --git a/apps/ledger/src/schema/interfaces/schema.interface.ts b/apps/ledger/src/schema/interfaces/schema.interface.ts index c2f8eb05d..1968f8a20 100644 --- a/apps/ledger/src/schema/interfaces/schema.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema.interface.ts @@ -44,4 +44,21 @@ export interface AgentDetails { orgDid: string; agentEndPoint: string; tenantId: string -} \ No newline at end of file +} + +export interface ISchemaData { + createDateTime: Date; + createdBy: string; + name: string; + version: string; + attributes: string; + schemaLedgerId: string; + publisherDid: string; + issuerId: string; + orgId: string; +} + +export interface ISchemasWithCount { + schemasCount: number; + schemasResult: ISchemaData[]; +} diff --git a/apps/ledger/src/schema/repositories/schema.repository.ts b/apps/ledger/src/schema/repositories/schema.repository.ts index f822025b8..912f59d35 100644 --- a/apps/ledger/src/schema/repositories/schema.repository.ts +++ b/apps/ledger/src/schema/repositories/schema.repository.ts @@ -1,10 +1,11 @@ /* eslint-disable camelcase */ -import { ConflictException, Injectable, Logger } from '@nestjs/common'; +import { ConflictException, Injectable, InternalServerErrorException, Logger } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; import { ledgers, org_agents, org_agents_type, organisation, schema } from '@prisma/client'; import { ISchema, ISchemaSearchCriteria } from '../interfaces/schema-payload.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; -import { AgentDetails } from '../interfaces/schema.interface'; +import { AgentDetails, ISchemasWithCount } from '../interfaces/schema.interface'; +import { SortValue } from '@credebl/enum/enum'; @Injectable() export class SchemaRepository { @@ -70,20 +71,7 @@ export class SchemaRepository { } } - async getSchemas(payload: ISchemaSearchCriteria, orgId: string): Promise<{ - schemasCount: number; - schemasResult: { - createDateTime: Date; - createdBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - }[]; - }> { + async getSchemas(payload: ISchemaSearchCriteria, orgId: string): Promise { try { const schemasResult = await this.prisma.schema.findMany({ where: { @@ -107,7 +95,7 @@ export class SchemaRepository { issuerId: true }, orderBy: { - [payload.sorting]: 'DESC' === payload.sortByValue ? 'desc' : 'ASC' === payload.sortByValue ? 'asc' : 'desc' + [payload.sortField]: SortValue.ASC === payload.sortBy ? 'asc' : 'desc' }, take: Number(payload.pageSize), skip: (payload.pageNumber - 1) * payload.pageSize @@ -122,7 +110,11 @@ export class SchemaRepository { return { schemasCount, schemasResult }; } catch (error) { this.logger.error(`Error in getting schemas: ${error}`); - throw error; + throw new InternalServerErrorException( + ResponseMessages.schema.error.failedFetchSchema, + { cause: new Error(), description: error.message } + ); + } } @@ -192,7 +184,7 @@ export class SchemaRepository { createDateTime: true }, orderBy: { - [payload.sorting]: 'DESC' === payload.sortByValue ? 'desc' : 'ASC' === payload.sortByValue ? 'asc' : 'desc' + [payload.sortField]: SortValue.ASC === payload.sortBy ? 'asc' : 'desc' } }); } catch (error) { @@ -238,7 +230,7 @@ export class SchemaRepository { issuerId: true }, orderBy: { - [payload.sorting]: 'DESC' === payload.sortByValue ? 'desc' : 'ASC' === payload.sortByValue ? 'asc' : 'desc' + [payload.sortField]: 'DESC' === payload.sortBy ? 'desc' : 'ASC' === payload.sortBy ? 'asc' : 'desc' }, take: Number(payload.pageSize), skip: (payload.pageNumber - 1) * payload.pageSize diff --git a/apps/ledger/src/schema/schema.controller.ts b/apps/ledger/src/schema/schema.controller.ts index 1b790ef81..d80df8995 100644 --- a/apps/ledger/src/schema/schema.controller.ts +++ b/apps/ledger/src/schema/schema.controller.ts @@ -1,9 +1,10 @@ import { Controller } from '@nestjs/common'; import { SchemaService } from './schema.service'; import { MessagePattern } from '@nestjs/microservices'; -import { ISchema, ISchemaCredDeffSearchInterface, ISchemaSearchInterface } from './interfaces/schema-payload.interface'; +import { ISchema, ISchemaCredDeffSearchInterface, ISchemaSearchPayload } from './interfaces/schema-payload.interface'; import { schema } from '@prisma/client'; import { ResponseMessages } from '@credebl/common/response-messages'; +import { ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; @Controller('schema') @@ -24,27 +25,9 @@ export class SchemaController { } @MessagePattern({ cmd: 'get-schemas' }) - async getSchemas(schemaSearch: ISchemaSearchInterface): Promise<{ - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - createDateTime: Date; - createdBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - }[]; - }> { - const { schemaSearchCriteria, user, orgId } = schemaSearch; - return this.schemaService.getSchemas(schemaSearchCriteria, user, orgId); + async getSchemas(schemaSearch: ISchemaSearchPayload): Promise { + const { schemaSearchCriteria, orgId } = schemaSearch; + return this.schemaService.getSchemas(schemaSearchCriteria, orgId); } @MessagePattern({ cmd: 'get-cred-deff-list-by-schemas-id' }) @@ -67,7 +50,7 @@ export class SchemaController { } @MessagePattern({ cmd: 'get-all-schemas' }) - async getAllSchema(schemaSearch: ISchemaSearchInterface): Promise<{ + async getAllSchema(schemaSearch: ISchemaSearchPayload): Promise<{ totalItems: number; hasNextPage: boolean; hasPreviousPage: boolean; diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index ca848b0da..c2d5f8323 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -17,6 +17,7 @@ import { IUserRequestInterface } from './interfaces/schema.interface'; import { CreateSchemaAgentRedirection, GetSchemaAgentRedirection } from './schema.interface'; import { map } from 'rxjs/operators'; import { OrgAgentType } from '@credebl/enum/enum'; +import { ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; @Injectable() export class SchemaService extends BaseService { @@ -319,49 +320,32 @@ export class SchemaService extends BaseService { } } - async getSchemas(schemaSearchCriteria: ISchemaSearchCriteria, user: IUserRequestInterface, orgId: string): Promise<{ - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - createDateTime: Date; - createdBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - }[]; - }> { + async getSchemas(schemaSearchCriteria: ISchemaSearchCriteria, orgId: string): Promise { try { const response = await this.schemaRepository.getSchemas(schemaSearchCriteria, orgId); + if (0 === response.schemasCount) { + throw new NotFoundException(ResponseMessages.schema.error.notFound); + } + const schemasDetails = response?.schemasResult.map(schemaAttributeItem => { const attributes = JSON.parse(schemaAttributeItem.attributes); return { ...schemaAttributeItem, attributes }; }); - const schemasResponse = { + const nextPage:number = Number(schemaSearchCriteria.pageNumber) + 1; + + const schemasResponse: ISchemasWithPagination = { totalItems: response.schemasCount, hasNextPage: schemaSearchCriteria.pageSize * schemaSearchCriteria.pageNumber < response.schemasCount, hasPreviousPage: 1 < schemaSearchCriteria.pageNumber, - nextPage: schemaSearchCriteria.pageNumber + 1, + nextPage, previousPage: schemaSearchCriteria.pageNumber - 1, lastPage: Math.ceil(response.schemasCount / schemaSearchCriteria.pageSize), data: schemasDetails }; - if (0 !== response.schemasCount) { - return schemasResponse; - } else { - throw new NotFoundException(ResponseMessages.schema.error.notFound); - } - + return schemasResponse; } catch (error) { this.logger.error(`Error in retrieving schemas by org id: ${error}`); diff --git a/libs/common/src/interfaces/schema.interface.ts b/libs/common/src/interfaces/schema.interface.ts new file mode 100644 index 000000000..568272663 --- /dev/null +++ b/libs/common/src/interfaces/schema.interface.ts @@ -0,0 +1,23 @@ + +export interface ISchemasWithPagination { + totalItems: number; + hasNextPage: boolean; + hasPreviousPage: boolean; + nextPage: number; + previousPage: number; + lastPage: number; + data: ISchemaData[]; + } + + export interface ISchemaData { + createDateTime: Date; + createdBy: string; + name: string; + version: string; + attributes: string; + schemaLedgerId: string; + publisherDid: string; + issuerId: string; + orgId: string; + } + \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 02a92385e..db8744af6 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -118,7 +118,8 @@ export const ResponseMessages = { schemaIdNotFound: 'SchemaLedgerId not found', credentialDefinitionNotFound: 'No credential definition exist', notStoredCredential: 'User credential not stored', - agentDetailsNotFound: 'Agent details not found' + agentDetailsNotFound: 'Agent details not found', + failedFetchSchema: 'Failed to fetch schema data' } }, credentialDefinition: { From e28af85fc46d9feed1b5463326baad12466e28e8 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Fri, 22 Dec 2023 19:07:00 +0530 Subject: [PATCH 020/107] refactor: get connection details by connection id api Signed-off-by: bhavanakarwade --- .../src/agent-service.controller.ts | 3 ++- .../src/agent-service.service.ts | 5 +++-- .../src/connection/connection.controller.ts | 10 +++++----- .../src/connection/connection.service.ts | 8 +++----- .../src/interfaces/ISchemaSearch.interface.ts | 16 ++++++++++++++++ apps/api-gateway/src/main.ts | 8 +++++++- apps/connection/src/connection.controller.ts | 3 ++- apps/connection/src/connection.service.ts | 19 +++++++------------ .../src/interfaces/connection.interfaces.ts | 15 ++++++++++++++- .../src/interfaces/response.interface.ts | 8 ++++++++ libs/common/src/response-messages/index.ts | 4 ++-- 11 files changed, 69 insertions(+), 30 deletions(-) diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 9fc94f190..8a38c062c 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -5,6 +5,7 @@ import { GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAgentSpinupDto, import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; +import { IConnectionDetailsById } from 'apps/connection/src/interfaces/connection.interfaces'; @Controller() export class AgentServiceController { @@ -90,7 +91,7 @@ export class AgentServiceController { } @MessagePattern({ cmd: 'agent-get-connections-by-connectionId' }) - async getConnectionsByconnectionId(payload: { url: string, apiKey: string }): Promise { + async getConnectionsByconnectionId(payload: { url: string, apiKey: string }): Promise { return this.agentServiceService.getConnectionsByconnectionId(payload.url, payload.apiKey); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 8659486c1..110c4a133 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -31,6 +31,7 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { Socket, io } from 'socket.io-client'; import { WebSocketGateway } from '@nestjs/websockets'; import * as retry from 'async-retry'; +import { IConnectionDetailsById } from 'apps/connection/src/interfaces/connection.interfaces'; @Injectable() @WebSocketGateway() @@ -948,13 +949,13 @@ export class AgentServiceService { } } - async getConnectionsByconnectionId(url: string, apiKey: string): Promise { + async getConnectionsByconnectionId(url: string, apiKey: string): Promise { try { const data = await this.commonService .httpGet(url, { headers: { 'x-api-key': apiKey } }) .then(async response => response); - return data; + } catch (error) { this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); throw error; diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 850355101..c29e34715 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -18,6 +18,7 @@ import { Roles } from '../authz/decorators/roles.decorator'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { GetAllConnectionsDto } from './dtos/get-all-connections.dto'; import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; +import IResponse from '@credebl/common/interfaces/response.interface'; @UseFilters(CustomExceptionFilter) @Controller() @@ -45,19 +46,18 @@ export class ConnectionController { summary: `Get connections by connection Id`, description: `Get connections by connection Id` }) - @ApiResponse({ status: 200, description: 'Success', type: AuthTokenResponse }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: AuthTokenResponse }) async getConnectionsById( @User() user: IUserRequest, @Param('connectionId') connectionId: string, @Param('orgId') orgId: string, @Res() res: Response - ): Promise { + ): Promise { const connectionsDetails = await this.connectionService.getConnectionsById(user, connectionId, orgId); - - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.connection.success.fetch, - data: connectionsDetails.response + data: connectionsDetails }; return res.status(HttpStatus.OK).json(finalResponse); } diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 214a5c013..9425f26bb 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -4,7 +4,7 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { ConnectionDto, CreateConnectionDto } from './dtos/connection.dto'; import { IUserRequestInterface } from './interfaces'; -import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; +import { IConnectionDetailsById, IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; @Injectable() export class ConnectionService extends BaseService { @@ -71,10 +71,8 @@ export class ConnectionService extends BaseService { user: IUserRequest, connectionId: string, orgId: string - ): Promise<{ - response: object; - }> { + ): Promise { const payload = { user, connectionId, orgId }; - return this.sendNats(this.connectionServiceProxy, 'get-all-connections-by-connectionId', payload); + return this.sendNatsMessage(this.connectionServiceProxy, 'get-all-connections-by-connectionId', payload); } } diff --git a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts index 13e0c77e6..a1fdb706e 100644 --- a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts @@ -25,3 +25,19 @@ export interface IConnectionSearchinterface { searchByText: string; user?: IUserRequestInterface } + +export interface IConnectionDetailsById { + id: string; + createdAt: string; + did: string; + theirDid: string; + theirLabel: string; + state: string; + role: string; + autoAcceptConnection: boolean; + threadId: string; + protocol: string; + outOfBandId: string; + updatedAt: string; + } + diff --git a/apps/api-gateway/src/main.ts b/apps/api-gateway/src/main.ts index a0b591fba..b7d9893a2 100644 --- a/apps/api-gateway/src/main.ts +++ b/apps/api-gateway/src/main.ts @@ -31,7 +31,13 @@ async function bootstrap(): Promise { app.use(helmet({ xssFilter:true })); - app.useGlobalPipes(new ValidationPipe()); + + app.useGlobalPipes( + new ValidationPipe({ + whitelist: true + }) + ); + const options = new DocumentBuilder() .setTitle(`${process.env.PLATFORM_NAME}`) .setDescription(`${process.env.PLATFORM_NAME} Platform APIs`) diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 3bb9a2572..d13dc136e 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -3,6 +3,7 @@ import { ConnectionService } from './connection.service'; // Import the common s import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package import { IConnection, + IConnectionDetailsById, IConnectionInterface, IFetchConnectionById, IFetchConnectionInterface @@ -59,7 +60,7 @@ export class ConnectionController { } @MessagePattern({ cmd: 'get-all-connections-by-connectionId' }) - async getConnectionsById(payload: IFetchConnectionById): Promise { + async getConnectionsById(payload: IFetchConnectionById): Promise { const { user, connectionId, orgId } = payload; return this.connectionService.getConnectionsById(user, connectionId, orgId); } diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index c613768e3..4f06a8ed6 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -6,6 +6,7 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs'; import { ConnectionInvitationResponse, + IConnectionDetailsById, IConnectionInterface, IConnectionSearchCriteria, IUserRequestInterface @@ -286,7 +287,7 @@ export class ConnectionService { } } - async getConnectionsById(user: IUserRequest, connectionId: string, orgId: string): Promise { + async getConnectionsById(user: IUserRequest, connectionId: string, orgId: string): Promise { try { const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); @@ -309,8 +310,9 @@ export class ConnectionService { } const apiKey = platformConfig?.sgApiKey; - const createConnectionInvitation = await this._getConnectionsByConnectionId(url, apiKey); - return createConnectionInvitation?.response; + const getConnectionDetailsByConnectionId = await this._getConnectionsByConnectionId(url, apiKey); + return getConnectionDetailsByConnectionId; + } catch (error) { this.logger.error(`[getConnectionsById] - error in get connections : ${JSON.stringify(error)}`); @@ -330,19 +332,12 @@ export class ConnectionService { async _getConnectionsByConnectionId( url: string, apiKey: string - ): Promise<{ - response: string; - }> { + ): Promise { try { const pattern = { cmd: 'agent-get-connections-by-connectionId' }; const payload = { url, apiKey }; return this.connectionServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ({ - response - })) - ) + .send(pattern, payload) .toPromise() .catch((error) => { this.logger.error(`catch: ${JSON.stringify(error)}`); diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 2bbedae60..5829f715c 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -122,4 +122,17 @@ export interface IConnectionSearchCriteria { searchByText: string; user: IUserRequestInterface } - +export interface IConnectionDetailsById { + id: string; + createdAt: string; + did: string; + theirDid: string; + theirLabel: string; + state: string; + role: string; + autoAcceptConnection: boolean; + threadId: string; + protocol: string; + outOfBandId: string; + updatedAt: string; +} diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 52639580f..524342408 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -5,3 +5,11 @@ export default interface IResponseType { data?: unknown; error?: unknown; }; + +export default interface IResponse { + statusCode: number; + message?: string; + label?: string; + data?: unknown; + error?: unknown; +}; diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index c45eb1181..627623705 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -158,7 +158,7 @@ export const ResponseMessages = { connection: { success: { create: 'Connection created successfully', - fetch: 'Connection fetched successfully' + fetch: 'Connection details fetched successfully' }, error: { exists: 'Connection is already exist', @@ -179,7 +179,7 @@ export const ResponseMessages = { error: { exists: 'Credentials is already exist', credentialsNotFound: 'Credentials not found', - agentEndPointNotFound: 'agentEndPoint Not Found', + agentEndPointNotFound: 'agent end point Not Found', organizationNotFound: 'organization Not Found', agentUrlNotFound: 'agent url not found', notFound: 'History not found', From c6016bd64014f88af12434d4df6349d95b031607 Mon Sep 17 00:00:00 2001 From: Nishad Date: Fri, 22 Dec 2023 19:34:16 +0530 Subject: [PATCH 021/107] changes in the cred-def API Signed-off-by: Nishad --- .../src/interfaces/ISchemaSearch.interface.ts | 9 +-------- apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts | 4 ++-- apps/api-gateway/src/schema/schema.controller.ts | 6 +++--- apps/api-gateway/src/schema/schema.service.ts | 4 ++-- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts index 1714c1654..8f5fdf87e 100644 --- a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts @@ -6,17 +6,10 @@ export interface ISchemaSearchPayload { pageSize: number; sortField: string; sortBy: string; - searchByText: string; + searchByText?: string; user?: IUserRequestInterface } -export interface ICredDeffSchemaSearchInterface { - pageNumber: number; - pageSize: number; - sorting: string; - sortByValue: string; - user?: IUserRequestInterface -} export interface IConnectionSearchinterface { pageNumber: number; pageSize: number; diff --git a/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts b/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts index 7e8739636..90b43cf2f 100644 --- a/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts +++ b/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts @@ -53,11 +53,11 @@ export class GetCredentialDefinitionBySchemaIdDto { @ApiProperty({ required: false }) @IsOptional() - sorting: string = 'id'; + sortField: string = 'id'; @ApiProperty({ required: false }) @IsOptional() - sortByValue: string = SortValue.DESC; + sortBy: string = SortValue.DESC; } export class GetAllSchemaByPlatformDto { diff --git a/apps/api-gateway/src/schema/schema.controller.ts b/apps/api-gateway/src/schema/schema.controller.ts index 7d0fee4a0..b0031f7e5 100644 --- a/apps/api-gateway/src/schema/schema.controller.ts +++ b/apps/api-gateway/src/schema/schema.controller.ts @@ -10,7 +10,7 @@ import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import IResponseType from '@credebl/common/interfaces/response.interface'; import { Response } from 'express'; import { User } from '../authz/decorators/user.decorator'; -import { ICredDeffSchemaSearchInterface, ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; +import { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { GetAllSchemaDto, GetCredentialDefinitionBySchemaIdDto } from './dtos/get-all-schema.dto'; import { OrgRoles } from 'libs/org-roles/enums'; @@ -75,12 +75,12 @@ export class SchemaController { required: false }) @ApiQuery({ - name: 'sorting', + name: 'sortField', type: String, required: false }) @ApiQuery({ - name: 'sortByValue', + name: 'sortBy', type: String, required: false }) diff --git a/apps/api-gateway/src/schema/schema.service.ts b/apps/api-gateway/src/schema/schema.service.ts index 6ac010521..48bf86dc3 100644 --- a/apps/api-gateway/src/schema/schema.service.ts +++ b/apps/api-gateway/src/schema/schema.service.ts @@ -2,7 +2,7 @@ import { Injectable, Inject } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; import { BaseService } from '../../../../libs/service/base.service'; import { CreateSchemaDto } from '../dtos/create-schema.dto'; -import { ICredDeffSchemaSearchInterface, ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; +import { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; import { IUserRequestInterface } from './interfaces'; import { ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; @@ -32,7 +32,7 @@ export class SchemaService extends BaseService { return this.sendNatsMessage(this.schemaServiceProxy, 'get-schemas', schemaSearch); } - getcredDeffListBySchemaId(schemaId: string, schemaSearchCriteria: ICredDeffSchemaSearchInterface, user: IUserRequestInterface, orgId: string): Promise<{ + getcredDeffListBySchemaId(schemaId: string, schemaSearchCriteria: ISchemaSearchPayload, user: IUserRequestInterface, orgId: string): Promise<{ response: object; }> { const payload = { schemaId, schemaSearchCriteria, user, orgId }; From 5429d1a75b17931097557220b516187dbc22772e Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Sat, 23 Dec 2023 16:05:34 +0530 Subject: [PATCH 022/107] refactor: get all connections api Signed-off-by: bhavanakarwade --- .../src/connection/connection.controller.ts | 51 +++++++------------ .../src/connection/connection.service.ts | 11 ++-- .../dtos/get-all-connections.dto.ts | 30 ++++++++--- .../interfaces/IConnectionSearch.interface.ts | 10 ++++ .../src/interfaces/ISchemaSearch.interface.ts | 9 ---- apps/connection/src/connection.controller.ts | 5 +- apps/connection/src/connection.repository.ts | 19 ++----- apps/connection/src/connection.service.ts | 38 +++++--------- apps/connection/src/enum/connection.enum.ts | 3 ++ .../src/interfaces/connection.interfaces.ts | 13 ++--- .../src/interfaces/connection.interface.ts | 22 ++++++++ .../src/interfaces/response.interface.ts | 8 +++ libs/common/src/response-messages/index.ts | 2 +- 13 files changed, 110 insertions(+), 111 deletions(-) create mode 100644 apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts create mode 100644 apps/connection/src/enum/connection.enum.ts create mode 100644 libs/common/src/interfaces/connection.interface.ts diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 850355101..0fe1751f5 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -17,7 +17,10 @@ import { OrgRoles } from 'libs/org-roles/enums'; import { Roles } from '../authz/decorators/roles.decorator'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { GetAllConnectionsDto } from './dtos/get-all-connections.dto'; -import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; +import { IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; +import { SortFields } from 'apps/connection/src/enum/connection.enum'; +import { ApiResponseDto } from '../dtos/apiResponse.dto'; +import IResponse from '@credebl/common/interfaces/response.interface'; @UseFilters(CustomExceptionFilter) @Controller() @@ -72,56 +75,36 @@ export class ConnectionController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @ApiOperation({ - summary: `Fetch all connection details`, - description: `Fetch all connection details` + summary: `Fetch all connections by orgId`, + description: `Fetch all connections by orgId` }) @ApiQuery({ - name: 'pageNumber', - type: Number, + name: 'sortField', + enum: SortFields, required: false - }) - @ApiQuery({ - name: 'searchByText', - type: String, - required: false - }) - @ApiQuery({ - name: 'pageSize', - type: Number, - required: false - }) - @ApiQuery({ - name: 'sorting', - type: String, - required: false - }) - @ApiQuery({ - name: 'sortByValue', - type: String, - required: false - }) - @ApiResponse({ status: 200, description: 'Success', type: AuthTokenResponse }) + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getConnections( @Query() getAllConnectionsDto: GetAllConnectionsDto, @User() user: IUserRequest, @Param('orgId') orgId: string, @Res() res: Response ): Promise { - - const { pageSize, searchByText, pageNumber, sorting, sortByValue } = getAllConnectionsDto; - const connectionSearchCriteria: IConnectionSearchinterface = { + + const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllConnectionsDto; + const connectionSearchCriteria: IConnectionSearchCriteria = { pageNumber, searchByText, pageSize, - sorting, - sortByValue + sortField, + sortBy }; const connectionDetails = await this.connectionService.getConnections(connectionSearchCriteria, user, orgId); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.connection.success.fetch, - data: connectionDetails.response + data: connectionDetails }; return res.status(HttpStatus.OK).json(finalResponse); } diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 214a5c013..839ddb956 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -4,7 +4,8 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { ConnectionDto, CreateConnectionDto } from './dtos/connection.dto'; import { IUserRequestInterface } from './interfaces'; -import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; +import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; @Injectable() export class ConnectionService extends BaseService { @@ -57,14 +58,12 @@ export class ConnectionService extends BaseService { } getConnections( - connectionSearchCriteria: IConnectionSearchinterface, + connectionSearchCriteria: IConnectionSearchCriteria, user: IUserRequest, orgId: string - ): Promise<{ - response: object; - }> { + ): Promise { const payload = { connectionSearchCriteria, user, orgId }; - return this.sendNats(this.connectionServiceProxy, 'get-all-connections', payload); + return this.sendNatsMessage(this.connectionServiceProxy, 'get-all-connections', payload); } getConnectionsById( diff --git a/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts b/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts index 5f02fc395..5fb4fce65 100644 --- a/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts +++ b/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts @@ -1,27 +1,41 @@ import { ApiProperty } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsOptional } from "class-validator"; +import { Transform, Type } from "class-transformer"; +import { IsEnum, IsOptional } from "class-validator"; import { SortValue } from "../../enum"; +import { trim } from "@credebl/common/cast.helper"; +import { SortFields } from "apps/connection/src/enum/connection.enum"; export class GetAllConnectionsDto { + @ApiProperty({ required: false }) @IsOptional() + @Transform(({ value }) => trim(value)) @Type(() => String) searchByText: string = ''; - @ApiProperty({ required: false }) + @ApiProperty({ required: false, example: '1' }) @IsOptional() pageNumber: number = 1; - @ApiProperty({ required: false }) + @ApiProperty({ required: false, example: '10' }) @IsOptional() pageSize: number = 10; - @ApiProperty({ required: false }) + @ApiProperty({ + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() - sorting: string = 'id'; + @IsEnum(SortFields) + sortField: string = SortFields.CREATED_DATE_TIME; - @ApiProperty({ required: false }) + @ApiProperty({ + enum: [SortValue.DESC, SortValue.ASC], + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() - sortByValue: string = SortValue.DESC; + @IsEnum(SortValue) + sortBy: string = SortValue.DESC; } + diff --git a/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts b/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts new file mode 100644 index 000000000..25b90d897 --- /dev/null +++ b/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts @@ -0,0 +1,10 @@ +import { IUserRequestInterface } from './IUserRequestInterface'; + +export interface IConnectionSearchCriteria { + pageNumber: number; + pageSize: number; + sortField: string; + sortBy: string; + searchByText: string; + user?: IUserRequestInterface +} diff --git a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts index 8f5fdf87e..0e219c8bd 100644 --- a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts @@ -9,12 +9,3 @@ export interface ISchemaSearchPayload { searchByText?: string; user?: IUserRequestInterface } - -export interface IConnectionSearchinterface { - pageNumber: number; - pageSize: number; - sorting: string; - sortByValue: string; - searchByText: string; - user?: IUserRequestInterface -} diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 3bb9a2572..37b2e0651 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -5,8 +5,9 @@ import { IConnection, IConnectionInterface, IFetchConnectionById, - IFetchConnectionInterface + IFetchConnections } from './interfaces/connection.interfaces'; +import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; @Controller() export class ConnectionController { @@ -53,7 +54,7 @@ export class ConnectionController { } @MessagePattern({ cmd: 'get-all-connections' }) - async getConnections(payload: IFetchConnectionInterface): Promise { + async getConnections(payload: IFetchConnections): Promise { const { user, orgId, connectionSearchCriteria } = payload; return this.connectionService.getConnections(user, orgId, connectionSearchCriteria); } diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index 2465982c6..16a17405c 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -4,6 +4,8 @@ import { PrismaService } from '@credebl/prisma-service'; import { agent_invitations, org_agents, platform_config, shortening_url } from '@prisma/client'; import { IConnectionInterface, IConnectionSearchCriteria, OrgAgent } from './interfaces/connection.interfaces'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; +import { IConnectionsListCount } from '@credebl/common/interfaces/connection.interface'; +import { SortValue } from '@credebl/enum/enum'; // import { OrgAgent } from './interfaces/connection.interfaces'; @Injectable() export class ConnectionRepository { @@ -245,17 +247,7 @@ export class ConnectionRepository { user: IUserRequest, orgId: string, connectionSearchCriteria: IConnectionSearchCriteria - ): Promise<{ - connectionCount: number; - connectionsList: { - createDateTime: Date; - createdBy: string; - connectionId: string; - theirLabel: string; - state: string; - orgId: string; - }[]; - }> { + ): Promise { try { const connectionsList = await this.prisma.connections.findMany({ where: { @@ -274,10 +266,7 @@ export class ConnectionRepository { connectionId: true }, orderBy: { - [connectionSearchCriteria?.sorting || 'createDateTime']: - 'DESC' === connectionSearchCriteria?.sortByValue - ? 'desc' - : 'asc' + [connectionSearchCriteria.sortField]: SortValue.ASC === connectionSearchCriteria.sortBy ? 'asc' : 'desc' }, take: Number(connectionSearchCriteria.pageSize), skip: (connectionSearchCriteria.pageNumber - 1) * connectionSearchCriteria.pageSize diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index c613768e3..e0be37c83 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -15,6 +15,7 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { OrgAgentType } from '@credebl/enum/enum'; import { platform_config } from '@prisma/client'; +import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; @Injectable() export class ConnectionService { @@ -188,28 +189,18 @@ export class ConnectionService { user: IUserRequest, orgId: string, connectionSearchCriteria: IConnectionSearchCriteria - ): Promise<{ - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - createDateTime: Date; - createdBy: string; - connectionId: string; - theirLabel: string; - state: string; - orgId: string; - }[]; - }> { + ): Promise { try { const getConnectionList = await this.connectionRepository.getAllConnections( user, orgId, connectionSearchCriteria ); + + if (0 === getConnectionList.connectionCount) { + throw new NotFoundException(ResponseMessages.connection.error.connectionNotFound); + } + const connectionResponse: { totalItems: number; hasNextPage: boolean; @@ -235,20 +226,15 @@ export class ConnectionService { lastPage: Math.ceil(getConnectionList.connectionCount / connectionSearchCriteria.pageSize), data: getConnectionList.connectionsList }; - - if (0 !== getConnectionList.connectionCount) { return connectionResponse; - } else { - throw new NotFoundException(ResponseMessages.connection.error.connectionNotFound); - } } catch (error) { -; if (404 === error.status) { - throw new NotFoundException(error.response.message); - } - throw new RpcException( + + this.logger.error( `[getConnections] [NATS call]- error in fetch connections details : ${JSON.stringify(error)}` ); - } + + throw new RpcException(error.response ? error.response : error); + } } async _getAllConnections( diff --git a/apps/connection/src/enum/connection.enum.ts b/apps/connection/src/enum/connection.enum.ts new file mode 100644 index 000000000..492f37029 --- /dev/null +++ b/apps/connection/src/enum/connection.enum.ts @@ -0,0 +1,3 @@ +export enum SortFields { + CREATED_DATE_TIME = 'createDateTime' +} \ No newline at end of file diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 2bbedae60..01cf026e0 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -69,7 +69,7 @@ export class ConnectionPayload { contextCorrelationId: string; } -export class IFetchConnectionInterface { +export class IFetchConnections { connectionSearchCriteria: IConnectionSearchCriteria; user: IUserRequest; orgId: string; @@ -92,7 +92,6 @@ export interface ConnectionInvitationResponse { invitation: object; }; } - export interface OrgAgent { organisation: organisation; id: string; @@ -109,17 +108,11 @@ export interface OrgAgent { orgAgentTypeId: string; tenantId: string; } -export interface IConnectionSearchInterface { - schemaSearchCriteria: IConnectionSearchCriteria, - user: IUserRequestInterface, - orgId: string -} export interface IConnectionSearchCriteria { pageNumber: number; pageSize: number; - sorting: string; - sortByValue: string; + sortField: string; + sortBy: string; searchByText: string; user: IUserRequestInterface } - diff --git a/libs/common/src/interfaces/connection.interface.ts b/libs/common/src/interfaces/connection.interface.ts new file mode 100644 index 000000000..0ccbea2e0 --- /dev/null +++ b/libs/common/src/interfaces/connection.interface.ts @@ -0,0 +1,22 @@ +export interface IConnectionsListCount { + connectionCount: number; + connectionsList: IConnectionItem[]; + } + export interface IConnectionItem { + createDateTime: Date; + createdBy: string; + connectionId: string; + theirLabel: string; + state: string; + orgId: string; + } + export interface IConnectionList { + totalItems: number; + hasNextPage: boolean; + hasPreviousPage: boolean; + nextPage: number; + previousPage: number; + lastPage: number; + data: IConnectionItem[]; + } + \ No newline at end of file diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 52639580f..524342408 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -5,3 +5,11 @@ export default interface IResponseType { data?: unknown; error?: unknown; }; + +export default interface IResponse { + statusCode: number; + message?: string; + label?: string; + data?: unknown; + error?: unknown; +}; diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index db8744af6..a47be39c2 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -163,7 +163,7 @@ export const ResponseMessages = { connection: { success: { create: 'Connection created successfully', - fetch: 'Connection fetched successfully' + fetch: 'Connections details fetched successfully' }, error: { exists: 'Connection is already exist', From 22a5c70408dd4d5b8c766ec001ef3c1d118abd5d Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Sat, 23 Dec 2023 16:40:44 +0530 Subject: [PATCH 023/107] resolved sonarlint checks Signed-off-by: bhavanakarwade --- .../src/connection/dtos/get-all-connections.dto.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts b/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts index 5fb4fce65..553a8a5a2 100644 --- a/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts +++ b/apps/api-gateway/src/connection/dtos/get-all-connections.dto.ts @@ -7,12 +7,6 @@ import { SortFields } from "apps/connection/src/enum/connection.enum"; export class GetAllConnectionsDto { - @ApiProperty({ required: false }) - @IsOptional() - @Transform(({ value }) => trim(value)) - @Type(() => String) - searchByText: string = ''; - @ApiProperty({ required: false, example: '1' }) @IsOptional() pageNumber: number = 1; @@ -21,6 +15,12 @@ export class GetAllConnectionsDto { @IsOptional() pageSize: number = 10; + @ApiProperty({ required: false }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @Type(() => String) + searchByText: string = ''; + @ApiProperty({ required: false }) From 71ea39a1281e4f1fbcdbb74f3459bc3fc8218320 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Sat, 23 Dec 2023 23:50:41 +0530 Subject: [PATCH 024/107] fix:comments on user profile api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 2 +- apps/api-gateway/src/user/user.service.ts | 8 ++++---- apps/user/interfaces/user.interface.ts | 21 +++++++++++--------- apps/user/repositories/user.repository.ts | 12 +++++------ apps/user/src/user.controller.ts | 8 ++++---- apps/user/src/user.service.ts | 10 +++++----- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 48c8eef9a..3ca48abe1 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -71,7 +71,7 @@ export class UserController { */ @Get('/public-profiles') @ApiExcludeEndpoint() - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiOperation({ summary: 'Get users list', description: 'Get users list.' }) @ApiQuery({ name: 'pageNumber', diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index a077afc19..e9c2394ae 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -9,7 +9,7 @@ import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; import { AddPasskeyDetails } from './dto/add-user.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; -import { UsersProfile } from 'apps/user/interfaces/user.interface'; +import { IUsersProfile } from 'apps/user/interfaces/user.interface'; import { UsersActivity } from 'libs/user-activity/interface'; @Injectable() @@ -18,14 +18,14 @@ export class UserService extends BaseService { super('User Service'); } - async getProfile(id: string): Promise { + async getProfile(id: string): Promise { const payload = { id }; return this.sendNatsMessage(this.serviceProxy, 'get-user-profile', payload); } async getPublicProfile(username: string): Promise<{ response: object }> { - const payload = { username }; - return this.sendNats(this.serviceProxy, 'get-user-public-profile', payload); + const payload = { username }; + return this.sendNats(this.serviceProxy, 'get-user-public-profile', payload); } diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index c0446e58f..0f493701b 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -22,27 +22,30 @@ export interface Organisation { logoUrl: string; } -export interface UsersProfile { +export interface IUsersProfile { id?: string; username?: string; email?: string; firstName?: string; lastName?: string; supabaseUserId?: string; - userOrgRoles?: UserOrgRole[]; + userOrgRoles?: IUserOrgRole[]; } -interface UserOrgRole { +interface IUserOrgRole { id: string; userId: string; orgRoleId: string; orgId: string; - orgRole: { + orgRole :IOrgRole; + organisation:IOrganisation; +} + export interface IOrgRole{ id: string; - name: string; - description: string; + name: string; + description: string; }; - organisation: { + export interface IOrganisation{ id: string; name: string; description: string; @@ -51,7 +54,7 @@ interface UserOrgRole { website: string; publicProfile: boolean; }; -} + export interface OrgInvitations { id: string; @@ -69,7 +72,7 @@ interface UserOrgRole { username?: string; } - export interface UserInfo { + export interface IUserInformation { email: string; password: string; firstName: string; diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index ce4d23eca..cc5c72fea 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -8,8 +8,8 @@ import { UpdateUserProfile, UserCredentials, UserEmailVerificationDto, - UsersProfile, - UserInfo + IUsersProfile, + IUserInformation } from '../interfaces/user.interface'; import { InternalServerErrorException } from '@nestjs/common'; @@ -97,7 +97,7 @@ export class UserRepository { * @param id * @returns User profile data */ - async getUserById(id: string): Promise { + async getUserById(id: string): Promise { const queryOptions: UserQueryOptions = { id }; @@ -123,7 +123,7 @@ export class UserRepository { * @param id * @returns User profile data */ - async getUserPublicProfile(username: string): Promise { + async getUserPublicProfile(username: string): Promise { const queryOptions: UserQueryOptions = { username }; @@ -203,7 +203,7 @@ export class UserRepository { return this.findUser(queryOptions); } - async findUser(queryOptions: UserQueryOptions): Promise { + async findUser(queryOptions: UserQueryOptions): Promise { return this.prisma.user.findFirst({ where: { OR: [ @@ -330,7 +330,7 @@ export class UserRepository { * @returns Updates user details */ // eslint-disable-next-line camelcase - async updateUserInfo(email: string, userInfo: UserInfo): Promise { + async updateUserInfo(email: string, userInfo: IUserInformation): Promise { try { const updateUserDetails = await this.prisma.user.update({ where: { diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index cd51eeb54..51e28b845 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, CheckUserDetails, PlatformSettings, ShareUserCertificate, UserInvitations, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, UserInfo, UsersProfile } from '../interfaces/user.interface'; +import { AddPasskeyDetails, CheckUserDetails, PlatformSettings, ShareUserCertificate, UserInvitations, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, IUserInformation, IUsersProfile } from '../interfaces/user.interface'; import {IOrgUsers, Payload} from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; @@ -40,12 +40,12 @@ export class UserController { } @MessagePattern({ cmd: 'get-user-profile' }) - async getProfile(payload: { id }): Promise { + async getProfile(payload: { id }): Promise { return this.userService.getProfile(payload); } @MessagePattern({ cmd: 'get-user-public-profile' }) - async getPublicProfile(payload: { username }): Promise { + async getPublicProfile(payload: { username }): Promise { return this.userService.getPublicProfile(payload); } @MessagePattern({ cmd: 'update-user-profile' }) @@ -126,7 +126,7 @@ export class UserController { return this.userService.checkUserExist(payload.userEmail); } @MessagePattern({ cmd: 'add-user' }) - async addUserDetailsInKeyCloak(payload: { userInfo: UserInfo }): Promise { + async addUserDetailsInKeyCloak(payload: { userInfo: IUserInformation }): Promise { return this.userService.createUserForToken(payload.userInfo); } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 36e1d260f..f679712bc 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -38,8 +38,8 @@ import { UpdateUserProfile, UserCredentials, UserEmailVerificationDto, - UserInfo, - UsersProfile + IUserInformation, + IUsersProfile } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { UserActivityService } from '@credebl/user-activity'; @@ -208,7 +208,7 @@ export class UserService { } } - async createUserForToken(userInfo: UserInfo): Promise { + async createUserForToken(userInfo: IUserInformation): Promise { try { const { email } = userInfo; if (!userInfo.email) { @@ -368,7 +368,7 @@ export class UserService { } } - async getProfile(payload: { id }): Promise { + async getProfile(payload: { id }): Promise { try { const userData = await this.userRepository.getUserById(payload.id); const ecosystemSettingsList = await this.prisma.ecosystem_config.findMany({ @@ -388,7 +388,7 @@ export class UserService { } } - async getPublicProfile(payload: { username }): Promise { + async getPublicProfile(payload: { username }): Promise { try { const userProfile = await this.userRepository.getUserPublicProfile(payload.username); From a55992d6cdbb1c7f0c974ac1439d8238b73b2904 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Sun, 24 Dec 2023 00:00:54 +0530 Subject: [PATCH 025/107] fix:resolved comments of get user profile api Signed-off-by: pranalidhanavade --- apps/user/interfaces/user.interface.ts | 2 +- apps/user/repositories/user.repository.ts | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index 0f493701b..28ef25f61 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -23,7 +23,7 @@ export interface Organisation { } export interface IUsersProfile { - id?: string; + id: string; username?: string; email?: string; firstName?: string; diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index cc5c72fea..32c1d4b2e 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -254,7 +254,7 @@ export class UserRepository { }); } - async findUserForPublicProfile(queryOptions: UserQueryOptions): Promise { + async findUserForPublicProfile(queryOptions: UserQueryOptions): Promise { return this.prisma.user.findFirst({ where: { publicProfile: true, @@ -279,22 +279,30 @@ export class UserRepository { isEmailVerified: true, publicProfile: true, userOrgRoles: { - include: { - orgRole: true, + select:{ + id: true, + userId:true, + orgRoleId:true, + orgId:true, + orgRole: { + select:{ + id: true, + name: true, + description: true + } + }, organisation: { select: { id: true, name: true, description: true, + orgSlug:true, logoUrl: true, website: true, - orgSlug: true - }, - where: { publicProfile: true } - } } + } } } }); From 89baf0ede81f4b1f8df42dfe004c3669906be742 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Sun, 24 Dec 2023 00:15:00 +0530 Subject: [PATCH 026/107] fix:resolved comments of get user profile api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 2 +- apps/api-gateway/src/user/user.service.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 3ca48abe1..1a3c48fad 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -133,7 +133,7 @@ export class UserController { }) @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() - async getProfile(@User() reqUser: user, @Res() res: Response): Promise { + async getProfile(@User() reqUser: user, @Res() res: Response): Promise { const userData = await this.userService.getProfile(reqUser.id); const finalResponse: IResponseType = { diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index e9c2394ae..13d7f8cbb 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -25,7 +25,7 @@ export class UserService extends BaseService { async getPublicProfile(username: string): Promise<{ response: object }> { const payload = { username }; - return this.sendNats(this.serviceProxy, 'get-user-public-profile', payload); + return this.sendNatsMessage(this.serviceProxy, 'get-user-public-profile', payload); } @@ -71,7 +71,7 @@ export class UserService extends BaseService { ): Promise<{ response: object }> { const { pageNumber, pageSize, search } = getAllUsersDto; const payload = { pageNumber, pageSize, search }; - return this.sendNats(this.serviceProxy, 'fetch-users', payload); + return this.sendNatsMessage(this.serviceProxy, 'fetch-users', payload); } async checkUserExist(userEmail: string): Promise<{ response: string }> { From 4b8a8a56beb67ae1a7bc5c1233aef97fa27d3c91 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Sun, 24 Dec 2023 00:54:38 +0530 Subject: [PATCH 027/107] refactor:user activity api summary and description Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 6 +++--- apps/api-gateway/src/user/user.service.ts | 4 ++-- apps/user/src/user.controller.ts | 4 ++-- apps/user/src/user.service.ts | 4 ++-- libs/user-activity/interface/index.ts | 2 +- libs/user-activity/repositories/index.ts | 4 ++-- libs/user-activity/src/user-activity.service.ts | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 1a3c48fad..a4d295757 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -167,8 +167,8 @@ export class UserController { @Get('/activity') @ApiOperation({ - summary: 'organization invitations', - description: 'Fetch organization invitations' + summary: 'users activity', + description: 'Fetch users activity' }) @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() @@ -177,7 +177,7 @@ export class UserController { @Query('limit') limit: number, @Res() res: Response, @User() reqUser: user - ): Promise { + ): Promise { const userDetails = await this.userService.getUserActivities(reqUser.id, limit); const finalResponse: IResponseType = { diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index 13d7f8cbb..a9ff4d91a 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -10,7 +10,7 @@ import { AddPasskeyDetails } from './dto/add-user.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; import { IUsersProfile } from 'apps/user/interfaces/user.interface'; -import { UsersActivity } from 'libs/user-activity/interface'; +import { IUsersActivity } from 'libs/user-activity/interface'; @Injectable() export class UserService extends BaseService { @@ -79,7 +79,7 @@ export class UserService extends BaseService { return this.sendNats(this.serviceProxy, 'check-user-exist', payload); } - async getUserActivities(userId: string, limit: number): Promise { + async getUserActivities(userId: string, limit: number): Promise { const payload = { userId, limit }; return this.sendNatsMessage(this.serviceProxy, 'get-user-activity', payload); } diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 51e28b845..4f8770b97 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -8,7 +8,7 @@ import { MessagePattern } from '@nestjs/microservices'; import { UserService } from './user.service'; import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; import { user } from '@prisma/client'; -import { UsersActivity } from 'libs/user-activity/interface'; +import { IUsersActivity } from 'libs/user-activity/interface'; @Controller() export class UserController { @@ -132,7 +132,7 @@ export class UserController { // Fetch Users recent activities @MessagePattern({ cmd: 'get-user-activity' }) - async getUserActivity(payload: { userId: string, limit: number }): Promise { + async getUserActivity(payload: { userId: string, limit: number }): Promise { return this.userService.getUserActivity(payload.userId, payload.limit); } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index f679712bc..552f9a4ca 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -55,7 +55,7 @@ import { DISALLOWED_EMAIL_DOMAIN } from '@credebl/common/common.constant'; import { AwsService } from '@credebl/aws'; import puppeteer from 'puppeteer'; import { WorldRecordTemplate } from '../templates/world-record-template'; -import { UsersActivity } from 'libs/user-activity/interface'; +import { IUsersActivity } from 'libs/user-activity/interface'; @Injectable() export class UserService { @@ -755,7 +755,7 @@ export class UserService { } - async getUserActivity(userId: string, limit: number): Promise { + async getUserActivity(userId: string, limit: number): Promise { try { return this.userActivityService.getUserActivity(userId, limit); } catch (error) { diff --git a/libs/user-activity/interface/index.ts b/libs/user-activity/interface/index.ts index d6bc0c120..87ba1685b 100644 --- a/libs/user-activity/interface/index.ts +++ b/libs/user-activity/interface/index.ts @@ -1,4 +1,4 @@ -export interface UsersActivity { +export interface IUsersActivity { id: string, orgId: string, userId: string, diff --git a/libs/user-activity/repositories/index.ts b/libs/user-activity/repositories/index.ts index 3618f188c..7ab76edfc 100644 --- a/libs/user-activity/repositories/index.ts +++ b/libs/user-activity/repositories/index.ts @@ -1,6 +1,6 @@ /* eslint-disable camelcase */ import { Injectable, Logger } from '@nestjs/common'; -import { UsersActivity} from '../interface'; +import { IUsersActivity} from '../interface'; import { PrismaService } from '@credebl/prisma-service'; import { user_activity } from '@prisma/client'; @@ -23,7 +23,7 @@ export class UserActivityRepository { } - async getRecentActivities(userId: string, limit: number): Promise { + async getRecentActivities(userId: string, limit: number): Promise { return this.prisma.user_activity.findMany({ where: { userId diff --git a/libs/user-activity/src/user-activity.service.ts b/libs/user-activity/src/user-activity.service.ts index a84554d0a..f90f4f00a 100644 --- a/libs/user-activity/src/user-activity.service.ts +++ b/libs/user-activity/src/user-activity.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { UserActivityRepository } from '../repositories'; import { user_activity } from '@prisma/client'; -import { UsersActivity } from '../interface'; +import { IUsersActivity } from '../interface'; @Injectable() export class UserActivityService { @@ -16,7 +16,7 @@ export class UserActivityService { return this.userActivityRepository.logActivity(userId, orgId, action, details); } - async getUserActivity(userId: string, limit: number): Promise { + async getUserActivity(userId: string, limit: number): Promise { return this.userActivityRepository.getRecentActivities(userId, limit); } } From 62f2df61d1a294a09939eac31843054d4e4ffd98 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Sun, 24 Dec 2023 12:44:23 +0530 Subject: [PATCH 028/107] resolved comments Signed-off-by: bhavanakarwade --- apps/api-gateway/src/connection/connection.controller.ts | 8 +++++--- apps/connection/src/connection.controller.ts | 4 ++-- apps/connection/src/connection.repository.ts | 4 ++-- apps/connection/src/connection.service.ts | 4 ++-- apps/connection/src/interfaces/connection.interfaces.ts | 6 +++--- libs/common/src/interfaces/response.interface.ts | 8 ++++++++ 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 4ee43c1e6..cf02c71b5 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -18,6 +18,8 @@ import { Roles } from '../authz/decorators/roles.decorator'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { GetAllConnectionsDto } from './dtos/get-all-connections.dto'; import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; +import { ApiResponseDto } from '../dtos/apiResponse.dto'; +import IResponse from '@credebl/common/interfaces/response.interface'; @UseFilters(CustomExceptionFilter) @Controller() @@ -168,15 +170,15 @@ export class ConnectionController { summary: 'Catch connection webhook responses', description: 'Callback URL for connection' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: AuthTokenResponse }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) async getConnectionWebhook( @Body() connectionDto: ConnectionDto, @Param('orgId') orgId: string, @Res() res: Response - ): Promise { + ): Promise { this.logger.debug(`connectionDto ::: ${JSON.stringify(connectionDto)} ${orgId}`); const connectionData = await this.connectionService.getConnectionWebhook(connectionDto, orgId); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.connection.success.create, data: connectionData diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 900600e71..ed15700fd 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -2,8 +2,8 @@ import { Controller } from '@nestjs/common'; // Import the common service in the import { ConnectionService } from './connection.service'; // Import the common service in connection module import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package import { - Connection, IConnection, + ICreateConnection, IFetchConnectionById, IFetchConnectionInterface } from './interfaces/connection.interfaces'; @@ -38,7 +38,7 @@ export class ConnectionController { * @returns Callback URL for connection and created connections details */ @MessagePattern({ cmd: 'webhook-get-connection' }) - async getConnectionWebhook(payload: Connection): Promise { + async getConnectionWebhook(payload: ICreateConnection): Promise { return this.connectionService.getConnectionWebhook(payload); } diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index fe7ed215d..cab6dcbf5 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; // eslint-disable-next-line camelcase import { agent_invitations, org_agents, platform_config, shortening_url } from '@prisma/client'; -import { Connection, IConnectionSearchCriteria, OrgAgent } from './interfaces/connection.interfaces'; +import { IConnectionSearchCriteria, ICreateConnection, OrgAgent } from './interfaces/connection.interfaces'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; // import { OrgAgent } from './interfaces/connection.interfaces'; @Injectable() @@ -93,7 +93,7 @@ export class ConnectionRepository { * @returns Get connection details */ // eslint-disable-next-line camelcase - async saveConnectionWebhook(payload: Connection): Promise { + async saveConnectionWebhook(payload: ICreateConnection): Promise { try { let organisationId: string; diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 239f7ef92..3e4b88a92 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -5,9 +5,9 @@ import { HttpException, Inject, Injectable, Logger, NotFoundException } from '@n import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs'; import { - Connection, ConnectionInvitationResponse, IConnectionSearchCriteria, + ICreateConnection, IUserRequestInterface } from './interfaces/connection.interfaces'; import { ConnectionRepository } from './connection.repository'; @@ -113,7 +113,7 @@ export class ConnectionService { * @param user * @returns Connection legacy invitation URL */ - async getConnectionWebhook(payload: Connection): Promise { + async getConnectionWebhook(payload: ICreateConnection): Promise { try { const saveConnectionDetails = await this.connectionRepository.saveConnectionWebhook(payload); return saveConnectionDetails; diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 92183bef8..105382d4f 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -51,12 +51,12 @@ export interface IOrgAgentInterface { orgId: string; } -export class Connection { - connectionDto: ConnectionPayload; +export class ICreateConnection { + connectionDto: ICreateConnectionPayload; orgId: string; } -export class ConnectionPayload { +export class ICreateConnectionPayload { createDateTime: string; lastChangedDateTime: string; id: string; diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 52639580f..524342408 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -5,3 +5,11 @@ export default interface IResponseType { data?: unknown; error?: unknown; }; + +export default interface IResponse { + statusCode: number; + message?: string; + label?: string; + data?: unknown; + error?: unknown; +}; From d227e59001ce57abad588ec486d40388cba2bc4c Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Sun, 24 Dec 2023 20:34:46 +0530 Subject: [PATCH 029/107] refactor:email exist api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 2 +- apps/api-gateway/src/user/user.service.ts | 6 +++--- apps/user/interfaces/user.interface.ts | 2 +- apps/user/src/user.controller.ts | 6 +++--- apps/user/src/user.service.ts | 14 +++++++------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index a4d295757..a4e05dc7a 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -254,7 +254,7 @@ export class UserController { const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.checkEmail, - data: userDetails.response + data: userDetails }; return res.status(HttpStatus.OK).json(finalResponse); diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index a9ff4d91a..221c7d8d4 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -9,7 +9,7 @@ import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; import { AddPasskeyDetails } from './dto/add-user.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; -import { IUsersProfile } from 'apps/user/interfaces/user.interface'; +import { IUsersProfile, ICheckUserDetails } from 'apps/user/interfaces/user.interface'; import { IUsersActivity } from 'libs/user-activity/interface'; @Injectable() @@ -74,9 +74,9 @@ export class UserService extends BaseService { return this.sendNatsMessage(this.serviceProxy, 'fetch-users', payload); } - async checkUserExist(userEmail: string): Promise<{ response: string }> { + async checkUserExist(userEmail: string): Promise { const payload = { userEmail }; - return this.sendNats(this.serviceProxy, 'check-user-exist', payload); + return this.sendNatsMessage(this.serviceProxy, 'check-user-exist', payload); } async getUserActivities(userId: string, limit: number): Promise { diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index 28ef25f61..a3f6fecb7 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -112,7 +112,7 @@ interface IUserOrgRole { label: string; } - export interface CheckUserDetails { + export interface ICheckUserDetails { isEmailVerified?: boolean; isFidoVerified?: boolean; isSupabase?: boolean; diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 4f8770b97..9719e9a0b 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, CheckUserDetails, PlatformSettings, ShareUserCertificate, UserInvitations, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, IUserInformation, IUsersProfile } from '../interfaces/user.interface'; +import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, IUserInformation, IUsersProfile, UserInvitations } from '../interfaces/user.interface'; import {IOrgUsers, Payload} from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; @@ -72,7 +72,7 @@ export class UserController { @MessagePattern({ cmd: 'get-org-invitations' }) async invitations(payload: { id; status; pageNumber; pageSize; search; }): Promise { - return this.userService.invitations(payload); + return this.userService.invitations(payload); } /** @@ -122,7 +122,7 @@ export class UserController { } @MessagePattern({ cmd: 'check-user-exist' }) - async checkUserExist(payload: { userEmail: string }): Promise { + async checkUserExist(payload: { userEmail: string }): Promise { return this.userService.checkUserExist(payload.userEmail); } @MessagePattern({ cmd: 'add-user' }) diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 552f9a4ca..1f2f1b367 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -29,17 +29,17 @@ import { user } from '@prisma/client'; import { AddPasskeyDetails, Attribute, - CheckUserDetails, + ICheckUserDetails, OrgInvitations, PlatformSettings, ShareUserCertificate, - UserInvitations, IOrgUsers, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, IUserInformation, - IUsersProfile + IUsersProfile, + UserInvitations } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { UserActivityService } from '@credebl/user-activity'; @@ -458,7 +458,7 @@ export class UserService { if (!userData) { throw new NotFoundException(ResponseMessages.user.error.notFound); } - + const invitationsData = await this.getOrgInvitations( userData.email, payload.status, @@ -466,11 +466,11 @@ export class UserService { payload.pageSize, payload.search ); - + const invitations: OrgInvitations[] = await this.updateOrgInvitations(invitationsData['invitations']); invitationsData['invitations'] = invitations; // console.log("{-----------------}",invitationsData); - + return invitationsData; } catch (error) { this.logger.error(`Error in get invitations: ${JSON.stringify(error)}`); @@ -728,7 +728,7 @@ export class UserService { } } - async checkUserExist(email: string): Promise { + async checkUserExist(email: string): Promise { try { const userDetails = await this.userRepository.checkUniqueUserExist(email); if (userDetails && !userDetails.isEmailVerified) { From 9e14b377c9b58b588d6e2a26cc4e61b624e56b77 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Mon, 25 Dec 2023 12:24:17 +0530 Subject: [PATCH 030/107] refactor: API agent health Signed-off-by: KulkarniShashank --- .../src/agent-service.controller.ts | 9 +- .../src/agent-service.service.ts | 38 +- .../src/interface/agent-service.interface.ts | 9 +- .../repositories/agent-service.repository.ts | 515 +++++++++--------- .../agent-service/agent-service.controller.ts | 18 +- .../agent-service/agent-service.service.ts | 8 +- .../interface/agent-service.interface.ts | 5 + libs/common/src/common.constant.ts | 3 + 8 files changed, 329 insertions(+), 276 deletions(-) create mode 100644 apps/api-gateway/src/agent-service/interface/agent-service.interface.ts diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 9fc94f190..81e08f488 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -1,7 +1,7 @@ import { Controller } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; import { AgentServiceService } from './agent-service.service'; -import { GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAgentSpinupDto, IIssuanceCreateOffer, ITenantCredDef, ITenantDto, ITenantSchema, OutOfBandCredentialOffer } from './interface/agent-service.interface'; +import { AgentStatus, GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAgentSpinupDto, IIssuanceCreateOffer, ITenantCredDef, ITenantDto, ITenantSchema, OutOfBandCredentialOffer } from './interface/agent-service.interface'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; @@ -94,8 +94,13 @@ export class AgentServiceController { return this.agentServiceService.getConnectionsByconnectionId(payload.url, payload.apiKey); } + /** + * Get agent health + * @param payload + * @returns Get agent health + */ @MessagePattern({ cmd: 'agent-health' }) - async getAgentHealth(payload: { user: user, orgId: string }): Promise { + async getAgentHealth(payload: { user: user, orgId: string }): Promise { return this.agentServiceService.getAgentHealthDetails(payload.orgId); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 6088a7cce..649d8a2af 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -18,7 +18,7 @@ import * as dotenv from 'dotenv'; import * as fs from 'fs'; import { catchError, map } from 'rxjs/operators'; dotenv.config(); -import { GetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, OutOfBandCredentialOffer } from './interface/agent-service.interface'; +import { GetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, OutOfBandCredentialOffer, AgentStatus } from './interface/agent-service.interface'; import { AgentSpinUpStatus, AgentType, Ledgers, OrgAgentType } from '@credebl/enum/enum'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { AgentServiceRepository } from './repositories/agent-service.repository'; @@ -973,25 +973,41 @@ export class AgentServiceService { } } - async getAgentHealthDetails(orgId: string): Promise { + /** + * Get agent health + * @param payload + * @returns Get agent health + */ + async getAgentHealthDetails(orgId: string): Promise { try { + + // Get organization agent details const orgAgentDetails: org_agents = await this.agentServiceRepository.getOrgAgentDetails(orgId); if (!orgAgentDetails) { - throw new NotFoundException(ResponseMessages.agent.error.agentNotExists); + throw new NotFoundException( + ResponseMessages.agent.error.agentNotExists, + { cause: new Error(), description: ResponseMessages.errorMessages.notFound } + ); } - if (orgAgentDetails.agentEndPoint) { - const data = await this.commonService - .httpGet(`${orgAgentDetails.agentEndPoint}/agent`, { headers: { 'x-api-key': '' } }) - .then(async response => response); - return data; - } else { - throw new NotFoundException(ResponseMessages.agent.error.agentUrl); + + if (!orgAgentDetails?.agentEndPoint) { + throw new NotFoundException( + ResponseMessages.agent.error.agentUrl, + { cause: new Error(), description: ResponseMessages.errorMessages.notFound } + ); } + // Invoke an API request from the agent to assess its current status + const agentHealthData = await this.commonService + .httpGet(`${orgAgentDetails.agentEndPoint}${CommonConstants.URL_AGENT_STATUS}`, { headers: { 'x-api-key': '' } }) + .then(async response => response); + + return agentHealthData; + } catch (error) { this.logger.error(`Agent health details : ${JSON.stringify(error)}`); - throw error; + throw new RpcException(error.response ? error.response : error); } } diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 32cb5e82a..04a8a885a 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -261,6 +261,12 @@ export interface ISendProofRequestPayload { autoAcceptProof: string; } +export interface AgentStatus { + label: string; + endpoints: string[]; + isInitialized: boolean; +} + interface IProofFormats { indy: IndyProof } @@ -292,4 +298,5 @@ interface IRequestedPredicatesName { interface IRequestedRestriction { cred_def_id: string; -} \ No newline at end of file +} + diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 8d96907a0..e2ac3cb8b 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -7,310 +7,311 @@ import { AgentType } from '@credebl/enum/enum'; @Injectable() export class AgentServiceRepository { - constructor(private readonly prisma: PrismaService, private readonly logger: Logger) { } + constructor(private readonly prisma: PrismaService, private readonly logger: Logger) { } - /** - * Get platform config details - * @returns - */ - // eslint-disable-next-line camelcase - async getPlatformConfigDetails(): Promise { - try { + /** + * Get platform config details + * @returns + */ + // eslint-disable-next-line camelcase + async getPlatformConfigDetails(): Promise { + try { - return this.prisma.platform_config.findFirst(); + return this.prisma.platform_config.findFirst(); - } catch (error) { - this.logger.error(`[getPlatformConfigDetails] - error: ${JSON.stringify(error)}`); - throw error; - } + } catch (error) { + this.logger.error(`[getPlatformConfigDetails] - error: ${JSON.stringify(error)}`); + throw error; } + } + + /** + * Get genesis url + * @param id + * @returns + */ + async getGenesisUrl(ledgerId: string[]): Promise { + try { - /** - * Get genesis url - * @param id - * @returns - */ - async getGenesisUrl(ledgerId: string[]): Promise { - try { - - const genesisData = await this.prisma.ledgers.findMany({ - where: { - id: { - in: ledgerId - } - } - }); - - return genesisData; - } catch (error) { - this.logger.error(`[getGenesisUrl] - get genesis URL: ${JSON.stringify(error)}`); - throw error; + const genesisData = await this.prisma.ledgers.findMany({ + where: { + id: { + in: ledgerId + } } + }); + + return genesisData; + } catch (error) { + this.logger.error(`[getGenesisUrl] - get genesis URL: ${JSON.stringify(error)}`); + throw error; } + } + + /** + * Get organization details + * @param id + * @returns + */ + async getOrgDetails(id: string): Promise { + try { - /** - * Get organization details - * @param id - * @returns - */ - async getOrgDetails(id: string): Promise { - try { - - const oranizationDetails = await this.prisma.organisation.findFirst({ - where: { - id - } - }); - return oranizationDetails; - } catch (error) { - this.logger.error(`[getOrgDetails] - get organization details: ${JSON.stringify(error)}`); - throw error; + const oranizationDetails = await this.prisma.organisation.findFirst({ + where: { + id } + }); + return oranizationDetails; + } catch (error) { + this.logger.error(`[getOrgDetails] - get organization details: ${JSON.stringify(error)}`); + throw error; } + } - // eslint-disable-next-line camelcase - async createOrgAgent(agentSpinUpStatus: number, userId: string): Promise { - try { - - return this.prisma.org_agents.create({ - data: { - agentSpinUpStatus, - createdBy: userId, - lastChangedBy: userId - } - }); - } catch (error) { - this.logger.error(`[createOrgAgent] - create agent details: ${JSON.stringify(error)}`); - throw error; + // eslint-disable-next-line camelcase + async createOrgAgent(agentSpinUpStatus: number, userId: string): Promise { + try { + + return this.prisma.org_agents.create({ + data: { + agentSpinUpStatus, + createdBy: userId, + lastChangedBy: userId } + }); + } catch (error) { + this.logger.error(`[createOrgAgent] - create agent details: ${JSON.stringify(error)}`); + throw error; } + } + + // eslint-disable-next-line camelcase + async removeOrgAgent(id: string): Promise { + try { - // eslint-disable-next-line camelcase - async removeOrgAgent(id: string): Promise { - try { - - return this.prisma.org_agents.delete({ - where: { - id - } - }); - } catch (error) { - this.logger.error(`[removeOrgAgent] - remove org agent details: ${JSON.stringify(error)}`); - throw error; + return this.prisma.org_agents.delete({ + where: { + id } + }); + } catch (error) { + this.logger.error(`[removeOrgAgent] - remove org agent details: ${JSON.stringify(error)}`); + throw error; } + } + + /** + * Store agent details + * @param storeAgentDetails + * @returns + */ + // eslint-disable-next-line camelcase + async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { + try { - /** - * Store agent details - * @param storeAgentDetails - * @returns - */ - // eslint-disable-next-line camelcase - async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { - try { - - return this.prisma.org_agents.update({ - where: { - id: storeOrgAgentDetails.id - }, - data: { - orgDid: storeOrgAgentDetails.did, - verkey: storeOrgAgentDetails.verkey, - isDidPublic: storeOrgAgentDetails.isDidPublic, - agentSpinUpStatus: storeOrgAgentDetails.agentSpinUpStatus, - walletName: storeOrgAgentDetails.walletName, - agentsTypeId: storeOrgAgentDetails.agentsTypeId, - orgId: storeOrgAgentDetails.orgId, - agentEndPoint: storeOrgAgentDetails.agentEndPoint, - agentId: storeOrgAgentDetails.agentId ? storeOrgAgentDetails.agentId : null, - orgAgentTypeId: storeOrgAgentDetails.orgAgentTypeId ? storeOrgAgentDetails.orgAgentTypeId : null, - tenantId: storeOrgAgentDetails.tenantId ? storeOrgAgentDetails.tenantId : null, - ledgerId: storeOrgAgentDetails.ledgerId[0] - } - }); - } catch (error) { - this.logger.error(`[storeAgentDetails] - store agent details: ${JSON.stringify(error)}`); - throw error; + return this.prisma.org_agents.update({ + where: { + id: storeOrgAgentDetails.id + }, + data: { + orgDid: storeOrgAgentDetails.did, + verkey: storeOrgAgentDetails.verkey, + isDidPublic: storeOrgAgentDetails.isDidPublic, + agentSpinUpStatus: storeOrgAgentDetails.agentSpinUpStatus, + walletName: storeOrgAgentDetails.walletName, + agentsTypeId: storeOrgAgentDetails.agentsTypeId, + orgId: storeOrgAgentDetails.orgId, + agentEndPoint: storeOrgAgentDetails.agentEndPoint, + agentId: storeOrgAgentDetails.agentId ? storeOrgAgentDetails.agentId : null, + orgAgentTypeId: storeOrgAgentDetails.orgAgentTypeId ? storeOrgAgentDetails.orgAgentTypeId : null, + tenantId: storeOrgAgentDetails.tenantId ? storeOrgAgentDetails.tenantId : null, + ledgerId: storeOrgAgentDetails.ledgerId[0] } + }); + } catch (error) { + this.logger.error(`[storeAgentDetails] - store agent details: ${JSON.stringify(error)}`); + throw error; } + } - /** - * Get agent details - * @param orgId - * @returns - */ - // eslint-disable-next-line camelcase - async getAgentDetails(orgId: string): Promise { - try { + /** + * Get agent details + * @param orgId + * @returns + */ + // eslint-disable-next-line camelcase + async getAgentDetails(orgId: string): Promise { + try { - const x = await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); + const x = await this.prisma.org_agents.findFirst({ + where: { + orgId + } + }); - return x; + return x; - } catch (error) { + } catch (error) { - this.logger.error(`[getAgentDetails] - get agent details: ${JSON.stringify(error)}`); - throw error; - } + this.logger.error(`[getAgentDetails] - get agent details: ${JSON.stringify(error)}`); + throw error; } + } - // eslint-disable-next-line camelcase - async platformAdminAgent(platformOrg: string): Promise { - const platformAdminSpinnedUp = await this.prisma.organisation.findFirst({ - where: { - name: platformOrg - }, - include: { - // eslint-disable-next-line camelcase - org_agents: true - } - }); - return platformAdminSpinnedUp; - } + // eslint-disable-next-line camelcase + async platformAdminAgent(platformOrg: string): Promise { + const platformAdminSpinnedUp = await this.prisma.organisation.findFirst({ + where: { + name: platformOrg + }, + include: { + // eslint-disable-next-line camelcase + org_agents: true + } + }); + return platformAdminSpinnedUp; + } + + /** + * Get agent details + * @param orgId + * @returns Agent health details + */ + // eslint-disable-next-line camelcase + async getOrgAgentDetails(orgId: string): Promise { + try { - /** - * Get agent details - * @param orgId - * @returns Agent health details - */ - // eslint-disable-next-line camelcase - async getOrgAgentDetails(orgId: string): Promise { - try { - const oranizationAgentDetails = await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); - return oranizationAgentDetails; - } catch (error) { - this.logger.error(`[getOrgAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); - throw error; + const oranizationAgentDetails = await this.prisma.org_agents.findFirstOrThrow({ + where: { + orgId } + }); + return oranizationAgentDetails; + } catch (error) { + this.logger.error(`[getOrgAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); + throw error; } + } - async getAgentTypeDetails(): Promise { - try { - const { id } = await this.prisma.agents_type.findFirst({ - where: { - agent: AgentType.AFJ - } - }); - return id; - } catch (error) { - this.logger.error(`[getAgentTypeDetails] - get org agent health details: ${JSON.stringify(error)}`); - throw error; + async getAgentTypeDetails(): Promise { + try { + const { id } = await this.prisma.agents_type.findFirst({ + where: { + agent: AgentType.AFJ } + }); + return id; + } catch (error) { + this.logger.error(`[getAgentTypeDetails] - get org agent health details: ${JSON.stringify(error)}`); + throw error; } + } - async getLedgerDetails(name: string[] | string): Promise<{ - id: string; - createDateTime: Date; - lastChangedDateTime: Date; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - registerDIDEndpoint: string; - registerDIDPayload: Prisma.JsonValue; - indyNamespace: string; - }[]> { - try { - let whereClause; - - if (Array.isArray(name)) { - whereClause = { - name: { - in: name - } - }; - } else { - whereClause = { - name - }; - } - - const ledgersDetails = await this.prisma.ledgers.findMany({ - where: whereClause - }); - return ledgersDetails; - } catch (error) { - this.logger.error(`[getLedgerDetails] - get ledger details: ${JSON.stringify(error)}`); - throw error; - } + async getLedgerDetails(name: string[] | string): Promise<{ + id: string; + createDateTime: Date; + lastChangedDateTime: Date; + name: string; + networkType: string; + poolConfig: string; + isActive: boolean; + networkString: string; + registerDIDEndpoint: string; + registerDIDPayload: Prisma.JsonValue; + indyNamespace: string; + }[]> { + try { + let whereClause; + + if (Array.isArray(name)) { + whereClause = { + name: { + in: name + } + }; + } else { + whereClause = { + name + }; + } + + const ledgersDetails = await this.prisma.ledgers.findMany({ + where: whereClause + }); + return ledgersDetails; + } catch (error) { + this.logger.error(`[getLedgerDetails] - get ledger details: ${JSON.stringify(error)}`); + throw error; } + } - async getOrgAgentTypeDetails(agentType: string): Promise { - try { - const { id } = await this.prisma.org_agents_type.findFirst({ - where: { - agent: agentType - } - }); - return id; - } catch (error) { - this.logger.error(`[getOrgAgentTypeDetails] - get org agent type details: ${JSON.stringify(error)}`); - throw error; + async getOrgAgentTypeDetails(agentType: string): Promise { + try { + const { id } = await this.prisma.org_agents_type.findFirst({ + where: { + agent: agentType } + }); + return id; + } catch (error) { + this.logger.error(`[getOrgAgentTypeDetails] - get org agent type details: ${JSON.stringify(error)}`); + throw error; } + } - async getPlatfomOrg(orgName: string): Promise { - try { - const { id } = await this.prisma.organisation.findFirst({ - where: { - name: orgName - } - }); - return id; - } catch (error) { - this.logger.error(`[getPlatfomOrg] - get platform org details: ${JSON.stringify(error)}`); - throw error; + async getPlatfomOrg(orgName: string): Promise { + try { + const { id } = await this.prisma.organisation.findFirst({ + where: { + name: orgName } + }); + return id; + } catch (error) { + this.logger.error(`[getPlatfomOrg] - get platform org details: ${JSON.stringify(error)}`); + throw error; } + } - async getPlatfomAdminUser(platformAdminUserEmail: string): Promise { - try { - const platformAdminUser = await this.prisma.user.findUnique({ - where: { - email: platformAdminUserEmail - } - }); - return platformAdminUser; - } catch (error) { - this.logger.error(`[getPlatfomAdminUser] - get platform admin user: ${JSON.stringify(error)}`); - throw error; + async getPlatfomAdminUser(platformAdminUserEmail: string): Promise { + try { + const platformAdminUser = await this.prisma.user.findUnique({ + where: { + email: platformAdminUserEmail } + }); + return platformAdminUser; + } catch (error) { + this.logger.error(`[getPlatfomAdminUser] - get platform admin user: ${JSON.stringify(error)}`); + throw error; } + } - async getAgentType(id: string): Promise { - try { - const { agent } = await this.prisma.agents_type.findUnique({ - where: { - id - } - }); - return agent; - } catch (error) { - this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); - throw error; + async getAgentType(id: string): Promise { + try { + const { agent } = await this.prisma.agents_type.findUnique({ + where: { + id } + }); + return agent; + } catch (error) { + this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); + throw error; } + } - async getAgentTypeId(agentType: string): Promise { - try { - const { id } = await this.prisma.agents_type.findFirst({ - where: { - agent: agentType - } - }); - return id; - } catch (error) { - this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); - throw error; + async getAgentTypeId(agentType: string): Promise { + try { + const { id } = await this.prisma.agents_type.findFirst({ + where: { + agent: agentType } + }); + return id; + } catch (error) { + this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); + throw error; } + } } \ No newline at end of file diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index dcb33d9fb..76d8e36c0 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -44,19 +44,31 @@ export class AgentController { constructor(private readonly agentService: AgentService) { } private readonly logger = new Logger(); + /** + * Get Organization agent health + * @param orgId + * @param reqUser + * @param res + * @returns Get agent details + */ @Get('/orgs/:orgId/agents/health') @ApiOperation({ summary: 'Get the agent health details', description: 'Get the agent health details' }) @UseGuards(AuthGuard('jwt')) - async getAgentHealth(@User() reqUser: user, @Param('orgId') orgId: string, @Res() res: Response): Promise { + async getAgentHealth( + @Param('orgId') orgId: string, + @User() reqUser: user, + @Res() res: Response + ): Promise { + const agentData = await this.agentService.getAgentHealth(reqUser, orgId); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.agent.success.health, - data: agentData.response + data: agentData }; return res.status(HttpStatus.OK).json(finalResponse); @@ -99,7 +111,7 @@ export class AgentController { agentSpinupDto.orgId = orgId; const agentDetails = await this.agentService.agentSpinup(agentSpinupDto, user); - + const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, diff --git a/apps/api-gateway/src/agent-service/agent-service.service.ts b/apps/api-gateway/src/agent-service/agent-service.service.ts index 2ede160b7..4b49acdea 100644 --- a/apps/api-gateway/src/agent-service/agent-service.service.ts +++ b/apps/api-gateway/src/agent-service/agent-service.service.ts @@ -4,6 +4,7 @@ import { user } from '@prisma/client'; import { BaseService } from 'libs/service/base.service'; import { AgentSpinupDto } from './dto/agent-service.dto'; import { CreateTenantDto } from './dto/create-tenant.dto'; +import { AgentStatus } from './interface/agent-service.interface'; @Injectable() export class AgentService extends BaseService { @@ -23,9 +24,12 @@ export class AgentService extends BaseService { return this.sendNats(this.agentServiceProxy, 'create-tenant', payload); } - async getAgentHealth(user: user, orgId:string): Promise<{ response: object }> { + async getAgentHealth(user: user, orgId:string): Promise { const payload = { user, orgId }; - return this.sendNats(this.agentServiceProxy, 'agent-health', payload); + + // NATS call + return this.sendNatsMessage(this.agentServiceProxy, 'agent-health', payload); + } } diff --git a/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts b/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts new file mode 100644 index 000000000..0a5a5e146 --- /dev/null +++ b/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts @@ -0,0 +1,5 @@ +export interface AgentStatus { + label: string; + endpoints: string[]; + isInitialized: boolean; +} \ No newline at end of file diff --git a/libs/common/src/common.constant.ts b/libs/common/src/common.constant.ts index d94cf5380..15cdd6da3 100644 --- a/libs/common/src/common.constant.ts +++ b/libs/common/src/common.constant.ts @@ -219,6 +219,9 @@ export enum CommonConstants { // delete wallet URL_DELETE_WALLET = '/agent/wallet', URL_DELETE_SHARED_WALLET = '/multi-tenancy/#', + + // agent status + URL_AGENT_STATUS = '/agent', // Tenant Status PENDING_STATE = 0, From 0c8f00aa1fc4d04d5ab143fe10c906b32a23f83a Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Mon, 25 Dec 2023 14:37:13 +0530 Subject: [PATCH 031/107] refactor: API create tenant Signed-off-by: KulkarniShashank --- .../src/agent-service.controller.ts | 6 +- .../src/agent-service.service.ts | 69 ++++++++++++++++--- .../src/interface/agent-service.interface.ts | 33 ++++++++- .../repositories/agent-service.repository.ts | 12 ++-- .../agent-service/agent-service.controller.ts | 20 ++++-- .../agent-service/agent-service.service.ts | 5 +- .../agent-service/dto/create-tenant.dto.ts | 15 ++-- .../interface/agent-service.interface.ts | 3 + libs/common/src/response-messages/index.ts | 7 +- 9 files changed, 136 insertions(+), 34 deletions(-) create mode 100644 apps/api-gateway/src/agent-service/interface/agent-service.interface.ts diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 9fc94f190..63e1b3d99 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -1,7 +1,7 @@ import { Controller } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; import { AgentServiceService } from './agent-service.service'; -import { GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAgentSpinupDto, IIssuanceCreateOffer, ITenantCredDef, ITenantDto, ITenantSchema, OutOfBandCredentialOffer } from './interface/agent-service.interface'; +import { AgentSpinUpSatus, GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAgentSpinupDto, IIssuanceCreateOffer, ITenantCredDef, ITenantDto, ITenantSchema, OutOfBandCredentialOffer } from './interface/agent-service.interface'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; @@ -16,9 +16,7 @@ export class AgentServiceController { } @MessagePattern({ cmd: 'create-tenant' }) - async createTenant(payload: { createTenantDto: ITenantDto, user: IUserRequestInterface }): Promise<{ - agentSpinupStatus: number; - }> { + async createTenant(payload: { createTenantDto: ITenantDto, user: IUserRequestInterface }): Promise { return this.agentServiceService.createTenant(payload.createTenantDto, payload.user); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 6088a7cce..e09645bcd 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -18,7 +18,7 @@ import * as dotenv from 'dotenv'; import * as fs from 'fs'; import { catchError, map } from 'rxjs/operators'; dotenv.config(); -import { GetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, OutOfBandCredentialOffer } from './interface/agent-service.interface'; +import { GetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, OutOfBandCredentialOffer, AgentSpinUpSatus, CreateTenant } from './interface/agent-service.interface'; import { AgentSpinUpStatus, AgentType, Ledgers, OrgAgentType } from '@credebl/enum/enum'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { AgentServiceRepository } from './repositories/agent-service.repository'; @@ -550,53 +550,86 @@ export class AgentServiceService { } } - async createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise<{ - agentSpinupStatus: number; - }> { + /** + * Create tenant (Shared agent) + * @param payload + * @param user + * @returns Get agent status + */ + async createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { const agentStatusResponse = { agentSpinupStatus: AgentSpinUpStatus.PROCESSED }; + // Create tenant this._createTenant(payload, user); return agentStatusResponse; } + /** + * Create tenant (Shared agent) + * @param payload + * @param user + * @returns Get agent status + */ async _createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { let agentProcess; try { + + // Get orgaization agent details by orgId const getOrgAgent = await this.agentServiceRepository.getAgentDetails(payload.orgId); if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { this.logger.error(`Your wallet has already been created.`); - throw new BadRequestException('Your wallet has already been created.'); + throw new BadRequestException( + ResponseMessages.agent.error.walletAlreadyCreated, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { this.logger.error(`Your wallet has already processing.`); - throw new BadRequestException('Your wallet has already processing.'); + throw new BadRequestException( + ResponseMessages.agent.error.walletAlreadyProcessing, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } + // Get ledgers details const ledgerIdData = await this.agentServiceRepository.getLedgerDetails(Ledgers.Indicio_Demonet); const ledgerIds = ledgerIdData.map(ledger => ledger.id); payload.ledgerId = !payload.ledgerId || 0 === payload.ledgerId?.length ? ledgerIds : payload.ledgerId; const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; - agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user.id); + // Create and stored agent details + agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user.id); + // Get platform admin details const platformAdminSpinnedUp = await this.getPlatformAdminAndNotify(payload.clientSocketId); + + // Get genesis URLs by ledger Id const ledgerDetails: ledgers[] = await this.agentServiceRepository.getGenesisUrl(payload.ledgerId); for (const iterator of ledgerDetails) { + + // Create tenant in agent controller const tenantDetails = await this.createTenantAndNotify(payload, iterator, platformAdminSpinnedUp); if (AgentSpinUpStatus.COMPLETED !== platformAdminSpinnedUp.org_agents[0].agentSpinUpStatus) { - throw new NotFoundException('Platform-admin agent is not spun-up'); + this.logger.error(`Platform-admin agent is not spun-up`); + throw new NotFoundException( + ResponseMessages.agent.error.platformAdminNotAbleToSpinp, + { cause: new Error(), description: ResponseMessages.errorMessages.notFound } + ); } + // Get org agent type details by shared agent const orgAgentTypeId = await this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.SHARED); + + // Get agent type details by AFJ agent const agentTypeId = await this.agentServiceRepository.getAgentTypeId(AgentType.AFJ); const storeOrgAgentData: IStoreOrgAgentDetails = { @@ -614,12 +647,15 @@ export class AgentServiceService { id: agentProcess.id }; + // Get organization data const getOrganization = await this.agentServiceRepository.getOrgDetails(payload.orgId); this.notifyClientSocket('agent-spinup-process-completed', payload.clientSocketId); const saveTenant = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData); this.notifyClientSocket('invitation-url-creation-started', payload.clientSocketId); + + // Create the legacy connection invitation this._createLegacyConnectionInvitation(payload.orgId, user, getOrganization.name); this.notifyClientSocket('invitation-url-creation-success', payload.clientSocketId); @@ -646,13 +682,24 @@ export class AgentServiceService { const platformAdminSpinnedUp = await this.agentServiceRepository.platformAdminAgent(CommonConstants.PLATFORM_ADMIN_ORG); if (!platformAdminSpinnedUp) { - throw new InternalServerErrorException('Agent not able to spin-up'); + this.logger.error(`Agent not able to spin-up`); + throw new BadRequestException( + ResponseMessages.agent.error.notAbleToSpinp, + { cause: new Error(), description: ResponseMessages.errorMessages.serverError } + ); } return platformAdminSpinnedUp; } - private async createTenantAndNotify(payload: ITenantDto, ledgerIds: ledgers, platformAdminSpinnedUp: organisation & { org_agents: org_agents[] }): Promise { + /** + * Create tenant on the agent + * @param payload + * @param ledgerIds + * @param platformAdminSpinnedUp + * @returns Get tanant status + */ + private async createTenantAndNotify(payload: ITenantDto, ledgerIds: ledgers, platformAdminSpinnedUp: organisation & { org_agents: org_agents[] }): Promise { const socket = await this.createSocketInstance(); if (payload.clientSocketId) { socket.emit('agent-spinup-process-initiated', { clientId: payload.clientSocketId }); @@ -667,6 +714,8 @@ export class AgentServiceService { }; const apiKey = ''; + + // Invoke an API request from the agent to create multi-tenant agent const tenantDetails = await this.commonService.httpPost( `${platformAdminSpinnedUp.org_agents[0].agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_TENANT}`, createTenantOptions, diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 32cb5e82a..42f40d90d 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -292,4 +292,35 @@ interface IRequestedPredicatesName { interface IRequestedRestriction { cred_def_id: string; -} \ No newline at end of file +} + +export interface AgentSpinUpSatus { + agentSpinupStatus: number; +} + +interface WalletConfig { + id: string; + key: string; + keyDerivationMethod: string; + } + + interface Config { + label: string; + walletConfig: WalletConfig; + } + + interface TenantRecord { + _tags: string; + metadata: string; + id: string; + createdAt: string; + config: Config; + updatedAt: string; + } + + export interface CreateTenant { + tenantRecord: TenantRecord; + did: string; + verkey: string; + } + \ No newline at end of file diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 8d96907a0..da0213080 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -56,7 +56,7 @@ export class AgentServiceRepository { async getOrgDetails(id: string): Promise { try { - const oranizationDetails = await this.prisma.organisation.findFirst({ + const oranizationDetails = await this.prisma.organisation.findFirstOrThrow({ where: { id } @@ -143,13 +143,13 @@ export class AgentServiceRepository { async getAgentDetails(orgId: string): Promise { try { - const x = await this.prisma.org_agents.findFirst({ + const orgAgentDataByOrgId = await this.prisma.org_agents.findFirstOrThrow({ where: { orgId } }); - return x; + return orgAgentDataByOrgId; } catch (error) { @@ -160,7 +160,7 @@ export class AgentServiceRepository { // eslint-disable-next-line camelcase async platformAdminAgent(platformOrg: string): Promise { - const platformAdminSpinnedUp = await this.prisma.organisation.findFirst({ + const platformAdminSpinnedUp = await this.prisma.organisation.findFirstOrThrow({ where: { name: platformOrg }, @@ -246,7 +246,7 @@ export class AgentServiceRepository { async getOrgAgentTypeDetails(agentType: string): Promise { try { - const { id } = await this.prisma.org_agents_type.findFirst({ + const { id } = await this.prisma.org_agents_type.findFirstOrThrow({ where: { agent: agentType } @@ -302,7 +302,7 @@ export class AgentServiceRepository { async getAgentTypeId(agentType: string): Promise { try { - const { id } = await this.prisma.agents_type.findFirst({ + const { id } = await this.prisma.agents_type.findFirstOrThrow({ where: { agent: agentType } diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index dcb33d9fb..fcaa3eb01 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -99,7 +99,7 @@ export class AgentController { agentSpinupDto.orgId = orgId; const agentDetails = await this.agentService.agentSpinup(agentSpinupDto, user); - + const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, @@ -109,6 +109,14 @@ export class AgentController { return res.status(HttpStatus.CREATED).json(finalResponse); } + /** + * Create wallet for shared agent + * @param orgId + * @param createTenantDto + * @param user + * @param res + * @returns wallet initialization status + */ @Post('/orgs/:orgId/agents/wallet') @ApiOperation({ summary: 'Shared Agent', @@ -122,12 +130,16 @@ export class AgentController { @Body() createTenantDto: CreateTenantDto, @User() user: user, @Res() res: Response - ): Promise { + ): Promise { createTenantDto.orgId = orgId; if (seedLength !== createTenantDto.seed.length) { - throw new BadRequestException(`seed must be at most 32 characters.`); + this.logger.error(`seed must be at most 32 characters`); + throw new BadRequestException( + ResponseMessages.agent.error.seedCharCount, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } const tenantDetails = await this.agentService.createTenant(createTenantDto, user); @@ -135,7 +147,7 @@ export class AgentController { const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, - data: tenantDetails.response + data: tenantDetails }; return res.status(HttpStatus.CREATED).json(finalResponse); diff --git a/apps/api-gateway/src/agent-service/agent-service.service.ts b/apps/api-gateway/src/agent-service/agent-service.service.ts index 2ede160b7..1f2896eca 100644 --- a/apps/api-gateway/src/agent-service/agent-service.service.ts +++ b/apps/api-gateway/src/agent-service/agent-service.service.ts @@ -4,6 +4,7 @@ import { user } from '@prisma/client'; import { BaseService } from 'libs/service/base.service'; import { AgentSpinupDto } from './dto/agent-service.dto'; import { CreateTenantDto } from './dto/create-tenant.dto'; +import { AgentSpinUpSatus } from './interface/agent-service.interface'; @Injectable() export class AgentService extends BaseService { @@ -18,9 +19,9 @@ export class AgentService extends BaseService { return this.sendNats(this.agentServiceProxy, 'agent-spinup', payload); } - async createTenant(createTenantDto: CreateTenantDto, user: user): Promise<{ response: object }> { + async createTenant(createTenantDto: CreateTenantDto, user: user): Promise { const payload = { createTenantDto, user }; - return this.sendNats(this.agentServiceProxy, 'create-tenant', payload); + return this.sendNatsMessage(this.agentServiceProxy, 'create-tenant', payload); } async getAgentHealth(user: user, orgId:string): Promise<{ response: object }> { diff --git a/apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts b/apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts index 34938eef9..9204d6370 100644 --- a/apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts @@ -7,7 +7,7 @@ export class CreateTenantDto { @ApiProperty() @MaxLength(25, { message: 'Maximum length for label must be 25 characters.' }) @IsString({ message: 'label must be in string format.' }) - @Transform(({ value }) => value.trim()) + @Transform(({ value }) => trim(value)) @MinLength(2, { message: 'Minimum length for label must be 2 characters.' }) @Matches(labelRegex, { message: 'Label must not contain special characters.' }) @Matches(/^\S*$/, { @@ -15,7 +15,7 @@ export class CreateTenantDto { }) label: string; - @ApiProperty() + @ApiProperty({ example: 'dfuhgfklskmjngrjekjfgjjfkoekfdad' }) @MaxLength(32, { message: 'seed must be at most 32 characters.' }) @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'seed is required' }) @@ -26,20 +26,23 @@ export class CreateTenantDto { seed: string; @ApiProperty({ example: [1] }) + @ApiPropertyOptional() @IsOptional() @IsArray({ message: 'ledgerId must be an array' }) @IsNotEmpty({ message: 'please provide valid ledgerId' }) ledgerId?: string[]; - orgId: string; - - @ApiProperty() + @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) @IsOptional() + @ApiPropertyOptional() @IsString({ message: 'did must be in string format.' }) did?: string; - @ApiProperty() + @ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' }) @IsOptional() @ApiPropertyOptional() + @IsString({ message: 'did must be in string format.' }) clientSocketId?: string; + + orgId: string; } \ No newline at end of file diff --git a/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts b/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts new file mode 100644 index 000000000..1d4d60e3f --- /dev/null +++ b/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts @@ -0,0 +1,3 @@ +export interface AgentSpinUpSatus { + agentSpinupStatus: number; +} \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index db8744af6..bb8266cb4 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -157,7 +157,12 @@ export const ResponseMessages = { alreadySpinUp: 'Agent already spin-up', agentUrl: 'Agent url not exist', agentNotExists: 'Agent not spinned up for this organization', - agentDown: 'Agent is down or not spinned up' + agentDown: 'Agent is down or not spinned up', + walletAlreadyCreated: 'Your wallet has already been created', + walletAlreadyProcessing: 'Your wallet has already processing', + notAbleToSpinp: 'Agent not able to spin-up', + platformAdminNotAbleToSpinp: 'Platform-admin agent is not spun-up', + seedCharCount: 'seed must be at most 32 characters', } }, connection: { From 2139cb6bbc09117f4ab42beddc6d069218a8dd57 Mon Sep 17 00:00:00 2001 From: sanjay-k1910 Date: Tue, 26 Dec 2023 11:44:15 +0530 Subject: [PATCH 032/107] feat: delete organization invitation api Signed-off-by: sanjay-k1910 --- .../organization/organization.controller.ts | 19 ++++++++++++ .../src/organization/organization.service.ts | 8 +++++ .../repositories/organization.repository.ts | 19 ++++++++++++ .../src/organization.controller.ts | 5 ++++ apps/organization/src/organization.service.ts | 30 ++++++++++++++++++- libs/common/src/response-messages/index.ts | 7 +++-- 6 files changed, 85 insertions(+), 3 deletions(-) diff --git a/apps/api-gateway/src/organization/organization.controller.ts b/apps/api-gateway/src/organization/organization.controller.ts index 865ec93ef..297a0f739 100644 --- a/apps/api-gateway/src/organization/organization.controller.ts +++ b/apps/api-gateway/src/organization/organization.controller.ts @@ -372,4 +372,23 @@ export class OrganizationController { }; return res.status(HttpStatus.ACCEPTED).json(finalResponse); } + + @Delete('/:orgId/invitations/:invitationId') + @ApiOperation({ summary: 'Delete organization invitation', description: 'Delete organization invitation' }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + @ApiBearerAuth() + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + async deleteOrganizationInvitation( + @Param('orgId') orgId: string, + @Param('invitationId') invitationId: string, + @Res() res: Response + ): Promise { + await this.organizationService.deleteOrganizationInvitation(orgId, invitationId); + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.organisation.success.orgInvitationDeleted + }; + return res.status(HttpStatus.OK).json(finalResponse); + } } \ No newline at end of file diff --git a/apps/api-gateway/src/organization/organization.service.ts b/apps/api-gateway/src/organization/organization.service.ts index c1d44ac64..7e7cde553 100644 --- a/apps/api-gateway/src/organization/organization.service.ts +++ b/apps/api-gateway/src/organization/organization.service.ts @@ -150,4 +150,12 @@ export class OrganizationService extends BaseService { return this.sendNats(this.serviceProxy, 'delete-organization', payload); } + + async deleteOrganizationInvitation( + orgId: string, + invitationId: string + ): Promise { + const payload = {orgId, invitationId}; + return this.sendNats(this.serviceProxy, 'delete-organization-invitation', payload); + } } diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index 5e56ceb56..9254ede5d 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -575,4 +575,23 @@ export class OrganizationRepository { } } + + /** + * + * @param id + * @returns Delete Invitation + */ + async deleteOrganizationInvitation(id: string): Promise { + try { + return await this.prisma.org_invitations.delete({ + where: { + id + } + }); + } catch (error) { + this.logger.error(`error: ${JSON.stringify(error)}`); + throw new InternalServerErrorException(error); + } + } + } diff --git a/apps/organization/src/organization.controller.ts b/apps/organization/src/organization.controller.ts index f77ef73ee..6ee9b9d90 100644 --- a/apps/organization/src/organization.controller.ts +++ b/apps/organization/src/organization.controller.ts @@ -163,4 +163,9 @@ export class OrganizationController { async deleteOrganization(payload: { orgId: string }): Promise { return this.organizationService.deleteOrganization(payload.orgId); } + + @MessagePattern({ cmd: 'delete-organization-invitation' }) + async deleteOrganizationInvitation(payload: { orgId: string; invitationId: string; }): Promise { + return this.organizationService.deleteOrganizationInvitation(payload.orgId, payload.invitationId); + } } diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index d5755864e..a3c8b330c 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -1,6 +1,6 @@ // eslint-disable-next-line camelcase import { organisation, org_roles, user } from '@prisma/client'; -import { Injectable, Logger, ConflictException, InternalServerErrorException, HttpException } from '@nestjs/common'; +import { Injectable, Logger, ConflictException, InternalServerErrorException, HttpException, BadRequestException, ForbiddenException } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; import { CommonService } from '@credebl/common'; import { OrganizationRepository } from '../repositories/organization.repository'; @@ -563,4 +563,32 @@ export class OrganizationService { throw error; } } + + async deleteOrganizationInvitation(orgId: string, invitationId: string): Promise { + try { + const invitationDetails = await this.organizationRepository.getInvitationById(invitationId); + + // Check invitation is present + if (!invitationDetails) { + throw new NotFoundException(ResponseMessages.user.error.invitationNotFound); + } + + // Check if delete process initiated by the org who has created invitation + if (orgId !== invitationDetails.orgId) { + throw new ForbiddenException(ResponseMessages.organisation.error.deleteOrgInvitation); + } + + // Check if invitation is already accepted/rejected + if (Invitation.PENDING !== invitationDetails.status) { + throw new BadRequestException(ResponseMessages.organisation.error.invitationStatusInvalid); + } + + await this.organizationRepository.deleteOrganizationInvitation(invitationId); + + return true; + } catch (error) { + this.logger.error(`delete organization invitation: ${JSON.stringify(error)}`); + throw new RpcException(error.response ? error.response : error); + } + } } \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index c45eb1181..8b3dc00c5 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -58,7 +58,8 @@ export const ResponseMessages = { getOrgDashboard: 'Organization dashboard details fetched', getOrganizations: 'Organizations details fetched successfully', updateUserRoles: 'User roles updated successfully', - delete: 'Organization deleted successfully' + delete: 'Organization deleted successfully', + orgInvitationDeleted: 'Organization invitation deleted successfully' }, error: { exists: 'An organization name is already exist', @@ -68,7 +69,9 @@ export const ResponseMessages = { userNotFound: 'User not found for the given organization', updateUserRoles: 'Unable to update user roles', deleteOrg: 'Organization not found', - notFound: 'Organization agent not found' + deleteOrgInvitation: 'Organization does not have access to delete this invitation', + notFound: 'Organization agent not found', + invitationStatusInvalid: 'Unable to delete invitation with accepted/rejected status' } }, From 9bc2d7ccc6d357fb2b70414f77d6073a073713ee Mon Sep 17 00:00:00 2001 From: sanjay-k1910 Date: Tue, 26 Dec 2023 12:04:30 +0530 Subject: [PATCH 033/107] refactor: delete org invitation api Signed-off-by: sanjay-k1910 --- apps/api-gateway/src/organization/organization.service.ts | 2 +- apps/organization/repositories/organization.repository.ts | 4 ++-- libs/common/src/response-messages/index.ts | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/api-gateway/src/organization/organization.service.ts b/apps/api-gateway/src/organization/organization.service.ts index cf69dfd22..24b17e18a 100644 --- a/apps/api-gateway/src/organization/organization.service.ts +++ b/apps/api-gateway/src/organization/organization.service.ts @@ -164,6 +164,6 @@ export class OrganizationService extends BaseService { invitationId: string ): Promise { const payload = {orgId, invitationId}; - return this.sendNats(this.serviceProxy, 'delete-organization-invitation', payload); + return this.sendNatsMessage(this.serviceProxy, 'delete-organization-invitation', payload); } } diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index f71da0c3f..9bc7183d9 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -599,8 +599,8 @@ export class OrganizationRepository { } }); } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`Delete Org Invitation Error: ${JSON.stringify(error)}`); + throw error; } } diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 199e3e0fc..df38286ce 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -74,7 +74,6 @@ export const ResponseMessages = { invitationStatusInvalid: 'Unable to delete invitation with accepted/rejected status', orgNotFound: 'Organization not found' } - }, fido: { From 63d0ca49c153ec17ef56f90c4adcedafc05c005d Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Tue, 26 Dec 2023 12:59:39 +0530 Subject: [PATCH 034/107] improve error handling Signed-off-by: bhavanakarwade --- apps/api-gateway/src/connection/connection.controller.ts | 5 +++-- apps/api-gateway/src/connection/connection.service.ts | 2 +- apps/connection/src/connection.controller.ts | 2 +- apps/connection/src/connection.service.ts | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index c29e34715..309970f17 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -19,6 +19,7 @@ import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { GetAllConnectionsDto } from './dtos/get-all-connections.dto'; import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; import IResponse from '@credebl/common/interfaces/response.interface'; +import { ApiResponseDto } from '../dtos/apiResponse.dto'; @UseFilters(CustomExceptionFilter) @Controller() @@ -46,13 +47,13 @@ export class ConnectionController { summary: `Get connections by connection Id`, description: `Get connections by connection Id` }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: AuthTokenResponse }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getConnectionsById( @User() user: IUserRequest, @Param('connectionId') connectionId: string, @Param('orgId') orgId: string, @Res() res: Response - ): Promise { + ): Promise { const connectionsDetails = await this.connectionService.getConnectionsById(user, connectionId, orgId); const finalResponse: IResponse = { statusCode: HttpStatus.OK, diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 9425f26bb..4c7ea6a35 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -73,6 +73,6 @@ export class ConnectionService extends BaseService { orgId: string ): Promise { const payload = { user, connectionId, orgId }; - return this.sendNatsMessage(this.connectionServiceProxy, 'get-all-connections-by-connectionId', payload); + return this.sendNatsMessage(this.connectionServiceProxy, 'get-all-connection-details-by-connectionId', payload); } } diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index d13dc136e..7fbe1f5ff 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -59,7 +59,7 @@ export class ConnectionController { return this.connectionService.getConnections(user, orgId, connectionSearchCriteria); } - @MessagePattern({ cmd: 'get-all-connections-by-connectionId' }) + @MessagePattern({ cmd: 'get-all-connection-details-by-connectionId' }) async getConnectionsById(payload: IFetchConnectionById): Promise { const { user, connectionId, orgId } = payload; return this.connectionService.getConnectionsById(user, connectionId, orgId); diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 4f06a8ed6..5627b6045 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -344,7 +344,8 @@ export class ConnectionService { throw new HttpException( { status: error.statusCode, - error: error.message + error: error.error, + message: error.message }, error.error ); From 520166dbff48ee196b588ddba0f543ccded0b6f4 Mon Sep 17 00:00:00 2001 From: Nishad Date: Tue, 26 Dec 2023 15:23:35 +0530 Subject: [PATCH 035/107] Worked on the GET API of credential definition by schema id Signed-off-by: Nishad --- .../src/authz/guards/org-roles.guard.ts | 2 +- .../src/schema/dtos/get-all-schema.dto.ts | 21 +++++++-- .../src/schema/schema.controller.ts | 34 +++++--------- apps/api-gateway/src/schema/schema.service.ts | 11 +++-- apps/ledger/src/schema/enum/schema.enum.ts | 8 ++++ .../interfaces/schema-payload.interface.ts | 7 +-- .../schema/repositories/schema.repository.ts | 24 +++++++--- apps/ledger/src/schema/schema.controller.ts | 20 ++------- apps/ledger/src/schema/schema.service.ts | 45 ++++++++----------- .../src/interfaces/response.interface.ts | 8 ++++ .../common/src/interfaces/schema.interface.ts | 35 ++++++++++++--- libs/common/src/response-messages/index.ts | 3 +- 12 files changed, 122 insertions(+), 96 deletions(-) diff --git a/apps/api-gateway/src/authz/guards/org-roles.guard.ts b/apps/api-gateway/src/authz/guards/org-roles.guard.ts index 45e9e50f1..4520f046b 100644 --- a/apps/api-gateway/src/authz/guards/org-roles.guard.ts +++ b/apps/api-gateway/src/authz/guards/org-roles.guard.ts @@ -41,7 +41,7 @@ export class OrgRolesGuard implements CanActivate { }); if (!specificOrg) { - throw new ForbiddenException(ResponseMessages.organisation.error.orgNotFound, { cause: new Error(), description: ResponseMessages.errorMessages.forbidden }); + throw new ForbiddenException(ResponseMessages.organisation.error.orgNotMatch, { cause: new Error(), description: ResponseMessages.errorMessages.forbidden }); } user.selectedOrg = specificOrg; diff --git a/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts b/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts index 90b43cf2f..e16ec07c2 100644 --- a/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts +++ b/apps/api-gateway/src/schema/dtos/get-all-schema.dto.ts @@ -5,7 +5,7 @@ import { SortValue } from '../../enum'; import { Transform, Type } from 'class-transformer'; import { IsEnum, IsOptional } from 'class-validator'; import { trim } from '@credebl/common/cast.helper'; -import { SortFields } from 'apps/ledger/src/schema/enum/schema.enum'; +import { CredDefSortFields, SortFields } from 'apps/ledger/src/schema/enum/schema.enum'; export class GetAllSchemaDto { @ApiProperty({ required: false }) @@ -51,13 +51,26 @@ export class GetCredentialDefinitionBySchemaIdDto { @Type(() => Number) pageSize: number = 10; - @ApiProperty({ required: false }) + @ApiProperty({ + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() - sortField: string = 'id'; + @IsEnum(CredDefSortFields) + sortField: string = SortFields.CREATED_DATE_TIME; - @ApiProperty({ required: false }) + @ApiProperty({ + enum: [SortValue.DESC, SortValue.ASC], + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() + @IsEnum(SortValue) sortBy: string = SortValue.DESC; + + schemaId: string; + + orgId: string; } export class GetAllSchemaByPlatformDto { diff --git a/apps/api-gateway/src/schema/schema.controller.ts b/apps/api-gateway/src/schema/schema.controller.ts index b0031f7e5..d530e9d8f 100644 --- a/apps/api-gateway/src/schema/schema.controller.ts +++ b/apps/api-gateway/src/schema/schema.controller.ts @@ -19,7 +19,7 @@ import { IUserRequestInterface } from './interfaces'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { CreateSchemaDto } from '../dtos/create-schema.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { SortFields } from 'apps/ledger/src/schema/enum/schema.enum'; +import { CredDefSortFields, SortFields } from 'apps/ledger/src/schema/enum/schema.enum'; @UseFilters(CustomExceptionFilter) @Controller('orgs') @@ -60,28 +60,13 @@ export class SchemaController { @Get('/:orgId/schemas/:schemaId/cred-defs') @ApiOperation({ - summary: 'Get credential definition list by schema Id', + summary: 'Credential definitions by schema Id', description: 'Get credential definition list by schema Id' }) - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) - @ApiQuery({ - name: 'pageNumber', - type: Number, - required: false - }) - @ApiQuery({ - name: 'pageSize', - type: Number, - required: false - }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiQuery({ name: 'sortField', - type: String, - required: false - }) - @ApiQuery({ - name: 'sortBy', - type: String, + enum: CredDefSortFields, required: false }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @@ -89,19 +74,22 @@ export class SchemaController { async getcredDeffListBySchemaId( @Param('orgId') orgId: string, @Param('schemaId') schemaId: string, - @Query() GetCredentialDefinitionBySchemaIdDto: GetCredentialDefinitionBySchemaIdDto, + @Query() getCredentialDefinitionBySchemaIdDto: GetCredentialDefinitionBySchemaIdDto, @Res() res: Response, - @User() user: IUserRequestInterface): Promise { + @User() user: IUserRequestInterface): Promise { if (!schemaId) { throw new BadRequestException(ResponseMessages.schema.error.invalidSchemaId); } - const credentialDefinitionList = await this.appService.getcredDeffListBySchemaId(schemaId, GetCredentialDefinitionBySchemaIdDto, user, orgId); + getCredentialDefinitionBySchemaIdDto.schemaId = schemaId; + getCredentialDefinitionBySchemaIdDto.orgId = orgId; + + const credentialDefinitionList = await this.appService.getcredDeffListBySchemaId(getCredentialDefinitionBySchemaIdDto, user); const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.schema.success.fetch, - data: credentialDefinitionList.response + data: credentialDefinitionList }; return res.status(HttpStatus.OK).json(finalResponse); diff --git a/apps/api-gateway/src/schema/schema.service.ts b/apps/api-gateway/src/schema/schema.service.ts index 48bf86dc3..5991b41f8 100644 --- a/apps/api-gateway/src/schema/schema.service.ts +++ b/apps/api-gateway/src/schema/schema.service.ts @@ -4,7 +4,8 @@ import { BaseService } from '../../../../libs/service/base.service'; import { CreateSchemaDto } from '../dtos/create-schema.dto'; import { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; import { IUserRequestInterface } from './interfaces'; -import { ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; +import { ICredDefWithPagination, ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; +import { GetCredentialDefinitionBySchemaIdDto } from './dtos/get-all-schema.dto'; @Injectable() export class SchemaService extends BaseService { @@ -32,10 +33,8 @@ export class SchemaService extends BaseService { return this.sendNatsMessage(this.schemaServiceProxy, 'get-schemas', schemaSearch); } - getcredDeffListBySchemaId(schemaId: string, schemaSearchCriteria: ISchemaSearchPayload, user: IUserRequestInterface, orgId: string): Promise<{ - response: object; - }> { - const payload = { schemaId, schemaSearchCriteria, user, orgId }; - return this.sendNats(this.schemaServiceProxy, 'get-cred-deff-list-by-schemas-id', payload); + getcredDeffListBySchemaId(schemaSearchCriteria: GetCredentialDefinitionBySchemaIdDto, user: IUserRequestInterface): Promise { + const payload = { schemaSearchCriteria, user }; + return this.sendNatsMessage(this.schemaServiceProxy, 'get-cred-deff-list-by-schemas-id', payload); } } \ No newline at end of file diff --git a/apps/ledger/src/schema/enum/schema.enum.ts b/apps/ledger/src/schema/enum/schema.enum.ts index 6a7f716d9..cafabff1d 100644 --- a/apps/ledger/src/schema/enum/schema.enum.ts +++ b/apps/ledger/src/schema/enum/schema.enum.ts @@ -8,4 +8,12 @@ export enum SortFields { LEDGER_ID = 'schemaLedgerId', PUBLISHER_DID = 'publisherDid', ISSUER_ID = 'issuerId' +} + +export enum CredDefSortFields { + ID = 'id', + CREATED_DATE_TIME = 'createDateTime', + TAG = 'tag', + LEDGER_ID = 'schemaLedgerId', + CRED_DEF_ID= 'credentialDefinitionId' } \ No newline at end of file diff --git a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts index 353bb2a55..1b0c2797e 100644 --- a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts @@ -53,14 +53,15 @@ export interface ISchemaSearchCriteria { pageSize: number; sortField: string; sortBy: string; - searchByText: string; - user: IUserRequestInterface + searchByText?: string; + user?: IUserRequestInterface + schemaId?: string; + orgId?: string; } export interface ISchemaCredDeffSearchInterface { schemaId: string; schemaSearchCriteria?: ISchemaSearchCriteria, user: IUserRequestInterface, - orgId?: string } diff --git a/apps/ledger/src/schema/repositories/schema.repository.ts b/apps/ledger/src/schema/repositories/schema.repository.ts index 912f59d35..84102155b 100644 --- a/apps/ledger/src/schema/repositories/schema.repository.ts +++ b/apps/ledger/src/schema/repositories/schema.repository.ts @@ -6,6 +6,7 @@ import { ISchema, ISchemaSearchCriteria } from '../interfaces/schema-payload.int import { ResponseMessages } from '@credebl/common/response-messages'; import { AgentDetails, ISchemasWithCount } from '../interfaces/schema.interface'; import { SortValue } from '@credebl/enum/enum'; +import { ICredDefWithCount } from '@credebl/common/interfaces/schema.interface'; @Injectable() export class SchemaRepository { @@ -162,14 +163,12 @@ export class SchemaRepository { } } - async getSchemasCredDeffList(payload: ISchemaSearchCriteria, orgId: string, schemaId: string): Promise<{ - tag: string; - credentialDefinitionId: string; - schemaLedgerId: string; - revocable: boolean; - }[]> { + async getSchemasCredDeffList(payload: ISchemaSearchCriteria): Promise { + + const {orgId, schemaId} = payload; + try { - return this.prisma.credential_definition.findMany({ + const credDefResult = await this.prisma.credential_definition.findMany({ where: { AND: [ { orgId }, @@ -185,8 +184,19 @@ export class SchemaRepository { }, orderBy: { [payload.sortField]: SortValue.ASC === payload.sortBy ? 'asc' : 'desc' + }, + take: Number(payload.pageSize), + skip: (payload.pageNumber - 1) * payload.pageSize + }); + const credDefCount = await this.prisma.credential_definition.count({ + where: { + AND: [ + { orgId }, + { schemaLedgerId: schemaId } + ] } }); + return { credDefResult, credDefCount }; } catch (error) { this.logger.error(`Error in getting agent DID: ${error}`); throw error; diff --git a/apps/ledger/src/schema/schema.controller.ts b/apps/ledger/src/schema/schema.controller.ts index d80df8995..f17d197f4 100644 --- a/apps/ledger/src/schema/schema.controller.ts +++ b/apps/ledger/src/schema/schema.controller.ts @@ -4,7 +4,7 @@ import { MessagePattern } from '@nestjs/microservices'; import { ISchema, ISchemaCredDeffSearchInterface, ISchemaSearchPayload } from './interfaces/schema-payload.interface'; import { schema } from '@prisma/client'; import { ResponseMessages } from '@credebl/common/response-messages'; -import { ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; +import { ICredDefWithPagination, ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; @Controller('schema') @@ -31,22 +31,8 @@ export class SchemaController { } @MessagePattern({ cmd: 'get-cred-deff-list-by-schemas-id' }) - async getcredDeffListBySchemaId(payload: ISchemaCredDeffSearchInterface): Promise<{ - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - tag: string; - credentialDefinitionId: string; - schemaLedgerId: string; - revocable: boolean; - }[]; - }> { - const { schemaId, schemaSearchCriteria, user, orgId } = payload; - return this.schemaService.getcredDeffListBySchemaId(schemaId, schemaSearchCriteria, user, orgId); + async getcredDeffListBySchemaId(payload: ISchemaCredDeffSearchInterface): Promise { + return this.schemaService.getcredDeffListBySchemaId(payload); } @MessagePattern({ cmd: 'get-all-schemas' }) diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index c2d5f8323..838795be9 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -11,13 +11,13 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { SchemaRepository } from './repositories/schema.repository'; import { schema } from '@prisma/client'; -import { ISchema, ISchemaPayload, ISchemaSearchCriteria } from './interfaces/schema-payload.interface'; +import { ISchema, ISchemaCredDeffSearchInterface, ISchemaPayload, ISchemaSearchCriteria } from './interfaces/schema-payload.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { IUserRequestInterface } from './interfaces/schema.interface'; import { CreateSchemaAgentRedirection, GetSchemaAgentRedirection } from './schema.interface'; import { map } from 'rxjs/operators'; import { OrgAgentType } from '@credebl/enum/enum'; -import { ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; +import { ICredDefWithPagination, ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; @Injectable() export class SchemaService extends BaseService { @@ -353,38 +353,29 @@ export class SchemaService extends BaseService { } } - async getcredDeffListBySchemaId(schemaId: string, schemaSearchCriteria: ISchemaSearchCriteria, user: IUserRequestInterface, orgId: string): Promise<{ - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - tag: string; - credentialDefinitionId: string; - schemaLedgerId: string; - revocable: boolean; - }[]; - }> { + async getcredDeffListBySchemaId( + payload: ISchemaCredDeffSearchInterface + ): Promise { + const { schemaSearchCriteria } = payload; + try { - const response = await this.schemaRepository.getSchemasCredDeffList(schemaSearchCriteria, orgId, schemaId); + const response = await this.schemaRepository.getSchemasCredDeffList(schemaSearchCriteria); + + if (0 === response.credDefCount) { + throw new NotFoundException(ResponseMessages.schema.error.credentialDefinitionNotFound); + } + const schemasResponse = { - totalItems: response.length, - hasNextPage: schemaSearchCriteria.pageSize * schemaSearchCriteria.pageNumber < response.length, + totalItems: response.credDefCount, + hasNextPage: schemaSearchCriteria.pageSize * schemaSearchCriteria.pageNumber < response.credDefCount, hasPreviousPage: 1 < schemaSearchCriteria.pageNumber, nextPage: schemaSearchCriteria.pageNumber + 1, previousPage: schemaSearchCriteria.pageNumber - 1, - lastPage: Math.ceil(response.length / schemaSearchCriteria.pageSize), - data: response + lastPage: Math.ceil(response.credDefCount / schemaSearchCriteria.pageSize), + data: response.credDefResult }; - if (0 !== response.length) { - return schemasResponse; - } else { - throw new NotFoundException(ResponseMessages.schema.error.credentialDefinitionNotFound); - } - + return schemasResponse; } catch (error) { this.logger.error(`Error in retrieving credential definition: ${error}`); diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 52639580f..859364831 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -5,3 +5,11 @@ export default interface IResponseType { data?: unknown; error?: unknown; }; + +export default interface IResponse { + statusCode: number; + message?: string; + label?: string; + data?: unknown; +}; + diff --git a/libs/common/src/interfaces/schema.interface.ts b/libs/common/src/interfaces/schema.interface.ts index 568272663..c773c206a 100644 --- a/libs/common/src/interfaces/schema.interface.ts +++ b/libs/common/src/interfaces/schema.interface.ts @@ -1,11 +1,15 @@ -export interface ISchemasWithPagination { - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; +export interface IPaginationDetails { + totalItems: number; + hasNextPage: boolean; + hasPreviousPage: boolean; + nextPage: number; + previousPage: number; + lastPage: number; +} + + +export interface ISchemasWithPagination extends IPaginationDetails{ data: ISchemaData[]; } @@ -19,5 +23,22 @@ export interface ISchemasWithPagination { publisherDid: string; issuerId: string; orgId: string; + } + + export interface ICredDefData { + tag: string; + credentialDefinitionId: string; + schemaLedgerId: string; + revocable: boolean; + createDateTime?: Date; + } + + export interface ICredDefWithPagination extends IPaginationDetails{ + data: ICredDefData[]; + } + + export interface ICredDefWithCount { + credDefCount: number; + credDefResult: ICredDefData[]; } \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index db8744af6..0f932aaaa 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -69,7 +69,8 @@ export const ResponseMessages = { updateUserRoles: 'Unable to update user roles', deleteOrg: 'Organization not found', notFound: 'Organization agent not found', - orgNotFound: 'Organization not found' + orgNotFound: 'Organization not found', + orgNotMatch: 'Organization does not match' } }, From db26e63225a96abb6a749980c2b9d6d215aa21a8 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Tue, 26 Dec 2023 15:24:57 +0530 Subject: [PATCH 036/107] refactor: get connection details by connection id details Signed-off-by: bhavanakarwade --- apps/connection/src/connection.service.ts | 35 ++++++++++------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 5627b6045..6bbcc8e6c 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -316,13 +316,13 @@ export class ConnectionService { } catch (error) { this.logger.error(`[getConnectionsById] - error in get connections : ${JSON.stringify(error)}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + if (error?.response?.error?.reason) { throw new RpcException({ - message: error?.status?.message?.error?.reason - ? error?.status?.message?.error?.reason - : error?.status?.message?.error, - statusCode: error?.status?.code + message: ResponseMessages.connection.error.connectionNotFound, + statusCode: error?.status?.code, + error: error?.response?.error?.reason }); + } else { throw new RpcException(error.response ? error.response : error); } @@ -333,30 +333,25 @@ export class ConnectionService { url: string, apiKey: string ): Promise { - try { + const pattern = { cmd: 'agent-get-connections-by-connectionId' }; const payload = { url, apiKey }; return this.connectionServiceProxy .send(pattern, payload) .toPromise() - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( + .catch(error => { + this.logger.error( + `[_getConnectionsByConnectionId] [NATS call]- error in fetch connections : ${JSON.stringify(error)}` + ); + throw new HttpException( { - status: error.statusCode, - error: error.error, + status: error.statusCode, + error: error.error?.message?.error ? error.error?.message?.error : error.error, message: error.message - }, - error.error - ); + }, error.error); }); - } catch (error) { - this.logger.error( - `[_getConnectionsByConnectionId] [NATS call]- error in fetch connections : ${JSON.stringify(error)}` - ); - throw error; - } } + /** * Description: Fetch agent url * @param referenceId From a49a85dbce7c75624e1dcfcd72d7f433fc66742b Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Tue, 26 Dec 2023 15:43:12 +0530 Subject: [PATCH 037/107] removed duplicate function Signed-off-by: bhavanakarwade --- apps/api-gateway/src/main.ts | 6 ------ libs/common/src/interfaces/response.interface.ts | 1 - 2 files changed, 7 deletions(-) diff --git a/apps/api-gateway/src/main.ts b/apps/api-gateway/src/main.ts index b7d9893a2..959cba04b 100644 --- a/apps/api-gateway/src/main.ts +++ b/apps/api-gateway/src/main.ts @@ -32,12 +32,6 @@ async function bootstrap(): Promise { xssFilter:true })); - app.useGlobalPipes( - new ValidationPipe({ - whitelist: true - }) - ); - const options = new DocumentBuilder() .setTitle(`${process.env.PLATFORM_NAME}`) .setDescription(`${process.env.PLATFORM_NAME} Platform APIs`) diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 524342408..bde8e16a1 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -11,5 +11,4 @@ export default interface IResponse { message?: string; label?: string; data?: unknown; - error?: unknown; }; From d9c74664a967a95d2c5526c052638d7d12460a7a Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Tue, 26 Dec 2023 17:14:09 +0530 Subject: [PATCH 038/107] removed optional fields from interface Signed-off-by: bhavanakarwade --- apps/api-gateway/src/connection/connection.controller.ts | 3 +-- apps/connection/src/enum/connection.enum.ts | 4 +++- libs/common/src/interfaces/response.interface.ts | 6 ++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 0fe1751f5..0e7cf1420 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -1,4 +1,4 @@ -import IResponseType from '@credebl/common/interfaces/response.interface'; +import IResponseType, {IResponse} from '@credebl/common/interfaces/response.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { Controller, Logger, Post, Body, UseGuards, HttpStatus, Res, Get, Param, UseFilters, Query } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @@ -20,7 +20,6 @@ import { GetAllConnectionsDto } from './dtos/get-all-connections.dto'; import { IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; import { SortFields } from 'apps/connection/src/enum/connection.enum'; import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import IResponse from '@credebl/common/interfaces/response.interface'; @UseFilters(CustomExceptionFilter) @Controller() diff --git a/apps/connection/src/enum/connection.enum.ts b/apps/connection/src/enum/connection.enum.ts index 492f37029..6e42e5d6d 100644 --- a/apps/connection/src/enum/connection.enum.ts +++ b/apps/connection/src/enum/connection.enum.ts @@ -1,3 +1,5 @@ export enum SortFields { - CREATED_DATE_TIME = 'createDateTime' + CREATED_DATE_TIME = 'createDateTime', + USER_LABEL = 'theirLabel', + CONNECTION_ID = 'connectionId' } \ No newline at end of file diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 524342408..6c1b4160a 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -5,11 +5,9 @@ export default interface IResponseType { data?: unknown; error?: unknown; }; - -export default interface IResponse { +export interface IResponse { statusCode: number; - message?: string; + message: string; label?: string; data?: unknown; - error?: unknown; }; From d583bdc4256e63a008dc2362670ed3b3660f1450 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Tue, 26 Dec 2023 19:14:11 +0530 Subject: [PATCH 039/107] reafctor: create outbound connection API Signed-off-by: bhavanakarwade --- .../src/agent-service.service.ts | 20 +++++++++---------- .../src/connection/connection.controller.ts | 9 +++++---- .../src/connection/connection.service.ts | 6 ++---- .../src/connection/dtos/connection.dto.ts | 15 +++++++------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 6088a7cce..f38e33a9c 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -491,22 +491,22 @@ export class AgentServiceService { } - async _createLegacyConnectionInvitation(orgId: string, user: IUserRequestInterface, label: string): Promise<{ - response; - }> { + async _createLegacyConnectionInvitation(orgId: string, user: IUserRequestInterface, label: string): Promise< + object> { try { const pattern = { cmd: 'create-connection' }; const payload = { orgId, user, label }; return this.agentServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ( - { - response - })) - ).toPromise() + .send(pattern, payload) + // .pipe( + // map((response) => ( + // { + // response + // })) + // ) + .toPromise() .catch(error => { this.logger.error(`catch: ${JSON.stringify(error)}`); throw new HttpException( diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 850355101..342c8ddb3 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -18,6 +18,7 @@ import { Roles } from '../authz/decorators/roles.decorator'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { GetAllConnectionsDto } from './dtos/get-all-connections.dto'; import { IConnectionSearchinterface } from '../interfaces/ISchemaSearch.interface'; +import { ApiResponseDto } from '../dtos/apiResponse.dto'; @UseFilters(CustomExceptionFilter) @Controller() @@ -136,7 +137,7 @@ export class ConnectionController { @ApiOperation({ summary: 'Create outbound out-of-band connection (Legacy Invitation)', description: 'Create outbound out-of-band connection (Legacy Invitation)' }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) - @ApiResponse({ status: 201, description: 'Success', type: AuthTokenResponse }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) async createLegacyConnectionInvitation( @Param('orgId') orgId: string, @Body() connectionDto: CreateConnectionDto, @@ -145,11 +146,11 @@ export class ConnectionController { ): Promise { connectionDto.orgId = orgId; - const connectionData = await this.connectionService.createLegacyConnectionInvitation(connectionDto, reqUser); + await this.connectionService.createLegacyConnectionInvitation(connectionDto, reqUser); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, - message: ResponseMessages.connection.success.create, - data: connectionData.response + message: ResponseMessages.connection.success.create + // data: connectionData }; return res.status(HttpStatus.CREATED).json(finalResponse); diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 214a5c013..91e2288ec 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -15,9 +15,7 @@ export class ConnectionService extends BaseService { createLegacyConnectionInvitation( connectionDto: CreateConnectionDto, user: IUserRequestInterface - ): Promise<{ - response: object; - }> { + ): Promise { try { const connectionDetails = { orgId: connectionDto.orgId, @@ -29,7 +27,7 @@ export class ConnectionService extends BaseService { user }; - return this.sendNats(this.connectionServiceProxy, 'create-connection', connectionDetails); + return this.sendNatsMessage(this.connectionServiceProxy, 'create-connection', connectionDetails); } catch (error) { throw new RpcException(error.response); } diff --git a/apps/api-gateway/src/connection/dtos/connection.dto.ts b/apps/api-gateway/src/connection/dtos/connection.dto.ts index fe225792b..baed2472e 100644 --- a/apps/api-gateway/src/connection/dtos/connection.dto.ts +++ b/apps/api-gateway/src/connection/dtos/connection.dto.ts @@ -1,30 +1,31 @@ import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class CreateConnectionDto { - @ApiProperty() + @ApiPropertyOptional() @IsOptional() - @IsString({ message: 'alias must be a string' }) @IsNotEmpty({ message: 'please provide valid alias' }) + @IsString({ message: 'alias must be a string' }) + @IsNotEmpty({ message: 'please provide valid alias' }) alias: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() @IsString({ message: 'label must be a string' }) @IsNotEmpty({ message: 'please provide valid label' }) label: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() @IsNotEmpty({ message: 'please provide valid imageUrl' }) imageUrl: string; - @ApiProperty() + @ApiPropertyOptional() @IsBoolean() @IsOptional() @IsNotEmpty({ message: 'please provide multiUseInvitation' }) multiUseInvitation: boolean; - @ApiProperty() + @ApiPropertyOptional() @IsBoolean() @IsOptional() @IsNotEmpty({ message: 'autoAcceptConnection should boolean' }) From 04dfc642b0e2e2b966fd0a69631ee652c28af695 Mon Sep 17 00:00:00 2001 From: sanjay-k1910 Date: Tue, 26 Dec 2023 19:17:34 +0530 Subject: [PATCH 040/107] refactor: response type Signed-off-by: sanjay-k1910 --- apps/api-gateway/src/organization/organization.controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api-gateway/src/organization/organization.controller.ts b/apps/api-gateway/src/organization/organization.controller.ts index df66ed869..060a8e663 100644 --- a/apps/api-gateway/src/organization/organization.controller.ts +++ b/apps/api-gateway/src/organization/organization.controller.ts @@ -3,7 +3,7 @@ import { CommonService } from '@credebl/common'; import { Controller, Get, Put, Param, UseGuards, UseFilters, Post, Body, Res, HttpStatus, Query, Delete } from '@nestjs/common'; import { OrganizationService } from './organization.service'; import { CreateOrganizationDto } from './dtos/create-organization-dto'; -import IResponseType from '@credebl/common/interfaces/response.interface'; +import IResponseType, { IResponse } from '@credebl/common/interfaces/response.interface'; import { Response } from 'express'; import { ApiResponseDto } from '../dtos/apiResponse.dto'; import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; @@ -385,7 +385,7 @@ export class OrganizationController { @Res() res: Response ): Promise { await this.organizationService.deleteOrganizationInvitation(orgId, invitationId); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.orgInvitationDeleted }; From 60a8dbb3161f0f2c606e90b5fada17aa60ad87c0 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Tue, 26 Dec 2023 19:30:38 +0530 Subject: [PATCH 041/107] refactor:verify-user-and-send-verification-mail-api Signed-off-by: pranalidhanavade --- .../api-gateway/src/authz/authz.controller.ts | 8 ++--- apps/api-gateway/src/authz/authz.service.ts | 11 +++---- .../src/user/dto/email-verify.dto.ts | 3 +- apps/user/interfaces/user.interface.ts | 10 ++++-- apps/user/repositories/user.repository.ts | 32 +++++++++---------- apps/user/src/user.controller.ts | 8 ++--- apps/user/src/user.service.ts | 31 +++++++++--------- libs/common/src/response-messages/index.ts | 3 +- 8 files changed, 56 insertions(+), 50 deletions(-) diff --git a/apps/api-gateway/src/authz/authz.controller.ts b/apps/api-gateway/src/authz/authz.controller.ts index 3e35edf4f..cafaedfe7 100644 --- a/apps/api-gateway/src/authz/authz.controller.ts +++ b/apps/api-gateway/src/authz/authz.controller.ts @@ -41,7 +41,7 @@ export class AuthzController { * @returns User email verified */ @Get('/verify') - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiOperation({ summary: 'Verify user’s email', description: 'Verify user’s email' }) async verifyEmail(@Query() query: EmailVerificationDto, @Res() res: Response): Promise { await this.authzService.verifyEmail(query); @@ -61,10 +61,10 @@ export class AuthzController { * @returns Email sent success */ @Post('/verification-mail') - @ApiResponse({ status: 201, description: 'Success', type: ApiResponseDto }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) @ApiOperation({ summary: 'Send verification email', description: 'Send verification email to new user' }) - async create(@Body() userEmailVerificationDto: UserEmailVerificationDto, @Res() res: Response): Promise { - await this.authzService.sendVerificationMail(userEmailVerificationDto); + async create(@Body() userEmailVerification: UserEmailVerificationDto, @Res() res: Response): Promise { + await this.authzService.sendVerificationMail(userEmailVerification); const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.user.success.sendVerificationCode diff --git a/apps/api-gateway/src/authz/authz.service.ts b/apps/api-gateway/src/authz/authz.service.ts index 317712669..5a5f17203 100644 --- a/apps/api-gateway/src/authz/authz.service.ts +++ b/apps/api-gateway/src/authz/authz.service.ts @@ -28,15 +28,14 @@ export class AuthzService extends BaseService { return this.sendNats(this.authServiceProxy, 'get-user-by-keycloakUserId', keycloakUserId); } - async sendVerificationMail(userEmailVerificationDto: UserEmailVerificationDto): Promise { - const payload = { userEmailVerificationDto }; - return this.sendNats(this.authServiceProxy, 'send-verification-mail', payload); + async sendVerificationMail(userEmailVerification: UserEmailVerificationDto): Promise { + const payload = { userEmailVerification }; + return this.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload); } - async verifyEmail(param: EmailVerificationDto): Promise { + async verifyEmail(param: EmailVerificationDto): Promise { const payload = { param }; - return this.sendNats(this.authServiceProxy, 'user-email-verification', payload); - + return this.sendNatsMessage(this.authServiceProxy, 'user-email-verification', payload); } async login(email: string, password?: string, isPasskey = false): Promise<{ response: object }> { diff --git a/apps/api-gateway/src/user/dto/email-verify.dto.ts b/apps/api-gateway/src/user/dto/email-verify.dto.ts index 23c4acd5a..c54db401d 100644 --- a/apps/api-gateway/src/user/dto/email-verify.dto.ts +++ b/apps/api-gateway/src/user/dto/email-verify.dto.ts @@ -1,4 +1,4 @@ -import { IsEmail, IsNotEmpty, MaxLength } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString, MaxLength } from 'class-validator'; import { toLowerCase, trim } from '@credebl/common/cast.helper'; import { ApiProperty } from '@nestjs/swagger'; @@ -17,5 +17,6 @@ export class EmailVerificationDto { @ApiProperty() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'Verification code is required.' }) + @IsString({ message: 'Verification code should be string' }) verificationCode: string; } diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index a3f6fecb7..c495c5fc1 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -66,8 +66,8 @@ interface IUserOrgRole { email?: string; orgRoles: string[]; } - - export interface UserEmailVerificationDto { + + export interface ISendVerificationEmail { email: string; username?: string; } @@ -175,3 +175,9 @@ interface IUserOrgRole { pageSize: number; search: string; } + + export class IVerifyUserEmail { + email: string; + verificationCode: string; +} + diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index 32c1d4b2e..59c406882 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -7,11 +7,11 @@ import { ShareUserCertificate, UpdateUserProfile, UserCredentials, - UserEmailVerificationDto, - IUsersProfile, - IUserInformation + ISendVerificationEmail, + IUsersProfile, + IUserInformation, + IVerifyUserEmail } from '../interfaces/user.interface'; - import { InternalServerErrorException } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; // eslint-disable-next-line camelcase @@ -27,21 +27,21 @@ interface UserQueryOptions { @Injectable() export class UserRepository { constructor( - private readonly prisma: PrismaService, + private readonly prisma: PrismaService, private readonly logger: Logger ) {} /** * - * @param userEmailVerificationDto + * @param userEmailVerification * @returns user email */ - async createUser(userEmailVerificationDto: UserEmailVerificationDto, verifyCode: string): Promise { + async createUser(userEmailVerification:ISendVerificationEmail, verifyCode: string): Promise { try { const saveResponse = await this.prisma.user.create({ data: { - username: userEmailVerificationDto.username, - email: userEmailVerificationDto.email, + username: userEmailVerification.username, + email: userEmailVerification.email, verificationCode: verifyCode.toString(), publicProfile: true } @@ -247,11 +247,11 @@ export class UserRepository { website: true, publicProfile: true } + } } - } } } - }); + }); } async findUserForPublicProfile(queryOptions: UserQueryOptions): Promise { @@ -301,8 +301,8 @@ export class UserRepository { website: true, publicProfile: true } + } } - } } } }); @@ -375,15 +375,15 @@ export class UserRepository { }, select: { id: true, -username: true, + username: true, email: true, firstName: true, lastName: true, isEmailVerified: true, userOrgRoles: { - where: { + where: { ...filterOptions -// Additional filtering conditions if needed + // Additional filtering conditions if needed }, select: { id: true, @@ -526,7 +526,7 @@ username: true, } } - async verifyUser(email: string): Promise { + async verifyUser(email: string): Promise { try { const updateUserDetails = await this.prisma.user.update({ where: { diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 9719e9a0b..7e9224ac9 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, UserCredentials, UserEmailVerificationDto, IUserInformation, IUsersProfile, UserInvitations } from '../interfaces/user.interface'; +import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, UserCredentials, IUserInformation, IUsersProfile, UserInvitations, ISendVerificationEmail, IVerifyUserEmail} from '../interfaces/user.interface'; import {IOrgUsers, Payload} from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; @@ -20,8 +20,8 @@ export class UserController { * @returns Get registered user response */ @MessagePattern({ cmd: 'send-verification-mail' }) - async sendVerificationMail(payload: { userEmailVerificationDto: UserEmailVerificationDto }): Promise { - return this.userService.sendVerificationMail(payload.userEmailVerificationDto); + async sendVerificationMail(payload: { userEmailVerification: ISendVerificationEmail }): Promise { + return this.userService.sendVerificationMail(payload.userEmailVerification); } /** @@ -30,7 +30,7 @@ export class UserController { * @returns Get user's email verified */ @MessagePattern({ cmd: 'user-email-verification' }) - async verifyEmail(payload: { param: VerifyEmailTokenDto }): Promise { + async verifyEmail(payload: { param: VerifyEmailTokenDto }): Promise { return this.userService.verifyEmail(payload.param); } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 1f2f1b367..530c18cbb 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -35,11 +35,12 @@ import { ShareUserCertificate, IOrgUsers, UpdateUserProfile, - UserCredentials, - UserEmailVerificationDto, + UserCredentials, + ISendVerificationEmail, IUserInformation, IUsersProfile, - UserInvitations + UserInvitations, + IVerifyUserEmail } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { UserActivityService } from '@credebl/user-activity'; @@ -76,12 +77,12 @@ export class UserService { /** * - * @param userEmailVerificationDto + * @param userEmailVerification * @returns */ - async sendVerificationMail(userEmailVerificationDto: UserEmailVerificationDto): Promise { + async sendVerificationMail(userEmailVerification: ISendVerificationEmail): Promise { try { - const { email } = userEmailVerificationDto; + const { email } = userEmailVerification; if ('PROD' === process.env.PLATFORM_PROFILE_MODE) { // eslint-disable-next-line prefer-destructuring @@ -91,7 +92,7 @@ export class UserService { throw new BadRequestException(ResponseMessages.user.error.InvalidEmailDomain); } } - const userDetails = await this.userRepository.checkUserExist(userEmailVerificationDto.email); + const userDetails = await this.userRepository.checkUserExist(userEmailVerification.email); if (userDetails && userDetails.isEmailVerified) { throw new ConflictException(ResponseMessages.user.error.exists); @@ -102,12 +103,12 @@ export class UserService { } const verifyCode = uuidv4(); - const uniqueUsername = await this.createUsername(userEmailVerificationDto.email, verifyCode); - userEmailVerificationDto.username = uniqueUsername; - const resUser = await this.userRepository.createUser(userEmailVerificationDto, verifyCode); + const uniqueUsername = await this.createUsername(userEmailVerification.email, verifyCode); + userEmailVerification.username = uniqueUsername; + const resUser = await this.userRepository.createUser(userEmailVerification, verifyCode); try { - await this.sendEmailForVerification(userEmailVerificationDto.email, resUser.verificationCode); + await this.sendEmailForVerification(userEmailVerification.email, resUser.verificationCode); } catch (error) { throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); } @@ -178,7 +179,7 @@ export class UserService { * @returns Email verification succcess */ - async verifyEmail(param: VerifyEmailTokenDto): Promise { + async verifyEmail(param: VerifyEmailTokenDto): Promise { try { const invalidMessage = ResponseMessages.user.error.invalidEmailUrl; @@ -197,10 +198,8 @@ export class UserService { } if (param.verificationCode === userDetails.verificationCode) { - await this.userRepository.verifyUser(param.email); - return { - message: 'User Verified sucessfully' - }; + const verifiedEmail = await this.userRepository.verifyUser(param.email); + return verifiedEmail; } } catch (error) { this.logger.error(`error in verifyEmail: ${JSON.stringify(error)}`); diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index db8744af6..afa31420c 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -13,11 +13,12 @@ export const ResponseMessages = { fetchUsers: 'Users fetched successfully', newUser: 'User not found', checkEmail: 'User email checked successfully.', - sendVerificationCode: 'Verification code has been sent sucessfully to the mail. Please verify', + sendVerificationCode: 'Verification link has been successfully sent on the email. Please verify', userActivity: 'User activities fetched successfully', userCredentials: 'User credentials fetched successfully', platformEcosystemettings: 'Platform and ecosystem settings updated', fetchPlatformSettings: 'Platform settings fetched' + }, error: { exists: 'User already exists', From 846969b7a0da6c098b6db38b2662f6c88c79186e Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Tue, 26 Dec 2023 19:42:24 +0530 Subject: [PATCH 042/107] refactor: API agent spin-up Signed-off-by: KulkarniShashank --- .../src/agent-service.controller.ts | 5 + .../src/agent-service.service.ts | 126 ++++++++++++++++-- .../src/interface/agent-service.interface.ts | 4 + .../repositories/agent-service.repository.ts | 12 +- .../agent-service/agent-service.controller.ts | 22 ++- .../agent-service/agent-service.service.ts | 8 +- .../agent-service/dto/agent-service.dto.ts | 37 ++--- libs/common/src/response-messages/index.ts | 13 +- 8 files changed, 173 insertions(+), 54 deletions(-) diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 9fc94f190..45dbdcb15 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -10,6 +10,11 @@ import { user } from '@prisma/client'; export class AgentServiceController { constructor(private readonly agentServiceService: AgentServiceService) { } + /** + * Spinup the agent by organization + * @param payload + * @returns Get agent status + */ @MessagePattern({ cmd: 'agent-spinup' }) async walletProvision(payload: { agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface }): Promise { return this.agentServiceService.walletProvision(payload.agentSpinupDto, payload.user); diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 6088a7cce..23c6bfb26 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -18,7 +18,7 @@ import * as dotenv from 'dotenv'; import * as fs from 'fs'; import { catchError, map } from 'rxjs/operators'; dotenv.config(); -import { GetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, OutOfBandCredentialOffer } from './interface/agent-service.interface'; +import { GetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, OutOfBandCredentialOffer, AgentSpinupStatus } from './interface/agent-service.interface'; import { AgentSpinUpStatus, AgentType, Ledgers, OrgAgentType } from '@credebl/enum/enum'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { AgentServiceRepository } from './repositories/agent-service.repository'; @@ -126,18 +126,26 @@ export class AgentServiceService { } } - - async walletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise<{ agentSpinupStatus: number }> { + /** + * Spinup the agent by organization + * @param agentSpinupDto + * @param user + * @returns Get agent status + */ + async walletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise { let agentProcess: org_agents; try { - this.processWalletProvision(agentSpinupDto, user); + // Invoke an internal function to create wallet + await this.processWalletProvision(agentSpinupDto, user); const agentStatusResponse = { agentSpinupStatus: AgentSpinUpStatus.PROCESSED }; return agentStatusResponse; } catch (error) { + + // Invoke an internal function to handle error to create wallet this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess); throw new RpcException(error.response ? error.response : error); } @@ -148,6 +156,10 @@ export class AgentServiceService { let userId: string; let agentProcess: org_agents; try { + + /** + * Get agent details by organization + */ const [getOrgAgent, platformConfig, getAgentType, ledgerIdData, orgData] = await Promise.all([ this.agentServiceRepository.getAgentDetails(agentSpinupDto.orgId), this.agentServiceRepository.getPlatformConfigDetails(), @@ -158,6 +170,9 @@ export class AgentServiceService { if (!user?.userId && agentSpinupDto?.platformAdminEmail) { + /** + * Get Platform admin user by platform admin email + */ platformAdminUser = await this.agentServiceRepository.getPlatfomAdminUser(agentSpinupDto?.platformAdminEmail); userId = platformAdminUser?.id; @@ -166,17 +181,33 @@ export class AgentServiceService { } agentSpinupDto.ledgerId = agentSpinupDto.ledgerId?.length ? agentSpinupDto.ledgerId : ledgerIdData.map(ledger => ledger.id); + + /** + * Get ledgers by ledgerIds + */ const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { - throw new BadRequestException('Your wallet has already been created.'); + this.logger.error(`Your wallet has already been created`); + throw new BadRequestException( + ResponseMessages.agent.error.walletAlreadyCreated, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { - throw new BadRequestException('Your wallet is already processing.'); + this.logger.error('Your wallet is already processing.'); + throw new BadRequestException( + ResponseMessages.agent.error.walletAlreadyProcessing, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } if (!agentSpinupDto.orgId) { + + /** + * Get platform details by platform org name + */ const platformAdminOrgDetails = await this.agentServiceRepository.getPlatfomOrg(agentSpinupDto?.orgName); if (platformAdminOrgDetails) { @@ -188,13 +219,23 @@ export class AgentServiceService { agentSpinupDto.tenant = agentSpinupDto.tenant || false; agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]; + /** + * Invoke function for validate platform configuration + */ this.validatePlatformConfig(platformConfig); const externalIp = platformConfig?.externalIp; const controllerIp = platformConfig?.lastInternalId !== 'false' ? platformConfig?.lastInternalId : ''; const apiEndpoint = platformConfig?.apiEndpoint; + /** + * Create payload for the wallet create and store payload + */ const walletProvisionPayload = await this.prepareWalletProvisionPayload(agentSpinupDto, externalIp, apiEndpoint, controllerIp, ledgerDetails, platformConfig, orgData); + + /** + * Socket connection + */ const socket: Socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); this.emitAgentSpinupInitiatedEvent(agentSpinupDto, socket); @@ -213,26 +254,46 @@ export class AgentServiceService { validatePlatformConfig(platformConfig: platform_config): void { if (!platformConfig) { - throw new BadRequestException('Platform configuration is missing or invalid.'); + this.logger.error(`Platform configuration is missing or invalid`); + throw new BadRequestException( + ResponseMessages.agent.error.platformConfiguration, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } if (!platformConfig.apiEndpoint) { - throw new BadRequestException('API endpoint is missing in the platform configuration.'); + this.logger.error(`API endpoint is missing in the platform configuration`); + throw new BadRequestException( + ResponseMessages.agent.error.apiEndpoint, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } if (!platformConfig.externalIp) { - throw new BadRequestException('External IP is missing in the platform configuration.'); + this.logger.error(`External IP is missing in the platform configuration`); + throw new BadRequestException( + ResponseMessages.agent.error.externalIp, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } if (typeof platformConfig.externalIp !== 'string') { - throw new BadRequestException('External IP must be a string.'); + this.logger.error(`External IP must be a string`); + throw new BadRequestException( + ResponseMessages.agent.error.externalIp, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } } validateAgentProcess(agentProcess: org_agents): void { try { if (!agentProcess) { - throw new BadRequestException('Agent process is invalid or not in a completed state.'); + this.logger.error(`Agent process is invalid or not in a completed state`); + throw new BadRequestException( + ResponseMessages.agent.error.externalIp, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } } catch (error) { this.logger.error(`Error validating agent process: ${error.message}`); @@ -344,16 +405,27 @@ export class AgentServiceService { async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: org_agents): Promise { try { + + /** + * Invoke wallet create and provision with agent + */ const walletProvision = await this._walletProvision(walletProvisionPayload); if (!walletProvision?.response) { - throw new BadRequestException('Agent not able to spin-up'); + this.logger.error(`Agent not able to spin-up`); + throw new BadRequestException( + ResponseMessages.agent.error.notAbleToSpinup, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } const agentDetails = JSON.parse(walletProvision.response); const agentEndPoint = `${process.env.API_GATEWAY_PROTOCOL}://${agentDetails.CONTROLLER_ENDPOINT}`; + /** + * Socket connection + */ const socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); if (agentEndPoint && agentSpinupDto.clientSocketId) { @@ -375,6 +447,9 @@ export class AgentServiceService { id: agentProcess.id }; + /** + * Store organization agent details + */ const storeAgentDetails = await this._storeOrgAgentDetails(agentPayload); if (storeAgentDetails) { @@ -384,13 +459,20 @@ export class AgentServiceService { const getOrganization = await this.agentServiceRepository.getOrgDetails(orgData.id); + /** + * Create legacy connection invitation + */ await this._createLegacyConnectionInvitation(orgData.id, user, getOrganization.name); if (agentSpinupDto.clientSocketId) { socket.emit('invitation-url-creation-success', { clientId: agentSpinupDto.clientSocketId }); } } else { - throw new BadRequestException('Agent not able to spin-up'); + this.logger.error(`Agent not able to spin-up`); + throw new BadRequestException( + ResponseMessages.agent.error.notAbleToSpinup, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } } catch (error) { if (agentSpinupDto.clientSocketId) { @@ -398,6 +480,9 @@ export class AgentServiceService { } if (agentProcess && agentProcess?.id) { + /** + * If getting error remove organization agent + */ await this.agentServiceRepository.removeOrgAgent(agentProcess?.id); } this.logger.error(`[_agentSpinup] - Error in Agent spin up : ${JSON.stringify(error)}`); @@ -406,13 +491,28 @@ export class AgentServiceService { async _storeOrgAgentDetails(payload: IStoreOrgAgentDetails): Promise { try { + + /** + * Get orgaization agent type and agent details + */ const [agentDid, orgAgentTypeId] = await Promise.all([ this._getAgentDid(payload), this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.DEDICATED) ]); + /** + * Get DID method by agent + */ const getDidMethod = await this._getDidMethod(payload, agentDid); + + /** + * Organization storage data + */ const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, orgAgentTypeId); + + /** + * Store org agent details + */ const storeAgentDid = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData); return storeAgentDid; diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 32cb5e82a..f79e93184 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -292,4 +292,8 @@ interface IRequestedPredicatesName { interface IRequestedRestriction { cred_def_id: string; +} + +export interface AgentSpinupStatus { + agentSpinupStatus: number; } \ No newline at end of file diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 8d96907a0..cec9c0cc9 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -143,7 +143,7 @@ export class AgentServiceRepository { async getAgentDetails(orgId: string): Promise { try { - const x = await this.prisma.org_agents.findFirst({ + const x = await this.prisma.org_agents.findFirstOrThrow({ where: { orgId } @@ -160,7 +160,7 @@ export class AgentServiceRepository { // eslint-disable-next-line camelcase async platformAdminAgent(platformOrg: string): Promise { - const platformAdminSpinnedUp = await this.prisma.organisation.findFirst({ + const platformAdminSpinnedUp = await this.prisma.organisation.findFirstOrThrow({ where: { name: platformOrg }, @@ -180,7 +180,7 @@ export class AgentServiceRepository { // eslint-disable-next-line camelcase async getOrgAgentDetails(orgId: string): Promise { try { - const oranizationAgentDetails = await this.prisma.org_agents.findFirst({ + const oranizationAgentDetails = await this.prisma.org_agents.findFirstOrThrow({ where: { orgId } @@ -194,7 +194,7 @@ export class AgentServiceRepository { async getAgentTypeDetails(): Promise { try { - const { id } = await this.prisma.agents_type.findFirst({ + const { id } = await this.prisma.agents_type.findFirstOrThrow({ where: { agent: AgentType.AFJ } @@ -246,7 +246,7 @@ export class AgentServiceRepository { async getOrgAgentTypeDetails(agentType: string): Promise { try { - const { id } = await this.prisma.org_agents_type.findFirst({ + const { id } = await this.prisma.org_agents_type.findFirstOrThrow({ where: { agent: agentType } @@ -260,7 +260,7 @@ export class AgentServiceRepository { async getPlatfomOrg(orgName: string): Promise { try { - const { id } = await this.prisma.organisation.findFirst({ + const { id } = await this.prisma.organisation.findFirstOrThrow({ where: { name: orgName } diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index dcb33d9fb..63110e5f9 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -64,10 +64,10 @@ export class AgentController { } /** - * + * Spinup the agent by organization * @param agentSpinupDto * @param user - * @returns + * @returns Get agent status */ @Post('/orgs/:orgId/agents/spinup') @ApiOperation({ @@ -78,22 +78,30 @@ export class AgentController { @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @ApiResponse({ status: 201, description: 'Success', type: ApiResponseDto }) async agentSpinup( - @Body() agentSpinupDto: AgentSpinupDto, @Param('orgId') orgId: string, + @Body() agentSpinupDto: AgentSpinupDto, @User() user: user, @Res() res: Response - ): Promise>> { + ): Promise { if (seedLength !== agentSpinupDto.seed.length) { - throw new BadRequestException(`seed must be at most 32 characters.`); + this.logger.error(`seed must be at most 32 characters.`); + throw new BadRequestException( + ResponseMessages.agent.error.seedChar, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } const regex = new RegExp('^[a-zA-Z0-9]+$'); if (!regex.test(agentSpinupDto.walletName)) { - this.logger.error(`Wallet name in wrong format.`); - throw new BadRequestException(`Please enter valid wallet name, It allows only alphanumeric values`); + this.logger.error(`Please enter valid wallet name, It allows only alphanumeric values`); + throw new BadRequestException( + ResponseMessages.agent.error.seedChar, + { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } + ); } + this.logger.log(`**** Spin up the agent...${JSON.stringify(agentSpinupDto)}`); agentSpinupDto.orgId = orgId; diff --git a/apps/api-gateway/src/agent-service/agent-service.service.ts b/apps/api-gateway/src/agent-service/agent-service.service.ts index 2ede160b7..711be7d4f 100644 --- a/apps/api-gateway/src/agent-service/agent-service.service.ts +++ b/apps/api-gateway/src/agent-service/agent-service.service.ts @@ -13,9 +13,15 @@ export class AgentService extends BaseService { super('AgentService'); } + /** + * Spinup the agent by organization + * @param agentSpinupDto + * @param user + * @returns Get agent status + */ async agentSpinup(agentSpinupDto: AgentSpinupDto, user: user): Promise<{ response: object }> { const payload = { agentSpinupDto, user }; - return this.sendNats(this.agentServiceProxy, 'agent-spinup', payload); + return this.sendNatsMessage(this.agentServiceProxy, 'agent-spinup', payload); } async createTenant(createTenantDto: CreateTenantDto, user: user): Promise<{ response: object }> { diff --git a/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts b/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts index 4fd6f1447..a668a0025 100644 --- a/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/agent-service.dto.ts @@ -5,8 +5,6 @@ import { IsBoolean, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLen const regex = /^[a-zA-Z0-9 ]*$/; export class AgentSpinupDto { - orgId: string; - @ApiProperty() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'walletName is required' }) @@ -21,10 +19,11 @@ export class AgentSpinupDto { @ApiProperty() @Transform(({ value }) => trim(value)) + @IsString({ message: 'walletPassword must be in string format.' }) @IsNotEmpty({ message: 'Password is required.' }) walletPassword: string; - @ApiProperty() + @ApiProperty({ example: 'dfuhgfklskmjngrjekjfgjjfkoekfdad' }) @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'seed is required' }) @MaxLength(32, { message: 'seed must be at most 32 characters.' }) @@ -34,45 +33,31 @@ export class AgentSpinupDto { }) seed: string; - @ApiProperty() + @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) @IsOptional() + @ApiPropertyOptional() @IsString({ message: 'did must be in string format.' }) did?: string; - @ApiProperty({ example: [1] }) + @ApiProperty({ example: ['6ba7b810-9dad-11d1-80b4-00c04fd430c8'] }) @IsOptional() + @ApiPropertyOptional() @IsArray({ message: 'ledgerId must be an array' }) + @IsString({ each: true, message: 'Each ledgerId must be a string' }) + @MaxLength(36, { each: true, message: 'ledgerId must be at most 36 characters.' }) @IsNotEmpty({ message: 'please provide valid ledgerId' }) ledgerId?: string[]; - @ApiProperty() + @ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' }) @IsOptional() @ApiPropertyOptional() clientSocketId?: string; - @ApiProperty() + @ApiProperty({ example: true }) @IsOptional() @IsBoolean() @ApiPropertyOptional() tenant?: boolean; - @ApiProperty() - @IsOptional() - @ApiPropertyOptional() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'agentType is required' }) - @MinLength(2, { message: 'agentType must be at least 2 characters.' }) - @MaxLength(50, { message: 'agentType must be at most 50 characters.' }) - @IsString({ message: 'agentType must be in string format.' }) - agentType?: string; - - @ApiProperty() - @IsOptional() - @ApiPropertyOptional() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'transactionApproval is required' }) - @MinLength(2, { message: 'transactionApproval must be at least 2 characters.' }) - @MaxLength(50, { message: 'transactionApproval must be at most 50 characters.' }) - @IsString({ message: 'transactionApproval must be in string format.' }) - transactionApproval?: string; + orgId: string; } \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index db8744af6..23c5697a7 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -157,7 +157,18 @@ export const ResponseMessages = { alreadySpinUp: 'Agent already spin-up', agentUrl: 'Agent url not exist', agentNotExists: 'Agent not spinned up for this organization', - agentDown: 'Agent is down or not spinned up' + agentDown: 'Agent is down or not spinned up', + seedChar: 'seed must be at most 32 characters.', + validWalletName: 'Please enter valid wallet name, It allows only alphanumeric values', + walletAlreadyCreated: 'Your wallet has already been created', + walletAlreadyProcessing: 'Your wallet is already processing', + platformConfiguration: 'Platform configuration is missing or invalid', + apiEndpoint: 'API endpoint is missing in the platform configuration', + externalIp: 'External IP is missing in the platform configuration', + stringExternalIp: 'External IP must be a string', + agentProcess: 'Agent process is invalid or not in a completed state', + notAbleToSpinup: 'Agent not able to spin-up', + ledgerNotFound: 'Ledgers not found' } }, connection: { From 898fca882c2d4b22918435623014f7af93ee3034 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Tue, 26 Dec 2023 19:45:04 +0530 Subject: [PATCH 043/107] Changes in Response interface Signed-off-by: KulkarniShashank --- .../api-gateway/src/agent-service/agent-service.controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index 76d8e36c0..c9c0d916e 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -21,7 +21,7 @@ import { ApiResponseDto } from '../dtos/apiResponse.dto'; import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import { ResponseMessages } from '@credebl/common/response-messages'; import { AgentService } from './agent-service.service'; -import IResponseType from '@credebl/common/interfaces/response.interface'; +import IResponseType, { IResponse } from '@credebl/common/interfaces/response.interface'; import { AgentSpinupDto } from './dto/agent-service.dto'; import { Response } from 'express'; // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -65,7 +65,7 @@ export class AgentController { const agentData = await this.agentService.getAgentHealth(reqUser, orgId); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.agent.success.health, data: agentData From f5bf53f8f260a9dae5972e090e0171036cca509d Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Tue, 26 Dec 2023 20:04:25 +0530 Subject: [PATCH 044/107] Changes on the comment in payload on the agent-service Signed-off-by: KulkarniShashank --- apps/agent-service/src/agent-service.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 649d8a2af..2907998a2 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -975,7 +975,7 @@ export class AgentServiceService { /** * Get agent health - * @param payload + * @param orgId * @returns Get agent health */ async getAgentHealthDetails(orgId: string): Promise { From 9e0f53591a472b79d5384eb0630ed3a2db5402f9 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Tue, 26 Dec 2023 20:05:51 +0530 Subject: [PATCH 045/107] Changes on the comment in payload on the agent-service Signed-off-by: KulkarniShashank --- apps/agent-service/src/agent-service.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 2907998a2..db4791248 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -976,7 +976,7 @@ export class AgentServiceService { /** * Get agent health * @param orgId - * @returns Get agent health + * @returns Get agent status */ async getAgentHealthDetails(orgId: string): Promise { try { From 63a56c41e2fc6a1a1f031b9688c3c974381af927 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Tue, 26 Dec 2023 20:07:10 +0530 Subject: [PATCH 046/107] Changes on the comment in payload on the agent-service Signed-off-by: KulkarniShashank --- apps/agent-service/src/agent-service.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index db4791248..a1a779238 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -976,7 +976,7 @@ export class AgentServiceService { /** * Get agent health * @param orgId - * @returns Get agent status + * @returns agent status */ async getAgentHealthDetails(orgId: string): Promise { try { From e38398d6396c5683d55272cfb6c87e179fc8bb16 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Tue, 26 Dec 2023 20:16:49 +0530 Subject: [PATCH 047/107] added parameters Signed-off-by: bhavanakarwade --- apps/api-gateway/src/connection/connection.controller.ts | 3 +-- apps/connection/src/connection.controller.ts | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index e4a65c061..69841d677 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -35,10 +35,9 @@ export class ConnectionController { /** * Description: Get connection by connectionId - * @param user * @param connectionId * @param orgId - * + * @returns connection details by connection Id */ @Get('orgs/:orgId/connections/:connectionId') @UseGuards(AuthGuard('jwt'), OrgRolesGuard) diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index b3aed03fb..0b4ddf8bf 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -60,6 +60,12 @@ export class ConnectionController { return this.connectionService.getConnections(user, orgId, connectionSearchCriteria); } + /** + * + * @param connectionId + * @param orgId + * @returns connection details by connection Id + */ @MessagePattern({ cmd: 'get-all-connection-details-by-connectionId' }) async getConnectionsById(payload: IFetchConnectionById): Promise { const { user, connectionId, orgId } = payload; From e0bafda95485184b17da88caeb9d3fc2b449a539 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Tue, 26 Dec 2023 20:29:26 +0530 Subject: [PATCH 048/107] added comment for nats call Signed-off-by: bhavanakarwade --- apps/connection/src/connection.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index ff5b8bb98..6f068aa5f 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -320,6 +320,7 @@ export class ConnectionService { apiKey: string ): Promise { + //nats call in agent service const pattern = { cmd: 'agent-get-connections-by-connectionId' }; const payload = { url, apiKey }; return this.connectionServiceProxy From ef181a4c4978f16a33246e37564d463e4e6f39dc Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Tue, 26 Dec 2023 20:40:38 +0530 Subject: [PATCH 049/107] refactor:verify-user-and-send-verification-mail-api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/authz/authz.controller.ts | 11 ++++------- apps/api-gateway/src/user/user.controller.ts | 3 +-- apps/user/interfaces/user.interface.ts | 2 +- apps/user/src/user.controller.ts | 18 +++++++++++------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/api-gateway/src/authz/authz.controller.ts b/apps/api-gateway/src/authz/authz.controller.ts index cafaedfe7..7e8ff1f60 100644 --- a/apps/api-gateway/src/authz/authz.controller.ts +++ b/apps/api-gateway/src/authz/authz.controller.ts @@ -35,10 +35,9 @@ export class AuthzController { private readonly commonService: CommonService) { } /** - * - * @param query - * @param res - * @returns User email verified + * @param email + * @param verificationcode + * @returns User's email verification status */ @Get('/verify') @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @@ -55,10 +54,8 @@ export class AuthzController { } /** - * * @param email - * @param res - * @returns Email sent success + * @returns User's verification email sent status */ @Post('/verification-mail') @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index a4e05dc7a..02594d994 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -243,8 +243,7 @@ export class UserController { /** * * @param email - * @param res - * @returns User email check + * @returns User's email exist status */ @Get('/:email') @ApiOperation({ summary: 'Check user exist', description: 'check user existence' }) diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index c495c5fc1..678ed95c5 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -113,10 +113,10 @@ interface IUserOrgRole { } export interface ICheckUserDetails { + isExist: boolean; isEmailVerified?: boolean; isFidoVerified?: boolean; isSupabase?: boolean; - isExist?: boolean; } export interface UserCredentials { diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 7e9224ac9..e20d5fd62 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -16,8 +16,8 @@ export class UserController { /** * Description: Registers new user - * @param payload Registration Details - * @returns Get registered user response + * @param email + * @returns User's verification email sent status */ @MessagePattern({ cmd: 'send-verification-mail' }) async sendVerificationMail(payload: { userEmailVerification: ISendVerificationEmail }): Promise { @@ -26,8 +26,9 @@ export class UserController { /** * Description: Verify user's email - * @param param - * @returns Get user's email verified + * @param email + * @param verificationcode + * @returns User's email verification status */ @MessagePattern({ cmd: 'user-email-verification' }) async verifyEmail(payload: { param: VerifyEmailTokenDto }): Promise { @@ -111,7 +112,6 @@ export class UserController { } /** - * * @param payload * @returns organization users list */ @@ -120,9 +120,13 @@ export class UserController { const users = this.userService.get(payload.pageNumber, payload.pageSize, payload.search); return users; } - + + /** + * @param email + * @returns User's email exist status + * */ @MessagePattern({ cmd: 'check-user-exist' }) - async checkUserExist(payload: { userEmail: string }): Promise { + async checkUserExist(payload: { userEmail: string }): Promise { return this.userService.checkUserExist(payload.userEmail); } @MessagePattern({ cmd: 'add-user' }) From 75965aa763f7874e6ae1d0210084169ee535fd76 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Tue, 26 Dec 2023 20:46:01 +0530 Subject: [PATCH 050/107] refactor:verify-user-and-send-verification-mail-api Signed-off-by: pranalidhanavade --- apps/user/src/user.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 530c18cbb..3c42129f8 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -468,7 +468,6 @@ export class UserService { const invitations: OrgInvitations[] = await this.updateOrgInvitations(invitationsData['invitations']); invitationsData['invitations'] = invitations; - // console.log("{-----------------}",invitationsData); return invitationsData; } catch (error) { From 3f6f7f845638db5711cd61a84a7058e6e13bdd93 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 10:50:06 +0530 Subject: [PATCH 051/107] improved error handling for agent details Signed-off-by: bhavanakarwade --- apps/agent-service/src/agent-service.service.ts | 10 ++++++++-- apps/connection/src/connection.service.ts | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 68a25a529..661ddbe8c 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -965,14 +965,20 @@ export class AgentServiceService { try { const data = await this.commonService .httpGet(url, { headers: { 'x-api-key': apiKey } }) - .then(async response => response); + .then(async response => response) + .catch(error => { + throw new InternalServerErrorException( + ResponseMessages.agent.error.agentDown, + { cause: new Error(), description: ResponseMessages.errorMessages.serverError } + ); + }); return data; } catch (error) { this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); throw error; } - } + } /** * Get agent health diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 6f068aa5f..ca6243bf9 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -308,7 +308,6 @@ export class ConnectionService { statusCode: error?.status?.code, error: error?.response?.error?.reason }); - } else { throw new RpcException(error.response ? error.response : error); } @@ -320,7 +319,7 @@ export class ConnectionService { apiKey: string ): Promise { - //nats call in agent service + //nats call in agent service for fetch connection details const pattern = { cmd: 'agent-get-connections-by-connectionId' }; const payload = { url, apiKey }; return this.connectionServiceProxy From 39a4359ec03560504d379ae53c6ed1dbe03c3142 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 11:05:29 +0530 Subject: [PATCH 052/107] refactor interfaces Signed-off-by: bhavanakarwade --- apps/api-gateway/src/connection/connection.controller.ts | 4 ++-- apps/connection/src/connection.controller.ts | 2 +- apps/connection/src/connection.service.ts | 5 ++--- apps/connection/src/interfaces/connection.interfaces.ts | 6 +++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index d59f63e29..8556b6bfa 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -140,8 +140,8 @@ export class ConnectionController { /** * Catch connection webhook responses. * @Body connectionDto - * @param id - * @param res + * @param orgId + * @returns Callback URL for connection and created connections details */ @Post('wh/:orgId/connections/') diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 6be7c5104..d01cbff22 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -35,7 +35,7 @@ export class ConnectionController { /** * Description: Catch connection webhook responses and save details in connection table - * @param payload + * @param orgId * @returns Callback URL for connection and created connections details */ @MessagePattern({ cmd: 'webhook-get-connection' }) diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 029726ed1..aed1e76af 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -109,10 +109,9 @@ export class ConnectionService { } /** - * Description: create connection legacy invitation + * Description: Catch connection webhook responses and save details in connection table * @param orgId - * @param user - * @returns Connection legacy invitation URL + * @returns Callback URL for connection and created connections details */ async getConnectionWebhook(payload: ICreateConnection): Promise { try { diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 74209f2c0..f26a5e5e6 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -51,12 +51,12 @@ export interface IOrgAgentInterface { orgId: string; } -export class ICreateConnection { +export interface ICreateConnection { connectionDto: ICreateConnectionPayload; orgId: string; } -export class ICreateConnectionPayload { +export interface ICreateConnectionPayload { createDateTime: string; lastChangedDateTime: string; id: string; @@ -69,7 +69,7 @@ export class ICreateConnectionPayload { contextCorrelationId: string; } -export class IFetchConnections { +export interface IFetchConnections { connectionSearchCriteria: IConnectionSearchCriteria; user: IUserRequest; orgId: string; From f96de9eeb6d60d7182d5273ac1b222e6fd36f7f8 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Wed, 27 Dec 2023 11:15:58 +0530 Subject: [PATCH 053/107] resolved:comments on code Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 2 +- apps/user/repositories/user.repository.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 02594d994..6d7a69dd5 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -246,7 +246,7 @@ export class UserController { * @returns User's email exist status */ @Get('/:email') - @ApiOperation({ summary: 'Check user exist', description: 'check user existence' }) + @ApiOperation({ summary: 'Check if user exist', description: 'check user existence' }) async checkUserExist(@Param() emailParam: EmailValidator, @Res() res: Response): Promise { const userDetails = await this.userService.checkUserExist(emailParam.email); diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index 59c406882..6dbb300cd 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -34,7 +34,7 @@ export class UserRepository { /** * * @param userEmailVerification - * @returns user email + * @returns user's email */ async createUser(userEmailVerification:ISendVerificationEmail, verifyCode: string): Promise { try { From 8a6726230ba3bc994cfacec34ec34d176261cb5f Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 11:48:44 +0530 Subject: [PATCH 054/107] removed unwanted fields Signed-off-by: bhavanakarwade --- .../api-gateway/src/interfaces/ISchemaSearch.interface.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts index ae868cc68..a9033cc2d 100644 --- a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts @@ -9,14 +9,6 @@ export interface ISchemaSearchPayload { searchByText?: string; user?: IUserRequestInterface } -export interface IConnectionSearchinterface { - pageNumber: number; - pageSize: number; - sorting: string; - sortByValue: string; - searchByText: string; - user?: IUserRequestInterface -} export interface IConnectionDetailsById { id: string; createdAt: string; From 9bdf0ec841b7c2012938e845edf6677a33a44d1b Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Wed, 27 Dec 2023 12:18:56 +0530 Subject: [PATCH 055/107] Changes and solved the issue for the get org agent details related function Signed-off-by: KulkarniShashank --- .../repositories/agent-service.repository.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index ea8ceffa1..c80e38c00 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -294,4 +294,24 @@ export class AgentServiceRepository { throw error; } } + + /** + * Get agent details + * @param orgId + * @returns Agent health details + */ + // eslint-disable-next-line camelcase + async getOrgAgentDetails(orgId: string): Promise { + try { + const oranizationAgentDetails = await this.prisma.org_agents.findFirstOrThrow({ + where: { + orgId + } + }); + return oranizationAgentDetails; + } catch (error) { + this.logger.error(`[getOrgAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); + throw error; + } + } } \ No newline at end of file From 005a0fb11b0c12766e764574a71270d5a15bd653 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 17:05:34 +0530 Subject: [PATCH 056/107] improve error handling for agent Signed-off-by: bhavanakarwade --- .../src/agent-service.controller.ts | 4 ++-- .../src/agent-service.service.ts | 21 ++++++++++++------- .../src/connection/connection.controller.ts | 2 +- .../src/connection/connection.service.ts | 2 +- apps/connection/src/connection.controller.ts | 2 +- apps/connection/src/connection.service.ts | 4 ++-- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 5e1ee41cc..4dbdddcc1 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -89,8 +89,8 @@ export class AgentServiceController { async getConnections(payload: { url: string, apiKey: string }): Promise { return this.agentServiceService.getConnections(payload.url, payload.apiKey); } - - @MessagePattern({ cmd: 'agent-get-connections-by-connectionId' }) + + @MessagePattern({ cmd: 'agent-get-connection-details-by-connectionId' }) async getConnectionsByconnectionId(payload: { url: string, apiKey: string }): Promise { return this.agentServiceService.getConnectionsByconnectionId(payload.url, payload.apiKey); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 661ddbe8c..5d964d8f9 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -962,22 +962,29 @@ export class AgentServiceService { } async getConnectionsByconnectionId(url: string, apiKey: string): Promise { + try { const data = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) - .then(async response => response) - .catch(error => { + .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .then(async response => response) + .catch(error => { + this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); + + if (error && Object.keys(error).length === 0) { throw new InternalServerErrorException( ResponseMessages.agent.error.agentDown, { cause: new Error(), description: ResponseMessages.errorMessages.serverError } ); - }); - return data; - + } else { + throw error; + } + }); + return data; } catch (error) { this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); - throw error; + throw new RpcException(error.response ? error.response : error); } + } /** diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 69841d677..817ee0297 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -34,7 +34,7 @@ export class ConnectionController { ) { } /** - * Description: Get connection by connectionId + * Get connection details by connectionId * @param connectionId * @param orgId * @returns connection details by connection Id diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 28c2c1db9..9e990161a 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -73,6 +73,6 @@ export class ConnectionService extends BaseService { orgId: string ): Promise { const payload = { user, connectionId, orgId }; - return this.sendNatsMessage(this.connectionServiceProxy, 'get-all-connection-details-by-connectionId', payload); + return this.sendNatsMessage(this.connectionServiceProxy, 'get-connection-details-by-connectionId', payload); } } diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 0b4ddf8bf..731f853eb 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -66,7 +66,7 @@ export class ConnectionController { * @param orgId * @returns connection details by connection Id */ - @MessagePattern({ cmd: 'get-all-connection-details-by-connectionId' }) + @MessagePattern({ cmd: 'get-connection-details-by-connectionId' }) async getConnectionsById(payload: IFetchConnectionById): Promise { const { user, connectionId, orgId } = payload; return this.connectionService.getConnectionsById(user, connectionId, orgId); diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index ca6243bf9..03b7d8a8f 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -305,7 +305,7 @@ export class ConnectionService { if (error?.response?.error?.reason) { throw new RpcException({ message: ResponseMessages.connection.error.connectionNotFound, - statusCode: error?.status?.code, + statusCode: error?.response?.status, error: error?.response?.error?.reason }); } else { @@ -320,7 +320,7 @@ export class ConnectionService { ): Promise { //nats call in agent service for fetch connection details - const pattern = { cmd: 'agent-get-connections-by-connectionId' }; + const pattern = { cmd: 'agent-get-connection-details-by-connectionId' }; const payload = { url, apiKey }; return this.connectionServiceProxy .send(pattern, payload) From 075b4172ffa79f691043175e7e9e08a858d669da Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 17:31:39 +0530 Subject: [PATCH 057/107] optimized data Signed-off-by: bhavanakarwade --- .../agent-service/src/agent-service.controller.ts | 2 +- apps/agent-service/src/agent-service.service.ts | 2 +- .../src/connection/connection.service.ts | 3 +-- .../src/interfaces/IConnectionSearch.interface.ts | 15 +++++++++++++++ .../src/interfaces/ISchemaSearch.interface.ts | 14 -------------- apps/connection/src/connection.controller.ts | 2 +- apps/connection/src/connection.service.ts | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 4dbdddcc1..54691e990 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -5,7 +5,7 @@ import { AgentStatus, GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAg import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; -import { IConnectionDetailsById } from 'apps/connection/src/interfaces/connection.interfaces'; +import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Controller() export class AgentServiceController { diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 5d964d8f9..7777d7e0f 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -31,7 +31,7 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { Socket, io } from 'socket.io-client'; import { WebSocketGateway } from '@nestjs/websockets'; import * as retry from 'async-retry'; -import { IConnectionDetailsById } from 'apps/connection/src/interfaces/connection.interfaces'; +import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Injectable() @WebSocketGateway() diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index bbad30941..e58d30901 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -4,9 +4,8 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { ConnectionDto, CreateConnectionDto } from './dtos/connection.dto'; import { IUserRequestInterface } from './interfaces'; -import { IConnectionDetailsById } from '../interfaces/ISchemaSearch.interface'; import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; -import { IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; +import { IConnectionDetailsById, IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; @Injectable() export class ConnectionService extends BaseService { diff --git a/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts b/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts index 25b90d897..35d79949d 100644 --- a/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts @@ -8,3 +8,18 @@ export interface IConnectionSearchCriteria { searchByText: string; user?: IUserRequestInterface } + +export interface IConnectionDetailsById { + id: string; + createdAt: string; + did: string; + theirDid: string; + theirLabel: string; + state: string; + role: string; + autoAcceptConnection: boolean; + threadId: string; + protocol: string; + outOfBandId: string; + updatedAt: string; + } diff --git a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts index a9033cc2d..2f83d26cb 100644 --- a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts @@ -9,18 +9,4 @@ export interface ISchemaSearchPayload { searchByText?: string; user?: IUserRequestInterface } -export interface IConnectionDetailsById { - id: string; - createdAt: string; - did: string; - theirDid: string; - theirLabel: string; - state: string; - role: string; - autoAcceptConnection: boolean; - threadId: string; - protocol: string; - outOfBandId: string; - updatedAt: string; - } diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 82a2d44cd..a133c179d 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -3,12 +3,12 @@ import { ConnectionService } from './connection.service'; // Import the common s import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package import { IConnection, - IConnectionDetailsById, ICreateConnection, IFetchConnectionById, IFetchConnections } from './interfaces/connection.interfaces'; import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Controller() export class ConnectionController { diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 853d05baf..053d3b928 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -6,7 +6,6 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs'; import { ConnectionInvitationResponse, - IConnectionDetailsById, IConnectionSearchCriteria, ICreateConnection, IUserRequestInterface @@ -17,6 +16,7 @@ import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { OrgAgentType } from '@credebl/enum/enum'; import { platform_config } from '@prisma/client'; import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Injectable() export class ConnectionService { From 2f6daa83fd4062c291712c07e4ab6100552db4bd Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 17:36:53 +0530 Subject: [PATCH 058/107] refactored response Signed-off-by: bhavanakarwade --- .../src/interfaces/connection.interfaces.ts | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 5ea321aad..8ed016e4a 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -115,18 +115,4 @@ export interface IConnectionSearchCriteria { sortBy: string; searchByText: string; user: IUserRequestInterface -} -export interface IConnectionDetailsById { - id: string; - createdAt: string; - did: string; - theirDid: string; - theirLabel: string; - state: string; - role: string; - autoAcceptConnection: boolean; - threadId: string; - protocol: string; - outOfBandId: string; - updatedAt: string; -} +} \ No newline at end of file From c660e2965e82d8560bf90a0ec2925321367a63ba Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Wed, 27 Dec 2023 17:51:20 +0530 Subject: [PATCH 059/107] Solved the conflicts as per comment Signed-off-by: KulkarniShashank --- .../src/agent-service.controller.ts | 12 +- .../src/agent-service.service.ts | 114 ++++++++++------ .../src/interface/agent-service.interface.ts | 85 +++++++----- .../repositories/agent-service.repository.ts | 123 ++++++++++-------- .../agent-service/agent-service.controller.ts | 2 +- .../agent-service/agent-service.service.ts | 2 + libs/common/src/response-messages/index.ts | 2 +- .../migration.sql | 8 ++ libs/prisma-service/prisma/schema.prisma | 2 +- 9 files changed, 215 insertions(+), 135 deletions(-) create mode 100644 libs/prisma-service/prisma/migrations/20231227105815_org_id_unique_org_agent/migration.sql diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index b7671d913..d7d9552e7 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -1,7 +1,7 @@ import { Controller } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; import { AgentServiceService } from './agent-service.service'; -import { AgentStatus, AgentSpinUpSatus, GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAgentSpinupDto, IIssuanceCreateOffer, ITenantCredDef, ITenantDto, ITenantSchema, OutOfBandCredentialOffer } from './interface/agent-service.interface'; +import { IAgentStatus, IAgentSpinUpSatus, IGetCredDefAgentRedirection, IGetSchemaAgentRedirection, IAgentSpinupDto, IIssuanceCreateOffer, ITenantCredDef, ITenantDto, ITenantSchema, IOutOfBandCredentialOffer } from './interface/agent-service.interface'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; @@ -16,7 +16,7 @@ export class AgentServiceController { } @MessagePattern({ cmd: 'create-tenant' }) - async createTenant(payload: { createTenantDto: ITenantDto, user: IUserRequestInterface }): Promise { + async createTenant(payload: { createTenantDto: ITenantDto, user: IUserRequestInterface }): Promise { return this.agentServiceService.createTenant(payload.createTenantDto, payload.user); } @@ -26,7 +26,7 @@ export class AgentServiceController { } @MessagePattern({ cmd: 'agent-get-schema' }) - async getSchemaById(payload: GetSchemaAgentRedirection): Promise { + async getSchemaById(payload: IGetSchemaAgentRedirection): Promise { return this.agentServiceService.getSchemaById(payload); } @@ -37,7 +37,7 @@ export class AgentServiceController { } @MessagePattern({ cmd: 'agent-get-credential-definition' }) - async getCredentialDefinitionById(payload: GetCredDefAgentRedirection): Promise { + async getCredentialDefinitionById(payload: IGetCredDefAgentRedirection): Promise { return this.agentServiceService.getCredentialDefinitionById(payload); } @@ -98,7 +98,7 @@ export class AgentServiceController { * @returns Get agent health */ @MessagePattern({ cmd: 'agent-health' }) - async getAgentHealth(payload: { user: user, orgId: string }): Promise { + async getAgentHealth(payload: { user: user, orgId: string }): Promise { return this.agentServiceService.getAgentHealthDetails(payload.orgId); } @@ -132,7 +132,7 @@ export class AgentServiceController { } @MessagePattern({ cmd: 'agent-out-of-band-credential-offer' }) - async outOfBandCredentialOffer(payload: { outOfBandIssuancePayload: OutOfBandCredentialOffer, url: string, apiKey: string }): Promise { + async outOfBandCredentialOffer(payload: { outOfBandIssuancePayload: IOutOfBandCredentialOffer, url: string, apiKey: string }): Promise { return this.agentServiceService.outOfBandCredentialOffer(payload.outOfBandIssuancePayload, payload.url, payload.apiKey); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 207f8f270..ea7bff0b2 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -6,6 +6,7 @@ /* eslint-disable camelcase */ import { BadRequestException, + ConflictException, HttpException, Inject, Injectable, @@ -18,7 +19,7 @@ import * as dotenv from 'dotenv'; import * as fs from 'fs'; import { catchError, map } from 'rxjs/operators'; dotenv.config(); -import { GetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, OutOfBandCredentialOffer, AgentSpinUpSatus, CreateTenant, AgentStatus } from './interface/agent-service.interface'; +import { IGetCredDefAgentRedirection, IAgentSpinupDto, IStoreOrgAgentDetails, ITenantCredDef, ITenantDto, ITenantSchema, IWalletProvision, ISendProofRequestPayload, IIssuanceCreateOffer, IOutOfBandCredentialOffer, IAgentSpinUpSatus, ICreateTenant, IAgentStatus, ICreateOrgAgent, IOrgAgentsResponse } from './interface/agent-service.interface'; import { AgentSpinUpStatus, AgentType, Ledgers, OrgAgentType } from '@credebl/enum/enum'; import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { AgentServiceRepository } from './repositories/agent-service.repository'; @@ -146,16 +147,16 @@ export class AgentServiceService { private async processWalletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise { let platformAdminUser; let userId: string; - let agentProcess: org_agents; + let agentProcess: ICreateOrgAgent; + let getOrgAgent; try { - const [getOrgAgent, platformConfig, getAgentType, ledgerIdData, orgData] = await Promise.all([ - this.agentServiceRepository.getAgentDetails(agentSpinupDto.orgId), + const [platformConfig, getAgentType, ledgerIdData] = await Promise.all([ this.agentServiceRepository.getPlatformConfigDetails(), this.agentServiceRepository.getAgentTypeDetails(), - this.agentServiceRepository.getLedgerDetails(agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]), - this.agentServiceRepository.getOrgDetails(agentSpinupDto.orgId) + this.agentServiceRepository.getLedgerDetails(agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]) ]); + let orgData; if (!user?.userId && agentSpinupDto?.platformAdminEmail) { platformAdminUser = await this.agentServiceRepository.getPlatfomAdminUser(agentSpinupDto?.platformAdminEmail); @@ -165,7 +166,16 @@ export class AgentServiceService { userId = user?.userId; } - agentSpinupDto.ledgerId = agentSpinupDto.ledgerId?.length ? agentSpinupDto.ledgerId : ledgerIdData.map(ledger => ledger.id); + const platformAdminOrgDetails = await this.agentServiceRepository.getPlatfomOrg(agentSpinupDto?.orgName); + if (agentSpinupDto.orgId) { + getOrgAgent = await this.agentServiceRepository.getAgentDetails(agentSpinupDto.orgId); + orgData = await this.agentServiceRepository.getOrgDetails(agentSpinupDto.orgId); + } else { + getOrgAgent = await this.agentServiceRepository.getAgentDetails(platformAdminOrgDetails); + orgData = await this.agentServiceRepository.getOrgDetails(platformAdminOrgDetails); + } + + agentSpinupDto.ledgerId = agentSpinupDto.ledgerId?.length ? agentSpinupDto.ledgerId : ledgerIdData.map(ledger => ledger?.id); const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { @@ -176,8 +186,8 @@ export class AgentServiceService { throw new BadRequestException('Your wallet is already processing.'); } + if (!agentSpinupDto.orgId) { - const platformAdminOrgDetails = await this.agentServiceRepository.getPlatfomOrg(agentSpinupDto?.orgName); if (platformAdminOrgDetails) { agentSpinupDto.orgId = platformAdminOrgDetails; @@ -229,7 +239,7 @@ export class AgentServiceService { } } - validateAgentProcess(agentProcess: org_agents): void { + validateAgentProcess(agentProcess: ICreateOrgAgent): void { try { if (!agentProcess) { throw new BadRequestException('Agent process is invalid or not in a completed state.'); @@ -272,11 +282,11 @@ export class AgentServiceService { const escapedJsonString = JSON.stringify(ledgerArray).replace(/"/g, '\\"'); const walletProvisionPayload: IWalletProvision = { - orgId: orgData.id, + orgId: orgData?.id, externalIp, - walletName: agentSpinupDto.walletName, - walletPassword: agentSpinupDto.walletPassword, - seed: agentSpinupDto.seed, + walletName: agentSpinupDto?.walletName, + walletPassword: agentSpinupDto?.walletPassword, + seed: agentSpinupDto?.seed, webhookEndpoint: apiEndpoint, walletStorageHost: process.env.WALLET_STORAGE_HOST || '', walletStoragePort: process.env.WALLET_STORAGE_PORT || '', @@ -285,7 +295,7 @@ export class AgentServiceService { internalIp: await this._validateInternalIp(platformConfig, controllerIp), containerName: orgData.name.split(' ').join('_'), agentType: AgentType.AFJ, - orgName: orgData.name, + orgName: orgData?.name, indyLedger: escapedJsonString, afjVersion: process.env.AFJ_VERSION || '', protocol: process.env.AGENT_PROTOCOL || '', @@ -307,7 +317,7 @@ export class AgentServiceService { return socket; } - async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus, userId: string): Promise { + async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus, userId: string): Promise { try { const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, userId); this.logger.log(`Organization agent created with status: ${agentSpinUpStatus}`); @@ -319,7 +329,7 @@ export class AgentServiceService { } } - private async handleErrorOnWalletProvision(agentSpinupDto: IAgentSpinupDto, error: Error, agentProcess: org_agents): Promise { + private async handleErrorOnWalletProvision(agentSpinupDto: IAgentSpinupDto, error: Error, agentProcess: ICreateOrgAgent): Promise { if (agentProcess) { const socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); @@ -342,7 +352,7 @@ export class AgentServiceService { } } - async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: org_agents): Promise { + async _agentSpinup(walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, ledgerId: string[], agentProcess: ICreateOrgAgent): Promise { try { const walletProvision = await this._walletProvision(walletProvisionPayload); @@ -372,7 +382,7 @@ export class AgentServiceService { clientSocketId: agentSpinupDto.clientSocketId, ledgerId, did: agentSpinupDto.did, - id: agentProcess.id + id: agentProcess?.id }; const storeAgentDetails = await this._storeOrgAgentDetails(agentPayload); @@ -382,9 +392,9 @@ export class AgentServiceService { socket.emit('did-publish-process-completed', { clientId: agentSpinupDto.clientSocketId }); } - const getOrganization = await this.agentServiceRepository.getOrgDetails(orgData.id); + const getOrganization = await this.agentServiceRepository.getOrgDetails(orgData?.id); - await this._createLegacyConnectionInvitation(orgData.id, user, getOrganization.name); + await this._createLegacyConnectionInvitation(orgData?.id, user, getOrganization.name); if (agentSpinupDto.clientSocketId) { socket.emit('invitation-url-creation-success', { clientId: agentSpinupDto.clientSocketId }); @@ -449,7 +459,7 @@ export class AgentServiceService { agentId: payload.agentId, orgAgentTypeId, ledgerId: payload.ledgerId, - id: payload.id + id: payload?.id }; } @@ -556,15 +566,38 @@ export class AgentServiceService { * @param user * @returns Get agent status */ - async createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { + async createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { + try { - const agentStatusResponse = { - agentSpinupStatus: AgentSpinUpStatus.PROCESSED - }; + const agentStatusResponse = { + agentSpinupStatus: AgentSpinUpStatus.PROCESSED + }; + + const getOrgAgent = await this.agentServiceRepository.getAgentDetails(payload.orgId); + + if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { + this.logger.error(`Your wallet has already been created.`); + throw new ConflictException( + ResponseMessages.agent.error.walletAlreadyCreated, + { cause: new Error(), description: ResponseMessages.errorMessages.conflict } + ); + } + + if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { + this.logger.error(`Your wallet has already processing.`); + throw new ConflictException( + ResponseMessages.agent.error.walletAlreadyProcessing, + { cause: new Error(), description: ResponseMessages.errorMessages.conflict } + ); + } - // Create tenant - this._createTenant(payload, user); - return agentStatusResponse; + // Create tenant + this._createTenant(payload, user); + return agentStatusResponse; + } catch (error) { + this.logger.error(`error in create tenant : ${JSON.stringify(error)}`); + throw new RpcException(error.response ? error.response : error); + } } /** @@ -573,7 +606,7 @@ export class AgentServiceService { * @param user * @returns Get agent status */ - async _createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { + async _createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { let agentProcess; try { @@ -599,13 +632,13 @@ export class AgentServiceService { // Get ledgers details const ledgerIdData = await this.agentServiceRepository.getLedgerDetails(Ledgers.Indicio_Demonet); - const ledgerIds = ledgerIdData.map(ledger => ledger.id); + const ledgerIds = ledgerIdData.map(ledger => ledger?.id); payload.ledgerId = !payload.ledgerId || 0 === payload.ledgerId?.length ? ledgerIds : payload.ledgerId; const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; // Create and stored agent details - agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user.id); + agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user?.id); // Get platform admin details const platformAdminSpinnedUp = await this.getPlatformAdminAndNotify(payload.clientSocketId); @@ -644,14 +677,14 @@ export class AgentServiceService { tenantId: tenantDetails['tenantRecord']['id'], walletName: payload.label, ledgerId: payload.ledgerId, - id: agentProcess.id + id: agentProcess?.id }; // Get organization data const getOrganization = await this.agentServiceRepository.getOrgDetails(payload.orgId); this.notifyClientSocket('agent-spinup-process-completed', payload.clientSocketId); - const saveTenant = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData); + await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData); this.notifyClientSocket('invitation-url-creation-started', payload.clientSocketId); @@ -659,8 +692,6 @@ export class AgentServiceService { this._createLegacyConnectionInvitation(payload.orgId, user, getOrganization.name); this.notifyClientSocket('invitation-url-creation-success', payload.clientSocketId); - - return saveTenant; } } catch (error) { this.handleError(error, payload.clientSocketId); @@ -668,12 +699,11 @@ export class AgentServiceService { if (agentProcess && agentProcess?.id) { this.agentServiceRepository.removeOrgAgent(agentProcess?.id); } - - throw new RpcException(error.response ? error.response : error); + throw error; } } - private async getPlatformAdminAndNotify(clientSocketId: string | undefined): Promise { + private async getPlatformAdminAndNotify(clientSocketId: string | undefined): Promise { const socket = await this.createSocketInstance(); if (clientSocketId) { socket.emit('agent-spinup-process-initiated', { clientId: clientSocketId }); @@ -699,7 +729,7 @@ export class AgentServiceService { * @param platformAdminSpinnedUp * @returns Get tanant status */ - private async createTenantAndNotify(payload: ITenantDto, ledgerIds: ledgers, platformAdminSpinnedUp: organisation & { org_agents: org_agents[] }): Promise { + private async createTenantAndNotify(payload: ITenantDto, ledgerIds: ledgers, platformAdminSpinnedUp: IOrgAgentsResponse): Promise { const socket = await this.createSocketInstance(); if (payload.clientSocketId) { socket.emit('agent-spinup-process-initiated', { clientId: payload.clientSocketId }); @@ -873,7 +903,7 @@ export class AgentServiceService { } } - async getCredentialDefinitionById(payload: GetCredDefAgentRedirection): Promise { + async getCredentialDefinitionById(payload: IGetCredDefAgentRedirection): Promise { try { let credDefResponse; @@ -1027,7 +1057,7 @@ export class AgentServiceService { * @param orgId * @returns agent status */ - async getAgentHealthDetails(orgId: string): Promise { + async getAgentHealthDetails(orgId: string): Promise { try { // Get organization agent details @@ -1135,7 +1165,7 @@ export class AgentServiceService { } } - async outOfBandCredentialOffer(outOfBandIssuancePayload: OutOfBandCredentialOffer, url: string, apiKey: string): Promise { + async outOfBandCredentialOffer(outOfBandIssuancePayload: IOutOfBandCredentialOffer, url: string, apiKey: string): Promise { try { const sendOutOfbandCredentialOffer = await this.commonService .httpPost(url, outOfBandIssuancePayload, { headers: { 'x-api-key': apiKey } }) diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 591ad7e36..358d3083c 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -17,9 +17,9 @@ export interface IAgentSpinupDto { platformAdminEmail?: string; } -export interface OutOfBandCredentialOffer { +export interface IOutOfBandCredentialOffer { emailId: string; - attributes: Attributes[]; + attributes: IAttributes[]; credentialDefinitionId: string; comment: string; protocolVersion?: string; @@ -57,17 +57,17 @@ export interface ITenantSchemaDto { issuerId: string; } -export interface GetSchemaAgentRedirection { +export interface IGetSchemaAgentRedirection { schemaId?: string; tenantId?: string; - payload?: GetSchemaFromTenantPayload; + payload?: IGetSchemaFromTenantPayload; apiKey?: string; agentEndPoint?: string; agentType?: string; method?: string; } -export interface GetSchemaFromTenantPayload { +export interface IGetSchemaFromTenantPayload { schemaId: string; } @@ -89,17 +89,17 @@ export interface ITenantCredDefDto { issuerId: string; } -export interface GetCredDefAgentRedirection { +export interface IGetCredDefAgentRedirection { credentialDefinitionId?: string; tenantId?: string; - payload?: GetCredDefFromTenantPayload; + payload?: IGetCredDefFromTenantPayload; apiKey?: string; agentEndPoint?: string; agentType?: string; method?: string; } -export interface GetCredDefFromTenantPayload { +export interface IGetCredDefFromTenantPayload { credentialDefinitionId: string; } @@ -220,17 +220,17 @@ export interface ITenantCredDefDto { issuerId: string; } -export interface GetCredDefAgentRedirection { +export interface IGetCredDefAgentRedirection { credentialDefinitionId?: string; tenantId?: string; - payload?: GetCredDefFromTenantPayload; + payload?: IGetCredDefFromTenantPayload; apiKey?: string; agentEndPoint?: string; agentType?: string; method?: string; } -export interface GetCredDefFromTenantPayload { +export interface IGetCredDefFromTenantPayload { credentialDefinitionId: string; } @@ -247,10 +247,10 @@ export interface ICredentialFormats { } export interface IIndy { - attributes: Attributes[]; + attributes: IAttributes[]; } -export interface Attributes { +export interface IAttributes { name: string; value: string; } @@ -261,7 +261,7 @@ export interface ISendProofRequestPayload { autoAcceptProof: string; } -export interface AgentStatus { +export interface IAgentStatus { label: string; endpoints: string[]; isInitialized: boolean; @@ -300,33 +300,58 @@ interface IRequestedRestriction { cred_def_id: string; } -export interface AgentSpinUpSatus { +export interface IAgentSpinUpSatus { agentSpinupStatus: number; } -interface WalletConfig { +interface IWalletConfig { id: string; key: string; keyDerivationMethod: string; - } - - interface Config { +} + +interface IConfig { label: string; - walletConfig: WalletConfig; - } - - interface TenantRecord { + walletConfig: IWalletConfig; +} + +interface ITenantRecord { _tags: string; metadata: string; id: string; createdAt: string; - config: Config; + config: IConfig; updatedAt: string; - } - - export interface CreateTenant { - tenantRecord: TenantRecord; +} + +export interface ICreateTenant { + tenantRecord: ITenantRecord; did: string; verkey: string; - } - +} + +export interface IOrgAgent { + agentSpinUpStatus: number; +} + +export interface IOrgLedgers { + id: string; +} + +export interface ICreateOrgAgent { + id: string; +} + +interface IOrgAgentEndPoint { + agentSpinUpStatus: number; + agentEndPoint: string +} + +export interface IOrgAgentsResponse { + org_agents: IOrgAgentEndPoint[]; +} + + +export interface IStoreAgent { + id: string; +} \ No newline at end of file diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index c80e38c00..11b124c96 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -1,8 +1,8 @@ import { PrismaService } from '@credebl/prisma-service'; import { Injectable, Logger } from '@nestjs/common'; // eslint-disable-next-line camelcase -import { Prisma, ledgers, org_agents, organisation, platform_config, user } from '@prisma/client'; -import { IStoreOrgAgentDetails } from '../interface/agent-service.interface'; +import { ledgers, org_agents, organisation, platform_config, user } from '@prisma/client'; +import { ICreateOrgAgent, IStoreOrgAgentDetails, IOrgAgent, IOrgAgentsResponse, IOrgLedgers, IStoreAgent } from '../interface/agent-service.interface'; import { AgentType } from '@credebl/enum/enum'; @Injectable() @@ -56,12 +56,14 @@ export class AgentServiceRepository { async getOrgDetails(id: string): Promise { try { - const oranizationDetails = await this.prisma.organisation.findFirstOrThrow({ - where: { - id - } - }); - return oranizationDetails; + if (id) { + const oranizationDetails = await this.prisma.organisation.findUnique({ + where: { + id + } + }); + return oranizationDetails; + } } catch (error) { this.logger.error(`[getOrgDetails] - get organization details: ${JSON.stringify(error)}`); throw error; @@ -69,7 +71,7 @@ export class AgentServiceRepository { } // eslint-disable-next-line camelcase - async createOrgAgent(agentSpinUpStatus: number, userId: string): Promise { + async createOrgAgent(agentSpinUpStatus: number, userId: string): Promise { try { return this.prisma.org_agents.create({ @@ -77,6 +79,9 @@ export class AgentServiceRepository { agentSpinUpStatus, createdBy: userId, lastChangedBy: userId + }, + select: { + id: true } }); } catch (error) { @@ -86,14 +91,16 @@ export class AgentServiceRepository { } // eslint-disable-next-line camelcase - async removeOrgAgent(id: string): Promise { + async removeOrgAgent(id: string): Promise { try { + if (id) { - return this.prisma.org_agents.delete({ - where: { - id - } - }); + await this.prisma.org_agents.delete({ + where: { + id + } + }); + } } catch (error) { this.logger.error(`[removeOrgAgent] - remove org agent details: ${JSON.stringify(error)}`); throw error; @@ -106,7 +113,7 @@ export class AgentServiceRepository { * @returns */ // eslint-disable-next-line camelcase - async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { + async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { try { return this.prisma.org_agents.update({ @@ -126,6 +133,9 @@ export class AgentServiceRepository { orgAgentTypeId: storeOrgAgentDetails.orgAgentTypeId ? storeOrgAgentDetails.orgAgentTypeId : null, tenantId: storeOrgAgentDetails.tenantId ? storeOrgAgentDetails.tenantId : null, ledgerId: storeOrgAgentDetails.ledgerId[0] + }, + select: { + id: true } }); } catch (error) { @@ -140,16 +150,20 @@ export class AgentServiceRepository { * @returns */ // eslint-disable-next-line camelcase - async getAgentDetails(orgId: string): Promise { + async getAgentDetails(orgId: string): Promise { try { - const orgAgentDataByOrgId = await this.prisma.org_agents.findFirstOrThrow({ - where: { - orgId - } - }); + if (orgId) { - return orgAgentDataByOrgId; + return this.prisma.org_agents.findUnique({ + where: { + orgId + }, + select: { + agentSpinUpStatus: true + } + }); + } } catch (error) { @@ -159,17 +173,21 @@ export class AgentServiceRepository { } // eslint-disable-next-line camelcase - async platformAdminAgent(platformOrg: string): Promise { - const platformAdminSpinnedUp = await this.prisma.organisation.findFirstOrThrow({ + async platformAdminAgent(platformOrg: string): Promise { + return this.prisma.organisation.findFirstOrThrow({ where: { name: platformOrg }, - include: { + select: { // eslint-disable-next-line camelcase - org_agents: true + org_agents: { + select: { + agentSpinUpStatus: true, + agentEndPoint: true + } + } } }); - return platformAdminSpinnedUp; } @@ -187,19 +205,7 @@ export class AgentServiceRepository { } } - async getLedgerDetails(name: string[] | string): Promise<{ - id: string; - createDateTime: Date; - lastChangedDateTime: Date; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - registerDIDEndpoint: string; - registerDIDPayload: Prisma.JsonValue; - indyNamespace: string; - }[]> { + async getLedgerDetails(name: string[] | string): Promise { try { let whereClause; @@ -216,7 +222,10 @@ export class AgentServiceRepository { } const ledgersDetails = await this.prisma.ledgers.findMany({ - where: whereClause + where: whereClause, + select: { + id: true + } }); return ledgersDetails; } catch (error) { @@ -269,12 +278,15 @@ export class AgentServiceRepository { async getAgentType(id: string): Promise { try { - const { agent } = await this.prisma.agents_type.findUnique({ - where: { - id - } - }); - return agent; + if (id) { + + const { agent } = await this.prisma.agents_type.findUnique({ + where: { + id + } + }); + return agent; + } } catch (error) { this.logger.error(`[getAgentType] - get agent type details: ${JSON.stringify(error)}`); throw error; @@ -303,12 +315,15 @@ export class AgentServiceRepository { // eslint-disable-next-line camelcase async getOrgAgentDetails(orgId: string): Promise { try { - const oranizationAgentDetails = await this.prisma.org_agents.findFirstOrThrow({ - where: { - orgId - } - }); - return oranizationAgentDetails; + if (orgId) { + + const oranizationAgentDetails = await this.prisma.org_agents.findUnique({ + where: { + orgId + } + }); + return oranizationAgentDetails; + } } catch (error) { this.logger.error(`[getOrgAgentDetails] - get org agent health details: ${JSON.stringify(error)}`); throw error; diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index 916c05dd6..d68b2e326 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -156,7 +156,7 @@ export class AgentController { const tenantDetails = await this.agentService.createTenant(createTenantDto, user); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, data: tenantDetails diff --git a/apps/api-gateway/src/agent-service/agent-service.service.ts b/apps/api-gateway/src/agent-service/agent-service.service.ts index 9ab62bfff..c36cee8d8 100644 --- a/apps/api-gateway/src/agent-service/agent-service.service.ts +++ b/apps/api-gateway/src/agent-service/agent-service.service.ts @@ -22,6 +22,8 @@ export class AgentService extends BaseService { async createTenant(createTenantDto: CreateTenantDto, user: user): Promise { const payload = { createTenantDto, user }; + + // NATS call return this.sendNatsMessage(this.agentServiceProxy, 'create-tenant', payload); } diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index d715f906a..17f58bc7c 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -165,7 +165,7 @@ export const ResponseMessages = { walletAlreadyProcessing: 'Your wallet has already processing', notAbleToSpinp: 'Agent not able to spin-up', platformAdminNotAbleToSpinp: 'Platform-admin agent is not spun-up', - seedCharCount: 'seed must be at most 32 characters', + seedCharCount: 'seed must be at most 32 characters' } }, connection: { diff --git a/libs/prisma-service/prisma/migrations/20231227105815_org_id_unique_org_agent/migration.sql b/libs/prisma-service/prisma/migrations/20231227105815_org_id_unique_org_agent/migration.sql new file mode 100644 index 000000000..241cb06ea --- /dev/null +++ b/libs/prisma-service/prisma/migrations/20231227105815_org_id_unique_org_agent/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - A unique constraint covering the columns `[orgId]` on the table `org_agents` will be added. If there are existing duplicate values, this will fail. + +*/ +-- CreateIndex +CREATE UNIQUE INDEX "org_agents_orgId_key" ON "org_agents"("orgId"); diff --git a/libs/prisma-service/prisma/schema.prisma b/libs/prisma-service/prisma/schema.prisma index d8885aa6e..4e1a47116 100644 --- a/libs/prisma-service/prisma/schema.prisma +++ b/libs/prisma-service/prisma/schema.prisma @@ -168,7 +168,7 @@ model org_agents { tenantId String? apiKey String? agentsTypeId String? @db.Uuid - orgId String? @db.Uuid + orgId String? @unique @db.Uuid orgAgentTypeId String? @db.Uuid ledgerId String? @db.Uuid agent_invitations agent_invitations[] From b46edab22db3cc78a6cf2f3425e2f31862073e76 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Wed, 27 Dec 2023 18:04:14 +0530 Subject: [PATCH 060/107] Solved the conflicts as per comment Signed-off-by: KulkarniShashank --- apps/agent-service/src/agent-service.service.ts | 4 ++-- libs/common/src/response-messages/index.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index ea7bff0b2..44564eabd 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -576,7 +576,7 @@ export class AgentServiceService { const getOrgAgent = await this.agentServiceRepository.getAgentDetails(payload.orgId); if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { - this.logger.error(`Your wallet has already been created.`); + this.logger.error(`Your wallet is already been created.`); throw new ConflictException( ResponseMessages.agent.error.walletAlreadyCreated, { cause: new Error(), description: ResponseMessages.errorMessages.conflict } @@ -584,7 +584,7 @@ export class AgentServiceService { } if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { - this.logger.error(`Your wallet has already processing.`); + this.logger.error(`Your wallet is already processing.`); throw new ConflictException( ResponseMessages.agent.error.walletAlreadyProcessing, { cause: new Error(), description: ResponseMessages.errorMessages.conflict } diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 17f58bc7c..48cd54c5f 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -159,12 +159,12 @@ export const ResponseMessages = { notAbleToSpinUpAgent: 'Agent not able to spin-up', alreadySpinUp: 'Agent already spin-up', agentUrl: 'Agent url not exist', - agentNotExists: 'Agent not spinned up for this organization', - agentDown: 'Agent is down or not spinned up', - walletAlreadyCreated: 'Your wallet has already been created', - walletAlreadyProcessing: 'Your wallet has already processing', + agentNotExists: 'Agent not spun up for this organization', + agentDown: 'Agent is down or not spun up', + walletAlreadyCreated: 'Your wallet is already been created', + walletAlreadyProcessing: 'Your wallet is already processing', notAbleToSpinp: 'Agent not able to spin-up', - platformAdminNotAbleToSpinp: 'Platform-admin agent is not spun-up', + platformAdminNotAbleToSpinp: 'Platform-admin agent is not spun up', seedCharCount: 'seed must be at most 32 characters' } }, From d9089103c8d0efe545dffac387e443ebf6bf8d39 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Wed, 27 Dec 2023 19:11:09 +0530 Subject: [PATCH 061/107] refactor:user-sign-in-and-sign-up-api Signed-off-by: pranalidhanavade --- .../api-gateway/src/authz/authz.controller.ts | 27 +++++++------------ apps/api-gateway/src/authz/authz.service.ts | 16 +++++------ .../src/dtos/email-validator.dto.ts | 3 ++- apps/api-gateway/src/user/dto/add-user.dto.ts | 2 +- .../src/user/dto/create-user.dto.ts | 1 + .../src/user/dto/email-verify.dto.ts | 3 ++- .../src/user/dto/login-user.dto.ts | 4 +-- apps/user/interfaces/user.interface.ts | 15 +++++++---- apps/user/src/user.controller.ts | 16 ++++++++--- apps/user/src/user.service.ts | 12 ++++----- libs/common/src/interfaces/user.interface.ts | 16 +++++++++++ libs/common/src/response-messages/index.ts | 4 +-- 12 files changed, 72 insertions(+), 47 deletions(-) create mode 100644 libs/common/src/interfaces/user.interface.ts diff --git a/apps/api-gateway/src/authz/authz.controller.ts b/apps/api-gateway/src/authz/authz.controller.ts index 7e8ff1f60..fa8307c13 100644 --- a/apps/api-gateway/src/authz/authz.controller.ts +++ b/apps/api-gateway/src/authz/authz.controller.ts @@ -21,7 +21,7 @@ import { Response } from 'express'; import { EmailVerificationDto } from '../user/dto/email-verify.dto'; import { AuthTokenResponse } from './dtos/auth-token-res.dto'; import { LoginUserDto } from '../user/dto/login-user.dto'; -import { AddUserDetails } from '../user/dto/add-user.dto'; +import { AddUserDetailsDto } from '../user/dto/add-user.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; @@ -71,37 +71,30 @@ export class AuthzController { /** * - * @param email - * @param userInfo - * @param res - * @returns Add new user + * @Body userInfo + * @returns User's registration status */ @Post('/signup') @ApiOperation({ summary: 'Register new user to platform', description: 'Register new user to platform' }) - async addUserDetails(@Body() userInfo: AddUserDetails, @Res() res: Response): Promise { - const userDetails = await this.authzService.addUserDetails(userInfo); + async addUserDetails(@Body() userInfo: AddUserDetailsDto, @Res() res: Response): Promise { + await this.authzService.addUserDetails(userInfo); const finalResponse = { statusCode: HttpStatus.CREATED, - message: ResponseMessages.user.success.create, - data: userDetails.response + message: ResponseMessages.user.success.create }; return res.status(HttpStatus.CREATED).json(finalResponse); } - - /** - * - * @param loginUserDto - * @param res - * @returns User access token details + * @Body loginUserDto + * @returns User's access token details */ @Post('/signin') @ApiOperation({ summary: 'Authenticate the user for the access', description: 'Authenticate the user for the access' }) - @ApiResponse({ status: 200, description: 'Success', type: AuthTokenResponse }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: AuthTokenResponse }) @ApiBody({ type: LoginUserDto }) async login(@Body() loginUserDto: LoginUserDto, @Res() res: Response): Promise { @@ -110,7 +103,7 @@ export class AuthzController { const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.login, - data: userData.response + data: userData }; return res.status(HttpStatus.OK).json(finalResponse); diff --git a/apps/api-gateway/src/authz/authz.service.ts b/apps/api-gateway/src/authz/authz.service.ts index 5a5f17203..413d942cb 100644 --- a/apps/api-gateway/src/authz/authz.service.ts +++ b/apps/api-gateway/src/authz/authz.service.ts @@ -8,8 +8,8 @@ import { } from '@nestjs/websockets'; import { UserEmailVerificationDto } from '../user/dto/create-user.dto'; import { EmailVerificationDto } from '../user/dto/email-verify.dto'; -import { AddUserDetails } from '../user/dto/add-user.dto'; - +import { AddUserDetailsDto } from '../user/dto/add-user.dto'; +import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail } from '@credebl/common/interfaces/user.interface'; @Injectable() @WebSocketGateway() @@ -28,23 +28,23 @@ export class AuthzService extends BaseService { return this.sendNats(this.authServiceProxy, 'get-user-by-keycloakUserId', keycloakUserId); } - async sendVerificationMail(userEmailVerification: UserEmailVerificationDto): Promise { + async sendVerificationMail(userEmailVerification: UserEmailVerificationDto): Promise { const payload = { userEmailVerification }; return this.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload); } - async verifyEmail(param: EmailVerificationDto): Promise { + async verifyEmail(param: EmailVerificationDto): Promise { const payload = { param }; return this.sendNatsMessage(this.authServiceProxy, 'user-email-verification', payload); } - async login(email: string, password?: string, isPasskey = false): Promise<{ response: object }> { + async login(email: string, password?: string, isPasskey = false): Promise { const payload = { email, password, isPasskey }; - return this.sendNats(this.authServiceProxy, 'user-holder-login', payload); + return this.sendNatsMessage(this.authServiceProxy, 'user-holder-login', payload); } - async addUserDetails(userInfo: AddUserDetails): Promise<{ response: string }> { + async addUserDetails(userInfo: AddUserDetailsDto): Promise { const payload = { userInfo }; - return this.sendNats(this.authServiceProxy, 'add-user', payload); + return this.sendNatsMessage(this.authServiceProxy, 'add-user', payload); } } \ No newline at end of file diff --git a/apps/api-gateway/src/dtos/email-validator.dto.ts b/apps/api-gateway/src/dtos/email-validator.dto.ts index c41ad0ef5..107314e6c 100644 --- a/apps/api-gateway/src/dtos/email-validator.dto.ts +++ b/apps/api-gateway/src/dtos/email-validator.dto.ts @@ -5,7 +5,8 @@ import { IsEmail, IsNotEmpty, MaxLength } from 'class-validator'; export class EmailValidator { @ApiProperty() - @IsNotEmpty({ message: 'Email is required.' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) @MaxLength(256, { message: 'Email must be at most 256 character.' }) @IsEmail() email: string; diff --git a/apps/api-gateway/src/user/dto/add-user.dto.ts b/apps/api-gateway/src/user/dto/add-user.dto.ts index 4007d8629..328d162a9 100644 --- a/apps/api-gateway/src/user/dto/add-user.dto.ts +++ b/apps/api-gateway/src/user/dto/add-user.dto.ts @@ -3,7 +3,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { Transform } from 'class-transformer'; import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator'; -export class AddUserDetails { +export class AddUserDetailsDto { @ApiProperty({ example: 'awqx@getnada.com' }) @IsEmail({}, { message: 'Please provide a valid email' }) diff --git a/apps/api-gateway/src/user/dto/create-user.dto.ts b/apps/api-gateway/src/user/dto/create-user.dto.ts index 16c097e9c..b8326be5d 100644 --- a/apps/api-gateway/src/user/dto/create-user.dto.ts +++ b/apps/api-gateway/src/user/dto/create-user.dto.ts @@ -8,6 +8,7 @@ export class UserEmailVerificationDto { @ApiProperty() @Transform(({ value }) => trim(value)) @Transform(({ value }) => toLowerCase(value)) + @IsEmail({}, { message: 'Please provide a valid email' }) @IsNotEmpty({ message: 'Email is required.' }) @MaxLength(256, { message: 'Email must be at most 256 character.' }) @IsEmail() diff --git a/apps/api-gateway/src/user/dto/email-verify.dto.ts b/apps/api-gateway/src/user/dto/email-verify.dto.ts index c54db401d..a12177381 100644 --- a/apps/api-gateway/src/user/dto/email-verify.dto.ts +++ b/apps/api-gateway/src/user/dto/email-verify.dto.ts @@ -9,7 +9,8 @@ export class EmailVerificationDto { @ApiProperty() @Transform(({ value }) => trim(value)) @Transform(({ value }) => toLowerCase(value)) - @IsNotEmpty({ message: 'Email is required.' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) @MaxLength(256, { message: 'Email must be at most 256 character.' }) @IsEmail() email: string; diff --git a/apps/api-gateway/src/user/dto/login-user.dto.ts b/apps/api-gateway/src/user/dto/login-user.dto.ts index f62980e6e..a9ae0cc9d 100644 --- a/apps/api-gateway/src/user/dto/login-user.dto.ts +++ b/apps/api-gateway/src/user/dto/login-user.dto.ts @@ -6,8 +6,8 @@ import { trim } from '@credebl/common/cast.helper'; export class LoginUserDto { @ApiProperty({ example: 'awqx@getnada.com' }) - @IsEmail() - @IsNotEmpty({ message: 'Please provide valid email' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) @IsString({ message: 'email should be string' }) email: string; diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index 678ed95c5..e704a16af 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -66,8 +66,8 @@ interface IUserOrgRole { email?: string; orgRoles: string[]; } - - export interface ISendVerificationEmail { + +export interface ISendVerificationEmail { email: string; username?: string; } @@ -176,8 +176,13 @@ interface IUserOrgRole { search: string; } - export class IVerifyUserEmail { - email: string; - verificationCode: string; +export interface IVerifyUserEmail{ + email: string; + verificationCode: string; } +export interface IUserSignIn{ + email: string; + password: string; + isPasskey: boolean; +} \ No newline at end of file diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index e20d5fd62..001995d69 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,14 +1,14 @@ -import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, UserCredentials, IUserInformation, IUsersProfile, UserInvitations, ISendVerificationEmail, IVerifyUserEmail} from '../interfaces/user.interface'; +import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, UserCredentials, IUsersProfile, UserInvitations, IUserInformation, IUserSignIn} from '../interfaces/user.interface'; import {IOrgUsers, Payload} from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { Controller } from '@nestjs/common'; -import { LoginUserDto } from '../dtos/login-user.dto'; import { MessagePattern } from '@nestjs/microservices'; import { UserService } from './user.service'; import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; import { user } from '@prisma/client'; import { IUsersActivity } from 'libs/user-activity/interface'; +import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail } from '@credebl/common/interfaces/user.interface'; @Controller() export class UserController { @@ -34,9 +34,13 @@ export class UserController { async verifyEmail(payload: { param: VerifyEmailTokenDto }): Promise { return this.userService.verifyEmail(payload.param); } + /** + * @Body loginUserDto + * @returns User's access token details + */ @MessagePattern({ cmd: 'user-holder-login' }) - async login(payload: LoginUserDto): Promise { + async login(payload: IUserSignIn): Promise { return this.userService.login(payload); } @@ -129,8 +133,12 @@ export class UserController { async checkUserExist(payload: { userEmail: string }): Promise { return this.userService.checkUserExist(payload.userEmail); } + /** + * @Body userInfo + * @returns User's registration status + */ @MessagePattern({ cmd: 'add-user' }) - async addUserDetailsInKeyCloak(payload: { userInfo: IUserInformation }): Promise { + async addUserDetailsInKeyCloak(payload: { userInfo: IUserInformation }): Promise { return this.userService.createUserForToken(payload.userInfo); } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 3c42129f8..d3c5038a0 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -36,11 +36,9 @@ import { IOrgUsers, UpdateUserProfile, UserCredentials, - ISendVerificationEmail, IUserInformation, IUsersProfile, - UserInvitations, - IVerifyUserEmail + UserInvitations } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { UserActivityService } from '@credebl/user-activity'; @@ -57,6 +55,7 @@ import { AwsService } from '@credebl/aws'; import puppeteer from 'puppeteer'; import { WorldRecordTemplate } from '../templates/world-record-template'; import { IUsersActivity } from 'libs/user-activity/interface'; +import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail } from '@credebl/common/interfaces/user.interface'; @Injectable() export class UserService { @@ -267,7 +266,7 @@ export class UserService { const holderRoleData = await this.orgRoleService.getRole(OrgRoles.HOLDER); await this.userOrgRoleService.createUserOrgRole(userDetails.id, holderRoleData.id); - return 'User created successfully'; + return ResponseMessages.user.success.signUpUser; } catch (error) { this.logger.error(`Error in createUserForToken: ${JSON.stringify(error)}`); throw new RpcException(error.response ? error.response : error); @@ -312,7 +311,7 @@ export class UserService { * @param loginUserDto * @returns User access token details */ - async login(loginUserDto: LoginUserDto): Promise { + async login(loginUserDto: LoginUserDto): Promise { const { email, password, isPasskey } = loginUserDto; try { @@ -344,7 +343,7 @@ export class UserService { } } - async generateToken(email: string, password: string): Promise { + async generateToken(email: string, password: string): Promise { try { const supaInstance = await this.supabaseService.getClient(); this.logger.error(`supaInstance::`, supaInstance); @@ -361,6 +360,7 @@ export class UserService { } const token = data?.session; + return token; } catch (error) { throw new RpcException(error.response ? error.response : error); diff --git a/libs/common/src/interfaces/user.interface.ts b/libs/common/src/interfaces/user.interface.ts new file mode 100644 index 000000000..695b76747 --- /dev/null +++ b/libs/common/src/interfaces/user.interface.ts @@ -0,0 +1,16 @@ +export interface ISignInUser { + access_token: string; + token_type?: string; + expires_in?: number; + expires_at?: number; + refresh_token?: string; + } + export interface IVerifyUserEmail{ + email: string; + verificationCode: string; + } + export interface ISendVerificationEmail { + email: string; + username?: string; + } + \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index aa58a377c..913368695 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -17,8 +17,8 @@ export const ResponseMessages = { userActivity: 'User activities fetched successfully', userCredentials: 'User credentials fetched successfully', platformEcosystemettings: 'Platform and ecosystem settings updated', - fetchPlatformSettings: 'Platform settings fetched' - + fetchPlatformSettings: 'Platform settings fetched', + signUpUser:'User created successfully' }, error: { exists: 'User already exists', From 9d15abd7e90087c26ccd235cf00e6102004104e9 Mon Sep 17 00:00:00 2001 From: sanjay-k1910 Date: Wed, 27 Dec 2023 19:18:02 +0530 Subject: [PATCH 062/107] refactor: issued credential list API Signed-off-by: sanjay-k1910 --- .../dtos/get-all-issued-credentials.dto.ts | 54 +++++---- .../src/issuance/interfaces/index.ts | 6 +- .../src/issuance/issuance.controller.ts | 113 +++++++----------- .../src/issuance/issuance.service.ts | 11 +- apps/issuance/enum/issuance.enum.ts | 6 + .../interfaces/issuance.interfaces.ts | 4 +- apps/issuance/src/issuance.controller.ts | 3 +- apps/issuance/src/issuance.repository.ts | 11 +- apps/issuance/src/issuance.service.ts | 53 ++------ .../src/interfaces/issuance.interface.ts | 18 +++ 10 files changed, 129 insertions(+), 150 deletions(-) create mode 100644 apps/issuance/enum/issuance.enum.ts create mode 100644 libs/common/src/interfaces/issuance.interface.ts diff --git a/apps/api-gateway/src/issuance/dtos/get-all-issued-credentials.dto.ts b/apps/api-gateway/src/issuance/dtos/get-all-issued-credentials.dto.ts index 1112de27a..9e07e5ecf 100644 --- a/apps/api-gateway/src/issuance/dtos/get-all-issued-credentials.dto.ts +++ b/apps/api-gateway/src/issuance/dtos/get-all-issued-credentials.dto.ts @@ -1,27 +1,39 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsOptional } from "class-validator"; -import { SortValue } from "../../enum"; +import { ApiProperty } from '@nestjs/swagger'; +import { Transform, Type } from 'class-transformer'; +import { IsEnum, IsInt, IsOptional, IsString } from 'class-validator'; +import { SortValue } from '../../enum'; +import { trim } from '@credebl/common/cast.helper'; +import { SortFields } from 'apps/issuance/enum/issuance.enum'; -export class GetAllIssuedCredentialsDto { - @ApiProperty({ required: false }) - @IsOptional() - pageNumber: number = 1; +export class IGetAllIssuedCredentialsDto { + @ApiProperty({ required: false, default: 1 }) + @IsOptional() + @Type(() => Number) + @IsInt({ message: 'Page Number should be a number' }) + pageNumber: number = 1; - @ApiProperty({ required: false }) - @IsOptional() - pageSize: number = 10; + @ApiProperty({ required: false, default: 10 }) + @IsOptional() + @Type(() => Number) + @IsInt({ message: 'Page size should be a number' }) + pageSize: number; - @ApiProperty({ required: false }) - @IsOptional() - @Type(() => String) - searchByText: string = ''; + @ApiProperty({ required: false }) + @IsOptional() + @Type(() => String) + @IsString({ message: 'Search text should be a string' }) + @Transform(({ value }) => trim(value)) + searchByText: string; - @ApiProperty({ required: false }) - @IsOptional() - sorting: string = 'id'; + @ApiProperty({ required: false, enum: SortFields }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SortFields) + sortField: string = SortFields.CREATED_DATE_TIME; - @ApiProperty({ required: false }) - @IsOptional() - sortByValue: string = SortValue.DESC; + @ApiProperty({ required: false, enum: SortValue }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SortValue) + sortBy: string = SortValue.DESC; } diff --git a/apps/api-gateway/src/issuance/interfaces/index.ts b/apps/api-gateway/src/issuance/interfaces/index.ts index 1b3eb5bf5..834a33b4d 100644 --- a/apps/api-gateway/src/issuance/interfaces/index.ts +++ b/apps/api-gateway/src/issuance/interfaces/index.ts @@ -67,11 +67,11 @@ export interface RequestPayload { fileKey: string; fileName: string; } -export interface IIssuedCredentialSearchinterface { +export interface IIssuedCredentialSearchParams { pageNumber: number; pageSize: number; - sorting: string; - sortByValue: string; + sortField: string; + sortBy: string; searchByText: string; } diff --git a/apps/api-gateway/src/issuance/issuance.controller.ts b/apps/api-gateway/src/issuance/issuance.controller.ts index 774915802..b1e13188d 100644 --- a/apps/api-gateway/src/issuance/issuance.controller.ts +++ b/apps/api-gateway/src/issuance/issuance.controller.ts @@ -36,7 +36,7 @@ import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import { CommonService } from '@credebl/common/common.service'; import { Response } from 'express'; -import IResponseType from '@credebl/common/interfaces/response.interface'; +import IResponseType, { IResponse } from '@credebl/common/interfaces/response.interface'; import { IssuanceService } from './issuance.service'; import { ClientDetails, @@ -54,14 +54,14 @@ import { OrgRoles } from 'libs/org-roles/enums'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; import { ImageServiceService } from '@credebl/image-service'; -import { FileExportResponse, IIssuedCredentialSearchinterface, RequestPayload } from './interfaces'; +import { FileExportResponse, IIssuedCredentialSearchParams, RequestPayload } from './interfaces'; import { AwsService } from '@credebl/aws'; import { FileInterceptor } from '@nestjs/platform-express'; import { v4 as uuidv4 } from 'uuid'; import { RpcException } from '@nestjs/microservices'; /* eslint-disable @typescript-eslint/no-unused-vars */ import { user } from '@prisma/client'; -import { GetAllIssuedCredentialsDto } from './dtos/get-all-issued-credentials.dto'; +import { IGetAllIssuedCredentialsDto } from './dtos/get-all-issued-credentials.dto'; @Controller() @UseFilters(CustomExceptionFilter) @@ -79,82 +79,59 @@ export class IssuanceController { private readonly PAGE: number = 1; /** - * Description: Get all issued credentials - * @param user * @param orgId - * + * @returns List of issued credentials for a specific organization */ - @Get('/orgs/:orgId/credentials') - @UseGuards(AuthGuard('jwt')) - @ApiBearerAuth() - @ApiOperation({ - summary: `Get all issued credentials for a specific organization`, - description: `Get all issued credentials for a specific organization` - }) - @ApiQuery({ - name: 'pageNumber', - type: Number, - required: false - }) - @ApiQuery({ - name: 'searchByText', - type: String, - required: false - }) - @ApiQuery({ - name: 'pageSize', - type: Number, - required: false - }) - @ApiQuery({ - name: 'sortByValue', - type: String, - required: false - }) - @ApiQuery({ - name: 'sorting', - type: String, - required: false - }) - - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER) - async getIssueCredentials( - @Query() getAllIssuedCredentials: GetAllIssuedCredentialsDto, - @User() user: IUserRequest, - @Param('orgId') orgId: string, - @Res() res: Response - ): Promise { - const { pageSize, searchByText, pageNumber, sorting, sortByValue } = getAllIssuedCredentials; - const issuedCredentialsSearchCriteria: IIssuedCredentialSearchinterface = { - pageNumber, - searchByText, - pageSize, - sorting, - sortByValue - }; + @Get('/orgs/:orgId/credentials') + @UseGuards(AuthGuard('jwt')) + @ApiBearerAuth() + @ApiOperation({ + summary: `Get all issued credentials for a specific organization`, + description: `Get all issued credentials for a specific organization` + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER) + async getIssueCredentials( + @Query() getAllIssuedCredentials: IGetAllIssuedCredentialsDto, + @User() user: IUserRequest, + @Param('orgId') orgId: string, + @Res() res: Response + ): Promise { + const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllIssuedCredentials; + const issuedCredentialsSearchCriteria: IIssuedCredentialSearchParams = { + pageNumber, + searchByText, + pageSize, + sortField, + sortBy + }; - const getCredentialDetails = await this.issueCredentialService.getIssueCredentials(issuedCredentialsSearchCriteria, user, orgId); + const getCredentialDetails = await this.issueCredentialService.getIssueCredentials( + issuedCredentialsSearchCriteria, + user, + orgId + ); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.issuance.success.fetch, - data: getCredentialDetails.response - }; - return res.status(HttpStatus.OK).json(finalResponse); - } - + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.issuance.success.fetch, + data: getCredentialDetails + }; + return res.status(HttpStatus.OK).json(finalResponse); + } /** - * Description: Get all issued credentials + * * @param user * @param credentialRecordId * @param orgId - * + * @param res + * @returns Details of specific credential */ + @Get('/orgs/:orgId/credentials/:credentialRecordId') @ApiBearerAuth() @ApiOperation({ diff --git a/apps/api-gateway/src/issuance/issuance.service.ts b/apps/api-gateway/src/issuance/issuance.service.ts index 1f9611a6c..907bc2a14 100644 --- a/apps/api-gateway/src/issuance/issuance.service.ts +++ b/apps/api-gateway/src/issuance/issuance.service.ts @@ -4,7 +4,8 @@ import { ClientProxy } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { ClientDetails, FileParameter, IssuanceDto, IssueCredentialDto, OutOfBandCredentialDto, PreviewFileDetails } from './dtos/issuance.dto'; -import { FileExportResponse, IIssuedCredentialSearchinterface, RequestPayload } from './interfaces'; +import { FileExportResponse, IIssuedCredentialSearchParams, RequestPayload } from './interfaces'; +import { IIssuedCredential } from '@credebl/common/interfaces/issuance.interface'; @Injectable() export class IssuanceService extends BaseService { @@ -32,12 +33,10 @@ export class IssuanceService extends BaseService { return this.sendNats(this.issuanceProxy, 'send-credential-create-offer-oob', payload); } - getIssueCredentials(issuedCredentialsSearchCriteria: IIssuedCredentialSearchinterface, user: IUserRequest, orgId: string): Promise<{ - response: object; - }> { + getIssueCredentials(issuedCredentialsSearchCriteria: IIssuedCredentialSearchParams, user: IUserRequest, orgId: string): Promise { const payload = { issuedCredentialsSearchCriteria, user, orgId }; - return this.sendNats(this.issuanceProxy, 'get-all-issued-credentials', payload); - } + return this.sendNatsMessage(this.issuanceProxy, 'get-all-issued-credentials', payload); + } getIssueCredentialsbyCredentialRecordId(user: IUserRequest, credentialRecordId: string, orgId: string): Promise<{ diff --git a/apps/issuance/enum/issuance.enum.ts b/apps/issuance/enum/issuance.enum.ts new file mode 100644 index 000000000..aa09cabc9 --- /dev/null +++ b/apps/issuance/enum/issuance.enum.ts @@ -0,0 +1,6 @@ +export enum SortFields { + CREATED_DATE_TIME = 'createDateTime', + SCHEMA_ID = 'schemaId', + CONNECTION_ID = 'connectionId', + STATE = 'state' +} \ No newline at end of file diff --git a/apps/issuance/interfaces/issuance.interfaces.ts b/apps/issuance/interfaces/issuance.interfaces.ts index 088bb841c..ebf87d72e 100644 --- a/apps/issuance/interfaces/issuance.interfaces.ts +++ b/apps/issuance/interfaces/issuance.interfaces.ts @@ -134,8 +134,8 @@ export interface IIssuedCredentialsSearchInterface { export interface IIssuedCredentialsSearchCriteria { pageNumber: number; pageSize: number; - sorting: string; - sortByValue: string; + sortField: string; + sortBy: string; searchByText: string; user?: IUserRequestInterface; } diff --git a/apps/issuance/src/issuance.controller.ts b/apps/issuance/src/issuance.controller.ts index d535d6c69..7ecfd3432 100644 --- a/apps/issuance/src/issuance.controller.ts +++ b/apps/issuance/src/issuance.controller.ts @@ -2,6 +2,7 @@ import { Controller, Logger } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; import { ClientDetails, IIssuance, IIssueCredentials, IIssueCredentialsDefinitions, ImportFileDetails, IssueCredentialWebhookPayload, OutOfBandCredentialOffer, PreviewRequest } from '../interfaces/issuance.interfaces'; import { IssuanceService } from './issuance.service'; +import { IIssuedCredential } from '@credebl/common/interfaces/issuance.interface'; @Controller() export class IssuanceController { @@ -23,7 +24,7 @@ export class IssuanceController { } @MessagePattern({ cmd: 'get-all-issued-credentials' }) - async getIssueCredentials(payload: IIssueCredentials): Promise { + async getIssueCredentials(payload: IIssueCredentials): Promise { const { user, orgId, issuedCredentialsSearchCriteria} = payload; return this.issuanceService.getIssueCredentials(user, orgId, issuedCredentialsSearchCriteria); } diff --git a/apps/issuance/src/issuance.repository.ts b/apps/issuance/src/issuance.repository.ts index 0c4870222..d8fd75f40 100644 --- a/apps/issuance/src/issuance.repository.ts +++ b/apps/issuance/src/issuance.repository.ts @@ -21,7 +21,8 @@ import { } from '../interfaces/issuance.interfaces'; import { FileUploadStatus } from 'apps/api-gateway/src/enum'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { IIssuedCredentialSearchinterface } from 'apps/api-gateway/src/issuance/interfaces'; +import { IIssuedCredentialSearchParams } from 'apps/api-gateway/src/issuance/interfaces'; +import { SortValue } from '@credebl/enum/enum'; @Injectable() export class IssuanceRepository { constructor( @@ -70,7 +71,7 @@ export class IssuanceRepository { async getAllIssuedCredentials( user: IUserRequest, orgId: string, - issuedCredentialsSearchCriteria: IIssuedCredentialSearchinterface + issuedCredentialsSearchCriteria: IIssuedCredentialSearchParams ): Promise<{ issuedCredentialsCount: number; issuedCredentialsList: { @@ -100,10 +101,8 @@ export class IssuanceRepository { connectionId: true }, orderBy: { - [issuedCredentialsSearchCriteria?.sorting || 'createDateTime']: - 'DESC' === issuedCredentialsSearchCriteria?.sortByValue - ? 'desc' - : 'asc' + [issuedCredentialsSearchCriteria?.sortField]: + SortValue.DESC === issuedCredentialsSearchCriteria?.sortBy?.toLocaleUpperCase() ? 'desc' : 'asc' }, take: Number(issuedCredentialsSearchCriteria.pageSize), skip: (issuedCredentialsSearchCriteria.pageNumber - 1) * issuedCredentialsSearchCriteria.pageSize diff --git a/apps/issuance/src/issuance.service.ts b/apps/issuance/src/issuance.service.ts index ab5f06189..d9b83bcf3 100644 --- a/apps/issuance/src/issuance.service.ts +++ b/apps/issuance/src/issuance.service.ts @@ -28,7 +28,8 @@ import { Queue } from 'bull'; import { FileUploadStatus, FileUploadType } from 'apps/api-gateway/src/enum'; import { AwsService } from '@credebl/aws'; import { io } from 'socket.io-client'; -import { IIssuedCredentialSearchinterface } from 'apps/api-gateway/src/issuance/interfaces'; +import { IIssuedCredentialSearchParams } from 'apps/api-gateway/src/issuance/interfaces'; +import { IIssuedCredential } from '@credebl/common/interfaces/issuance.interface'; @Injectable() export class IssuanceService { @@ -178,45 +179,15 @@ export class IssuanceService { async getIssueCredentials( user: IUserRequest, orgId: string, - issuedCredentialsSearchCriteria: IIssuedCredentialSearchinterface - ): Promise<{ - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - createDateTime: Date; - createdBy: string; - connectionId: string; - schemaId: string; - state: string; - orgId: string; - }[]; - }> { + issuedCredentialsSearchCriteria: IIssuedCredentialSearchParams + ): Promise { try { const getIssuedCredentialsList = await this.issuanceRepository.getAllIssuedCredentials( user, orgId, issuedCredentialsSearchCriteria ); - const issuedCredentialsResponse: { - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - createDateTime: Date; - createdBy: string; - connectionId: string; - schemaId: string; - state: string; - orgId: string; - }[]; - } = { + const issuedCredentialsResponse: IIssuedCredential = { totalItems: getIssuedCredentialsList.issuedCredentialsCount, hasNextPage: issuedCredentialsSearchCriteria.pageSize * issuedCredentialsSearchCriteria.pageNumber < getIssuedCredentialsList.issuedCredentialsCount, @@ -227,18 +198,14 @@ export class IssuanceService { data: getIssuedCredentialsList.issuedCredentialsList }; - if (0 !== getIssuedCredentialsList.issuedCredentialsCount) { - return issuedCredentialsResponse; - } else { + if (0 === getIssuedCredentialsList?.issuedCredentialsCount) { throw new NotFoundException(ResponseMessages.issuance.error.credentialsNotFound); } + + return issuedCredentialsResponse; } catch (error) { - if (404 === error.status) { - throw new NotFoundException(error.response.message); - } - throw new RpcException( - `[getConnections] [NATS call]- error in fetch connections details : ${JSON.stringify(error)}` - ); + this.logger.error(`Error in fetching issued credentials by org id: ${error}`); + throw new RpcException(error.response ? error.response : error); } } diff --git a/libs/common/src/interfaces/issuance.interface.ts b/libs/common/src/interfaces/issuance.interface.ts new file mode 100644 index 000000000..fe7783064 --- /dev/null +++ b/libs/common/src/interfaces/issuance.interface.ts @@ -0,0 +1,18 @@ +export interface IIssuedCredentialResponse { + createDateTime: Date; + createdBy: string; + connectionId: string; + schemaId: string; + state: string; + orgId: string; + } + +export interface IIssuedCredential { + totalItems: number; + hasNextPage: boolean; + hasPreviousPage: boolean; + nextPage: number; + previousPage: number; + lastPage: number; + data: IIssuedCredentialResponse[]; + } \ No newline at end of file From 4514dc5ed50823dc583992ab84ade34cc971b36b Mon Sep 17 00:00:00 2001 From: sanjay-k1910 Date: Wed, 27 Dec 2023 19:27:37 +0530 Subject: [PATCH 063/107] refactor: issuance controller Signed-off-by: sanjay-k1910 --- apps/api-gateway/src/issuance/issuance.controller.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/api-gateway/src/issuance/issuance.controller.ts b/apps/api-gateway/src/issuance/issuance.controller.ts index b1e13188d..727461254 100644 --- a/apps/api-gateway/src/issuance/issuance.controller.ts +++ b/apps/api-gateway/src/issuance/issuance.controller.ts @@ -124,19 +124,16 @@ export class IssuanceController { } /** - * - * @param user * @param credentialRecordId * @param orgId - * @param res * @returns Details of specific credential */ @Get('/orgs/:orgId/credentials/:credentialRecordId') @ApiBearerAuth() @ApiOperation({ - summary: `Get credential by credentialRecordId`, - description: `Get credential credentialRecordId` + summary: `Fetch credentials by credentialRecordId`, + description: `Fetch credentials credentialRecordId` }) @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -145,7 +142,6 @@ export class IssuanceController { @User() user: IUserRequest, @Param('credentialRecordId') credentialRecordId: string, @Param('orgId') orgId: string, - @Res() res: Response ): Promise { const getCredentialDetails = await this.issueCredentialService.getIssueCredentialsbyCredentialRecordId( From 2358144660c747cdb69159250685da7115fe53b3 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Wed, 27 Dec 2023 19:34:33 +0530 Subject: [PATCH 064/107] refactor:validations in dto Signed-off-by: pranalidhanavade --- apps/api-gateway/src/dtos/email-validator.dto.ts | 2 +- apps/api-gateway/src/user/dto/add-user.dto.ts | 6 +++++- apps/api-gateway/src/user/dto/create-user.dto.ts | 4 ++-- apps/api-gateway/src/user/dto/email-verify.dto.ts | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/api-gateway/src/dtos/email-validator.dto.ts b/apps/api-gateway/src/dtos/email-validator.dto.ts index 107314e6c..802e062e0 100644 --- a/apps/api-gateway/src/dtos/email-validator.dto.ts +++ b/apps/api-gateway/src/dtos/email-validator.dto.ts @@ -7,7 +7,7 @@ export class EmailValidator { @ApiProperty() @IsEmail({}, { message: 'Please provide a valid email' }) @IsNotEmpty({ message: 'Email is required' }) - @MaxLength(256, { message: 'Email must be at most 256 character.' }) + @MaxLength(256, { message: 'Email must be at most 256 character' }) @IsEmail() email: string; } \ No newline at end of file diff --git a/apps/api-gateway/src/user/dto/add-user.dto.ts b/apps/api-gateway/src/user/dto/add-user.dto.ts index 328d162a9..05145b8d9 100644 --- a/apps/api-gateway/src/user/dto/add-user.dto.ts +++ b/apps/api-gateway/src/user/dto/add-user.dto.ts @@ -1,7 +1,7 @@ import { trim } from '@credebl/common/cast.helper'; import { ApiProperty } from '@nestjs/swagger'; import { Transform } from 'class-transformer'; -import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString, MaxLength, MinLength } from 'class-validator'; export class AddUserDetailsDto { @@ -13,11 +13,15 @@ export class AddUserDetailsDto { @ApiProperty({ example: 'Alen' }) @IsNotEmpty({ message: 'First name is required' }) + @MinLength(2, { message: 'First name must be at least 2 characters.' }) + @MaxLength(50, { message: 'First name must be at most 50 characters.' }) @IsString({ message: 'First name should be a string' }) firstName: string; @ApiProperty({ example: 'Harvey' }) @IsNotEmpty({ message: 'Last name is required' }) + @MinLength(2, { message: 'Last name must be at least 2 characters.' }) + @MaxLength(50, { message: 'Last name must be at most 50 characters.' }) @IsString({ message: 'Last name should be a string' }) lastName: string; diff --git a/apps/api-gateway/src/user/dto/create-user.dto.ts b/apps/api-gateway/src/user/dto/create-user.dto.ts index b8326be5d..68bafd310 100644 --- a/apps/api-gateway/src/user/dto/create-user.dto.ts +++ b/apps/api-gateway/src/user/dto/create-user.dto.ts @@ -9,8 +9,8 @@ export class UserEmailVerificationDto { @Transform(({ value }) => trim(value)) @Transform(({ value }) => toLowerCase(value)) @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required.' }) - @MaxLength(256, { message: 'Email must be at most 256 character.' }) + @IsNotEmpty({ message: 'Email is required' }) + @MaxLength(256, { message: 'Email must be at most 256 character' }) @IsEmail() email: string; } diff --git a/apps/api-gateway/src/user/dto/email-verify.dto.ts b/apps/api-gateway/src/user/dto/email-verify.dto.ts index a12177381..b74ed9bfa 100644 --- a/apps/api-gateway/src/user/dto/email-verify.dto.ts +++ b/apps/api-gateway/src/user/dto/email-verify.dto.ts @@ -11,7 +11,7 @@ export class EmailVerificationDto { @Transform(({ value }) => toLowerCase(value)) @IsEmail({}, { message: 'Please provide a valid email' }) @IsNotEmpty({ message: 'Email is required' }) - @MaxLength(256, { message: 'Email must be at most 256 character.' }) + @MaxLength(256, { message: 'Email must be at most 256 character' }) @IsEmail() email: string; From 4888cfc04e49110d148c1f9c80af60422b52bbf7 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Wed, 27 Dec 2023 19:38:25 +0530 Subject: [PATCH 065/107] Solved the query for the findFirst in get agent functionality Signed-off-by: KulkarniShashank --- .../AFJ/scripts/start_agent.sh | 38 +++++++++++++++--- .../src/agent-service.controller.ts | 2 +- .../src/agent-service.service.ts | 40 +++++++++++-------- .../agent-service/agent-service.controller.ts | 2 +- .../agent-service/agent-service.service.ts | 4 +- 5 files changed, 62 insertions(+), 24 deletions(-) diff --git a/apps/agent-provisioning/AFJ/scripts/start_agent.sh b/apps/agent-provisioning/AFJ/scripts/start_agent.sh index 4a793ea12..de1905ca9 100755 --- a/apps/agent-provisioning/AFJ/scripts/start_agent.sh +++ b/apps/agent-provisioning/AFJ/scripts/start_agent.sh @@ -76,12 +76,25 @@ else mkdir ${PWD}/apps/agent-provisioning/AFJ/endpoints fi -docker build . -t $AFJ_VERSION -f apps/agent-provisioning/AFJ/afj-controller/Dockerfile +if [ -d "${PWD}/apps/agent-provisioning/AFJ/agent-config" ]; then + echo "Endpoints directory exists." +else + echo "Error: Endpoints directory does not exists." + mkdir ${PWD}/apps/agent-provisioning/AFJ/agent-config +fi AGENT_ENDPOINT="${PROTOCOL}://${EXTERNAL_IP}:${INBOUND_PORT}" echo "-----$AGENT_ENDPOINT----" -cat <>${PWD}/apps/agent-provisioning/AFJ/agent-config/${AGENCY}_${CONTAINER_NAME}.json +CONFIG_FILE="${PWD}/apps/agent-provisioning/AFJ/agent-config/${AGENCY}_${CONTAINER_NAME}.json" + +# Check if the file exists +if [ -f "$CONFIG_FILE" ]; then + # If it exists, remove the file + rm "$CONFIG_FILE" +fi + +cat <>${CONFIG_FILE} { "label": "${AGENCY}_${CONTAINER_NAME}", "walletId": "$WALLET_NAME", @@ -117,7 +130,15 @@ cat <>${PWD}/apps/agent-provisioning/AFJ/agent-config/${AGENCY}_${CONTAINE EOF FILE_NAME="docker-compose_${AGENCY}_${CONTAINER_NAME}.yaml" -cat <>${PWD}/apps/agent-provisioning/AFJ/${FILE_NAME} + +DOCKER_COMPOSE="${PWD}/apps/agent-provisioning/AFJ/${FILE_NAME}" + +# Check if the file exists +if [ -f "$DOCKER_COMPOSE" ]; then + # If it exists, remove the file + rm "$DOCKER_COMPOSE" +fi +cat <>${DOCKER_COMPOSE} version: '3' services: @@ -152,7 +173,7 @@ if [ $? -eq 0 ]; then echo "container-name::::::${CONTAINER_NAME}" echo "file-name::::::$FILE_NAME" - docker-compose -f $FILE_NAME --project-name ${AGENCY}_${CONTAINER_NAME} up -d + docker compose -f $FILE_NAME up -d if [ $? -eq 0 ]; then n=0 @@ -177,7 +198,14 @@ if [ $? -eq 0 ]; then done echo "Creating agent config" - cat <>${PWD}/endpoints/${AGENCY}_${CONTAINER_NAME}.json + ENDPOINT="${PWD}/endpoints/${AGENCY}_${CONTAINER_NAME}.json" + + # Check if the file exists + if [ -f "$ENDPOINT" ]; then + # If it exists, remove the file + rm "$ENDPOINT" + fi + cat <>${ENDPOINT} { "CONTROLLER_ENDPOINT":"${EXTERNAL_IP}:${ADMIN_PORT}", "AGENT_ENDPOINT" : "${INTERNAL_IP}:${ADMIN_PORT}" diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index e98a4ba63..2fd35f4ee 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -16,7 +16,7 @@ export class AgentServiceController { * @returns Get agent status */ @MessagePattern({ cmd: 'agent-spinup' }) - async walletProvision(payload: { agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface }): Promise { + async walletProvision(payload: { agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface }): Promise { return this.agentServiceService.walletProvision(payload.agentSpinupDto, payload.user); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 161fe4fb2..dc6a1e3fb 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -134,7 +134,7 @@ export class AgentServiceService { * @returns Get agent status */ async walletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise { - let agentProcess: org_agents; + let agentProcess: ICreateOrgAgent; try { // Invoke an internal function to create wallet @@ -158,6 +158,7 @@ export class AgentServiceService { let agentProcess: ICreateOrgAgent; let getOrgAgent; try { + const [platformConfig, getAgentType, ledgerIdData] = await Promise.all([ this.agentServiceRepository.getPlatformConfigDetails(), this.agentServiceRepository.getAgentTypeDetails(), @@ -167,30 +168,41 @@ export class AgentServiceService { let orgData; if (!user?.userId && agentSpinupDto?.platformAdminEmail) { - /** - * Get Platform admin user by platform admin email - */ + + // Get Platform admin user by platform admin email platformAdminUser = await this.agentServiceRepository.getPlatfomAdminUser(agentSpinupDto?.platformAdminEmail); userId = platformAdminUser?.id; } else { - userId = user?.userId; + userId = user?.id; } + // Get platform org const platformAdminOrgDetails = await this.agentServiceRepository.getPlatfomOrg(agentSpinupDto?.orgName); + if (agentSpinupDto.orgId) { + + // Get organization details getOrgAgent = await this.agentServiceRepository.getAgentDetails(agentSpinupDto.orgId); + + // Get organization data by orgId orgData = await this.agentServiceRepository.getOrgDetails(agentSpinupDto.orgId); } else { + + // Get platform organization details getOrgAgent = await this.agentServiceRepository.getAgentDetails(platformAdminOrgDetails); + + // Get platform organization data by orgId orgData = await this.agentServiceRepository.getOrgDetails(platformAdminOrgDetails); } agentSpinupDto.ledgerId = agentSpinupDto.ledgerId?.length ? agentSpinupDto.ledgerId : ledgerIdData.map(ledger => ledger?.id); + + // Get genesis URL and ledger details const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { - this.logger.error(`Your wallet has already been created`); + this.logger.error(`Your wallet is already been created`); throw new BadRequestException( ResponseMessages.agent.error.walletAlreadyCreated, { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } @@ -205,7 +217,6 @@ export class AgentServiceService { ); } - if (!agentSpinupDto.orgId) { if (platformAdminOrgDetails) { @@ -217,23 +228,19 @@ export class AgentServiceService { agentSpinupDto.tenant = agentSpinupDto.tenant || false; agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]; - /** - * Invoke function for validate platform configuration - */ + + // Invoke function for validate platform configuration this.validatePlatformConfig(platformConfig); const externalIp = platformConfig?.externalIp; const controllerIp = platformConfig?.lastInternalId !== 'false' ? platformConfig?.lastInternalId : ''; const apiEndpoint = platformConfig?.apiEndpoint; - /** - * Create payload for the wallet create and store payload - */ + // Create payload for the wallet create and store payload const walletProvisionPayload = await this.prepareWalletProvisionPayload(agentSpinupDto, externalIp, apiEndpoint, controllerIp, ledgerDetails, platformConfig, orgData); - /** - * Socket connection - */ + + // Socket connection const socket: Socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); this.emitAgentSpinupInitiatedEvent(agentSpinupDto, socket); @@ -242,6 +249,7 @@ export class AgentServiceService { agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId); this.validateAgentProcess(agentProcess); + // AFJ agent spin-up this._agentSpinup(walletProvisionPayload, agentSpinupDto, platformConfig?.sgApiKey, orgData, user, socket, agentSpinupDto.ledgerId, agentProcess); } catch (error) { diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.ts b/apps/api-gateway/src/agent-service/agent-service.controller.ts index 926265a35..c9e50bc59 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -123,7 +123,7 @@ export class AgentController { const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, - data: agentDetails.response + data: agentDetails }; return res.status(HttpStatus.CREATED).json(finalResponse); diff --git a/apps/api-gateway/src/agent-service/agent-service.service.ts b/apps/api-gateway/src/agent-service/agent-service.service.ts index 7b4d7b187..417512bed 100644 --- a/apps/api-gateway/src/agent-service/agent-service.service.ts +++ b/apps/api-gateway/src/agent-service/agent-service.service.ts @@ -21,8 +21,10 @@ export class AgentService extends BaseService { * @param user * @returns Get agent status */ - async agentSpinup(agentSpinupDto: AgentSpinupDto, user: user): Promise<{ response: object }> { + async agentSpinup(agentSpinupDto: AgentSpinupDto, user: user): Promise { const payload = { agentSpinupDto, user }; + + // NATS call return this.sendNatsMessage(this.agentServiceProxy, 'agent-spinup', payload); } From f0c4745d565d745afb774adf2f573eb936622006 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Wed, 27 Dec 2023 19:52:58 +0530 Subject: [PATCH 066/107] Resolved comments Signed-off-by: KulkarniShashank --- .../src/agent-service.service.ts | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 141469304..904279a5d 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -202,18 +202,16 @@ export class AgentServiceService { // Get genesis URL and ledger details const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); - if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { - this.logger.error(`Your wallet is already been created`); + if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { throw new BadRequestException( - ResponseMessages.agent.error.walletAlreadyCreated, + ResponseMessages.agent.error.walletAlreadyProcessing, { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } ); } - if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { - this.logger.error('Your wallet is already processing.'); + if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { throw new BadRequestException( - ResponseMessages.agent.error.walletAlreadyProcessing, + ResponseMessages.agent.error.walletAlreadyCreated, { cause: new Error(), description: ResponseMessages.errorMessages.badRequest } ); } @@ -1134,30 +1132,30 @@ export class AgentServiceService { } async getConnectionsByconnectionId(url: string, apiKey: string): Promise { - + try { const data = await this.commonService - .httpGet(url, { headers: { 'x-api-key': apiKey } }) - .then(async response => response) - .catch(error => { - this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); - - if (error && Object.keys(error).length === 0) { - throw new InternalServerErrorException( - ResponseMessages.agent.error.agentDown, - { cause: new Error(), description: ResponseMessages.errorMessages.serverError } - ); - } else { - throw error; - } - }); - return data; + .httpGet(url, { headers: { 'x-api-key': apiKey } }) + .then(async response => response) + .catch(error => { + this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); + + if (error && Object.keys(error).length === 0) { + throw new InternalServerErrorException( + ResponseMessages.agent.error.agentDown, + { cause: new Error(), description: ResponseMessages.errorMessages.serverError } + ); + } else { + throw error; + } + }); + return data; } catch (error) { this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); throw new RpcException(error.response ? error.response : error); } - - } + + } /** * Get agent health From 41352c33680a30906bcf11ac943587ae2e0fcb9d Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 20:31:01 +0530 Subject: [PATCH 067/107] refactor: create connection url api Signed-off-by: bhavanakarwade --- .../src/agent-service.controller.ts | 4 +-- .../src/agent-service.service.ts | 15 ++++---- .../src/connection/connection.controller.ts | 8 ++--- .../src/connection/connection.service.ts | 4 +-- apps/connection/src/connection.controller.ts | 16 ++------- apps/connection/src/connection.service.ts | 36 +++++++------------ .../src/interfaces/connection.interfaces.ts | 10 +++--- .../src/interfaces/connection.interface.ts | 12 +++++++ 8 files changed, 50 insertions(+), 55 deletions(-) diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 81e08f488..238f4503a 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -5,6 +5,7 @@ import { AgentStatus, GetCredDefAgentRedirection, GetSchemaAgentRedirection, IAg import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; +import { ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; @Controller() export class AgentServiceController { @@ -45,8 +46,7 @@ export class AgentServiceController { @MessagePattern({ cmd: 'agent-create-connection-legacy-invitation' }) - async createLegacyConnectionInvitation(payload: { connectionPayload: IConnectionDetails, url: string, apiKey: string }): Promise { - + async createLegacyConnectionInvitation(payload: { connectionPayload: IConnectionDetails, url: string, apiKey: string }): Promise { return this.agentServiceService.createLegacyConnectionInvitation(payload.connectionPayload, payload.url, payload.apiKey); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index d500617ca..6c9c71b64 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -31,6 +31,7 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { Socket, io } from 'socket.io-client'; import { WebSocketGateway } from '@nestjs/websockets'; import * as retry from 'async-retry'; +import { ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; @Injectable() @WebSocketGateway() @@ -500,12 +501,12 @@ export class AgentServiceService { const payload = { orgId, user, label }; return this.agentServiceProxy .send(pattern, payload) - // .pipe( - // map((response) => ( - // { - // response - // })) - // ) + .pipe( + map((response) => ( + { + response + })) + ) .toPromise() .catch(error => { this.logger.error(`catch: ${JSON.stringify(error)}`); @@ -851,7 +852,7 @@ export class AgentServiceService { } } - async createLegacyConnectionInvitation(connectionPayload: IConnectionDetails, url: string, apiKey: string): Promise { + async createLegacyConnectionInvitation(connectionPayload: IConnectionDetails, url: string, apiKey: string): Promise { try { const data = await this.commonService diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index 1494a4bce..0baabf26a 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -127,11 +127,11 @@ export class ConnectionController { ): Promise { connectionDto.orgId = orgId; - await this.connectionService.createLegacyConnectionInvitation(connectionDto, reqUser); - const finalResponse: IResponseType = { + const connectionData = await this.connectionService.createLegacyConnectionInvitation(connectionDto, reqUser); + const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: ResponseMessages.connection.success.create - // data: connectionData + message: ResponseMessages.connection.success.create, + data: connectionData }; return res.status(HttpStatus.CREATED).json(finalResponse); diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 88cc1ccdc..139c02758 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -4,7 +4,7 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { ConnectionDto, CreateConnectionDto } from './dtos/connection.dto'; import { IUserRequestInterface } from './interfaces'; -import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionList, ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; import { IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; @Injectable() @@ -16,7 +16,7 @@ export class ConnectionService extends BaseService { createLegacyConnectionInvitation( connectionDto: CreateConnectionDto, user: IUserRequestInterface - ): Promise { + ): Promise { try { const connectionDetails = { orgId: connectionDto.orgId, diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index d01cbff22..8921eb2ce 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -7,7 +7,7 @@ import { IFetchConnectionById, IFetchConnections } from './interfaces/connection.interfaces'; -import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionList, ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; @Controller() export class ConnectionController { @@ -19,18 +19,8 @@ export class ConnectionController { * @returns Created connection invitation for out-of-band */ @MessagePattern({ cmd: 'create-connection' }) - async createLegacyConnectionInvitation(payload: IConnection): Promise { - const { orgId, user, multiUseInvitation, autoAcceptConnection, alias, imageUrl, label } = payload; - - return this.connectionService.createLegacyConnectionInvitation( - orgId, - user, - multiUseInvitation, - autoAcceptConnection, - alias, - imageUrl, - label - ); + async createLegacyConnectionInvitation(payload: IConnection): Promise { + return this.connectionService.createLegacyConnectionInvitation(payload); } /** diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index aed1e76af..12f958f7c 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -5,17 +5,17 @@ import { HttpException, Inject, Injectable, Logger, NotFoundException } from '@n import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs'; import { - ConnectionInvitationResponse, + IConnection, + IConnectionInvitation, IConnectionSearchCriteria, - ICreateConnection, - IUserRequestInterface + ICreateConnection } from './interfaces/connection.interfaces'; import { ConnectionRepository } from './connection.repository'; import { ResponseMessages } from '@credebl/common/response-messages'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { OrgAgentType } from '@credebl/enum/enum'; import { platform_config } from '@prisma/client'; -import { IConnectionList } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionList, ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; @Injectable() export class ConnectionService { @@ -27,29 +27,21 @@ export class ConnectionService { ) {} /** - * Description: create connection legacy invitation + * Create connection legacy invitation URL * @param orgId * @param user * @returns Connection legacy invitation URL */ - async createLegacyConnectionInvitation( - orgId: string, - user: IUserRequestInterface, - multiUseInvitation: boolean, - autoAcceptConnection: boolean, - alias: string, - imageUrl: string, - label: string - ): Promise { + async createLegacyConnectionInvitation(payload: IConnection): Promise { + + const {orgId, multiUseInvitation, autoAcceptConnection, alias, label} = payload; try { const connectionInvitationExist = await this.connectionRepository.getConnectionInvitationByOrgId(orgId); - if (connectionInvitationExist) { return connectionInvitationExist; } const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); - const platformConfig: platform_config = await this.connectionRepository.getPlatformConfigDetails(); const { agentEndPoint, id, organisation } = agentDetails; const agentId = id; @@ -76,9 +68,7 @@ export class ConnectionService { const apiKey = platformConfig?.sgApiKey; const createConnectionInvitation = await this._createConnectionInvitation(connectionPayload, url, apiKey); - const invitationObject = createConnectionInvitation?.message?.invitation['@id']; - let shortenedUrl; if (agentDetails?.tenantId) { shortenedUrl = `${agentEndPoint}/multi-tenancy/url/${agentDetails?.tenantId}/${invitationObject}`; @@ -91,7 +81,6 @@ export class ConnectionService { agentId, orgId ); - return saveConnectionDetails; } catch (error) { this.logger.error(`[createLegacyConnectionInvitation] - error in connection invitation: ${error}`); @@ -124,16 +113,17 @@ export class ConnectionService { } /** - * Description: Store shortening URL - * @param referenceId - * @param url + * Store shortening URL + * @param orgId * @returns connection invitation URL */ async _createConnectionInvitation( connectionPayload: object, url: string, apiKey: string - ): Promise { + ): Promise { + + //nats call in agent-service to create an invitation url const pattern = { cmd: 'agent-create-connection-legacy-invitation' }; const payload = { connectionPayload, url, apiKey }; diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index f26a5e5e6..cbee08a34 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -87,10 +87,12 @@ export interface IFetchConnectionUrlById { orgId: string; } -export interface ConnectionInvitationResponse { - message: { - invitation: object; - }; +export interface IConnectionInvitation { + message: IInvitation; +} +interface IInvitation { + invitation: string; + } export interface OrgAgent { organisation: organisation; diff --git a/libs/common/src/interfaces/connection.interface.ts b/libs/common/src/interfaces/connection.interface.ts index 0ccbea2e0..8b685477d 100644 --- a/libs/common/src/interfaces/connection.interface.ts +++ b/libs/common/src/interfaces/connection.interface.ts @@ -19,4 +19,16 @@ export interface IConnectionsListCount { lastPage: number; data: IConnectionItem[]; } + + export interface ICreateConnectioQr { + id: string; + orgId: string; + agentId: string; + connectionInvitation: string; + multiUse: boolean; + createDateTime: Date; + createdBy: number; + lastChangedDateTime: Date; + lastChangedBy: number; +} \ No newline at end of file From f0808520a08d7a8960c3345c61ba1fb062b609a4 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 20:49:57 +0530 Subject: [PATCH 068/107] refactored interfaces Signed-off-by: bhavanakarwade --- apps/agent-service/src/agent-service.controller.ts | 4 ++-- apps/agent-service/src/agent-service.service.ts | 4 ++-- apps/api-gateway/src/connection/connection.service.ts | 4 ++-- apps/connection/src/connection.controller.ts | 4 ++-- apps/connection/src/connection.service.ts | 4 ++-- libs/common/src/interfaces/connection.interface.ts | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index d7b3c7ae5..34b76cb01 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -5,7 +5,7 @@ import { IAgentStatus, IAgentSpinUpSatus, IGetCredDefAgentRedirection, IGetSchem import { IConnectionDetails, IUserRequestInterface } from './interface/agent-service.interface'; import { ISendProofRequestPayload } from './interface/agent-service.interface'; import { user } from '@prisma/client'; -import { ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; +import { ICreateConnectionUrl } from '@credebl/common/interfaces/connection.interface'; import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Controller() @@ -45,7 +45,7 @@ export class AgentServiceController { @MessagePattern({ cmd: 'agent-create-connection-legacy-invitation' }) - async createLegacyConnectionInvitation(payload: { connectionPayload: IConnectionDetails, url: string, apiKey: string }): Promise { + async createLegacyConnectionInvitation(payload: { connectionPayload: IConnectionDetails, url: string, apiKey: string }): Promise { return this.agentServiceService.createLegacyConnectionInvitation(payload.connectionPayload, payload.url, payload.apiKey); } diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 832c7fea1..cd9502a15 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -32,7 +32,7 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { Socket, io } from 'socket.io-client'; import { WebSocketGateway } from '@nestjs/websockets'; import * as retry from 'async-retry'; -import { ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; +import { ICreateConnectionUrl } from '@credebl/common/interfaces/connection.interface'; import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Injectable() @@ -932,7 +932,7 @@ export class AgentServiceService { } } - async createLegacyConnectionInvitation(connectionPayload: IConnectionDetails, url: string, apiKey: string): Promise { + async createLegacyConnectionInvitation(connectionPayload: IConnectionDetails, url: string, apiKey: string): Promise { try { const data = await this.commonService diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 9181d1399..5bc8162d0 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -4,7 +4,7 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { ConnectionDto, CreateConnectionDto } from './dtos/connection.dto'; import { IUserRequestInterface } from './interfaces'; -import { IConnectionList, ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionList, ICreateConnectionUrl } from '@credebl/common/interfaces/connection.interface'; import { IConnectionDetailsById, IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; @Injectable() @@ -16,7 +16,7 @@ export class ConnectionService extends BaseService { createLegacyConnectionInvitation( connectionDto: CreateConnectionDto, user: IUserRequestInterface - ): Promise { + ): Promise { try { const connectionDetails = { orgId: connectionDto.orgId, diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 8096870f3..934665ad6 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -7,7 +7,7 @@ import { IFetchConnectionById, IFetchConnections } from './interfaces/connection.interfaces'; -import { IConnectionList, ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionList, ICreateConnectionUrl } from '@credebl/common/interfaces/connection.interface'; import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Controller() @@ -20,7 +20,7 @@ export class ConnectionController { * @returns Created connection invitation URL */ @MessagePattern({ cmd: 'create-connection' }) - async createLegacyConnectionInvitation(payload: IConnection): Promise { + async createLegacyConnectionInvitation(payload: IConnection): Promise { return this.connectionService.createLegacyConnectionInvitation(payload); } diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 0fdbcf2f0..3de739f7c 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -15,7 +15,7 @@ import { ResponseMessages } from '@credebl/common/response-messages'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { OrgAgentType } from '@credebl/enum/enum'; import { platform_config } from '@prisma/client'; -import { IConnectionList, ICreateConnectioQr } from '@credebl/common/interfaces/connection.interface'; +import { IConnectionList, ICreateConnectionUrl } from '@credebl/common/interfaces/connection.interface'; import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; @Injectable() @@ -33,7 +33,7 @@ export class ConnectionService { * @param user * @returns Connection legacy invitation URL */ - async createLegacyConnectionInvitation(payload: IConnection): Promise { + async createLegacyConnectionInvitation(payload: IConnection): Promise { const {orgId, multiUseInvitation, autoAcceptConnection, alias, label} = payload; try { diff --git a/libs/common/src/interfaces/connection.interface.ts b/libs/common/src/interfaces/connection.interface.ts index 8b685477d..0d4a34ca5 100644 --- a/libs/common/src/interfaces/connection.interface.ts +++ b/libs/common/src/interfaces/connection.interface.ts @@ -20,7 +20,7 @@ export interface IConnectionsListCount { data: IConnectionItem[]; } - export interface ICreateConnectioQr { + export interface ICreateConnectionUrl { id: string; orgId: string; agentId: string; From 20453a405269f7d756801835865c2cf9f6b27844 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 20:55:52 +0530 Subject: [PATCH 069/107] resolved conflicts Signed-off-by: bhavanakarwade --- apps/agent-service/src/agent-service.service.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index cd9502a15..b2a466d59 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -502,23 +502,22 @@ export class AgentServiceService { } } - - async _createLegacyConnectionInvitation(orgId: string, user: IUserRequestInterface, label: string): Promise< - object> { + async _createLegacyConnectionInvitation(orgId: string, user: IUserRequestInterface, label: string): Promise<{ + response; + }> { try { const pattern = { cmd: 'create-connection' }; const payload = { orgId, user, label }; return this.agentServiceProxy - .send(pattern, payload) + .send(pattern, payload) .pipe( map((response) => ( { response })) - ) - .toPromise() + ).toPromise() .catch(error => { this.logger.error(`catch: ${JSON.stringify(error)}`); throw new HttpException( From 3e3d2eb7ee8aa77a862a5f2cdb86b371a8b1bc06 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 20:57:54 +0530 Subject: [PATCH 070/107] removed unnecessary fields Signed-off-by: bhavanakarwade --- apps/agent-service/src/agent-service.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index b2a466d59..92cb4a36d 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -501,7 +501,6 @@ export class AgentServiceService { throw error; } } - async _createLegacyConnectionInvitation(orgId: string, user: IUserRequestInterface, label: string): Promise<{ response; }> { From ed3c44772216895b611a476006baf3e8bd5917ee Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 20:59:21 +0530 Subject: [PATCH 071/107] resolved eslint errors Signed-off-by: bhavanakarwade --- apps/agent-service/src/agent-service.service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 92cb4a36d..65f575451 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -501,6 +501,8 @@ export class AgentServiceService { throw error; } } + + async _createLegacyConnectionInvitation(orgId: string, user: IUserRequestInterface, label: string): Promise<{ response; }> { From dbd21534639f94bb8bb5fcd702f36327771642f4 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 21:07:09 +0530 Subject: [PATCH 072/107] refactored fields Signed-off-by: bhavanakarwade --- apps/connection/src/connection.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 934665ad6..73f20e676 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -17,7 +17,7 @@ export class ConnectionController { /** * Create connection legacy invitation URL * @param payload - * @returns Created connection invitation URL + * @returns connection invitation URL */ @MessagePattern({ cmd: 'create-connection' }) async createLegacyConnectionInvitation(payload: IConnection): Promise { From eab25cd4ad92c4f008414aba09e8d874ee7988c7 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Wed, 27 Dec 2023 23:22:17 +0530 Subject: [PATCH 073/107] resolved comments Signed-off-by: bhavanakarwade --- apps/api-gateway/src/connection/dtos/connection.dto.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api-gateway/src/connection/dtos/connection.dto.ts b/apps/api-gateway/src/connection/dtos/connection.dto.ts index e3d25febd..4122d6755 100644 --- a/apps/api-gateway/src/connection/dtos/connection.dto.ts +++ b/apps/api-gateway/src/connection/dtos/connection.dto.ts @@ -29,7 +29,7 @@ export class CreateConnectionDto { @ApiPropertyOptional() @IsBoolean() @IsOptional() - @IsNotEmpty({ message: 'autoAcceptConnection should boolean' }) + @IsNotEmpty({ message: 'autoAcceptConnection should be boolean' }) autoAcceptConnection: boolean; orgId: string; From 83d7ff3f35c55421054d0026f07e5a751644095c Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 00:44:57 +0530 Subject: [PATCH 074/107] refactor:user exist api Signed-off-by: pranalidhanavade --- apps/user/interfaces/user.interface.ts | 4 ++-- apps/user/src/user.service.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index e704a16af..0e72a5fe0 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -113,10 +113,10 @@ export interface ISendVerificationEmail { } export interface ICheckUserDetails { - isExist: boolean; + isRegistered: boolean; isEmailVerified?: boolean; isFidoVerified?: boolean; - isSupabase?: boolean; + isAuthenticated?: boolean; } export interface UserCredentials { diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index d3c5038a0..cfe82bf9d 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -468,8 +468,8 @@ export class UserService { const invitations: OrgInvitations[] = await this.updateOrgInvitations(invitationsData['invitations']); invitationsData['invitations'] = invitations; - return invitationsData; + } catch (error) { this.logger.error(`Error in get invitations: ${JSON.stringify(error)}`); throw new RpcException(error.response ? error.response : error); @@ -735,14 +735,14 @@ export class UserService { throw new ConflictException(ResponseMessages.user.error.exists); } else if (null === userDetails) { return { - isExist: false + isRegistered: false }; } else { const userVerificationDetails = { isEmailVerified: userDetails.isEmailVerified, isFidoVerified: userDetails.isFidoVerified, - isSupabase: null !== userDetails.supabaseUserId && undefined !== userDetails.supabaseUserId, - isExist: true + isAuthenticated: null !== userDetails.supabaseUserId && undefined !== userDetails.supabaseUserId, + isRegistered: true }; return userVerificationDetails; } From a2e0e060a308accd824461da5170780d76c2955d Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 28 Dec 2023 11:09:35 +0530 Subject: [PATCH 075/107] refactor: webhook proof presentation api Signed-off-by: bhavanakarwade --- .../src/verification/dto/webhook-proof.dto.ts | 30 ++++++++--------- .../verification/verification.controller.ts | 33 +++++++++++-------- .../src/verification/verification.service.ts | 8 ++--- .../src/interfaces/verification.interface.ts | 8 ++--- .../src/verification.controller.ts | 8 +++-- apps/verification/src/verification.service.ts | 5 ++- 6 files changed, 48 insertions(+), 44 deletions(-) diff --git a/apps/api-gateway/src/verification/dto/webhook-proof.dto.ts b/apps/api-gateway/src/verification/dto/webhook-proof.dto.ts index 7a871e5eb..5b547c85a 100644 --- a/apps/api-gateway/src/verification/dto/webhook-proof.dto.ts +++ b/apps/api-gateway/src/verification/dto/webhook-proof.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from "@nestjs/swagger"; +import { ApiPropertyOptional } from "@nestjs/swagger"; import { IsOptional } from "class-validator"; interface IWebhookPresentationProof { @@ -7,57 +7,57 @@ interface IWebhookPresentationProof { connectionId } -export class WebhookPresentationProof { +export class WebhookPresentationProofDto { - @ApiProperty() + @ApiPropertyOptional() @IsOptional() metadata: object; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() _tags: IWebhookPresentationProof; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() id: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() createdAt: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() protocolVersion: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() state: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() connectionId: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() threadId: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() presentationId: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() autoAcceptProof: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() updatedAt: string; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() isVerified: boolean; - @ApiProperty() + @ApiPropertyOptional() @IsOptional() contextCorrelationId: string; } \ No newline at end of file diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index 86746f412..04eafde96 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -18,7 +18,7 @@ import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import { OutOfBandRequestProof, RequestProof } from './dto/request-proof.dto'; import { VerificationService } from './verification.service'; -import IResponseType from '@credebl/common/interfaces/response.interface'; +import IResponseType, { IResponse } from '@credebl/common/interfaces/response.interface'; import { Response } from 'express'; import { ResponseMessages } from '@credebl/common/response-messages'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; @@ -26,7 +26,7 @@ import { Roles } from '../authz/decorators/roles.decorator'; import { OrgRoles } from 'libs/org-roles/enums'; import { AuthGuard } from '@nestjs/passport'; import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { WebhookPresentationProof } from './dto/webhook-proof.dto'; +import { WebhookPresentationProofDto } from './dto/webhook-proof.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; import { ImageServiceService } from '@credebl/image-service'; import { User } from '../authz/decorators/user.decorator'; @@ -282,26 +282,31 @@ export class VerificationController { return res.status(HttpStatus.CREATED).json(finalResponse); } - @Post('wh/:id/proofs') + /** + * + * @param orgId + * @returns Proof presentation details + */ + @Post('wh/:orgId/proofs') @ApiOperation({ - summary: `Webhook proof presentation`, - description: `Webhook proof presentation` + summary: `Receive webhook proof presentation`, + description: `Handle proof presentations for a specified organization via a webhook` }) @ApiExcludeEndpoint() - @ApiResponse({ status: 201, description: 'Success', type: ApiResponseDto }) - @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) - @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) + @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) + @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) async webhookProofPresentation( - @Param('id') id: string, - @Body() proofPresentationPayload: WebhookPresentationProof, + @Param('orgId') orgId: string, + @Body() proofPresentationPayload: WebhookPresentationProofDto, @Res() res: Response - ): Promise { + ): Promise { this.logger.debug(`proofPresentationPayload ::: ${JSON.stringify(proofPresentationPayload)}`); - const webhookProofPresentation = await this.verificationService.webhookProofPresentation(id, proofPresentationPayload); - const finalResponse: IResponseType = { + const webhookProofPresentation = await this.verificationService.webhookProofPresentation(orgId, proofPresentationPayload); + const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.verification.success.fetch, - data: webhookProofPresentation.response + data: webhookProofPresentation }; return res.status(HttpStatus.CREATED).json(finalResponse); } diff --git a/apps/api-gateway/src/verification/verification.service.ts b/apps/api-gateway/src/verification/verification.service.ts index 3148fcd64..789b44676 100644 --- a/apps/api-gateway/src/verification/verification.service.ts +++ b/apps/api-gateway/src/verification/verification.service.ts @@ -3,7 +3,7 @@ import { ClientProxy } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { OutOfBandRequestProof, RequestProof } from './dto/request-proof.dto'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { WebhookPresentationProof } from './dto/webhook-proof.dto'; +import { WebhookPresentationProofDto } from './dto/webhook-proof.dto'; import { IProofRequestsSearchCriteria } from './interfaces/verification.interface'; @@ -62,9 +62,9 @@ export class VerificationService extends BaseService { return this.sendNats(this.verificationServiceProxy, 'verify-presentation', payload); } - webhookProofPresentation(id: string, proofPresentationPayload: WebhookPresentationProof): Promise<{ response: object }> { - const payload = { id, proofPresentationPayload }; - return this.sendNats(this.verificationServiceProxy, 'webhook-proof-presentation', payload); + webhookProofPresentation(orgId: string, proofPresentationPayload: WebhookPresentationProofDto): Promise { + const payload = { orgId, proofPresentationPayload }; + return this.sendNatsMessage(this.verificationServiceProxy, 'webhook-proof-presentation', payload); } /** diff --git a/apps/verification/src/interfaces/verification.interface.ts b/apps/verification/src/interfaces/verification.interface.ts index 44a3bfc57..943ecd6d6 100644 --- a/apps/verification/src/interfaces/verification.interface.ts +++ b/apps/verification/src/interfaces/verification.interface.ts @@ -99,10 +99,6 @@ interface IWebhookPresentationProof { connectionId } -export interface IWebhookProofPresentationPayload { - proofPresentationDto: IWebhookProofPresentation; - id: string; -} export interface IWebhookProofPresentation { metadata: object; _tags: IWebhookPresentationProof; @@ -119,9 +115,9 @@ export interface IWebhookProofPresentation { contextCorrelationId: string; } -export interface ProofPresentationPayload { +export interface IProofPresentation { proofPresentationPayload: IWebhookProofPresentation; - id: string; + orgId: string; } export interface IProofRequests { diff --git a/apps/verification/src/verification.controller.ts b/apps/verification/src/verification.controller.ts index 23946706e..f5b3403d3 100644 --- a/apps/verification/src/verification.controller.ts +++ b/apps/verification/src/verification.controller.ts @@ -1,7 +1,7 @@ import { Controller } from '@nestjs/common'; import { VerificationService } from './verification.service'; import { MessagePattern } from '@nestjs/microservices'; -import { IProofRequests, IRequestProof, ProofFormData, ProofPresentationPayload } from './interfaces/verification.interface'; +import { IProofPresentation, IProofRequests, IRequestProof, ProofFormData } from './interfaces/verification.interface'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { presentations } from '@prisma/client'; @@ -50,8 +50,12 @@ export class VerificationController { return this.verificationService.verifyPresentation(payload.id, payload.orgId); } + /** + * @param orgId + * @returns proof presentation details + */ @MessagePattern({ cmd: 'webhook-proof-presentation' }) - async webhookProofPresentation(payload: ProofPresentationPayload): Promise { + async webhookProofPresentation(payload: IProofPresentation): Promise { return this.verificationService.webhookProofPresentation(payload); } diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 476f9a582..cfc9b31cc 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -2,7 +2,7 @@ import { BadRequestException, HttpException, Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs/operators'; -import { IGetAllProofPresentations, IGetProofPresentationById, IProofRequestPayload, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, ProofFormDataPayload, ProofPresentationPayload } from './interfaces/verification.interface'; +import { IGetAllProofPresentations, IGetProofPresentationById, IProofPresentation, IProofRequestPayload, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, ProofFormDataPayload } from './interfaces/verification.interface'; import { VerificationRepository } from './repositories/verification.repository'; import { CommonConstants } from '@credebl/common/common.constant'; import { org_agents, organisation, presentations } from '@prisma/client'; @@ -377,9 +377,8 @@ export class VerificationService { } } - async webhookProofPresentation(proofPresentationPayload: ProofPresentationPayload): Promise { + async webhookProofPresentation(proofPresentationPayload: IProofPresentation): Promise { try { - const proofPresentation = await this.verificationRepository.storeProofPresentation(proofPresentationPayload); return proofPresentation; From 48d2f9667baa06838ad4e28173604af016e52829 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 28 Dec 2023 11:11:35 +0530 Subject: [PATCH 076/107] refactored fucntionality Signed-off-by: bhavanakarwade --- .../src/repositories/verification.repository.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index 5ed4bbd30..4cef984eb 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -3,7 +3,7 @@ import { PrismaService } from '@credebl/prisma-service'; import { Injectable, Logger, NotFoundException } from '@nestjs/common'; // eslint-disable-next-line camelcase import { org_agents, organisation, platform_config, presentations } from '@prisma/client'; -import { ProofPresentationPayload } from '../interfaces/verification.interface'; +import { IProofPresentation } from '../interfaces/verification.interface'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { IProofRequestsSearchCriteria } from 'apps/api-gateway/src/verification/interfaces/verification.interface'; @@ -111,16 +111,16 @@ export class VerificationRepository { } } - async storeProofPresentation(payload: ProofPresentationPayload): Promise { + async storeProofPresentation(payload: IProofPresentation): Promise { try { let organisationId: string; - const { proofPresentationPayload, id } = payload; + const { proofPresentationPayload, orgId } = payload; if (proofPresentationPayload?.contextCorrelationId) { const getOrganizationId = await this.getOrganizationByTenantId(proofPresentationPayload?.contextCorrelationId); organisationId = getOrganizationId?.orgId; } else { - organisationId = id; + organisationId = orgId; } const proofPresentationsDetails = await this.prisma.presentations.upsert({ @@ -146,7 +146,7 @@ export class VerificationRepository { }); return proofPresentationsDetails; } catch (error) { - this.logger.error(`Error in get saveIssuedCredentialDetails: ${error.message} `); + this.logger.error(`Error in get saveProofPresentationDetails: ${error.message} `); throw error; } } From 7cdfe0225a4ee88b6c432d9d4e02b9f63250248e Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 12:15:34 +0530 Subject: [PATCH 077/107] Resolved comments for error messages Signed-off-by: KulkarniShashank --- libs/common/src/response-messages/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index ffdac5a33..c763bc340 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -157,24 +157,24 @@ export const ResponseMessages = { exists: 'An agent name is already exist', orgNotFound: 'Organization not found', apiEndpointNotFound: 'apiEndpoint not found', - notAbleToSpinUpAgent: 'Agent not able to spin-up', - alreadySpinUp: 'Agent already spin-up', + notAbleToSpinUpAgent: 'Agent not able to spin up', + alreadySpinUp: 'Agent already spun up', agentUrl: 'Agent url not exist', - seedChar: 'seed must be at most 32 characters.', - validWalletName: 'Please enter valid wallet name, It allows only alphanumeric values', + seedChar: 'seed must be at most 32 characters', + validWalletName: 'Please enter valid wallet name. It allows only alphanumeric values', platformConfiguration: 'Platform configuration is missing or invalid', apiEndpoint: 'API endpoint is missing in the platform configuration', externalIp: 'External IP is missing in the platform configuration', stringExternalIp: 'External IP must be a string', agentProcess: 'Agent process is invalid or not in a completed state', - notAbleToSpinup: 'Agent not able to spin-up', + notAbleToSpinup: 'Agent not able to spun up', ledgerNotFound: 'Ledgers not found', agentNotExists: 'Agent not spun up for this organization', agentDown: 'Agent is down or not spun up', walletAlreadyCreated: 'Your wallet is already been created', walletAlreadyProcessing: 'Your wallet is already processing', - notAbleToSpinp: 'Agent not able to spin-up', - platformAdminNotAbleToSpinp: 'Platform-admin agent is not spun up', + notAbleToSpinp: 'Agent not able to spun up', + platformAdminNotAbleToSpinp: 'Platform admin agent is not spun up', seedCharCount: 'seed must be at most 32 characters' } }, From 8df1212719d8dbbdeb6e56d13bed89dfec0f023f Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 13:19:20 +0530 Subject: [PATCH 078/107] Added interface for the agent-service Signed-off-by: KulkarniShashank --- apps/agent-service/src/interface/agent-service.interface.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index 5314d317e..38debe437 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -346,7 +346,8 @@ export interface ICreateOrgAgent { interface IOrgAgentEndPoint { agentSpinUpStatus: number; - agentEndPoint: string + agentEndPoint: string; + apiKey; } export interface IOrgAgentsResponse { From 5b10295cb3def448cd928694cfb0a23cf6f8ee53 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 13:40:15 +0530 Subject: [PATCH 079/107] Common error function handling Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 115 +++++++----------- 1 file changed, 43 insertions(+), 72 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 703404b8c..92ce13423 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -80,7 +80,7 @@ export class VerificationService { } = { totalItems: getProofRequestsList.proofRequestsCount, hasNextPage: - proofRequestsSearchCriteria.pageSize * proofRequestsSearchCriteria.pageNumber < getProofRequestsList.proofRequestsCount, + proofRequestsSearchCriteria.pageSize * proofRequestsSearchCriteria.pageNumber < getProofRequestsList.proofRequestsCount, hasPreviousPage: 1 < proofRequestsSearchCriteria.pageNumber, nextPage: Number(proofRequestsSearchCriteria.pageNumber) + 1, previousPage: proofRequestsSearchCriteria.pageNumber - 1, @@ -94,14 +94,14 @@ export class VerificationService { throw new NotFoundException(ResponseMessages.verification.error.proofPresentationNotFound); } // const apiKey = await this._getOrgAgentApiKey(orgId); - // let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - // this.logger.log(`cachedApiKey----${apiKey}`); - // if (!apiKey || null === apiKey || undefined === apiKey) { - // apiKey = await this._getOrgAgentApiKey(orgId); - // } - // const payload = { apiKey, url }; - // const getProofPresentationsDetails = await this._getProofPresentations(payload); - // return getProofPresentationsDetails?.response; + // let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + // this.logger.log(`cachedApiKey----${apiKey}`); + // if (!apiKey || null === apiKey || undefined === apiKey) { + // apiKey = await this._getOrgAgentApiKey(orgId); + // } + // const payload = { apiKey, url }; + // const getProofPresentationsDetails = await this._getProofPresentations(payload); + // return getProofPresentationsDetails?.response; } catch (error) { if (404 === error.status) { @@ -164,10 +164,10 @@ export class VerificationService { const verificationMethodLabel = 'get-proof-presentation-by-id'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const payload = { apiKey, url }; @@ -175,15 +175,7 @@ export class VerificationService { return getProofPresentationById?.response; } catch (error) { this.logger.error(`[getProofPresentationById] - error in get proof presentation by id : ${JSON.stringify(error)}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { - throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, - statusCode: error?.status?.code - }); - - } else { - throw new RpcException(error.response ? error.response : error); - } + await this.verificationErrorHandling(error); } } @@ -273,10 +265,10 @@ export class VerificationService { const verificationMethodLabel = 'request-proof'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); // const apiKey = await this._getOrgAgentApiKey(requestProof.orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(requestProof.orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(requestProof.orgId); } const payload = { apiKey, url, proofRequestPayload }; @@ -284,15 +276,7 @@ export class VerificationService { return getProofPresentationById?.response; } catch (error) { this.logger.error(`[verifyPresentation] - error in verify presentation : ${JSON.stringify(error)}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { - throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, - statusCode: error?.status?.code - }); - - } else { - throw new RpcException(error.response ? error.response : error); - } + await this.verificationErrorHandling(error); } } @@ -347,25 +331,17 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const payload = { apiKey, url }; const getProofPresentationById = await this._verifyPresentation(payload); return getProofPresentationById?.response; } catch (error) { this.logger.error(`[verifyPresentation] - error in verify presentation : ${JSON.stringify(error)}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { - throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, - statusCode: error?.status?.code - }); - - } else { - throw new RpcException(error.response ? error.response : error); - } + await this.verificationErrorHandling(error); } } @@ -440,10 +416,10 @@ export class VerificationService { const verificationMethodLabel = 'create-request-out-of-band'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); // const apiKey = await this._getOrgAgentApiKey(outOfBandRequestProof.orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(outOfBandRequestProof.orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(outOfBandRequestProof.orgId); } const payload: IProofRequestPayload = { @@ -471,15 +447,7 @@ export class VerificationService { return true; } catch (error) { this.logger.error(`[sendOutOfBandPresentationRequest] - error in out of band proof request : ${error.message}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { - throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, - statusCode: error?.status?.code - }); - - } else { - throw new RpcException(error.response ? error.response : error); - } + await this.verificationErrorHandling(error); } } @@ -513,10 +481,10 @@ export class VerificationService { async sendOutOfBandProofRequest(payload: IProofRequestPayload, email: string, getAgentDetails: org_agents, organizationDetails: organisation): Promise { // const apiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); } payload.apiKey = apiKey; const getProofPresentation = await this._sendOutOfBandProofRequest(payload); @@ -788,10 +756,10 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); // const apiKey = await this._getOrgAgentApiKey(orgId); - let apiKey:string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(orgId); + if (!apiKey || null === apiKey || undefined === apiKey) { + apiKey = await this._getOrgAgentApiKey(orgId); } const payload = { apiKey, url }; @@ -886,15 +854,7 @@ export class VerificationService { return extractedDataArray; } catch (error) { this.logger.error(`[getProofFormData] - error in get proof form data : ${JSON.stringify(error)}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { - throw new RpcException({ - message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, - statusCode: error?.status?.code - }); - - } else { - throw new RpcException(error.response ? error.response : error); - } + await this.verificationErrorHandling(error); } } @@ -949,4 +909,15 @@ export class VerificationService { } } + verificationErrorHandling(error): void { + if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + throw new RpcException({ + message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, + statusCode: error?.status?.code + }); + + } else { + throw new RpcException(error.response ? error.response : error); + } + } } From 9f73e8e3d1ecb0a0eb44ab6700793d1025d06140 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 13:58:39 +0530 Subject: [PATCH 080/107] Common nats internal function Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 136 +++++------------- 1 file changed, 35 insertions(+), 101 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 92ce13423..a4b31a34c 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -122,27 +122,8 @@ export class VerificationService { response: string; }> { try { - - const pattern = { - cmd: 'agent-get-proof-presentations' - }; - - return this.verificationServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ( - { - response - })) - ).toPromise() - .catch(error => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.statusCode, - error: error.message - }, error.error); - }); + const pattern = { cmd: 'agent-get-proof-presentations' }; + return await this.natsCall(pattern, payload); } catch (error) { this.logger.error(`[_getProofPresentations] - error in get proof presentations : ${JSON.stringify(error)}`); throw error; @@ -193,22 +174,7 @@ export class VerificationService { cmd: 'agent-get-proof-presentation-by-id' }; - return this.verificationServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ( - { - response - })) - ).toPromise() - .catch(error => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.statusCode, - error: error.message - }, error.error); - }); + return await this.natsCall(pattern, payload); } catch (error) { this.logger.error(`[_getProofPresentationById] - error in get proof presentation by id : ${JSON.stringify(error)}`); throw error; @@ -294,22 +260,7 @@ export class VerificationService { cmd: 'agent-send-proof-request' }; - return this.verificationServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ( - { - response - })) - ).toPromise() - .catch(error => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.statusCode, - error: error.message - }, error.error); - }); + return await this.natsCall(pattern, payload); } catch (error) { this.logger.error(`[_sendProofRequest] - error in verify presentation : ${JSON.stringify(error)}`); throw error; @@ -359,22 +310,8 @@ export class VerificationService { cmd: 'agent-verify-presentation' }; - return this.verificationServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ( - { - response - })) - ).toPromise() - .catch(error => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.statusCode, - error: error.message - }, error.error); - }); + return await this.natsCall(pattern, payload); + } catch (error) { this.logger.error(`[_verifyPresentation] - error in verify presentation : ${JSON.stringify(error)}`); throw error; @@ -548,22 +485,8 @@ export class VerificationService { cmd: 'agent-send-out-of-band-proof-request' }; - return this.verificationServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ( - { - response - })) - ).toPromise() - .catch(error => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.statusCode, - error: error.message - }, error.error); - }); + return await this.natsCall(pattern, payload); + } catch (error) { this.logger.error(`[_sendOutOfBandProofRequest] - error in Out Of Band Presentation : ${JSON.stringify(error)}`); throw error; @@ -869,22 +792,7 @@ export class VerificationService { cmd: 'agent-proof-form-data' }; - return this.verificationServiceProxy - .send(pattern, payload) - .pipe( - map((response) => ( - { - response - })) - ).toPromise() - .catch(error => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.statusCode, - error: error.message - }, error.error); - }); + return await this.natsCall(pattern, payload); } catch (error) { this.logger.error(`[_getProofFormData] - error in proof form data : ${JSON.stringify(error)}`); throw error; @@ -920,4 +828,30 @@ export class VerificationService { throw new RpcException(error.response ? error.response : error); } } + + async natsCall(pattern: object, payload: object): Promise<{ + response: string; + }> { + try { + return this.verificationServiceProxy + .send(pattern, payload) + .pipe( + map((response) => ( + { + response + })) + ).toPromise() + .catch(error => { + this.logger.error(`catch: ${JSON.stringify(error)}`); + throw new HttpException( + { + status: error.statusCode, + error: error.message + }, error.error); + }); + } catch (error) { + this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`); + throw new RpcException(error.response ? error.response : error); + } + } } From f0ea3b109725b6d0787ca25c1d04fb196a95b763 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 28 Dec 2023 13:59:12 +0530 Subject: [PATCH 081/107] refactor: get all proof presentations api Signed-off-by: bhavanakarwade --- .../dto/get-all-proof-requests.dto.ts | 42 +++++++++----- .../verification/enum/verification.enum.ts | 6 ++ .../interfaces/verification.interface.ts | 5 +- .../verification/verification.controller.ts | 55 ++++++------------- .../src/verification/verification.service.ts | 9 ++- .../src/interfaces/verification.interface.ts | 4 +- .../repositories/verification.repository.ts | 30 ++++------ .../src/verification.controller.ts | 5 +- apps/verification/src/verification.service.ts | 52 +++++++----------- .../src/interfaces/verification.interface.ts | 23 ++++++++ 10 files changed, 117 insertions(+), 114 deletions(-) create mode 100644 apps/api-gateway/src/verification/enum/verification.enum.ts create mode 100644 libs/common/src/interfaces/verification.interface.ts diff --git a/apps/api-gateway/src/verification/dto/get-all-proof-requests.dto.ts b/apps/api-gateway/src/verification/dto/get-all-proof-requests.dto.ts index 5ed8cc376..6c8a8920d 100644 --- a/apps/api-gateway/src/verification/dto/get-all-proof-requests.dto.ts +++ b/apps/api-gateway/src/verification/dto/get-all-proof-requests.dto.ts @@ -1,27 +1,41 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsOptional } from "class-validator"; -import { SortValue } from "../../enum"; +import { ApiProperty } from '@nestjs/swagger'; +import { Transform, Type } from 'class-transformer'; +import { IsEnum, IsOptional } from 'class-validator'; +import { SortValue } from '../../enum'; +import { trim } from '@credebl/common/cast.helper'; +import { SortFields } from '../enum/verification.enum'; export class GetAllProofRequestsDto { - @ApiProperty({ required: false }) + @ApiProperty({ required: false, example: '1' }) @IsOptional() pageNumber: number = 1; - + @ApiProperty({ required: false }) @IsOptional() + @Transform(({ value }) => trim(value)) @Type(() => String) searchByText: string = ''; - - @ApiProperty({ required: false }) + + @ApiProperty({ required: false, example: '10' }) @IsOptional() pageSize: number = 10; - - @ApiProperty({ required: false }) + + @ApiProperty({ + enum: [SortValue.DESC, SortValue.ASC], + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() - sortByValue: string = SortValue.DESC; - - @ApiProperty({ required: false }) + @IsEnum(SortValue) + sortBy: string = SortValue.DESC; + + @ApiProperty({ + required: false + }) + @Transform(({ value }) => trim(value)) @IsOptional() - sorting: string = 'id'; + @IsEnum(SortFields) + sortField: string = SortFields.CREATED_DATE_TIME; + } + diff --git a/apps/api-gateway/src/verification/enum/verification.enum.ts b/apps/api-gateway/src/verification/enum/verification.enum.ts new file mode 100644 index 000000000..bcb8ab6fc --- /dev/null +++ b/apps/api-gateway/src/verification/enum/verification.enum.ts @@ -0,0 +1,6 @@ +export enum SortFields { + CREATED_DATE_TIME = 'createDateTime', + STATUS = 'state', + CONNECTION_ID = 'connectionId', + PRESENTATION_ID = 'presentationId' +} \ No newline at end of file diff --git a/apps/api-gateway/src/verification/interfaces/verification.interface.ts b/apps/api-gateway/src/verification/interfaces/verification.interface.ts index b23294011..845402db1 100644 --- a/apps/api-gateway/src/verification/interfaces/verification.interface.ts +++ b/apps/api-gateway/src/verification/interfaces/verification.interface.ts @@ -11,8 +11,9 @@ export interface IProofRequestAttribute { export interface IProofRequestsSearchCriteria { pageNumber: number; pageSize: number; - sorting: string; - sortByValue: string; + sortField: string; + sortBy: string; searchByText: string; user?: IUserRequestInterface } + diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index 86746f412..9c16d8866 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -18,7 +18,7 @@ import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import { OutOfBandRequestProof, RequestProof } from './dto/request-proof.dto'; import { VerificationService } from './verification.service'; -import IResponseType from '@credebl/common/interfaces/response.interface'; +import IResponseType, { IResponse } from '@credebl/common/interfaces/response.interface'; import { Response } from 'express'; import { ResponseMessages } from '@credebl/common/response-messages'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; @@ -32,6 +32,7 @@ import { ImageServiceService } from '@credebl/image-service'; import { User } from '../authz/decorators/user.decorator'; import { GetAllProofRequestsDto } from './dto/get-all-proof-requests.dto'; import { IProofRequestsSearchCriteria } from './interfaces/verification.interface'; +import { SortFields } from './enum/verification.enum'; @UseFilters(CustomExceptionFilter) @Controller() @@ -107,43 +108,21 @@ export class VerificationController { * Get all proof presentations * @param user * @param orgId - * @returns Get all proof presentation + * @returns All proof presentations details */ @Get('/orgs/:orgId/proofs') @ApiOperation({ - summary: `Get all proof presentations`, - description: `Get all proof presentations` - }) - - @ApiQuery({ - name: 'pageNumber', - type: Number, - required: false + summary: `Get all proof presentations by orgId`, + description: `Get all proof presentations by orgId` }) @ApiQuery({ - name: 'pageSize', - type: Number, + name: 'sortField', + enum: SortFields, required: false - }) - @ApiQuery({ - name: 'searchByText', - type: String, - required: false - }) - @ApiQuery({ - name: 'sorting', - type: String, - required: false - }) - @ApiQuery({ - name: 'sortByValue', - type: String, - required: false - }) - - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) - @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) - @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) + @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) @ApiBearerAuth() @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -152,21 +131,21 @@ export class VerificationController { @Res() res: Response, @User() user: IUserRequest, @Param('orgId') orgId: string - ): Promise { - const { pageSize, searchByText, pageNumber, sorting, sortByValue } = getAllProofRequests; + ): Promise { + const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllProofRequests; const proofRequestsSearchCriteria: IProofRequestsSearchCriteria = { pageNumber, searchByText, pageSize, - sorting, - sortByValue + sortField, + sortBy }; const proofPresentationDetails = await this.verificationService.getProofPresentations(proofRequestsSearchCriteria, user, orgId); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.verification.success.fetch, - data: proofPresentationDetails.response + data: proofPresentationDetails }; return res.status(HttpStatus.OK).json(finalResponse); } diff --git a/apps/api-gateway/src/verification/verification.service.ts b/apps/api-gateway/src/verification/verification.service.ts index 3148fcd64..f9f73259e 100644 --- a/apps/api-gateway/src/verification/verification.service.ts +++ b/apps/api-gateway/src/verification/verification.service.ts @@ -5,6 +5,7 @@ import { OutOfBandRequestProof, RequestProof } from './dto/request-proof.dto'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { WebhookPresentationProof } from './dto/webhook-proof.dto'; import { IProofRequestsSearchCriteria } from './interfaces/verification.interface'; +import { IProofPresentationList } from '@credebl/common/interfaces/verification.interface'; @Injectable() @@ -18,13 +19,11 @@ export class VerificationService extends BaseService { /** * Get all proof presentations * @param orgId - * @param user - * @returns Get all proof presentation + * @returns All proof presentations details */ - - getProofPresentations(proofRequestsSearchCriteria: IProofRequestsSearchCriteria, user: IUserRequest, orgId: string): Promise<{ response: object }> { + getProofPresentations(proofRequestsSearchCriteria: IProofRequestsSearchCriteria, user: IUserRequest, orgId: string): Promise { const payload = { proofRequestsSearchCriteria, user, orgId }; - return this.sendNats(this.verificationServiceProxy, 'get-proof-presentations', payload); + return this.sendNatsMessage(this.verificationServiceProxy, 'get-all-proof-presentations', payload); } /** diff --git a/apps/verification/src/interfaces/verification.interface.ts b/apps/verification/src/interfaces/verification.interface.ts index 44a3bfc57..dab4b54ad 100644 --- a/apps/verification/src/interfaces/verification.interface.ts +++ b/apps/verification/src/interfaces/verification.interface.ts @@ -133,8 +133,8 @@ export interface IProofRequests { export interface IProofRequestsSearchCriteria { pageNumber: number; pageSize: number; - sorting: string; - sortByValue: string; + sortField: string; + sortBy: string; searchByText: string; } diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index 5ed4bbd30..faf25c367 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -3,9 +3,10 @@ import { PrismaService } from '@credebl/prisma-service'; import { Injectable, Logger, NotFoundException } from '@nestjs/common'; // eslint-disable-next-line camelcase import { org_agents, organisation, platform_config, presentations } from '@prisma/client'; -import { ProofPresentationPayload } from '../interfaces/verification.interface'; +import { IProofRequestsSearchCriteria, ProofPresentationPayload } from '../interfaces/verification.interface'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { IProofRequestsSearchCriteria } from 'apps/api-gateway/src/verification/interfaces/verification.interface'; +import { IProofsPresentationsListCount } from '@credebl/common/interfaces/verification.interface'; +import { SortValue } from '@credebl/enum/enum'; @Injectable() export class VerificationRepository { @@ -57,23 +58,15 @@ export class VerificationRepository { user: IUserRequest, orgId: string, proofRequestsSearchCriteria: IProofRequestsSearchCriteria - ): Promise<{ - proofRequestsCount: number; - proofRequestsList: { - createDateTime: Date; - createdBy: string; - connectionId: string; - state: string; - orgId: string; - }[]; - }> { + ): Promise { try { const proofRequestsList = await this.prisma.presentations.findMany({ where: { orgId, OR: [ { connectionId: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } }, - { state: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } } + { state: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } }, + { presentationId: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } } ] }, select: { @@ -86,11 +79,9 @@ export class VerificationRepository { presentationId: true }, orderBy: { - [proofRequestsSearchCriteria?.sorting || 'createDateTime']: - 'DESC' === proofRequestsSearchCriteria?.sortByValue - ? 'desc' - : 'asc' + [proofRequestsSearchCriteria.sortField]: SortValue.ASC === proofRequestsSearchCriteria.sortBy ? 'asc' : 'desc' }, + take: Number(proofRequestsSearchCriteria.pageSize), skip: (proofRequestsSearchCriteria.pageNumber - 1) * proofRequestsSearchCriteria.pageSize }); @@ -99,8 +90,9 @@ export class VerificationRepository { orgId, OR: [ { connectionId: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } }, - { state: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } } - ] + { state: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } }, + { presentationId: { contains: proofRequestsSearchCriteria.searchByText, mode: 'insensitive' } } + ] } }); diff --git a/apps/verification/src/verification.controller.ts b/apps/verification/src/verification.controller.ts index 23946706e..d96f6de51 100644 --- a/apps/verification/src/verification.controller.ts +++ b/apps/verification/src/verification.controller.ts @@ -4,6 +4,7 @@ import { MessagePattern } from '@nestjs/microservices'; import { IProofRequests, IRequestProof, ProofFormData, ProofPresentationPayload } from './interfaces/verification.interface'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { presentations } from '@prisma/client'; +import { IProofPresentationList } from '@credebl/common/interfaces/verification.interface'; @Controller() export class VerificationController { @@ -14,8 +15,8 @@ export class VerificationController { * @param payload * @returns Get all proof presentation */ - @MessagePattern({ cmd: 'get-proof-presentations' }) - async getProofPresentations(payload: IProofRequests): Promise { + @MessagePattern({ cmd: 'get-all-proof-presentations' }) + async getProofPresentations(payload: IProofRequests): Promise { const { user, orgId, proofRequestsSearchCriteria} = payload; return this.verificationService.getProofPresentations(user, orgId, proofRequestsSearchCriteria); } diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 476f9a582..1b063d755 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -2,7 +2,7 @@ import { BadRequestException, HttpException, Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs/operators'; -import { IGetAllProofPresentations, IGetProofPresentationById, IProofRequestPayload, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, ProofFormDataPayload, ProofPresentationPayload } from './interfaces/verification.interface'; +import { IGetAllProofPresentations, IGetProofPresentationById, IProofRequestPayload, IProofRequestsSearchCriteria, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, ProofFormDataPayload, ProofPresentationPayload } from './interfaces/verification.interface'; import { VerificationRepository } from './repositories/verification.repository'; import { CommonConstants } from '@credebl/common/common.constant'; import { org_agents, organisation, presentations } from '@prisma/client'; @@ -13,7 +13,7 @@ import { OutOfBandVerification } from '../templates/out-of-band-verification.tem import { EmailDto } from '@credebl/common/dtos/email.dto'; import { sendEmail } from '@credebl/common/send-grid-helper-file'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { IProofRequestsSearchCriteria } from 'apps/api-gateway/src/verification/interfaces/verification.interface'; +import { IProofPresentationList } from '@credebl/common/interfaces/verification.interface'; @Injectable() export class VerificationService { @@ -39,28 +39,19 @@ export class VerificationService { user: IUserRequest, orgId: string, proofRequestsSearchCriteria: IProofRequestsSearchCriteria - ): Promise<{ - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: { - createDateTime: Date; - createdBy: string; - connectionId: string; - state: string; - orgId: string; - }[]; - }> { + ): Promise { try { const getProofRequestsList = await this.verificationRepository.getAllProofRequests( user, orgId, proofRequestsSearchCriteria ); - const issuedCredentialsResponse: { + + if (0 === getProofRequestsList.proofRequestsCount) { + throw new NotFoundException(ResponseMessages.verification.error.proofPresentationNotFound); + } + + const proofPresentationsResponse: { totalItems: number; hasNextPage: boolean; hasPreviousPage: boolean; @@ -73,6 +64,8 @@ export class VerificationService { connectionId: string; state: string; orgId: string; + presentationId: string; + id: string; }[]; } = { totalItems: getProofRequestsList.proofRequestsCount, @@ -85,20 +78,15 @@ export class VerificationService { data: getProofRequestsList.proofRequestsList }; - if (0 !== getProofRequestsList.proofRequestsCount) { - return issuedCredentialsResponse; - } else { - throw new NotFoundException(ResponseMessages.verification.error.proofPresentationNotFound); - } - } catch (error) { - if (404 === error.status) { - throw new NotFoundException(error.response.message); - } - throw new RpcException( - `[getConnections] [NATS call]- error in fetch proof requests details : ${JSON.stringify(error)}` - ); - } - } + return proofPresentationsResponse; + } catch (error) { + + this.logger.error( + `[getProofRequests] [NATS call]- error in fetch proof requests details : ${JSON.stringify(error)}` + ); + throw new RpcException(error.response ? error.response : error); + } +} /** * Consume agent API for get all proof presentations diff --git a/libs/common/src/interfaces/verification.interface.ts b/libs/common/src/interfaces/verification.interface.ts new file mode 100644 index 000000000..2fd271f69 --- /dev/null +++ b/libs/common/src/interfaces/verification.interface.ts @@ -0,0 +1,23 @@ +export interface IProofsPresentationsListCount { + proofRequestsCount: number; + proofRequestsList: IProofPresentationItem[]; + } + export interface IProofPresentationItem { + id: string, + createDateTime: Date; + createdBy: string; + connectionId: string; + state: string; + orgId: string; + presentationId: string; + } + export interface IProofPresentationList { + totalItems: number; + hasNextPage: boolean; + hasPreviousPage: boolean; + nextPage: number; + previousPage: number; + lastPage: number; + data: IProofPresentationItem[]; + } + From 6dd23450e46687393ce9cb9ecb6505365130c1ae Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 14:03:19 +0530 Subject: [PATCH 082/107] Solved duplicated code Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index a4b31a34c..a2062d474 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -144,7 +144,6 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const verificationMethodLabel = 'get-proof-presentation-by-id'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); - // const apiKey = await this._getOrgAgentApiKey(orgId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { @@ -230,7 +229,6 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const verificationMethodLabel = 'request-proof'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); - // const apiKey = await this._getOrgAgentApiKey(requestProof.orgId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { @@ -277,11 +275,10 @@ export class VerificationService { async verifyPresentation(id: string, orgId: string): Promise { try { const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId); - const verificationMethodLabel = 'accept-presentation'; - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); + + const verificationMethodLabel = 'accept-presentation'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); - // const apiKey = await this._getOrgAgentApiKey(orgId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { @@ -352,7 +349,6 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const verificationMethodLabel = 'create-request-out-of-band'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); - // const apiKey = await this._getOrgAgentApiKey(outOfBandRequestProof.orgId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { @@ -417,7 +413,6 @@ export class VerificationService { async sendOutOfBandProofRequest(payload: IProofRequestPayload, email: string, getAgentDetails: org_agents, organizationDetails: organisation): Promise { - // const apiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { @@ -678,7 +673,6 @@ export class VerificationService { const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); - // const apiKey = await this._getOrgAgentApiKey(orgId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { From 78e68a405528edea226ba200022c55a445628316 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 14:06:57 +0530 Subject: [PATCH 083/107] Solved duplicated code Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index a2062d474..86538fe6c 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -274,13 +274,13 @@ export class VerificationService { */ async verifyPresentation(id: string, orgId: string): Promise { try { - const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId); - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); - - const verificationMethodLabel = 'accept-presentation'; - const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); + const getAgentData = await this.verificationRepository.getAgentEndPoint(orgId); + const orgAgentTypeData = await this.verificationRepository.getOrgAgentType(getAgentData?.orgAgentTypeId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); + + const verificationMethod = 'accept-presentation'; + + const url = await this.getAgentUrl(verificationMethod, orgAgentTypeData, getAgentData?.agentEndPoint, getAgentData?.tenantId, '', id); if (!apiKey || null === apiKey || undefined === apiKey) { apiKey = await this._getOrgAgentApiKey(orgId); } From 0ee8f6188d37879a0283a08cbde74493aa6f88f7 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 14:09:38 +0530 Subject: [PATCH 084/107] Solved duplicated code Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 86538fe6c..1ac99e873 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -155,7 +155,7 @@ export class VerificationService { return getProofPresentationById?.response; } catch (error) { this.logger.error(`[getProofPresentationById] - error in get proof presentation by id : ${JSON.stringify(error)}`); - await this.verificationErrorHandling(error); + this.verificationErrorHandling(error); } } @@ -240,7 +240,7 @@ export class VerificationService { return getProofPresentationById?.response; } catch (error) { this.logger.error(`[verifyPresentation] - error in verify presentation : ${JSON.stringify(error)}`); - await this.verificationErrorHandling(error); + this.verificationErrorHandling(error); } } @@ -289,7 +289,7 @@ export class VerificationService { return getProofPresentationById?.response; } catch (error) { this.logger.error(`[verifyPresentation] - error in verify presentation : ${JSON.stringify(error)}`); - await this.verificationErrorHandling(error); + this.verificationErrorHandling(error); } } @@ -380,7 +380,7 @@ export class VerificationService { return true; } catch (error) { this.logger.error(`[sendOutOfBandPresentationRequest] - error in out of band proof request : ${error.message}`); - await this.verificationErrorHandling(error); + this.verificationErrorHandling(error); } } @@ -771,7 +771,7 @@ export class VerificationService { return extractedDataArray; } catch (error) { this.logger.error(`[getProofFormData] - error in get proof form data : ${JSON.stringify(error)}`); - await this.verificationErrorHandling(error); + this.verificationErrorHandling(error); } } From 50f19f7912a6234db5a907f8c6ebf256f655a2c6 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 28 Dec 2023 14:12:59 +0530 Subject: [PATCH 085/107] refactor interface fields Signed-off-by: bhavanakarwade --- .../src/verification/interfaces/verification.interface.ts | 2 +- .../src/verification/verification.controller.ts | 4 ++-- apps/api-gateway/src/verification/verification.service.ts | 4 ++-- .../verification/src/interfaces/verification.interface.ts | 4 ++-- .../src/repositories/verification.repository.ts | 8 ++++---- apps/verification/src/verification.service.ts | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/api-gateway/src/verification/interfaces/verification.interface.ts b/apps/api-gateway/src/verification/interfaces/verification.interface.ts index 845402db1..118b2a977 100644 --- a/apps/api-gateway/src/verification/interfaces/verification.interface.ts +++ b/apps/api-gateway/src/verification/interfaces/verification.interface.ts @@ -8,7 +8,7 @@ export interface IProofRequestAttribute { credentialName: string; } -export interface IProofRequestsSearchCriteria { +export interface IProofRequestSearchCriteria { pageNumber: number; pageSize: number; sortField: string; diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index 9c16d8866..c1f6c0328 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -31,7 +31,7 @@ import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler import { ImageServiceService } from '@credebl/image-service'; import { User } from '../authz/decorators/user.decorator'; import { GetAllProofRequestsDto } from './dto/get-all-proof-requests.dto'; -import { IProofRequestsSearchCriteria } from './interfaces/verification.interface'; +import { IProofRequestSearchCriteria } from './interfaces/verification.interface'; import { SortFields } from './enum/verification.enum'; @UseFilters(CustomExceptionFilter) @@ -133,7 +133,7 @@ export class VerificationController { @Param('orgId') orgId: string ): Promise { const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllProofRequests; - const proofRequestsSearchCriteria: IProofRequestsSearchCriteria = { + const proofRequestsSearchCriteria: IProofRequestSearchCriteria = { pageNumber, searchByText, pageSize, diff --git a/apps/api-gateway/src/verification/verification.service.ts b/apps/api-gateway/src/verification/verification.service.ts index f9f73259e..28a47e622 100644 --- a/apps/api-gateway/src/verification/verification.service.ts +++ b/apps/api-gateway/src/verification/verification.service.ts @@ -4,7 +4,7 @@ import { BaseService } from 'libs/service/base.service'; import { OutOfBandRequestProof, RequestProof } from './dto/request-proof.dto'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; import { WebhookPresentationProof } from './dto/webhook-proof.dto'; -import { IProofRequestsSearchCriteria } from './interfaces/verification.interface'; +import { IProofRequestSearchCriteria } from './interfaces/verification.interface'; import { IProofPresentationList } from '@credebl/common/interfaces/verification.interface'; @@ -21,7 +21,7 @@ export class VerificationService extends BaseService { * @param orgId * @returns All proof presentations details */ - getProofPresentations(proofRequestsSearchCriteria: IProofRequestsSearchCriteria, user: IUserRequest, orgId: string): Promise { + getProofPresentations(proofRequestsSearchCriteria: IProofRequestSearchCriteria, user: IUserRequest, orgId: string): Promise { const payload = { proofRequestsSearchCriteria, user, orgId }; return this.sendNatsMessage(this.verificationServiceProxy, 'get-all-proof-presentations', payload); } diff --git a/apps/verification/src/interfaces/verification.interface.ts b/apps/verification/src/interfaces/verification.interface.ts index dab4b54ad..66a685df4 100644 --- a/apps/verification/src/interfaces/verification.interface.ts +++ b/apps/verification/src/interfaces/verification.interface.ts @@ -125,12 +125,12 @@ export interface ProofPresentationPayload { } export interface IProofRequests { - proofRequestsSearchCriteria: IProofRequestsSearchCriteria; + proofRequestsSearchCriteria: IProofRequestSearchCriteria; user: IUserRequest; orgId: string; } -export interface IProofRequestsSearchCriteria { +export interface IProofRequestSearchCriteria { pageNumber: number; pageSize: number; sortField: string; diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index faf25c367..b1fb78022 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -3,9 +3,9 @@ import { PrismaService } from '@credebl/prisma-service'; import { Injectable, Logger, NotFoundException } from '@nestjs/common'; // eslint-disable-next-line camelcase import { org_agents, organisation, platform_config, presentations } from '@prisma/client'; -import { IProofRequestsSearchCriteria, ProofPresentationPayload } from '../interfaces/verification.interface'; +import { IProofRequestSearchCriteria, ProofPresentationPayload } from '../interfaces/verification.interface'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { IProofsPresentationsListCount } from '@credebl/common/interfaces/verification.interface'; +import { IProofPresentationsListCount } from '@credebl/common/interfaces/verification.interface'; import { SortValue } from '@credebl/enum/enum'; @Injectable() @@ -57,8 +57,8 @@ export class VerificationRepository { async getAllProofRequests( user: IUserRequest, orgId: string, - proofRequestsSearchCriteria: IProofRequestsSearchCriteria - ): Promise { + proofRequestsSearchCriteria: IProofRequestSearchCriteria + ): Promise { try { const proofRequestsList = await this.prisma.presentations.findMany({ where: { diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 1b063d755..b5ba8c1ba 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -2,7 +2,7 @@ import { BadRequestException, HttpException, Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; import { ClientProxy, RpcException } from '@nestjs/microservices'; import { map } from 'rxjs/operators'; -import { IGetAllProofPresentations, IGetProofPresentationById, IProofRequestPayload, IProofRequestsSearchCriteria, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, ProofFormDataPayload, ProofPresentationPayload } from './interfaces/verification.interface'; +import { IGetAllProofPresentations, IGetProofPresentationById, IProofRequestPayload, IProofRequestSearchCriteria, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, ProofFormDataPayload, ProofPresentationPayload } from './interfaces/verification.interface'; import { VerificationRepository } from './repositories/verification.repository'; import { CommonConstants } from '@credebl/common/common.constant'; import { org_agents, organisation, presentations } from '@prisma/client'; @@ -38,7 +38,7 @@ export class VerificationService { async getProofPresentations( user: IUserRequest, orgId: string, - proofRequestsSearchCriteria: IProofRequestsSearchCriteria + proofRequestsSearchCriteria: IProofRequestSearchCriteria ): Promise { try { const getProofRequestsList = await this.verificationRepository.getAllProofRequests( From da8246abf37079acbcc9cf3ce7faa58650a782a2 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 14:14:06 +0530 Subject: [PATCH 086/107] Solved duplicated code Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 1ac99e873..317b39fe8 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -141,11 +141,10 @@ export class VerificationService { try { const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId); - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); const verificationMethodLabel = 'get-proof-presentation-by-id'; - const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); + const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); + const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId, '', id); if (!apiKey || null === apiKey || undefined === apiKey) { apiKey = await this._getOrgAgentApiKey(orgId); } @@ -347,9 +346,9 @@ export class VerificationService { ]); const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); + let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); const verificationMethodLabel = 'create-request-out-of-band'; const url = await this.getAgentUrl(verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId); - let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); this.logger.log(`cachedApiKey----${apiKey}`); if (!apiKey || null === apiKey || undefined === apiKey) { apiKey = await this._getOrgAgentApiKey(outOfBandRequestProof.orgId); From eaa840f5fe28eb4582de335a0221d4a553e97de1 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 28 Dec 2023 14:15:21 +0530 Subject: [PATCH 087/107] refactor interface Signed-off-by: bhavanakarwade --- libs/common/src/interfaces/verification.interface.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common/src/interfaces/verification.interface.ts b/libs/common/src/interfaces/verification.interface.ts index 2fd271f69..97fd0d0cb 100644 --- a/libs/common/src/interfaces/verification.interface.ts +++ b/libs/common/src/interfaces/verification.interface.ts @@ -1,4 +1,4 @@ -export interface IProofsPresentationsListCount { +export interface IProofPresentationsListCount { proofRequestsCount: number; proofRequestsList: IProofPresentationItem[]; } From 267b130a74e7b6302260c50403cdae6f93f166b1 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 14:18:07 +0530 Subject: [PATCH 088/107] Solved duplicated code Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 317b39fe8..5ef754851 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -412,12 +412,12 @@ export class VerificationService { async sendOutOfBandProofRequest(payload: IProofRequestPayload, email: string, getAgentDetails: org_agents, organizationDetails: organisation): Promise { - let apiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); - this.logger.log(`cachedApiKey----${apiKey}`); - if (!apiKey || null === apiKey || undefined === apiKey) { - apiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); + let agentApiKey: string = await this.cacheService.get(CommonConstants.CACHE_APIKEY_KEY); + this.logger.log(`cachedApiKey----${agentApiKey}`); + if (!agentApiKey || null === agentApiKey || undefined === agentApiKey) { + agentApiKey = await this._getOrgAgentApiKey(getAgentDetails.orgId); } - payload.apiKey = apiKey; + payload.apiKey = agentApiKey; const getProofPresentation = await this._sendOutOfBandProofRequest(payload); if (!getProofPresentation) { @@ -479,7 +479,7 @@ export class VerificationService { cmd: 'agent-send-out-of-band-proof-request' }; - return await this.natsCall(pattern, payload); + return this.natsCall(pattern, payload); } catch (error) { this.logger.error(`[_sendOutOfBandProofRequest] - error in Out Of Band Presentation : ${JSON.stringify(error)}`); From e28d83d87e1590e3e4b71719098da9b45a8843b0 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 15:30:17 +0530 Subject: [PATCH 089/107] Add await for the oob proof request Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 5ef754851..956e995de 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -479,7 +479,7 @@ export class VerificationService { cmd: 'agent-send-out-of-band-proof-request' }; - return this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload); } catch (error) { this.logger.error(`[_sendOutOfBandProofRequest] - error in Out Of Band Presentation : ${JSON.stringify(error)}`); From ea9784659fe290d6e65101e3d77405f717502945 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 15:35:08 +0530 Subject: [PATCH 090/107] Resolve the sonar lint issue on the verification service Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 956e995de..8cfe9e9b1 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -695,10 +695,10 @@ export class VerificationService { for (const key in requestedAttributes) { if (requestedAttributes.hasOwnProperty(key)) { - const attribute = requestedAttributes[key]; - const attributeName = attribute.name; - const credDefId = attribute?.restrictions[0]?.cred_def_id; - const schemaId = attribute?.restrictions[0]?.schema_id; + const requestedAttributeKey = requestedAttributes[key]; + const attributeName = requestedAttributeKey.name; + const credDefId = requestedAttributeKey?.restrictions[0]?.cred_def_id; + const schemaId = requestedAttributeKey?.restrictions[0]?.schema_id; if (revealedAttrs.hasOwnProperty(key)) { const extractedData = { From 0e0b935677a8650bb306c00f524dc9217ced9988 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 15:39:33 +0530 Subject: [PATCH 091/107] Resolve the sonar lint duplication issuue on the verification service Signed-off-by: KulkarniShashank --- apps/verification/src/verification.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 8cfe9e9b1..8e9c95cca 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -811,14 +811,14 @@ export class VerificationService { } verificationErrorHandling(error): void { - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + if (!error && !error?.status && !error?.status?.message && !error?.status?.message?.error) { + + throw new RpcException(error.response ? error.response : error); + } else { throw new RpcException({ message: error?.status?.message?.error?.reason ? error?.status?.message?.error?.reason : error?.status?.message?.error, statusCode: error?.status?.code }); - - } else { - throw new RpcException(error.response ? error.response : error); } } From 5bf51b162bab012bb3bcc1bebb93ed8e9499cada Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 16:04:26 +0530 Subject: [PATCH 092/107] Resolved the comments Signed-off-by: KulkarniShashank --- libs/common/src/response-messages/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 35d16ec5a..0928dd0e1 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -160,7 +160,7 @@ export const ResponseMessages = { notAbleToSpinUpAgent: 'Agent not able to spin up', alreadySpinUp: 'Agent already spun up', agentUrl: 'Agent url not exist', - apiKeyNotExist:'Api key is not found', + apiKeyNotExist:'API key is not found', seedChar: 'seed must be at most 32 characters', validWalletName: 'Please enter valid wallet name. It allows only alphanumeric values', platformConfiguration: 'Platform configuration is missing or invalid', From 0f5f344d53432c1188f4563205185facae1f3a60 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 28 Dec 2023 16:16:04 +0530 Subject: [PATCH 093/107] refactored response messages Signed-off-by: bhavanakarwade --- apps/api-gateway/src/verification/verification.controller.ts | 2 +- libs/common/src/response-messages/index.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index a3c14bcc9..34b5edf86 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -284,7 +284,7 @@ export class VerificationController { const webhookProofPresentation = await this.verificationService.webhookProofPresentation(orgId, proofPresentationPayload); const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: ResponseMessages.verification.success.fetch, + message: ResponseMessages.verification.success.create, data: webhookProofPresentation }; return res.status(HttpStatus.CREATED).json(finalResponse); diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 327060ecd..dc60ff911 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -226,6 +226,7 @@ export const ResponseMessages = { verification: { success: { fetch: 'Proof presentations details fetched successfully.', + create: 'Proof presentations details created successfully.', proofFormData: 'Proof presentation form data received successfully.', send: 'Proof request send successfully.', verified: 'Proof presentation verified successfully.' From 94515d75369b3f1e933ff5d64173077c910bac43 Mon Sep 17 00:00:00 2001 From: bhavanakarwade Date: Thu, 28 Dec 2023 16:25:34 +0530 Subject: [PATCH 094/107] refactored response messages Signed-off-by: bhavanakarwade --- libs/common/src/response-messages/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index dc60ff911..44a50e481 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -226,7 +226,7 @@ export const ResponseMessages = { verification: { success: { fetch: 'Proof presentations details fetched successfully.', - create: 'Proof presentations details created successfully.', + create: 'Presentation of proof details created successfully.', proofFormData: 'Proof presentation form data received successfully.', send: 'Proof request send successfully.', verified: 'Proof presentation verified successfully.' From 9a9ca871b79ba3652ffc7bab05f80fed97f8eb55 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 17:19:21 +0530 Subject: [PATCH 095/107] refactor:platform settings api and user credentials api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/dto/add-user.dto.ts | 15 +++-- apps/api-gateway/src/user/user.controller.ts | 56 ++++++++++++------- apps/api-gateway/src/user/user.service.ts | 6 +- apps/user/src/user.controller.ts | 17 ++++-- apps/user/src/user.service.ts | 16 +++--- libs/common/src/response-messages/index.ts | 3 +- 6 files changed, 66 insertions(+), 47 deletions(-) diff --git a/apps/api-gateway/src/user/dto/add-user.dto.ts b/apps/api-gateway/src/user/dto/add-user.dto.ts index 05145b8d9..4f9639ed1 100644 --- a/apps/api-gateway/src/user/dto/add-user.dto.ts +++ b/apps/api-gateway/src/user/dto/add-user.dto.ts @@ -13,23 +13,22 @@ export class AddUserDetailsDto { @ApiProperty({ example: 'Alen' }) @IsNotEmpty({ message: 'First name is required' }) - @MinLength(2, { message: 'First name must be at least 2 characters.' }) - @MaxLength(50, { message: 'First name must be at most 50 characters.' }) + @MinLength(2, { message: 'First name must be at least 2 characters' }) + @MaxLength(50, { message: 'First name must be at most 50 characters' }) @IsString({ message: 'First name should be a string' }) firstName: string; @ApiProperty({ example: 'Harvey' }) @IsNotEmpty({ message: 'Last name is required' }) - @MinLength(2, { message: 'Last name must be at least 2 characters.' }) - @MaxLength(50, { message: 'Last name must be at most 50 characters.' }) + @MinLength(2, { message: 'Last name must be at least 2 characters' }) + @MaxLength(50, { message: 'Last name must be at most 50 characters' }) @IsString({ message: 'Last name should be a string' }) lastName: string; @ApiProperty() @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Password is required.' }) - @IsOptional() - password?: string; + @IsNotEmpty({ message: 'Password is required' }) + password: string; @ApiProperty({ example: 'false' }) @IsOptional() @@ -40,7 +39,7 @@ export class AddUserDetailsDto { export class AddPasskeyDetails { @ApiProperty() @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Password is required.' }) + @IsNotEmpty({ message: 'Password is required' }) password: string; } diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 6d7a69dd5..07bc23201 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -29,7 +29,7 @@ import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; import { Response } from 'express'; import { CommonService } from '@credebl/common'; -import IResponseType from '@credebl/common/interfaces/response.interface'; +import IResponse from '@credebl/common/interfaces/response.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { user } from '@prisma/client'; import { AuthGuard } from '@nestjs/passport'; @@ -94,7 +94,7 @@ export class UserController { @Res() res: Response ): Promise { const users = await this.userService.get(getAllUsersDto); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchUsers, data: users.response @@ -117,7 +117,7 @@ export class UserController { async getPublicProfile(@Param('username') username: string, @Res() res: Response): Promise { const userData = await this.userService.getPublicProfile(username); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchProfile, data: userData.response @@ -136,7 +136,7 @@ export class UserController { async getProfile(@User() reqUser: user, @Res() res: Response): Promise { const userData = await this.userService.getProfile(reqUser.id); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchProfile, data: userData @@ -145,6 +145,9 @@ export class UserController { return res.status(HttpStatus.OK).json(finalResponse); } + /** + * @returns platform and ecosystem settings + */ @Get('/platform-settings') @ApiOperation({ summary: 'Get all platform and ecosystem settings', @@ -159,7 +162,7 @@ export class UserController { const finalResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchPlatformSettings, - data: settings.response + data: settings }; return res.status(HttpStatus.OK).json(finalResponse); @@ -180,7 +183,7 @@ export class UserController { ): Promise { const userDetails = await this.userService.getUserActivities(reqUser.id, limit); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.userActivity, data: userDetails @@ -231,7 +234,7 @@ export class UserController { getAllInvitationsDto ); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchInvitations, data: invitations.response @@ -250,7 +253,7 @@ export class UserController { async checkUserExist(@Param() emailParam: EmailValidator, @Res() res: Response): Promise { const userDetails = await this.userService.checkUserExist(emailParam.email); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.checkEmail, data: userDetails @@ -258,17 +261,20 @@ export class UserController { return res.status(HttpStatus.OK).json(finalResponse); } - + /** + * @param credentialId + * @returns User credentials + */ @Get('/user-credentials/:credentialId') @ApiOperation({ summary: 'Get user credentials by Id', description: 'Get user credentials by Id' }) - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getUserCredentialsById(@Param('credentialId') credentialId: string, @Res() res: Response): Promise { const getUserCrdentialsById = await this.userService.getUserCredentialsById(credentialId); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.userCredentials, - data: getUserCrdentialsById.response + data: getUserCrdentialsById }; return res.status(HttpStatus.OK).json(finalResponse); } @@ -296,33 +302,36 @@ export class UserController { acceptRejectInvitation.invitationId = invitationId; const invitationRes = await this.userService.acceptRejectInvitaion(acceptRejectInvitation, reqUser.id); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: invitationRes.response }; return res.status(HttpStatus.CREATED).json(finalResponse); } - + /** + * @Body shareUserCredentials + * @returns User certificate url + */ @Post('/certificate') @ApiOperation({ summary: 'Share user certificate', description: 'Share user certificate' }) - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async shareUserCertificate( @Body() shareUserCredentials: CreateUserCertificateDto, @Res() res: Response - ): Promise { + ): Promise { const schemaIdParts = shareUserCredentials.schemaId.split(':'); // eslint-disable-next-line prefer-destructuring const title = schemaIdParts[2]; const imageBuffer = await this.userService.shareUserCertificate(shareUserCredentials); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: 'Certificate url generated successfully', + message: ResponseMessages.user.success.shareUserCertificate, label: title, - data: imageBuffer.response + data: imageBuffer }; return res.status(HttpStatus.CREATED).json(finalResponse); } @@ -344,7 +353,7 @@ export class UserController { updateUserProfileDto.id = userId; await this.userService.updateUserProfile(updateUserProfileDto); - const finalResponse: IResponseType = { + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.update }; @@ -370,6 +379,11 @@ export class UserController { return res.status(HttpStatus.OK).json(finalResponse); } + /** + * @Body platformSettings + * @returns platform and ecosystem settings updated status + */ + @Put('/platform-settings') @ApiOperation({ summary: 'Update platform and ecosystem settings', @@ -386,7 +400,7 @@ export class UserController { const finalResponse = { statusCode: HttpStatus.OK, - message: result.response + message: result }; return res.status(HttpStatus.OK).json(finalResponse); diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index 221c7d8d4..2859de6f9 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -63,7 +63,7 @@ export class UserService extends BaseService { shareUserCredentials: CreateUserCertificateDto ): Promise<{ response: Buffer }> { const payload = { shareUserCredentials}; - return this.sendNats(this.serviceProxy, 'share-user-certificate', payload); + return this.sendNatsMessage(this.serviceProxy, 'share-user-certificate', payload); } async get( @@ -91,10 +91,10 @@ export class UserService extends BaseService { async updatePlatformSettings(platformSettings: UpdatePlatformSettingsDto): Promise<{ response: string }> { const payload = { platformSettings }; - return this.sendNats(this.serviceProxy, 'update-platform-settings', payload); + return this.sendNatsMessage(this.serviceProxy, 'update-platform-settings', payload); } async getPlatformSettings(): Promise<{ response: object }> { - return this.sendNats(this.serviceProxy, 'fetch-platform-settings', ''); + return this.sendNatsMessage(this.serviceProxy, 'fetch-platform-settings', ''); } } diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 001995d69..59579ac01 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -68,8 +68,10 @@ export class UserController { async findUserByEmail(payload: { email }): Promise { return this.userService.findUserByEmail(payload); } - - + /** + * @param credentialId + * @returns User credentials + */ @MessagePattern({ cmd: 'get-user-credentials-by-id' }) async getUserCredentialsById(payload: { credentialId }): Promise { return this.userService.getUserCredentialsById(payload); @@ -94,9 +96,8 @@ export class UserController { } /** - * * @param payload - * @returns Share user certificate + * @returns User certificate url */ @MessagePattern({ cmd: 'share-user-certificate' }) async shareUserCertificate(payload: { @@ -152,12 +153,16 @@ export class UserController { async addPasskey(payload: { userEmail: string, userInfo: AddPasskeyDetails }): Promise { return this.userService.addPasskey(payload.userEmail, payload.userInfo); } - + /** + * @returns platform and ecosystem settings updated status + */ @MessagePattern({ cmd: 'update-platform-settings' }) async updatePlatformSettings(payload: { platformSettings: PlatformSettings }): Promise { return this.userService.updatePlatformSettings(payload.platformSettings); } - + /** + * @returns platform and ecosystem settings + */ @MessagePattern({ cmd: 'fetch-platform-settings' }) async getPlatformEcosystemSettings(): Promise { return this.userService.getPlatformEcosystemSettings(); diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index cfe82bf9d..b81c64ed8 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -457,6 +457,7 @@ export class UserService { if (!userData) { throw new NotFoundException(ResponseMessages.user.error.notFound); } + const invitationsData = await this.getOrgInvitations( userData.email, @@ -464,10 +465,11 @@ export class UserService { payload.pageNumber, payload.pageSize, payload.search - ); - - const invitations: OrgInvitations[] = await this.updateOrgInvitations(invitationsData['invitations']); - invitationsData['invitations'] = invitations; + ); + + const invitations: OrgInvitations[] = await this.updateOrgInvitations(invitationsData['invitations']); + invitationsData['invitations'] = invitations; + return invitationsData; } catch (error) { @@ -510,6 +512,8 @@ export class UserService { } async updateOrgInvitations(invitations: OrgInvitations[]): Promise { + + const updatedInvitations = []; for (const invitation of invitations) { @@ -546,10 +550,6 @@ export class UserService { } } - /** - * - * @returns - */ async shareUserCertificate(shareUserCertificate: ShareUserCertificate): Promise { const attributeArray = []; diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 404ef907a..a3600669a 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -18,7 +18,8 @@ export const ResponseMessages = { userCredentials: 'User credentials fetched successfully', platformEcosystemettings: 'Platform and ecosystem settings updated', fetchPlatformSettings: 'Platform settings fetched', - signUpUser:'User created successfully' + signUpUser:'User created successfully', + shareUserCertificate:'Certificate url generated successfully' }, error: { exists: 'User already exists', From f549285ff4a4e3612dade21e11eb86e0b882aa07 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 17:48:44 +0530 Subject: [PATCH 096/107] refactor:check user exist api flags Signed-off-by: pranalidhanavade --- apps/user/interfaces/user.interface.ts | 2 +- apps/user/src/user.service.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index 0e72a5fe0..5198953b7 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -113,7 +113,7 @@ export interface ISendVerificationEmail { } export interface ICheckUserDetails { - isRegistered: boolean; + isRegistrationCompleted: boolean; isEmailVerified?: boolean; isFidoVerified?: boolean; isAuthenticated?: boolean; diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index b81c64ed8..324bb890b 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -735,14 +735,14 @@ export class UserService { throw new ConflictException(ResponseMessages.user.error.exists); } else if (null === userDetails) { return { - isRegistered: false + isRegistrationCompleted: false }; } else { const userVerificationDetails = { isEmailVerified: userDetails.isEmailVerified, isFidoVerified: userDetails.isFidoVerified, isAuthenticated: null !== userDetails.supabaseUserId && undefined !== userDetails.supabaseUserId, - isRegistered: true + isRegistrationCompleted: true }; return userVerificationDetails; } From 32145fc7debe52ea9b81f6ef292edf10877b6550 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 19:33:27 +0530 Subject: [PATCH 097/107] Changes the path for the port-file Signed-off-by: KulkarniShashank --- apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh b/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh index 2c1c1879a..59a92970a 100644 --- a/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh +++ b/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh @@ -26,8 +26,8 @@ TESKDEFINITION_FAMILY=${20} SERVICE_NAME="${AGENCY}-${CONTAINER_NAME}-service" DESIRED_COUNT=1 EXTERNAL_IP=$(echo "$2" | tr -d '[:space:]') -ADMIN_PORT_FILE="$PWD/apps/agent-provisioning/AFJ/port-file/last-admin-port.txt" -INBOUND_PORT_FILE="$PWD/apps/agent-provisioning/AFJ/port-file/last-inbound-port.txt" +ADMIN_PORT_FILE="$PWD/agent-provisioning/AFJ/port-file/last-admin-port.txt" +INBOUND_PORT_FILE="$PWD/agent-provisioning/AFJ/port-file/last-inbound-port.txt" ADMIN_PORT=8001 INBOUND_PORT=9001 @@ -239,6 +239,7 @@ if [ $? -eq 0 ]; then "AGENT_ENDPOINT" : "${INTERNAL_IP}:${ADMIN_PORT}" } EOF + echo "Agent config created" else echo "===============" From ebaad1580662a0b64babbc2cb7056c2d59361cb4 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Thu, 28 Dec 2023 19:58:32 +0530 Subject: [PATCH 098/107] Create token folder for the agent Signed-off-by: KulkarniShashank --- .../AFJ/scripts/start_agent_ecs.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh b/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh index 59a92970a..e685f75a0 100644 --- a/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh +++ b/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh @@ -23,7 +23,6 @@ S3_BUCKET_ARN=${18} CLUSTER_NAME=${19} TESKDEFINITION_FAMILY=${20} -SERVICE_NAME="${AGENCY}-${CONTAINER_NAME}-service" DESIRED_COUNT=1 EXTERNAL_IP=$(echo "$2" | tr -d '[:space:]') ADMIN_PORT_FILE="$PWD/agent-provisioning/AFJ/port-file/last-admin-port.txt" @@ -74,13 +73,14 @@ last_used_inbound_port=$(increment_port "$last_used_inbound_port" "$last_used_in echo "$last_used_inbound_port" > "$INBOUND_PORT_FILE" INBOUND_PORT="$last_used_inbound_port" +SERVICE_NAME="${AGENCY}-${CONTAINER_NAME}-service-${ADMIN_PORT}" echo "Last used admin port: $ADMIN_PORT" echo "Last used inbound port: $INBOUND_PORT" echo "AGENT SPIN-UP STARTED" AGENT_ENDPOINT="${PROTOCOL}://${EXTERNAL_IP}:${INBOUND_PORT}" -cat <>/app/agent-provisioning/AFJ/agent-config/${AGENCY}_${CONTAINER_NAME}.json +cat </app/agent-provisioning/AFJ/agent-config/${AGENCY}_${CONTAINER_NAME}.json { "label": "${AGENCY}_${CONTAINER_NAME}", "walletId": "$WALLET_NAME", @@ -233,13 +233,19 @@ if [ $? -eq 0 ]; then done echo "Creating agent config" - cat <>${PWD}/agent-provisioning/AFJ/endpoints/${AGENCY}_${CONTAINER_NAME}.json + cat <${PWD}/agent-provisioning/AFJ/endpoints/${AGENCY}_${CONTAINER_NAME}.json { "CONTROLLER_ENDPOINT":"${EXTERNAL_IP}:${ADMIN_PORT}", "AGENT_ENDPOINT" : "${INTERNAL_IP}:${ADMIN_PORT}" } EOF + cat <${PWD}/agent-provisioning/AFJ/token/${AGENCY}_${CONTAINER_NAME}.json + { + "token" : "$token" + } +EOF + echo "Agent config created" else echo "===============" From a3e14a9342908d769b1632c1d015333ad455d465 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 20:08:47 +0530 Subject: [PATCH 099/107] refactor:get organization invitations api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.controller.ts | 9 +++-- apps/api-gateway/src/user/user.service.ts | 5 +-- apps/user/interfaces/user.interface.ts | 35 +++++--------------- apps/user/repositories/user.repository.ts | 4 +-- apps/user/src/user.controller.ts | 13 +++++--- apps/user/src/user.service.ts | 19 +++++------ libs/common/src/interfaces/user.interface.ts | 25 +++++++++++++- libs/common/src/response-messages/index.ts | 2 +- 8 files changed, 61 insertions(+), 51 deletions(-) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 07bc23201..c754681ee 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -191,6 +191,9 @@ export class UserController { return res.status(HttpStatus.OK).json(finalResponse); } + /** + * @returns Organization invitation data + */ @Get('/org-invitations') @ApiOperation({ @@ -223,7 +226,7 @@ export class UserController { @Query() getAllInvitationsDto: GetAllInvitationsDto, @User() reqUser: user, @Res() res: Response - ): Promise { + ): Promise { if (!Object.values(Invitation).includes(getAllInvitationsDto.status)) { throw new BadRequestException(ResponseMessages.user.error.invalidInvitationStatus); } @@ -237,7 +240,7 @@ export class UserController { const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchInvitations, - data: invitations.response + data: invitations }; return res.status(HttpStatus.OK).json(finalResponse); @@ -310,7 +313,7 @@ export class UserController { } /** * @Body shareUserCredentials - * @returns User certificate url + * @returns User certificate URL */ @Post('/certificate') @ApiOperation({ diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index 2859de6f9..75dbee98a 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -11,6 +11,7 @@ import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; import { IUsersProfile, ICheckUserDetails } from 'apps/user/interfaces/user.interface'; import { IUsersActivity } from 'libs/user-activity/interface'; +import { IUserInvitations } from '@credebl/common/interfaces/user.interface'; @Injectable() export class UserService extends BaseService { @@ -45,10 +46,10 @@ export class UserService extends BaseService { } - async invitations(id: string, status: string, getAllInvitationsDto: GetAllInvitationsDto): Promise<{ response: object }> { + async invitations(id: string, status: string, getAllInvitationsDto: GetAllInvitationsDto): Promise { const { pageNumber, pageSize, search } = getAllInvitationsDto; const payload = { id, status, pageNumber, pageSize, search }; - return this.sendNats(this.serviceProxy, 'get-org-invitations', payload); + return this.sendNatsMessage(this.serviceProxy, 'get-org-invitations', payload); } async acceptRejectInvitaion( diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index 5198953b7..9e2c420de 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -1,27 +1,3 @@ -export interface UserInvitations { - totalPages:number; - userInvitationsData:UserInvitationsData[]; -} -export interface UserInvitationsData { - orgRoles: OrgRole[]; - status: string; - id: string; - orgId: string; - organisation: Organisation; - userId: string; -} -export interface OrgRole { - id: string; - name: string; - description: string; -} - -export interface Organisation { - id: string; - name: string; - logoUrl: string; -} - export interface IUsersProfile { id: string; username?: string; @@ -113,13 +89,13 @@ export interface ISendVerificationEmail { } export interface ICheckUserDetails { - isRegistrationCompleted: boolean; + isExist: boolean; isEmailVerified?: boolean; isFidoVerified?: boolean; - isAuthenticated?: boolean; + isSupabase?: boolean; } - export interface UserCredentials { + export interface IUserCredentials { id: string; imageUrl?: string; credentialId?: string; @@ -150,6 +126,11 @@ export interface ISendVerificationEmail { orgRole: OrgRole; organisation: Organization } + interface OrgRole { + id: string; + name: string; + description: string; + } interface Organization { id: string, diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index 6dbb300cd..940dd67e5 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -6,7 +6,7 @@ import { PlatformSettings, ShareUserCertificate, UpdateUserProfile, - UserCredentials, + IUserCredentials, ISendVerificationEmail, IUsersProfile, IUserInformation, @@ -110,7 +110,7 @@ export class UserRepository { * @param id * @returns User profile data */ - async getUserCredentialsById(credentialId: string): Promise { + async getUserCredentialsById(credentialId: string): Promise { return this.prisma.user_credentials.findUnique({ where: { credentialId diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 59579ac01..b3ff31f22 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, UserCredentials, IUsersProfile, UserInvitations, IUserInformation, IUserSignIn} from '../interfaces/user.interface'; +import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, IUserCredentials, IUsersProfile, IUserInformation, IUserSignIn} from '../interfaces/user.interface'; import {IOrgUsers, Payload} from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; @@ -8,7 +8,7 @@ import { UserService } from './user.service'; import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; import { user } from '@prisma/client'; import { IUsersActivity } from 'libs/user-activity/interface'; -import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail } from '@credebl/common/interfaces/user.interface'; +import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations } from '@credebl/common/interfaces/user.interface'; @Controller() export class UserController { @@ -73,12 +73,15 @@ export class UserController { * @returns User credentials */ @MessagePattern({ cmd: 'get-user-credentials-by-id' }) - async getUserCredentialsById(payload: { credentialId }): Promise { + async getUserCredentialsById(payload: { credentialId }): Promise { return this.userService.getUserCredentialsById(payload); } + /** + * @returns Organization invitation data + */ @MessagePattern({ cmd: 'get-org-invitations' }) - async invitations(payload: { id; status; pageNumber; pageSize; search; }): Promise { + async invitations(payload: { id; status; pageNumber; pageSize; search; }): Promise { return this.userService.invitations(payload); } @@ -97,7 +100,7 @@ export class UserController { /** * @param payload - * @returns User certificate url + * @returns User certificate URL */ @MessagePattern({ cmd: 'share-user-certificate' }) async shareUserCertificate(payload: { diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 324bb890b..97c17b3cc 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -35,10 +35,9 @@ import { ShareUserCertificate, IOrgUsers, UpdateUserProfile, - UserCredentials, + IUserCredentials, IUserInformation, - IUsersProfile, - UserInvitations + IUsersProfile } from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; import { UserActivityService } from '@credebl/user-activity'; @@ -55,7 +54,7 @@ import { AwsService } from '@credebl/aws'; import puppeteer from 'puppeteer'; import { WorldRecordTemplate } from '../templates/world-record-template'; import { IUsersActivity } from 'libs/user-activity/interface'; -import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail } from '@credebl/common/interfaces/user.interface'; +import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations } from '@credebl/common/interfaces/user.interface'; @Injectable() export class UserService { @@ -402,7 +401,7 @@ export class UserService { } } - async getUserCredentialsById(payload: { credentialId }): Promise { + async getUserCredentialsById(payload: { credentialId }): Promise { try { const userCredentials = await this.userRepository.getUserCredentialsById(payload.credentialId); if (!userCredentials) { @@ -451,7 +450,7 @@ export class UserService { } } - async invitations(payload: { id; status; pageNumber; pageSize; search }): Promise { + async invitations(payload: { id; status; pageNumber; pageSize; search }): Promise { try { const userData = await this.userRepository.getUserById(payload.id); if (!userData) { @@ -484,7 +483,7 @@ export class UserService { pageNumber: number, pageSize: number, search = '' - ): Promise { + ): Promise { const pattern = { cmd: 'fetch-user-invitations' }; const payload = { email, @@ -735,14 +734,14 @@ export class UserService { throw new ConflictException(ResponseMessages.user.error.exists); } else if (null === userDetails) { return { - isRegistrationCompleted: false + isExist: false }; } else { const userVerificationDetails = { isEmailVerified: userDetails.isEmailVerified, isFidoVerified: userDetails.isFidoVerified, - isAuthenticated: null !== userDetails.supabaseUserId && undefined !== userDetails.supabaseUserId, - isRegistrationCompleted: true + isSupabase: null !== userDetails.supabaseUserId && undefined !== userDetails.supabaseUserId, + isExist: true }; return userVerificationDetails; } diff --git a/libs/common/src/interfaces/user.interface.ts b/libs/common/src/interfaces/user.interface.ts index 695b76747..6bcf7a6ea 100644 --- a/libs/common/src/interfaces/user.interface.ts +++ b/libs/common/src/interfaces/user.interface.ts @@ -13,4 +13,27 @@ export interface ISignInUser { email: string; username?: string; } - \ No newline at end of file + + export interface IUserInvitations { + totalPages:number; + userInvitationsData:IUserInvitationsData[]; + } + export interface IUserInvitationsData { + orgRoles: IOrgRole[]; + status: string; + id: string; + orgId: string; + organisation: IOrganisation; + userId: string; + } + export interface IOrgRole { + id: string; + name: string; + description: string; + } + + export interface IOrganisation { + id: string; + name: string; + logoUrl: string; + } \ No newline at end of file diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 8741bdf67..73dcf6746 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -19,7 +19,7 @@ export const ResponseMessages = { platformEcosystemettings: 'Platform and ecosystem settings updated', fetchPlatformSettings: 'Platform settings fetched', signUpUser:'User created successfully', - shareUserCertificate:'Certificate url generated successfully' + shareUserCertificate:'Certificate URL generated successfully' }, error: { exists: 'User already exists', From 89dbe8937ee94e507005eae5b9fb41c0b029bd00 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 21:20:55 +0530 Subject: [PATCH 100/107] refactor:user profile api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/dto/add-user.dto.ts | 2 +- apps/api-gateway/src/user/user.controller.ts | 17 +++++++++++++---- apps/api-gateway/src/user/user.service.ts | 11 ++++++----- apps/user/src/user.controller.ts | 8 ++++++-- apps/user/src/user.service.ts | 6 +++--- libs/common/src/response-messages/index.ts | 3 ++- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/apps/api-gateway/src/user/dto/add-user.dto.ts b/apps/api-gateway/src/user/dto/add-user.dto.ts index 4f9639ed1..4b3183706 100644 --- a/apps/api-gateway/src/user/dto/add-user.dto.ts +++ b/apps/api-gateway/src/user/dto/add-user.dto.ts @@ -36,7 +36,7 @@ export class AddUserDetailsDto { isPasskey?: boolean; } -export class AddPasskeyDetails { +export class AddPasskeyDetailsDtoDto { @ApiProperty() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'Password is required' }) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index c754681ee..dc3aabbe5 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -41,7 +41,7 @@ import { GetAllInvitationsDto } from './dto/get-all-invitations.dto'; import { GetAllUsersDto } from './dto/get-all-users.dto'; import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { AddPasskeyDetails } from './dto/add-user.dto'; +import { AddPasskeyDetailsDtoDto } from './dto/add-user.dto'; import { EmailValidator } from '../dtos/email-validator.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { Roles } from '../authz/decorators/roles.decorator'; @@ -339,12 +339,16 @@ export class UserController { return res.status(HttpStatus.CREATED).json(finalResponse); } + /** + * @Body updateUserProfileDto + * @returns User details + */ @Put('/') @ApiOperation({ summary: 'Update user profile', description: 'Update user profile' }) - @ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiBearerAuth() @UseGuards(AuthGuard('jwt')) async updateUserProfile( @@ -362,13 +366,18 @@ export class UserController { }; return res.status(HttpStatus.OK).json(finalResponse); } + /** + * @Body userInfo + * @returns User's profile update status + */ + @Put('/password/:email') @ApiOperation({ summary: 'Store user password details', description: 'Store user password details' }) @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() async addPasskey( - @Body() userInfo: AddPasskeyDetails, + @Body() userInfo: AddPasskeyDetailsDtoDto, @Param('email') email: string, @Res() res: Response ): Promise { @@ -376,7 +385,7 @@ export class UserController { const finalResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.update, - data: userDetails.response + data: userDetails }; return res.status(HttpStatus.OK).json(finalResponse); diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index 75dbee98a..d4c2384d4 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -6,12 +6,13 @@ import { AcceptRejectInvitationDto } from './dto/accept-reject-invitation.dto'; import { GetAllInvitationsDto } from './dto/get-all-invitations.dto'; import { GetAllUsersDto } from './dto/get-all-users.dto'; import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; -import { AddPasskeyDetails } from './dto/add-user.dto'; +import { AddPasskeyDetailsDtoDto } from './dto/add-user.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; import { IUsersProfile, ICheckUserDetails } from 'apps/user/interfaces/user.interface'; import { IUsersActivity } from 'libs/user-activity/interface'; import { IUserInvitations } from '@credebl/common/interfaces/user.interface'; +import { user } from '@prisma/client'; @Injectable() export class UserService extends BaseService { @@ -35,9 +36,9 @@ export class UserService extends BaseService { return this.sendNats(this.serviceProxy, 'get-user-credentials-by-id', payload); } - async updateUserProfile(updateUserProfileDto: UpdateUserProfileDto): Promise<{ response: object }> { + async updateUserProfile(updateUserProfileDto: UpdateUserProfileDto): Promise { const payload = { updateUserProfileDto }; - return this.sendNats(this.serviceProxy, 'update-user-profile', payload); + return this.sendNatsMessage(this.serviceProxy, 'update-user-profile', payload); } async findUserinSupabase(id: string): Promise<{ response: object }> { @@ -85,9 +86,9 @@ export class UserService extends BaseService { return this.sendNatsMessage(this.serviceProxy, 'get-user-activity', payload); } - async addPasskey(userEmail: string, userInfo: AddPasskeyDetails): Promise<{ response: string }> { + async addPasskey(userEmail: string, userInfo: AddPasskeyDetailsDtoDto): Promise<{ response: string }> { const payload = { userEmail, userInfo }; - return this.sendNats(this.serviceProxy, 'add-passkey', payload); + return this.sendNatsMessage(this.serviceProxy, 'add-passkey', payload); } async updatePlatformSettings(platformSettings: UpdatePlatformSettingsDto): Promise<{ response: string }> { diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index b3ff31f22..104311b3d 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,4 +1,4 @@ -import { AddPasskeyDetails, ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, IUserCredentials, IUsersProfile, IUserInformation, IUserSignIn} from '../interfaces/user.interface'; +import { ICheckUserDetails, PlatformSettings, ShareUserCertificate, UpdateUserProfile, IUserCredentials, IUsersProfile, IUserInformation, IUserSignIn} from '../interfaces/user.interface'; import {IOrgUsers, Payload} from '../interfaces/user.interface'; import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; @@ -9,6 +9,7 @@ import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; import { user } from '@prisma/client'; import { IUsersActivity } from 'libs/user-activity/interface'; import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations } from '@credebl/common/interfaces/user.interface'; +import { AddPasskeyDetailsDtoDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; @Controller() export class UserController { @@ -53,6 +54,9 @@ export class UserController { async getPublicProfile(payload: { username }): Promise { return this.userService.getPublicProfile(payload); } + /** + * @returns User details + */ @MessagePattern({ cmd: 'update-user-profile' }) async updateUserProfile(payload: { updateUserProfileDto: UpdateUserProfile }): Promise { return this.userService.updateUserProfile(payload.updateUserProfileDto); @@ -153,7 +157,7 @@ export class UserController { } @MessagePattern({ cmd: 'add-passkey' }) - async addPasskey(payload: { userEmail: string, userInfo: AddPasskeyDetails }): Promise { + async addPasskey(payload: { userEmail: string, userInfo: AddPasskeyDetailsDtoDto }): Promise { return this.userService.addPasskey(payload.userEmail, payload.userInfo); } /** diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 97c17b3cc..ae72f2b6d 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -27,7 +27,6 @@ import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; import { sendEmail } from '@credebl/common/send-grid-helper-file'; import { user } from '@prisma/client'; import { - AddPasskeyDetails, Attribute, ICheckUserDetails, OrgInvitations, @@ -55,6 +54,7 @@ import puppeteer from 'puppeteer'; import { WorldRecordTemplate } from '../templates/world-record-template'; import { IUsersActivity } from 'libs/user-activity/interface'; import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations } from '@credebl/common/interfaces/user.interface'; +import { AddPasskeyDetailsDtoDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; @Injectable() export class UserService { @@ -272,7 +272,7 @@ export class UserService { } } - async addPasskey(email: string, userInfo: AddPasskeyDetails): Promise { + async addPasskey(email: string, userInfo: AddPasskeyDetailsDtoDto): Promise { try { if (!email) { throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail); @@ -292,7 +292,7 @@ export class UserService { throw new NotFoundException(ResponseMessages.user.error.invalidEmail); } - return 'User updated successfully'; + return ResponseMessages.user.success.updateUserProfile; } catch (error) { this.logger.error(`Error in createUserForToken: ${JSON.stringify(error)}`); throw new RpcException(error.response ? error.response : error); diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 73dcf6746..1a4b04839 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -19,7 +19,8 @@ export const ResponseMessages = { platformEcosystemettings: 'Platform and ecosystem settings updated', fetchPlatformSettings: 'Platform settings fetched', signUpUser:'User created successfully', - shareUserCertificate:'Certificate URL generated successfully' + shareUserCertificate:'Certificate URL generated successfully', + updateUserProfile:'User updated successfully' }, error: { exists: 'User already exists', From b59b377c31c61369e5349514c6bdb406b227429a Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 23:20:26 +0530 Subject: [PATCH 101/107] refactor:user profile api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/dto/add-user.dto.ts | 2 +- apps/api-gateway/src/user/user.controller.ts | 4 ++-- apps/api-gateway/src/user/user.service.ts | 4 ++-- apps/user/src/user.controller.ts | 4 ++-- apps/user/src/user.service.ts | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/api-gateway/src/user/dto/add-user.dto.ts b/apps/api-gateway/src/user/dto/add-user.dto.ts index 4b3183706..f25b4ae25 100644 --- a/apps/api-gateway/src/user/dto/add-user.dto.ts +++ b/apps/api-gateway/src/user/dto/add-user.dto.ts @@ -36,7 +36,7 @@ export class AddUserDetailsDto { isPasskey?: boolean; } -export class AddPasskeyDetailsDtoDto { +export class AddPasskeyDetailsDto { @ApiProperty() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'Password is required' }) diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index dc3aabbe5..3af4539a5 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -41,7 +41,7 @@ import { GetAllInvitationsDto } from './dto/get-all-invitations.dto'; import { GetAllUsersDto } from './dto/get-all-users.dto'; import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { AddPasskeyDetailsDtoDto } from './dto/add-user.dto'; +import { AddPasskeyDetailsDto } from './dto/add-user.dto'; import { EmailValidator } from '../dtos/email-validator.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { Roles } from '../authz/decorators/roles.decorator'; @@ -377,7 +377,7 @@ export class UserController { @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() async addPasskey( - @Body() userInfo: AddPasskeyDetailsDtoDto, + @Body() userInfo: AddPasskeyDetailsDto, @Param('email') email: string, @Res() res: Response ): Promise { diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index d4c2384d4..fa36774db 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -6,7 +6,7 @@ import { AcceptRejectInvitationDto } from './dto/accept-reject-invitation.dto'; import { GetAllInvitationsDto } from './dto/get-all-invitations.dto'; import { GetAllUsersDto } from './dto/get-all-users.dto'; import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; -import { AddPasskeyDetailsDtoDto } from './dto/add-user.dto'; +import { AddPasskeyDetailsDto } from './dto/add-user.dto'; import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto'; import { CreateUserCertificateDto } from './dto/share-certificate.dto'; import { IUsersProfile, ICheckUserDetails } from 'apps/user/interfaces/user.interface'; @@ -86,7 +86,7 @@ export class UserService extends BaseService { return this.sendNatsMessage(this.serviceProxy, 'get-user-activity', payload); } - async addPasskey(userEmail: string, userInfo: AddPasskeyDetailsDtoDto): Promise<{ response: string }> { + async addPasskey(userEmail: string, userInfo: AddPasskeyDetailsDto): Promise<{ response: string }> { const payload = { userEmail, userInfo }; return this.sendNatsMessage(this.serviceProxy, 'add-passkey', payload); } diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 104311b3d..401e93e7c 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -9,7 +9,7 @@ import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; import { user } from '@prisma/client'; import { IUsersActivity } from 'libs/user-activity/interface'; import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations } from '@credebl/common/interfaces/user.interface'; -import { AddPasskeyDetailsDtoDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; +import { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; @Controller() export class UserController { @@ -157,7 +157,7 @@ export class UserController { } @MessagePattern({ cmd: 'add-passkey' }) - async addPasskey(payload: { userEmail: string, userInfo: AddPasskeyDetailsDtoDto }): Promise { + async addPasskey(payload: { userEmail: string, userInfo: AddPasskeyDetailsDto }): Promise { return this.userService.addPasskey(payload.userEmail, payload.userInfo); } /** diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index ae72f2b6d..e81546bc7 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -54,7 +54,7 @@ import puppeteer from 'puppeteer'; import { WorldRecordTemplate } from '../templates/world-record-template'; import { IUsersActivity } from 'libs/user-activity/interface'; import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations } from '@credebl/common/interfaces/user.interface'; -import { AddPasskeyDetailsDtoDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; +import { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; @Injectable() export class UserService { @@ -272,7 +272,7 @@ export class UserService { } } - async addPasskey(email: string, userInfo: AddPasskeyDetailsDtoDto): Promise { + async addPasskey(email: string, userInfo: AddPasskeyDetailsDto): Promise { try { if (!email) { throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail); From ca3d3f5420972abe1d9b03b0afbc61ad7d87721f Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 23:28:30 +0530 Subject: [PATCH 102/107] refactor:user profile update message Signed-off-by: pranalidhanavade --- libs/common/src/response-messages/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 1a4b04839..fd2711509 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -20,7 +20,7 @@ export const ResponseMessages = { fetchPlatformSettings: 'Platform settings fetched', signUpUser:'User created successfully', shareUserCertificate:'Certificate URL generated successfully', - updateUserProfile:'User updated successfully' + updateUserProfile:'User profile updated successfully' }, error: { exists: 'User already exists', From c3ef4c7e3374037f50eed27719dc1d1b7cdbc011 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Thu, 28 Dec 2023 23:37:30 +0530 Subject: [PATCH 103/107] refactor:user profile update Signed-off-by: pranalidhanavade --- apps/api-gateway/src/user/user.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index fa36774db..fff980f8e 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -33,7 +33,7 @@ export class UserService extends BaseService { async getUserCredentialsById(credentialId: string): Promise<{ response: object }> { const payload = { credentialId }; - return this.sendNats(this.serviceProxy, 'get-user-credentials-by-id', payload); + return this.sendNatsMessage(this.serviceProxy, 'get-user-credentials-by-id', payload); } async updateUserProfile(updateUserProfileDto: UpdateUserProfileDto): Promise { @@ -43,7 +43,7 @@ export class UserService extends BaseService { async findUserinSupabase(id: string): Promise<{ response: object }> { const payload = { id }; - return this.sendNats(this.serviceProxy, 'get-user-by-supabase', payload); + return this.sendNatsMessage(this.serviceProxy, 'get-user-by-supabase', payload); } @@ -58,7 +58,7 @@ export class UserService extends BaseService { userId: string ): Promise<{ response: string }> { const payload = { acceptRejectInvitation, userId }; - return this.sendNats(this.serviceProxy, 'accept-reject-invitations', payload); + return this.sendNatsMessage(this.serviceProxy, 'accept-reject-invitations', payload); } async shareUserCertificate( From d82af87df00e3f35b6dabda750e8d499ee49efdb Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Fri, 29 Dec 2023 13:21:34 +0530 Subject: [PATCH 104/107] fix: create service name random in shell script Signed-off-by: KulkarniShashank --- Dockerfiles/Dockerfile.agnet-provisioning | 11 +++++++++++ .../AFJ/scripts/start_agent_ecs.sh | 15 +++++++++++++-- .../src/agent-provisioning.service.ts | 4 ++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Dockerfiles/Dockerfile.agnet-provisioning b/Dockerfiles/Dockerfile.agnet-provisioning index 134846452..ce8acdd0d 100644 --- a/Dockerfiles/Dockerfile.agnet-provisioning +++ b/Dockerfiles/Dockerfile.agnet-provisioning @@ -1,6 +1,11 @@ # Stage 1: Build the application FROM node:18-alpine as build RUN npm install -g pnpm +# Install AWS CLI +RUN apk update +RUN apk add openssh-client +RUN apk update +RUN apk add aws-cli # Set the working directory WORKDIR /app @@ -23,6 +28,12 @@ RUN pnpm run build agent-provisioning # Stage 2: Create the final image FROM node:18-alpine as prod +# Install AWS CLI +RUN apk update +RUN apk add openssh-client +RUN apk update +RUN apk add aws-cli + WORKDIR /app RUN npm install -g pnpm diff --git a/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh b/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh index e685f75a0..86c89ed85 100644 --- a/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh +++ b/apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh @@ -24,6 +24,18 @@ CLUSTER_NAME=${19} TESKDEFINITION_FAMILY=${20} DESIRED_COUNT=1 + +generate_random_string() { + echo "$(date +%s%N | sha256sum | base64 | head -c 12)" +} + +# Call the function to generate a random string +random_string=$(generate_random_string) + +# Print the generated random string +echo "Random String: $random_string" + +SERVICE_NAME="${AGENCY}-${CONTAINER_NAME}-service-${random_string}" EXTERNAL_IP=$(echo "$2" | tr -d '[:space:]') ADMIN_PORT_FILE="$PWD/agent-provisioning/AFJ/port-file/last-admin-port.txt" INBOUND_PORT_FILE="$PWD/agent-provisioning/AFJ/port-file/last-inbound-port.txt" @@ -73,7 +85,6 @@ last_used_inbound_port=$(increment_port "$last_used_inbound_port" "$last_used_in echo "$last_used_inbound_port" > "$INBOUND_PORT_FILE" INBOUND_PORT="$last_used_inbound_port" -SERVICE_NAME="${AGENCY}-${CONTAINER_NAME}-service-${ADMIN_PORT}" echo "Last used admin port: $ADMIN_PORT" echo "Last used inbound port: $INBOUND_PORT" echo "AGENT SPIN-UP STARTED" @@ -242,7 +253,7 @@ EOF cat <${PWD}/agent-provisioning/AFJ/token/${AGENCY}_${CONTAINER_NAME}.json { - "token" : "$token" + "token" : "" } EOF diff --git a/apps/agent-provisioning/src/agent-provisioning.service.ts b/apps/agent-provisioning/src/agent-provisioning.service.ts index 7dc510df5..465e4087d 100644 --- a/apps/agent-provisioning/src/agent-provisioning.service.ts +++ b/apps/agent-provisioning/src/agent-provisioning.service.ts @@ -22,10 +22,10 @@ export class AgentProvisioningService { async walletProvision(payload: IWalletProvision): Promise { try { - const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, afjVersion, tenant, indyLedger, apiKey } = payload; + const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, afjVersion, tenant, indyLedger } = payload; if (agentType === AgentType.AFJ) { // The wallet provision command is used to invoke a shell script - const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${afjVersion} ${indyLedger} ${apiKey} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`; + const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${afjVersion} ${indyLedger} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`; const spinUpResponse: object = new Promise(async (resolve) => { await exec(walletProvision, async (err, stdout, stderr) => { From 9845b494ac6c22ab00372bd0dd179b79bd0c74d4 Mon Sep 17 00:00:00 2001 From: pranalidhanavade Date: Fri, 29 Dec 2023 13:26:01 +0530 Subject: [PATCH 105/107] fix:get user details api Signed-off-by: pranalidhanavade --- apps/api-gateway/src/authz/jwt.strategy.ts | 4 ++-- apps/api-gateway/src/user/user.controller.ts | 6 +++--- apps/api-gateway/src/user/user.service.ts | 18 +++++++++--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/api-gateway/src/authz/jwt.strategy.ts b/apps/api-gateway/src/authz/jwt.strategy.ts index c435799d2..e4dcdae29 100644 --- a/apps/api-gateway/src/authz/jwt.strategy.ts +++ b/apps/api-gateway/src/authz/jwt.strategy.ts @@ -27,12 +27,12 @@ export class JwtStrategy extends PassportStrategy(Strategy) { const userDetails = await this.usersService.findUserinSupabase(payload.sub); - if (!userDetails.response) { + if (!userDetails) { throw new NotFoundException('User not found'); } return { - ...userDetails.response, + ...userDetails, ...payload }; } diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index 3af4539a5..ae1f92896 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -97,7 +97,7 @@ export class UserController { const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchUsers, - data: users.response + data: users }; return res.status(HttpStatus.OK).json(finalResponse); @@ -120,7 +120,7 @@ export class UserController { const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchProfile, - data: userData.response + data: userData }; return res.status(HttpStatus.OK).json(finalResponse); @@ -307,7 +307,7 @@ export class UserController { const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: invitationRes.response + message: invitationRes }; return res.status(HttpStatus.CREATED).json(finalResponse); } diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index fff980f8e..77889dc39 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -25,13 +25,13 @@ export class UserService extends BaseService { return this.sendNatsMessage(this.serviceProxy, 'get-user-profile', payload); } - async getPublicProfile(username: string): Promise<{ response: object }> { + async getPublicProfile(username: string): Promise { const payload = { username }; return this.sendNatsMessage(this.serviceProxy, 'get-user-public-profile', payload); } - async getUserCredentialsById(credentialId: string): Promise<{ response: object }> { + async getUserCredentialsById(credentialId: string): Promise { const payload = { credentialId }; return this.sendNatsMessage(this.serviceProxy, 'get-user-credentials-by-id', payload); } @@ -41,7 +41,7 @@ export class UserService extends BaseService { return this.sendNatsMessage(this.serviceProxy, 'update-user-profile', payload); } - async findUserinSupabase(id: string): Promise<{ response: object }> { + async findUserinSupabase(id: string): Promise { const payload = { id }; return this.sendNatsMessage(this.serviceProxy, 'get-user-by-supabase', payload); } @@ -56,21 +56,21 @@ export class UserService extends BaseService { async acceptRejectInvitaion( acceptRejectInvitation: AcceptRejectInvitationDto, userId: string - ): Promise<{ response: string }> { + ): Promise { const payload = { acceptRejectInvitation, userId }; return this.sendNatsMessage(this.serviceProxy, 'accept-reject-invitations', payload); } async shareUserCertificate( shareUserCredentials: CreateUserCertificateDto - ): Promise<{ response: Buffer }> { + ): Promise { const payload = { shareUserCredentials}; return this.sendNatsMessage(this.serviceProxy, 'share-user-certificate', payload); } async get( getAllUsersDto: GetAllUsersDto - ): Promise<{ response: object }> { + ): Promise { const { pageNumber, pageSize, search } = getAllUsersDto; const payload = { pageNumber, pageSize, search }; return this.sendNatsMessage(this.serviceProxy, 'fetch-users', payload); @@ -86,17 +86,17 @@ export class UserService extends BaseService { return this.sendNatsMessage(this.serviceProxy, 'get-user-activity', payload); } - async addPasskey(userEmail: string, userInfo: AddPasskeyDetailsDto): Promise<{ response: string }> { + async addPasskey(userEmail: string, userInfo: AddPasskeyDetailsDto): Promise { const payload = { userEmail, userInfo }; return this.sendNatsMessage(this.serviceProxy, 'add-passkey', payload); } - async updatePlatformSettings(platformSettings: UpdatePlatformSettingsDto): Promise<{ response: string }> { + async updatePlatformSettings(platformSettings: UpdatePlatformSettingsDto): Promise { const payload = { platformSettings }; return this.sendNatsMessage(this.serviceProxy, 'update-platform-settings', payload); } - async getPlatformSettings(): Promise<{ response: object }> { + async getPlatformSettings(): Promise { return this.sendNatsMessage(this.serviceProxy, 'fetch-platform-settings', ''); } } From 4754574bc628023d05b61cb9997cd40d637eb7a2 Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Fri, 29 Dec 2023 14:03:58 +0530 Subject: [PATCH 106/107] Solved issue regarding the sonar lint Signed-off-by: KulkarniShashank --- Dockerfiles/Dockerfile.agnet-provisioning | 26 +++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Dockerfiles/Dockerfile.agnet-provisioning b/Dockerfiles/Dockerfile.agnet-provisioning index ce8acdd0d..3a5a6d8eb 100644 --- a/Dockerfiles/Dockerfile.agnet-provisioning +++ b/Dockerfiles/Dockerfile.agnet-provisioning @@ -1,11 +1,15 @@ # Stage 1: Build the application FROM node:18-alpine as build -RUN npm install -g pnpm +# RUN npm install -g pnpm # Install AWS CLI -RUN apk update -RUN apk add openssh-client -RUN apk update -RUN apk add aws-cli +# RUN apk update +# RUN apk add openssh-client +# RUN apk update +# RUN apk add aws-cli +RUN npm install -g pnpm \ + && apk update \ + && apk add openssh-client \ + && apk add aws-cli # Set the working directory WORKDIR /app @@ -29,10 +33,14 @@ RUN pnpm run build agent-provisioning # Stage 2: Create the final image FROM node:18-alpine as prod # Install AWS CLI -RUN apk update -RUN apk add openssh-client -RUN apk update -RUN apk add aws-cli +# RUN apk update +# RUN apk add openssh-client +# RUN apk update +# RUN apk add aws-cli +RUN npm install -g pnpm \ + && apk update \ + && apk add openssh-client \ + && apk add aws-cli WORKDIR /app RUN npm install -g pnpm From c56a543372e13fea07e9f0815131ff60f6908ead Mon Sep 17 00:00:00 2001 From: KulkarniShashank Date: Fri, 29 Dec 2023 16:26:19 +0530 Subject: [PATCH 107/107] Solved issue in dockerfile.agent-provisioning Signed-off-by: KulkarniShashank --- ...isioning => Dockerfile.agent-provisioning} | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) rename Dockerfiles/{Dockerfile.agnet-provisioning => Dockerfile.agent-provisioning} (69%) diff --git a/Dockerfiles/Dockerfile.agnet-provisioning b/Dockerfiles/Dockerfile.agent-provisioning similarity index 69% rename from Dockerfiles/Dockerfile.agnet-provisioning rename to Dockerfiles/Dockerfile.agent-provisioning index fffb90839..5c9c4f19d 100644 --- a/Dockerfiles/Dockerfile.agnet-provisioning +++ b/Dockerfiles/Dockerfile.agent-provisioning @@ -1,6 +1,15 @@ # Stage 1: Build the application FROM node:18-alpine as build -RUN npm install -g pnpm +# RUN npm install -g pnpm +# Install AWS CLI +# RUN apk update +# RUN apk add openssh-client +# RUN apk update +# RUN apk add aws-cli +RUN npm install -g pnpm --ignore-scripts \ + && apk update \ + && apk add openssh-client \ + && apk add aws-cli # Set the working directory WORKDIR /app @@ -23,24 +32,35 @@ RUN pnpm run build agent-provisioning # Stage 2: Create the final image FROM node:18-alpine as prod +# Install AWS CLI +# RUN apk update +# RUN apk add openssh-client +# RUN apk update +# RUN apk add aws-cli +RUN npm install -g pnpm --ignore-scripts \ + && apk update \ + && apk add openssh-client \ + && apk add aws-cli + WORKDIR /app -RUN npm install -g pnpm RUN mkdir -p ./agent-provisioning/AFJ/endpoints RUN mkdir -p ./agent-provisioning/AFJ/agent-config +RUN mkdir -p ./agent-provisioning/AFJ/port-file +RUN mkdir -p ./agent-provisioning/AFJ/token # Copy the compiled code COPY --from=build /app/dist/apps/agent-provisioning/ ./dist/apps/agent-provisioning/ COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/apps/agent-provisioning/AFJ/scripts ./agent-provisioning/AFJ/scripts -COPY --from=build /app/apps/agent-provisioning/AFJ/port-files ./agent-provisioning/AFJ/port-file +COPY --from=build /app/apps/agent-provisioning/AFJ/port-file ./agent-provisioning/AFJ/port-file # Set permissions RUN chmod +x /app/agent-provisioning/AFJ/scripts/start_agent.sh RUN chmod +x /app/agent-provisioning/AFJ/scripts/start_agent_ecs.sh RUN chmod 777 /app/agent-provisioning/AFJ/endpoints RUN chmod 777 /app/agent-provisioning/AFJ/agent-config - +RUN chmod 777 /app/agent-provisioning/AFJ/token # Copy the libs folder COPY libs/ ./libs/