From 91e5052be83d7b31d14646f25a9f7dfaf9623cee Mon Sep 17 00:00:00 2001 From: Sahil Kamble Date: Tue, 29 Apr 2025 16:30:35 +0530 Subject: [PATCH 01/23] chore: removed unwanted values (#1212) Signed-off-by: Sahil Kamble --- .env.demo | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.env.demo b/.env.demo index dcb223caf..f9130b987 100644 --- a/.env.demo +++ b/.env.demo @@ -86,22 +86,22 @@ DEEPLINK_DOMAIN='https://link.credebl.id?url=' ENABLE_CORS_IP_LIST=http://localhost:3000, http://localhost:3001, http://localhost:5000,http://localhost:8085,https://verify.credebl.id,https://verifyed.credebl.id,https://verify-api.credebl.id,https://qa.credebl.id,https://dev.credebl.id,https://credebl.id -USER_NKEY_SEED=SUAILBO6CYQF4RPIZYCVCFRIOMJ7BW33PFZDFEZKOHV65MN3W37FFJA3JY -API_GATEWAY_NKEY_SEED=SUAI7SDZAHS24I7JWOB77BK6EFE3ZS3NCF5FW22PMWCXGE56OBPYHK5734 -ORGANIZATION_NKEY_SEED=SUABORS4UFEV2OAWNEXB7JA76XNOF7A6YJAFOGRZTWOEGCXER36P2NP7JQ -AGENT_PROVISIONING_NKEY_SEED=SUAIUEPEC5D4KMTLK45UOPZ45JQ5QUMMIIJY2UT37RMQE6GENBTJTT2MSQ -AGENT_SERVICE_NKEY_SEED=SUABOFFEQNQY7YR4BIZDJENJ5T24CCDYOYTVHBKQLEWTZUTPTL3EQ3IZ3U -VERIFICATION_NKEY_SEED=SUAOTKYQMN6RGVWLZII22A4EFURAT65H4PGU3G5QXKM427HZ3JKIQZ7KU4 -LEDGER_NKEY_SEED=SUABKZWIZCMUROUKCSHL774UOLKFQZR2UPQXII5FCGXHF25GFQX2XLIPLI -ISSUANCE_NKEY_SEED=SUAG7GEESSHO2ZF4J2IUKB6QPF4ENTLO7MLXZSSF67MEETTFZWFGJNDYVU -CONNECTION_NKEY_SEED=SUALLWKCDN2KBB4YTZUNUUFP7ZNSI4PBXVK7X5FPNX6LQ3DCHFGYX4JPLQ -ECOSYSTEM_NKEY_SEED=SUAGUAGZZLT2LYEA3SRWFXCJL32MXR5GCBAZNYJLLIUH4O76GDEGQAYM74 -CREDENTAILDEFINITION_NKEY_SEED=SUAAYNLVKEP2E4JPCJ7OYSQ6OFCDBQ3GCTOPARBXBNP64JFESDWH7N3FQA -SCHEMA_NKEY_SEED=SUAESXIRPE4PBJR26T44XPPIAONQ3YJTN45VSTRNZUW77GAF5RBP3SEBFA -UTILITIES_NKEY_SEED=SUAHLF3PYEGNN3J2LZHHT6LOQ4GQ2CPGATEO66XRXLCEE6QYSM26TKCNUM -CLOUD_WALLET_NKEY_SEED=SUAJ3VT7IFZXVE7SSTX3JFE6F2U6DYDROW6VTCCGFVVB6D7O6C7OWJWTPM -GEOLOCATION_NKEY_SEED=SUAA3YQLMQPKEK224OVFGENQ3VRYD57LNPJFMGDULOO57CUYOQLAA7KBJU -NOTIFICATION_NKEY_SEED=SUAF5V6RN6HHOLBJX6UV7443PBNT7NSAJ6YCUOW7LTZQ77PXXAMH25AHPI +USER_NKEY_SEED= +API_GATEWAY_NKEY_SEED= +ORGANIZATION_NKEY_SEED= +AGENT_PROVISIONING_NKEY_SEED= +AGENT_SERVICE_NKEY_SEED= +VERIFICATION_NKEY_SEED= +LEDGER_NKEY_SEED= +ISSUANCE_NKEY_SEED= +CONNECTION_NKEY_SEED= +ECOSYSTEM_NKEY_SEED= +CREDENTAILDEFINITION_NKEY_SEED= +SCHEMA_NKEY_SEED= +UTILITIES_NKEY_SEED= +CLOUD_WALLET_NKEY_SEED= +GEOLOCATION_NKEY_SEED= +NOTIFICATION_NKEY_SEED= KEYCLOAK_DOMAIN=http://localhost:8080/ KEYCLOAK_ADMIN_URL=http://localhost:8080 @@ -144,5 +144,5 @@ APP=api #Schema-file-server APP_PORT=4000 -JWT_TOKEN_SECRET=c2e48ca31ac2a0b9af47f3a9f5a0809a858c296948c1326eb746bb7bc945a9d5 +JWT_TOKEN_SECRET= ISSUER=Credebl \ No newline at end of file From 4951f7283a310ea85d8c039a10fcb717b5f5cf02 Mon Sep 17 00:00:00 2001 From: Sahil Kamble Date: Fri, 9 May 2025 15:25:03 +0530 Subject: [PATCH 02/23] Merge pull request #1228 from credebl/refactor/optimise-dockerfile refactor: update dockerfile to reduce dockerimages --- Dockerfiles/Dockerfile.cloud-wallet | 11 +++-- Dockerfiles/Dockerfile.seed | 8 ++-- Dockerfiles/Dockerfile.user | 41 ++++--------------- Dockerfiles/Dockerfile.utility | 12 +++--- .../scripts/geo_location_data_import.sh | 2 +- .../scripts/update_client_credential_data.sh | 4 +- 6 files changed, 26 insertions(+), 52 deletions(-) diff --git a/Dockerfiles/Dockerfile.cloud-wallet b/Dockerfiles/Dockerfile.cloud-wallet index a9d6d95af..db7e31f1e 100644 --- a/Dockerfiles/Dockerfile.cloud-wallet +++ b/Dockerfiles/Dockerfile.cloud-wallet @@ -1,10 +1,9 @@ # Stage 1: Build the application -FROM node:18-slim as build +FROM node:18-alpine AS build # Install OpenSSL +RUN apk add --no-cache openssl RUN npm install -g pnpm -RUN apt-get update -y -RUN apt-get --no-install-recommends install -y openssl # Set the working directory WORKDIR /app @@ -25,10 +24,10 @@ RUN cd libs/prisma-service && npx prisma generate RUN pnpm run build cloud-wallet # Stage 2: Create the final image -FROM node:18-slim +FROM node:18-alpine + +RUN apk add --no-cache openssl -RUN apt-get update -y -RUN apt-get --no-install-recommends install -y openssl # Set the working directory WORKDIR /app # RUN npm install -g pnpm diff --git a/Dockerfiles/Dockerfile.seed b/Dockerfiles/Dockerfile.seed index f4c51da87..b7c6611b7 100644 --- a/Dockerfiles/Dockerfile.seed +++ b/Dockerfiles/Dockerfile.seed @@ -1,16 +1,18 @@ -FROM node:18 as build +FROM node:18-alpine # Install pnpm RUN npm install -g pnpm -# Install PostgreSQL client (use apt for Debian-based images) -RUN apt-get update && apt-get install -y postgresql-client +RUN apk add --no-cache postgresql-client openssl # Set working directory WORKDIR /app COPY . . +RUN chmod +x /app/libs/prisma-service/prisma/scripts/geo_location_data_import.sh +RUN chmod +x /app/libs/prisma-service/prisma/scripts/update_client_credential_data.sh +ENV PUPPETEER_SKIP_DOWNLOAD=true RUN pnpm i --ignore-scripts # Run Prisma commands diff --git a/Dockerfiles/Dockerfile.user b/Dockerfiles/Dockerfile.user index 41bc20ddc..8969f6e77 100644 --- a/Dockerfiles/Dockerfile.user +++ b/Dockerfiles/Dockerfile.user @@ -1,32 +1,20 @@ # Stage 1: Build the application -FROM node:18-slim as build - - +FROM node:18-alpine AS build +# Install OpenSSL +RUN apk add --no-cache openssl RUN npm install -g pnpm -# We don't need the standalone Chromium -ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true -ENV PUPPETEER_SKIP_DOWNLOAD true - -# Install Google Chrome Stable and fonts -# Note: this installs the necessary libs to make the browser work with Puppeteer. -RUN apt-get update && apt-get install openssl gnupg wget -y && \ - wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \ - sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \ - apt-get update && \ - apt-get install google-chrome-stable -y --no-install-recommends && \ - rm -rf /var/lib/apt/lists/* - -# RUN apk update && apk list --all-versions chromium # Set the working directory WORKDIR /app # Copy package.json and package-lock.json COPY package.json ./ +ENV PUPPETEER_SKIP_DOWNLOAD=true + # Install dependencies -RUN pnpm install +RUN pnpm i --ignore-scripts # Copy the rest of the application code COPY . . @@ -37,24 +25,11 @@ RUN cd libs/prisma-service && npx prisma generate RUN pnpm run build user # Stage 2: Create the final image -FROM node:18-slim - -# We don't need the standalone Chromium -ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true -ENV PUPPETEER_SKIP_DOWNLOAD true - -# Install Google Chrome Stable and fonts -# Note: this installs the necessary libs to make the browser work with Puppeteer. -RUN apt-get update && apt-get install openssl gnupg wget -y && \ - wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \ - sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \ - apt-get update && \ - apt-get install google-chrome-stable -y --no-install-recommends && \ - rm -rf /var/lib/apt/lists/* +FROM node:18-alpine +RUN apk add --no-cache openssl # Set the working directory WORKDIR /app -RUN npm install -g pnpm # Copy the compiled code from the build stage COPY --from=build /app/dist/apps/user/ ./dist/apps/user/ diff --git a/Dockerfiles/Dockerfile.utility b/Dockerfiles/Dockerfile.utility index ad96df022..a39aef3b8 100644 --- a/Dockerfiles/Dockerfile.utility +++ b/Dockerfiles/Dockerfile.utility @@ -1,10 +1,9 @@ # Stage 1: Build the application -FROM node:18-slim as build +FROM node:18-alpine AS build +# Install OpenSSL +RUN apk add --no-cache openssl RUN npm install -g pnpm - -RUN apt-get update -y -RUN apt-get --no-install-recommends install -y openssl # Set the working directory WORKDIR /app @@ -25,10 +24,9 @@ RUN cd libs/prisma-service && npx prisma generate RUN pnpm run build utility # Stage 2: Create the final image -FROM node:18-slim +FROM node:18-alpine -RUN apt-get update -y -RUN apt-get --no-install-recommends install -y openssl +RUN apk add --no-cache openssl # Set the working directory WORKDIR /app # RUN npm install -g pnpm diff --git a/libs/prisma-service/prisma/scripts/geo_location_data_import.sh b/libs/prisma-service/prisma/scripts/geo_location_data_import.sh index e598ce5f8..61247b088 100755 --- a/libs/prisma-service/prisma/scripts/geo_location_data_import.sh +++ b/libs/prisma-service/prisma/scripts/geo_location_data_import.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # Database connection details DB_URL=$1 diff --git a/libs/prisma-service/prisma/scripts/update_client_credential_data.sh b/libs/prisma-service/prisma/scripts/update_client_credential_data.sh index 2b6d49a54..1c62ffa4a 100755 --- a/libs/prisma-service/prisma/scripts/update_client_credential_data.sh +++ b/libs/prisma-service/prisma/scripts/update_client_credential_data.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # Database connection URL DB_URL=$1 @@ -30,7 +30,7 @@ update_client_credentials() { } # Check if CLIENT_ID and CLIENT_SECRET are not empty -if [[ -n "$CLIENT_ID" && -n "$CLIENT_SECRET" ]]; then +if [ -n "$CLIENT_ID" ] && [ -n "$CLIENT_SECRET" ]; then # Update client credentials if both CLIENT_ID and CLIENT_SECRET are provided update_client_credentials else From cadc7eccc7fa90cfaa360a212d3cd1e2d0ea772e Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Mon, 12 May 2025 12:22:24 +0530 Subject: [PATCH 03/23] init Signed-off-by: Krishna Waske --- biome.json | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 biome.json diff --git a/biome.json b/biome.json new file mode 100644 index 000000000..e854e7c0d --- /dev/null +++ b/biome.json @@ -0,0 +1,142 @@ +{ + "files": { + "ignore": [ + "**/*.eslintrc.js", + "**/*.json", + "**/node_modules", + "**/dist", + "**/.idea", + "**/coverage", + "**/pnpm-lock.yaml" + ] + }, + "formatter": { + "enabled": true, + "useEditorconfig": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 120, + "attributePosition": "auto", + "bracketSpacing": true + }, + "linter": { + "rules": { + "recommended": true, + "complexity": { + "noBannedTypes": "error", + "noUselessCatch": "error", + "noUselessLoneBlockStatements": "error", + "noUselessRename": "error", + "noUselessStringConcat": "error", + "noUselessTernary": "error", + "noUselessTypeConstraint": "error" + }, + "correctness": { + "noInvalidUseBeforeDeclaration": "error", + "noPrecisionLoss": "error", + "noSwitchDeclarations": "error", + "noUnusedVariables": "off", + "useArrayLiterals": "off" + }, + "style": { + "noArguments": "warn", + "noNamespace": "error", + "noParameterAssign": "error", + "noVar": "error", + "noYodaExpression": "error", + "useAsConstAssertion": "error", + "useBlockStatements": "error", + "useConsistentArrayType": "error", + "useConst": "error", + "useDefaultParameterLast": "error", + "useDefaultSwitchClause": "error", + "useNumericLiterals": "error", + "useTemplate": "error" + }, + "suspicious": { + "noConsole": "error", + "noExplicitAny": "error", + "noExtraNonNullAssertion": "error", + "noMisleadingInstantiator": "error", + "noSelfCompare": "error", + "noUnsafeDeclarationMerging": "error", + "useDefaultSwitchClauseLast": "error" + } + }, + "ignore": [ + "**/*.eslintrc.js", + "**/*.json", + "**/node_modules", + "**/dist", + "**/.idea", + "**/coverage", + "**/pnpm-lock.yaml" + ] + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "none", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto", + "bracketSpacing": true + }, + "parser": { + "unsafeParameterDecoratorsEnabled": true + } + }, + "json": { + "formatter": { + "enabled": false + } + }, + "overrides": [ + { + "include": ["*.ts", "*.tsx", "*.mts", "*.cts"], + "ignore": [ + "**/*.eslintrc.js", + "**/*.json", + "**/node_modules", + "**/dist", + "**/.idea", + "**/coverage", + "**/pnpm-lock.yaml" + ], + "linter": { + "rules": { + "correctness": { + "noConstAssign": "off", + "noGlobalObjectCalls": "off", + "noInvalidConstructorSuper": "off", + "noNewSymbol": "off", + "noSetterReturn": "off", + "noUndeclaredVariables": "off", + "noUnreachable": "off", + "noUnreachableSuper": "off" + }, + "style": { + "noArguments": "error", + "noVar": "error", + "useConst": "error" + }, + "suspicious": { + "noDuplicateClassMembers": "off", + "noDuplicateObjectKeys": "off", + "noDuplicateParameters": "off", + "noFunctionAssign": "off", + "noImportAssign": "off", + "noRedeclare": "off", + "noUnsafeNegation": "off", + "useGetterReturn": "off" + } + } + } + } + ] +} From 3a30bdb0dd6c0d618b1323891908c5ee96200361 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Mon, 12 May 2025 16:31:29 +0530 Subject: [PATCH 04/23] update: biomejson Signed-off-by: Krishna Waske --- biome.json | 85 ++++++++++++++++------------------ package.json | 9 ++-- pnpm-lock.yaml | 121 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 164 insertions(+), 51 deletions(-) diff --git a/biome.json b/biome.json index e854e7c0d..1161b1e86 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,12 @@ { + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, "files": { + "maxSize": 10000000, "ignore": [ "**/*.eslintrc.js", "**/*.json", @@ -19,50 +26,34 @@ "lineEnding": "lf", "lineWidth": 120, "attributePosition": "auto", - "bracketSpacing": true + "bracketSpacing": true, + "ignore": ["**/node_modules/*", "**/dist/*", "**/.idea", "**/coverage", "**/pnpm-lock.yaml", "**/test/*", "*.spec.ts"] }, "linter": { "rules": { "recommended": true, - "complexity": { - "noBannedTypes": "error", - "noUselessCatch": "error", - "noUselessLoneBlockStatements": "error", - "noUselessRename": "error", - "noUselessStringConcat": "error", - "noUselessTernary": "error", - "noUselessTypeConstraint": "error" + "style": { + "useImportType": "off", + "useNodejsImportProtocol": "off", + "noNonNullAssertion": "error" }, "correctness": { - "noInvalidUseBeforeDeclaration": "error", - "noPrecisionLoss": "error", - "noSwitchDeclarations": "error", - "noUnusedVariables": "off", - "useArrayLiterals": "off" + "noUnusedVariables": { + "level": "error", + "fix": "safe" + }, + "noUnusedFunctionParameters": "off", + "noUnusedImports": "error", + "noUndeclaredDependencies": "off" }, - "style": { - "noArguments": "warn", - "noNamespace": "error", - "noParameterAssign": "error", - "noVar": "error", - "noYodaExpression": "error", - "useAsConstAssertion": "error", - "useBlockStatements": "error", - "useConsistentArrayType": "error", - "useConst": "error", - "useDefaultParameterLast": "error", - "useDefaultSwitchClause": "error", - "useNumericLiterals": "error", - "useTemplate": "error" + "performance": { + "noDelete": { + "level": "error" + } }, - "suspicious": { - "noConsole": "error", - "noExplicitAny": "error", - "noExtraNonNullAssertion": "error", - "noMisleadingInstantiator": "error", - "noSelfCompare": "error", - "noUnsafeDeclarationMerging": "error", - "useDefaultSwitchClauseLast": "error" + "complexity": { + "useLiteralKeys": "warn", + "noForEach": "warn" } }, "ignore": [ @@ -72,30 +63,34 @@ "**/dist", "**/.idea", "**/coverage", - "**/pnpm-lock.yaml" + "**/pnpm-lock.yaml", + "**/test/*", + "*.spec.ts" ] }, "javascript": { "formatter": { - "jsxQuoteStyle": "double", - "quoteProperties": "asNeeded", - "trailingCommas": "none", - "semicolons": "always", - "arrowParentheses": "always", - "bracketSameLine": false, + "semicolons": "asNeeded", "quoteStyle": "single", - "attributePosition": "auto", - "bracketSpacing": true + "trailingCommas": "es5", + "lineWidth": 120, + "indentStyle": "space" }, "parser": { "unsafeParameterDecoratorsEnabled": true } }, "json": { + "parser": { + "allowComments": true + }, "formatter": { "enabled": false } }, + "organizeImports": { + "enabled": true + }, "overrides": [ { "include": ["*.ts", "*.tsx", "*.mts", "*.cts"], diff --git a/package.json b/package.json index b4217c6ee..91e6af493 100755 --- a/package.json +++ b/package.json @@ -20,7 +20,10 @@ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./apps/api-gateway/test/jest-e2e.json", "prisma:generate": "npx prisma generate", - "prepare": "husky install" + "prepare": "husky install", + "check": "biome check", + "check:fix": "biome check --write", + "ci": "biome ci" }, "prisma": { "seed": "ts-node prisma/seed.ts" @@ -113,6 +116,7 @@ "xml-js": "^1.6.11" }, "devDependencies": { + "@biomejs/biome": "1.9.4", "@nestjs/cli": "^10.1.11", "@nestjs/schematics": "^10.0.1", "@nestjs/testing": "^10.1.3", @@ -146,8 +150,7 @@ }, "lint-staged": { "**/*.{js,ts}": [ - "eslint --fix", - "prettier --write" + "biome check --write" ] }, "jest": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83708c63d..7dcd88182 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,6 +74,9 @@ importers: '@types/json2csv': specifier: ^5.0.5 version: 5.0.5 + '@types/jsonwebtoken': + specifier: ^9.0.9 + version: 9.0.9 '@types/pdfkit': specifier: ^0.12.6 version: 0.12.6 @@ -264,6 +267,9 @@ importers: specifier: ^1.6.11 version: 1.6.11 devDependencies: + '@biomejs/biome': + specifier: 1.9.4 + version: 1.9.4 '@nestjs/cli': specifier: ^10.1.11 version: 10.1.11 @@ -655,6 +661,59 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -1286,12 +1345,18 @@ packages: '@types/jsonwebtoken@9.0.2': resolution: {integrity: sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==} + '@types/jsonwebtoken@9.0.9': + resolution: {integrity: sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ==} + '@types/mime@1.3.2': resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} '@types/mime@3.0.1': resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/multer@1.4.9': resolution: {integrity: sha512-9NSvPJ2E8bNTc8XtJq1Cimx2Wrn2Ah48F15B2Du/hM8a8CHLhVbJMlF3ZCqhvMdht7Sa+YdP0aKP7N4fxDcrrg==} @@ -1517,6 +1582,7 @@ packages: acorn-import-assertions@1.9.0: resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + deprecated: package has been renamed to acorn-import-attributes peerDependencies: acorn: ^8 @@ -2533,6 +2599,7 @@ packages: eslint-config-standard-with-typescript@37.0.0: resolution: {integrity: sha512-V8I/Q1eFf9tiOuFHkbksUdWO3p1crFmewecfBtRxXdnvb71BCJx+1xAknlIRZMwZioMX3/bPtMVCZsf1+AjjOw==} + deprecated: Please use eslint-config-love, instead. peerDependencies: '@typescript-eslint/eslint-plugin': ^5.52.0 eslint: ^8.0.1 @@ -2646,6 +2713,7 @@ packages: eslint@8.46.0: resolution: {integrity: sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -3187,6 +3255,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} @@ -3728,6 +3797,7 @@ packages: lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} @@ -3740,6 +3810,7 @@ packages: lodash.omit@4.5.0: resolution: {integrity: sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==} + deprecated: This package is deprecated. Use destructuring assignment syntax instead. lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} @@ -4496,11 +4567,12 @@ packages: puppeteer@21.0.1: resolution: {integrity: sha512-KTjmSdPZ6bMkq3EbAzAUhcB3gMDXvdwd6912rxG9hNtjwRJzHSA568vh6vIbO2WQeNmozRdt1LtiUMLSWfeMrg==} engines: {node: '>=16.3.0'} - deprecated: < 22.6.4 is no longer supported + deprecated: < 22.8.2 is no longer supported puppeteer@21.5.0: resolution: {integrity: sha512-prvy9rdauyIaaEgefQRcw9zhQnYQbl8O1Gj5VJazKJ7kwNx703+Paw/1bwA+b96jj/S+r55hrmF5SfiEG5PUcg==} engines: {node: '>=16.3.0'} + deprecated: < 22.8.2 is no longer supported pure-rand@6.0.2: resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} @@ -5633,6 +5705,7 @@ packages: yaeti@0.0.6: resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} engines: {node: '>=0.10.32'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} @@ -5953,6 +6026,41 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + '@colors/colors@1.5.0': optional: true @@ -6753,10 +6861,17 @@ snapshots: dependencies: '@types/node': 20.4.6 + '@types/jsonwebtoken@9.0.9': + dependencies: + '@types/ms': 2.1.0 + '@types/node': 20.4.6 + '@types/mime@1.3.2': {} '@types/mime@3.0.1': {} + '@types/ms@2.1.0': {} + '@types/multer@1.4.9': dependencies: '@types/express': 4.17.17 @@ -6768,7 +6883,7 @@ snapshots: '@types/passport-jwt@3.0.9': dependencies: '@types/express': 4.17.17 - '@types/jsonwebtoken': 9.0.2 + '@types/jsonwebtoken': 9.0.9 '@types/passport-strategy': 0.2.35 '@types/passport-local@1.0.35': @@ -9746,7 +9861,7 @@ snapshots: jwks-rsa@3.0.1: dependencies: '@types/express': 4.17.17 - '@types/jsonwebtoken': 9.0.2 + '@types/jsonwebtoken': 9.0.9 debug: 4.3.5 jose: 4.14.4 limiter: 1.1.5 From 6cc48166896700b61704729939c5f0205e76f7b3 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Mon, 12 May 2025 17:24:18 +0530 Subject: [PATCH 05/23] update: biomejson Signed-off-by: Krishna Waske --- biome.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 1161b1e86..46a01091a 100644 --- a/biome.json +++ b/biome.json @@ -101,7 +101,8 @@ "**/dist", "**/.idea", "**/coverage", - "**/pnpm-lock.yaml" + "**/pnpm-lock.yaml", + "*.spec.ts" ], "linter": { "rules": { From 61678c79b03a259ccff43f938a8152ac45f4d40b Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Tue, 13 May 2025 15:38:42 +0530 Subject: [PATCH 06/23] fix: biome config Signed-off-by: Krishna Waske --- biome.json | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/biome.json b/biome.json index 46a01091a..632b78cb0 100644 --- a/biome.json +++ b/biome.json @@ -19,15 +19,14 @@ }, "formatter": { "enabled": true, - "useEditorconfig": true, - "formatWithErrors": false, + "formatWithErrors": true, "indentStyle": "space", - "indentWidth": 2, + "indentWidth": 2, "lineEnding": "lf", "lineWidth": 120, "attributePosition": "auto", "bracketSpacing": true, - "ignore": ["**/node_modules/*", "**/dist/*", "**/.idea", "**/coverage", "**/pnpm-lock.yaml", "**/test/*", "*.spec.ts"] + "ignore": ["**/node_modules/*", "**/dist/*", "**/coverage", "**/pnpm-lock.yaml", "**/test/*", "*.spec.ts"] }, "linter": { "rules": { @@ -52,8 +51,13 @@ } }, "complexity": { - "useLiteralKeys": "warn", - "noForEach": "warn" + "useLiteralKeys": { + "level": "warn", + "fix": "safe" + }, + "noForEach": { + "level": "info" + } } }, "ignore": [ @@ -93,13 +97,12 @@ }, "overrides": [ { - "include": ["*.ts", "*.tsx", "*.mts", "*.cts"], + "include": ["*.tsx", "*.mts", "*.cts"], "ignore": [ "**/*.eslintrc.js", "**/*.json", "**/node_modules", "**/dist", - "**/.idea", "**/coverage", "**/pnpm-lock.yaml", "*.spec.ts" From f587f3a50ee859dcd043be829597a0819b303045 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Tue, 13 May 2025 15:47:28 +0530 Subject: [PATCH 07/23] chore: retorfit templates in develop (#1242) * fix: qa conflict fixes (#1214) * chore: Platform version upgrade (#1100) * chore: platform version upgrade Signed-off-by: pranalidhanavade * fix: docker file for cloud wallet Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * Add OpenSSL installation support for Docker image Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Krishna Waske * Add OpenSSL installation support for Docker image Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Krishna Waske * Add OpenSSL installation support for Docker image Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Krishna Waske * fix: Changes in NATS interceptor for error handling (#1103) * fix: changes in nats intercepor for error handling Signed-off-by: pranalidhanavade * fix: Error handling for send proof request with identical attributes when one attribute uses predicates and the other does not Signed-off-by: pranalidhanavade * fix: Resolve comments on PR Signed-off-by: pranalidhanavade * fix: added comments in service Signed-off-by: pranalidhanavade * fix: added comments in service Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * error handling in NATS interceptor (#1106) Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * fix: exception handling for common handler (#1108) * fix: exception handling Signed-off-by: pranalidhanavade * refactor: NATS interceptor Signed-off-by: pranalidhanavade * refactor: exception handler component changes Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * feat: add array data type in schema payload (#1110) * fix:added array data type in schema payload Signed-off-by: pallavicoder * fix:added nested attributes in schema paylaod Signed-off-by: pallavicoder * feat: add array data type while creating schema Signed-off-by: bhavanakarwade * replace hardcoded value with dynamic Signed-off-by: bhavanakarwade * fix: removed commented code Signed-off-by: bhavanakarwade --------- Signed-off-by: pallavicoder Signed-off-by: bhavanakarwade Co-authored-by: bhavanakarwade Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * fix: added search on schema name for credentials list (#1111) * fix:added array data type in schema payload Signed-off-by: pallavicoder * fix:added nested attributes in schema paylaod Signed-off-by: pallavicoder * feat: add array data type while creating schema Signed-off-by: bhavanakarwade * replace hardcoded value with dynamic Signed-off-by: bhavanakarwade * fix: removed commented code Signed-off-by: bhavanakarwade * fix: added search on schema name Signed-off-by: bhavanakarwade * fix: made api property optional Signed-off-by: bhavanakarwade * handled conditions for empty array Signed-off-by: bhavanakarwade --------- Signed-off-by: pallavicoder Signed-off-by: bhavanakarwade Co-authored-by: pallavicoder Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * chore: added parentThreadId in webhook dto (#1112) * fix:added array data type in schema payload Signed-off-by: pallavicoder * fix:added nested attributes in schema paylaod Signed-off-by: pallavicoder * feat: add array data type while creating schema Signed-off-by: bhavanakarwade * replace hardcoded value with dynamic Signed-off-by: bhavanakarwade * fix: removed commented code Signed-off-by: bhavanakarwade * fix: added search on schema name Signed-off-by: bhavanakarwade * fix: made api property optional Signed-off-by: bhavanakarwade * handled conditions for empty array Signed-off-by: bhavanakarwade * chore: added loggers Signed-off-by: bhavanakarwade * chore: added loggers for issuance and verification Signed-off-by: bhavanakarwade * chore: added parentthreadid in webhook dto Signed-off-by: bhavanakarwade * fix: remove unnecessary loggers Signed-off-by: bhavanakarwade * fix: remove unnecessary loggers Signed-off-by: bhavanakarwade --------- Signed-off-by: pallavicoder Signed-off-by: bhavanakarwade Co-authored-by: pallavicoder Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * fix: changes schema endpoint (#1114) Signed-off-by: Tipu_Singh Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * feat: added purpose property in send proof request (#1113) Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * refactor:modification on API summary and description (#1116) Signed-off-by: Tipu_Singh Signed-off-by: Krishna Waske * chore: added orgdid in get all orgs response Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * refactor: improve response for oob verification via email (#1118) Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * refactor: swagger documentation changes for auth, schema, ledger, credential-definition, agent and user controllers. (#1117) * swagger documentation changes for auth, schema and user controllers Signed-off-by: pranalidhanavade * swagger documentation changes for auth, schema and user controller Signed-off-by: pranalidhanavade * refactor: API descrption Signed-off-by: pranalidhanavade * refactor: swagger API documentation for agent controller Signed-off-by: pranalidhanavade * fix: API trim validation Signed-off-by: pranalidhanavade * fix: Removed extra description related to pagination from API documentation Signed-off-by: pranalidhanavade * fix: changes in email example Signed-off-by: pranalidhanavade * fix: changes in API documentation Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * fix: removed unnecessary code Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * chore: added orgdid in get all orgs response (#1119) Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * fix: added API params validations (#1124) * fix: added API params validations Signed-off-by: pranalidhanavade * fix: removed unneccessary roles from role gaurd Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * fix: added api param validations (#1121) * fix: added api param validations Signed-off-by: bhavanakarwade * fix: removed unnecessary validations Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * refactor:Conditions to get issued credential list for OOB issuance (#1125) Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * fix: parameter validations issues (#1126) * fix: added api param validations Signed-off-by: bhavanakarwade * fix: removed unnecessary validations Signed-off-by: bhavanakarwade * fix:resolved validations issue Signed-off-by: bhavanakarwade * added comment on function for understanding Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * added compass.yml file Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske * feat: update schema details and add alias in schema table (#1129) * API for update schema details Signed-off-by: pallavighule * refactored query Signed-off-by: pallavighule * chore: added alias in response Signed-off-by: bhavanakarwade --------- Signed-off-by: pallavighule Signed-off-by: bhavanakarwade Co-authored-by: bhavanakarwade Signed-off-by: Krishna Waske * chore: remove yarn.lock and package-lock.json files (#1133) Signed-off-by: Sai Ranjit Tummalapalli Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * fix: platform agent set up issue (#1136) Signed-off-by: bhavanakarwade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * fix: Parameter validations (#1138) * fix: added api param validations Signed-off-by: bhavanakarwade * fix: removed unnecessary validations Signed-off-by: bhavanakarwade * fix:resolved validations issue Signed-off-by: bhavanakarwade * added comment on function for understanding Signed-off-by: bhavanakarwade * fix: resolve orgid validations Signed-off-by: bhavanakarwade * fix: added response message Signed-off-by: bhavanakarwade * fix: added space in response messages Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * added tenant id in get org info (#1139) Signed-off-by: pallavighule Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * fix/added-yml-file-to-push-docker-images (#1142) * fix: removed prisma commands in build stage Signed-off-by: sahil.kamble@ayanworks.com * feat: create yml file for all services Signed-off-by: sahil.kamble@ayanworks.com * Updated Dockerfiles Signed-off-by: sahil.kamble@ayanworks.com * Updated yml to push docker images Signed-off-by: sahil.kamble@ayanworks.com * updated yml files Signed-off-by: sahil.kamble@ayanworks.com --------- Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * fix/push docker image (#1154) * fix: used single yml file using matrix instead of multiple files Signed-off-by: sahil.kamble@ayanworks.com * fix: renamed yml file to cicd.yml Signed-off-by: sahil.kamble@ayanworks.com * fix: renamed yml file Signed-off-by: sahil.kamble@ayanworks.com * fix: renamed yml file Signed-off-by: sahil.kamble@ayanworks.com * chore: removed id-token and attestations Signed-off-by: sahil.kamble@ayanworks.com --------- Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * chore: add aws module into monorepo (#1135) * chore: add aws into monorepo Signed-off-by: Sai Ranjit Tummalapalli * chore: update tsconfig Signed-off-by: Sai Ranjit Tummalapalli * refactor:tsconfig.build.json file Signed-off-by: Tipu_Singh * refactor: remove redundant .nvmrc file Signed-off-by: Sai Ranjit Tummalapalli --------- Signed-off-by: Sai Ranjit Tummalapalli Signed-off-by: Tipu_Singh Co-authored-by: Tipu_Singh Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * chore: remove unused modules (#1163) Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * refactor: remove image-service from libs (#1164) Signed-off-by: Sai Ranjit Tummalapalli Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * refactor: merge nats-interceptor and responses lib into common (#1165) * refactor: merge nats-interceptor into common Signed-off-by: Sai Ranjit Tummalapalli * refactor: merge repsonses lib into common Signed-off-by: Sai Ranjit Tummalapalli * refactor: create common function to handle errors Signed-off-by: Sai Ranjit Tummalapalli * chore: add todo Signed-off-by: Sai Ranjit Tummalapalli * fix: remove missed image service Signed-off-by: Sai Ranjit Tummalapalli * fix: create separate function to handle common error Signed-off-by: Sai Ranjit Tummalapalli * chore: add comment for the purpose of the functions Signed-off-by: Sai Ranjit Tummalapalli * chore: update function comments Signed-off-by: Sai Ranjit Tummalapalli --------- Signed-off-by: Sai Ranjit Tummalapalli Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * refactor: create common package in libs (#1167) * refactor: merge nats-interceptor into common Signed-off-by: Sai Ranjit Tummalapalli * refactor: merge repsonses lib into common Signed-off-by: Sai Ranjit Tummalapalli * refactor: create common function to handle errors Signed-off-by: Sai Ranjit Tummalapalli * chore: add todo Signed-off-by: Sai Ranjit Tummalapalli * refactor: create common package in libs Signed-off-by: Sai Ranjit Tummalapalli * fix: remove missed image service Signed-off-by: Sai Ranjit Tummalapalli * refactor: common service Signed-off-by: Sai Ranjit Tummalapalli --------- Signed-off-by: Sai Ranjit Tummalapalli Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * feat: Support nested attributes while creating schema (#1166) * wip: support nested attributes while creating schema Signed-off-by: bhavanakarwade * wip: aligned issuance functionality with nested attributes structure Signed-off-by: bhavanakarwade * refactor: modify csv to json function Signed-off-by: bhavanakarwade * fix: formatting changes Signed-off-by: bhavanakarwade * fix: resolved sonar cloud issue Signed-off-by: bhavanakarwade * fix: security hotspot issue Signed-off-by: bhavanakarwade * feat: added schema builder function Signed-off-by: bhavanakarwade * fix: resolved issue Signed-off-by: bhavanakarwade * refactor: modify extract attributes function Signed-off-by: bhavanakarwade * fix: destructured objects Signed-off-by: bhavanakarwade * feat: added description property Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * refactor: schema data type validations (#1174) * wip: support nested attributes while creating schema Signed-off-by: bhavanakarwade * wip: aligned issuance functionality with nested attributes structure Signed-off-by: bhavanakarwade * refactor: modify csv to json function Signed-off-by: bhavanakarwade * fix: formatting changes Signed-off-by: bhavanakarwade * fix: resolved sonar cloud issue Signed-off-by: bhavanakarwade * fix: security hotspot issue Signed-off-by: bhavanakarwade * feat: added schema builder function Signed-off-by: bhavanakarwade * fix: resolved issue Signed-off-by: bhavanakarwade * refactor: modify extract attributes function Signed-off-by: bhavanakarwade * fix: destructured objects Signed-off-by: bhavanakarwade * feat: added description property Signed-off-by: bhavanakarwade * fix: added validations for schema type Signed-off-by: bhavanakarwade * formatted enum file Signed-off-by: bhavanakarwade * chore: added enum for indy schema data type Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * refactor: update organization API to support updation of country, state and city (#1180) * refactor: update organization API to support updation of country, state and city Signed-off-by: pranalidhanavade * resolved sonarlint issues Signed-off-by: pranalidhanavade * resolved sonarlint issues Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * refactor: error handling for download csv file (#1182) * wip: support nested attributes while creating schema Signed-off-by: bhavanakarwade * wip: aligned issuance functionality with nested attributes structure Signed-off-by: bhavanakarwade * refactor: modify csv to json function Signed-off-by: bhavanakarwade * fix: formatting changes Signed-off-by: bhavanakarwade * fix: resolved sonar cloud issue Signed-off-by: bhavanakarwade * fix: security hotspot issue Signed-off-by: bhavanakarwade * feat: added schema builder function Signed-off-by: bhavanakarwade * fix: resolved issue Signed-off-by: bhavanakarwade * refactor: modify extract attributes function Signed-off-by: bhavanakarwade * fix: destructured objects Signed-off-by: bhavanakarwade * feat: added description property Signed-off-by: bhavanakarwade * fix: added validations for schema type Signed-off-by: bhavanakarwade * formatted enum file Signed-off-by: bhavanakarwade * chore: added enum for indy schema data type Signed-off-by: bhavanakarwade * chore: refactor validations Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * feat: implemented get verified presentation counts by issuer id (#1184) Signed-off-by: bhavanakarwade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * fix: local setup issues (#1155) * Update start_agent.sh Signed-off-by: Krishna Waske * Update .env.demo fix: correct script for local build Signed-off-by: Krishna Waske --------- Signed-off-by: Krishna Waske Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * fix: issues related nested attributes in issuance process (#1194) * fix: issues related nested attributes in issuance process Signed-off-by: bhavanakarwade * fix: added statuscode Signed-off-by: bhavanakarwade * fix: required field validation for request id field Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * chore: update .env.demo file (#1198) Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * feat: Validations for organization and template ledgerId in all issuance methods (#1200) * fix: ledgerId validations in issuance process Signed-off-by: bhavanakarwade * fix: added validations for not found exception Signed-off-by: bhavanakarwade * chore: added comment Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: Krishna Waske * feat: added seed dockerfile (#1203) * feat: added seed dockerfile Signed-off-by: Sahil Kamble * feat: updated seed dockerfile Signed-off-by: Sahil Kamble --------- Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * Update nats server and redis configurations (#1206) * Update nats-server.conf Signed-off-by: Krishna Waske * Create docker-compose.nats.yml Signed-off-by: Krishna Waske * Create docker-compose.redis.yml Signed-off-by: Krishna Waske --------- Signed-off-by: Krishna Waske * Update .env.demo (#1205) * Update .env.demo Signed-off-by: Krishna Waske * Update .env.demo Signed-off-by: Krishna Waske --------- Signed-off-by: Krishna Waske * feat/update-docker-compose (#1209) * feat: add schema and seed service to docker-compose Signed-off-by: Sahil Kamble * feat: add docker-compose-dev.yml Signed-off-by: Sahil Kamble --------- Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * chore: removed unwanted values (#1212) Signed-off-by: Sahil Kamble Signed-off-by: Krishna Waske * feat: created yml file for tag v2.0.0 Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Krishna Waske * fix: added organization service in yml file Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Krishna Waske * feat: create yml file to push docker images Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: Krishna Waske * Create FEATURE-REQUEST.md (#1181) * Create FEATURE-REQUEST.md Create FEATURE-REQUEST.md Signed-off-by: Krishna Waske * Update bug_report.md Update bug_report.md Signed-off-by: Krishna Waske * Update FEATURE-REQUEST.md change links Signed-off-by: Krishna Waske * Update bug_report.md Signed-off-by: Krishna Waske --------- Signed-off-by: Krishna Waske * fix readme typo (#1170) fix readme typo Signed-off-by: NucleonGodX Signed-off-by: Krishna Waske * fix: Update GET proof record endpoint to return 404 for non-existing records (#1190) Signed-off-by: Amr Mubarak Signed-off-by: Krishna Waske --------- Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: pallavicoder Signed-off-by: bhavanakarwade Signed-off-by: Tipu_Singh Signed-off-by: pallavighule Signed-off-by: Sai Ranjit Tummalapalli Signed-off-by: Sahil Kamble Signed-off-by: NucleonGodX Signed-off-by: Amr Mubarak Co-authored-by: pranalidhanavade Co-authored-by: sahil.kamble@ayanworks.com Co-authored-by: pallavighule <61926403+pallavighule@users.noreply.github.com> Co-authored-by: bhavanakarwade Co-authored-by: pallavicoder Co-authored-by: Tipu_Singh Co-authored-by: Sai Ranjit Tummalapalli Co-authored-by: Manit Singh <79140607+NucleonGodX@users.noreply.github.com> Co-authored-by: Amr Mubarak <138404703+amrrdev@users.noreply.github.com> * feat: created yml file for tag v2.0.0 Signed-off-by: sahil.kamble@ayanworks.com * fix: added organization service in yml file Signed-off-by: sahil.kamble@ayanworks.com * feat: create yml file to push docker images Signed-off-by: sahil.kamble@ayanworks.com * Update and rename FEATURE-REQUEST.md to FEATURE-REQUEST.yml update template from .md to .yml Signed-off-by: Krishna Waske * Update FEATURE-REQUEST.yml Signed-off-by: Krishna Waske * Update and rename bug_report.md to bug_report.yml Signed-off-by: Krishna Waske * Update FEATURE-REQUEST.yml Signed-off-by: Krishna Waske * Update bug_report.yml Signed-off-by: Krishna Waske * Update bug_report.yml Signed-off-by: Krishna Waske * Update bug_report.yml Signed-off-by: Krishna Waske * Update bug_report.yml Signed-off-by: Krishna Waske * Update FEATURE-REQUEST.yml Signed-off-by: Krishna Waske --------- Signed-off-by: pranalidhanavade Signed-off-by: Krishna Waske Signed-off-by: sahil.kamble@ayanworks.com Signed-off-by: pallavicoder Signed-off-by: bhavanakarwade Signed-off-by: Tipu_Singh Signed-off-by: pallavighule Signed-off-by: Sai Ranjit Tummalapalli Signed-off-by: Sahil Kamble Signed-off-by: NucleonGodX Signed-off-by: Amr Mubarak Co-authored-by: pranalidhanavade Co-authored-by: sahil.kamble@ayanworks.com Co-authored-by: pallavighule <61926403+pallavighule@users.noreply.github.com> Co-authored-by: bhavanakarwade Co-authored-by: pallavicoder Co-authored-by: Tipu_Singh Co-authored-by: Sai Ranjit Tummalapalli Co-authored-by: Manit Singh <79140607+NucleonGodX@users.noreply.github.com> Co-authored-by: Amr Mubarak <138404703+amrrdev@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml | 57 +++++++++++++++ .github/ISSUE_TEMPLATE/bug_report.md | 31 -------- .github/ISSUE_TEMPLATE/bug_report.yml | 71 +++++++++++++++++++ README.md | 4 +- apps/verification/src/verification.service.ts | 18 ++--- 5 files changed, 136 insertions(+), 45 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml diff --git a/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml new file mode 100644 index 000000000..da89002ce --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml @@ -0,0 +1,57 @@ +name: "🚀 Feature Request" +description: Suggest an idea or enhancement for this project +labels: [enhancement] +title: "feat: " +body: + - type: checkboxes + id: agreement + attributes: + label: Preliminary Checks + options: + - label: "I've read the [contibution guide](https://docs.credebl.id/docs/contribute/how-to-contribute) and agree to it" + required: true + - label: "I have searched [existing issues](https://github.com/credebl/platform/issues) and [pull requests](https://github.com/credebl/platform/pulls) to avoid duplicates." + required: true + - label: "I'm willing to create a PR for this feature. (if applicable)." + - type: markdown + attributes: + value: | + ## 🧩 Problem Statement + + _Is your feature request related to a problem? Please describe it clearly._ + + > Ex: I'm always frustrated when [...] + + --- + + ## 💡 Proposed Solution + + _A clear and concise description of what you want to happen._ + + > Ex: It would be great if [...] + + --- + + ## 🔄 Alternatives Considered + + _Have you considered any alternative solutions or features?_ + + > Ex: I also thought about [...], but [...] + + --- + + ## 📎 Additional Context + + _Add any other context, references, mockups, or screenshots here._ + + --- + + ## ✅ Acceptance Criteria + + _List specific tasks or outcomes that define when this request is complete._ + + - A new endpoint `/v1/...` is added + - Docs updated + - Tests written and passing + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 08cd90e3e..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Prerequisites** - -**Steps to Reproduce** - -**Current behavior** - -**Expected behavior** - -**Environment** - -**Desktop** - - OS: - - Browser: - - Browser Version: - - CREDEBL Version: - -**Smartphone** - - Device: - - OS: - - ADEYA version: - -**Screenshots or Screen recording** diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..3a946e71a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,71 @@ +name: "🐛 Bug Report" +description: Report a bug or unexpected behavior in the project +labels: [bug] +title: "fix: " +body: + - type: checkboxes + id: agreement + attributes: + label: Preliminary Checks + options: + - label: I have read the contributions guide [contibution guide](https://docs.credebl.id/docs/contribute/how-to-contribute) and agree to it + required: true + - label: I have searched [existing issues](https://github.com/credebl/platform/issues) and [pull requests](https://github.com/credebl/platform/pulls) to avoid duplicates. + required: true + - label: "I'm willing to create a PR for this feature. (if applicable)." + - type: markdown + attributes: + value: | + ## 🐞 Bug Description + + _A clear and concise description of what the bug is._ + + When I try to [...], I get this unexpected behavior [...] + + --- + + ## 🧪 Steps to Reproduce + + _Provide clear steps to reproduce the bug._ + + 1. Go to '...' + 2. Click on '...' + 3. Scroll down to '...' + 4. See error + + --- + + ## ✅ Expected Behavior + + _What did you expect to happen?_ + + --- + + ## ❌ Actual Behavior + + _What actually happened instead?_ + + --- + + ## 📌 Affected Version/Commit + + _Version number, branch name, or commit hash where the bug occurs._ + + --- + + ## 💻 Environment + + _Where did the issue occur?_ + + - [ ] Local development + - [ ] Production + - [ ] CI/CD + - [ ] Other + + --- + + ## 🧾 Relevant Logs, Screenshots, or Stack Traces + + _Paste any error messages or screenshots that can help diagnose the issue._ + validations: + required: false diff --git a/README.md b/README.md index efebe8b60..71336eb02 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ docker run --name some-postgres -p 5432:5432 -e POSTGRES_PASSWORD= Date: Thu, 15 May 2025 18:25:15 +0530 Subject: [PATCH 08/23] chore: update biome js Signed-off-by: Krishna Waske --- biome.json | 126 +++++++++++++++-------------------------------------- 1 file changed, 35 insertions(+), 91 deletions(-) diff --git a/biome.json b/biome.json index 632b78cb0..010cb8340 100644 --- a/biome.json +++ b/biome.json @@ -6,31 +6,35 @@ "useIgnoreFile": true }, "files": { - "maxSize": 10000000, - "ignore": [ - "**/*.eslintrc.js", - "**/*.json", - "**/node_modules", - "**/dist", - "**/.idea", - "**/coverage", - "**/pnpm-lock.yaml" - ] + "maxSize": 10000000 }, "formatter": { - "enabled": true, - "formatWithErrors": true, "indentStyle": "space", - "indentWidth": 2, - "lineEnding": "lf", "lineWidth": 120, - "attributePosition": "auto", - "bracketSpacing": true, - "ignore": ["**/node_modules/*", "**/dist/*", "**/coverage", "**/pnpm-lock.yaml", "**/test/*", "*.spec.ts"] + "ignore": ["**/node_modules", "**/dist", "**/.idea", "**/coverage", "**/pnpm-lock.yaml"] + }, + "javascript": { + "parser": { + "unsafeParameterDecoratorsEnabled": true + }, + "formatter": { + "semicolons": "asNeeded", + "quoteStyle": "single", + "trailingCommas": "es5", + "lineWidth": 120, + "indentStyle": "space" + } + }, + "json": { + "parser": { + "allowComments": true + } + }, + "organizeImports": { + "enabled": true }, "linter": { "rules": { - "recommended": true, "style": { "useImportType": "off", "useNodejsImportProtocol": "off", @@ -43,20 +47,26 @@ }, "noUnusedFunctionParameters": "off", "noUnusedImports": "error", - "noUndeclaredDependencies": "off" + "noUndeclaredDependencies": "off", + "noInvalidUseBeforeDeclaration": "error" }, - "performance": { - "noDelete": { - "level": "error" - } + "suspicious": { + "noConsole": "error" }, "complexity": { + "noBannedTypes": "error", "useLiteralKeys": { "level": "warn", "fix": "safe" }, "noForEach": { - "level": "info" + "level": "warn" + } + }, + "performance": { + "noDelete": { + "fix": "safe", + "level": "error" } } }, @@ -71,71 +81,5 @@ "**/test/*", "*.spec.ts" ] - }, - "javascript": { - "formatter": { - "semicolons": "asNeeded", - "quoteStyle": "single", - "trailingCommas": "es5", - "lineWidth": 120, - "indentStyle": "space" - }, - "parser": { - "unsafeParameterDecoratorsEnabled": true - } - }, - "json": { - "parser": { - "allowComments": true - }, - "formatter": { - "enabled": false - } - }, - "organizeImports": { - "enabled": true - }, - "overrides": [ - { - "include": ["*.tsx", "*.mts", "*.cts"], - "ignore": [ - "**/*.eslintrc.js", - "**/*.json", - "**/node_modules", - "**/dist", - "**/coverage", - "**/pnpm-lock.yaml", - "*.spec.ts" - ], - "linter": { - "rules": { - "correctness": { - "noConstAssign": "off", - "noGlobalObjectCalls": "off", - "noInvalidConstructorSuper": "off", - "noNewSymbol": "off", - "noSetterReturn": "off", - "noUndeclaredVariables": "off", - "noUnreachable": "off", - "noUnreachableSuper": "off" - }, - "style": { - "noArguments": "error", - "noVar": "error", - "useConst": "error" - }, - "suspicious": { - "noDuplicateClassMembers": "off", - "noDuplicateObjectKeys": "off", - "noDuplicateParameters": "off", - "noFunctionAssign": "off", - "noImportAssign": "off", - "noRedeclare": "off", - "noUnsafeNegation": "off", - "useGetterReturn": "off" - } - } - } - } - ] + } } From 5811e3a6f278e50debc6880d0d41a644ed028d43 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 15 May 2025 18:45:28 +0530 Subject: [PATCH 09/23] fix: biomejs issues Signed-off-by: Krishna Waske --- .eslintrc.js | 18 +- .../src/agent-provisioning.controller.ts | 16 +- .../src/agent-provisioning.module.ts | 34 +- .../src/agent-provisioning.service.ts | 110 +- .../agent-provisioning.interfaces.ts | 106 +- apps/agent-provisioning/src/main.ts | 33 +- apps/agent-provisioning/test/app.e2e-spec.ts | 27 +- .../src/agent-service.controller.ts | 218 +- .../agent-service/src/agent-service.module.ts | 55 +- .../src/agent-service.service.ts | 1508 +++++++------- .../src/interface/agent-service.interface.ts | 879 ++++---- apps/agent-service/src/main.ts | 58 +- .../repositories/agent-service.repository.ts | 938 ++++----- apps/agent-service/test/app.e2e-spec.ts | 29 +- apps/api-gateway/common/exception-handler.ts | 57 +- apps/api-gateway/common/interface.ts | 8 +- .../agent-service.controller.spec.ts | 20 +- .../agent-service/agent-service.controller.ts | 216 +- .../src/agent-service/agent-service.module.ts | 33 +- .../agent-service/agent-service.service.ts | 176 +- .../src/agent-service/agent.service.spec.ts | 20 +- .../agent-service/dto/agent-configure.dto.ts | 20 +- .../agent-service/dto/agent-service.dto.ts | 28 +- .../src/agent-service/dto/create-did.dto.ts | 119 +- .../agent-service/dto/create-new-did.dto.ts | 16 +- .../agent-service/dto/create-schema.dto.ts | 47 +- .../agent-service/dto/create-tenant.dto.ts | 47 +- .../agent-service/dto/create-wallet.dto.ts | 46 +- .../agent-service/dto/register-webhook-dto.ts | 21 +- .../interface/agent-service.interface.ts | 32 +- .../src/agent/agent.controller.spec.ts | 20 +- .../api-gateway/src/agent/agent.controller.ts | 242 ++- apps/api-gateway/src/agent/agent.module.ts | 30 +- .../src/agent/agent.service.spec.ts | 20 +- apps/api-gateway/src/agent/agent.service.ts | 170 +- apps/api-gateway/src/app.controller.spec.ts | 19 +- apps/api-gateway/src/app.controller.ts | 12 +- apps/api-gateway/src/app.module.ts | 80 +- apps/api-gateway/src/app.service.ts | 14 +- .../api-gateway/src/authz/authz.controller.ts | 265 ++- .../api-gateway/src/authz/authz.middleware.ts | 138 +- apps/api-gateway/src/authz/authz.module.ts | 61 +- apps/api-gateway/src/authz/authz.service.ts | 75 +- .../authz/decorators/get-user.decorator.ts | 12 +- .../src/authz/decorators/roles.decorator.ts | 16 +- .../src/authz/decorators/user.decorator.ts | 12 +- .../src/authz/dtos/auth-token-res.dto.ts | 30 +- .../src/authz/dtos/client-login.dto.ts | 11 +- .../src/authz/dtos/firebase-token.dto.ts | 14 +- .../src/authz/dtos/forgot-password.dto.ts | 64 +- .../src/authz/dtos/refresh-token.dto.ts | 20 +- .../src/authz/dtos/requesting-user.dto.ts | 31 +- .../src/authz/dtos/reset-password.dto.ts | 39 +- .../src/authz/dtos/reset-token-password.ts | 31 +- .../src/authz/dtos/user-login.dto.ts | 14 +- .../src/authz/dtos/user-role-org-perms.dto.ts | 19 +- .../src/authz/guards/org-roles.guard.ts | 126 +- .../src/authz/guards/user-access-guard.ts | 26 +- .../src/authz/guards/user-role.guard.ts | 16 +- .../src/authz/jwt-payload.interface.ts | 23 +- apps/api-gateway/src/authz/jwt.strategy.ts | 109 +- .../src/authz/mobile-jwt.strategy.ts | 57 +- apps/api-gateway/src/authz/roles.guard.ts | 50 +- apps/api-gateway/src/authz/socket.gateway.ts | 108 +- .../cloud-wallet/cloud-wallet.controller.ts | 1079 +++++----- .../src/cloud-wallet/cloud-wallet.module.ts | 41 +- .../src/cloud-wallet/cloud-wallet.service.ts | 189 +- .../dtos/accept-proof-request.dto.ts | 16 +- .../src/cloud-wallet/dtos/cloudWallet.dto.ts | 420 ++-- .../dtos/configure-base-wallet.dto.ts | 18 +- .../dtos/create-connection.dto.ts | 106 +- .../cloud-wallet/enums/connections.enum.ts | 6 +- .../src/connection/connection.controller.ts | 719 ++++--- .../src/connection/connection.module.ts | 41 +- .../src/connection/connection.service.ts | 155 +- .../src/connection/dtos/connection.dto.ts | 665 +++--- .../dtos/get-all-connections.dto.ts | 36 +- .../connection/dtos/question-answer.dto.ts | 187 +- .../src/connection/enums/connections.enum.ts | 6 +- .../src/connection/interfaces/index.ts | 166 +- .../credential-definition.controller.spec.ts | 221 +- .../credential-definition.controller.ts | 156 +- .../credential-definition.module.ts | 27 +- .../credential-definition.service.spec.ts | 20 +- .../credential-definition.service.ts | 49 +- .../dto/create-cred-defs.dto.ts | 51 +- .../dto/get-all-cred-defs.dto.ts | 57 +- .../dto/get-all-platform-cred-defs.dto.ts | 48 +- .../credential-definition/interfaces/index.ts | 91 +- apps/api-gateway/src/dtos/PresentProof.dto.ts | 4 +- .../src/dtos/UpdateNonAdminUser.dto.ts | 20 +- .../src/dtos/admin-onboard-user.dto.ts | 103 +- .../src/dtos/admin-profile-update.dto.ts | 94 +- .../src/dtos/apiResponse.dto copy.ts | 18 +- apps/api-gateway/src/dtos/apiResponse.dto.ts | 18 +- .../src/dtos/approval-status.dto.ts | 7 +- apps/api-gateway/src/dtos/authDto.dto.ts | 36 +- .../src/dtos/bad-request-error.dto.ts | 17 +- apps/api-gateway/src/dtos/category.dto.ts | 32 +- .../src/dtos/connection-out-of-band.dto.ts | 38 +- apps/api-gateway/src/dtos/connection.dto.ts | 71 +- .../dtos/create-credential-definition.dto.ts | 45 +- .../src/dtos/create-feature-price.dto.ts | 47 +- .../src/dtos/create-proof-request.dto.ts | 32 +- .../dtos/create-revocation-registry.dto.ts | 17 +- .../api-gateway/src/dtos/create-schema.dto.ts | 144 +- .../src/dtos/createEnterprise-query.dto.ts | 68 +- .../src/dtos/created-response-dto.ts | 20 +- .../src/dtos/credential-offer.dto.ts | 57 +- .../src/dtos/credential-send-offer.dto.ts | 13 +- .../src/dtos/email-validator.dto.ts | 14 +- apps/api-gateway/src/dtos/email.dto.ts | 26 +- .../src/dtos/endorse-transaction.dto.ts | 4 +- apps/api-gateway/src/dtos/enums.ts | 56 +- apps/api-gateway/src/dtos/fido-user.dto.ts | 144 +- .../src/dtos/forbidden-error.dto copy.ts | 11 +- .../src/dtos/forbidden-error.dto.ts | 11 +- .../src/dtos/forgot-password.dto.ts | 31 +- apps/api-gateway/src/dtos/geo-location-dto.ts | 10 +- .../api-gateway/src/dtos/get-cred-defs.dto.ts | 14 +- .../src/dtos/holder-details.dto.ts | 108 +- .../src/dtos/holder-reset-password.ts | 39 +- .../src/dtos/internal-server-error-res.dto.ts | 11 +- .../src/dtos/issue-credential-offer.dto .ts | 108 +- .../dtos/issue-credential-out-of-band.dto.ts | 104 +- .../src/dtos/issue-credential-save.dto.ts | 91 +- .../src/dtos/issue-credential.dto.ts | 68 +- apps/api-gateway/src/dtos/label-editor.dto.ts | 16 +- .../src/dtos/not-found-error.dto.ts | 27 +- .../src/dtos/org-name-check.dto.ts | 25 +- .../src/dtos/platform-config.dto.ts | 26 +- .../src/dtos/platform-connection.dtos.ts | 32 +- .../src/dtos/printable-form-details.dto.ts | 16 +- .../src/dtos/register-non-admin-user.dto.ts | 80 +- .../src/dtos/register-tenant.dto.ts | 37 +- .../api-gateway/src/dtos/register-user.dto.ts | 221 +- .../src/dtos/remote-get-credential.dto.ts | 21 +- .../api-gateway/src/dtos/remove-holder.dto.ts | 20 +- .../src/dtos/reset-password.dto.ts | 38 +- .../src/dtos/revoke-credential.dto.ts | 60 +- .../src/dtos/save-roles-permissions.dto.ts | 14 +- apps/api-gateway/src/dtos/schemasearch.dto.ts | 67 +- .../src/dtos/send-invite-toOrg.dto.ts | 34 +- .../src/dtos/send-proof-request.dto.ts | 45 +- apps/api-gateway/src/dtos/subscription.dto.ts | 11 +- .../src/dtos/unauthorized-error.dto.ts | 11 +- .../src/dtos/update-profile.dto.ts | 35 +- .../dtos/update-revocation-registry.dto.ts | 19 +- apps/api-gateway/src/dtos/user-counts.dto.ts | 10 +- .../src/dtos/user-profile-update.dto.ts | 22 +- .../src/dtos/user-role-org-perms.dto.ts | 34 +- .../src/dtos/wallet-details.dto.ts | 22 +- apps/api-gateway/src/enum.ts | 121 +- .../api-gateway/src/fido/dto/fido-user.dto.ts | 121 +- apps/api-gateway/src/fido/fido.controller.ts | 459 +++-- apps/api-gateway/src/fido/fido.module.ts | 27 +- apps/api-gateway/src/fido/fido.service.ts | 107 +- .../geo-location/geo-location.controller.ts | 61 +- .../src/geo-location/geo-location.module.ts | 32 +- .../src/geo-location/geo-location.service.ts | 33 +- .../src/helper-files/file-operation.helper.ts | 52 +- .../interfaces/IConnectionSearch.interface.ts | 50 +- .../src/interfaces/ISchemaSearch.interface.ts | 64 +- .../src/interfaces/ISocket.interface.ts | 20 +- .../src/interfaces/IUserRequestInterface.ts | 25 +- .../src/interfaces/fileExport.interface.ts | 16 +- .../dtos/get-all-issued-credentials.dto.ts | 19 +- .../src/issuance/dtos/issuance.dto.ts | 272 +-- .../src/issuance/dtos/multi-connection.dto.ts | 208 +- .../src/issuance/interfaces/index.ts | 161 +- .../src/issuance/issuance.controller.ts | 518 ++--- .../src/issuance/issuance.module.ts | 28 +- .../src/issuance/issuance.service.ts | 168 +- apps/api-gateway/src/issuance/utils/helper.ts | 32 +- apps/api-gateway/src/main.ts | 116 +- .../src/notification/dtos/notification.dto.ts | 127 +- .../interfaces/notification.interfaces.ts | 8 +- .../notification/notification.controller.ts | 141 +- .../src/notification/notification.module.ts | 32 +- .../src/notification/notification.service.ts | 61 +- .../dtos/client-credentials.dto.ts | 24 +- .../dtos/create-organization-dto.ts | 24 +- .../dtos/get-organizations.dto.ts | 22 +- .../organization/dtos/send-invitation.dto.ts | 59 +- .../organization/dtos/set-primary-did.dto.ts | 32 +- .../dtos/update-organization-dto.ts | 22 +- .../dtos/update-user-roles.dto.ts | 29 +- .../organization/organization.controller.ts | 386 ++-- .../src/organization/organization.module.ts | 30 +- .../src/organization/organization.service.ts | 158 +- .../src/platform/platform.controller.spec.ts | 139 +- .../src/platform/platform.controller.ts | 381 ++-- .../src/platform/platform.interface.ts | 45 +- .../src/platform/platform.module.ts | 24 +- .../src/platform/platform.service.ts | 75 +- .../src/revocation/revocation.controller.ts | 129 +- .../src/revocation/revocation.module.ts | 22 +- .../src/revocation/revocation.service.ts | 61 +- .../src/schema/dtos/create-schema.dto.ts | 43 +- .../src/schema/dtos/get-all-schema.dto.ts | 246 ++- .../src/schema/dtos/update-schema-dto.ts | 12 +- .../src/schema/interfaces/index.ts | 75 +- .../src/schema/schema.controller.spec.ts | 399 ++-- .../src/schema/schema.controller.ts | 230 ++- apps/api-gateway/src/schema/schema.module.ts | 27 +- apps/api-gateway/src/schema/schema.service.ts | 69 +- .../user/dto/accept-reject-invitation.dto.ts | 37 +- apps/api-gateway/src/user/dto/add-user.dto.ts | 88 +- .../src/user/dto/create-user.dto.ts | 58 +- .../src/user/dto/email-verify.dto.ts | 35 +- .../src/user/dto/get-all-invitations.dto.ts | 18 +- .../src/user/dto/login-user.dto.ts | 31 +- .../user/dto/update-platform-settings.dto.ts | 46 +- .../src/user/dto/update-user-profile.dto.ts | 41 +- apps/api-gateway/src/user/interfaces/index.ts | 30 +- apps/api-gateway/src/user/user.controller.ts | 350 ++-- apps/api-gateway/src/user/user.module.ts | 31 +- apps/api-gateway/src/user/user.service.ts | 104 +- .../src/utilities/dtos/shortening-url.dto.ts | 67 +- .../src/utilities/utilities.controller.ts | 70 +- .../src/utilities/utilities.module.ts | 28 +- .../src/utilities/utilities.service.ts | 25 +- .../dto/get-all-proof-requests.dto.ts | 49 +- .../src/verification/dto/request-proof.dto.ts | 723 +++---- .../src/verification/dto/webhook-proof.dto.ts | 153 +- .../verification/enum/verification.enum.ts | 29 +- .../interfaces/verification.interface.ts | 118 +- .../verification/verification.controller.ts | 279 +-- .../src/verification/verification.module.ts | 24 +- .../src/verification/verification.service.ts | 96 +- .../src/webhook/dtos/get-webhoook-dto.ts | 33 +- .../src/webhook/dtos/register-webhook-dto.ts | 25 +- .../src/webhook/dtos/webhook-response-dto.ts | 31 +- .../src/webhook/webhook.controller.ts | 107 +- .../api-gateway/src/webhook/webhook.module.ts | 30 +- .../src/webhook/webhook.service.ts | 31 +- apps/api-gateway/test/app.e2e-spec.ts | 27 +- .../src/cloud-wallet.controller.ts | 67 +- apps/cloud-wallet/src/cloud-wallet.module.ts | 40 +- .../src/cloud-wallet.repository.ts | 121 +- apps/cloud-wallet/src/cloud-wallet.service.ts | 535 ++--- apps/cloud-wallet/src/main.ts | 33 +- apps/connection/src/connection.controller.ts | 72 +- apps/connection/src/connection.module.ts | 52 +- apps/connection/src/connection.repository.ts | 321 ++- apps/connection/src/connection.service.ts | 687 +++---- apps/connection/src/enum.ts | 6 +- apps/connection/src/enum/connection.enum.ts | 8 +- .../src/interfaces/connection.interfaces.ts | 392 ++-- .../src/interfaces/messaging.interfaces.ts | 22 +- apps/connection/src/main.ts | 35 +- apps/connection/test/app.e2e-spec.ts | 27 +- .../src/geo-location.controller.ts | 14 +- apps/geo-location/src/geo-location.module.ts | 40 +- .../src/geo-location.repository.ts | 38 +- apps/geo-location/src/geo-location.service.ts | 42 +- apps/geo-location/src/main.ts | 32 +- apps/issuance/enum/issuance.enum.ts | 10 +- .../interfaces/issuance.interfaces.ts | 558 ++--- .../libs/helpers/attributes.extractor.ts | 242 +-- .../libs/helpers/attributes.validator.ts | 51 +- apps/issuance/src/issuance.controller.ts | 92 +- apps/issuance/src/issuance.module.ts | 64 +- apps/issuance/src/issuance.processor.ts | 24 +- apps/issuance/src/issuance.repository.ts | 567 +++--- apps/issuance/src/issuance.service.ts | 1650 +++++++-------- apps/issuance/src/main.ts | 34 +- .../out-of-band-issuance.template.ts | 11 +- .../ledger/libs/helpers/w3c.schema.builder.ts | 316 +-- .../credential-definition.controller.ts | 103 +- .../credential-definition.module.ts | 45 +- .../credential-definition.service.ts | 811 ++++---- .../create-credential-definition.interface.ts | 105 +- .../credential-definition.interface.ts | 55 +- .../credential-definition/interfaces/index.ts | 85 +- .../credential-definition.repository.ts | 637 +++--- .../src/interfaces/ledgers.interface.ts | 10 +- apps/ledger/src/ledger.controller.spec.ts | 24 +- apps/ledger/src/ledger.controller.ts | 35 +- apps/ledger/src/ledger.module.ts | 49 +- apps/ledger/src/ledger.service.ts | 137 +- apps/ledger/src/main.ts | 32 +- .../src/repositories/ledger.repository.ts | 195 +- .../schema/dtos/user-role-org-perms.dto.ts | 49 +- apps/ledger/src/schema/enum/schema.enum.ts | 18 +- .../interfaces/schema-payload.interface.ts | 210 +- .../src/schema/interfaces/schema.interface.ts | 199 +- .../schema/repositories/schema.repository.ts | 342 ++-- apps/ledger/src/schema/schema.controller.ts | 115 +- apps/ledger/src/schema/schema.interface.ts | 74 +- apps/ledger/src/schema/schema.module.ts | 42 +- apps/ledger/src/schema/schema.service.ts | 727 +++---- .../interfaces/notification.interfaces.ts | 24 +- apps/notification/src/main.ts | 35 +- .../src/notification.controller.ts | 18 +- apps/notification/src/notification.module.ts | 44 +- .../src/notification.repository.ts | 117 +- apps/notification/src/notification.service.ts | 52 +- .../dtos/create-organization.dto.ts | 36 +- apps/organization/dtos/send-invitation.dto.ts | 12 +- .../organization/dtos/update-invitation.dt.ts | 16 +- .../dtos/verify-email-token.dto.ts | 12 +- .../interfaces/organization.interface.ts | 406 ++-- .../repositories/organization.repository.ts | 816 ++++---- apps/organization/src/main.ts | 34 +- .../src/organization.controller.ts | 199 +- apps/organization/src/organization.module.ts | 86 +- apps/organization/src/organization.service.ts | 1801 ++++++++--------- ...elete-organization-invitations.template.ts | 19 +- .../organization-invitation.template.ts | 43 +- .../organization-onboard.template.ts | 10 +- .../templates/organization-url-template.ts | 156 +- .../user/dtos/accept-reject-invitation.dto.ts | 8 +- apps/user/dtos/create-user.dto.ts | 10 +- apps/user/dtos/keycloak-register.dto.ts | 43 +- apps/user/dtos/login-user.dto.ts | 38 +- apps/user/dtos/verify-email.dto.ts | 4 +- apps/user/interfaces/user.interface.ts | 328 +-- .../user/repositories/fido-user.repository.ts | 119 +- .../repositories/user-device.repository.ts | 279 ++- apps/user/repositories/user.repository.ts | 513 ++--- apps/user/src/fido/dtos/fido-user.dto.ts | 309 ++- apps/user/src/fido/fido.controller.ts | 109 +- apps/user/src/fido/fido.module.ts | 60 +- apps/user/src/fido/fido.service.ts | 471 ++--- apps/user/src/main.ts | 32 +- apps/user/src/user.controller.ts | 190 +- apps/user/src/user.module.ts | 70 +- apps/user/src/user.service.ts | 1115 +++++----- .../user/templates/reset-password-template.ts | 27 +- apps/user/templates/user-email-template.ts | 28 +- apps/user/templates/user-onboard.template.ts | 10 +- apps/user/test/app.e2e-spec.ts | 29 +- .../interfaces/shortening-url.interface.ts | 12 +- apps/utility/src/main.ts | 34 +- apps/utility/src/utilities.controller.ts | 20 +- apps/utility/src/utilities.module.ts | 44 +- apps/utility/src/utilities.repository.ts | 85 +- apps/utility/src/utilities.service.ts | 108 +- .../src/interfaces/verification.interface.ts | 349 ++-- apps/verification/src/main.ts | 34 +- .../repositories/verification.repository.ts | 200 +- .../src/verification.controller.ts | 62 +- apps/verification/src/verification.module.ts | 73 +- apps/verification/src/verification.service.ts | 868 ++++---- .../out-of-band-verification.template.ts | 17 +- apps/webhook/interfaces/webhook.interfaces.ts | 8 +- apps/webhook/src/main.ts | 34 +- apps/webhook/src/webhook.controller.ts | 18 +- apps/webhook/src/webhook.module.ts | 38 +- apps/webhook/src/webhook.repository.ts | 65 +- apps/webhook/src/webhook.service.ts | 90 +- libs/aws/package.json | 4 +- libs/aws/src/aws.module.ts | 6 +- libs/aws/src/aws.service.spec.ts | 20 +- libs/aws/src/aws.service.ts | 80 +- libs/aws/src/index.ts | 4 +- .../src/client-registration.module.ts | 6 +- .../src/client-registration.service.spec.ts | 20 +- .../src/client-registration.service.ts | 482 ++--- .../src/dtos/accessTokenPayloadDto.ts | 11 +- .../client-credential-token-payload.dto.ts | 14 +- .../src/dtos/create-user.dto.ts | 32 +- .../src/dtos/userTokenPayloadDto.ts | 14 +- libs/client-registration/src/index.ts | 4 +- .../src/interfaces/client.interface.ts | 14 +- libs/common/package.json | 4 +- libs/common/src/NATSClient.ts | 53 +- libs/common/src/cast.helper.ts | 362 ++-- libs/common/src/common.constant.ts | 235 ++- libs/common/src/common.module.ts | 8 +- libs/common/src/common.service.spec.ts | 20 +- libs/common/src/common.service.ts | 244 +-- libs/common/src/common.utils.ts | 69 +- libs/common/src/dtos/email.dto.ts | 26 +- libs/common/src/dtos/pagination.dto.ts | 43 +- libs/common/src/exception-handler.ts | 115 +- libs/common/src/index.ts | 6 +- .../src/interfaces/agent-service.interface.ts | 105 +- .../src/interfaces/cloud-wallet.interface.ts | 438 ++-- .../src/interfaces/connection.interface.ts | 74 +- .../src/interfaces/cred-def.interface.ts | 51 +- libs/common/src/interfaces/did.interface.ts | 24 +- .../src/interfaces/geolocation.interface.ts | 28 +- libs/common/src/interfaces/interface.ts | 96 +- .../src/interfaces/issuance.interface.ts | 244 +-- .../src/interfaces/organization.interface.ts | 200 +- .../src/interfaces/response.interface.ts | 22 +- .../common/src/interfaces/schema.interface.ts | 205 +- libs/common/src/interfaces/user.interface.ts | 98 +- .../src/interfaces/verification.interface.ts | 86 +- .../src/interfaces/webhook.interface.ts | 6 +- libs/common/src/nats.config.ts | 26 +- libs/common/src/nats.interceptor.ts | 29 +- libs/common/src/response-messages/index.ts | 110 +- libs/common/src/send-grid-helper-file.ts | 29 +- libs/common/src/validator.ts | 69 +- libs/common/tsconfig.json | 2 +- libs/config/src/config.module.ts | 12 +- libs/config/src/config.service.ts | 16 +- libs/config/src/global-config.module.ts | 12 +- libs/config/src/index.ts | 6 +- libs/context/src/contextInterceptorModule.ts | 44 +- libs/context/src/contextModule.ts | 22 +- .../src/contextStorageService.interface.ts | 10 +- libs/context/src/index.ts | 4 +- .../src/nestjsClsContextStorageService.ts | 25 +- libs/enum/src/enum.module.ts | 6 +- libs/enum/src/enum.service.spec.ts | 20 +- libs/enum/src/enum.service.ts | 2 +- libs/enum/src/enum.ts | 80 +- libs/enum/src/index.ts | 4 +- libs/http-exception.filter.ts | 78 +- libs/keycloak-url/src/index.ts | 4 +- libs/keycloak-url/src/keycloak-url.module.ts | 6 +- libs/keycloak-url/src/keycloak-url.service.ts | 136 +- libs/logger/src/index.ts | 4 +- libs/logger/src/log.ts | 51 +- libs/logger/src/logger.interface.ts | 29 +- libs/logger/src/logger.module.ts | 60 +- libs/logger/src/logger.service.ts | 78 +- libs/logger/src/logging.interceptor.ts | 68 +- libs/logger/src/nestjsLoggerServiceAdapter.ts | 47 +- .../logger/src/transports/consoleTransport.ts | 70 +- libs/logger/src/transports/fileTransport.ts | 6 +- libs/logger/src/winstonLogger.ts | 142 +- libs/nest-cli.json | 2 +- libs/org-roles/enums/index.ts | 18 +- .../interfaces/org-roles.interface.ts | 16 +- libs/org-roles/repositories/index.ts | 88 +- libs/org-roles/src/index.ts | 4 +- libs/org-roles/src/org-roles.module.ts | 12 +- libs/org-roles/src/org-roles.service.ts | 38 +- libs/org-roles/tsconfig.lib.json | 2 +- libs/prisma-service/cli.ts | 124 +- libs/prisma-service/prisma/seed.ts | 858 ++++---- libs/prisma-service/src/index.ts | 4 +- .../src/prisma-service.module.ts | 6 +- .../src/prisma-service.service.ts | 12 +- libs/service/base.service.ts | 11 +- libs/service/nats.options.ts | 16 +- libs/supabase/src/index.ts | 4 +- libs/supabase/src/supabase.module.ts | 6 +- libs/supabase/src/supabase.service.ts | 39 +- libs/user-activity/interface/index.ts | 16 +- libs/user-activity/repositories/index.ts | 150 +- libs/user-activity/src/index.ts | 4 +- .../user-activity/src/user-activity.module.ts | 10 +- .../src/user-activity.service.ts | 26 +- libs/user-org-roles/repositories/index.ts | 78 +- libs/user-org-roles/src/index.ts | 4 +- .../src/user-org-roles.module.ts | 12 +- .../src/user-org-roles.service.ts | 61 +- libs/user-request/src/index.ts | 4 +- .../src/user-request.interface.ts | 74 +- libs/user-request/src/user-request.module.ts | 6 +- .../src/user-request.service.spec.ts | 20 +- libs/user-request/src/user-request.service.ts | 2 +- libs/validations/arrayKeyword.ts | 2 +- libs/validations/exclusiveMaximum.ts | 26 +- libs/validations/exclusiveMinimum.ts | 26 +- libs/validations/keyword.ts | 10 +- libs/validations/maxItems.ts | 26 +- libs/validations/maxLength.ts | 23 +- libs/validations/maximum.ts | 26 +- libs/validations/minItems.ts | 26 +- libs/validations/minLength.ts | 22 +- libs/validations/minimum.ts | 26 +- libs/validations/multipleOf.ts | 26 +- libs/validations/numberKeyword.ts | 2 +- libs/validations/objectKeyword.ts | 2 +- libs/validations/pattern.ts | 34 +- libs/validations/stringKeyword.ts | 4 +- libs/validations/uniqueItems.ts | 22 +- package.json | 20 +- .../taskdef/agent-provisioning-taskdef.json | 138 +- scripts/taskdef/agent-service-taskdef.json | 73 +- scripts/taskdef/api-gateway-taskdef.json | 122 +- scripts/taskdef/connection-taskdef.json | 73 +- scripts/taskdef/issuance-service-taskdef.json | 108 +- scripts/taskdef/ledger-taskdef.json | 75 +- scripts/taskdef/notification-taskdef.json | 73 +- scripts/taskdef/organization-taskdef.json | 75 +- scripts/taskdef/user-taskdef.json | 75 +- scripts/taskdef/utility-taskdef.json | 73 +- scripts/taskdef/verfication-taskdef.json | 75 +- scripts/taskdef/webhook-taskdef.json | 75 +- tsconfig.json | 143 +- 488 files changed, 25667 insertions(+), 25459 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index f55a1efc2..da9ec1c69 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,14 +2,14 @@ module.exports = { parser: '@typescript-eslint/parser', parserOptions: { project: 'tsconfig.json', - sourceType: 'module' + sourceType: 'module', }, plugins: ['@typescript-eslint/eslint-plugin'], extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], root: true, env: { node: true, - jest: true + jest: true, }, ignorePatterns: ['.eslintrc.js'], rules: { @@ -17,7 +17,7 @@ module.exports = { 'no-console': 'error', // "@typescript-eslint/consistent-type-imports": "error", '@typescript-eslint/no-unused-vars': [ - 'error' + 'error', // { // "argsIgnorePattern": "_" // } @@ -59,11 +59,11 @@ module.exports = { 'error', { array: true, - object: true + object: true, }, { - enforceForRenamedProperties: false - } + enforceForRenamedProperties: false, + }, ], 'prefer-numeric-literals': 'error', 'prefer-rest-params': 'warn', @@ -99,6 +99,6 @@ module.exports = { 'object-shorthand': 'error', 'prefer-const': 'error', 'prefer-template': 'error', - quotes: ['warn', 'single', { allowTemplateLiterals: true }] - } -}; \ No newline at end of file + quotes: ['warn', 'single', { allowTemplateLiterals: true }], + }, +} diff --git a/apps/agent-provisioning/src/agent-provisioning.controller.ts b/apps/agent-provisioning/src/agent-provisioning.controller.ts index 12f1f6c3b..ddb4f5925 100644 --- a/apps/agent-provisioning/src/agent-provisioning.controller.ts +++ b/apps/agent-provisioning/src/agent-provisioning.controller.ts @@ -1,19 +1,19 @@ -import { Controller } from '@nestjs/common'; -import { AgentProvisioningService } from './agent-provisioning.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { IWalletProvision } from './interface/agent-provisioning.interfaces'; +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { AgentProvisioningService } from './agent-provisioning.service' +import type { IWalletProvision } from './interface/agent-provisioning.interfaces' @Controller() export class AgentProvisioningController { - constructor(private readonly agentProvisioningService: AgentProvisioningService) { } + constructor(private readonly agentProvisioningService: AgentProvisioningService) {} /** - * Description: Wallet provision - * @param payload + * Description: Wallet provision + * @param payload * @returns Get DID and verkey */ @MessagePattern({ cmd: 'wallet-provisioning' }) walletProvision(payload: IWalletProvision): Promise { - return this.agentProvisioningService.walletProvision(payload); + return this.agentProvisioningService.walletProvision(payload) } } diff --git a/apps/agent-provisioning/src/agent-provisioning.module.ts b/apps/agent-provisioning/src/agent-provisioning.module.ts index 829667fc9..bc85ce690 100644 --- a/apps/agent-provisioning/src/agent-provisioning.module.ts +++ b/apps/agent-provisioning/src/agent-provisioning.module.ts @@ -1,14 +1,14 @@ -import { Logger, Module } from '@nestjs/common'; -import { AgentProvisioningController } from './agent-provisioning.controller'; -import { AgentProvisioningService } from './agent-provisioning.service'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { ConfigModule } from '@nestjs/config'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; +import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { Logger, Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { AgentProvisioningController } from './agent-provisioning.controller' +import { AgentProvisioningService } from './agent-provisioning.service' @Module({ imports: [ ConfigModule.forRoot(), @@ -20,9 +20,9 @@ import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.AGENT_PROVISIONING, process.env.AGENT_PROVISIONING_NKEY_SEED) - } - ]) + options: getNatsOptions(CommonConstants.AGENT_PROVISIONING, process.env.AGENT_PROVISIONING_NKEY_SEED), + }, + ]), ], controllers: [AgentProvisioningController], providers: [ @@ -30,8 +30,8 @@ import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; Logger, { provide: MICRO_SERVICE_NAME, - useValue: 'Agent-provisioning' - } - ] + useValue: 'Agent-provisioning', + }, + ], }) export class AgentProvisioningModule {} diff --git a/apps/agent-provisioning/src/agent-provisioning.service.ts b/apps/agent-provisioning/src/agent-provisioning.service.ts index 92d382358..b83c01585 100644 --- a/apps/agent-provisioning/src/agent-provisioning.service.ts +++ b/apps/agent-provisioning/src/agent-provisioning.service.ts @@ -1,80 +1,102 @@ -import { Injectable, Logger, NotFoundException } from '@nestjs/common'; -import { RpcException } from '@nestjs/microservices'; -import { IWalletProvision } from './interface/agent-provisioning.interfaces'; -import * as dotenv from 'dotenv'; -import { AgentType } from '@credebl/enum/enum'; -import * as fs from 'fs'; -import { exec } from 'child_process'; -dotenv.config(); +import * as fs from 'fs' +import { exec } from 'node:child_process' +import { AgentType } from '@credebl/enum/enum' +import { Injectable, type Logger, NotFoundException } from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' +import * as dotenv from 'dotenv' +import type { IWalletProvision } from './interface/agent-provisioning.interfaces' +dotenv.config() @Injectable() export class AgentProvisioningService { - - constructor( - private readonly logger: Logger - ) { } + constructor(private readonly logger: Logger) {} /** * Description: Wallet provision - * @param payload + * @param payload * @returns Get DID and verkey */ async walletProvision(payload: IWalletProvision): Promise { try { - - const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, credoImage, tenant, indyLedger, inboundEndpoint } = payload; + const { + containerName, + externalIp, + orgId, + seed, + walletName, + walletPassword, + walletStorageHost, + walletStoragePassword, + walletStoragePort, + walletStorageUser, + webhookEndpoint, + agentType, + protocol, + credoImage, + tenant, + indyLedger, + inboundEndpoint, + } = 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} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${process.env.SCHEMA_FILE_SERVER_URL} ${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) => { - this.logger.log(`shell script output: ${stdout}`); + const walletProvision = `${ + process.cwd() + process.env.AFJ_AGENT_SPIN_UP + } ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${ + process.env.SCHEMA_FILE_SERVER_URL + } ${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((resolve) => { + exec(walletProvision, async (_err, stdout, stderr) => { + this.logger.log(`shell script output: ${stdout}`) if (stderr) { - this.logger.log(`shell script error: ${stderr}`); + this.logger.log(`shell script error: ${stderr}`) } - const agentEndpointPath = `${process.cwd()}${process.env.AFJ_AGENT_ENDPOINT_PATH}${orgId}_${containerName}.json`; - const agentTokenPath = `${process.cwd()}${process.env.AFJ_AGENT_TOKEN_PATH}${orgId}_${containerName}.json`; + const agentEndpointPath = `${process.cwd()}${ + process.env.AFJ_AGENT_ENDPOINT_PATH + }${orgId}_${containerName}.json` + const agentTokenPath = `${process.cwd()}${process.env.AFJ_AGENT_TOKEN_PATH}${orgId}_${containerName}.json` - const agentEndPointExists = await this.checkFileExistence(agentEndpointPath); - const agentTokenExists = await this.checkFileExistence(agentTokenPath); + const agentEndPointExists = await this.checkFileExistence(agentEndpointPath) + const agentTokenExists = await this.checkFileExistence(agentTokenPath) - let agentEndPoint; - let agentToken; + let agentEndPoint: string + let agentToken: string if (agentEndPointExists && agentTokenExists) { - this.logger.log('Both files exist'); - agentEndPoint = await fs.readFileSync(agentEndpointPath, 'utf8'); - agentToken = await fs.readFileSync(agentTokenPath, 'utf8'); + this.logger.log('Both files exist') + agentEndPoint = fs.readFileSync(agentEndpointPath, 'utf8') + agentToken = fs.readFileSync(agentTokenPath, 'utf8') // Proceed with accessing the files if needed } else { - this.logger.log('One or both files do not exist'); - throw new NotFoundException(`${agentEndpointPath} or ${agentTokenPath} files do not exist `); + this.logger.log('One or both files do not exist') + throw new NotFoundException(`${agentEndpointPath} or ${agentTokenPath} files do not exist `) } resolve({ agentEndPoint: JSON.parse(agentEndPoint).CONTROLLER_ENDPOINT, - agentToken: JSON.parse(agentToken).token - }); - }); - }); - return spinUpResponse; - } else if (agentType === AgentType.ACAPY) { + agentToken: JSON.parse(agentToken).token, + }) + }) + }) + return spinUpResponse + } + if (agentType === AgentType.ACAPY) { // TODO: ACA-PY Agent Spin-Up } } catch (error) { - this.logger.error(`[walletProvision] - error in wallet provision: ${JSON.stringify(error)}`); - throw new RpcException(error); + this.logger.error(`[walletProvision] - error in wallet provision: ${JSON.stringify(error)}`) + throw new RpcException(error) } } async checkFileExistence(filePath: string): Promise { try { - await fs.accessSync(filePath); - return true; // File exists - } catch (error) { - return false; // File does not exist + await fs.accessSync(filePath) + return true // File exists + } catch (_error) { + return false // File does not exist } } } diff --git a/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts b/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts index f82b31cca..47454193d 100644 --- a/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts +++ b/apps/agent-provisioning/src/interface/agent-provisioning.interfaces.ts @@ -1,69 +1,69 @@ /* eslint-disable quotes */ -import { AgentType } from "@credebl/enum/enum"; +import type { AgentType } from '@credebl/enum/enum' export interface IWalletProvision { - orgId: string; - externalIp: string; - walletName: string; - walletPassword: string; - seed: string; - webhookEndpoint: string; - walletStorageHost: string; - walletStoragePort: string; - walletStorageUser: string; - walletStoragePassword: string; - internalIp: string; - containerName: string; - agentType: AgentType; - orgName: string; - indyLedger: string; - protocol: string; - credoImage: string; - tenant: boolean; - inboundEndpoint: string; - apiKey?:string; + orgId: string + externalIp: string + walletName: string + walletPassword: string + seed: string + webhookEndpoint: string + walletStorageHost: string + walletStoragePort: string + walletStorageUser: string + walletStoragePassword: string + internalIp: string + containerName: string + agentType: AgentType + orgName: string + indyLedger: string + protocol: string + credoImage: string + tenant: boolean + inboundEndpoint: string + apiKey?: string } export interface IAgentSpinUp { - issuerNumber: string; - issuerName: string; - externalIp: string; - genesisUrl: string; - adminKey: string; - walletName: string; - walletPassword: string; - randomSeed: string; - apiEndpoint: string; - walletStorageHost: string; - walletStoragePort: string; - walletStorageUser: string; - walletStoragePassword: string; - internalIp: string; - tailsFailServer: string; - containerName: string; + issuerNumber: string + issuerName: string + externalIp: string + genesisUrl: string + adminKey: string + walletName: string + walletPassword: string + randomSeed: string + apiEndpoint: string + walletStorageHost: string + walletStoragePort: string + walletStorageUser: string + walletStoragePassword: string + internalIp: string + tailsFailServer: string + containerName: string } export interface IStartStopAgent { - action: string; - orgId: string; - orgName: string; + action: string + orgId: string + orgName: string } export interface IAgentStatus { - apiKey: string; - agentEndPoint: string; - orgId: string; - agentSpinUpStatus: number; - orgName: string; + apiKey: string + agentEndPoint: string + orgId: string + agentSpinUpStatus: number + orgName: string } export interface IPlatformConfig { - externalIP: string; - genesisURL: string; - adminKey: string; - lastInternalIP: number; - platformTestNetApiKey: string; - sgEmailFrom: string; - apiEndpoint: string; - tailsFileServer: string; + externalIP: string + genesisURL: string + adminKey: string + lastInternalIP: number + platformTestNetApiKey: string + sgEmailFrom: string + apiEndpoint: string + tailsFileServer: string } diff --git a/apps/agent-provisioning/src/main.ts b/apps/agent-provisioning/src/main.ts index 4e9a61f80..dea345e50 100644 --- a/apps/agent-provisioning/src/main.ts +++ b/apps/agent-provisioning/src/main.ts @@ -1,23 +1,22 @@ -import { NestFactory } from '@nestjs/core'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { AgentProvisioningModule } from './agent-provisioning.module'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; -const logger = new Logger(); +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { AgentProvisioningModule } from './agent-provisioning.module' +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(AgentProvisioningModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.AGENT_PROVISIONING, process.env.AGENT_PROVISIONING_NKEY_SEED) - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.AGENT_PROVISIONING, process.env.AGENT_PROVISIONING_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Agent-Provisioning-Service Microservice is listening to NATS '); + await app.listen() + logger.log('Agent-Provisioning-Service Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/agent-provisioning/test/app.e2e-spec.ts b/apps/agent-provisioning/test/app.e2e-spec.ts index 244d42bd8..94e2a4aec 100644 --- a/apps/agent-provisioning/test/app.e2e-spec.ts +++ b/apps/agent-provisioning/test/app.e2e-spec.ts @@ -1,22 +1,19 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { AgentProvisioningModule } from './../src/agent-provisioning.module'; +import type { INestApplication } from '@nestjs/common' +import { Test, type TestingModule } from '@nestjs/testing' +import * as request from 'supertest' +import { AgentProvisioningModule } from './../src/agent-provisioning.module' describe('AgentProvisioningController (e2e)', () => { - let app: INestApplication; + let app: INestApplication beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AgentProvisioningModule] - }).compile(); + imports: [AgentProvisioningModule], + }).compile() - app = moduleFixture.createNestApplication(); - await app.init(); - }); + app = moduleFixture.createNestApplication() + await app.init() + }) - it('/ (GET)', () => request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!')); -}); + it('/ (GET)', () => request(app.getHttpServer()).get('/').expect(200).expect('Hello World!')) +}) diff --git a/apps/agent-service/src/agent-service.controller.ts b/apps/agent-service/src/agent-service.controller.ts index 64ea5a711..2cb31dc06 100644 --- a/apps/agent-service/src/agent-service.controller.ts +++ b/apps/agent-service/src/agent-service.controller.ts @@ -1,31 +1,31 @@ -import { Controller } from '@nestjs/common'; -import { MessagePattern } from '@nestjs/microservices'; -import { AgentServiceService } from './agent-service.service'; -import { +import type { InvitationMessage } from '@credebl/common/interfaces/agent-service.interface' +import type { AgentSpinUpStatus } from '@credebl/enum/enum' +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { user } from '@prisma/client' +import type { AgentServiceService } from './agent-service.service' +import type { + IAgentConfigure, + IAgentProofRequest, + IAgentSpinUpSatus, + IAgentSpinupDto, IAgentStatus, IConnectionDetails, - IUserRequestInterface, - ISendProofRequestPayload, - IAgentSpinUpSatus, + ICreateConnectionInvitation, + IDidCreate, IGetCredDefAgentRedirection, IGetSchemaAgentRedirection, - IAgentSpinupDto, IIssuanceCreateOffer, + IOutOfBandCredentialOffer, + ISendProofRequestPayload, + IStoreAgent, ITenantCredDef, ITenantDto, + ITenantRecord, ITenantSchema, - IOutOfBandCredentialOffer, - IAgentProofRequest, - IDidCreate, + IUserRequestInterface, IWallet, - ITenantRecord, - ICreateConnectionInvitation, - IStoreAgent, - IAgentConfigure -} from './interface/agent-service.interface'; -import { user } from '@prisma/client'; -import { InvitationMessage } from '@credebl/common/interfaces/agent-service.interface'; -import { AgentSpinUpStatus } from '@credebl/enum/enum'; +} from './interface/agent-service.interface' @Controller() export class AgentServiceController { @@ -37,134 +37,134 @@ export class AgentServiceController { * @returns Get agent status */ @MessagePattern({ cmd: 'agent-spinup' }) - async walletProvision(payload: { agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface }): Promise<{ - agentSpinupStatus: AgentSpinUpStatus; + async walletProvision(payload: { agentSpinupDto: IAgentSpinupDto; user: IUserRequestInterface }): Promise<{ + agentSpinupStatus: AgentSpinUpStatus }> { - return this.agentServiceService.walletProvision(payload.agentSpinupDto, payload.user); + return this.agentServiceService.walletProvision(payload.agentSpinupDto, payload.user) } //DONE @MessagePattern({ cmd: 'create-tenant' }) async createTenant(payload: { - createTenantDto: ITenantDto, - user: IUserRequestInterface, + createTenantDto: ITenantDto + user: IUserRequestInterface }): Promise { - return this.agentServiceService.createTenant(payload.createTenantDto, payload.user); + return this.agentServiceService.createTenant(payload.createTenantDto, payload.user) } /** * @returns did */ @MessagePattern({ cmd: 'create-did' }) - async createDid(payload: { createDidDto: IDidCreate, orgId: string, user: IUserRequestInterface }): Promise { - return this.agentServiceService.createDid(payload.createDidDto, payload.orgId, payload.user); + async createDid(payload: { createDidDto: IDidCreate; orgId: string; user: IUserRequestInterface }): Promise { + return this.agentServiceService.createDid(payload.createDidDto, payload.orgId, payload.user) } @MessagePattern({ cmd: 'create-wallet' }) - async createWallet(payload: { createWalletDto: IWallet, user: IUserRequestInterface }): Promise { - return this.agentServiceService.createWallet(payload.createWalletDto); + async createWallet(payload: { createWalletDto: IWallet; user: IUserRequestInterface }): Promise { + return this.agentServiceService.createWallet(payload.createWalletDto) } //DONE @MessagePattern({ cmd: 'agent-create-schema' }) async createSchema(payload: ITenantSchema): Promise { - return this.agentServiceService.createSchema(payload); + return this.agentServiceService.createSchema(payload) } //DONE @MessagePattern({ cmd: 'agent-create-w3c-schema' }) - async createW3CSchema(payload: { url, orgId, schemaRequestPayload }): Promise { - return this.agentServiceService.createW3CSchema(payload.url, payload.orgId, payload.schemaRequestPayload); + async createW3CSchema(payload: { url; orgId; schemaRequestPayload }): Promise { + return this.agentServiceService.createW3CSchema(payload.url, payload.orgId, payload.schemaRequestPayload) } //DONE @MessagePattern({ cmd: 'agent-get-schema' }) async getSchemaById(payload: IGetSchemaAgentRedirection): Promise { - return this.agentServiceService.getSchemaById(payload); + return this.agentServiceService.getSchemaById(payload) } //DONE @MessagePattern({ cmd: 'agent-create-credential-definition' }) async createCredentialDefinition(payload: ITenantCredDef): Promise { - return this.agentServiceService.createCredentialDefinition(payload); + return this.agentServiceService.createCredentialDefinition(payload) } // DONE @MessagePattern({ cmd: 'agent-get-credential-definition' }) async getCredentialDefinitionById(payload: IGetCredDefAgentRedirection): Promise { - return this.agentServiceService.getCredentialDefinitionById(payload); + return this.agentServiceService.getCredentialDefinitionById(payload) } //DONE @MessagePattern({ cmd: 'agent-create-connection-legacy-invitation' }) async createLegacyConnectionInvitation(payload: { - connectionPayload: IConnectionDetails; - url: string, - orgId: string, + connectionPayload: IConnectionDetails + url: string + orgId: string }): Promise { return this.agentServiceService.createLegacyConnectionInvitation( payload.connectionPayload, payload.url, payload.orgId - ); + ) } @MessagePattern({ cmd: 'agent-send-credential-create-offer' }) async sendCredentialCreateOffer(payload: { - issueData: IIssuanceCreateOffer; - url: string, - orgId: string, + issueData: IIssuanceCreateOffer + url: string + orgId: string }): Promise { - return this.agentServiceService.sendCredentialCreateOffer(payload.issueData, payload.url, payload.orgId); + return this.agentServiceService.sendCredentialCreateOffer(payload.issueData, payload.url, payload.orgId) } //DONE @MessagePattern({ cmd: 'agent-get-all-issued-credentials' }) - async getIssueCredentials(payload: { url: string, apiKey: string }): Promise { - return this.agentServiceService.getIssueCredentials(payload.url, payload.apiKey); + 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, orgId: string }): Promise { - return this.agentServiceService.getIssueCredentialsbyCredentialRecordId(payload.url, payload.orgId); + async getIssueCredentialsbyCredentialRecordId(payload: { url: string; orgId: string }): Promise { + return this.agentServiceService.getIssueCredentialsbyCredentialRecordId(payload.url, payload.orgId) } //DONE @MessagePattern({ cmd: 'agent-get-proof-presentations' }) - async getProofPresentations(payload: { url: string, apiKey: string }): Promise { - return this.agentServiceService.getProofPresentations(payload.url, payload.apiKey); + 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, orgId: string }): Promise { - return this.agentServiceService.getProofPresentationById(payload.url, payload.orgId); + async getProofPresentationById(payload: { url: string; orgId: string }): Promise { + return this.agentServiceService.getProofPresentationById(payload.url, payload.orgId) } //DONE @MessagePattern({ cmd: 'agent-send-proof-request' }) async sendProofRequest(payload: { - proofRequestPayload: ISendProofRequestPayload, - url: string, - orgId: string, + proofRequestPayload: ISendProofRequestPayload + url: string + orgId: string }): Promise { - return this.agentServiceService.sendProofRequest(payload.proofRequestPayload, payload.url, payload.orgId); + return this.agentServiceService.sendProofRequest(payload.proofRequestPayload, payload.url, payload.orgId) } //DONE @MessagePattern({ cmd: 'agent-verify-presentation' }) - async verifyPresentation(payload: { url: string, orgId: string }): Promise { - return this.agentServiceService.verifyPresentation(payload.url, payload.orgId); + async verifyPresentation(payload: { url: string; orgId: string }): Promise { + return this.agentServiceService.verifyPresentation(payload.url, payload.orgId) } //DONE @MessagePattern({ cmd: 'agent-get-all-connections' }) - async getConnections(payload: { url: string, orgId: string }): Promise { - return this.agentServiceService.getConnections(payload.url, payload.orgId); + async getConnections(payload: { url: string; orgId: string }): Promise { + return this.agentServiceService.getConnections(payload.url, payload.orgId) } @MessagePattern({ cmd: 'agent-get-connection-details-by-connectionId' }) - async getConnectionsByconnectionId(payload: { url: string, orgId: string }): Promise { - return this.agentServiceService.getConnectionsByconnectionId(payload.url, payload.orgId); + async getConnectionsByconnectionId(payload: { url: string; orgId: string }): Promise { + return this.agentServiceService.getConnectionsByconnectionId(payload.url, payload.orgId) } /** @@ -173,116 +173,116 @@ export class AgentServiceController { * @returns Get agent health */ @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 }): Promise { + return this.agentServiceService.getAgentHealthDetails(payload.orgId) } @MessagePattern({ cmd: 'get-ledger-config' }) async getLedgerConfig(payload: { user: IUserRequestInterface }): Promise { - return this.agentServiceService.getLedgerConfigDetails(payload.user); + return this.agentServiceService.getLedgerConfigDetails(payload.user) } //DONE @MessagePattern({ cmd: 'agent-send-out-of-band-proof-request' }) async sendOutOfBandProofRequest(payload: { - proofRequestPayload: ISendProofRequestPayload, - url: string, - orgId: string, + proofRequestPayload: ISendProofRequestPayload + url: string + orgId: string }): Promise { - return this.agentServiceService.sendOutOfBandProofRequest(payload.proofRequestPayload, payload.url, payload.orgId); + return this.agentServiceService.sendOutOfBandProofRequest(payload.proofRequestPayload, payload.url, payload.orgId) } //DONE @MessagePattern({ cmd: 'get-agent-verified-proof-details' }) - async getVerifiedProofDetails(payload: { url: string, orgId: string }): Promise { - return this.agentServiceService.getVerifiedProofDetails(payload.url, payload.orgId); + async getVerifiedProofDetails(payload: { url: string; orgId: string }): Promise { + return this.agentServiceService.getVerifiedProofDetails(payload.url, payload.orgId) } @MessagePattern({ cmd: 'agent-schema-endorsement-request' }) async schemaEndorsementRequest(payload: { - url: string, - orgId: string, - requestSchemaPayload: object, + url: string + orgId: string + requestSchemaPayload: object }): Promise { - return this.agentServiceService.schemaEndorsementRequest(payload.url, payload.orgId, payload.requestSchemaPayload); + return this.agentServiceService.schemaEndorsementRequest(payload.url, payload.orgId, payload.requestSchemaPayload) } @MessagePattern({ cmd: 'agent-credDef-endorsement-request' }) async credDefEndorsementRequest(payload: { - url: string; - orgId: string; - requestSchemaPayload: object; + url: string + orgId: string + requestSchemaPayload: object }): Promise { - return this.agentServiceService.credDefEndorsementRequest(payload.url, payload.orgId, payload.requestSchemaPayload); + return this.agentServiceService.credDefEndorsementRequest(payload.url, payload.orgId, payload.requestSchemaPayload) } //DONE @MessagePattern({ cmd: 'agent-sign-transaction' }) - async signTransaction(payload: { url: string, orgId: string, signEndorsementPayload: object }): Promise { - return this.agentServiceService.signTransaction(payload.url, payload.orgId, payload.signEndorsementPayload); + async signTransaction(payload: { url: string; orgId: string; signEndorsementPayload: object }): Promise { + return this.agentServiceService.signTransaction(payload.url, payload.orgId, payload.signEndorsementPayload) } //DONE @MessagePattern({ cmd: 'agent-submit-transaction' }) - async submitTransaction(payload: { url: string; orgId: string, submitEndorsementPayload: object }): Promise { - return this.agentServiceService.sumbitTransaction(payload.url, payload.orgId, payload.submitEndorsementPayload); + async submitTransaction(payload: { url: string; orgId: string; submitEndorsementPayload: object }): Promise { + return this.agentServiceService.sumbitTransaction(payload.url, payload.orgId, payload.submitEndorsementPayload) } //DONE @MessagePattern({ cmd: 'agent-out-of-band-credential-offer' }) async outOfBandCredentialOffer(payload: { - outOfBandIssuancePayload: IOutOfBandCredentialOffer, - url: string, - orgId: string, + outOfBandIssuancePayload: IOutOfBandCredentialOffer + url: string + orgId: string }): Promise { return this.agentServiceService.outOfBandCredentialOffer( payload.outOfBandIssuancePayload, payload.url, payload.orgId - ); + ) } @MessagePattern({ cmd: 'delete-wallet' }) - async deleteWallet(payload: { orgId, user }): Promise { - return this.agentServiceService.deleteWallet(payload.orgId, payload.user); + async deleteWallet(payload: { orgId; user }): Promise { + return this.agentServiceService.deleteWallet(payload.orgId, payload.user) } @MessagePattern({ cmd: 'agent-receive-invitation-url' }) - async receiveInvitationUrl(payload: { url, orgId, receiveInvitationUrl }): Promise { - return this.agentServiceService.receiveInvitationUrl(payload.receiveInvitationUrl, payload.url, payload.orgId); + async receiveInvitationUrl(payload: { url; orgId; receiveInvitationUrl }): Promise { + return this.agentServiceService.receiveInvitationUrl(payload.receiveInvitationUrl, payload.url, payload.orgId) } @MessagePattern({ cmd: 'agent-receive-invitation' }) - async receiveInvitation(payload: { url, orgId, receiveInvitation }): Promise { - return this.agentServiceService.receiveInvitation(payload.receiveInvitation, payload.url, payload.orgId); + async receiveInvitation(payload: { url; orgId; receiveInvitation }): Promise { + return this.agentServiceService.receiveInvitation(payload.receiveInvitation, payload.url, payload.orgId) } @MessagePattern({ cmd: 'agent-send-question' }) - async sendQuestion(payload: { url, orgId, questionPayload }): Promise { - return this.agentServiceService.sendQuestion(payload.questionPayload, payload.url, payload.orgId); + async sendQuestion(payload: { url; orgId; questionPayload }): Promise { + return this.agentServiceService.sendQuestion(payload.questionPayload, payload.url, payload.orgId) } @MessagePattern({ cmd: 'agent-send-basic-message' }) - async sendBasicMessage(payload: { url, orgId, content }): Promise { - return this.agentServiceService.sendBasicMessage(payload.content, payload.url, payload.orgId); + async sendBasicMessage(payload: { url; orgId; content }): Promise { + return this.agentServiceService.sendBasicMessage(payload.content, payload.url, payload.orgId) } @MessagePattern({ cmd: 'agent-get-question-answer-record' }) - async getQuestionAnswersRecord(payload: { url: string, orgId: string }): Promise { - return this.agentServiceService.getQuestionAnswersRecord(payload.url, payload.orgId); + async getQuestionAnswersRecord(payload: { url: string; orgId: string }): Promise { + return this.agentServiceService.getQuestionAnswersRecord(payload.url, payload.orgId) } @MessagePattern({ cmd: 'polygon-create-keys' }) async createSecp256k1KeyPair(payload: { orgId: string }): Promise { - return this.agentServiceService.createSecp256k1KeyPair(payload.orgId); + return this.agentServiceService.createSecp256k1KeyPair(payload.orgId) } @MessagePattern({ cmd: 'agent-create-connection-invitation' }) async createConnectionInvitation(payload: { - url: string, - orgId: string, - connectionPayload: ICreateConnectionInvitation, + url: string + orgId: string + connectionPayload: ICreateConnectionInvitation }): Promise { - return this.agentServiceService.createConnectionInvitation(payload.url, payload.orgId, payload.connectionPayload); + return this.agentServiceService.createConnectionInvitation(payload.url, payload.orgId, payload.connectionPayload) } /** @@ -292,16 +292,16 @@ export class AgentServiceController { */ @MessagePattern({ cmd: 'agent-configure' }) async agentConfigure(payload: { - agentConfigureDto: IAgentConfigure, - user: IUserRequestInterface, + agentConfigureDto: IAgentConfigure + user: IUserRequestInterface }): Promise { - return this.agentServiceService.agentConfigure(payload.agentConfigureDto, payload.user); + return this.agentServiceService.agentConfigure(payload.agentConfigureDto, payload.user) } @MessagePattern({ cmd: 'get-agent-details-by-org-id' }) async agentdetailsByOrgId(payload: { - orgId: string, + orgId: string }): Promise { - return this.agentServiceService.getAgentDetails(payload.orgId); + return this.agentServiceService.getAgentDetails(payload.orgId) } -} \ No newline at end of file +} diff --git a/apps/agent-service/src/agent-service.module.ts b/apps/agent-service/src/agent-service.module.ts index d8fe46193..15fe7dcfe 100644 --- a/apps/agent-service/src/agent-service.module.ts +++ b/apps/agent-service/src/agent-service.module.ts @@ -1,38 +1,39 @@ -import { CommonModule } from '@credebl/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { Logger, Module } from '@nestjs/common'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { AgentServiceController } from './agent-service.controller'; -import { AgentServiceService } from './agent-service.service'; -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'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { NATSClient } from '@credebl/common/NATSClient'; - +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { CacheModule } from '@nestjs/cache-manager' +import { Logger, Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { ConnectionRepository } from 'apps/connection/src/connection.repository' +import { ConnectionService } from 'apps/connection/src/connection.service' +import { UserActivityRepository } from 'libs/user-activity/repositories' +import { AgentServiceController } from './agent-service.controller' +import { AgentServiceService } from './agent-service.service' +import { AgentServiceRepository } from './repositories/agent-service.repository' @Module({ imports: [ ConfigModule.forRoot(), GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, + LoggerModule, + PlatformConfig, + ContextInterceptorModule, ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.AGENT_SERVICE, process.env.AGENT_SERVICE_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.AGENT_SERVICE, process.env.AGENT_SERVICE_NKEY_SEED), + }, ]), CommonModule, - CacheModule.register() + CacheModule.register(), ], controllers: [AgentServiceController], providers: [ @@ -45,10 +46,10 @@ import { NATSClient } from '@credebl/common/NATSClient'; UserActivityRepository, { provide: MICRO_SERVICE_NAME, - useValue: 'Agent-service' + useValue: 'Agent-service', }, - NATSClient + NATSClient, ], - exports: [AgentServiceService, AgentServiceRepository, AgentServiceModule] + exports: [AgentServiceService, AgentServiceRepository, 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 acac5a637..7229a01c4 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs' /* eslint-disable quotes */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable yoda */ @@ -13,76 +14,78 @@ import { Injectable, InternalServerErrorException, Logger, - NotFoundException -} from '@nestjs/common'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import * as dotenv from 'dotenv'; -import * as fs from 'fs'; -import { map } from 'rxjs/operators'; -dotenv.config(); + NotFoundException, +} from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +import * as dotenv from 'dotenv' +import { map } from 'rxjs/operators' +dotenv.config() +import type { CommonService } from '@credebl/common' +import type { NATSClient } from '@credebl/common/NATSClient' +import { ledgerName } from '@credebl/common/cast.helper' +import { CommonConstants } from '@credebl/common/common.constant' +import type { InvitationMessage } from '@credebl/common/interfaces/agent-service.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { AgentSpinUpStatus, AgentType, DidMethod, Ledgers, OrgAgentType, PromiseResult } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import { CACHE_MANAGER } from '@nestjs/cache-manager' +import { WebSocketGateway } from '@nestjs/websockets' import { - IGetCredDefAgentRedirection, - IConnectionDetails, - IUserRequestInterface, - IAgentSpinupDto, - IStoreOrgAgentDetails, - ITenantCredDef, - ITenantDto, - ITenantSchema, - IWalletProvision, - ISendProofRequestPayload, - IIssuanceCreateOffer, - IOutOfBandCredentialOffer, - IAgentSpinUpSatus, - ICreateTenant, - IAgentStatus, - ICreateOrgAgent, - IOrgAgentsResponse, - IProofPresentation, - IAgentProofRequest, - IPresentation, - IReceiveInvitationUrl, - IReceiveInvitation, - IQuestionPayload, - IDidCreate, - IWallet, - ITenantRecord, - LedgerListResponse, - ICreateConnectionInvitation, - IStoreAgent, - AgentHealthData, - IAgentStore, - IAgentConfigure, - OrgDid, - IBasicMessage -} from './interface/agent-service.interface'; -import { AgentSpinUpStatus, AgentType, DidMethod, Ledgers, OrgAgentType, PromiseResult } from '@credebl/enum/enum'; -import { AgentServiceRepository } from './repositories/agent-service.repository'; -import { Prisma, RecordType, ledgers, org_agents, organisation, platform_config, user } from '@prisma/client'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { CommonService } from '@credebl/common'; -import { GetSchemaAgentRedirection } from 'apps/ledger/src/schema/schema.interface'; -import { ConnectionService } from 'apps/connection/src/connection.service'; -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'; -import { IProofPresentationDetails } from '@credebl/common/interfaces/verification.interface'; -import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; -import { ledgerName } from '@credebl/common/cast.helper'; -import { InvitationMessage } from '@credebl/common/interfaces/agent-service.interface'; -import * as CryptoJS from 'crypto-js'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { PrismaService } from '@credebl/prisma-service'; -import { from } from 'rxjs'; -import { NATSClient } from '@credebl/common/NATSClient'; + RecordType, + type ledgers, + type org_agents, + type organisation, + type platform_config, + type user, +} from '@prisma/client' +import type { ConnectionService } from 'apps/connection/src/connection.service' +import type { GetSchemaAgentRedirection } from 'apps/ledger/src/schema/schema.interface' +import * as retry from 'async-retry' +import type { Cache } from 'cache-manager' +import * as CryptoJS from 'crypto-js' +import type { UserActivityRepository } from 'libs/user-activity/repositories' +import { from } from 'rxjs' +import { type Socket, io } from 'socket.io-client' +import { + type AgentHealthData, + type IAgentConfigure, + type IAgentProofRequest, + type IAgentSpinUpSatus, + type IAgentSpinupDto, + type IAgentStatus, + type IBasicMessage, + type IConnectionDetails, + type ICreateConnectionInvitation, + type ICreateOrgAgent, + type ICreateTenant, + type IDidCreate, + type IGetCredDefAgentRedirection, + type IIssuanceCreateOffer, + IOrgAgent, + type IOrgAgentsResponse, + type IOutOfBandCredentialOffer, + type IQuestionPayload, + type IReceiveInvitation, + type IReceiveInvitationUrl, + type ISendProofRequestPayload, + type IStoreAgent, + type IStoreOrgAgentDetails, + type ITenantCredDef, + type ITenantDto, + type ITenantRecord, + type ITenantSchema, + type IUserRequestInterface, + type IWallet, + type IWalletProvision, + type LedgerListResponse, + type OrgDid, +} from './interface/agent-service.interface' +import type { AgentServiceRepository } from './repositories/agent-service.repository' @Injectable() @WebSocketGateway() export class AgentServiceService { - private readonly logger = new Logger('WalletService'); + private readonly logger = new Logger('WalletService') constructor( private readonly agentServiceRepository: AgentServiceRepository, @@ -92,22 +95,20 @@ export class AgentServiceService { @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy, @Inject(CACHE_MANAGER) private cacheService: Cache, private readonly userActivityRepository: UserActivityRepository, - private readonly natsClient : NATSClient + private readonly natsClient: NATSClient ) {} async ReplaceAt(input, search, replace, start, end): Promise { - return input.slice(0, start) + input.slice(start, end).replace(search, replace) + input.slice(end); + return input.slice(0, start) + input.slice(start, end).replace(search, replace) + input.slice(end) } - async getAgentDetails( - orgId: string - ): Promise { + async getAgentDetails(orgId: string): Promise { try { - const agentDetails = await this.agentServiceRepository.getAgentDetailsByOrgId(orgId); - return agentDetails; + const agentDetails = await this.agentServiceRepository.getAgentDetailsByOrgId(orgId) + return agentDetails } catch (error) { - this.logger.error(`in getAgentDetails::: ${JSON.stringify(error)}`); - throw new RpcException(error.response ?? error); + this.logger.error(`in getAgentDetails::: ${JSON.stringify(error)}`) + throw new RpcException(error.response ?? error) } } @@ -121,98 +122,98 @@ export class AgentServiceService { agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface ): Promise<{ - agentSpinupStatus: AgentSpinUpStatus; + agentSpinupStatus: AgentSpinUpStatus }> { - let agentProcess: ICreateOrgAgent; + let agentProcess: ICreateOrgAgent try { - await this.processWalletProvision(agentSpinupDto, user); - return { agentSpinupStatus: AgentSpinUpStatus.PROCESSED }; + await this.processWalletProvision(agentSpinupDto, user) + return { agentSpinupStatus: AgentSpinUpStatus.PROCESSED } } catch (error) { - this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess); - throw new RpcException(error.response ?? error); + this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess) + throw new RpcException(error.response ?? error) } } private async processWalletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise { - let platformAdminUser; - let userId: string; - let agentProcess: ICreateOrgAgent; - let getOrgAgent; + let platformAdminUser: user + let userId: string + let agentProcess: ICreateOrgAgent + let getOrgAgent: IOrgAgent try { const [platformConfig, getAgentType, ledgerIdData] = await Promise.all([ this.agentServiceRepository.getPlatformConfigDetails(), this.agentServiceRepository.getAgentTypeDetails(), this.agentServiceRepository.getLedgerDetails( agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet] - ) - ]); + ), + ]) - let orgData; + let orgData: organisation if (!user?.userId && agentSpinupDto?.platformAdminEmail) { // Get Platform admin user by platform admin email - platformAdminUser = await this.agentServiceRepository.getPlatfomAdminUser(agentSpinupDto?.platformAdminEmail); + platformAdminUser = await this.agentServiceRepository.getPlatfomAdminUser(agentSpinupDto?.platformAdminEmail) - userId = platformAdminUser?.id; + userId = platformAdminUser?.id } else { - userId = user?.id; + userId = user?.id } // Get platform org - const platformAdminOrgDetails = await this.agentServiceRepository.getPlatfomOrg(agentSpinupDto?.orgName); + const platformAdminOrgDetails = await this.agentServiceRepository.getPlatfomOrg(agentSpinupDto?.orgName) if (agentSpinupDto.orgId) { // Get organization details - getOrgAgent = await this.agentServiceRepository.getAgentDetails(agentSpinupDto.orgId); + getOrgAgent = await this.agentServiceRepository.getAgentDetails(agentSpinupDto.orgId) // Get organization data by orgId - orgData = await this.agentServiceRepository.getOrgDetails(agentSpinupDto.orgId); + orgData = await this.agentServiceRepository.getOrgDetails(agentSpinupDto.orgId) } else { // Get platform organization details - getOrgAgent = await this.agentServiceRepository.getAgentDetails(platformAdminOrgDetails); + getOrgAgent = await this.agentServiceRepository.getAgentDetails(platformAdminOrgDetails) // Get platform organization data by orgId - orgData = await this.agentServiceRepository.getOrgDetails(platformAdminOrgDetails); + orgData = await this.agentServiceRepository.getOrgDetails(platformAdminOrgDetails) } agentSpinupDto.ledgerId = agentSpinupDto.ledgerId?.length ? agentSpinupDto.ledgerId - : ledgerIdData.map((ledger) => ledger?.id); + : ledgerIdData.map((ledger) => ledger?.id) // Get genesis URL and ledger details - const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); + const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId) if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { throw new BadRequestException(ResponseMessages.agent.error.walletAlreadyProcessing, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { throw new ConflictException(ResponseMessages.agent.error.walletAlreadyCreated, { cause: new Error(), - description: ResponseMessages.errorMessages.conflict - }); + description: ResponseMessages.errorMessages.conflict, + }) } if (!agentSpinupDto.orgId) { if (platformAdminOrgDetails) { - agentSpinupDto.orgId = platformAdminOrgDetails; + agentSpinupDto.orgId = platformAdminOrgDetails } } - agentSpinupDto.agentType = agentSpinupDto.agentType || getAgentType; - agentSpinupDto.tenant = agentSpinupDto.tenant || false; + agentSpinupDto.agentType = agentSpinupDto.agentType || getAgentType + agentSpinupDto.tenant = agentSpinupDto.tenant || false agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length ? agentSpinupDto.ledgerName - : [Ledgers.Indicio_Demonet]; + : [Ledgers.Indicio_Demonet] // Invoke function for validate platform configuration - this.validatePlatformConfig(platformConfig); + this.validatePlatformConfig(platformConfig) - const externalIp = platformConfig?.externalIp; - const inboundEndpoint = platformConfig?.inboundEndpoint !== 'false' ? platformConfig?.inboundEndpoint : ''; - const apiEndpoint = platformConfig?.apiEndpoint; + const externalIp = platformConfig?.externalIp + const inboundEndpoint = platformConfig?.inboundEndpoint !== 'false' ? platformConfig?.inboundEndpoint : '' + const apiEndpoint = platformConfig?.apiEndpoint // Create payload for the wallet create and store payload const walletProvisionPayload = await this.prepareWalletProvisionPayload( @@ -222,14 +223,14 @@ export class AgentServiceService { inboundEndpoint, ledgerDetails, orgData - ); + ) // Socket connection - const socket: Socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); - this.emitAgentSpinupInitiatedEvent(agentSpinupDto, socket); + const socket: Socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`) + this.emitAgentSpinupInitiatedEvent(agentSpinupDto, socket) - const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; - agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId); + const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED + agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId) // AFJ agent spin-up this._agentSpinup( @@ -241,58 +242,59 @@ export class AgentServiceService { socket, agentSpinupDto.ledgerId, agentProcess - ); + ) } catch (error) { - this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess); - throw error; + this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess) + throw error } } async agentConfigure(agentConfigureDto: IAgentConfigure, user: IUserRequestInterface): Promise { try { - const { agentEndpoint, apiKey, did, walletName, orgId } = agentConfigureDto; - const { id: userId } = user; - const orgExist = await this.agentServiceRepository.getAgentDetails(orgId); + const { agentEndpoint, apiKey, did, walletName, orgId } = agentConfigureDto + const { id: userId } = user + const orgExist = await this.agentServiceRepository.getAgentDetails(orgId) if (orgExist) { - throw new ConflictException(ResponseMessages.agent.error.alreadySpinUp); + throw new ConflictException(ResponseMessages.agent.error.alreadySpinUp) } if (!agentEndpoint) { - throw new BadRequestException(ResponseMessages.agent.error.agentEndpointRequired); + throw new BadRequestException(ResponseMessages.agent.error.agentEndpointRequired) } - const { isInitialized } = await this.getAgentHealthData(agentEndpoint, apiKey); + const { isInitialized } = await this.getAgentHealthData(agentEndpoint, apiKey) if (!isInitialized) { - throw new BadRequestException(ResponseMessages.agent.error.agentSpinupError); + throw new BadRequestException(ResponseMessages.agent.error.agentSpinupError) } const [agentsTypeId, encryptedToken, orgAgentTypeId] = await Promise.allSettled([ this.agentServiceRepository.getAgentTypeDetails(), this.tokenEncryption(apiKey), - this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.DEDICATED) + this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.DEDICATED), ]).then((results) => { - const fulfilledValues = results.map((result) => (result.status === 'fulfilled' ? result.value : null)); + const fulfilledValues = results.map((result) => (result.status === 'fulfilled' ? result.value : null)) const rejectedIndices = results .map((result, index) => (result.status === 'rejected' ? index : -1)) - .filter((index) => index !== -1); + .filter((index) => index !== -1) + // biome-ignore lint/complexity/noForEach: rejectedIndices.forEach((index) => { switch (index) { case 0: - throw new Error(ResponseMessages.agent.error.failedAgentType); + throw new Error(ResponseMessages.agent.error.failedAgentType) case 1: - throw new Error(ResponseMessages.agent.error.failedApiKey); + throw new Error(ResponseMessages.agent.error.failedApiKey) case 2: - throw new Error(ResponseMessages.agent.error.failedOrganization); + throw new Error(ResponseMessages.agent.error.failedOrganization) default: - throw new Error(ResponseMessages.agent.error.promiseReject); + throw new Error(ResponseMessages.agent.error.promiseReject) } - }); + }) - return fulfilledValues.filter((value) => value !== null); - }); + return fulfilledValues.filter((value) => value !== null) + }) - const getOrganization = await this.agentServiceRepository.getOrgDetails(orgId); + const getOrganization = await this.agentServiceRepository.getOrgDetails(orgId) const storeAgentConfig = await this.agentServiceRepository.storeOrgAgentDetails({ did, @@ -304,14 +306,14 @@ export class AgentServiceService { agentEndPoint: agentEndpoint, orgAgentTypeId, apiKey: encryptedToken, - userId - }); + userId, + }) - await this._createConnectionInvitation(orgId, user, getOrganization.name); - return storeAgentConfig; + await this._createConnectionInvitation(orgId, user, getOrganization.name) + return storeAgentConfig } catch (error) { - this.logger.error(`Error Agent configure ::: ${JSON.stringify(error)}`); - throw new RpcException(error.response ?? error); + this.logger.error(`Error Agent configure ::: ${JSON.stringify(error)}`) + throw new RpcException(error.response ?? error) } } @@ -319,73 +321,74 @@ export class AgentServiceService { try { return await this.commonService .httpGet(`${agentEndpoint}${CommonConstants.URL_AGENT_STATUS}`, { - headers: { authorization: apiKey } + headers: { authorization: apiKey }, }) - .then((response) => response); + .then((response) => response) } catch (error) { - throw error; + // biome-ignore lint/complexity/noUselessCatch: + throw error } } validatePlatformConfig(platformConfig: platform_config): void { if (!platformConfig) { - this.logger.error(`Platform configuration is missing or invalid`); + this.logger.error(ResponseMessages.agent.error.platformConfiguration) throw new BadRequestException(ResponseMessages.agent.error.platformConfiguration, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } if (!platformConfig.apiEndpoint) { - this.logger.error(`API endpoint is missing in the platform configuration`); + this.logger.error(ResponseMessages.agent.error.apiEndpoint) throw new BadRequestException(ResponseMessages.agent.error.apiEndpoint, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } if (!platformConfig.externalIp) { - this.logger.error(`External IP is missing in the platform configuration`); + this.logger.error(ResponseMessages.agent.error.externalIp) throw new BadRequestException(ResponseMessages.agent.error.externalIp, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } if (typeof platformConfig.externalIp !== 'string') { - this.logger.error(`External IP must be a string`); - throw new BadRequestException(ResponseMessages.agent.error.externalIp, { + this.logger.error(ResponseMessages.agent.error.stringExternalIp) + throw new BadRequestException(ResponseMessages.agent.error.stringExternalIp, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } } validateAgentProcess(agentProcess: ICreateOrgAgent): void { try { if (!agentProcess) { - this.logger.error(`Agent process is invalid or not in a completed state`); - throw new BadRequestException(ResponseMessages.agent.error.externalIp, { + this.logger.error(ResponseMessages.agent.error.agentProcess) + throw new BadRequestException(ResponseMessages.agent.error.agentProcess, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } } catch (error) { - this.logger.error(`Error validating agent process: ${error.message}`); - throw error; + this.logger.error(`Error validating agent process: ${error.message}`) + throw error } } emitAgentSpinupInitiatedEvent(agentSpinupDto: IAgentSpinupDto, socket: Socket): void { try { if (agentSpinupDto.clientSocketId) { - socket.emit('agent-spinup-process-initiated', { clientId: agentSpinupDto.clientSocketId }); + socket.emit('agent-spinup-process-initiated', { clientId: agentSpinupDto.clientSocketId }) // Log or perform other actions after emitting the event - this.logger.log(`Agent spinup initiated event emitted for orgId ${agentSpinupDto.orgId}`); + this.logger.log(`Agent spinup initiated event emitted for orgId ${agentSpinupDto.orgId}`) } } catch (error) { - this.logger.error(`Error emitting agent-spinup-initiated event: ${error.message}`); - throw error; + this.logger.error(`Error emitting agent-spinup-initiated event: ${error.message}`) + throw error } } @@ -399,10 +402,10 @@ export class AgentServiceService { ): Promise { const ledgerArray = ledgerDetails.map((ledger) => ({ genesisTransactions: ledger.poolConfig, - indyNamespace: ledger.indyNamespace - })); + indyNamespace: ledger.indyNamespace, + })) - const escapedJsonString = JSON.stringify(ledgerArray).replace(/"/g, '\\"'); + const escapedJsonString = JSON.stringify(ledgerArray).replace(/"/g, '\\"') const walletProvisionPayload: IWalletProvision = { orgId: orgData?.id, @@ -423,31 +426,31 @@ export class AgentServiceService { credoImage: process.env.AFJ_VERSION || '', protocol: process.env.AGENT_PROTOCOL || '', tenant: agentSpinupDto.tenant || false, - apiKey: agentSpinupDto.apiKey - }; - return walletProvisionPayload; + apiKey: agentSpinupDto.apiKey, + } + return walletProvisionPayload } async initSocketConnection(socketHost: string): Promise { const socket = io(socketHost, { reconnection: true, reconnectionDelay: 5000, - reconnectionAttempts: Infinity, + reconnectionAttempts: Number.POSITIVE_INFINITY, autoConnect: true, - transports: ['websocket'] - }); + transports: ['websocket'], + }) - return socket; + return socket } 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}`); - return agentProcess; + const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, userId) + this.logger.log(`Organization agent created with status: ${agentSpinUpStatus}`) + return agentProcess } catch (error) { - this.logger.error(`Error creating organization agent: ${error.message}`); - throw error; + this.logger.error(`Error creating organization agent: ${error.message}`) + throw error } } @@ -457,78 +460,78 @@ export class AgentServiceService { agentProcess: ICreateOrgAgent ): Promise { if (agentProcess) { - const socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); + const socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`) if (agentSpinupDto.clientSocketId) { - this.emitErrorInWalletCreationEvent(agentSpinupDto, socket, error); + this.emitErrorInWalletCreationEvent(agentSpinupDto, socket, error) } - this.agentServiceRepository.removeOrgAgent(agentProcess?.id); - this.logger.error(`Error in Agent spin up: ${JSON.stringify(error)}`); + this.agentServiceRepository.removeOrgAgent(agentProcess?.id) + this.logger.error(`Error in Agent spin up: ${JSON.stringify(error)}`) } } async emitErrorInWalletCreationEvent(agentSpinupDto: IAgentSpinupDto, socket: Socket, error: Error): Promise { try { - socket.emit('error-in-wallet-creation-process', { clientId: agentSpinupDto.clientSocketId, error }); - this.logger.error(`Error in wallet creation process emitted for orgId ${agentSpinupDto.orgId}: ${error.message}`); + socket.emit('error-in-wallet-creation-process', { clientId: agentSpinupDto.clientSocketId, error }) + this.logger.error(`Error in wallet creation process emitted for orgId ${agentSpinupDto.orgId}: ${error.message}`) } catch (emitError) { - this.logger.error(`Error emitting error-in-wallet-creation-process event: ${emitError.message}`); - throw emitError; + this.logger.error(`Error emitting error-in-wallet-creation-process event: ${emitError.message}`) + throw emitError } } async _agentSpinup( walletProvisionPayload: IWalletProvision, agentSpinupDto: IAgentSpinupDto, - orgApiKey: string, + _orgApiKey: string, orgData: organisation, user: IUserRequestInterface, socket: Socket, - ledgerId: string[], + _ledgerId: string[], agentProcess: ICreateOrgAgent ): Promise { - let ledgerIdData = []; + let ledgerIdData = [] try { if (agentSpinupDto.method !== DidMethod.KEY && agentSpinupDto.method !== DidMethod.WEB) { - const { network } = agentSpinupDto; - const ledger = await ledgerName(network); - const ledgerList = (await this._getALlLedgerDetails()) as unknown as LedgerListResponse; - const isLedgerExist = ledgerList.response.find((existingLedgers) => existingLedgers.name === ledger); + const { network } = agentSpinupDto + const ledger = await ledgerName(network) + const ledgerList = (await this._getALlLedgerDetails()) as unknown as LedgerListResponse + const isLedgerExist = ledgerList.response.find((existingLedgers) => existingLedgers.name === ledger) if (!isLedgerExist) { throw new BadRequestException(ResponseMessages.agent.error.invalidLedger, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - ledgerIdData = await this.agentServiceRepository.getLedgerDetails(ledger); + ledgerIdData = await this.agentServiceRepository.getLedgerDetails(ledger) } /** * Invoke wallet create and provision with agent */ - const walletProvision = await this._walletProvision(walletProvisionPayload); + const walletProvision = await this._walletProvision(walletProvisionPayload) if (!walletProvision?.response) { - this.logger.error(`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 - }); + description: ResponseMessages.errorMessages.badRequest, + }) } - const agentDetails = walletProvision.response; - const agentEndPoint = `${process.env.API_GATEWAY_PROTOCOL}://${agentDetails.agentEndPoint}`; + const agentDetails = walletProvision.response + const agentEndPoint = `${process.env.API_GATEWAY_PROTOCOL}://${agentDetails.agentEndPoint}` /** * Socket connection */ - const socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); + const socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`) if (agentEndPoint && agentSpinupDto.clientSocketId) { - socket.emit('agent-spinup-process-completed', { clientId: agentSpinupDto.clientSocketId }); - socket.emit('did-publish-process-initiated', { clientId: agentSpinupDto.clientSocketId }); - socket.emit('invitation-url-creation-started', { clientId: agentSpinupDto.clientSocketId }); + socket.emit('agent-spinup-process-completed', { clientId: agentSpinupDto.clientSocketId }) + socket.emit('did-publish-process-initiated', { clientId: agentSpinupDto.clientSocketId }) + socket.emit('invitation-url-creation-started', { clientId: agentSpinupDto.clientSocketId }) } - const encryptedToken = await this.tokenEncryption(agentDetails?.agentToken); + const encryptedToken = await this.tokenEncryption(agentDetails?.agentToken) const agentPayload: IStoreOrgAgentDetails = { agentEndPoint, @@ -544,56 +547,55 @@ export class AgentServiceService { keyType: agentSpinupDto.keyType, ledgerId: ledgerIdData ? ledgerIdData.map((item) => item.id) : null, did: agentSpinupDto.did, - id: agentProcess?.id - }; + id: agentProcess?.id, + } /** * Store organization agent details */ - const storeAgentDetails = await this._storeOrgAgentDetails(agentPayload); + 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`; + .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`); + this.logger.error(`Error removing file: ${err.message}`) + throw new InternalServerErrorException(err.message) } - }); + this.logger.log(`File ${filePath} has been removed successfully`) + }) } if (agentSpinupDto.clientSocketId) { - socket.emit('did-publish-process-completed', { clientId: agentSpinupDto.clientSocketId }); + 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._createConnectionInvitation(orgData?.id, user, getOrganization.name); + await this._createConnectionInvitation(orgData?.id, user, getOrganization.name) if (agentSpinupDto.clientSocketId) { - socket.emit('invitation-url-creation-success', { clientId: agentSpinupDto.clientSocketId }); + socket.emit('invitation-url-creation-success', { clientId: agentSpinupDto.clientSocketId }) } } else { - this.logger.error(`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 - }); + description: ResponseMessages.errorMessages.badRequest, + }) } } catch (error) { if (agentSpinupDto.clientSocketId) { - socket.emit('error-in-wallet-creation-process', { clientId: agentSpinupDto.clientSocketId, error }); + socket.emit('error-in-wallet-creation-process', { clientId: agentSpinupDto.clientSocketId, error }) } - if (agentProcess && agentProcess?.id) { + if (agentProcess?.id) { /** * If getting error remove organization agent */ - await this.agentServiceRepository.removeOrgAgent(agentProcess?.id); + await this.agentServiceRepository.removeOrgAgent(agentProcess?.id) } - this.logger.error(`[_agentSpinup] - Error in Agent spin up : ${JSON.stringify(error)}`); + this.logger.error(`[_agentSpinup] - Error in Agent spin up : ${JSON.stringify(error)}`) } } @@ -604,39 +606,40 @@ export class AgentServiceService { */ const [agentDid, orgAgentTypeId] = await Promise.all([ this._getAgentDid(payload), - this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.DEDICATED) - ]); + this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.DEDICATED), + ]) /** * Get DID method by agent */ - const getDidMethod = await this._getDidMethod(payload, agentDid); + const getDidMethod = await this._getDidMethod(payload, agentDid) /** * Organization storage data */ - const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, `${orgAgentTypeId}`); + const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, `${orgAgentTypeId}`) /** * Store org agent details */ - const storeAgentDid = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData); - return storeAgentDid; + const storeAgentDid = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData) + return storeAgentDid } catch (error) { - await this._handleError(payload, error); - throw error; + await this._handleError(payload, error) + throw error } } private async _getAgentDid(payload: IStoreOrgAgentDetails): Promise { - const { agentEndPoint, apiKey, ledgerId, seed, keyType, method, network, role, did } = payload; - const writeDid = 'write-did'; - const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(ledgerId); - const agentDidWriteUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_WRITE_DID}`; - return this._retryAgentSpinup(agentDidWriteUrl, apiKey, writeDid, seed, keyType, method, network, role, did); + const { agentEndPoint, apiKey, ledgerId, seed, keyType, method, network, role, did } = payload + const writeDid = 'write-did' + const _ledgerDetails = await this.agentServiceRepository.getGenesisUrl(ledgerId) + const agentDidWriteUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_WRITE_DID}` + return this._retryAgentSpinup(agentDidWriteUrl, apiKey, writeDid, seed, keyType, method, network, role, did) } private async _getDidMethod(payload: IStoreOrgAgentDetails, agentDid: object): Promise { - const { agentEndPoint, apiKey, seed, keyType, method, network, role } = payload; - const getDidDoc = 'get-did-doc'; - const getDidMethodUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_GET_DID}/${agentDid['did']}`; + const { agentEndPoint, apiKey, seed, keyType, method, network, role } = payload + const getDidDoc = 'get-did-doc' + // biome-ignore lint/complexity/useLiteralKeys: + const getDidMethodUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_GET_DID}/${agentDid['did']}` return this._retryAgentSpinup( getDidMethodUrl, apiKey, @@ -646,8 +649,9 @@ export class AgentServiceService { method, network, role, + // biome-ignore lint/complexity/useLiteralKeys: `${agentDid['did']}` - ); + ) } private _buildStoreOrgAgentData( @@ -656,7 +660,9 @@ export class AgentServiceService { orgAgentTypeId: string ): IStoreOrgAgentDetails { return { + // biome-ignore lint/complexity/useLiteralKeys: did: getDidMethod['didDocument']?.id, + // biome-ignore lint/complexity/useLiteralKeys: verkey: getDidMethod['didDocument']?.verificationMethod[0]?.publicKeyBase58, isDidPublic: true, agentSpinUpStatus: AgentSpinUpStatus.COMPLETED, @@ -668,8 +674,8 @@ export class AgentServiceService { orgAgentTypeId, ledgerId: payload.ledgerId, id: payload.id, - apiKey: payload.apiKey - }; + apiKey: payload.apiKey, + } } private async _handleError(payload: IStoreOrgAgentDetails, error: Error): Promise { @@ -677,18 +683,18 @@ export class AgentServiceService { const socket = await io(`${process.env.SOCKET_HOST}`, { reconnection: true, reconnectionDelay: 5000, - reconnectionAttempts: Infinity, + reconnectionAttempts: Number.POSITIVE_INFINITY, autoConnect: true, - transports: ['websocket'] - }); - socket.emit('error-in-wallet-creation-process', { clientId: payload.clientSocketId, error }); + transports: ['websocket'], + }) + socket.emit('error-in-wallet-creation-process', { clientId: payload.clientSocketId, error }) } - if (payload && payload?.id) { - this.agentServiceRepository.removeOrgAgent(payload?.id); + if (payload?.id) { + this.agentServiceRepository.removeOrgAgent(payload?.id) } - this.logger.error(`[_storeOrgAgentDetails] - Error in store agent details : ${JSON.stringify(error)}`); + this.logger.error(`[_storeOrgAgentDetails] - Error in store agent details : ${JSON.stringify(error)}`) } async _retryAgentSpinup( @@ -703,23 +709,25 @@ export class AgentServiceService { did: string ): Promise { const retryOptions = { - retries: 10 - }; + retries: 10, + } try { - const getDcryptedToken = await this.commonService.decryptPassword(apiKey); + const getDcryptedToken = await this.commonService.decryptPassword(apiKey) return retry(async () => { if (agentApiState === 'write-did') { return this.commonService.httpPost( agentUrl, { seed, keyType, method, network, role, did }, { headers: { authorization: getDcryptedToken } } - ); - } else if (agentApiState === 'get-did-doc') { - return this.commonService.httpGet(agentUrl, { headers: { authorization: getDcryptedToken } }); + ) + } + if (agentApiState === 'get-did-doc') { + return this.commonService.httpGet(agentUrl, { headers: { authorization: getDcryptedToken } }) } - }, retryOptions); + }, retryOptions) } catch (error) { - throw error; + // biome-ignore lint/complexity/noUselessCatch: + throw error } } @@ -728,44 +736,44 @@ export class AgentServiceService { user: IUserRequestInterface, label: string ): Promise<{ - response; + response }> { try { const pattern = { - cmd: 'create-connection-invitation' - }; - const payload = { createOutOfBandConnectionInvitation: { orgId, user, label } }; - return await this.natsCall(pattern, payload); + cmd: 'create-connection-invitation', + } + const payload = { createOutOfBandConnectionInvitation: { orgId, user, label } } + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`error in create-connection in wallet provision : ${JSON.stringify(error)}`); + this.logger.error(`error in create-connection in wallet provision : ${JSON.stringify(error)}`) } } async _getALlLedgerDetails(): Promise<{ - response; + response }> { try { const pattern = { - cmd: 'get-all-ledgers' - }; - const payload = {}; - return await this.natsCall(pattern, payload); + cmd: 'get-all-ledgers', + } + const payload = {} + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`error in while fetching all the ledger details : ${JSON.stringify(error)}`); + this.logger.error(`error in while fetching all the ledger details : ${JSON.stringify(error)}`) } } async _walletProvision(payload: IWalletProvision): Promise<{ - response; + response }> { try { const pattern = { - cmd: 'wallet-provisioning' - }; - return await this.natsCall(pattern, payload); + cmd: 'wallet-provisioning', + } + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`error in wallet provision : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error in wallet provision : ${JSON.stringify(error)}`) + throw error } } @@ -778,33 +786,33 @@ export class AgentServiceService { async createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { try { const agentStatusResponse = { - agentSpinupStatus: AgentSpinUpStatus.PROCESSED - }; + agentSpinupStatus: AgentSpinUpStatus.PROCESSED, + } - const getOrgAgent = await this.agentServiceRepository.getAgentDetails(payload.orgId); + const getOrgAgent = await this.agentServiceRepository.getAgentDetails(payload.orgId) if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { - this.logger.error(`Your wallet is 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 - }); + description: ResponseMessages.errorMessages.conflict, + }) } if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { - this.logger.error(`Your wallet is already processing.`); + this.logger.error('Your wallet is already processing.') throw new ConflictException(ResponseMessages.agent.error.walletAlreadyProcessing, { cause: new Error(), - description: ResponseMessages.errorMessages.conflict - }); + description: ResponseMessages.errorMessages.conflict, + }) } // Create tenant - this._createTenant(payload, user); - return agentStatusResponse; + 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); + this.logger.error(`error in create tenant : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -815,57 +823,57 @@ export class AgentServiceService { * @returns Get agent status */ async _createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise { - let agentProcess; - let ledgerIdData = []; + let agentProcess: ICreateOrgAgent + let ledgerIdData = [] try { - let ledger; - const { network } = payload; - if (network) { - ledger = await ledgerName(network); - } else { - ledger = Ledgers.Not_Applicable; - } + let ledger: string | string[] + const { network } = payload + if (network) { + ledger = await ledgerName(network) + } else { + ledger = Ledgers.Not_Applicable + } - const ledgerList = (await this._getALlLedgerDetails()) as unknown as LedgerListResponse; - const isLedgerExist = ledgerList.response.find((existingLedgers) => existingLedgers.name === ledger); - if (!isLedgerExist) { - throw new BadRequestException(ResponseMessages.agent.error.invalidLedger, { - cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); - } - ledgerIdData = await this.agentServiceRepository.getLedgerDetails(ledger); - - const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; + const ledgerList = (await this._getALlLedgerDetails()) as unknown as LedgerListResponse + const isLedgerExist = ledgerList.response.find((existingLedgers) => existingLedgers.name === ledger) + if (!isLedgerExist) { + throw new BadRequestException(ResponseMessages.agent.error.invalidLedger, { + cause: new Error(), + description: ResponseMessages.errorMessages.notFound, + }) + } + ledgerIdData = await this.agentServiceRepository.getLedgerDetails(ledger) + + 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); + const platformAdminSpinnedUp = await this.getPlatformAdminAndNotify(payload.clientSocketId) - payload.endpoint = platformAdminSpinnedUp.org_agents[0].agentEndPoint; + payload.endpoint = platformAdminSpinnedUp.org_agents[0].agentEndPoint // Create tenant wallet and DID - const tenantDetails = await this.createTenantAndNotify(payload, platformAdminSpinnedUp); + const tenantDetails = await this.createTenantAndNotify(payload, platformAdminSpinnedUp) if (!tenantDetails?.walletResponseDetails?.id || !tenantDetails?.DIDCreationOption?.did) { - this.logger.error(`Error in getting wallet id and wallet did`); + this.logger.error('Error in getting wallet id and wallet did') throw new NotFoundException(ResponseMessages.agent.error.notAbleToSpinUpAgent, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } if (AgentSpinUpStatus.COMPLETED !== platformAdminSpinnedUp.org_agents[0].agentSpinUpStatus) { - this.logger.error(`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 - }); + description: ResponseMessages.errorMessages.notFound, + }) } // Get shared agent type - const orgAgentTypeId = await this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.SHARED); + const orgAgentTypeId = await this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.SHARED) // Get agent type details - const agentTypeId = await this.agentServiceRepository.getAgentTypeId(AgentType.AFJ); + const agentTypeId = await this.agentServiceRepository.getAgentTypeId(AgentType.AFJ) const storeOrgAgentData: IStoreOrgAgentDetails = { did: tenantDetails.DIDCreationOption.did, @@ -876,18 +884,18 @@ export class AgentServiceService { orgId: payload.orgId, agentEndPoint: platformAdminSpinnedUp.org_agents[0].agentEndPoint, orgAgentTypeId, - tenantId: tenantDetails.walletResponseDetails['id'], + tenantId: tenantDetails.walletResponseDetails.id, walletName: payload.label, ledgerId: ledgerIdData.map((item) => item.id), - id: agentProcess?.id - }; + id: agentProcess?.id, + } // Get organization data - const getOrganization = await this.agentServiceRepository.getOrgDetails(payload.orgId); + const getOrganization = await this.agentServiceRepository.getOrgDetails(payload.orgId) - this.notifyClientSocket('agent-spinup-process-completed', payload.clientSocketId); + this.notifyClientSocket('agent-spinup-process-completed', payload.clientSocketId) - const orgAgentDetails = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData); + const orgAgentDetails = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData) const createdDidDetails = { orgId: payload.orgId, @@ -895,24 +903,24 @@ export class AgentServiceService { didDocument: tenantDetails.DIDCreationOption.didDocument || tenantDetails.DIDCreationOption.didDoc, isPrimaryDid: true, orgAgentId: orgAgentDetails.id, - userId: user.id - }; + userId: user.id, + } - await this.agentServiceRepository.storeDidDetails(createdDidDetails); + await this.agentServiceRepository.storeDidDetails(createdDidDetails) - this.notifyClientSocket('invitation-url-creation-started', payload.clientSocketId); + this.notifyClientSocket('invitation-url-creation-started', payload.clientSocketId) // Create the legacy connection invitation - await this._createConnectionInvitation(payload.orgId, user, getOrganization.name); + await this._createConnectionInvitation(payload.orgId, user, getOrganization.name) - this.notifyClientSocket('invitation-url-creation-success', payload.clientSocketId); + this.notifyClientSocket('invitation-url-creation-success', payload.clientSocketId) } catch (error) { - this.handleError(error, payload.clientSocketId); + this.handleError(error, payload.clientSocketId) - if (agentProcess && agentProcess?.id) { - this.agentServiceRepository.removeOrgAgent(agentProcess?.id); + if (agentProcess?.id) { + this.agentServiceRepository.removeOrgAgent(agentProcess?.id) } - throw error; + throw error } } @@ -925,26 +933,26 @@ export class AgentServiceService { try { const platformAdminSpinnedUp = await this.agentServiceRepository.platformAdminAgent( CommonConstants.PLATFORM_ADMIN_ORG - ); + ) - const getPlatformAgentEndPoint = platformAdminSpinnedUp.org_agents[0].agentEndPoint; - const getDcryptedToken = await this.commonService.decryptPassword(platformAdminSpinnedUp?.org_agents[0].apiKey); + const getPlatformAgentEndPoint = platformAdminSpinnedUp.org_agents[0].agentEndPoint + const getDcryptedToken = await this.commonService.decryptPassword(platformAdminSpinnedUp?.org_agents[0].apiKey) - const { label } = payload; + const { label } = payload const createTenantOptions = { - config: { label } - }; + config: { label }, + } const tenantDetails = await this.commonService.httpPost( `${getPlatformAgentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_TENANT}`, createTenantOptions, { headers: { authorization: getDcryptedToken } } - ); + ) - return tenantDetails; + return tenantDetails } catch (error) { - this.logger.error(`error in create wallet : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`error in create wallet : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -955,181 +963,183 @@ export class AgentServiceService { */ async createDid(createDidPayload: IDidCreate, orgId: string, user: IUserRequestInterface): Promise { try { - const agentDetails = await this.agentServiceRepository.getOrgAgentDetails(orgId); + const agentDetails = await this.agentServiceRepository.getOrgAgentDetails(orgId) if (createDidPayload?.network) { - const getNameSpace = await this.agentServiceRepository.getLedgerByNameSpace(createDidPayload?.network); + const getNameSpace = await this.agentServiceRepository.getLedgerByNameSpace(createDidPayload?.network) if (agentDetails.ledgerId !== null) { if (agentDetails.ledgerId !== getNameSpace.id) { - throw new BadRequestException(ResponseMessages.agent.error.networkMismatch); + throw new BadRequestException(ResponseMessages.agent.error.networkMismatch) } } } - const getApiKey = await this.getOrgAgentApiKey(orgId); - const getOrgAgentType = await this.agentServiceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); + const getApiKey = await this.getOrgAgentApiKey(orgId) + const getOrgAgentType = await this.agentServiceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) - const url = this.constructUrl(agentDetails, getOrgAgentType); + const url = this.constructUrl(agentDetails, getOrgAgentType) if (createDidPayload.method === DidMethod.POLYGON) { - createDidPayload.endpoint = agentDetails.agentEndPoint; + createDidPayload.endpoint = agentDetails.agentEndPoint } - const { isPrimaryDid, ...payload } = createDidPayload; - const didDetails = await this.getDidDetails(url, payload, getApiKey); - const getDidByOrg = await this.agentServiceRepository.getOrgDid(orgId); + const { isPrimaryDid, ...payload } = createDidPayload + const didDetails = await this.getDidDetails(url, payload, getApiKey) + const getDidByOrg = await this.agentServiceRepository.getOrgDid(orgId) - await this.checkDidExistence(getDidByOrg, didDetails); + await this.checkDidExistence(getDidByOrg, didDetails) if (isPrimaryDid) { - await this.updateAllDidsToNonPrimary(orgId, getDidByOrg); + await this.updateAllDidsToNonPrimary(orgId, getDidByOrg) } const createdDidDetails = { orgId, + // biome-ignore lint/complexity/useLiteralKeys: did: didDetails?.['did'] ?? didDetails?.['didState']?.['did'], + // biome-ignore lint/complexity/useLiteralKeys: didDocument: didDetails?.['didDocument'] ?? didDetails?.['didDoc'] ?? didDetails?.['didState']?.['didDocument'], isPrimaryDid, orgAgentId: agentDetails.id, - userId: user.id - }; - const storeDidDetails = await this.storeDid(createdDidDetails); + userId: user.id, + } + const storeDidDetails = await this.storeDid(createdDidDetails) if (isPrimaryDid) { - await this.setPrimaryDidAndLedger(orgId, storeDidDetails, createDidPayload.network, createDidPayload.method); + await this.setPrimaryDidAndLedger(orgId, storeDidDetails, createDidPayload.network, createDidPayload.method) } - return storeDidDetails; + return storeDidDetails } catch (error) { - this.logger.error(`error in create did : ${JSON.stringify(error)}`); + this.logger.error(`error in create did : ${JSON.stringify(error)}`) if (error?.response?.error?.message) { throw new RpcException({ statusCode: error?.response?.status, - error: error?.response?.error?.message - }); - } else { - throw new RpcException(error.response ? error.response : error); + error: error?.response?.error?.message, + }) } + throw new RpcException(error.response ? error.response : error) } } private constructUrl(agentDetails, getOrgAgentType): string { if (getOrgAgentType.agent === OrgAgentType.DEDICATED) { - return `${agentDetails.agentEndPoint}${CommonConstants.URL_AGENT_WRITE_DID}`; - } else if (getOrgAgentType.agent === OrgAgentType.SHARED) { - return `${agentDetails.agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_DID}${agentDetails.tenantId}`; + return `${agentDetails.agentEndPoint}${CommonConstants.URL_AGENT_WRITE_DID}` + } + if (getOrgAgentType.agent === OrgAgentType.SHARED) { + return `${agentDetails.agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_DID}${agentDetails.tenantId}` } } private async getDidDetails(url, payload, apiKey): Promise { const didDetails = await this.commonService.httpPost(url, payload, { - headers: { authorization: apiKey } - }); + headers: { authorization: apiKey }, + }) if (!didDetails || Object.keys(didDetails).length === 0) { throw new InternalServerErrorException(ResponseMessages.agent.error.createDid, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } - return didDetails; + return didDetails } private checkDidExistence(getDidByOrg, didDetails): void { - const didExist = getDidByOrg.some((orgDidExist) => orgDidExist.did === didDetails.did); + const didExist = getDidByOrg.some((orgDidExist) => orgDidExist.did === didDetails.did) if (didExist) { throw new ConflictException(ResponseMessages.agent.error.didAlreadyExist, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } } private async updateAllDidsToNonPrimary(orgId, getDidByOrg): Promise { await Promise.all( getDidByOrg.map(async () => { - await this.agentServiceRepository.updateIsPrimaryDid(orgId, false); + await this.agentServiceRepository.updateIsPrimaryDid(orgId, false) }) - ); + ) } private async storeDid(createdDidDetails): Promise { - const storeDidDetails = await this.agentServiceRepository.storeDidDetails(createdDidDetails); + const storeDidDetails = await this.agentServiceRepository.storeDidDetails(createdDidDetails) if (!storeDidDetails) { throw new InternalServerErrorException(ResponseMessages.agent.error.storeDid, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } - return storeDidDetails; + return storeDidDetails } - private async setPrimaryDidAndLedger(orgId, storeDidDetails, network, method): Promise { + private async setPrimaryDidAndLedger(orgId, storeDidDetails, network, _method): Promise { if (storeDidDetails.did && storeDidDetails.didDocument) { - await this.agentServiceRepository.setPrimaryDid(storeDidDetails.did, orgId, storeDidDetails.didDocument); + await this.agentServiceRepository.setPrimaryDid(storeDidDetails.did, orgId, storeDidDetails.didDocument) } if (network) { - const getLedgerDetails = await this.agentServiceRepository.getLedgerByNameSpace(network); - await this.agentServiceRepository.updateLedgerId(orgId, getLedgerDetails.id); + const getLedgerDetails = await this.agentServiceRepository.getLedgerByNameSpace(network) + await this.agentServiceRepository.updateLedgerId(orgId, getLedgerDetails.id) } else { - const noLedgerData = await this.agentServiceRepository.getLedger(Ledgers.Not_Applicable); + const noLedgerData = await this.agentServiceRepository.getLedger(Ledgers.Not_Applicable) if (!noLedgerData) { - throw new NotFoundException(ResponseMessages.agent.error.noLedgerFound); + throw new NotFoundException(ResponseMessages.agent.error.noLedgerFound) } - await this.agentServiceRepository.updateLedgerId(orgId, noLedgerData?.id); + await this.agentServiceRepository.updateLedgerId(orgId, noLedgerData?.id) } } /** * @returns Secp256k1 key pair for polygon DID */ - async createSecp256k1KeyPair(orgId: string): Promise { + async createSecp256k1KeyPair(_orgId: string): Promise { try { const platformAdminSpinnedUp = await this.agentServiceRepository.platformAdminAgent( CommonConstants.PLATFORM_ADMIN_ORG - ); + ) - const getPlatformAgentEndPoint = platformAdminSpinnedUp.org_agents[0].agentEndPoint; - const getDcryptedToken = await this.commonService.decryptPassword(platformAdminSpinnedUp?.org_agents[0].apiKey); + const getPlatformAgentEndPoint = platformAdminSpinnedUp.org_agents[0].agentEndPoint + const getDcryptedToken = await this.commonService.decryptPassword(platformAdminSpinnedUp?.org_agents[0].apiKey) - const url = `${getPlatformAgentEndPoint}${CommonConstants.CREATE_POLYGON_SECP256k1_KEY}`; + const url = `${getPlatformAgentEndPoint}${CommonConstants.CREATE_POLYGON_SECP256k1_KEY}` const createKeyPairResponse = await this.commonService.httpPost( url, {}, { headers: { authorization: getDcryptedToken } } - ); - return createKeyPairResponse; + ) + return createKeyPairResponse } catch (error) { - this.logger.error(`error in createSecp256k1KeyPair : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`error in createSecp256k1KeyPair : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } private async getPlatformAdminAndNotify(clientSocketId: string | undefined): Promise { - const socket = await this.createSocketInstance(); + const socket = await this.createSocketInstance() if (clientSocketId) { - socket.emit('agent-spinup-process-initiated', { clientId: clientSocketId }); + socket.emit('agent-spinup-process-initiated', { clientId: clientSocketId }) } const platformAdminSpinnedUp = await this.agentServiceRepository.platformAdminAgent( CommonConstants.PLATFORM_ADMIN_ORG - ); + ) if (!platformAdminSpinnedUp) { - this.logger.error(`Agent not able to spin-up`); + this.logger.error(ResponseMessages.agent.error.notAbleToSpinp) throw new BadRequestException(ResponseMessages.agent.error.notAbleToSpinp, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } - return platformAdminSpinnedUp; + return platformAdminSpinnedUp } /** @@ -1140,41 +1150,41 @@ export class AgentServiceService { * @returns Get tanant status */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: private async createTenantAndNotify(payload: ITenantDto, platformAdminSpinnedUp: IOrgAgentsResponse): Promise { - const WalletSetupPayload = { ...payload }; - const socket = await this.createSocketInstance(); + const WalletSetupPayload = { ...payload } + const socket = await this.createSocketInstance() if (WalletSetupPayload.clientSocketId) { - socket.emit('agent-spinup-process-initiated', { clientId: WalletSetupPayload.clientSocketId }); + socket.emit('agent-spinup-process-initiated', { clientId: WalletSetupPayload.clientSocketId }) } - const walletLabel = WalletSetupPayload.label; + const walletLabel = WalletSetupPayload.label - delete WalletSetupPayload.label; - delete WalletSetupPayload.clientSocketId; - delete WalletSetupPayload.orgId; - delete WalletSetupPayload.ledgerId; + WalletSetupPayload.label = undefined + WalletSetupPayload.clientSocketId = undefined + WalletSetupPayload.orgId = undefined + WalletSetupPayload.ledgerId = undefined - const getDcryptedToken = await this.commonService.decryptPassword(platformAdminSpinnedUp?.org_agents[0].apiKey); + const getDcryptedToken = await this.commonService.decryptPassword(platformAdminSpinnedUp?.org_agents[0].apiKey) const walletResponseDetails = await this._createTenantWallet( walletLabel, platformAdminSpinnedUp.org_agents[0].agentEndPoint, getDcryptedToken - ); + ) if (!walletResponseDetails && !walletResponseDetails.id) { - throw new InternalServerErrorException('Error while creating the wallet'); + throw new InternalServerErrorException('Error while creating the wallet') } const didCreateOption = { didPayload: WalletSetupPayload, agentEndpoint: platformAdminSpinnedUp.org_agents[0].agentEndPoint, apiKey: getDcryptedToken, - tenantId: walletResponseDetails.id - }; - const DIDCreationOption = await this._createDID(didCreateOption); + tenantId: walletResponseDetails.id, + } + const DIDCreationOption = await this._createDID(didCreateOption) if (!DIDCreationOption) { - throw new InternalServerErrorException('Error while creating the wallet'); + throw new InternalServerErrorException('Error while creating the wallet') } - return { walletResponseDetails, DIDCreationOption }; + return { walletResponseDetails, DIDCreationOption } } // @@ -1184,20 +1194,20 @@ export class AgentServiceService { * @returns Get tanant status */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: private async _createTenantWallet(label, endpoint, agentApiKey): Promise { //remove any const createTenantOptions = { - config: { label } - }; + config: { label }, + } // Invoke an API request from the agent to create multi-tenant agent const tenantDetails = await this.commonService.httpPost( `${endpoint}${CommonConstants.URL_SHAGENT_CREATE_TENANT}`, createTenantOptions, { headers: { authorization: agentApiKey } } - ); - return tenantDetails; + ) + return tenantDetails } /** @@ -1206,183 +1216,183 @@ export class AgentServiceService { * @returns Get tanant status */ private async _createDID(didCreateOption): Promise { - const { didPayload, agentEndpoint, apiKey, tenantId } = didCreateOption; + const { didPayload, agentEndpoint, apiKey, tenantId } = didCreateOption // Invoke an API request from the agent to create multi-tenant agent const didDetails = await this.commonService.httpPost( `${agentEndpoint}${CommonConstants.URL_SHAGENT_CREATE_DID}${tenantId}`, didPayload, { headers: { authorization: apiKey } } - ); - return didDetails; + ) + return didDetails } private async createSocketInstance(): Promise { return io(`${process.env.SOCKET_HOST}`, { reconnection: true, reconnectionDelay: 5000, - reconnectionAttempts: Infinity, + reconnectionAttempts: Number.POSITIVE_INFINITY, autoConnect: true, - transports: ['websocket'] - }); + transports: ['websocket'], + }) } private async notifyClientSocket(eventName: string, clientId: string | undefined): Promise { - const socket = await this.createSocketInstance(); + const socket = await this.createSocketInstance() if (clientId) { - socket.emit(eventName, { clientId }); + socket.emit(eventName, { clientId }) } } private async handleError(error: Error, clientSocketId: string | undefined): Promise { - this.logger.error(`Error in creating tenant: ${error}`); - const socket = await this.createSocketInstance(); + this.logger.error(`Error in creating tenant: ${error}`) + const socket = await this.createSocketInstance() if (clientSocketId) { - socket.emit('error-in-wallet-creation-process', { clientId: clientSocketId, error }); + socket.emit('error-in-wallet-creation-process', { clientId: clientSocketId, error }) } } async createSchema(payload: ITenantSchema): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(payload.orgId); - let schemaResponse; + const getApiKey = await this.getOrgAgentApiKey(payload.orgId) + let schemaResponse: object | PromiseLike if (OrgAgentType.DEDICATED === payload.agentType) { - const url = `${payload.agentEndPoint}${CommonConstants.URL_SCHM_CREATE_SCHEMA}`; + const url = `${payload.agentEndPoint}${CommonConstants.URL_SCHM_CREATE_SCHEMA}` const schemaPayload = { attributes: payload.attributes, version: payload.version, name: payload.name, - issuerId: payload.issuerId - }; + issuerId: payload.issuerId, + } schemaResponse = await this.commonService .httpPost(url, schemaPayload, { headers: { authorization: getApiKey } }) .then(async (schema) => schema) - .catch((error) => { + .catch((_error) => { throw new InternalServerErrorException(ResponseMessages.agent.error.agentDown, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); - }); + description: ResponseMessages.errorMessages.serverError, + }) + }) } else if (OrgAgentType.SHARED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_SCHEMA}`.replace( '#', `${payload.tenantId}` - ); + ) const schemaPayload = { attributes: payload.payload.attributes, version: payload.payload.version, name: payload.payload.name, - issuerId: payload.payload.issuerId - }; + issuerId: payload.payload.issuerId, + } schemaResponse = await this.commonService .httpPost(url, schemaPayload, { headers: { authorization: getApiKey } }) .then(async (schema) => schema) - .catch((error) => { + .catch((_error) => { throw new InternalServerErrorException(ResponseMessages.agent.error.agentDown, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); - }); + description: ResponseMessages.errorMessages.serverError, + }) + }) } - return schemaResponse; + return schemaResponse } catch (error) { - this.logger.error(`Error in creating schema: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in creating schema: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async getSchemaById(payload: GetSchemaAgentRedirection): Promise { try { - let schemaResponse; + let schemaResponse: object | PromiseLike - const getApiKey = await this.getOrgAgentApiKey(payload.orgId); + const getApiKey = await this.getOrgAgentApiKey(payload.orgId) if (OrgAgentType.DEDICATED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SCHM_GET_SCHEMA_BY_ID.replace( '#', `${payload.schemaId}` - )}`; + )}` schemaResponse = await this.commonService .httpGet(url, { headers: { authorization: getApiKey } }) - .then(async (schema) => schema); + .then(async (schema) => schema) } else if (OrgAgentType.SHARED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SHAGENT_GET_SCHEMA}` .replace('@', `${payload.payload.schemaId}`) - .replace('#', `${payload.tenantId}`); + .replace('#', `${payload.tenantId}`) schemaResponse = await this.commonService .httpGet(url, { headers: { authorization: getApiKey } }) - .then(async (schema) => schema); + .then(async (schema) => schema) } - return schemaResponse; + return schemaResponse } catch (error) { - this.logger.error(`Error in getting schema: ${error}`); - throw error; + this.logger.error(`Error in getting schema: ${error}`) + throw error } } async createCredentialDefinition(payload: ITenantCredDef): Promise { try { - let credDefResponse; + let credDefResponse: object | PromiseLike - const getApiKey = await this.getOrgAgentApiKey(payload.orgId); + const getApiKey = await this.getOrgAgentApiKey(payload.orgId) if (OrgAgentType.DEDICATED === String(payload.agentType)) { - const url = `${payload.agentEndPoint}${CommonConstants.URL_SCHM_CREATE_CRED_DEF}`; + const url = `${payload.agentEndPoint}${CommonConstants.URL_SCHM_CREATE_CRED_DEF}` const credDefPayload = { tag: payload.tag, schemaId: payload.schemaId, - issuerId: payload.issuerId - }; + issuerId: payload.issuerId, + } credDefResponse = await this.commonService .httpPost(url, credDefPayload, { headers: { authorization: getApiKey } }) - .then(async (credDef) => credDef); + .then(async (credDef) => credDef) } else if (OrgAgentType.SHARED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_CRED_DEF}`.replace( '#', `${payload.tenantId}` - ); + ) const credDefPayload = { tag: payload.payload.tag, schemaId: payload.payload.schemaId, - issuerId: payload.payload.issuerId - }; + issuerId: payload.payload.issuerId, + } credDefResponse = await this.commonService .httpPost(url, credDefPayload, { headers: { authorization: getApiKey } }) - .then(async (credDef) => credDef); + .then(async (credDef) => credDef) } - return credDefResponse; + return credDefResponse } catch (error) { - this.logger.error(`Error in creating credential definition: ${error}`); - throw error; + this.logger.error(`Error in creating credential definition: ${error}`) + throw error } } async getCredentialDefinitionById(payload: IGetCredDefAgentRedirection): Promise { try { - let credDefResponse; + let credDefResponse: object | PromiseLike - const getApiKey = await this.getOrgAgentApiKey(payload.orgId); + const getApiKey = await this.getOrgAgentApiKey(payload.orgId) if (OrgAgentType.DEDICATED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SCHM_GET_CRED_DEF_BY_ID.replace( '#', `${payload.credentialDefinitionId}` - )}`; + )}` credDefResponse = await this.commonService .httpGet(url, { headers: { authorization: getApiKey } }) - .then(async (credDef) => credDef); + .then(async (credDef) => credDef) } else if (OrgAgentType.SHARED === payload.agentType) { const url = `${payload.agentEndPoint}${CommonConstants.URL_SHAGENT_GET_CRED_DEF}` .replace('@', `${payload.payload.credentialDefinitionId}`) - .replace('#', `${payload.tenantId}`); + .replace('#', `${payload.tenantId}`) credDefResponse = await this.commonService .httpGet(url, { headers: { authorization: getApiKey } }) - .then(async (credDef) => credDef); + .then(async (credDef) => credDef) } - return credDefResponse; + return credDefResponse } catch (error) { - this.logger.error(`Error in getting schema: ${error}`); - throw error; + this.logger.error(`Error in getting schema: ${error}`) + throw error } } @@ -1392,40 +1402,40 @@ export class AgentServiceService { orgId: string ): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const data = await this.commonService .httpPost(url, connectionPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); + .then(async (response) => response) - return data; + return data } catch (error) { - this.logger.error(`Error in connection Invitation in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in connection Invitation in agent service : ${JSON.stringify(error)}`) + throw error } } async sendCredentialCreateOffer(issueData: IIssuanceCreateOffer, url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const data = await this.commonService .httpPost(url, issueData, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return data; + .then(async (response) => response) + return data } catch (error) { - this.logger.error(`Error in sendCredentialCreateOffer in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in sendCredentialCreateOffer in agent service : ${JSON.stringify(error)}`) + throw error } } async getProofPresentations(url: string, apiKey: string): Promise { try { const getProofPresentationsData = await this.commonService .httpGet(url, { headers: { authorization: apiKey } }) - .then(async (response) => response); + .then(async (response) => response) - return getProofPresentationsData; + return getProofPresentationsData } catch (error) { - this.logger.error(`Error in proof presentations in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in proof presentations in agent service : ${JSON.stringify(error)}`) + throw error } } @@ -1433,34 +1443,34 @@ export class AgentServiceService { try { const data = await this.commonService .httpGet(url, { headers: { authorization: apiKey } }) - .then(async (response) => response); - return data; + .then(async (response) => response) + return data } catch (error) { - this.logger.error(`Error in getIssueCredentials in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in getIssueCredentials in agent service : ${JSON.stringify(error)}`) + throw error } } async getProofPresentationById(url: string, orgId: string): Promise { try { - const getProofPresentationById = await this.agentCall(url, orgId); - return getProofPresentationById; + const getProofPresentationById = await this.agentCall(url, orgId) + return getProofPresentationById } catch (error) { - this.logger.error(`Error in proof presentation by id in agent service : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in proof presentation by id in agent service : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getIssueCredentialsbyCredentialRecordId(url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const data = await this.commonService .httpGet(url, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return data; + .then(async (response) => response) + return data } catch (error) { - this.logger.error(`Error in getIssueCredentialsbyCredentialRecordId in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in getIssueCredentialsbyCredentialRecordId in agent service : ${JSON.stringify(error)}`) + throw error } } @@ -1470,51 +1480,51 @@ export class AgentServiceService { orgId: string ): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const sendProofRequest = await this.commonService .httpPost(url, proofRequestPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return sendProofRequest; + .then(async (response) => response) + return sendProofRequest } catch (error) { - this.logger.error(`Error in send proof request in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in send proof request in agent service : ${JSON.stringify(error)}`) + throw error } } async verifyPresentation(url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const verifyPresentation = await this.commonService .httpPost(url, '', { headers: { authorization: getApiKey } }) .then(async (response) => response) - .catch((error) => this.handleAgentSpinupStatusErrors(error)); - return verifyPresentation; + .catch((error) => this.handleAgentSpinupStatusErrors(error)) + return verifyPresentation } catch (error) { - this.logger.error(`Error in verify proof presentation in agent service : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in verify proof presentation in agent service : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getConnections(url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const data = await this.commonService .httpGet(url, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return data; + .then(async (response) => response) + return data } catch (error) { - this.logger.error(`Error in getConnections in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in getConnections in agent service : ${JSON.stringify(error)}`) + throw error } } async getConnectionsByconnectionId(url: string, orgId: string): Promise { try { - const getConnectionsByconnectionId = await this.agentCall(url, orgId); - return getConnectionsByconnectionId; + const getConnectionsByconnectionId = await this.agentCall(url, orgId) + return getConnectionsByconnectionId } catch (error) { - this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -1526,47 +1536,47 @@ export class AgentServiceService { async getAgentHealthDetails(orgId: string): Promise { try { // Get organization agent details - const orgAgentDetails: org_agents = await this.agentServiceRepository.getOrgAgentDetails(orgId); - let agentApiKey; + const orgAgentDetails: org_agents = await this.agentServiceRepository.getOrgAgentDetails(orgId) + let agentApiKey: string if (orgAgentDetails) { - agentApiKey = await this.getOrgAgentApiKey(orgId); + agentApiKey = await this.getOrgAgentApiKey(orgId) } if (!orgAgentDetails) { throw new NotFoundException(ResponseMessages.agent.error.agentNotExists, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } if (!orgAgentDetails?.agentEndPoint) { throw new NotFoundException(ResponseMessages.agent.error.agentUrl, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + 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: { authorization: agentApiKey } + headers: { authorization: agentApiKey }, }) - .then(async (response) => response); + .then(async (response) => response) - return agentHealthData; + return agentHealthData } catch (error) { - this.logger.error(`Agent health details : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Agent health details : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - async getLedgerConfigDetails(user: IUserRequestInterface): Promise { + async getLedgerConfigDetails(_user: IUserRequestInterface): Promise { try { - const getLedgerConfigData = await this.agentServiceRepository.getLedgerConfigByOrgId(); - return getLedgerConfigData; + const getLedgerConfigData = await this.agentServiceRepository.getLedgerConfigByOrgId() + return getLedgerConfigData } catch (error) { - this.logger.error(`Error in send out of band proof request in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in send out of band proof request in agent service : ${JSON.stringify(error)}`) + throw error } } @@ -1576,80 +1586,80 @@ export class AgentServiceService { orgId: string ): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const sendProofRequest = await this.commonService .httpPost(url, proofRequestPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return sendProofRequest; + .then(async (response) => response) + return sendProofRequest } catch (error) { - this.logger.error(`Error in send out of band proof request in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in send out of band proof request in agent service : ${JSON.stringify(error)}`) + throw error } } async getVerifiedProofDetails(url: string, orgId: string): Promise { try { - const getVerifiedProofDetails = await this.agentCall(url, orgId); - return getVerifiedProofDetails; + const getVerifiedProofDetails = await this.agentCall(url, orgId) + return getVerifiedProofDetails } catch (error) { - this.logger.error(`Error in get verified proof details in agent service : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in get verified proof details in agent service : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async schemaEndorsementRequest(url: string, orgId: string, requestSchemaPayload: object): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const schemaRequest = await this.commonService .httpPost(url, requestSchemaPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return schemaRequest; + .then(async (response) => response) + return schemaRequest } catch (error) { - this.logger.error(`Error in schema endorsement request in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in schema endorsement request in agent service : ${JSON.stringify(error)}`) + throw error } } async credDefEndorsementRequest(url: string, orgId: string, requestSchemaPayload: object): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const credDefRequest = await this.commonService .httpPost(url, requestSchemaPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return credDefRequest; + .then(async (response) => response) + return credDefRequest } catch (error) { this.logger.error( `Error in credential-definition endorsement request in agent service : ${JSON.stringify(error)}` - ); - throw error; + ) + throw error } } async signTransaction(url: string, orgId: string, signEndorsementPayload: object): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const signEndorsementTransaction = await this.commonService .httpPost(url, signEndorsementPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); + .then(async (response) => response) - return signEndorsementTransaction; + return signEndorsementTransaction } catch (error) { - this.logger.error(`Error in sign transaction in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in sign transaction in agent service : ${JSON.stringify(error)}`) + throw error } } async sumbitTransaction(url: string, orgId: string, submitEndorsementPayload: object): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const signEndorsementTransaction = await this.commonService .httpPost(url, submitEndorsementPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); + .then(async (response) => response) - return signEndorsementTransaction; + return signEndorsementTransaction } catch (error) { - this.logger.error(`Error in sumbit transaction in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in sumbit transaction in agent service : ${JSON.stringify(error)}`) + throw error } } @@ -1659,176 +1669,176 @@ export class AgentServiceService { orgId: string ): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const sendOutOfbandCredentialOffer = await this.commonService .httpPost(url, outOfBandIssuancePayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return sendOutOfbandCredentialOffer; + .then(async (response) => response) + return sendOutOfbandCredentialOffer } catch (error) { - this.logger.error(`Error in out-of-band credential in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in out-of-band credential in agent service : ${JSON.stringify(error)}`) + throw error } } async deleteWallet(orgId: string, user: user): Promise { try { - // Retrieve the API key and agent information - const [getApiKeyResult, orgAgentResult] = await Promise.allSettled([ - this.getOrgAgentApiKey(orgId), - this.agentServiceRepository.getAgentApiKey(orgId) - ]); - - if (orgAgentResult.status === PromiseResult.FULFILLED && !orgAgentResult.value) { - throw new NotFoundException(ResponseMessages.agent.error.walletDoesNotExists); + // Retrieve the API key and agent information + const [getApiKeyResult, orgAgentResult] = await Promise.allSettled([ + this.getOrgAgentApiKey(orgId), + this.agentServiceRepository.getAgentApiKey(orgId), + ]) + + if (orgAgentResult.status === PromiseResult.FULFILLED && !orgAgentResult.value) { + throw new NotFoundException(ResponseMessages.agent.error.walletDoesNotExists) } - if (getApiKeyResult.status === PromiseResult.REJECTED) { - throw new InternalServerErrorException(`Failed to get API key: ${getApiKeyResult.reason}`); - } + if (getApiKeyResult.status === PromiseResult.REJECTED) { + throw new InternalServerErrorException(`Failed to get API key: ${getApiKeyResult.reason}`) + } - if (orgAgentResult.status === PromiseResult.REJECTED) { - throw new InternalServerErrorException(`Failed to get agent information: ${orgAgentResult.reason}`); - } + if (orgAgentResult.status === PromiseResult.REJECTED) { + throw new InternalServerErrorException(`Failed to get agent information: ${orgAgentResult.reason}`) + } + + const getApiKey = getApiKeyResult?.value + const orgAgent = orgAgentResult?.value + + const orgAgentTypeResult = await this.agentServiceRepository.getOrgAgentType(orgAgent.orgAgentTypeId) + + if (!orgAgentTypeResult) { + throw new NotFoundException(ResponseMessages.agent.error.orgAgentNotFound) + } - const getApiKey = getApiKeyResult?.value; - const orgAgent = orgAgentResult?.value; + // Determine the URL based on the agent type + const url = + orgAgentTypeResult.agent === OrgAgentType.SHARED + ? `${orgAgent.agentEndPoint}${CommonConstants.URL_SHAGENT_DELETE_SUB_WALLET}`.replace('#', orgAgent?.tenantId) + : `${orgAgent.agentEndPoint}${CommonConstants.URL_DELETE_WALLET}` - const orgAgentTypeResult = await this.agentServiceRepository.getOrgAgentType(orgAgent.orgAgentTypeId); + // Perform the deletion in a transaction + return await this.prisma.$transaction(async (_prisma) => { + // Delete org agent and related records + const { orgDid, agentInvitation, deleteOrgAgent } = await this.agentServiceRepository.deleteOrgAgentByOrg(orgId) - if (!orgAgentTypeResult) { - throw new NotFoundException(ResponseMessages.agent.error.orgAgentNotFound); + // Make the HTTP DELETE request + const deleteWallet = await this.commonService.httpDelete(url, { + headers: { authorization: getApiKey }, + }) + + if (deleteWallet.status !== HttpStatus.NO_CONTENT) { + throw new InternalServerErrorException(ResponseMessages.agent.error.walletNotDeleted) } - // Determine the URL based on the agent type - const url = - orgAgentTypeResult.agent === OrgAgentType.SHARED - ? `${orgAgent.agentEndPoint}${CommonConstants.URL_SHAGENT_DELETE_SUB_WALLET}`.replace('#', orgAgent?.tenantId) - : `${orgAgent.agentEndPoint}${CommonConstants.URL_DELETE_WALLET}`; + const deletions = [ + { records: orgDid.count, tableName: 'org_dids' }, + { records: agentInvitation.count, tableName: 'agent_invitations' }, + { records: deleteOrgAgent ? 1 : 0, tableName: 'org_agents' }, + ] - // Perform the deletion in a transaction - return await this.prisma.$transaction(async (prisma) => { - // Delete org agent and related records - const { orgDid, agentInvitation, deleteOrgAgent } = await this.agentServiceRepository.deleteOrgAgentByOrg(orgId); + const did = orgAgent?.orgDid - // Make the HTTP DELETE request - const deleteWallet = await this.commonService.httpDelete(url, { - headers: { authorization: getApiKey } - }); + //archive schemas + await this._updateIsSchemaArchivedFlag(did) - if (deleteWallet.status !== HttpStatus.NO_CONTENT) { - throw new InternalServerErrorException(ResponseMessages.agent.error.walletNotDeleted); + const logDeletionActivity = async (records, tableName): Promise => { + if (records) { + const txnMetadata = { + deletedRecordsCount: records, + deletedRecordInTable: tableName, } + const recordType = RecordType.WALLET + await this.userActivityRepository._orgDeletedActivity(orgId, user, txnMetadata, recordType) + } + } - const deletions = [ - { records: orgDid.count, tableName: 'org_dids' }, - { records: agentInvitation.count, tableName: 'agent_invitations' }, - { records: deleteOrgAgent ? 1 : 0, tableName: 'org_agents' } - ]; - - const did = orgAgent?.orgDid; - - //archive schemas - await this._updateIsSchemaArchivedFlag(did); - - const logDeletionActivity = async (records, tableName): Promise => { - if (records) { - const txnMetadata = { - deletedRecordsCount: records, - deletedRecordInTable: tableName - }; - const recordType = RecordType.WALLET; - await this.userActivityRepository._orgDeletedActivity(orgId, user, txnMetadata, recordType); - } - }; - - for (const { records, tableName } of deletions) { - await logDeletionActivity(records, tableName); - } + for (const { records, tableName } of deletions) { + await logDeletionActivity(records, tableName) + } - return deleteOrgAgent; - }); + return deleteOrgAgent + }) } catch (error) { - this.logger.error(`Error in delete wallet in agent service: ${JSON.stringify(error.message)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in delete wallet in agent service: ${JSON.stringify(error.message)}`) + throw new RpcException(error.response ? error.response : error) } -} + } -async _updateIsSchemaArchivedFlag(did: string): Promise<{ - count: number -}> { - const pattern = { cmd: 'archive-schemas' }; - - const payload = { - did - }; - const updatedSchemaInfo = await this.agentServiceProxy - .send(pattern, payload) - .toPromise() - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.status, - error: error.message - }, - error.status - ); - }); - return updatedSchemaInfo; -} + async _updateIsSchemaArchivedFlag(did: string): Promise<{ + count: number + }> { + const pattern = { cmd: 'archive-schemas' } + + const payload = { + did, + } + const updatedSchemaInfo = await this.agentServiceProxy + .send(pattern, payload) + .toPromise() + .catch((error) => { + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw new HttpException( + { + status: error.status, + error: error.message, + }, + error.status + ) + }) + return updatedSchemaInfo + } async receiveInvitationUrl(receiveInvitationUrl: IReceiveInvitationUrl, url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const receiveInvitationUrlRes = await this.commonService .httpPost(url, receiveInvitationUrl, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return receiveInvitationUrlRes; + .then(async (response) => response) + return receiveInvitationUrlRes } catch (error) { - this.logger.error(`Error in receive invitation in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in receive invitation in agent service : ${JSON.stringify(error)}`) + throw error } } async receiveInvitation(receiveInvitation: IReceiveInvitation, url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const receiveInvitationRes = await this.commonService .httpPost(url, receiveInvitation, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return receiveInvitationRes; + .then(async (response) => response) + return receiveInvitationRes } catch (error) { - this.logger.error(`Error in receive invitation in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in receive invitation in agent service : ${JSON.stringify(error)}`) + throw error } } async getOrgAgentApiKey(orgId: string): Promise { try { - const orgAgentApiKey = await this.agentServiceRepository.getAgentApiKey(orgId); - const orgAgentId = await this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.SHARED); - let apiKey; + const orgAgentApiKey = await this.agentServiceRepository.getAgentApiKey(orgId) + const orgAgentId = await this.agentServiceRepository.getOrgAgentTypeDetails(OrgAgentType.SHARED) + let apiKey: string if (orgAgentApiKey?.orgAgentTypeId === orgAgentId) { const platformAdminSpinnedUp = await this.agentServiceRepository.platformAdminAgent( CommonConstants.PLATFORM_ADMIN_ORG - ); + ) if (!platformAdminSpinnedUp) { - throw new InternalServerErrorException('Agent not able to spin-up'); + throw new InternalServerErrorException('Agent not able to spin-up') } - apiKey = platformAdminSpinnedUp.org_agents[0]?.apiKey; + apiKey = platformAdminSpinnedUp.org_agents[0]?.apiKey } else { - apiKey = orgAgentApiKey?.apiKey; + apiKey = orgAgentApiKey?.apiKey } if (!apiKey) { - throw new NotFoundException(ResponseMessages.agent.error.apiKeyNotExist); + throw new NotFoundException(ResponseMessages.agent.error.apiKeyNotExist) } - const decryptedToken = await this.commonService.decryptPassword(apiKey); - return decryptedToken; + const decryptedToken = await this.commonService.decryptPassword(apiKey) + return decryptedToken } catch (error) { - this.logger.error(`Agent api key details : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Agent api key details : ${JSON.stringify(error)}`) + throw error } } @@ -1836,70 +1846,69 @@ async _updateIsSchemaArchivedFlag(did: string): Promise<{ if (error && Object.keys(error).length === 0) { throw new InternalServerErrorException(ResponseMessages.agent.error.agentDown, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); - } else { - throw error; + description: ResponseMessages.errorMessages.serverError, + }) } + throw error } async sendQuestion(questionPayload: IQuestionPayload, url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const sendQuestionRes = await this.commonService .httpPost(url, questionPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return sendQuestionRes; + .then(async (response) => response) + return sendQuestionRes } catch (error) { - this.logger.error(`Error in send question in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in send question in agent service : ${JSON.stringify(error)}`) + throw error } } async sendBasicMessage(messagePayload: IBasicMessage, url: string, orgId: string): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const basicMessageRes = await this.commonService .httpPost(url, messagePayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return basicMessageRes; + .then(async (response) => response) + return basicMessageRes } catch (error) { - this.logger.error(`Error in sendBasicMessage in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in sendBasicMessage in agent service : ${JSON.stringify(error)}`) + throw error } } async getQuestionAnswersRecord(url: string, orgId: string): Promise { try { - const getQuestionAnswersRecord = await this.agentCall(url, orgId); - return getQuestionAnswersRecord; + const getQuestionAnswersRecord = await this.agentCall(url, orgId) + return getQuestionAnswersRecord } catch (error) { - this.logger.error(`Error in getQuestionAnswersRecord in agent service : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in getQuestionAnswersRecord in agent service : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async agentCall(url: string, orgId: string): Promise { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const data = await this.commonService .httpGet(url, { headers: { authorization: getApiKey } }) .then(async (response) => response) - .catch((error) => this.handleAgentSpinupStatusErrors(error)); + .catch((error) => this.handleAgentSpinupStatusErrors(error)) - return data; + return data } async createW3CSchema(url: string, orgId: string, schemaRequestPayload): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const schemaRequest = await this.commonService .httpPost(url, schemaRequestPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return schemaRequest; + .then(async (response) => response) + return schemaRequest } catch (error) { - this.logger.error(`Error in createW3CSchema request in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in createW3CSchema request in agent service : ${JSON.stringify(error)}`) + throw error } } @@ -1909,15 +1918,15 @@ async _updateIsSchemaArchivedFlag(did: string): Promise<{ connectionPayload: ICreateConnectionInvitation ): Promise { try { - const getApiKey = await this.getOrgAgentApiKey(orgId); + const getApiKey = await this.getOrgAgentApiKey(orgId) const createConnectionInvitation = await this.commonService .httpPost(url, connectionPayload, { headers: { authorization: getApiKey } }) - .then(async (response) => response); - return createConnectionInvitation; + .then(async (response) => response) + return createConnectionInvitation } catch (error) { - this.logger.error(`Error in create connection invitation in agent service : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in create connection invitation in agent service : ${JSON.stringify(error)}`) + throw error } } @@ -1925,36 +1934,31 @@ async _updateIsSchemaArchivedFlag(did: string): Promise<{ pattern: object, payload: object ): Promise<{ - response: string; + response: string }> { try { - return from(this.natsClient - .send(this.agentServiceProxy, pattern, payload)) + return from(this.natsClient.send(this.agentServiceProxy, pattern, payload)) .pipe(map((response) => ({ response }))) .toPromise() .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.statusCode, - error: error.message + error: error.message, }, error.error - ); - }); + ) + }) } catch (error) { - this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`) + throw error } } private async tokenEncryption(token: string): Promise { - try { - const encryptedToken = CryptoJS.AES.encrypt(JSON.stringify(token), process.env.CRYPTO_PRIVATE_KEY).toString(); + const encryptedToken = CryptoJS.AES.encrypt(JSON.stringify(token), process.env.CRYPTO_PRIVATE_KEY).toString() - return encryptedToken; - } catch (error) { - throw error; - } + return encryptedToken } -} \ No newline at end of file +} diff --git a/apps/agent-service/src/interface/agent-service.interface.ts b/apps/agent-service/src/interface/agent-service.interface.ts index b4927f98c..2ea555947 100644 --- a/apps/agent-service/src/interface/agent-service.interface.ts +++ b/apps/agent-service/src/interface/agent-service.interface.ts @@ -1,658 +1,657 @@ -import { AgentSpinUpStatus } from '@credebl/enum/enum'; -import { Prisma } from '@prisma/client'; -import { UserRoleOrgPermsDto } from 'apps/api-gateway/src/dtos/user-role-org-perms.dto'; +import type { AgentSpinUpStatus } from '@credebl/enum/enum' +import type { Prisma } from '@prisma/client' +import type { UserRoleOrgPermsDto } from 'apps/api-gateway/src/dtos/user-role-org-perms.dto' export interface IAgentSpinupDto { - walletName: string; - walletPassword: string; - seed: string; - orgId?: string; - orgName?: string; - ledgerId?: string[]; - keyType: string; - domain?: string; - privatekey?: string; - endpoint?: string; - role?: string; - network?: string; - endorserDid?: string; - method: string; - did?: string; - agentType?: string; - transactionApproval?: boolean; - clientSocketId?: string; - tenant?: boolean; - ledgerName?: string[]; - platformAdminEmail?: string; - isOnPremises?: boolean; - agentEndpoint?: string; - apiKey?: string; - orgAgentType?: string; - userId?: string; + walletName: string + walletPassword: string + seed: string + orgId?: string + orgName?: string + ledgerId?: string[] + keyType: string + domain?: string + privatekey?: string + endpoint?: string + role?: string + network?: string + endorserDid?: string + method: string + did?: string + agentType?: string + transactionApproval?: boolean + clientSocketId?: string + tenant?: boolean + ledgerName?: string[] + platformAdminEmail?: string + isOnPremises?: boolean + agentEndpoint?: string + apiKey?: string + orgAgentType?: string + userId?: string } export interface IAgentConfigure { - walletName: string; - did: string; - agentEndpoint: string; - apiKey: string; - orgId: string; - network?: string; + walletName: string + did: string + agentEndpoint: string + apiKey: string + orgId: string + network?: string } export interface IOutOfBandCredentialOffer { - emailId: string; - attributes: IAttributes[]; - credentialDefinitionId: string; - comment: string; - protocolVersion?: string; - orgId: string; - goalCode?: string; - parentThreadId?: string; - willConfirm?: boolean; - label?: string; + emailId: string + attributes: IAttributes[] + credentialDefinitionId: string + comment: string + protocolVersion?: string + orgId: string + goalCode?: string + parentThreadId?: string + willConfirm?: boolean + label?: string } export interface ITenantDto { - label: string; - seed?: string; - keyType: string; - ledgerId: string[]; - domain?: string; - privatekey?: string; - endpoint?: string; - role?: string; - network?: string; - endorserDid?: string; - method: string; - orgId: string; - did?: string; - tenantId?: string; - didDocument?: string; - clientSocketId?: string; + label: string + seed?: string + keyType: string + ledgerId: string[] + domain?: string + privatekey?: string + endpoint?: string + role?: string + network?: string + endorserDid?: string + method: string + orgId: string + did?: string + tenantId?: string + didDocument?: string + clientSocketId?: string } export interface IWallet { - label: string; - orgId: string; - did?: string; - clientSocketId?: string; + label: string + orgId: string + did?: string + clientSocketId?: string } export interface IDidCreate { - keyType: KeyType; - seed: string; - domain?: string; - network?: string; - privatekey?: string; - endpoint?: string; - method: string; - did?: string; - role?: string; - endorserDid?: string; - isPrimaryDid?: boolean; + keyType: KeyType + seed: string + domain?: string + network?: string + privatekey?: string + endpoint?: string + method: string + did?: string + role?: string + endorserDid?: string + isPrimaryDid?: boolean } export interface ITenantSchema { - tenantId?: string; - attributes: string[]; - version: string; - name: string; - issuerId?: string; - payload?: ITenantSchemaDto; - method?: string; - agentType?: string; - apiKey?: string; - agentEndPoint?: string; - orgId?: string; + tenantId?: string + attributes: string[] + version: string + name: string + issuerId?: string + payload?: ITenantSchemaDto + method?: string + agentType?: string + apiKey?: string + agentEndPoint?: string + orgId?: string } export interface ITenantSchemaDto { - attributes: string[]; - version: string; - name: string; - issuerId: string; + attributes: string[] + version: string + name: string + issuerId: string } export interface IGetSchemaAgentRedirection { - schemaId?: string; - tenantId?: string; - payload?: IGetSchemaFromTenantPayload; - apiKey?: string; - agentEndPoint?: string; - agentType?: string; - method?: string; - orgId?: string; + schemaId?: string + tenantId?: string + payload?: IGetSchemaFromTenantPayload + apiKey?: string + agentEndPoint?: string + agentType?: string + method?: string + orgId?: string } export interface IGetSchemaFromTenantPayload { - schemaId: string; + schemaId: string } export interface ITenantCredDef { - tenantId?: string; - tag?: string; - schemaId?: string; - issuerId?: string; - payload?: ITenantCredDef; - method?: string; - agentType?: string; - apiKey?: string; - agentEndPoint?: string; - orgId?: string; + tenantId?: string + tag?: string + schemaId?: string + issuerId?: string + payload?: ITenantCredDef + method?: string + agentType?: string + apiKey?: string + agentEndPoint?: string + orgId?: string } export interface IWalletProvision { - orgId: string; - externalIp: string; - walletName: string; - walletPassword: string; - seed: string; - webhookEndpoint: string; - walletStorageHost: string; - walletStoragePort: string; - walletStorageUser: string; - walletStoragePassword: string; - containerName: string; - agentType: string; - orgName: string; - indyLedger: string; - credoImage: string; - protocol: string; - tenant: boolean; - inboundEndpoint: string; - apiKey?: string; + orgId: string + externalIp: string + walletName: string + walletPassword: string + seed: string + webhookEndpoint: string + walletStorageHost: string + walletStoragePort: string + walletStorageUser: string + walletStoragePassword: string + containerName: string + agentType: string + orgName: string + indyLedger: string + credoImage: string + protocol: string + tenant: boolean + inboundEndpoint: string + apiKey?: string } export interface IPlatformConfigDto { - externalIP: string; - genesisURL: string; - adminKey: string; - lastInternalIP: string; - platformTestNetApiKey: string; - sgEmailFrom: string; - apiEndpoint: string; - tailsFileServer: string; + externalIP: string + genesisURL: string + adminKey: string + lastInternalIP: string + platformTestNetApiKey: string + sgEmailFrom: string + apiEndpoint: string + tailsFileServer: string } export interface IStoreOrgAgentDetails { - id?: string; - clientSocketId?: string; - agentEndPoint?: string; - apiKey?: string; - seed?: string; - keyType?: string; - method?: string; - network?: string; - role?: string; - did?: string; - didDoc?: string; - verkey?: string; - isDidPublic?: boolean; - agentSpinUpStatus?: number; - walletName?: string; - agentsTypeId?: string; - orgId?: string; - agentId?: string; - orgAgentTypeId?: string; - tenantId?: string; - ledgerId?: string[]; - agentType?: string; - userId?: string; + id?: string + clientSocketId?: string + agentEndPoint?: string + apiKey?: string + seed?: string + keyType?: string + method?: string + network?: string + role?: string + did?: string + didDoc?: string + verkey?: string + isDidPublic?: boolean + agentSpinUpStatus?: number + walletName?: string + agentsTypeId?: string + orgId?: string + agentId?: string + orgAgentTypeId?: string + tenantId?: string + ledgerId?: string[] + agentType?: string + userId?: string } export interface IStoreDidDetails { - orgId: string; - isPrimaryDid?: boolean; - did: string; - didDocument?: string; - userId: string; - orgAgentId: string; + orgId: string + isPrimaryDid?: boolean + did: string + didDocument?: string + userId: string + orgAgentId: string } export interface IStoreOrgAgent { - id?: string; - clientSocketId?: string; - agentEndPoint?: string; - apiKey?: string; - seed?: string; - did?: string; - verkey?: string; - isDidPublic?: boolean; - agentSpinUpStatus?: number; - walletName?: string; - agentsTypeId?: string; - orgId?: string; - agentId?: string; - orgAgentTypeId?: string; - tenantId?: string; - ledgerId?: unknown; - agentType?: string; + id?: string + clientSocketId?: string + agentEndPoint?: string + apiKey?: string + seed?: string + did?: string + verkey?: string + isDidPublic?: boolean + agentSpinUpStatus?: number + walletName?: string + agentsTypeId?: string + orgId?: string + agentId?: string + orgAgentTypeId?: string + tenantId?: string + ledgerId?: unknown + agentType?: string } export interface IConnectionDetails { - multiUseInvitation?: boolean; - autoAcceptConnection: boolean; + multiUseInvitation?: boolean + autoAcceptConnection: boolean } export interface IUserRequestInterface { - userId?: string; - id?: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?: string; - selectedOrg: IOrgInterface; + userId?: string + id?: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string + selectedOrg: IOrgInterface } export interface IOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: IOrganizationAgentInterface; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: IOrganizationAgentInterface } export interface IOrganizationAgentInterface { - name: string; - description: string; - org_agents: IOrgAgentInterface[]; + name: string + description: string + org_agents: IOrgAgentInterface[] } export interface IPlatformAgent { - seed: string; - keyType: string; - method: string; - network: string; - role: string; + seed: string + keyType: string + method: string + network: string + role: string } export interface IOrgAgentInterface { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } export interface ITenantCredDefDto { - tag: string; - schemaId: string; - issuerId: string; + tag: string + schemaId: string + issuerId: string } export interface IGetCredDefAgentRedirection { - credentialDefinitionId?: string; - tenantId?: string; - payload?: IGetCredDefFromTenantPayload; - apiKey?: string; - agentEndPoint?: string; - agentType?: string; - method?: string; - orgId?: string; + credentialDefinitionId?: string + tenantId?: string + payload?: IGetCredDefFromTenantPayload + apiKey?: string + agentEndPoint?: string + agentType?: string + method?: string + orgId?: string } export interface IGetCredDefFromTenantPayload { - credentialDefinitionId: string; + credentialDefinitionId: string } export interface IIssuanceCreateOffer { - connectionId: string; - credentialFormats: ICredentialFormats; - autoAcceptCredential: string; - comment: string; + connectionId: string + credentialFormats: ICredentialFormats + autoAcceptCredential: string + comment: string } export interface ICredentialFormats { - indy: IIndy; - credentialDefinitionId: string; + indy: IIndy + credentialDefinitionId: string } export interface IIndy { - attributes: IAttributes[]; + attributes: IAttributes[] } export interface IAttributes { - name: string; - value: string; + name: string + value: string } export interface ISendProofRequestPayload { - comment: string; - connectionId?: string; - proofFormats: IProofFormats; - autoAcceptProof: string; - goalCode?: string; - parentThreadId?: string; - willConfirm?: boolean; - protocolVersion?: string; + comment: string + connectionId?: string + proofFormats: IProofFormats + autoAcceptProof: string + goalCode?: string + parentThreadId?: string + willConfirm?: boolean + protocolVersion?: string } export interface IAgentStatus { - label: string; - endpoints: string[]; - isInitialized: boolean; + label: string + endpoints: string[] + isInitialized: boolean } export interface ISchema { - uri: string; + uri: string } export interface IFields { - path: string[]; + path: string[] } export interface IConstraints { - fields: IFields[]; + fields: IFields[] } export interface IInputDescriptors { - id: string; - name?: string; - purpose?: string; - schema: ISchema[]; - constraints?: IConstraints; + id: string + name?: string + purpose?: string + schema: ISchema[] + constraints?: IConstraints } export interface IProofRequestPresentationDefinition { - id: string; - name: string; - purpose?: string; - input_descriptors: IInputDescriptors[]; + id: string + name: string + purpose?: string + input_descriptors: IInputDescriptors[] } export interface IPresentationExchange { - presentationDefinition: IProofRequestPresentationDefinition; + presentationDefinition: IProofRequestPresentationDefinition } interface IProofFormats { - indy?: IndyProof; - presentationExchange?: IPresentationExchange; + indy?: IndyProof + presentationExchange?: IPresentationExchange } interface IndyProof { - name: string; - version: string; - requested_attributes: IRequestedAttributes; - requested_predicates: IRequestedPredicates; + name: string + version: string + requested_attributes: IRequestedAttributes + requested_predicates: IRequestedPredicates } interface IRequestedAttributes { - [key: string]: IRequestedAttributesName; + [key: string]: IRequestedAttributesName } interface IRequestedAttributesName { - name: string; - restrictions: IRequestedRestriction[]; + name: string + restrictions: IRequestedRestriction[] } interface IRequestedPredicates { - [key: string]: IRequestedPredicatesName; + [key: string]: IRequestedPredicatesName } interface IRequestedPredicatesName { - name: string; - restrictions: IRequestedRestriction[]; + name: string + restrictions: IRequestedRestriction[] } interface IRequestedRestriction { - cred_def_id?: string; - schema_id?: string; - schema_issuer_did?: string; - schema_name?: string; - issuer_did?: string; + cred_def_id?: string + schema_id?: string + schema_issuer_did?: string + schema_name?: string + issuer_did?: string } export interface IAgentSpinUpSatus { - agentSpinupStatus: number; + agentSpinupStatus: number } interface IWalletConfig { - id: string; - key: string; - keyDerivationMethod: string; + id: string + key: string + keyDerivationMethod: string } interface IConfig { - label: string; - walletConfig: IWalletConfig; + label: string + walletConfig: IWalletConfig } export interface ITenantRecord { - _tags: string; - metadata: string; - id: string; - createdAt: string; - config: IConfig; - updatedAt: string; + _tags: string + metadata: string + id: string + createdAt: string + config: IConfig + updatedAt: string } export interface ICreateTenant { - tenantRecord: ITenantRecord; - did: string; - verkey: string; + tenantRecord: ITenantRecord + did: string + verkey: string } export interface IOrgAgent { - agentSpinUpStatus: number; + agentSpinUpStatus: number } export interface IOrgLedgers { - id: string; + id: string } export interface ICreateOrgAgent { - id: string; + id: string } interface IOrgAgentEndPoint { - agentSpinUpStatus: number; - agentEndPoint: string; - apiKey; + agentSpinUpStatus: number + agentEndPoint: string + apiKey } export interface IOrgAgentsResponse { - org_agents: IOrgAgentEndPoint[]; + org_agents: IOrgAgentEndPoint[] } export interface IStoreAgent { - id: string; + id: string } export interface IAcceptCredentials { - credentialRecordId: string; + credentialRecordId: string } export interface IAgentProofRequest { - metadata: object; - id: string; - createdAt: string; - protocolVersion: string; - state: string; - connectionId: string; - threadId: string; - autoAcceptProof: string; - updatedAt: string; + metadata: object + id: string + createdAt: string + protocolVersion: string + state: string + connectionId: string + threadId: string + autoAcceptProof: string + updatedAt: string } export interface IPresentation { - _tags: ITags; - metadata: object; - id: string; + _tags: ITags + metadata: object + id: string } export interface IStoreAgent { - id: string; + id: string } export interface IReceiveInvite { - alias?: string; - label?: string; - imageUrl?: string; - autoAcceptConnection?: boolean; - autoAcceptInvitation?: boolean; - reuseConnection?: boolean; - acceptInvitationTimeoutMs?: number; + alias?: string + label?: string + imageUrl?: string + autoAcceptConnection?: boolean + autoAcceptInvitation?: boolean + reuseConnection?: boolean + acceptInvitationTimeoutMs?: number } export interface IReceiveInvitationUrl extends IReceiveInvite { - invitationUrl: string; + invitationUrl: string } interface IService { - id: string; - serviceEndpoint: string; - type: string; - recipientKeys: string[]; - routingKeys: string[]; - accept: string[]; + id: string + serviceEndpoint: string + type: string + recipientKeys: string[] + routingKeys: string[] + accept: string[] } interface IInvitation { - '@id': string; - '@type': string; - label: string; - goalCode: string; - goal: string; - accept: string[]; - handshake_protocols: string[]; - services: (IService | string)[]; - imageUrl?: string; + '@id': string + '@type': string + label: string + goalCode: string + goal: string + accept: string[] + handshake_protocols: string[] + services: (IService | string)[] + imageUrl?: string } export interface IReceiveInvitation extends IReceiveInvite { - invitation: IInvitation; + invitation: IInvitation } export interface IProofPresentation { - createdAt: string; - protocolVersion: string; - state: string; - connectionId: string; - threadId: string; - autoAcceptProof: string; - updatedAt: string; - isVerified: boolean; + createdAt: string + protocolVersion: string + state: string + connectionId: string + threadId: string + autoAcceptProof: string + updatedAt: string + isVerified: boolean } interface ITags { - connectionId: string; - state: string; - threadId: string; + connectionId: string + state: string + threadId: string } export interface IValidResponses { - text: string; + text: string } export interface IQuestionPayload { - detail: string; - validResponses: IValidResponses[]; - question: string; - orgId?: string; - connectionId: string; - tenantId: string; + detail: string + validResponses: IValidResponses[] + question: string + orgId?: string + connectionId: string + tenantId: string } export interface IBasicMessage { - content: string; + content: string } interface Ledger { - id: string; - createDateTime: string; - lastChangedDateTime: string; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - nymTxnEndpoint: string; - indyNamespace: string; - networkUrl: string | null; + id: string + createDateTime: string + lastChangedDateTime: string + name: string + networkType: string + poolConfig: string + isActive: boolean + networkString: string + nymTxnEndpoint: string + indyNamespace: string + networkUrl: string | null } export interface LedgerListResponse { - response: Ledger[]; + response: Ledger[] } export interface ICreateConnectionInvitation { - label?: string; - alias?: string; - imageUrl?: string; - goalCode?: string; - goal?: string; - handshake?: boolean; - handshakeProtocols?: object[]; - messages?: object[]; - multiUseInvitation?: boolean; - autoAcceptConnection?: boolean; - routing?: object; - appendedAttachments?: object[]; - orgId?: string; + label?: string + alias?: string + imageUrl?: string + goalCode?: string + goal?: string + handshake?: boolean + handshakeProtocols?: object[] + messages?: object[] + multiUseInvitation?: boolean + autoAcceptConnection?: boolean + routing?: object + appendedAttachments?: object[] + orgId?: string } export interface AgentHealthData { - label: string; - endpoints: string[]; - isInitialized: boolean; + label: string + endpoints: string[] + isInitialized: boolean } export interface IAgentStore { - did?: string; - verkey?: string; - isDidPublic?: boolean; - agentSpinUpStatus?: AgentSpinUpStatus; - walletName?: string; - agentsTypeId?: string; - orgId?: string; - agentEndPoint?: string; - agentId?: string; - orgAgentTypeId?: string; - ledgerId?: string[]; - id?: string; - apiKey?: string; - userId?: string; - createdBy?: string; - lastChangedBy?: string; - didDoc?: string; - tenantId?: string; + did?: string + verkey?: string + isDidPublic?: boolean + agentSpinUpStatus?: AgentSpinUpStatus + walletName?: string + agentsTypeId?: string + orgId?: string + agentEndPoint?: string + agentId?: string + orgAgentTypeId?: string + ledgerId?: string[] + id?: string + apiKey?: string + userId?: string + createdBy?: string + lastChangedBy?: string + didDoc?: string + tenantId?: string } export interface LedgerNameSpace { - id: string; - createDateTime: Date; - lastChangedDateTime: Date; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - nymTxnEndpoint: string; - indyNamespace: string; - networkUrl: string; + id: string + createDateTime: Date + lastChangedDateTime: Date + name: string + networkType: string + poolConfig: string + isActive: boolean + networkString: string + nymTxnEndpoint: string + indyNamespace: string + networkUrl: string } export interface OrgDid { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - orgId: string; - isPrimaryDid: boolean; - did: string; - didDocument: Prisma.JsonValue; - orgAgentId: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + orgId: string + isPrimaryDid: boolean + did: string + didDocument: Prisma.JsonValue + orgAgentId: string } export interface ILedgers { - id: string; - createDateTime: Date; - lastChangedDateTime: Date; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - nymTxnEndpoint: string; - indyNamespace: string; - networkUrl: string; - -} \ No newline at end of file + id: string + createDateTime: Date + lastChangedDateTime: Date + name: string + networkType: string + poolConfig: string + isActive: boolean + networkString: string + nymTxnEndpoint: string + indyNamespace: string + networkUrl: string +} diff --git a/apps/agent-service/src/main.ts b/apps/agent-service/src/main.ts index 292253c1c..79656a78c 100644 --- a/apps/agent-service/src/main.ts +++ b/apps/agent-service/src/main.ts @@ -1,31 +1,29 @@ -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { NestFactory } from '@nestjs/core'; -import { AgentServiceModule } from './agent-service.module'; -import { AgentServiceService } from './agent-service.service'; -import { IAgentSpinupDto, IUserRequestInterface } from './interface/agent-service.interface'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { Ledgers } from '@credebl/enum/enum'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; - -const logger = new Logger(); +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Ledgers } from '@credebl/enum/enum' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { AgentServiceModule } from './agent-service.module' +import { AgentServiceService } from './agent-service.service' +import type { IAgentSpinupDto, IUserRequestInterface } from './interface/agent-service.interface' + +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(AgentServiceModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.AGENT_SERVICE, process.env.AGENT_SERVICE_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.AGENT_SERVICE, process.env.AGENT_SERVICE_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Agent-Service Microservice is listening to NATS '); + await app.listen() + logger.log('Agent-Service Microservice is listening to NATS ') - let user: IUserRequestInterface; + let user: IUserRequestInterface const agentSpinupPayload: IAgentSpinupDto = { walletName: process.env.PLATFORM_WALLET_NAME, @@ -38,16 +36,16 @@ async function bootstrap(): Promise { keyType: `${CommonConstants.KEYTYPE}`, method: `${CommonConstants.METHOD}`, network: `${CommonConstants.NETWORK}`, - role: `${CommonConstants.ROLE}` -}; + role: `${CommonConstants.ROLE}`, + } - const agentService = app.get(AgentServiceService); - await agentService.walletProvision(agentSpinupPayload, user); + const agentService = app.get(AgentServiceService) + await agentService.walletProvision(agentSpinupPayload, user) } process.on('unhandledRejection', (reason) => { - logger.error(reason); - process.exitCode = 1; -}); + logger.error(reason) + process.exitCode = 1 +}) -bootstrap(); \ No newline at end of file +bootstrap() diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 23537b343..3058ffc90 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -1,456 +1,463 @@ -import { PrismaService } from '@credebl/prisma-service'; -import { ConflictException, Injectable, Logger } from '@nestjs/common'; +import { AgentType, PrismaTables } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import { ConflictException, Injectable, type Logger } from '@nestjs/common' // eslint-disable-next-line camelcase -import { Prisma, ledgerConfig, ledgers, org_agents, org_agents_type, org_dids, organisation, platform_config, user } from '@prisma/client'; -import { ICreateOrgAgent, ILedgers, IOrgAgent, IOrgAgentsResponse, IOrgLedgers, IStoreAgent, IStoreDidDetails, IStoreOrgAgentDetails, LedgerNameSpace, OrgDid } from '../interface/agent-service.interface'; -import { AgentType, PrismaTables } from '@credebl/enum/enum'; +import type { + Prisma, + ledgerConfig, + ledgers, + org_agents, + org_agents_type, + org_dids, + organisation, + platform_config, + user, +} from '@prisma/client' +import type { + ICreateOrgAgent, + ILedgers, + IOrgAgent, + IOrgAgentsResponse, + IOrgLedgers, + IStoreAgent, + IStoreDidDetails, + IStoreOrgAgentDetails, + LedgerNameSpace, + OrgDid, +} from '../interface/agent-service.interface' @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 } + } - async getLedgerConfigByOrgId(): Promise { - try { - const ledgerConfigData = await this.prisma.ledgerConfig.findMany(); - return ledgerConfigData; - } 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 - } - } - }); - - return genesisData; - } catch (error) { - this.logger.error(`[getGenesisUrl] - get genesis URL: ${JSON.stringify(error)}`); - throw error; - } + async getLedgerConfigByOrgId(): Promise { + try { + const ledgerConfigData = await this.prisma.ledgerConfig.findMany() + return ledgerConfigData + } 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 { - 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; - } + 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, userId: string): Promise { - try { - - return this.prisma.org_agents.create({ - data: { - agentSpinUpStatus, - createdBy: userId, - lastChangedBy: userId - }, - select: { - id: true - } - }); - } 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 { + 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 } + } - // eslint-disable-next-line camelcase - async removeOrgAgent(id: string): Promise { - try { - if (id) { - - await 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): Promise { + try { + return this.prisma.org_agents.create({ + data: { + agentSpinUpStatus, + createdBy: userId, + lastChangedBy: userId, + }, + select: { + id: true, + }, + }) + } catch (error) { + this.logger.error(`[createOrgAgent] - create agent details: ${JSON.stringify(error)}`) + throw error } + } - // eslint-disable-next-line camelcase - async getAgentDetailsByOrgId(orgId: string): Promise { - try { - - const agentDetails = - await this.prisma.org_agents.findFirst({ - where: { - orgId - } - }); - return agentDetails; - } catch (error) { - this.logger.error(`[getAgentDetailsByOrgId] - get agent details by orgId: ${JSON.stringify(error)}`); - throw error; - } + // eslint-disable-next-line camelcase + async removeOrgAgent(id: string): Promise { + try { + if (id) { + await 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 { - const { id, userId, ledgerId, did, didDoc, ...commonFields } = storeOrgAgentDetails; - const firstLedgerId = Array.isArray(ledgerId) ? ledgerId[0] : null; - const data = { - ...commonFields, - ledgerId: firstLedgerId, - createdBy: userId, - lastChangedBy: userId, - didDocument: didDoc, - orgDid: did - }; - - // eslint-disable-next-line camelcase - const query: Promise = id ? - this.prisma.org_agents.update({ - where: { id }, - data - }) : - this.prisma.org_agents.create({ data }); - - return { id: (await query).id }; - } catch (error) { - this.logger.error(`[storeAgentDetails] - store agent details: ${JSON.stringify(error)}`); - throw error; - } + // eslint-disable-next-line camelcase + async getAgentDetailsByOrgId(orgId: string): Promise { + try { + const agentDetails = await this.prisma.org_agents.findFirst({ + where: { + orgId, + }, + }) + return agentDetails + } catch (error) { + this.logger.error(`[getAgentDetailsByOrgId] - get agent details by orgId: ${JSON.stringify(error)}`) + throw error } - - /** - * Store DID details - * @param storeDidDetails - * @returns did details - */ - // eslint-disable-next-line camelcase - async storeDidDetails(storeDidDetails: IStoreDidDetails): Promise { - try { - const {orgId, did, didDocument, isPrimaryDid, userId, orgAgentId} = storeDidDetails; - - return this.prisma.org_dids.create({ - data: { - orgId, - did, - didDocument, - isPrimaryDid, - createdBy: userId, - lastChangedBy: userId, - orgAgentId - } - }); - } catch (error) { - this.logger.error(`[storeDidDetails] - Store DID details: ${JSON.stringify(error)}`); - throw error; - } + } + + /** + * Store agent details + * @param storeAgentDetails + * @returns + */ + // eslint-disable-next-line camelcase + async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { + try { + const { id, userId, ledgerId, did, didDoc, ...commonFields } = storeOrgAgentDetails + const firstLedgerId = Array.isArray(ledgerId) ? ledgerId[0] : null + const data = { + ...commonFields, + ledgerId: firstLedgerId, + createdBy: userId, + lastChangedBy: userId, + didDocument: didDoc, + orgDid: did, + } + + // eslint-disable-next-line camelcase + const query: Promise = id + ? this.prisma.org_agents.update({ + where: { id }, + data, + }) + : this.prisma.org_agents.create({ data }) + + return { id: (await query).id } + } catch (error) { + this.logger.error(`[storeAgentDetails] - store agent details: ${JSON.stringify(error)}`) + throw error } + } + /** + * Store DID details + * @param storeDidDetails + * @returns did details + */ + // eslint-disable-next-line camelcase + async storeDidDetails(storeDidDetails: IStoreDidDetails): Promise { + try { + const { orgId, did, didDocument, isPrimaryDid, userId, orgAgentId } = storeDidDetails - /** - * Set primary DID - * @param did - * @returns did details - */ - // eslint-disable-next-line camelcase - async setPrimaryDid(orgDid: string, orgId: string, didDocument: Prisma.JsonValue): Promise { - try { - return await this.prisma.org_agents.update({ - where: { - orgId - }, - data: { - orgDid, - didDocument - } - }); - - } catch (error) { - this.logger.error(`[setprimaryDid] - Update DID details: ${JSON.stringify(error)}`); - throw error; - } + return this.prisma.org_dids.create({ + data: { + orgId, + did, + didDocument, + isPrimaryDid, + createdBy: userId, + lastChangedBy: userId, + orgAgentId, + }, + }) + } catch (error) { + this.logger.error(`[storeDidDetails] - Store DID details: ${JSON.stringify(error)}`) + throw error } + } - // eslint-disable-next-line camelcase - async updateLedgerId(orgId: string, ledgerId: string): Promise { - try { - return await this.prisma.org_agents.update({ - where: { - orgId - }, - data: { - ledgerId - } - }); - - } catch (error) { - this.logger.error(`[updateLedgerId] - Update ledgerId: ${JSON.stringify(error)}`); - throw error; - } + /** + * Set primary DID + * @param did + * @returns did details + */ + // eslint-disable-next-line camelcase + async setPrimaryDid(orgDid: string, orgId: string, didDocument: Prisma.JsonValue): Promise { + try { + return await this.prisma.org_agents.update({ + where: { + orgId, + }, + data: { + orgDid, + didDocument, + }, + }) + } catch (error) { + this.logger.error(`[setprimaryDid] - Update DID details: ${JSON.stringify(error)}`) + throw error } + } - /** - * Get agent details - * @param orgId - * @returns - */ - // eslint-disable-next-line camelcase - async getAgentDetails(orgId: string): Promise { - try { - - if (orgId) { - - return this.prisma.org_agents.findUnique({ - where: { - orgId - }, - select: { - agentSpinUpStatus: true - } - }); - } - - } catch (error) { - this.logger.error(`[getAgentDetails] - get agent details: ${JSON.stringify(error)}`); - throw error; - } + // eslint-disable-next-line camelcase + async updateLedgerId(orgId: string, ledgerId: string): Promise { + try { + return await this.prisma.org_agents.update({ + where: { + orgId, + }, + data: { + ledgerId, + }, + }) + } catch (error) { + this.logger.error(`[updateLedgerId] - Update ledgerId: ${JSON.stringify(error)}`) + throw error } + } - // eslint-disable-next-line camelcase - async platformAdminAgent(platformOrg: string): Promise { - return this.prisma.organisation.findFirstOrThrow({ - where: { - name: platformOrg - }, - select: { - // eslint-disable-next-line camelcase - org_agents: { - select: { - agentSpinUpStatus: true, - agentEndPoint: true, - apiKey: true - } - } - } - }); + /** + * Get agent details + * @param orgId + * @returns + */ + // eslint-disable-next-line camelcase + async getAgentDetails(orgId: string): Promise { + try { + if (orgId) { + return this.prisma.org_agents.findUnique({ + where: { + orgId, + }, + select: { + agentSpinUpStatus: true, + }, + }) + } + } catch (error) { + this.logger.error(`[getAgentDetails] - get agent details: ${JSON.stringify(error)}`) + throw error } + } - async getAgentTypeDetails(): Promise { - try { - const { id } = await this.prisma.agents_type.findFirstOrThrow({ - where: { - agent: AgentType.AFJ - } - }); - return id; - } catch (error) { - this.logger.error(`[getAgentTypeDetails] - get org agent health details: ${JSON.stringify(error)}`); - throw error; - } + // eslint-disable-next-line camelcase + async platformAdminAgent(platformOrg: string): Promise { + return this.prisma.organisation.findFirstOrThrow({ + where: { + name: platformOrg, + }, + select: { + // eslint-disable-next-line camelcase + org_agents: { + select: { + agentSpinUpStatus: true, + agentEndPoint: true, + apiKey: true, + }, + }, + }, + }) + } + + async getAgentTypeDetails(): Promise { + try { + const { id } = await this.prisma.agents_type.findFirstOrThrow({ + 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 { + try { + let whereClause: { name: string | { in: string[] } } - async getLedgerDetails(name: string[] | string): Promise { - try { - let whereClause; - - if (Array.isArray(name)) { - whereClause = { - name: { - in: name - } - }; - } else { - whereClause = { - name - }; - } - - const ledgersDetails = await this.prisma.ledgers.findMany({ - where: whereClause, - select: { - id: true - } - }); - return ledgersDetails; - } catch (error) { - this.logger.error(`[getLedgerDetails] - get ledger details: ${JSON.stringify(error)}`); - throw error; + if (Array.isArray(name)) { + whereClause = { + name: { + in: name, + }, + } + } else { + whereClause = { + name, } + } + + const ledgersDetails = await this.prisma.ledgers.findMany({ + where: whereClause, + select: { + id: true, + }, + }) + 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.findFirstOrThrow({ - 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.findFirstOrThrow({ + 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.findFirstOrThrow({ - 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.findFirstOrThrow({ + where: { + name: orgName, + }, + }) + return id + } catch (error) { + this.logger.error(`[getPlatfomOrg] - get platform org 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 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.findFirstOrThrow({ - 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.findFirstOrThrow({ + where: { + agent: agentType, + }, + }) + return id + } catch (error) { + this.logger.error(`[getAgentType] - get agent type 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 { - 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; - } + // eslint-disable-next-line camelcase + async getOrgAgentDetails(orgId: string): Promise { + try { + 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 } + } - // eslint-disable-next-line camelcase - async getOrgAgentType(orgAgentId: string): Promise { - try { - const orgAgent = await this.prisma.org_agents_type.findUnique({ - where: { - id: orgAgentId - } - }); - - return orgAgent; - - } catch (error) { - this.logger.error(`[getOrgAgentType] - error: ${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; - } + // eslint-disable-next-line camelcase + async getOrgAgentType(orgAgentId: string): Promise { + try { + const orgAgent = await this.prisma.org_agents_type.findUnique({ + where: { + id: orgAgentId, + }, + }) + + return orgAgent + } catch (error) { + this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`) + throw error } + } - // eslint-disable-next-line camelcase + 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 + } + } + + // eslint-disable-next-line camelcase async getAgentApiKey(orgId: string): Promise { try { if (orgId) { const agent = await this.prisma.org_agents.findUnique({ where: { - orgId - } - }); - return agent; + orgId, + }, + }) + return agent } - } catch (error) { - this.logger.error(`[getAgentApiKey] - get api key: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getAgentApiKey] - get api key: ${JSON.stringify(error)}`) + throw error } } @@ -459,15 +466,14 @@ export class AgentServiceRepository { if (indyNamespace) { const ledgerDetails = await this.prisma.ledgers.findFirstOrThrow({ where: { - indyNamespace - } - }); - return ledgerDetails; + indyNamespace, + }, + }) + return ledgerDetails } - } catch (error) { - this.logger.error(`[getLedgerByNameSpace] - get indy ledger: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getLedgerByNameSpace] - get indy ledger: ${JSON.stringify(error)}`) + throw error } } @@ -475,13 +481,13 @@ export class AgentServiceRepository { try { const orgDids = await this.prisma.org_dids.findMany({ where: { - orgId - } - }); - return orgDids; + orgId, + }, + }) + return orgDids } catch (error) { - this.logger.error(`[getOrgDid] - get org DID: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgDid] - get org DID: ${JSON.stringify(error)}`) + throw error } } @@ -489,71 +495,71 @@ export class AgentServiceRepository { try { const updateOrgDid = await this.prisma.org_dids.updateMany({ where: { - orgId + orgId, }, data: { - isPrimaryDid - } - }); - return updateOrgDid; + isPrimaryDid, + }, + }) + return updateOrgDid } catch (error) { - this.logger.error(`[getOrgDid] - get org DID: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgDid] - get org DID: ${JSON.stringify(error)}`) + throw error } } - async deleteOrgAgentByOrg(orgId: string): Promise<{orgDid: Prisma.BatchPayload; - agentInvitation: Prisma.BatchPayload; + async deleteOrgAgentByOrg(orgId: string): Promise<{ + orgDid: Prisma.BatchPayload + agentInvitation: Prisma.BatchPayload // eslint-disable-next-line camelcase - deleteOrgAgent: org_agents; - }> { - const tablesToCheck = [ - `${PrismaTables.CONNECTIONS}`, - `${PrismaTables.CREDENTIALS}`, - `${PrismaTables.PRESENTATIONS}` - ]; + deleteOrgAgent: org_agents + }> { + const tablesToCheck = [ + `${PrismaTables.CONNECTIONS}`, + `${PrismaTables.CREDENTIALS}`, + `${PrismaTables.PRESENTATIONS}`, + ] try { - return await this.prisma.$transaction(async (prisma) => { - const referenceCounts = await Promise.all( - tablesToCheck.map(table => prisma[table].count({ where: { orgId } })) - ); - - referenceCounts.forEach((count, index) => { - if (0 < count) { - throw new ConflictException(`Organization ID ${orgId} is referenced in the table ${tablesToCheck[index]}`); - } - }); - - // Concurrently delete related records - const [orgDid, agentInvitation] = await Promise.all([ - prisma.org_dids.deleteMany({ where: { orgId } }), - prisma.agent_invitations.deleteMany({ where: { orgId } }) - ]); - - // Delete the organization agent - const deleteOrgAgent = await prisma.org_agents.delete({ where: { orgId } }); - - return {orgDid, agentInvitation, deleteOrgAgent}; - }); + return await this.prisma.$transaction(async (prisma) => { + const referenceCounts = await Promise.all( + tablesToCheck.map((table) => prisma[table].count({ where: { orgId } })) + ) + + referenceCounts.forEach((count, index) => { + if (count > 0) { + throw new ConflictException(`Organization ID ${orgId} is referenced in the table ${tablesToCheck[index]}`) + } + }) + + // Concurrently delete related records + const [orgDid, agentInvitation] = await Promise.all([ + prisma.org_dids.deleteMany({ where: { orgId } }), + prisma.agent_invitations.deleteMany({ where: { orgId } }), + ]) + + // Delete the organization agent + const deleteOrgAgent = await prisma.org_agents.delete({ where: { orgId } }) + + return { orgDid, agentInvitation, deleteOrgAgent } + }) } catch (error) { - this.logger.error(`[deleteOrgAgentByOrg] - Error deleting org agent record: ${error.message}`); - throw error; + this.logger.error(`[deleteOrgAgentByOrg] - Error deleting org agent record: ${error.message}`) + throw error } -} - - async getLedger(name: string): Promise { - try { - const ledgerData = await this.prisma.ledgers.findFirstOrThrow({ - where: { - name - } - }); - return ledgerData; - } catch (error) { - this.logger.error(`[getLedger] - get org ledger: ${JSON.stringify(error)}`); - throw error; - } - } + } -} \ No newline at end of file + async getLedger(name: string): Promise { + try { + const ledgerData = await this.prisma.ledgers.findFirstOrThrow({ + where: { + name, + }, + }) + return ledgerData + } catch (error) { + this.logger.error(`[getLedger] - get org ledger: ${JSON.stringify(error)}`) + throw error + } + } +} diff --git a/apps/agent-service/test/app.e2e-spec.ts b/apps/agent-service/test/app.e2e-spec.ts index 58f95a822..cee68ac1f 100644 --- a/apps/agent-service/test/app.e2e-spec.ts +++ b/apps/agent-service/test/app.e2e-spec.ts @@ -1,24 +1,21 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { AgentServiceModule } from './../src/agent-service.module'; +import type { INestApplication } from '@nestjs/common' +import { Test, type TestingModule } from '@nestjs/testing' +import * as request from 'supertest' +import { AgentServiceModule } from './../src/agent-service.module' describe('AgentServiceController (e2e)', () => { - let app: INestApplication; + let app: INestApplication beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AgentServiceModule] - }).compile(); + imports: [AgentServiceModule], + }).compile() - app = moduleFixture.createNestApplication(); - await app.init(); - }); + app = moduleFixture.createNestApplication() + await app.init() + }) it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); - }); -}); + return request(app.getHttpServer()).get('/').expect(200).expect('Hello World!') + }) +}) diff --git a/apps/api-gateway/common/exception-handler.ts b/apps/api-gateway/common/exception-handler.ts index 674382356..b7cb8b41d 100644 --- a/apps/api-gateway/common/exception-handler.ts +++ b/apps/api-gateway/common/exception-handler.ts @@ -1,51 +1,46 @@ -import { Catch, ArgumentsHost, HttpException, HttpStatus, Logger } from '@nestjs/common'; -import { BaseExceptionFilter } from '@nestjs/core'; -import { ExceptionResponse } from './interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; +import { ResponseMessages } from '@credebl/common/response-messages' +import { type ArgumentsHost, Catch, HttpException, HttpStatus, Logger } from '@nestjs/common' +import { BaseExceptionFilter } from '@nestjs/core' +import type { ExceptionResponse } from './interface' @Catch() export class CustomExceptionFilter extends BaseExceptionFilter { - private readonly logger = new Logger(); + private readonly logger = new Logger() catch(exception: HttpException, host: ArgumentsHost): void { - const ctx = host.switchToHttp(); - const response = ctx.getResponse(); - - let errorResponse; - let status = HttpStatus.INTERNAL_SERVER_ERROR; + const ctx = host.switchToHttp() + const response = ctx.getResponse() - if (!exception || '{}' === JSON.stringify(exception)) { + let errorResponse: { statusCode: HttpStatus; message: string | string[]; error: string } + let status = HttpStatus.INTERNAL_SERVER_ERROR + + if (!exception || JSON.stringify(exception) === '{}') { errorResponse = { statusCode: status, message: 'Something went wrong!', - error: ResponseMessages.errorMessages.serverError - }; + error: ResponseMessages.errorMessages.serverError, + } } if (exception instanceof HttpException) { - status = exception.getStatus(); - + status = exception.getStatus() } - let exceptionResponse: ExceptionResponse = {} as ExceptionResponse; - const exceptionResponseData = exception.getResponse ? exception.getResponse() : exception; + let exceptionResponse: ExceptionResponse = {} as ExceptionResponse + const exceptionResponseData = exception.getResponse ? exception.getResponse() : exception - if ('string' === typeof exceptionResponseData) { - exceptionResponse.message = exceptionResponseData; + if (typeof exceptionResponseData === 'string') { + exceptionResponse.message = exceptionResponseData } else { - exceptionResponse = exceptionResponseData as unknown as ExceptionResponse; + exceptionResponse = exceptionResponseData as unknown as ExceptionResponse } - if (exceptionResponse.message && exceptionResponse.message.includes(ResponseMessages.nats.error.noSubscribers)) { - exceptionResponse.message = ResponseMessages.nats.error.noSubscribers; + if (exceptionResponse.message?.includes(ResponseMessages.nats.error.noSubscribers)) { + exceptionResponse.message = ResponseMessages.nats.error.noSubscribers } 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); + 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 d3869d75f..94bc9bea0 100644 --- a/apps/api-gateway/common/interface.ts +++ b/apps/api-gateway/common/interface.ts @@ -1,8 +1,8 @@ export interface ResponseType { - statusCode: number; - message: string; - data?: Record | string; - error?: Record | string; + statusCode: number + message: string + data?: Record | string + error?: Record | string } export interface ExceptionResponse { diff --git a/apps/api-gateway/src/agent-service/agent-service.controller.spec.ts b/apps/api-gateway/src/agent-service/agent-service.controller.spec.ts index c873b7321..71921f4fa 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.spec.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AgentController } from './agent.controller'; +import { Test, TestingModule } from '@nestjs/testing' +import { AgentController } from './agent.controller' describe('Agent Controller', () => { - let controller: AgentController; + let controller: AgentController beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - controllers: [AgentController] - }).compile(); + controllers: [AgentController], + }).compile() - controller = module.get(AgentController); - }); + controller = module.get(AgentController) + }) it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); + expect(controller).toBeDefined() + }) +}) 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 d7b4fcd34..e16233334 100644 --- a/apps/api-gateway/src/agent-service/agent-service.controller.ts +++ b/apps/api-gateway/src/agent-service/agent-service.controller.ts @@ -1,53 +1,53 @@ +import { AgentSpinupValidator, TrimStringParamPipe } from '@credebl/common/cast.helper' +import type IResponseType from '@credebl/common/interfaces/response.interface' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Validator } from '@credebl/common/validator' /* eslint-disable no-param-reassign */ /* eslint-disable camelcase */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { - Controller, - Logger, - Post, - UseGuards, BadRequestException, Body, + Controller, + Delete, + Get, HttpStatus, + Logger, + Param, + ParseUUIDPipe, + Post, Res, - Get, UseFilters, - Param, - Delete, - ParseUUIDPipe -} from '@nestjs/common'; + UseGuards, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' import { - ApiTags, - ApiResponse, + ApiBearerAuth, + ApiForbiddenResponse, ApiOperation, + ApiResponse, + ApiTags, ApiUnauthorizedResponse, - ApiForbiddenResponse, - ApiBearerAuth -} from '@nestjs/swagger'; -import { AuthGuard } from '@nestjs/passport'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -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, { 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 -import { user } from '@prisma/client'; -import { CreateTenantDto } from './dto/create-tenant.dto'; -import { User } from '../authz/decorators/user.decorator'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { Validator } from '@credebl/common/validator'; -import { CreateWalletDto } from './dto/create-wallet.dto'; -import { CreateNewDidDto } from './dto/create-new-did.dto'; -import { AgentSpinupValidator, TrimStringParamPipe } from '@credebl/common/cast.helper'; -import { AgentConfigureDto } from './dto/agent-configure.dto'; - -const seedLength = 32; +} from '@nestjs/swagger' +import type { user } from '@prisma/client' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { AgentService } from './agent-service.service' +import type { AgentConfigureDto } from './dto/agent-configure.dto' +import type { AgentSpinupDto } from './dto/agent-service.dto' +import type { CreateNewDidDto } from './dto/create-new-did.dto' +import type { CreateTenantDto } from './dto/create-tenant.dto' +import type { CreateWalletDto } from './dto/create-wallet.dto' + +const seedLength = 32 @UseFilters(CustomExceptionFilter) @Controller() @@ -57,7 +57,7 @@ const seedLength = 32; @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) export class AgentController { constructor(private readonly agentService: AgentService) {} - private readonly logger = new Logger(); + private readonly logger = new Logger() /** * Get Organization agent health @@ -69,21 +69,28 @@ export class AgentController { @Get('/orgs/:orgId/agents/health') @ApiOperation({ summary: 'Get the agent health details', - description: 'Get the agent health details for the organization' + description: 'Get the agent health details for the organization', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.HOLDER, OrgRoles.ISSUER, OrgRoles.SUPER_ADMIN, OrgRoles.MEMBER, OrgRoles.VERIFIER) - - async getAgentHealth(@Param('orgId') orgId: string, @User() reqUser: user, @Res() res: Response): Promise { - const agentData = await this.agentService.getAgentHealth(reqUser, orgId); + @Roles( + OrgRoles.OWNER, + OrgRoles.ADMIN, + OrgRoles.HOLDER, + OrgRoles.ISSUER, + OrgRoles.SUPER_ADMIN, + OrgRoles.MEMBER, + OrgRoles.VERIFIER + ) + async getAgentHealth(@Param('orgId') orgId: string, @User() reqUser: user, @Res() res: Response): Promise { + const agentData = await this.agentService.getAgentHealth(reqUser, orgId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.agent.success.health, - data: agentData - }; + data: agentData, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -95,19 +102,19 @@ export class AgentController { @Get('/orgs/agents/ledgerConfig') @ApiOperation({ summary: 'Get the ledger config details', - description: 'Get the all supported ledger configuration details for the platform' + description: 'Get the all supported ledger configuration details for the platform', }) @UseGuards(AuthGuard('jwt')) async getLedgerDetails(@User() reqUser: user, @Res() res: Response): Promise { - const ledgerConfigData = await this.agentService.getLedgerConfig(reqUser); + const ledgerConfigData = await this.agentService.getLedgerConfig(reqUser) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.agent.success.ledgerConfig, - data: ledgerConfigData - }; + data: ledgerConfigData, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -120,7 +127,7 @@ export class AgentController { @Post('/orgs/:orgId/agents/spinup') @ApiOperation({ summary: 'Spinup the platform admin agent', - description: 'Initialize and configure a new platform admin agent for the platform.' + description: 'Initialize and configure a new platform admin agent for the platform.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @@ -131,19 +138,19 @@ export class AgentController { @User() user: user, @Res() res: Response ): Promise { - AgentSpinupValidator.validate(agentSpinupDto); - this.logger.log(`**** Spin up the agent...${JSON.stringify(agentSpinupDto)}`); + AgentSpinupValidator.validate(agentSpinupDto) + this.logger.log(`**** Spin up the agent...${JSON.stringify(agentSpinupDto)}`) - agentSpinupDto.orgId = orgId; - const agentDetails = await this.agentService.agentSpinup(agentSpinupDto, user); + agentSpinupDto.orgId = orgId + const agentDetails = await this.agentService.agentSpinup(agentSpinupDto, user) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, - data: agentDetails - }; + data: agentDetails, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -157,7 +164,7 @@ export class AgentController { @Post('/orgs/:orgId/agents/wallet') @ApiOperation({ summary: 'Create Shared Agent Wallet', - description: 'Initialize and create a shared agent wallet for the organization.' + description: 'Initialize and create a shared agent wallet for the organization.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @@ -168,17 +175,17 @@ export class AgentController { @User() user: user, @Res() res: Response ): Promise { - createTenantDto.orgId = orgId; + createTenantDto.orgId = orgId - const tenantDetails = await this.agentService.createTenant(createTenantDto, user); + const tenantDetails = await this.agentService.createTenant(createTenantDto, user) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, - data: tenantDetails - }; + data: tenantDetails, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -192,7 +199,7 @@ export class AgentController { @Post('/orgs/:orgId/agents/createWallet') @ApiOperation({ summary: 'Create tenant in the agent', - description: 'Create a new wallet for the organization without storing the wallet details in the platform.' + description: 'Create a new wallet for the organization without storing the wallet details in the platform.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @@ -203,16 +210,16 @@ export class AgentController { @User() user: user, @Res() res: Response ): Promise { - createWalletDto.orgId = orgId; - const walletDetails = await this.agentService.createWallet(createWalletDto, user); + createWalletDto.orgId = orgId + const walletDetails = await this.agentService.createWallet(createWalletDto, user) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.createWallet, - data: walletDetails - }; + data: walletDetails, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -226,7 +233,7 @@ export class AgentController { @Post('/orgs/:orgId/agents/did') @ApiOperation({ summary: 'Create new DID', - description: 'Create a new DID for an organization wallet' + description: 'Create a new DID for an organization wallet', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER) @@ -237,25 +244,25 @@ export class AgentController { @User() user: user, @Res() res: Response ): Promise { - Validator.validateDid(createDidDto); + Validator.validateDid(createDidDto) if (createDidDto.seed && seedLength !== createDidDto.seed.length) { - this.logger.error(`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 - }); + description: ResponseMessages.errorMessages.badRequest, + }) } - const didDetails = await this.agentService.createDid(createDidDto, orgId, user); + const didDetails = await this.agentService.createDid(createDidDto, orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.createDid, - data: didDetails - }; + data: didDetails, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -267,21 +274,21 @@ export class AgentController { @Post('/orgs/:orgId/agents/polygon/create-keys') @ApiOperation({ summary: 'Create Secp256k1 key pair for polygon DID', - description: 'Create Secp256k1 key pair for polygon DID for an organization' + description: 'Create Secp256k1 key pair for polygon DID for an organization', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.PLATFORM_ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) async createSecp256k1KeyPair(@Param('orgId') orgId: string, @Res() res: Response): Promise { - const didDetails = await this.agentService.createSecp256k1KeyPair(orgId); + const didDetails = await this.agentService.createSecp256k1KeyPair(orgId) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.createKeys, - data: didDetails - }; + data: didDetails, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -294,7 +301,7 @@ export class AgentController { @Post('/orgs/:orgId/agents/configure') @ApiOperation({ summary: 'Configure the organization agent', - description: 'Configure the running dedicated agent for the organization using the provided configuration details.' + description: 'Configure the running dedicated agent for the organization using the provided configuration details.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @@ -305,18 +312,18 @@ export class AgentController { @User() user: user, @Res() res: Response ): Promise { - this.logger.log(`**** Configure the agent...${JSON.stringify(agentConfigureDto)}`); + this.logger.log(`**** Configure the agent...${JSON.stringify(agentConfigureDto)}`) - agentConfigureDto.orgId = orgId; - const agentDetails = await this.agentService.agentConfigure(agentConfigureDto, user); + agentConfigureDto.orgId = orgId + const agentDetails = await this.agentService.agentConfigure(agentConfigureDto, user) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.create, - data: agentDetails - }; + data: agentDetails, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -329,23 +336,32 @@ export class AgentController { @Delete('/orgs/:orgId/agents/wallet') @ApiOperation({ summary: 'Delete agent wallet', - description: 'Delete agent wallet for the organization using orgId.' + description: 'Delete agent wallet for the organization using orgId.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async deleteWallet( - @Param('orgId', TrimStringParamPipe, new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); }})) orgId: string, + @Param( + 'orgId', + TrimStringParamPipe, + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, @User() user: user, @Res() res: Response ): Promise { - await this.agentService.deleteWallet(orgId, user); + await this.agentService.deleteWallet(orgId, user) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, - message: ResponseMessages.agent.success.walletDelete - }; + message: ResponseMessages.agent.success.walletDelete, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/agent-service/agent-service.module.ts b/apps/api-gateway/src/agent-service/agent-service.module.ts index 0fa2da620..be6aa99ff 100644 --- a/apps/api-gateway/src/agent-service/agent-service.module.ts +++ b/apps/api-gateway/src/agent-service/agent-service.module.ts @@ -1,14 +1,14 @@ -import { Module } from '@nestjs/common'; -import { HttpModule } from '@nestjs/axios'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { CommonModule } from '../../../../libs/common/src/common.module'; -import { CommonService } from '../../../../libs/common/src/common.service'; -import { ConfigModule } from '@nestjs/config'; -import { AgentController } from './agent-service.controller'; -import { AgentService } from './agent-service.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { CommonModule } from '../../../../libs/common/src/common.module' +import { CommonService } from '../../../../libs/common/src/common.service' +import { AgentController } from './agent-service.controller' +import { AgentService } from './agent-service.service' @Module({ imports: [ @@ -18,13 +18,12 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.AGENT_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - + options: getNatsOptions(CommonConstants.AGENT_SERVICE, process.env.API_GATEWAY_NKEY_SEED), }, - CommonModule - ]) + CommonModule, + ]), ], controllers: [AgentController], - providers: [AgentService, CommonService, NATSClient] + providers: [AgentService, CommonService, NATSClient], }) -export class AgentModule { } +export class AgentModule {} 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 3601588f8..e4ac6438c 100644 --- a/apps/api-gateway/src/agent-service/agent-service.service.ts +++ b/apps/api-gateway/src/agent-service/agent-service.service.ts @@ -1,92 +1,90 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -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, IWalletRecord } from './interface/agent-service.interface'; -import { AgentStatus } from './interface/agent-service.interface'; -import { CreateDidDto } from './dto/create-did.dto'; -import { CreateWalletDto } from './dto/create-wallet.dto'; -import { AgentConfigureDto } from './dto/agent-configure.dto'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { user } from '@prisma/client' +import { BaseService } from 'libs/service/base.service' +import type { AgentConfigureDto } from './dto/agent-configure.dto' +import type { AgentSpinupDto } from './dto/agent-service.dto' +import type { CreateDidDto } from './dto/create-did.dto' +import type { CreateTenantDto } from './dto/create-tenant.dto' +import type { CreateWalletDto } from './dto/create-wallet.dto' +import type { AgentSpinUpSatus, IWalletRecord } from './interface/agent-service.interface' +import type { AgentStatus } from './interface/agent-service.interface' @Injectable() export class AgentService extends BaseService { - constructor( - @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy, - private readonly natsClient : NATSClient - ) { - super('AgentService'); - } - - /** - * Spinup the agent by organization - * @param agentSpinupDto - * @param user - * @returns Get agent status - */ - async agentSpinup(agentSpinupDto: AgentSpinupDto, user: user): Promise { - const payload = { agentSpinupDto, user }; - - // NATS call - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'agent-spinup', payload); - } - - async createTenant(createTenantDto: CreateTenantDto, user: user): Promise { - const payload = { createTenantDto, user }; - - // NATS call - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'create-tenant', payload); - } - - async createDid(createDidDto: CreateDidDto, orgId:string, user: user): Promise { - const payload = { createDidDto, orgId, user }; - - // NATS call - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'create-did', payload); - } - - async createWallet(createWalletDto: CreateWalletDto, user: user): Promise { - const payload = { createWalletDto, user }; - // NATS call - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'create-wallet', payload); - } - - async getAgentHealth(user: user, orgId:string): Promise { - const payload = { user, orgId }; - - // NATS call - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'agent-health', payload); - - } - - async getLedgerConfig(user: user): Promise { - const payload = { user }; - - // NATS call - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'get-ledger-config', payload); - } - - async createSecp256k1KeyPair(orgId:string): Promise { - const payload = {orgId}; - // NATS call - - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'polygon-create-keys', payload); - } - - async agentConfigure(agentConfigureDto: AgentConfigureDto, user: user): Promise { - const payload = { agentConfigureDto, user }; - // NATS call - - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'agent-configure', payload); - } - - async deleteWallet(orgId: string, user: user): Promise { - const payload = { orgId, user }; - // NATS call - - return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'delete-wallet', payload); - } - -} \ No newline at end of file + constructor( + @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('AgentService') + } + + /** + * Spinup the agent by organization + * @param agentSpinupDto + * @param user + * @returns Get agent status + */ + async agentSpinup(agentSpinupDto: AgentSpinupDto, user: user): Promise { + const payload = { agentSpinupDto, user } + + // NATS call + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'agent-spinup', payload) + } + + async createTenant(createTenantDto: CreateTenantDto, user: user): Promise { + const payload = { createTenantDto, user } + + // NATS call + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'create-tenant', payload) + } + + async createDid(createDidDto: CreateDidDto, orgId: string, user: user): Promise { + const payload = { createDidDto, orgId, user } + + // NATS call + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'create-did', payload) + } + + async createWallet(createWalletDto: CreateWalletDto, user: user): Promise { + const payload = { createWalletDto, user } + // NATS call + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'create-wallet', payload) + } + + async getAgentHealth(user: user, orgId: string): Promise { + const payload = { user, orgId } + + // NATS call + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'agent-health', payload) + } + + async getLedgerConfig(user: user): Promise { + const payload = { user } + + // NATS call + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'get-ledger-config', payload) + } + + async createSecp256k1KeyPair(orgId: string): Promise { + const payload = { orgId } + // NATS call + + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'polygon-create-keys', payload) + } + + async agentConfigure(agentConfigureDto: AgentConfigureDto, user: user): Promise { + const payload = { agentConfigureDto, user } + // NATS call + + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'agent-configure', payload) + } + + async deleteWallet(orgId: string, user: user): Promise { + const payload = { orgId, user } + // NATS call + + return this.natsClient.sendNatsMessage(this.agentServiceProxy, 'delete-wallet', payload) + } +} diff --git a/apps/api-gateway/src/agent-service/agent.service.spec.ts b/apps/api-gateway/src/agent-service/agent.service.spec.ts index 2b7709ccc..1ea9778c7 100644 --- a/apps/api-gateway/src/agent-service/agent.service.spec.ts +++ b/apps/api-gateway/src/agent-service/agent.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AgentService } from './agent.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { AgentService } from './agent.service' describe('AgentService', () => { - let service: AgentService; + let service: AgentService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [AgentService] - }).compile(); + providers: [AgentService], + }).compile() - service = module.get(AgentService); - }); + service = module.get(AgentService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/apps/api-gateway/src/agent-service/dto/agent-configure.dto.ts b/apps/api-gateway/src/agent-service/dto/agent-configure.dto.ts index a9ae783c5..5ac452f69 100644 --- a/apps/api-gateway/src/agent-service/dto/agent-configure.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/agent-configure.dto.ts @@ -1,8 +1,8 @@ -import { IsHostPortOrDomain, trim } from '@credebl/common/cast.helper'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsNotEmpty, IsString, Matches, MaxLength, MinLength } from 'class-validator'; -const regex = /^[a-zA-Z0-9 ]*$/; +import { IsHostPortOrDomain, trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsNotEmpty, IsString, Matches, MaxLength, MinLength } from 'class-validator' +const regex = /^[a-zA-Z0-9 ]*$/ export class AgentConfigureDto { @ApiProperty() @MaxLength(25, { message: 'Maximum length for wallet must be 25 characters.' }) @@ -11,20 +11,20 @@ export class AgentConfigureDto { @MinLength(2, { message: 'Minimum length for wallet name must be 2 characters.' }) @Matches(regex, { message: 'Wallet name must not contain special characters.' }) @Matches(/^\S*$/, { - message: 'Spaces are not allowed in walletName' + message: 'Spaces are not allowed in walletName', }) - walletName: string; + walletName: string @ApiProperty({ example: 'https://example.com' }) @IsString() @IsNotEmpty() @IsHostPortOrDomain() - agentEndpoint: string; + agentEndpoint: string @ApiProperty() @IsString() @IsNotEmpty() - apiKey: string; + apiKey: string - orgId: string; + orgId: string } 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 d04cce6a9..d1bdf6f28 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 @@ -1,9 +1,9 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsBoolean, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLength } from 'class-validator'; -import { CreateDidDto } from './create-did.dto'; -const regex = /^[a-zA-Z0-9 ]*$/; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsBoolean, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLength } from 'class-validator' +import { CreateDidDto } from './create-did.dto' +const regex = /^[a-zA-Z0-9 ]*$/ export class AgentSpinupDto extends CreateDidDto { @ApiProperty() @MaxLength(25, { message: 'Maximum length for wallet must be 25 characters.' }) @@ -12,31 +12,31 @@ export class AgentSpinupDto extends CreateDidDto { @MinLength(2, { message: 'Minimum length for wallet name must be 2 characters.' }) @Matches(regex, { message: 'Wallet name must not contain special characters.' }) @Matches(/^\S*$/, { - message: 'Spaces are not allowed in walletName' + message: 'Spaces are not allowed in walletName', }) - walletName: string; + walletName: string @ApiProperty() @Transform(({ value }) => trim(value)) @IsOptional() @IsString({ message: 'walletPassword must be in string format.' }) @IsNotEmpty({ message: 'Password is required.' }) - walletPassword?: string; + walletPassword?: string @ApiPropertyOptional({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'did must be in string format.' }) - did?: string; + did?: string @ApiPropertyOptional({ example: 'ojIckSD2jqNzOqIrAGzL' }) @IsOptional() - clientSocketId?: string; + clientSocketId?: string @ApiPropertyOptional({ example: true }) @IsOptional() @IsBoolean() - tenant?: boolean; - - orgId: string; + tenant?: boolean + + orgId: string } diff --git a/apps/api-gateway/src/agent-service/dto/create-did.dto.ts b/apps/api-gateway/src/agent-service/dto/create-did.dto.ts index 1dda2d25a..7836e3530 100644 --- a/apps/api-gateway/src/agent-service/dto/create-did.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/create-did.dto.ts @@ -1,71 +1,70 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { MaxLength, IsString, Matches, IsNotEmpty, IsOptional } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsNotEmpty, IsOptional, IsString, Matches, MaxLength } from 'class-validator' export class CreateDidDto { + @ApiProperty({ example: '000000000000000000000000000Seed1' }) + @MaxLength(32, { message: 'seed must be at most 32 characters.' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @ApiPropertyOptional() + @IsString({ message: 'seed must be in string format.' }) + @Matches(/^\S*$/, { + message: 'Spaces are not allowed in seed', + }) + seed?: string - @ApiProperty({ example: '000000000000000000000000000Seed1' }) - @MaxLength(32, { message: 'seed must be at most 32 characters.' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @ApiPropertyOptional() - @IsString({ message: 'seed must be in string format.' }) - @Matches(/^\S*$/, { - message: 'Spaces are not allowed in seed' - }) - seed?: string; + @ApiProperty({ example: 'ed25519' }) + @IsNotEmpty({ message: 'key type is required' }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'key type be in string format.' }) + keyType: string - @ApiProperty({ example: 'ed25519'}) - @IsNotEmpty({ message: 'key type is required' }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'key type be in string format.' }) - keyType: string; + @ApiProperty({ example: 'indy' }) + @IsNotEmpty({ message: 'method is required' }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'method must be in string format.' }) + method: string - @ApiProperty({ example: 'indy'}) - @IsNotEmpty({ message: 'method is required' }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'method must be in string format.' }) - method: string; + @ApiPropertyOptional({ example: 'bcovrin:testnet' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'network must be in string format.' }) + network?: string - @ApiPropertyOptional({example: 'bcovrin:testnet'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'network must be in string format.' }) - network?: string; + @ApiPropertyOptional({ example: 'www.github.com' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'domain must be in string format.' }) + domain?: string - @ApiPropertyOptional({example: 'www.github.com'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'domain must be in string format.' }) - domain?: string; + @ApiPropertyOptional({ example: 'endorser' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'role must be in string format.' }) + role?: string - @ApiPropertyOptional({example: 'endorser'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'role must be in string format.' }) - role?: string; + @ApiPropertyOptional({ example: '' }) + @IsOptional() + @IsString({ message: 'private key must be in string format.' }) + @Transform(({ value }) => trim(value)) + privatekey?: string - @ApiPropertyOptional({example: ''}) - @IsOptional() - @IsString({ message: 'private key must be in string format.' }) - @Transform(({ value }) => trim(value)) - privatekey?: string; + @ApiPropertyOptional({ example: 'http://localhost:6006/docs' }) + @IsOptional() + @IsString({ message: 'endpoint must be in string format.' }) + endpoint?: string - @ApiPropertyOptional({example: 'http://localhost:6006/docs'}) - @IsOptional() - @IsString({ message: 'endpoint must be in string format.' }) - endpoint?: string; + @ApiPropertyOptional({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'did must be in string format.' }) + did?: string - @ApiPropertyOptional({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'did must be in string format.' }) - did?: string; - - @ApiPropertyOptional({example: 'did:indy:bcovrin:testnet:UEeW111G1tYo1nEkPwMcF'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'endorser did must be in string format.' }) - endorserDid?: string; -} \ No newline at end of file + @ApiPropertyOptional({ example: 'did:indy:bcovrin:testnet:UEeW111G1tYo1nEkPwMcF' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'endorser did must be in string format.' }) + endorserDid?: string +} diff --git a/apps/api-gateway/src/agent-service/dto/create-new-did.dto.ts b/apps/api-gateway/src/agent-service/dto/create-new-did.dto.ts index 4ebe9e99d..847f939b0 100644 --- a/apps/api-gateway/src/agent-service/dto/create-new-did.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/create-new-did.dto.ts @@ -1,9 +1,9 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsBoolean } from 'class-validator'; -import { CreateDidDto } from './create-did.dto'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { IsBoolean } from 'class-validator' +import { CreateDidDto } from './create-did.dto' export class CreateNewDidDto extends CreateDidDto { - @ApiProperty({example: false}) - @ApiPropertyOptional() - @IsBoolean({ message: 'isPrimaryDid did must be true or false.' }) - isPrimaryDid: boolean = false; -} \ No newline at end of file + @ApiProperty({ example: false }) + @ApiPropertyOptional() + @IsBoolean({ message: 'isPrimaryDid did must be true or false.' }) + isPrimaryDid = false +} diff --git a/apps/api-gateway/src/agent-service/dto/create-schema.dto.ts b/apps/api-gateway/src/agent-service/dto/create-schema.dto.ts index f34d802ae..23b08729b 100644 --- a/apps/api-gateway/src/agent-service/dto/create-schema.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/create-schema.dto.ts @@ -1,27 +1,30 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty, IsArray } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsArray, IsNotEmpty, IsString } from 'class-validator' export class CreateTenantSchemaDto { - @ApiProperty() - @IsString({ message: 'tenantId must be a string' }) @IsNotEmpty({ message: 'please provide valid tenantId' }) - tenantId: string; - - @ApiProperty() - @IsString({ message: 'schema version must be a string' }) @IsNotEmpty({ message: 'please provide valid schema version' }) - schemaVersion: string; + @ApiProperty() + @IsString({ message: 'tenantId must be a string' }) + @IsNotEmpty({ message: 'please provide valid tenantId' }) + tenantId: string - @ApiProperty() - @IsString({ message: 'schema name must be a string' }) @IsNotEmpty({ message: 'please provide valid schema name' }) - schemaName: string; + @ApiProperty() + @IsString({ message: 'schema version must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema version' }) + schemaVersion: string - @ApiProperty() - @IsArray({ message: 'attributes must be an array' }) - @IsString({ each: true }) - @IsNotEmpty({ message: 'please provide valid attributes' }) - attributes: string[]; + @ApiProperty() + @IsString({ message: 'schema name must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema name' }) + schemaName: string - @ApiProperty() - - @IsNotEmpty({ message: 'please provide orgId' }) - orgId: string; -} \ No newline at end of file + @ApiProperty() + @IsArray({ message: 'attributes must be an array' }) + @IsString({ each: true }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + attributes: string[] + + @ApiProperty() + + @IsNotEmpty({ message: 'please provide orgId' }) + orgId: string +} 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 e26131431..bb0c2c64a 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 @@ -1,28 +1,27 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { MaxLength, IsString, MinLength, IsOptional } from 'class-validator'; -import { CreateDidDto } from './create-did.dto'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsOptional, IsString, MaxLength, MinLength } from 'class-validator' +import { CreateDidDto } from './create-did.dto' export class CreateTenantDto extends CreateDidDto { - @ApiProperty() - @MaxLength(25, { message: 'Maximum length for label must be 25 characters.' }) - @IsString({ message: 'label must be in string format.' }) - @Transform(({ value }) => trim(value)) - @MinLength(2, { message: 'Minimum length for label must be 2 characters.' }) - label: string; + @ApiProperty() + @MaxLength(25, { message: 'Maximum length for label must be 25 characters.' }) + @IsString({ message: 'label must be in string format.' }) + @Transform(({ value }) => trim(value)) + @MinLength(2, { message: 'Minimum length for label must be 2 characters.' }) + label: string - @ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' }) - @IsOptional() - @ApiPropertyOptional() - @IsString({ message: 'did must be in string format.' }) - clientSocketId?: string; + @ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' }) + @IsOptional() + @ApiPropertyOptional() + @IsString({ message: 'did must be in string format.' }) + clientSocketId?: string - @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) - @IsOptional() - @ApiPropertyOptional() - @IsString({ message: 'did must be in string format.' }) - did?: string; + @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) + @IsOptional() + @ApiPropertyOptional() + @IsString({ message: 'did must be in string format.' }) + did?: string - orgId: string; - -} \ No newline at end of file + orgId: string +} diff --git a/apps/api-gateway/src/agent-service/dto/create-wallet.dto.ts b/apps/api-gateway/src/agent-service/dto/create-wallet.dto.ts index eec4ac54c..4517ae174 100644 --- a/apps/api-gateway/src/agent-service/dto/create-wallet.dto.ts +++ b/apps/api-gateway/src/agent-service/dto/create-wallet.dto.ts @@ -1,28 +1,28 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { MaxLength, IsString, MinLength, IsNotEmpty, IsOptional } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsNotEmpty, IsOptional, IsString, MaxLength, MinLength } from 'class-validator' export class CreateWalletDto { - @ApiProperty() - @MaxLength(25, { message: 'Maximum length for label must be 25 characters.' }) - @IsString({ message: 'label must be in string format.' }) - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'label is required' }) - @MinLength(2, { message: 'Minimum length for label must be 2 characters.' }) - label: string; + @ApiProperty() + @MaxLength(25, { message: 'Maximum length for label must be 25 characters.' }) + @IsString({ message: 'label must be in string format.' }) + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'label is required' }) + @MinLength(2, { message: 'Minimum length for label must be 2 characters.' }) + label: string - @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) - @IsOptional() - @ApiPropertyOptional() - @IsString({ message: 'did must be in string format.' }) - did?: string; + @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) + @IsOptional() + @ApiPropertyOptional() + @IsString({ message: 'did must be in string format.' }) + did?: string - @ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' }) - @IsOptional() - @ApiPropertyOptional() - @IsString({ message: 'did must be in string format.' }) - clientSocketId?: string; + @ApiProperty({ example: 'ojIckSD2jqNzOqIrAGzL' }) + @IsOptional() + @ApiPropertyOptional() + @IsString({ message: 'did must be in string format.' }) + clientSocketId?: string - orgId: string; -} \ No newline at end of file + orgId: string +} diff --git a/apps/api-gateway/src/agent-service/dto/register-webhook-dto.ts b/apps/api-gateway/src/agent-service/dto/register-webhook-dto.ts index 9ae6ee72a..344b444ab 100644 --- a/apps/api-gateway/src/agent-service/dto/register-webhook-dto.ts +++ b/apps/api-gateway/src/agent-service/dto/register-webhook-dto.ts @@ -1,15 +1,14 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsNotEmpty, IsString } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsNotEmpty, IsString } from 'class-validator' export class RegisterWebhookDto { + orgId: string -orgId: string; - -@ApiProperty() -@Transform(({ value }) => trim(value)) -@IsNotEmpty({ message: 'webhookUrl is required.' }) -@IsString({ message: 'webhookUrl must be in string format.' }) -webhookUrl: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'webhookUrl is required.' }) + @IsString({ message: 'webhookUrl must be in string format.' }) + webhookUrl: string } 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 index 25511321e..6c6ff21f7 100644 --- a/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts +++ b/apps/api-gateway/src/agent-service/interface/agent-service.interface.ts @@ -1,26 +1,26 @@ export interface AgentSpinUpSatus { - agentSpinupStatus: number; + agentSpinupStatus: number } export interface AgentStatus { - label: string; - endpoints: string[]; - isInitialized: boolean; + label: string + endpoints: string[] + isInitialized: boolean } interface IWalletConfig { - id: string; - key: string; - keyDerivationMethod: string; + id: string + key: string + keyDerivationMethod: string } interface IConfig { - label: string; - walletConfig: IWalletConfig; + label: string + walletConfig: IWalletConfig } export interface IWalletRecord { - _tags: string; - metadata: string; - id: string; - createdAt: string; - config: IConfig; - updatedAt: string; -} \ No newline at end of file + _tags: string + metadata: string + id: string + createdAt: string + config: IConfig + updatedAt: string +} diff --git a/apps/api-gateway/src/agent/agent.controller.spec.ts b/apps/api-gateway/src/agent/agent.controller.spec.ts index c873b7321..71921f4fa 100644 --- a/apps/api-gateway/src/agent/agent.controller.spec.ts +++ b/apps/api-gateway/src/agent/agent.controller.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AgentController } from './agent.controller'; +import { Test, TestingModule } from '@nestjs/testing' +import { AgentController } from './agent.controller' describe('Agent Controller', () => { - let controller: AgentController; + let controller: AgentController beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - controllers: [AgentController] - }).compile(); + controllers: [AgentController], + }).compile() - controller = module.get(AgentController); - }); + controller = module.get(AgentController) + }) it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); + expect(controller).toBeDefined() + }) +}) diff --git a/apps/api-gateway/src/agent/agent.controller.ts b/apps/api-gateway/src/agent/agent.controller.ts index 164437c87..1bb413a8f 100644 --- a/apps/api-gateway/src/agent/agent.controller.ts +++ b/apps/api-gateway/src/agent/agent.controller.ts @@ -1,49 +1,58 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -/* eslint-disable no-param-reassign */ -/* eslint-disable camelcase */ -/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { CommonService } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' import { + BadRequestException, + Body, Controller, - Logger, Get, + HttpStatus, + Logger, + Param, Post, Query, - Param, - UseGuards, - BadRequestException, - Body, SetMetadata, - HttpStatus -} from '@nestjs/common'; -import { AgentService } from './agent.service'; -import { ApiTags, ApiResponse, ApiOperation, ApiQuery, ApiBearerAuth, ApiParam, ApiUnauthorizedResponse, ApiForbiddenResponse, ApiExcludeEndpoint } from '@nestjs/swagger'; -import { AuthGuard } from '@nestjs/passport'; -import { WalletDetailsDto } from '../dtos/wallet-details.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { AgentActions } from '../dtos/enums'; -import { RolesGuard } from '../authz/roles.guard'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { booleanStatus, sortValue } from '../enum'; -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'; + UseGuards, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' +import { + ApiBearerAuth, + ApiExcludeEndpoint, + ApiForbiddenResponse, + ApiOperation, + ApiParam, + ApiQuery, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import type { user } from '@prisma/client' +import { User } from '../authz/decorators/user.decorator' +import { RolesGuard } from '../authz/roles.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { AgentActions } from '../dtos/enums' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { WalletDetailsDto } from '../dtos/wallet-details.dto' +import { SortValue, booleanStatus } from '../enum' +import type { IUserRequestInterface } from '../interfaces/IUserRequestInterface' +import type { AgentService } from './agent.service' @ApiBearerAuth() @Controller('agent') export class AgentController { - constructor(private readonly agentService: AgentService, - private readonly commonService: CommonService) { } + constructor( + private readonly agentService: AgentService, + private readonly commonService: CommonService + ) {} - private readonly logger = new Logger(); + private readonly logger = new Logger() /** - * - * @param user - * @param _public - * @param verkey - * @param did + * + * @param user + * @param _public + * @param verkey + * @param did * @returns List of all the DID created for the current Cloud Agent. */ @Get('/wallet/did') @@ -58,18 +67,18 @@ export class AgentController { @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) getAllDid( - @User() user: any, + @User() user: user, @Query('_public') _public: boolean, @Query('verkey') verkey: string, @Query('did') did: string ): Promise { - this.logger.log(`**** Fetch all Did...`); - return this.agentService.getAllDid(_public, verkey, did, user); + this.logger.log('**** Fetch all Did...') + return this.agentService.getAllDid(_public, verkey, did, user) } /** - * - * @param user + * + * @param user * @returns Created DID */ @Post('/wallet/did/create') @@ -80,18 +89,16 @@ export class AgentController { @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - createLocalDid( - @User() user: any - ): Promise { - this.logger.log(`**** Create Local Did...`); - return this.agentService.createLocalDid(user); + createLocalDid(@User() user: user): Promise { + this.logger.log('**** Create Local Did...') + return this.agentService.createLocalDid(user) } /** - * - * @param walletUserDetails - * @param user - * @returns + * + * @param walletUserDetails + * @param user + * @returns */ @Post('/wallet/provision') @ApiTags('agent') @@ -99,25 +106,22 @@ export class AgentController { @SetMetadata('permissions', [CommonConstants.PERMISSION_USER_MANAGEMENT]) @ApiOperation({ summary: 'Create wallet and start ACA-Py', - description: 'Create a new wallet and spin up your Aries Cloud Agent Python by selecting your desired network.' + description: 'Create a new wallet and spin up your Aries Cloud Agent Python by selecting your desired network.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - walletProvision( - @Body() walletUserDetails: WalletDetailsDto, - @User() user: object - ): Promise { - this.logger.log(`**** Spin up the agent...${JSON.stringify(walletUserDetails)}`); + walletProvision(@Body() walletUserDetails: WalletDetailsDto, @User() user: object): Promise { + this.logger.log(`**** Spin up the agent...${JSON.stringify(walletUserDetails)}`) - const regex = new RegExp('^[a-zA-Z0-9]+$'); + const regex = /^[a-zA-Z0-9]+$/ if (!regex.test(walletUserDetails.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('Wallet name in wrong format.') + throw new BadRequestException('Please enter valid wallet name, It allows only alphanumeric values') } - const decryptedPassword = this.commonService.decryptPassword(walletUserDetails.walletPassword); - walletUserDetails.walletPassword = decryptedPassword; - return this.agentService.walletProvision(walletUserDetails, user); + const decryptedPassword = this.commonService.decryptPassword(walletUserDetails.walletPassword) + walletUserDetails.walletPassword = decryptedPassword + return this.agentService.walletProvision(walletUserDetails, user) } /** @@ -131,16 +135,14 @@ export class AgentController { @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - getPublicDid( - @User() user: any - ): Promise { - this.logger.log(`**** Fetch public Did...`); - return this.agentService.getPublicDid(user); + getPublicDid(@User() user: user): Promise { + this.logger.log('**** Fetch public Did...') + return this.agentService.getPublicDid(user) } /** * Description: Route for assign public DID - * @param did + * @param did */ @Get('/wallet/did/public/:id') @ApiTags('agent') @@ -150,49 +152,43 @@ export class AgentController { @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - assignPublicDid( - @Param('id') id: number, - @User() user: any - ): Promise { - this.logger.log(`**** Assign public DID...`); - this.logger.log(`user: ${user.orgId} == id: ${Number(id)}`); + assignPublicDid(@Param('id') id: number, @User() user: IUserRequestInterface): Promise { + this.logger.log('**** Assign public DID...') + this.logger.log(`user: ${user.orgId} == id: ${Number(id)}`) - if (user.orgId === Number(id)) { - return this.agentService.assignPublicDid(id, user); - } else { - this.logger.error(`Cannot make DID public of requested organization.`); - throw new BadRequestException(`Cannot make DID public requested organization.`); + if (id === Number(user.orgId)) { + return this.agentService.assignPublicDid(id, user) } + this.logger.error('Cannot make DID public of requested organization.') + throw new BadRequestException('Cannot make DID public requested organization.') } - /** * Description: Route for onboarding register role on ledger - * @param role - * @param alias - * @param verkey - * @param did + * @param role + * @param alias + * @param verkey + * @param did */ @Get('/ledger/register-nym/:id') @ApiTags('agent') @UseGuards(AuthGuard('jwt'), RolesGuard) @SetMetadata('permissions', [CommonConstants.PERMISSION_ORG_MGMT]) - @ApiOperation({ summary: 'Send a NYM registration to the ledger', description: 'Write the DID to the ledger to make that DID public.' }) + @ApiOperation({ + summary: 'Send a NYM registration to the ledger', + description: 'Write the DID to the ledger to make that DID public.', + }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - registerNym( - @Param('id') id: string, - @User() user: IUserRequestInterface - ): Promise { - this.logger.log(`user: ${typeof user.orgId} == id: ${typeof Number(id)}`); + registerNym(@Param('id') id: string, @User() user: IUserRequestInterface): Promise { + this.logger.log(`user: ${typeof user.orgId} == id: ${typeof Number(id)}`) if (user.orgId !== id) { - return this.agentService.registerNym(id, user); - } else { - this.logger.error(`Cannot register nym of requested organization.`); - throw new BadRequestException(`Cannot register nym of requested organization`); + return this.agentService.registerNym(id, user) } + this.logger.error('Cannot register nym of requested organization.') + throw new BadRequestException('Cannot register nym of requested organization') } @Get('/agents/:orgId/service/:action') @@ -201,14 +197,14 @@ export class AgentController { @SetMetadata('permissions', [CommonConstants.PERMISSION_PLATFORM_MANAGEMENT]) @ApiOperation({ summary: 'Restart/Stop an running Aries Agent. (Platform Admin)', - description: 'Platform Admin can restart or stop the running Aries Agent. (Platform Admin)' + description: 'Platform Admin can restart or stop the running Aries Agent. (Platform Admin)', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) @ApiParam({ name: 'action', enum: AgentActions }) restartStopAgent(@Param('orgId') orgId: string, @Param('action') action: string): Promise { - return this.agentService.restartStopAgent(action, orgId); + return this.agentService.restartStopAgent(action, orgId) } @Get('/server/status') @@ -217,14 +213,14 @@ export class AgentController { @SetMetadata('permissions', [CommonConstants.PERMISSION_CONNECTIONS]) @ApiOperation({ summary: 'Fetch Aries Cloud Agent status', - description: 'Fetch the status of the Aries Cloud Agent.' + description: 'Fetch the status of the Aries Cloud Agent.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - getAgentServerStatus(@User() user: any): Promise { - this.logger.log(`**** getPlatformConfig called...`); - return this.agentService.getAgentServerStatus(user); + getAgentServerStatus(@User() user: user): Promise { + this.logger.log('**** getPlatformConfig called...') + return this.agentService.getAgentServerStatus(user) } @Get('/ping-agent') @@ -233,11 +229,11 @@ export class AgentController { @ApiExcludeEndpoint() @ApiResponse({ status: 200, - description: 'The agent service status' + description: 'The agent service status', }) pingServiceAgent(): Promise { - this.logger.log(`**** pingServiceAgent called`); - return this.agentService.pingServiceAgent(); + this.logger.log('**** pingServiceAgent called') + return this.agentService.pingServiceAgent() } @Get('/spinup-status') @@ -246,7 +242,7 @@ export class AgentController { @SetMetadata('permissions', [CommonConstants.PERMISSION_ORG_MGMT]) @ApiOperation({ summary: 'List all Aries Cloud Agent status', - description: 'List of all created Aries Cloud Agent status.' + description: 'List of all created Aries Cloud Agent status.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -255,37 +251,37 @@ export class AgentController { @ApiQuery({ name: 'page', required: false }) @ApiQuery({ name: 'search_text', required: false }) @ApiQuery({ name: 'status', required: false }) - @ApiQuery({ name: 'sortValue', enum: sortValue, required: false }) + @ApiQuery({ name: 'sortValue', enum: SortValue, required: false }) @ApiQuery({ name: 'status', enum: booleanStatus, required: false }) agentSpinupStatus( @Query('items_per_page') items_per_page: number, @Query('page') page: number, @Query('search_text') search_text: string, - @Query('sortValue') sortValue: any, - @Query('status') status: any, - @User() user: any + @Query('sortValue') sortValue: string, + @Query('status') status: string, + @User() user: user ): Promise { + this.logger.log(`status: ${typeof status} ${status}`) - this.logger.log(`status: ${typeof status} ${status}`); - - items_per_page = items_per_page || 10; - page = page || 1; - search_text = search_text || ''; - sortValue = sortValue ? sortValue : 'DESC'; - status = status ? status : 'all'; - - let agentsStatus: any; - if ('all' === status) { - agentsStatus = 3; - } else if ('true' === status) { - agentsStatus = 2; - } else if ('false' === status) { - agentsStatus = 1; + let agentsStatus: number + if (!status || status === 'all') { + agentsStatus = 3 + } else if (status === 'true') { + agentsStatus = 2 + } else if (status === 'false') { + agentsStatus = 1 } else { - throw new BadRequestException('Invalid status received'); + throw new BadRequestException('Invalid status received') } - this.logger.log(`**** agentSpinupStatus called`); - return this.agentService.agentSpinupStatus(items_per_page, page, search_text, agentsStatus, sortValue, user); + this.logger.log('**** agentSpinupStatus called') + return this.agentService.agentSpinupStatus( + items_per_page ?? 10, + page ?? 1, + search_text ?? '', + agentsStatus, + sortValue ? sortValue : 'DESC', + user + ) } } diff --git a/apps/api-gateway/src/agent/agent.module.ts b/apps/api-gateway/src/agent/agent.module.ts index a077d3615..4a06e84fd 100644 --- a/apps/api-gateway/src/agent/agent.module.ts +++ b/apps/api-gateway/src/agent/agent.module.ts @@ -1,13 +1,13 @@ -import { Module } from '@nestjs/common'; -import { HttpModule } from '@nestjs/axios'; -import { AgentController } from './agent.controller'; -import { AgentService } from './agent.service'; -import { ClientsModule } from '@nestjs/microservices'; -import { CommonModule } from '../../../../libs/common/src/common.module'; -import { CommonService } from '../../../../libs/common/src/common.service'; -import { ConfigModule } from '@nestjs/config'; -import { commonNatsOptions } from 'libs/service/nats.options'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule } from '@nestjs/microservices' +import { commonNatsOptions } from 'libs/service/nats.options' +import { CommonModule } from '../../../../libs/common/src/common.module' +import { CommonService } from '../../../../libs/common/src/common.service' +import { AgentController } from './agent.controller' +import { AgentService } from './agent.service' @Module({ imports: [ @@ -16,12 +16,12 @@ import { NATSClient } from '@credebl/common/NATSClient'; ClientsModule.register([ { name: 'NATS_CLIENT', - ...commonNatsOptions('AGENT_SERVICE:REQUESTER') + ...commonNatsOptions('AGENT_SERVICE:REQUESTER'), }, - CommonModule - ]) + CommonModule, + ]), ], controllers: [AgentController], - providers: [AgentService, CommonService, NATSClient] + providers: [AgentService, CommonService, NATSClient], }) -export class AgentModule { } +export class AgentModule {} diff --git a/apps/api-gateway/src/agent/agent.service.spec.ts b/apps/api-gateway/src/agent/agent.service.spec.ts index 2b7709ccc..1ea9778c7 100644 --- a/apps/api-gateway/src/agent/agent.service.spec.ts +++ b/apps/api-gateway/src/agent/agent.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AgentService } from './agent.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { AgentService } from './agent.service' describe('AgentService', () => { - let service: AgentService; + let service: AgentService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [AgentService] - }).compile(); + providers: [AgentService], + }).compile() - service = module.get(AgentService); - }); + service = module.get(AgentService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/apps/api-gateway/src/agent/agent.service.ts b/apps/api-gateway/src/agent/agent.service.ts index 7b4b63602..f5680dad0 100644 --- a/apps/api-gateway/src/agent/agent.service.ts +++ b/apps/api-gateway/src/agent/agent.service.ts @@ -3,100 +3,106 @@ /* eslint-disable no-return-await */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from 'libs/service/base.service' -import { WalletDetailsDto } from '../dtos/wallet-details.dto'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { user } from '@prisma/client' +import type { WalletDetailsDto } from '../dtos/wallet-details.dto' +import type { IUserRequestInterface } from '../interfaces/IUserRequestInterface' @Injectable() export class AgentService extends BaseService { - constructor( - @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy, - private readonly natsClient : NATSClient - ) { - super('AgentService'); - } + constructor( + @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('AgentService') + } + /** + * Description: Calling agent service for get-all-did + * @param _public + * @param verkey + * @param did + */ + getAllDid(_public: boolean, verkey: string, did: string, user: user) { + this.logger.log('**** getAllDid called...') + const payload = { _public, verkey, did, user } + return this.natsClient.sendNats(this.agentServiceProxy, 'get-all-did', payload) + } - /** - * Description: Calling agent service for get-all-did - * @param _public - * @param verkey - * @param did - */ - getAllDid(_public: boolean, verkey: string, did: string, user: any) { - this.logger.log('**** getAllDid called...'); - const payload = { _public, verkey, did, user }; - return this.natsClient.sendNats(this.agentServiceProxy, 'get-all-did', payload); - } + /** + * Description: Calling agent service for create-local-did + */ + createLocalDid(user: user) { + this.logger.log('**** createLocalDid called...') + return this.natsClient.sendNats(this.agentServiceProxy, 'create-local-did', user) + } - /** - * Description: Calling agent service for create-local-did - */ - createLocalDid(user: any) { - this.logger.log('**** createLocalDid called...'); - return this.natsClient.sendNats(this.agentServiceProxy, 'create-local-did', user); - } + async walletProvision(walletUserDetails: WalletDetailsDto, user: user) { + this.logger.log(`**** walletProvision called...${JSON.stringify(walletUserDetails)}`) + const payload = { walletUserDetails, user } + return await this.natsClient.sendNats(this.agentServiceProxy, 'wallet-provision', payload) + } - async walletProvision(walletUserDetails: WalletDetailsDto, user: any) { - this.logger.log(`**** walletProvision called...${JSON.stringify(walletUserDetails)}`); - const payload = { walletUserDetails, user }; - return await this.natsClient.sendNats(this.agentServiceProxy, 'wallet-provision', payload); - } + /** + * Description: Calling agent service for get-public-did + */ + getPublicDid(user: user) { + this.logger.log('**** getPublicDid called...') + return this.natsClient.sendNats(this.agentServiceProxy, 'get-public-did', user) + } - /** - * Description: Calling agent service for get-public-did - */ - getPublicDid(user: any) { - this.logger.log('**** getPublicDid called...'); - return this.natsClient.sendNats(this.agentServiceProxy, 'get-public-did', user); - } + /** + * Description: Calling agent service for assign-public-did + * @param did + */ + assignPublicDid(id: number, user: user) { + this.logger.log('**** assignPublicDid called...') + const payload = { id, user } + return this.natsClient.sendNats(this.agentServiceProxy, 'assign-public-did-org', payload) + } - /** - * Description: Calling agent service for assign-public-did - * @param did - */ - assignPublicDid(id: number, user: any) { - this.logger.log('**** assignPublicDid called...'); - const payload = { id, user }; - return this.natsClient.sendNats(this.agentServiceProxy, 'assign-public-did-org', payload); - } + /** + * Description: Calling agent service for onboard-register-ledger + * @param role + * @param alias + * @param verkey + * @param did + */ + registerNym(id: string, user: IUserRequestInterface) { + this.logger.log('**** registerNym called...') + const payload = { id, user } + return this.natsClient.sendNats(this.agentServiceProxy, 'register-nym-org', payload) + } + restartStopAgent(action: string, orgId: string) { + const payload = { action, orgId } + return this.natsClient.sendNats(this.agentServiceProxy, 'restart-stop-agent', payload) + } - /** - * Description: Calling agent service for onboard-register-ledger - * @param role - * @param alias - * @param verkey - * @param did - */ - registerNym(id: string, user: any) { - this.logger.log('**** registerNym called...'); - const payload = { id, user }; - return this.natsClient.sendNats(this.agentServiceProxy, 'register-nym-org', payload); - } + getAgentServerStatus(user) { + return this.natsClient.sendNats(this.agentServiceProxy, 'get-agent-server-status', user) + } - restartStopAgent(action: string, orgId: string) { - const payload = { action, orgId }; - return this.natsClient.sendNats(this.agentServiceProxy, 'restart-stop-agent', payload); - } + pingServiceAgent() { + this.logger.log('**** pingServiceAgent called...') + const payload = {} + return this.natsClient.sendNats(this.agentServiceProxy, 'ping-agent', payload) + } - getAgentServerStatus(user) { - - return this.natsClient.sendNats(this.agentServiceProxy, 'get-agent-server-status', user); - } - - pingServiceAgent() { - this.logger.log('**** pingServiceAgent called...'); - const payload = {}; - return this.natsClient.sendNats(this.agentServiceProxy, 'ping-agent', payload); - } - - agentSpinupStatus(items_per_page: number, page: number, search_text: string, agentStatus: string, sortValue: string, user: any) { - this.logger.log('**** agentSpinupStatus called...'); - const payload = { items_per_page, page, search_text, agentStatus, sortValue, user }; - return this.natsClient.sendNats(this.agentServiceProxy, 'get-agent-spinup-status', payload); - } + agentSpinupStatus( + items_per_page: number, + page: number, + search_text: string, + agentStatus: number, + sortValue: string, + user: user + ) { + this.logger.log('**** agentSpinupStatus called...') + const payload = { items_per_page, page, search_text, agentStatus, sortValue, user } + return this.natsClient.sendNats(this.agentServiceProxy, 'get-agent-spinup-status', payload) + } } diff --git a/apps/api-gateway/src/app.controller.spec.ts b/apps/api-gateway/src/app.controller.spec.ts index a37961341..b9c7365df 100644 --- a/apps/api-gateway/src/app.controller.spec.ts +++ b/apps/api-gateway/src/app.controller.spec.ts @@ -1,17 +1,16 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { AppController } from './app.controller' +import { AppService } from './app.service' describe('AppController', () => { - let appController: AppController; + let _appController: AppController beforeEach(async () => { const app: TestingModule = await Test.createTestingModule({ controllers: [AppController], - providers: [AppService] - }).compile(); + providers: [AppService], + }).compile() - appController = app.get(AppController); - }); - -}); + _appController = app.get(AppController) + }) +}) diff --git a/apps/api-gateway/src/app.controller.ts b/apps/api-gateway/src/app.controller.ts index a778b44ba..3881d6a14 100644 --- a/apps/api-gateway/src/app.controller.ts +++ b/apps/api-gateway/src/app.controller.ts @@ -1,10 +1,10 @@ -import { Controller, Logger } from '@nestjs/common'; -import { ApiBearerAuth } from '@nestjs/swagger'; -import { AppService } from './app.service'; +import { Controller, Logger } from '@nestjs/common' +import { ApiBearerAuth } from '@nestjs/swagger' +import type { AppService } from './app.service' @Controller() @ApiBearerAuth() -export class AppController { - constructor(private readonly appService: AppService) {} +export class AppController { + constructor(private readonly appService: AppService) {} - private readonly logger = new Logger('AppController'); + private readonly logger = new Logger('AppController') } diff --git a/apps/api-gateway/src/app.module.ts b/apps/api-gateway/src/app.module.ts index 9994df54d..d663db7dd 100644 --- a/apps/api-gateway/src/app.module.ts +++ b/apps/api-gateway/src/app.module.ts @@ -1,37 +1,37 @@ -import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; -import { AgentController } from './agent/agent.controller'; -import { AgentModule } from './agent-service/agent-service.module'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; -import { AuthzMiddleware } from './authz/authz.middleware'; -import { AuthzModule } from './authz/authz.module'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { ConfigModule } from '@nestjs/config'; -import { CredentialDefinitionModule } from './credential-definition/credential-definition.module'; -import { FidoModule } from './fido/fido.module'; -import { IssuanceModule } from './issuance/issuance.module'; -import { OrganizationModule } from './organization/organization.module'; -import { PlatformModule } from './platform/platform.module'; -import { VerificationModule } from './verification/verification.module'; -import { RevocationController } from './revocation/revocation.controller'; -import { RevocationModule } from './revocation/revocation.module'; -import { SchemaModule } from './schema/schema.module'; +import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextModule } from '@credebl/context/contextModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { CacheModule } from '@nestjs/cache-manager' +import { type MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import * as redisStore from 'cache-manager-redis-store' +import { AgentModule } from './agent-service/agent-service.module' +import { AgentController } from './agent/agent.controller' +import { AppController } from './app.controller' +import { AppService } from './app.service' +import { AuthzMiddleware } from './authz/authz.middleware' +import { AuthzModule } from './authz/authz.module' +import { CloudWalletModule } from './cloud-wallet/cloud-wallet.module' +import { ConnectionModule } from './connection/connection.module' +import { CredentialDefinitionModule } from './credential-definition/credential-definition.module' +import { FidoModule } from './fido/fido.module' +import { GeoLocationModule } from './geo-location/geo-location.module' +import { IssuanceModule } from './issuance/issuance.module' +import { NotificationModule } from './notification/notification.module' +import { OrganizationModule } from './organization/organization.module' +import { PlatformModule } from './platform/platform.module' +import { RevocationController } from './revocation/revocation.controller' +import { RevocationModule } from './revocation/revocation.module' +import { SchemaModule } from './schema/schema.module' // import { commonNatsOptions } from 'libs/service/nats.options'; -import { UserModule } from './user/user.module'; -import { ConnectionModule } from './connection/connection.module'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CacheModule } from '@nestjs/cache-manager'; -import * as redisStore from 'cache-manager-redis-store'; -import { WebhookModule } from './webhook/webhook.module'; -import { UtilitiesModule } from './utilities/utilities.module'; -import { NotificationModule } from './notification/notification.module'; -import { GeoLocationModule } from './geo-location/geo-location.module'; -import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; -import { CloudWalletModule } from './cloud-wallet/cloud-wallet.module'; -import { ContextModule } from '@credebl/context/contextModule'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; +import { UserModule } from './user/user.module' +import { UtilitiesModule } from './utilities/utilities.module' +import { VerificationModule } from './verification/verification.module' +import { WebhookModule } from './webhook/webhook.module' @Module({ imports: [ @@ -43,8 +43,8 @@ import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.API_GATEWAY_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.API_GATEWAY_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, ]), AgentModule, PlatformModule, @@ -64,16 +64,16 @@ import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; GlobalConfigModule, CacheModule.register({ store: redisStore, host: process.env.REDIS_HOST, port: process.env.REDIS_PORT }), GeoLocationModule, - CloudWalletModule + CloudWalletModule, ], controllers: [AppController], providers: [ AppService, { provide: MICRO_SERVICE_NAME, - useValue: 'APIGATEWAY' - } - ] + useValue: 'APIGATEWAY', + }, + ], }) export class AppModule { configure(userContext: MiddlewareConsumer): void { @@ -109,6 +109,6 @@ export class AppModule { 'issue-credentials/national-id', 'labels/:id' ) - .forRoutes(AgentController, RevocationController); + .forRoutes(AgentController, RevocationController) } } diff --git a/apps/api-gateway/src/app.service.ts b/apps/api-gateway/src/app.service.ts index 095adb165..2e5bc03a5 100644 --- a/apps/api-gateway/src/app.service.ts +++ b/apps/api-gateway/src/app.service.ts @@ -1,12 +1,10 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from '../../../libs/service/base.service'; +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from '../../../libs/service/base.service' @Injectable() export class AppService extends BaseService { - constructor( - @Inject('NATS_CLIENT') private readonly appServiceProxy: ClientProxy - ) { - super('appService'); - } + constructor(@Inject('NATS_CLIENT') private readonly appServiceProxy: ClientProxy) { + super('appService') + } } diff --git a/apps/api-gateway/src/authz/authz.controller.ts b/apps/api-gateway/src/authz/authz.controller.ts index 5821d6bed..28b1b392b 100644 --- a/apps/api-gateway/src/authz/authz.controller.ts +++ b/apps/api-gateway/src/authz/authz.controller.ts @@ -1,3 +1,5 @@ +import type IResponseType from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' import { Body, Controller, @@ -9,221 +11,218 @@ import { Query, Res, UnauthorizedException, - UseFilters -} from '@nestjs/common'; -import { AuthzService } from './authz.service'; -import { CommonService } from '../../../../libs/common/src/common.service'; -import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UserEmailVerificationDto } from '../user/dto/create-user.dto'; -import IResponseType from '@credebl/common/interfaces/response.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -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 { AddUserDetailsDto } from '../user/dto/add-user.dto'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { ResetPasswordDto } from './dtos/reset-password.dto'; -import { ForgotPasswordDto } from './dtos/forgot-password.dto'; -import { ResetTokenPasswordDto } from './dtos/reset-token-password'; -import { RefreshTokenDto } from './dtos/refresh-token.dto'; - + UseFilters, +} from '@nestjs/common' +import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import type { CommonService } from '../../../../libs/common/src/common.service' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import type { AddUserDetailsDto } from '../user/dto/add-user.dto' +import type { UserEmailVerificationDto } from '../user/dto/create-user.dto' +import type { EmailVerificationDto } from '../user/dto/email-verify.dto' +import { LoginUserDto } from '../user/dto/login-user.dto' +import type { AuthzService } from './authz.service' +import { AuthTokenResponse } from './dtos/auth-token-res.dto' +import type { ForgotPasswordDto } from './dtos/forgot-password.dto' +import type { RefreshTokenDto } from './dtos/refresh-token.dto' +import type { ResetPasswordDto } from './dtos/reset-password.dto' +import type { ResetTokenPasswordDto } from './dtos/reset-token-password' @Controller('auth') @ApiTags('auth') @UseFilters(CustomExceptionFilter) export class AuthzController { - private logger = new Logger('AuthzController'); + private logger = new Logger('AuthzController') - constructor(private readonly authzService: AuthzService, - private readonly commonService: CommonService) { } + constructor( + private readonly authzService: AuthzService, + private readonly commonService: CommonService + ) {} /** * Verify user’s email address. - * + * * @param email The email address of the user. * @param verificationcode The verification code sent to the user's email. - * @returns Returns the email verification status. + * @returns Returns the email verification status. */ @Get('/verify') @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - @ApiOperation({ summary: 'Verify user’s email', description: 'Checks if the provided verification code is valid for the given email.' }) + @ApiOperation({ + summary: 'Verify user’s email', + description: 'Checks if the provided verification code is valid for the given email.', + }) async verifyEmail(@Query() query: EmailVerificationDto, @Res() res: Response): Promise { - await this.authzService.verifyEmail(query); + await this.authzService.verifyEmail(query) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.emaiVerified - }; + message: ResponseMessages.user.success.emaiVerified, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** - * Sends a verification email to the user. - * - * @body UserEmailVerificationDto. - * @returns The status of the verification email. - */ + * Sends a verification email to the user. + * + * @body UserEmailVerificationDto. + * @returns The status of the verification email. + */ @Post('/verification-mail') @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) @ApiOperation({ summary: 'Send verification email', description: 'Send verification email to new user' }) async create(@Body() userEmailVerification: UserEmailVerificationDto, @Res() res: Response): Promise { - await this.authzService.sendVerificationMail(userEmailVerification); + await this.authzService.sendVerificationMail(userEmailVerification) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, - message: ResponseMessages.user.success.sendVerificationCode - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + message: ResponseMessages.user.success.sendVerificationCode, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** - * Registers a new user on the platform. - * - * @body AddUserDetailsDto - * @returns User's registration status and user details - */ + * Registers a new user on the platform. + * + * @body AddUserDetailsDto + * @returns User's registration status and user details + */ @Post('/signup') @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) - @ApiOperation({ summary: 'Register new user to platform', description: 'Register new user to platform with the provided details.' }) + @ApiOperation({ + summary: 'Register new user to platform', + description: 'Register new user to platform with the provided details.', + }) async addUserDetails(@Body() userInfo: AddUserDetailsDto, @Res() res: Response): Promise { - const userData = await this.authzService.addUserDetails(userInfo); - const finalResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.user.success.create, - data: userData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); - + const userData = await this.authzService.addUserDetails(userInfo) + const finalResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.user.success.create, + data: userData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** - * Authenticates a user and returns an access token. - * - * @body LoginUserDto - * @returns User's access token details - */ + * Authenticates a user and returns an access token. + * + * @body LoginUserDto + * @returns User's access token details + */ @Post('/signin') @ApiOperation({ summary: 'Authenticate the user for the access', - description: 'Allows registered user to sign.' + description: 'Allows registered user to sign.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: AuthTokenResponse }) @ApiBody({ type: LoginUserDto }) async login(@Body() loginUserDto: LoginUserDto, @Res() res: Response): Promise { - if (loginUserDto.email) { - const userData = await this.authzService.login(loginUserDto.email, loginUserDto.password); + const userData = await this.authzService.login(loginUserDto.email, loginUserDto.password) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.login, - data: userData - }; + data: userData, + } - return res.status(HttpStatus.OK).json(finalResponse); - } else { - throw new UnauthorizedException(`Please provide valid credentials`); + return res.status(HttpStatus.OK).json(finalResponse) } + throw new UnauthorizedException('Please provide valid credentials') } - /** - * Resets user's password. - * - * @body ResetPasswordDto - * @returns The password reset status. - */ + * Resets user's password. + * + * @body ResetPasswordDto + * @returns The password reset status. + */ @Post('/reset-password') @ApiOperation({ summary: 'Reset password', - description: 'Allows users to reset a new password which should be different form existing password.' - }) + description: 'Allows users to reset a new password which should be different form existing password.', + }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async resetPassword(@Body() resetPasswordDto: ResetPasswordDto, @Res() res: Response): Promise { - - const userData = await this.authzService.resetPassword(resetPasswordDto); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.resetPassword, - data: userData - }; - return res.status(HttpStatus.OK).json(finalResponse); + const userData = await this.authzService.resetPassword(resetPasswordDto) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.user.success.resetPassword, + data: userData, + } + return res.status(HttpStatus.OK).json(finalResponse) } -/** - * Initiates the password reset process by sending a reset link to the user's email. - * - * @body ForgotPasswordDto - * @returns Status message indicating whether the reset link was sent successfully. - */ + /** + * Initiates the password reset process by sending a reset link to the user's email. + * + * @body ForgotPasswordDto + * @returns Status message indicating whether the reset link was sent successfully. + */ @Post('/forgot-password') @ApiOperation({ summary: 'Forgot password', - description: 'Sends a password reset link to the user’s email.' + description: 'Sends a password reset link to the user’s email.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async forgotPassword(@Body() forgotPasswordDto: ForgotPasswordDto, @Res() res: Response): Promise { - const userData = await this.authzService.forgotPassword(forgotPasswordDto); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.resetPasswordLink, - data: userData - }; + const userData = await this.authzService.forgotPassword(forgotPasswordDto) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.user.success.resetPasswordLink, + data: userData, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } -/** - * Resets the user's password using a verification token. - * - * @param email The email address of the user. - * @body ResetTokenPasswordDto - * @returns Status message indicating whether the password reset was successful. - */ + /** + * Resets the user's password using a verification token. + * + * @param email The email address of the user. + * @body ResetTokenPasswordDto + * @returns Status message indicating whether the password reset was successful. + */ @Post('/password-reset/:email') @ApiOperation({ summary: 'Reset password with verification token', - description: 'Resets a user’s password using a verification token sent to their email' + description: 'Resets a user’s password using a verification token sent to their email', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async resetNewPassword( @Param('email') email: string, @Body() resetTokenPasswordDto: ResetTokenPasswordDto, - @Res() res: Response): Promise { - resetTokenPasswordDto.email = email.trim(); - const userData = await this.authzService.resetNewPassword(resetTokenPasswordDto); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.resetPassword, - data: userData - }; - return res.status(HttpStatus.OK).json(finalResponse); + @Res() res: Response + ): Promise { + resetTokenPasswordDto.email = email.trim() + const userData = await this.authzService.resetNewPassword(resetTokenPasswordDto) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.user.success.resetPassword, + data: userData, + } + return res.status(HttpStatus.OK).json(finalResponse) } -/** - * Generates a new access token using a refresh token. - * - * @body RefreshTokenDto - * @returns New access token and its details. - */ + /** + * Generates a new access token using a refresh token. + * + * @body RefreshTokenDto + * @returns New access token and its details. + */ @Post('/refresh-token') @ApiOperation({ summary: 'Token from refresh token', - description: 'Generates a new access token using a refresh token.' + description: 'Generates a new access token using a refresh token.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async refreshToken( - @Body() refreshTokenDto: RefreshTokenDto, - @Res() res: Response): Promise { - const tokenData = await this.authzService.refreshToken(refreshTokenDto.refreshToken); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.refreshToken, - data: tokenData - }; + async refreshToken(@Body() refreshTokenDto: RefreshTokenDto, @Res() res: Response): Promise { + const tokenData = await this.authzService.refreshToken(refreshTokenDto.refreshToken) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.user.success.refreshToken, + data: tokenData, + } - return res.status(HttpStatus.OK).json(finalResponse); - + return res.status(HttpStatus.OK).json(finalResponse) } - -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/authz/authz.middleware.ts b/apps/api-gateway/src/authz/authz.middleware.ts index fd961a937..783c2bedc 100644 --- a/apps/api-gateway/src/authz/authz.middleware.ts +++ b/apps/api-gateway/src/authz/authz.middleware.ts @@ -1,23 +1,17 @@ /* eslint-disable camelcase */ -import { - HttpException, - Injectable, - Logger, - NestMiddleware, - UnauthorizedException -} from '@nestjs/common'; - -import { AuthzService } from './authz.service'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { ExtractJwt } from 'passport-jwt'; -import { JwtService } from '@nestjs/jwt'; -import { NextFunction } from 'express'; -import { RequestingUser } from './dtos/requesting-user.dto'; +import { HttpException, Injectable, Logger, type NestMiddleware, UnauthorizedException } from '@nestjs/common' + +import { CommonConstants } from '@credebl/common/common.constant' +import { JwtService } from '@nestjs/jwt' +import type { NextFunction } from 'express' +import { ExtractJwt } from 'passport-jwt' +import type { AuthzService } from './authz.service' +import { RequestingUser } from './dtos/requesting-user.dto' @Injectable() export class AuthzMiddleware implements NestMiddleware { - constructor(private readonly authService: AuthzService) { } - private readonly logger = new Logger('AuthzMiddleware'); + constructor(private readonly authService: AuthzService) {} + private readonly logger = new Logger('AuthzMiddleware') /** * Decodes and extracts the payload from the token @@ -27,105 +21,99 @@ export class AuthzMiddleware implements NestMiddleware { * @throws UnauthorizedException If the token is not found */ getPayload = (token: string): unknown => { - if (!token) { - throw new UnauthorizedException( - 'Authorization header does not contain a token' - ); + throw new UnauthorizedException('Authorization header does not contain a token') } // ignore options since we don't need to verify here - const jwtService = new JwtService({}); - const decoded = jwtService.decode(token, { complete: true }); + const jwtService = new JwtService({}) + const decoded = jwtService.decode(token, { complete: true }) if (!decoded) { - throw new UnauthorizedException( - 'Authorization header contains an invalid token' - ); + throw new UnauthorizedException('Authorization header contains an invalid token') } - return decoded['payload']; - }; + // TODO: add type to decoded + // biome-ignore lint/complexity/useLiteralKeys: + return decoded['payload'] + } - async use(req: Request, res: Response, next: NextFunction): Promise { + async use(req: Request, _res: Response, next: NextFunction): Promise { // get token and decode or any custom auth logic try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const token = ExtractJwt.fromAuthHeaderAsBearerToken()(req as any); - let payload; + // biome-ignore lint/suspicious/noExplicitAny: + const token = ExtractJwt.fromAuthHeaderAsBearerToken()(req as any) + let payload: unknown try { - payload = this.getPayload(token); + payload = this.getPayload(token) } catch (error) { - this.logger.log(`Caught error while parsing payload: ${error}`); - next(error); - return; + this.logger.log(`Caught error while parsing payload: ${error}`) + next(error) + return } - const requestor = new RequestingUser(); - const tenant = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response; - + const requestor = new RequestingUser() + // biome-ignore lint/complexity/useLiteralKeys: + const tenant = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response + if (tenant) { - this.logger.log(`tenant this.authService.getUserByKeycloakUserId: ${tenant.keycloakUserId}`); - this.logger.log(`tenant id: ${tenant.id}`); + this.logger.log(`tenant this.authService.getUserByKeycloakUserId: ${tenant.keycloakUserId}`) + this.logger.log(`tenant id: ${tenant.id}`) - requestor.tenant_name = `${tenant.firstName} ${tenant.lastName}`; - requestor.tenant_id = tenant.id; - requestor.userRoleOrgPermissions = tenant.userRoleOrgMap; - requestor.orgId = tenant.userRoleOrgMap[0].organization.id; - requestor.apiKey = tenant.userRoleOrgMap[0].organization.apiKey; - requestor.agentEndPoint = tenant.userRoleOrgMap[0].organization.agentEndPoint; + requestor.tenant_name = `${tenant.firstName} ${tenant.lastName}` + requestor.tenant_id = tenant.id + requestor.userRoleOrgPermissions = tenant.userRoleOrgMap + requestor.orgId = tenant.userRoleOrgMap[0].organization.id + requestor.apiKey = tenant.userRoleOrgMap[0].organization.apiKey + requestor.agentEndPoint = tenant.userRoleOrgMap[0].organization.agentEndPoint - let tenantOrgInfo; + let tenantOrgInfo: { id: string } for (const item of tenant.userRoleOrgMap) { - this.logger.log(`${JSON.stringify(item.organization.orgRole)}`); - - if (item.organization.orgRole.id == CommonConstants.ORG_TENANT_ROLE) { - this.logger.log(`In Tenant Org matched id : ${item.organization.id}`); - tenantOrgInfo = item.organization; + this.logger.log(`${JSON.stringify(item.organization.orgRole)}`) + if (item.organization.orgRole.id === CommonConstants.ORG_TENANT_ROLE) { + this.logger.log(`In Tenant Org matched id : ${item.organization.id}`) + tenantOrgInfo = item.organization } } - if (null != tenantOrgInfo) { - requestor.tenantOrgId = tenantOrgInfo.id; + if (tenantOrgInfo != null) { + requestor.tenantOrgId = tenantOrgInfo.id } + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (payload.hasOwnProperty('clientId')) { - this.logger.log(`tenant requestor.permissions: ${JSON.stringify(requestor)}`); + this.logger.log(`tenant requestor.permissions: ${JSON.stringify(requestor)}`) } else { - requestor.email = payload['email']; + // biome-ignore lint/complexity/useLiteralKeys: + requestor.email = payload['email'] - const userData - = ( - await this.authService.getUserByKeycloakUserId(payload['sub']) - )?.response; + // biome-ignore lint/complexity/useLiteralKeys: + const userData = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response - this.logger.debug(`User by keycloak ID ${userData.id}`); + this.logger.debug(`User by keycloak ID ${userData.id}`) - requestor.userId = userData?.id; - requestor.name = `${userData.firstName} ${userData.lastName}`; + requestor.userId = userData?.id + requestor.name = `${userData.firstName} ${userData.lastName}` - if (null != userData?.organization) { - this.logger.log(`Org Not Null: ${userData?.organization.Id} `); - requestor.orgId = userData?.organization.id; + if (userData?.organization != null) { + this.logger.log(`Org Not Null: ${userData?.organization.Id} `) + requestor.orgId = userData?.organization.id } - this.logger.log(` user id ${userData.id}`); + this.logger.log(` user id ${userData.id}`) } } - req['requestor'] = requestor; + // biome-ignore lint/complexity/useLiteralKeys: + req['requestor'] = requestor - next(); + next() } catch (error) { - this.logger.error( - `RequestorMiddleware Error in middleware: ${error} ${JSON.stringify( - error - )}` - ); - next(new HttpException(error, 500)); + this.logger.error(`RequestorMiddleware Error in middleware: ${error} ${JSON.stringify(error)}`) + next(new HttpException(error, 500)) } } } diff --git a/apps/api-gateway/src/authz/authz.module.ts b/apps/api-gateway/src/authz/authz.module.ts index 78b862ca0..99ac85f3b 100644 --- a/apps/api-gateway/src/authz/authz.module.ts +++ b/apps/api-gateway/src/authz/authz.module.ts @@ -1,42 +1,42 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; +import { ClientsModule, Transport } from '@nestjs/microservices' -import { AgentService } from '../agent/agent.service'; -import { AuthzController } from './authz.controller'; -import { AuthzService } from './authz.service'; -import { CommonModule } from '../../../../libs/common/src/common.module'; -import { CommonService } from '../../../../libs/common/src/common.service'; -import { ConnectionService } from '../connection/connection.service'; -import { HttpModule } from '@nestjs/axios'; -import { JwtStrategy } from './jwt.strategy'; -import { MobileJwtStrategy } from './mobile-jwt.strategy'; -import { Module } from '@nestjs/common'; -import { PassportModule } from '@nestjs/passport'; -import { SocketGateway } from './socket.gateway'; -import { SupabaseService } from '@credebl/supabase'; -import { UserModule } from '../user/user.module'; -import { UserService } from '../user/user.service'; -import { VerificationService } from '../verification/verification.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { OrganizationService } from '../organization/organization.service'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { SupabaseService } from '@credebl/supabase' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { PassportModule } from '@nestjs/passport' +import { CommonModule } from '../../../../libs/common/src/common.module' +import { CommonService } from '../../../../libs/common/src/common.service' +import { AgentService } from '../agent/agent.service' +import { ConnectionService } from '../connection/connection.service' +import { OrganizationService } from '../organization/organization.service' +import { UserModule } from '../user/user.module' +import { UserService } from '../user/user.service' +import { VerificationService } from '../verification/verification.service' +import { AuthzController } from './authz.controller' +import { AuthzService } from './authz.service' +import { JwtStrategy } from './jwt.strategy' +import { MobileJwtStrategy } from './mobile-jwt.strategy' +import { SocketGateway } from './socket.gateway' @Module({ imports: [ HttpModule, PassportModule.register({ defaultStrategy: 'jwt', - mobileStrategy: 'mobile-jwt' + mobileStrategy: 'mobile-jwt', }), ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.AUTH_SERVICE, process.env.API_GATEWAY_NKEY_SEED) + options: getNatsOptions(CommonConstants.AUTH_SERVICE, process.env.API_GATEWAY_NKEY_SEED), }, - CommonModule + CommonModule, ]), - UserModule + UserModule, ], providers: [ JwtStrategy, @@ -50,12 +50,9 @@ import { NATSClient } from '@credebl/common/NATSClient'; CommonService, UserService, SupabaseService, - OrganizationService + OrganizationService, ], - exports: [ - PassportModule, - AuthzService - ], - controllers: [AuthzController] + exports: [PassportModule, AuthzService], + controllers: [AuthzController], }) -export class AuthzModule { } \ No newline at end of file +export class AuthzModule {} diff --git a/apps/api-gateway/src/authz/authz.service.ts b/apps/api-gateway/src/authz/authz.service.ts index 83d4d8358..218ce0e34 100644 --- a/apps/api-gateway/src/authz/authz.service.ts +++ b/apps/api-gateway/src/authz/authz.service.ts @@ -1,71 +1,72 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from '../../../../libs/service/base.service'; -import { - WebSocketGateway, - WebSocketServer - -} from '@nestjs/websockets'; -import { UserEmailVerificationDto } from '../user/dto/create-user.dto'; -import { EmailVerificationDto } from '../user/dto/email-verify.dto'; -import { AddUserDetailsDto } from '../user/dto/add-user.dto'; -import { IResetPasswordResponse, ISendVerificationEmail, ISignInUser, ISignUpUserResponse, IVerifyUserEmail } from '@credebl/common/interfaces/user.interface'; -import { ResetPasswordDto } from './dtos/reset-password.dto'; -import { ForgotPasswordDto } from './dtos/forgot-password.dto'; -import { ResetTokenPasswordDto } from './dtos/reset-token-password'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { + IResetPasswordResponse, + ISendVerificationEmail, + ISignInUser, + ISignUpUserResponse, + IVerifyUserEmail, +} from '@credebl/common/interfaces/user.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { WebSocketGateway, WebSocketServer } from '@nestjs/websockets' +import { BaseService } from '../../../../libs/service/base.service' +import type { AddUserDetailsDto } from '../user/dto/add-user.dto' +import type { UserEmailVerificationDto } from '../user/dto/create-user.dto' +import type { EmailVerificationDto } from '../user/dto/email-verify.dto' +import type { ForgotPasswordDto } from './dtos/forgot-password.dto' +import type { ResetPasswordDto } from './dtos/reset-password.dto' +import type { ResetTokenPasswordDto } from './dtos/reset-token-password' @Injectable() @WebSocketGateway() export class AuthzService extends BaseService { //private logger = new Logger('AuthService'); - @WebSocketServer() server; + @WebSocketServer() server constructor( @Inject('NATS_CLIENT') private readonly authServiceProxy: ClientProxy, - private readonly natsClient : NATSClient + private readonly natsClient: NATSClient ) { - - super('AuthzService'); + super('AuthzService') } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: getUserByKeycloakUserId(keycloakUserId: string): Promise { - return this.natsClient.sendNats(this.authServiceProxy, 'get-user-by-keycloakUserId', keycloakUserId); + return this.natsClient.sendNats(this.authServiceProxy, 'get-user-by-keycloakUserId', keycloakUserId) } async sendVerificationMail(userEmailVerification: UserEmailVerificationDto): Promise { - const payload = { userEmailVerification }; - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload); + const payload = { userEmailVerification } + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload) } async verifyEmail(param: EmailVerificationDto): Promise { - const payload = { param }; - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-email-verification', payload); + const payload = { param } + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-email-verification', payload) } async login(email: string, password?: string, isPasskey = false): Promise { - const payload = { email, password, isPasskey }; - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-holder-login', payload); + const payload = { email, password, isPasskey } + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-holder-login', payload) } - + async resetPassword(resetPasswordDto: ResetPasswordDto): Promise { - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-reset-password', resetPasswordDto); + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-reset-password', resetPasswordDto) } - + async forgotPassword(forgotPasswordDto: ForgotPasswordDto): Promise { - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-forgot-password', forgotPasswordDto); + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-forgot-password', forgotPasswordDto) } async resetNewPassword(resetTokenPasswordDto: ResetTokenPasswordDto): Promise { - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-set-token-password', resetTokenPasswordDto); + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'user-set-token-password', resetTokenPasswordDto) } async refreshToken(refreshToken: string): Promise { - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'refresh-token-details', refreshToken); + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'refresh-token-details', refreshToken) } async addUserDetails(userInfo: AddUserDetailsDto): Promise { - const payload = { userInfo }; - return this.natsClient.sendNatsMessage(this.authServiceProxy, 'add-user', payload); + const payload = { userInfo } + return this.natsClient.sendNatsMessage(this.authServiceProxy, 'add-user', payload) } -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/authz/decorators/get-user.decorator.ts b/apps/api-gateway/src/authz/decorators/get-user.decorator.ts index 05a6151ed..26b927130 100644 --- a/apps/api-gateway/src/authz/decorators/get-user.decorator.ts +++ b/apps/api-gateway/src/authz/decorators/get-user.decorator.ts @@ -1,7 +1,7 @@ -import { createParamDecorator, ExecutionContext } from '@nestjs/common'; -import { RequestingUser } from '../dtos/requesting-user.dto'; +import { type ExecutionContext, createParamDecorator } from '@nestjs/common' +import type { RequestingUser } from '../dtos/requesting-user.dto' -export const GetUser = createParamDecorator((data, ctx: ExecutionContext): RequestingUser => { - const req = ctx.switchToHttp().getRequest(); - return req.requestor; -}); +export const GetUser = createParamDecorator((_data, ctx: ExecutionContext): RequestingUser => { + const req = ctx.switchToHttp().getRequest() + return req.requestor +}) diff --git a/apps/api-gateway/src/authz/decorators/roles.decorator.ts b/apps/api-gateway/src/authz/decorators/roles.decorator.ts index d6a2bd27b..5a0538c77 100644 --- a/apps/api-gateway/src/authz/decorators/roles.decorator.ts +++ b/apps/api-gateway/src/authz/decorators/roles.decorator.ts @@ -1,8 +1,10 @@ -import { CustomDecorator } from '@nestjs/common'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { SetMetadata } from '@nestjs/common'; +import type { CustomDecorator } from '@nestjs/common' +import { SetMetadata } from '@nestjs/common' +import type { OrgRoles } from 'libs/org-roles/enums' -export const ROLES_KEY = 'roles'; -export const Roles = (...roles: OrgRoles[]): CustomDecorator => SetMetadata(ROLES_KEY, roles); -export const Permissions = (...permissions: string[]): CustomDecorator => SetMetadata('permissions', permissions); -export const Subscriptions = (...subscriptions: string[]): CustomDecorator => SetMetadata('subscriptions', subscriptions); +export const ROLES_KEY = 'roles' +export const Roles = (...roles: OrgRoles[]): CustomDecorator => SetMetadata(ROLES_KEY, roles) +export const Permissions = (...permissions: string[]): CustomDecorator => + SetMetadata('permissions', permissions) +export const Subscriptions = (...subscriptions: string[]): CustomDecorator => + SetMetadata('subscriptions', subscriptions) diff --git a/apps/api-gateway/src/authz/decorators/user.decorator.ts b/apps/api-gateway/src/authz/decorators/user.decorator.ts index c733df0e8..5338a6e59 100644 --- a/apps/api-gateway/src/authz/decorators/user.decorator.ts +++ b/apps/api-gateway/src/authz/decorators/user.decorator.ts @@ -1,8 +1,6 @@ -import { createParamDecorator, ExecutionContext } from '@nestjs/common'; +import { type ExecutionContext, createParamDecorator } from '@nestjs/common' -export const User = createParamDecorator( - (data: unknown, ctx: ExecutionContext) => { - const request = ctx.switchToHttp().getRequest(); - return request.user; - } -); \ No newline at end of file +export const User = createParamDecorator((_data: unknown, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest() + return request.user +}) diff --git a/apps/api-gateway/src/authz/dtos/auth-token-res.dto.ts b/apps/api-gateway/src/authz/dtos/auth-token-res.dto.ts index 7c7e7a642..f418d8a83 100644 --- a/apps/api-gateway/src/authz/dtos/auth-token-res.dto.ts +++ b/apps/api-gateway/src/authz/dtos/auth-token-res.dto.ts @@ -1,21 +1,21 @@ -import { ApiResponseProperty } from '@nestjs/swagger'; +import { ApiResponseProperty } from '@nestjs/swagger' export class AuthTokenResponse { + @ApiResponseProperty({ + example: + 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4aExRb0lqeHRvTDBFVk9kNTJiZzNpbWt5cEt5SnNHSU5rTEd3VmQzWkdvIn0.eyJleHAiOjE2MTU1NDE1NzcsImlhdCI6MTYxNTU0MTI3NywianRpIjoiMjczOTJiYzctODNmNC00Yzg0LWJiODQtOTA0NjJmMTMyMWVkIiwiaXNzIjoiaHR0cDovLzM1LjE4OC44MC4zMjo4MDgwL2F1dGgvcmVhbG1zL2NyZWRlYmwtcGxhdGZvcm0iLCJhdWQiOlsiYWRtaW4tQ2FiaW0iLCJhZG1pbi1DZWxsbyIsImFkbWluLXp1bnV4ZSIsImFkbWluLUF5YW5Xb3JrcyBUZWNobm9sb2d5IFNvbHV0aW9ucyBQdnQuIEx0ZC4iLCJhZG1pbi1zZXJvcGFzcyIsImFkbWluLUhQRUMiLCJhZG1pbi1WeXZpYyIsImFkbWluLVNoaW5jaGFuIFRlY2hub2xvZ2llcyIsImFkbWluLVJva293eXIiLCJhZG1pbi1heWFud29ya3MiLCJhZG1pbi1UeXJvY2FyZSIsImFkbWluLVRlbmFudEJhbmsiLCJhZG1pbi1jZWZvcyIsImFkbWluLWNlbG90b3MiLCJhY2NvdW50IiwiYWRtaW4tY2Fub24iXSwic3ViIjoiZDhiOWI4MWItNzIzMi00YTdmLWI5ZDMtNGY3MjI2MTI5Njc3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRleWFDbGllbnQiLCJhY3IiOiIxIiwicmVzb3VyY2VfYWNjZXNzIjp7ImFkbWluLUNhYmltIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1DZWxsbyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tenVudXhlIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1BeWFuV29ya3MgVGVjaG5vbG9neSBTb2x1dGlvbnMgUHZ0LiBMdGQuIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1zZXJvcGFzcyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tSFBFQyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tVnl2aWMiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX0sImFkbWluLVNoaW5jaGFuIFRlY2hub2xvZ2llcyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tUm9rb3d5ciI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tYXlhbndvcmtzIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1UeXJvY2FyZSI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tVGVuYW50QmFuayI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tY2Vmb3MiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX0sImFkbWluLWNlbG90b3MiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX0sImFjY291bnQiOnsicm9sZXMiOlsidmlldy1wcm9maWxlIl19LCJhZG1pbi1jYW5vbiI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiY2xpZW50SWQiOiJhZGV5YUNsaWVudCIsImNsaWVudEhvc3QiOiIxMjQuNjYuMTcwLjExMCIsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC1hZGV5YWNsaWVudCIsImNsaWVudEFkZHJlc3MiOiIxMjQuNjYuMTcwLjExMCJ9.XY_m5rZuqK6AvIhuz6VDjVgTz4iC6SadEj-BmfhiEWQxhMyOcvRosZGIPOv4ywE_5Xzs0FUygJ0NMGjSddHYAY-jNMicWa6mw7bqZzit-5VZK7ClEpU_8QMqWy9bkobXwmNJpQc4pdbqPK8oKXak7U95LkvCNil1j3SFSVfVzctIAjA9Pw0jSdcamNlHQE4EQ1gTv6G3VdJEsZ4mrghR13oODUf80yqogsoXv5BRs9-FZhORAhzzSD5Qn6q7ZgEE8N7jXXmtg4dPCzu5mCCgDbLEd3T-IBqP7DlzlAmE_TS2U7jbaz83R8Xvg3iMAvJt9ETXgG9373b2QM0xHwLRsQ', + }) + // tslint:disable-next-line: variable-name + access_token: string - @ApiResponseProperty({ example: 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4aExRb0lqeHRvTDBFVk9kNTJiZzNpbWt5cEt5SnNHSU5rTEd3VmQzWkdvIn0.eyJleHAiOjE2MTU1NDE1NzcsImlhdCI6MTYxNTU0MTI3NywianRpIjoiMjczOTJiYzctODNmNC00Yzg0LWJiODQtOTA0NjJmMTMyMWVkIiwiaXNzIjoiaHR0cDovLzM1LjE4OC44MC4zMjo4MDgwL2F1dGgvcmVhbG1zL2NyZWRlYmwtcGxhdGZvcm0iLCJhdWQiOlsiYWRtaW4tQ2FiaW0iLCJhZG1pbi1DZWxsbyIsImFkbWluLXp1bnV4ZSIsImFkbWluLUF5YW5Xb3JrcyBUZWNobm9sb2d5IFNvbHV0aW9ucyBQdnQuIEx0ZC4iLCJhZG1pbi1zZXJvcGFzcyIsImFkbWluLUhQRUMiLCJhZG1pbi1WeXZpYyIsImFkbWluLVNoaW5jaGFuIFRlY2hub2xvZ2llcyIsImFkbWluLVJva293eXIiLCJhZG1pbi1heWFud29ya3MiLCJhZG1pbi1UeXJvY2FyZSIsImFkbWluLVRlbmFudEJhbmsiLCJhZG1pbi1jZWZvcyIsImFkbWluLWNlbG90b3MiLCJhY2NvdW50IiwiYWRtaW4tY2Fub24iXSwic3ViIjoiZDhiOWI4MWItNzIzMi00YTdmLWI5ZDMtNGY3MjI2MTI5Njc3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRleWFDbGllbnQiLCJhY3IiOiIxIiwicmVzb3VyY2VfYWNjZXNzIjp7ImFkbWluLUNhYmltIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1DZWxsbyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tenVudXhlIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1BeWFuV29ya3MgVGVjaG5vbG9neSBTb2x1dGlvbnMgUHZ0LiBMdGQuIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1zZXJvcGFzcyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tSFBFQyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tVnl2aWMiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX0sImFkbWluLVNoaW5jaGFuIFRlY2hub2xvZ2llcyI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tUm9rb3d5ciI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tYXlhbndvcmtzIjp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50Iiwidmlldy1wcm9maWxlIl19LCJhZG1pbi1UeXJvY2FyZSI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tVGVuYW50QmFuayI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfSwiYWRtaW4tY2Vmb3MiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX0sImFkbWluLWNlbG90b3MiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX0sImFjY291bnQiOnsicm9sZXMiOlsidmlldy1wcm9maWxlIl19LCJhZG1pbi1jYW5vbiI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiY2xpZW50SWQiOiJhZGV5YUNsaWVudCIsImNsaWVudEhvc3QiOiIxMjQuNjYuMTcwLjExMCIsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC1hZGV5YWNsaWVudCIsImNsaWVudEFkZHJlc3MiOiIxMjQuNjYuMTcwLjExMCJ9.XY_m5rZuqK6AvIhuz6VDjVgTz4iC6SadEj-BmfhiEWQxhMyOcvRosZGIPOv4ywE_5Xzs0FUygJ0NMGjSddHYAY-jNMicWa6mw7bqZzit-5VZK7ClEpU_8QMqWy9bkobXwmNJpQc4pdbqPK8oKXak7U95LkvCNil1j3SFSVfVzctIAjA9Pw0jSdcamNlHQE4EQ1gTv6G3VdJEsZ4mrghR13oODUf80yqogsoXv5BRs9-FZhORAhzzSD5Qn6q7ZgEE8N7jXXmtg4dPCzu5mCCgDbLEd3T-IBqP7DlzlAmE_TS2U7jbaz83R8Xvg3iMAvJt9ETXgG9373b2QM0xHwLRsQ' }) - // tslint:disable-next-line: variable-name - access_token: string; + @ApiResponseProperty({ example: 'email profile' }) + scope: string - @ApiResponseProperty({ example: 'email profile' }) - scope: string; + @ApiResponseProperty({ example: 86400 }) + // tslint:disable-next-line: variable-name + expires_in: number - @ApiResponseProperty({ example: 86400 }) - // tslint:disable-next-line: variable-name - expires_in: number; - - @ApiResponseProperty({ example: 'Bearer' }) - // tslint:disable-next-line: variable-name - token_type: string; - - + @ApiResponseProperty({ example: 'Bearer' }) + // tslint:disable-next-line: variable-name + token_type: string } diff --git a/apps/api-gateway/src/authz/dtos/client-login.dto.ts b/apps/api-gateway/src/authz/dtos/client-login.dto.ts index 41d40b578..fcd65e6f9 100644 --- a/apps/api-gateway/src/authz/dtos/client-login.dto.ts +++ b/apps/api-gateway/src/authz/dtos/client-login.dto.ts @@ -1,10 +1,9 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class ClientLoginDto { - @ApiProperty() - clientId: string; - - @ApiProperty() - clientSecret: string; + @ApiProperty() + clientId: string + @ApiProperty() + clientSecret: string } diff --git a/apps/api-gateway/src/authz/dtos/firebase-token.dto.ts b/apps/api-gateway/src/authz/dtos/firebase-token.dto.ts index 8d04ccc32..e134d65d9 100644 --- a/apps/api-gateway/src/authz/dtos/firebase-token.dto.ts +++ b/apps/api-gateway/src/authz/dtos/firebase-token.dto.ts @@ -1,8 +1,8 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class FirebaseTokenDto { - @ApiProperty() - @IsNotEmpty({message:'Please provide valid firebaseToken'}) - @IsString({message:'FirebaseToken should be string'}) - firebaseToken: string; -} \ No newline at end of file + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid firebaseToken' }) + @IsString({ message: 'FirebaseToken should be string' }) + firebaseToken: string +} diff --git a/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts b/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts index e9bcfcaa2..32d360488 100644 --- a/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts +++ b/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts @@ -1,38 +1,40 @@ -import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUrl } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUrl } from 'class-validator' -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class ForgotPasswordDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiPropertyOptional({ example: 'https://example.com/logo.png' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsUrl({ - // eslint-disable-next-line camelcase - require_protocol: true, - // eslint-disable-next-line camelcase - require_tld: true + @ApiPropertyOptional({ example: 'https://example.com/logo.png' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsUrl( + { + // eslint-disable-next-line camelcase + require_protocol: true, + // eslint-disable-next-line camelcase + require_tld: true, }, - { message: 'brandLogoUrl should be a valid URL' }) - brandLogoUrl?: string; + { message: 'brandLogoUrl should be a valid URL' } + ) + brandLogoUrl?: string - @ApiPropertyOptional({ example: 'MyPlatform' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsString({ message: 'platformName should be string' }) - platformName?: string; + @ApiPropertyOptional({ example: 'MyPlatform' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsString({ message: 'platformName should be string' }) + platformName?: string - @ApiPropertyOptional({ example: 'https://0.0.0.0:5000' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsString({ message: 'endpoint should be string' }) - endpoint?: string; -} \ No newline at end of file + @ApiPropertyOptional({ example: 'https://0.0.0.0:5000' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsString({ message: 'endpoint should be string' }) + endpoint?: string +} diff --git a/apps/api-gateway/src/authz/dtos/refresh-token.dto.ts b/apps/api-gateway/src/authz/dtos/refresh-token.dto.ts index e9ad0f6fa..f63cbba07 100644 --- a/apps/api-gateway/src/authz/dtos/refresh-token.dto.ts +++ b/apps/api-gateway/src/authz/dtos/refresh-token.dto.ts @@ -1,14 +1,12 @@ -import { IsNotEmpty } from 'class-validator'; +import { IsNotEmpty } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class RefreshTokenDto { - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'refreshToken is required.' }) - refreshToken: string; - -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'refreshToken is required.' }) + refreshToken: string +} diff --git a/apps/api-gateway/src/authz/dtos/requesting-user.dto.ts b/apps/api-gateway/src/authz/dtos/requesting-user.dto.ts index c73030bea..53736b4f7 100644 --- a/apps/api-gateway/src/authz/dtos/requesting-user.dto.ts +++ b/apps/api-gateway/src/authz/dtos/requesting-user.dto.ts @@ -1,20 +1,19 @@ /* eslint-disable camelcase */ -import { UserRoleOrgPermsDto } from './user-role-org-perms.dto'; +import type { UserRoleOrgPermsDto } from './user-role-org-perms.dto' export class RequestingUser { - userId: string; - username: string; - //roleId: number; - email: string; - //permissions: string[]; - orgId: string; - //org?: OrganizationDto; - name?: string; - agentEndPoint?: string; - apiKey?: string; - tenant_id?: string; - tenant_name?: string; - userRoleOrgPermissions: UserRoleOrgPermsDto[]; - tenantOrgId?: string; + userId: string + username: string + //roleId: number; + email: string + //permissions: string[]; + orgId: string + //org?: OrganizationDto; + name?: string + agentEndPoint?: string + apiKey?: string + tenant_id?: string + tenant_name?: string + userRoleOrgPermissions: UserRoleOrgPermsDto[] + tenantOrgId?: string } - diff --git a/apps/api-gateway/src/authz/dtos/reset-password.dto.ts b/apps/api-gateway/src/authz/dtos/reset-password.dto.ts index f2fc18aa0..04ea7328a 100644 --- a/apps/api-gateway/src/authz/dtos/reset-password.dto.ts +++ b/apps/api-gateway/src/authz/dtos/reset-password.dto.ts @@ -1,25 +1,24 @@ -import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class ResetPasswordDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'oldPassword is required.' }) - oldPassword: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'oldPassword is required.' }) + oldPassword: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'newPassword is required.' }) - newPassword?: string; - -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'newPassword is required.' }) + newPassword?: string +} diff --git a/apps/api-gateway/src/authz/dtos/reset-token-password.ts b/apps/api-gateway/src/authz/dtos/reset-token-password.ts index dfcecd59f..75167d3ae 100644 --- a/apps/api-gateway/src/authz/dtos/reset-token-password.ts +++ b/apps/api-gateway/src/authz/dtos/reset-token-password.ts @@ -1,22 +1,19 @@ -import { IsNotEmpty } from 'class-validator'; +import { IsNotEmpty } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class ResetTokenPasswordDto { - - email: string; + email: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'password is required.' }) - password: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'password is required.' }) + password: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'token is required.' }) - token: string; - - -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'token is required.' }) + token: string +} diff --git a/apps/api-gateway/src/authz/dtos/user-login.dto.ts b/apps/api-gateway/src/authz/dtos/user-login.dto.ts index bbbe129b3..8a2a4085e 100644 --- a/apps/api-gateway/src/authz/dtos/user-login.dto.ts +++ b/apps/api-gateway/src/authz/dtos/user-login.dto.ts @@ -1,12 +1,12 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class UserLoginDto { - @ApiProperty() - username: string; + @ApiProperty() + username: string - @ApiProperty() - password: string; + @ApiProperty() + password: string - @ApiProperty() - firebaseToken: string; + @ApiProperty() + firebaseToken: string } diff --git a/apps/api-gateway/src/authz/dtos/user-role-org-perms.dto.ts b/apps/api-gateway/src/authz/dtos/user-role-org-perms.dto.ts index fd9d363b6..0d7626656 100644 --- a/apps/api-gateway/src/authz/dtos/user-role-org-perms.dto.ts +++ b/apps/api-gateway/src/authz/dtos/user-role-org-perms.dto.ts @@ -1,19 +1,16 @@ - export class UserRoleOrgPermsDto { - id :string; - role : userRoleDto; - Organization: userOrgDto; + id: string + role: userRoleDto + Organization: userOrgDto } export class userRoleDto { - id: string; - name : string; - permissions :string[]; - + id: string + name: string + permissions: string[] } export class userOrgDto { - id: number; - orgName :string; + id: number + orgName: string } - 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 a5b9c5119..80359b4a9 100644 --- a/apps/api-gateway/src/authz/guards/org-roles.guard.ts +++ b/apps/api-gateway/src/authz/guards/org-roles.guard.ts @@ -1,102 +1,112 @@ -import { BadRequestException, CanActivate, ExecutionContext, ForbiddenException, Logger } from '@nestjs/common'; - -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'; -import { validate as isValidUUID } from 'uuid'; +import { + BadRequestException, + type CanActivate, + type ExecutionContext, + ForbiddenException, + Logger, +} from '@nestjs/common' + +import { ResponseMessages } from '@credebl/common/response-messages' +import { Injectable } from '@nestjs/common' +import type { Reflector } from '@nestjs/core' +import { OrgRoles } from 'libs/org-roles/enums' +import { validate as isValidUUID } from 'uuid' +import { ROLES_KEY } from '../decorators/roles.decorator' @Injectable() export class OrgRolesGuard implements CanActivate { - constructor(private reflector: Reflector) { } // eslint-disable-next-line array-callback-return + constructor(private reflector: Reflector) {} // eslint-disable-next-line array-callback-return - - private logger = new Logger('Org Role Guard'); + private logger = new Logger('Org Role Guard') async canActivate(context: ExecutionContext): Promise { const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [ context.getHandler(), - context.getClass() - ]); - const requiredRolesNames = Object.values(requiredRoles) as string[]; + context.getClass(), + ]) + const requiredRolesNames = Object.values(requiredRoles) as string[] if (!requiredRolesNames) { - return true; + return true } - const req = context.switchToHttp().getRequest(); - const { user } = req; - - if (user?.userRole && user?.userRole.includes('holder')) { - throw new ForbiddenException('This role is a holder.'); + const req = context.switchToHttp().getRequest() + const { user } = req + + if (user?.userRole?.includes('holder')) { + throw new ForbiddenException('This role is a holder.') } - req.params.orgId = req.params?.orgId ? req.params?.orgId?.trim() : ''; - req.query.orgId = req.query?.orgId ? req.query?.orgId?.trim() : ''; - req.body.orgId = req.body?.orgId ? req.body?.orgId?.trim() : ''; + req.params.orgId = req.params?.orgId ? req.params?.orgId?.trim() : '' + req.query.orgId = req.query?.orgId ? req.query?.orgId?.trim() : '' + req.body.orgId = req.body?.orgId ? req.body?.orgId?.trim() : '' - const orgId = req.params.orgId || req.query.orgId || req.body.orgId; + const orgId = req.params.orgId || req.query.orgId || req.body.orgId - if (orgId) { + if (orgId) { + if (!isValidUUID(orgId)) { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + } - if (!isValidUUID(orgId)) { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } - + // biome-ignore lint/suspicious/noPrototypeBuiltins: + if (user.hasOwnProperty('resource_access') && user.resource_access[orgId]) { + const orgRoles: string[] = user.resource_access[orgId].roles + const roleAccess = requiredRoles.some((role) => orgRoles.includes(role)) - if (user.hasOwnProperty('resource_access') && user.resource_access[orgId]) { - const orgRoles: string[] = user.resource_access[orgId].roles; - const roleAccess = requiredRoles.some((role) => orgRoles.includes(role)); - - if (!roleAccess) { - throw new ForbiddenException(ResponseMessages.organisation.error.roleNotMatch, { cause: new Error(), description: ResponseMessages.errorMessages.forbidden }); - } - return roleAccess; + if (!roleAccess) { + throw new ForbiddenException(ResponseMessages.organisation.error.roleNotMatch, { + cause: new Error(), + description: ResponseMessages.errorMessages.forbidden, + }) } + return roleAccess + } const specificOrg = user.userOrgRoles.find((orgDetails) => { if (!orgDetails.orgId) { - return false; + return false } - return orgDetails.orgId.toString().trim() === orgId.toString().trim(); - }); - + return orgDetails.orgId.toString().trim() === orgId.toString().trim() + }) + if (!specificOrg) { - throw new ForbiddenException(ResponseMessages.organisation.error.orgNotMatch, { cause: new Error(), description: ResponseMessages.errorMessages.forbidden }); + throw new ForbiddenException(ResponseMessages.organisation.error.orgNotMatch, { + cause: new Error(), + description: ResponseMessages.errorMessages.forbidden, + }) } - user.selectedOrg = specificOrg; + user.selectedOrg = specificOrg // eslint-disable-next-line array-callback-return user.selectedOrg.orgRoles = user.userOrgRoles.map((orgRoleItem) => { if (orgRoleItem.orgId && orgRoleItem.orgId.toString().trim() === orgId.toString().trim()) { - return orgRoleItem.orgRole.name; + return orgRoleItem.orgRole.name } - }); - - } else if (requiredRolesNames.includes(OrgRoles.PLATFORM_ADMIN)) { - + }) + } else if (requiredRolesNames.includes(OrgRoles.PLATFORM_ADMIN)) { // eslint-disable-next-line array-callback-return const isPlatformAdmin = user.userOrgRoles.find((orgDetails) => { if (orgDetails.orgRole.name === OrgRoles.PLATFORM_ADMIN) { - return true; + return true } - }); + }) if (isPlatformAdmin) { - return true; + return true } - return false; - + return false } else { - throw new BadRequestException('Please provide valid orgId'); + throw new BadRequestException('Please provide valid orgId') } // Sending user friendly message if a user attempts to access an API that is inaccessible to their role - const roleAccess = requiredRoles.some((role) => user.selectedOrg?.orgRoles.includes(role)); + const roleAccess = requiredRoles.some((role) => user.selectedOrg?.orgRoles.includes(role)) if (!roleAccess) { - throw new ForbiddenException(ResponseMessages.organisation.error.roleNotMatch, { cause: new Error(), description: ResponseMessages.errorMessages.forbidden }); + throw new ForbiddenException(ResponseMessages.organisation.error.roleNotMatch, { + cause: new Error(), + description: ResponseMessages.errorMessages.forbidden, + }) } - return roleAccess; + return roleAccess } -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/authz/guards/user-access-guard.ts b/apps/api-gateway/src/authz/guards/user-access-guard.ts index 95f37db58..520bc3af7 100644 --- a/apps/api-gateway/src/authz/guards/user-access-guard.ts +++ b/apps/api-gateway/src/authz/guards/user-access-guard.ts @@ -1,22 +1,28 @@ -import { Injectable, CanActivate, ExecutionContext, UnauthorizedException, ForbiddenException } from '@nestjs/common'; -import { Observable } from 'rxjs'; +import { + type CanActivate, + type ExecutionContext, + ForbiddenException, + Injectable, + UnauthorizedException, +} from '@nestjs/common' +import type { Observable } from 'rxjs' @Injectable() export class UserAccessGuard implements CanActivate { canActivate(context: ExecutionContext): boolean | Promise | Observable { - const request = context.switchToHttp().getRequest(); + const request = context.switchToHttp().getRequest() - const { user } = request; + const { user } = request + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (user.hasOwnProperty('client_id')) { - throw new UnauthorizedException('You do not have access'); + throw new UnauthorizedException('You do not have access') } - if (user?.userRole && user?.userRole.includes('holder')) { - throw new ForbiddenException('This role is a holder.'); + if (user?.userRole?.includes('holder')) { + throw new ForbiddenException('This role is a holder.') } - - - return true; + + return true } } diff --git a/apps/api-gateway/src/authz/guards/user-role.guard.ts b/apps/api-gateway/src/authz/guards/user-role.guard.ts index 3c3dc4d7a..4ecc40dae 100644 --- a/apps/api-gateway/src/authz/guards/user-role.guard.ts +++ b/apps/api-gateway/src/authz/guards/user-role.guard.ts @@ -1,21 +1,21 @@ -import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common'; -import { Observable } from 'rxjs'; +import { type CanActivate, type ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common' +import type { Observable } from 'rxjs' @Injectable() export class UserRoleGuard implements CanActivate { canActivate(context: ExecutionContext): boolean | Promise | Observable { - const request = context.switchToHttp().getRequest(); + const request = context.switchToHttp().getRequest() - const { user } = request; + const { user } = request if (!user?.userRole) { - throw new ForbiddenException('This role is not a holder.'); + throw new ForbiddenException('This role is not a holder.') } - + if (!user?.userRole.includes('holder')) { - throw new ForbiddenException('This role is not a holder.'); + throw new ForbiddenException('This role is not a holder.') } - return true; + return true } } diff --git a/apps/api-gateway/src/authz/jwt-payload.interface.ts b/apps/api-gateway/src/authz/jwt-payload.interface.ts index c4dcec845..7e050f858 100644 --- a/apps/api-gateway/src/authz/jwt-payload.interface.ts +++ b/apps/api-gateway/src/authz/jwt-payload.interface.ts @@ -1,13 +1,12 @@ export interface JwtPayload { - iss: string; - sub: string; - aud: string[]; - iat?: number; - exp?: number; - azp: string; - scope: string; - gty?: string; - permissions: string[]; - email?: string - } - \ No newline at end of file + iss: string + sub: string + aud: string[] + iat?: number + exp?: number + azp: string + scope: string + gty?: string + permissions: string[] + email?: string +} diff --git a/apps/api-gateway/src/authz/jwt.strategy.ts b/apps/api-gateway/src/authz/jwt.strategy.ts index a7bac5265..fe7129ab2 100644 --- a/apps/api-gateway/src/authz/jwt.strategy.ts +++ b/apps/api-gateway/src/authz/jwt.strategy.ts @@ -1,104 +1,105 @@ -import * as dotenv from 'dotenv'; +import * as dotenv from 'dotenv' -import { ExtractJwt, Strategy } from 'passport-jwt'; -import { Injectable, Logger, UnauthorizedException, NotFoundException } from '@nestjs/common'; +import { Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common' +import { ExtractJwt, Strategy } from 'passport-jwt' -import { JwtPayload } from './jwt-payload.interface'; -import { PassportStrategy } from '@nestjs/passport'; -import { UserService } from '../user/user.service'; -import * as jwt from 'jsonwebtoken'; -import { passportJwtSecret } from 'jwks-rsa'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { OrganizationService } from '../organization/organization.service'; -import { IOrganization } from '@credebl/common/interfaces/organization.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; +import { CommonConstants } from '@credebl/common/common.constant' +import type { IOrganization } from '@credebl/common/interfaces/organization.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { PassportStrategy } from '@nestjs/passport' +import * as jwt from 'jsonwebtoken' +import { passportJwtSecret, type secretType } from 'jwks-rsa' +import type { OrganizationService } from '../organization/organization.service' +import type { UserService } from '../user/user.service' +import type { JwtPayload } from './jwt-payload.interface' -dotenv.config(); +dotenv.config() @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { - private readonly logger = new Logger('Jwt Strategy'); + private readonly logger = new Logger('Jwt Strategy') constructor( private readonly usersService: UserService, private readonly organizationService: OrganizationService - ) { - + ) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKeyProvider: (request, jwtToken, done) => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const decodedToken: any = jwt.decode(jwtToken); + // biome-ignore lint/suspicious/noExplicitAny: + const decodedToken: any = jwt.decode(jwtToken) if (!decodedToken) { - throw new UnauthorizedException(ResponseMessages.user.error.invalidAccessToken); + throw new UnauthorizedException(ResponseMessages.user.error.invalidAccessToken) } - const audiance = decodedToken.iss.toString(); + const audiance = decodedToken.iss.toString() const jwtOptions = { cache: true, rateLimit: true, jwksRequestsPerMinute: 5, - jwksUri: `${audiance}${CommonConstants.URL_KEYCLOAK_JWKS}` - }; - const secretprovider = passportJwtSecret(jwtOptions); - let certkey; - secretprovider(request, jwtToken, async (err, data) => { - certkey = data; - done(null, certkey); - }); + jwksUri: `${audiance}${CommonConstants.URL_KEYCLOAK_JWKS}`, + } + const secretprovider = passportJwtSecret(jwtOptions) + let certkey: secretType + secretprovider(request, jwtToken, async (_err, data) => { + certkey = data + done(null, certkey) + }) }, - algorithms: ['RS256'] - }); + algorithms: ['RS256'], + }) } async validate(payload: JwtPayload): Promise { - - let userDetails = null; - let userInfo; + let userDetails = null + let userInfo: object if (payload?.email) { - userInfo = await this.usersService.getUserByUserIdInKeycloak(payload?.email); + userInfo = await this.usersService.getUserByUserIdInKeycloak(payload?.email) } - + + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (payload.hasOwnProperty('client_id')) { - const orgDetails: IOrganization = await this.organizationService.findOrganizationOwner(payload['client_id']); - - this.logger.log('Organization details fetched'); + // biome-ignore lint/complexity/useLiteralKeys: + const orgDetails: IOrganization = await this.organizationService.findOrganizationOwner(payload['client_id']) + + this.logger.log('Organization details fetched') if (!orgDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound) } - + // eslint-disable-next-line prefer-destructuring - const userOrgDetails = 0 < orgDetails.userOrgRoles.length && orgDetails.userOrgRoles[0]; + const userOrgDetails = orgDetails.userOrgRoles.length > 0 && orgDetails.userOrgRoles[0] - userDetails = userOrgDetails.user; - userDetails.userOrgRoles = []; + userDetails = userOrgDetails.user + userDetails.userOrgRoles = [] userDetails.userOrgRoles.push({ id: userOrgDetails.id, userId: userOrgDetails.userId, orgRoleId: userOrgDetails.orgRoleId, orgId: userOrgDetails.orgId, - orgRole: userOrgDetails.orgRole - }); - - this.logger.log('User details set'); + orgRole: userOrgDetails.orgRole, + }) + this.logger.log('User details set') } else { - userDetails = await this.usersService.findUserinKeycloak(payload.sub); + userDetails = await this.usersService.findUserinKeycloak(payload.sub) } - + if (!userDetails) { - throw new NotFoundException(ResponseMessages.user.error.notFound); + throw new NotFoundException(ResponseMessages.user.error.notFound) } //TODO patch to QA - if (userInfo && userInfo?.['attributes'] && userInfo?.['attributes']?.userRole) { - userDetails['userRole'] = userInfo?.['attributes']?.userRole; + // biome-ignore lint/complexity/useLiteralKeys: + if (userInfo?.['attributes']?.userRole) { + // biome-ignore lint/complexity/useLiteralKeys: + userDetails.userRole = userInfo?.['attributes']?.userRole } return { ...userDetails, - ...payload - }; + ...payload, + } } } diff --git a/apps/api-gateway/src/authz/mobile-jwt.strategy.ts b/apps/api-gateway/src/authz/mobile-jwt.strategy.ts index be5b49fc7..562b8f71a 100644 --- a/apps/api-gateway/src/authz/mobile-jwt.strategy.ts +++ b/apps/api-gateway/src/authz/mobile-jwt.strategy.ts @@ -1,51 +1,48 @@ -import * as dotenv from 'dotenv'; -import * as jwt from 'jsonwebtoken'; +import * as dotenv from 'dotenv' +import * as jwt from 'jsonwebtoken' -import { ExtractJwt, Strategy } from 'passport-jwt'; -import { BadRequestException, Injectable, Logger, UnauthorizedException } from '@nestjs/common'; +import { Injectable, Logger, UnauthorizedException } from '@nestjs/common' +import { ExtractJwt, Strategy } from 'passport-jwt' -import { CommonConstants } from '@credebl/common/common.constant'; -import { PassportStrategy } from '@nestjs/passport'; -import { passportJwtSecret } from 'jwks-rsa'; -dotenv.config(); -const logger = new Logger(); +import { CommonConstants } from '@credebl/common/common.constant' +import { PassportStrategy } from '@nestjs/passport' +import { passportJwtSecret, type secretType } from 'jwks-rsa' +import type { JwtPayload } from './jwt-payload.interface' +dotenv.config() +const _logger = new Logger() @Injectable() export class MobileJwtStrategy extends PassportStrategy(Strategy, 'mobile-jwt') { - private readonly logger = new Logger(); + private readonly logger = new Logger() constructor() { super({ - secretOrKeyProvider: (request, jwtToken, done) => { - const decodedToken: any = jwt.decode(jwtToken); - const audiance = decodedToken.iss.toString(); + const decodedToken = jwt.decode(jwtToken) as JwtPayload + const audiance = decodedToken.iss.toString() const jwtOptions = { cache: true, rateLimit: true, jwksRequestsPerMinute: 5, - jwksUri: `${audiance}${CommonConstants.URL_KEYCLOAK_JWKS}` - }; - const secretprovider = passportJwtSecret(jwtOptions); - let certkey; - secretprovider(request, jwtToken, async (err, data) => { - certkey = data; - done(null, certkey); - }); + jwksUri: `${audiance}${CommonConstants.URL_KEYCLOAK_JWKS}`, + } + const secretprovider = passportJwtSecret(jwtOptions) + let certkey: secretType + secretprovider(request, jwtToken, async (_err, data) => { + certkey = data + done(null, certkey) + }) }, jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), - algorithms: ['RS256'] - }); + algorithms: ['RS256'], + }) } + // biome-ignore lint/suspicious/noExplicitAny: validate(payload: any) { - if ('adeyaClient' !== payload.azp) { - throw new UnauthorizedException( - 'Authorization header contains an invalid token' - ); - } else { - return payload; + if (payload.azp !== 'adeyaClient') { + throw new UnauthorizedException('Authorization header contains an invalid token') } - + return payload } } diff --git a/apps/api-gateway/src/authz/roles.guard.ts b/apps/api-gateway/src/authz/roles.guard.ts index a79993757..13e87dbe2 100644 --- a/apps/api-gateway/src/authz/roles.guard.ts +++ b/apps/api-gateway/src/authz/roles.guard.ts @@ -1,55 +1,51 @@ -import { CanActivate, ExecutionContext, Injectable, Logger } from '@nestjs/common'; +import { type CanActivate, type ExecutionContext, Injectable, Logger } from '@nestjs/common' -import { Reflector } from '@nestjs/core'; +import type { Reflector } from '@nestjs/core' @Injectable() export class RolesGuard implements CanActivate { - constructor(private reflector: Reflector) { } + constructor(private reflector: Reflector) {} - private readonly logger = new Logger('RolesGuard'); + private readonly logger = new Logger('RolesGuard') async canActivate(context: ExecutionContext): Promise { - this.logger.log(`Before permissions`); - const permissions = this.reflector.get('permissions', context.getHandler()); - this.logger.log(`permissions: ${permissions}`); + this.logger.log('Before permissions') + const permissions = this.reflector.get('permissions', context.getHandler()) + this.logger.log(`permissions: ${permissions}`) if (!permissions) { - this.logger.log(`No Permissions found.`); - return true; + this.logger.log('No Permissions found.') + return true } - const subscription = this.reflector.get('subscription', context.getHandler()); - this.logger.log(`subscription: ${subscription}`); + const subscription = this.reflector.get('subscription', context.getHandler()) + this.logger.log(`subscription: ${subscription}`) if (!subscription) { - return true; + return true } - const request = context.switchToHttp().getRequest(); - const user = request.requestor; - this.logger.log(`user request:: orgId: ${user.orgId}`); + const request = context.switchToHttp().getRequest() + const user = request.requestor + this.logger.log(`user request:: orgId: ${user.orgId}`) - const userPermissions = user.userRoleOrgPermissions[0].role.permissions; + const userPermissions = user.userRoleOrgPermissions[0].role.permissions - const permsArray = []; + const permsArray = [] - userPermissions.every( - permissions => permsArray.push(permissions.name) - ); + userPermissions.every((permissions) => permsArray.push(permissions.name)) - return this.matchRoles(permsArray, permissions); + return this.matchRoles(permsArray, permissions) } matchRoles(UserPermissions: string[], APIPermissions: string[]): boolean { - this.logger.log('called matches permission'); + this.logger.log('called matches permission') - const checker = APIPermissions.some(function (val) { - return 0 <= UserPermissions.indexOf(val); - }); + const checker = APIPermissions.some((val) => UserPermissions.indexOf(val) >= 0) if (checker) { - return true; + return true } - return false; + return false } } diff --git a/apps/api-gateway/src/authz/socket.gateway.ts b/apps/api-gateway/src/authz/socket.gateway.ts index 9d7d7e90c..fa26fd834 100644 --- a/apps/api-gateway/src/authz/socket.gateway.ts +++ b/apps/api-gateway/src/authz/socket.gateway.ts @@ -1,37 +1,31 @@ -import { - OnGatewayConnection, - SubscribeMessage, - WebSocketGateway, - WebSocketServer +import { type OnGatewayConnection, SubscribeMessage, WebSocketGateway, WebSocketServer } from '@nestjs/websockets' -} from '@nestjs/websockets'; - -import { AgentService } from '../agent/agent.service'; -import { ConnectionService } from '../connection/connection.service'; -import { Logger } from '@nestjs/common'; -import { VerificationService } from '../verification/verification.service'; -import { ISocketInterface } from '../interfaces/ISocket.interface'; +import { Logger } from '@nestjs/common' +import type { AgentService } from '../agent/agent.service' +import type { ConnectionService } from '../connection/connection.service' +import type { ISocketInterface } from '../interfaces/ISocket.interface' +import type { VerificationService } from '../verification/verification.service' @WebSocketGateway() export class SocketGateway implements OnGatewayConnection { - @WebSocketServer() server; + @WebSocketServer() server constructor( private readonly verificationService: VerificationService, private readonly connectionService: ConnectionService, private readonly agentService: AgentService - ) { } - private readonly logger = new Logger('SocketGateway'); + ) {} + private readonly logger = new Logger('SocketGateway') handleConnection(): void { - this.logger.debug(`Socket connected.`); + this.logger.debug('Socket connected.') } /** * @description:Method used to disconnect the socket. */ handleDisconnect(): void { - this.logger.debug(`Socket disconnected.`); + this.logger.debug('Socket disconnected.') } // @SubscribeMessage('message') @@ -42,89 +36,67 @@ export class SocketGateway implements OnGatewayConnection { @SubscribeMessage('passwordLess') async handlePasswordLessResponse(payload: ISocketInterface): Promise { - this.server.to(payload.clientSocketId).emit('passwordLess', payload.token); + this.server.to(payload.clientSocketId).emit('passwordLess', payload.token) } @SubscribeMessage('agent-spinup-process-initiated') - async handlAgentSpinUpProccessStartedResponse( - client: string, - payload: ISocketInterface - ): Promise { - this.server.to(payload.clientId).emit('agent-spinup-process-initiated'); + async handlAgentSpinUpProccessStartedResponse(_client: string, payload: ISocketInterface): Promise { + this.server.to(payload.clientId).emit('agent-spinup-process-initiated') } @SubscribeMessage('agent-spinup-process-completed') - async handlAgentSpinUpProccessSucessResponse( - client: string, - payload: ISocketInterface - ): Promise { - this.server.to(payload.clientId).emit('agent-spinup-process-completed'); + async handlAgentSpinUpProccessSucessResponse(_client: string, payload: ISocketInterface): Promise { + this.server.to(payload.clientId).emit('agent-spinup-process-completed') } @SubscribeMessage('did-publish-process-initiated') - async handlDidPublicProcessStarted( - client: string, - payload: ISocketInterface - ): Promise { - this.server.to(payload.clientId).emit('did-publish-process-initiated'); + async handlDidPublicProcessStarted(_client: string, payload: ISocketInterface): Promise { + this.server.to(payload.clientId).emit('did-publish-process-initiated') } @SubscribeMessage('did-publish-process-completed') - async handlDidPublicProcessSuccess( - client: string, - payload: ISocketInterface - ): Promise { - this.server.to(payload.clientId).emit('did-publish-process-completed'); + async handlDidPublicProcessSuccess(_client: string, payload: ISocketInterface): Promise { + this.server.to(payload.clientId).emit('did-publish-process-completed') } @SubscribeMessage('invitation-url-creation-started') - async handleInvitationUrlCreationStartResponse( - client: string, - payload: ISocketInterface - ): Promise { - this.logger.log(`invitation-url-creation-started ${payload.clientId}`); - this.server.to(payload.clientId).emit('invitation-url-creation-started'); + async handleInvitationUrlCreationStartResponse(_client: string, payload: ISocketInterface): Promise { + this.logger.log(`invitation-url-creation-started ${payload.clientId}`) + this.server.to(payload.clientId).emit('invitation-url-creation-started') } @SubscribeMessage('invitation-url-creation-success') - async handleInvitationUrlCreationSuccessResponse( - client: string, - payload: ISocketInterface - ): Promise { - this.logger.log(`invitation-url-creation-success ${payload.clientId}`); - this.server.to(payload.clientId).emit('invitation-url-creation-success'); + async handleInvitationUrlCreationSuccessResponse(_client: string, payload: ISocketInterface): Promise { + this.logger.log(`invitation-url-creation-success ${payload.clientId}`) + this.server.to(payload.clientId).emit('invitation-url-creation-success') } @SubscribeMessage('error-in-wallet-creation-process') - async handleErrorResponse(client:string, payload: ISocketInterface): Promise { - this.logger.log(`error-in-wallet-creation-process ${payload.clientId}`); - this.server - .to(payload.clientId) - .emit('error-in-wallet-creation-process', payload.error); + async handleErrorResponse(_client: string, payload: ISocketInterface): Promise { + this.logger.log(`error-in-wallet-creation-process ${payload.clientId}`) + this.server.to(payload.clientId).emit('error-in-wallet-creation-process', payload.error) } @SubscribeMessage('bulk-issuance-process-completed') - async handleBulkIssuance(client:string, payload: ISocketInterface): Promise { - this.logger.log(`bulk-issuance-process-completed ${payload.clientId}`); - this.server - .to(payload.clientId) - .emit('bulk-issuance-process-completed', {fileUploadId: payload.fileUploadId}); + async handleBulkIssuance(_client: string, payload: ISocketInterface): Promise { + this.logger.log(`bulk-issuance-process-completed ${payload.clientId}`) + this.server.to(payload.clientId).emit('bulk-issuance-process-completed', { fileUploadId: payload.fileUploadId }) } @SubscribeMessage('error-in-bulk-issuance-process') - async handleBulkIssuanceErrorResponse(client:string, payload: ISocketInterface): Promise { - this.logger.log(`error-in-bulk-issuance-process ${payload.clientId}`); - const error = 'string' === typeof payload?.error ? payload?.error : payload?.error?.error; + async handleBulkIssuanceErrorResponse(_client: string, payload: ISocketInterface): Promise { + this.logger.log(`error-in-bulk-issuance-process ${payload.clientId}`) + const error = typeof payload?.error === 'string' ? payload?.error : payload?.error?.error this.server .to(payload.clientId) - .emit('error-in-bulk-issuance-process', {error, fileUploadId: payload.fileUploadId}); + .emit('error-in-bulk-issuance-process', { error, fileUploadId: payload.fileUploadId }) } @SubscribeMessage('bulk-issuance-process-retry-completed') - async handleBulkIssuanceRetry(client:string, payload: ISocketInterface): Promise { - this.logger.log(`bulk-issuance-process-retry-completed ${payload.clientId}`); + async handleBulkIssuanceRetry(_client: string, payload: ISocketInterface): Promise { + this.logger.log(`bulk-issuance-process-retry-completed ${payload.clientId}`) this.server .to(payload.clientId) - .emit('bulk-issuance-process-retry-completed', {fileUploadId: payload.fileUploadId}); + .emit('bulk-issuance-process-retry-completed', { fileUploadId: payload.fileUploadId }) } -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts b/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts index 393cbb536..cc3e4f54b 100644 --- a/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts +++ b/apps/api-gateway/src/cloud-wallet/cloud-wallet.controller.ts @@ -1,26 +1,61 @@ -import { IResponse } from '@credebl/common/interfaces/response.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { Controller, Post, Logger, Body, HttpStatus, Res, UseFilters, UseGuards, Get, Param, Query, BadRequestException } from '@nestjs/common'; -import { ApiBearerAuth, ApiForbiddenResponse, ApiOperation, ApiQuery, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { CloudWalletService } from './cloud-wallet.service'; -import { AcceptOfferDto, BasicMessageDTO, CreateCloudWalletDidDto, CreateCloudWalletDto, CredentialListDto, GetAllCloudWalletConnectionsDto, ReceiveInvitationUrlDTO } from './dtos/cloudWallet.dto'; -import { Response } from 'express'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { CloudBaseWalletConfigureDto } from './dtos/configure-base-wallet.dto'; -import { AuthGuard } from '@nestjs/passport'; -import { User } from '../authz/decorators/user.decorator'; +import { CommonConstants } from '@credebl/common/common.constant' +import type { + IBasicMessage, + IConnectionDetailsById, + ICredentialDetails, + IGetProofPresentation, + IGetProofPresentationById, + IWalletDetailsForDidList, +} from '@credebl/common/interfaces/cloud-wallet.interface' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Validator } from '@credebl/common/validator' +import { + BadRequestException, + Body, + Controller, + Get, + HttpStatus, + Logger, + Param, + Post, + Query, + Res, + UseFilters, + UseGuards, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' +import { + ApiBearerAuth, + ApiForbiddenResponse, + ApiOperation, + ApiQuery, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { user } from '@prisma/client'; -import { Validator } from '@credebl/common/validator'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { UserRoleGuard } from '../authz/guards/user-role.guard'; -import { AcceptProofRequestDto } from './dtos/accept-proof-request.dto'; -import { IBasicMessage, IConnectionDetailsById, ICredentialDetails, IGetProofPresentation, IGetProofPresentationById, IWalletDetailsForDidList } from '@credebl/common/interfaces/cloud-wallet.interface'; -import { CreateConnectionDto } from './dtos/create-connection.dto'; - +import type { user } from '@prisma/client' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { User } from '../authz/decorators/user.decorator' +import { UserRoleGuard } from '../authz/guards/user-role.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { CloudWalletService } from './cloud-wallet.service' +import type { AcceptProofRequestDto } from './dtos/accept-proof-request.dto' +import type { + AcceptOfferDto, + BasicMessageDTO, + CreateCloudWalletDidDto, + CreateCloudWalletDto, + CredentialListDto, + GetAllCloudWalletConnectionsDto, + ReceiveInvitationUrlDTO, +} from './dtos/cloudWallet.dto' +import type { CloudBaseWalletConfigureDto } from './dtos/configure-base-wallet.dto' +import type { CreateConnectionDto } from './dtos/create-connection.dto' @UseFilters(CustomExceptionFilter) @Controller() @@ -29,501 +64,557 @@ import { CreateConnectionDto } from './dtos/create-connection.dto'; @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) export class CloudWalletController { - - private readonly logger = new Logger('cloud-wallet'); - constructor(private readonly cloudWalletService: CloudWalletService) { } - - /** - * Configure cloud base wallet - * @param cloudBaseWalletConfigure - * @param user - * @param res - * @returns success message - */ - @Post('/configure/base-wallet') - @ApiOperation({ summary: 'Configure Cloud Base Wallet', description: 'Endpoint to configure the base wallet for the cloud wallet service.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Base wallet configured successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt')) - async configureBaseWallet( - @Res() res: Response, - @Body() cloudBaseWalletConfigure: CloudBaseWalletConfigureDto, - @User() user: user - ): Promise { - - const { id, email } = user; - - cloudBaseWalletConfigure.userId = id; - cloudBaseWalletConfigure.email = email; - - const configureBaseWalletData = await this.cloudWalletService.configureBaseWallet(cloudBaseWalletConfigure); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.cloudWallet.success.configureBaseWallet, - data: configureBaseWalletData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + private readonly logger = new Logger('cloud-wallet') + constructor(private readonly cloudWalletService: CloudWalletService) {} + + /** + * Configure cloud base wallet + * @param cloudBaseWalletConfigure + * @param user + * @param res + * @returns success message + */ + @Post('/configure/base-wallet') + @ApiOperation({ + summary: 'Configure Cloud Base Wallet', + description: 'Endpoint to configure the base wallet for the cloud wallet service.', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Base wallet configured successfully', type: ApiResponseDto }) + @UseGuards(AuthGuard('jwt')) + async configureBaseWallet( + @Res() res: Response, + @Body() cloudBaseWalletConfigure: CloudBaseWalletConfigureDto, + @User() user: user + ): Promise { + const { id, email } = user + + cloudBaseWalletConfigure.userId = id + cloudBaseWalletConfigure.email = email + + const configureBaseWalletData = await this.cloudWalletService.configureBaseWallet(cloudBaseWalletConfigure) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.configureBaseWallet, + data: configureBaseWalletData, } - - /** - * Create cloud wallet - * @param cloudWalletDetails - * @param res - * @returns Success message and wallet details - */ - @Post('/create-wallet') - @ApiOperation({ summary: 'Create Cloud Wallet', description: 'Endpoint to create a new cloud wallet for the user.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Cloud wallet created successfully', type: ApiResponseDto }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async createCloudWallet( - @Res() res: Response, - @Body() cloudWalletDetails: CreateCloudWalletDto, - @User() user: user - ): Promise { - const {email, id} = user; - cloudWalletDetails.email = email; - cloudWalletDetails.userId = id; - const cloudWalletData = await this.cloudWalletService.createCloudWallet(cloudWalletDetails); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.cloudWallet.success.create, - data: cloudWalletData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); - + return res.status(HttpStatus.CREATED).json(finalResponse) + } + + /** + * Create cloud wallet + * @param cloudWalletDetails + * @param res + * @returns Success message and wallet details + */ + @Post('/create-wallet') + @ApiOperation({ summary: 'Create Cloud Wallet', description: 'Endpoint to create a new cloud wallet for the user.' }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Cloud wallet created successfully', type: ApiResponseDto }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async createCloudWallet( + @Res() res: Response, + @Body() cloudWalletDetails: CreateCloudWalletDto, + @User() user: user + ): Promise { + const { email, id } = user + cloudWalletDetails.email = email + cloudWalletDetails.userId = id + const cloudWalletData = await this.cloudWalletService.createCloudWallet(cloudWalletDetails) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.create, + data: cloudWalletData, } - - /** - * Accept proof request - * @param acceptProofRequest - * @returns success message - */ - @Post('/proofs/accept-request') - @ApiOperation({ summary: 'Accept Proof Request', description: 'Endpoint to accept a proof request for the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Proof request accepted successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async acceptProofRequest( - @Res() res: Response, - @Body() acceptProofRequest: AcceptProofRequestDto, - @User() user: user - ): Promise { - const { id, email } = user; - acceptProofRequest.userId = id; - acceptProofRequest.email = email; - - const acceptProofRequestDetails = await this.cloudWalletService.acceptProofRequest(acceptProofRequest); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.cloudWallet.success.acceptProofRequest, - data: acceptProofRequestDetails - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) + } + + /** + * Accept proof request + * @param acceptProofRequest + * @returns success message + */ + @Post('/proofs/accept-request') + @ApiOperation({ + summary: 'Accept Proof Request', + description: 'Endpoint to accept a proof request for the cloud wallet.', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Proof request accepted successfully', type: ApiResponseDto }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async acceptProofRequest( + @Res() res: Response, + @Body() acceptProofRequest: AcceptProofRequestDto, + @User() user: user + ): Promise { + const { id, email } = user + acceptProofRequest.userId = id + acceptProofRequest.email = email + + const acceptProofRequestDetails = await this.cloudWalletService.acceptProofRequest(acceptProofRequest) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.acceptProofRequest, + data: acceptProofRequestDetails, } - - /** - * Get proof presentation by proof id - * @param proofRecordId - * @param res - * @returns success message - */ - @Get('/proofs/:proofRecordId') - @ApiOperation({ summary: 'Get Proof Presentation by ID', description: 'Endpoint to retrieve proof presentation details by proof record ID.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Proof presentation retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async getProofById( - @Param('proofRecordId') proofRecordId: string, - @Res() res: Response, - @User() user: user - ): Promise { - const { id, email } = user; - - const proofPresentationByIdPayload: IGetProofPresentationById = { - userId: id, - email, - proofRecordId - }; - - const getProofDetails = await this.cloudWalletService.getProofById(proofPresentationByIdPayload); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.getProofById, - data: getProofDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) + } + + /** + * Get proof presentation by proof id + * @param proofRecordId + * @param res + * @returns success message + */ + @Get('/proofs/:proofRecordId') + @ApiOperation({ + summary: 'Get Proof Presentation by ID', + description: 'Endpoint to retrieve proof presentation details by proof record ID.', + }) + @ApiResponse({ + status: HttpStatus.OK, + description: 'Proof presentation retrieved successfully', + type: ApiResponseDto, + }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async getProofById( + @Param('proofRecordId') proofRecordId: string, + @Res() res: Response, + @User() user: user + ): Promise { + const { id, email } = user + + const proofPresentationByIdPayload: IGetProofPresentationById = { + userId: id, + email, + proofRecordId, } - /** - * Get proof presentations - * @param threadId - * @param res - * @returns success message - */ - @Get('/proofs') - @ApiOperation({ summary: 'Get Proof Presentations', description: 'Endpoint to retrieve all proof presentations, optionally filtered by thread ID.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Proof presentations retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - @ApiQuery({ - name: 'threadId', - required: false - }) - async getProofPresentation( - @Res() res: Response, - @User() user: user, - @Query('threadId') threadId?: string - ): Promise { - - const { id, email } = user; - - const proofPresentationPayload: IGetProofPresentation = { - userId: id, - email, - threadId - }; - - const getProofDetails = await this.cloudWalletService.getProofPresentation(proofPresentationPayload); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.getProofPresentation, - data: getProofDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + const getProofDetails = await this.cloudWalletService.getProofById(proofPresentationByIdPayload) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.getProofById, + data: getProofDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Get proof presentations + * @param threadId + * @param res + * @returns success message + */ + @Get('/proofs') + @ApiOperation({ + summary: 'Get Proof Presentations', + description: 'Endpoint to retrieve all proof presentations, optionally filtered by thread ID.', + }) + @ApiResponse({ + status: HttpStatus.OK, + description: 'Proof presentations retrieved successfully', + type: ApiResponseDto, + }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + @ApiQuery({ + name: 'threadId', + required: false, + }) + async getProofPresentation( + @Res() res: Response, + @User() user: user, + @Query('threadId') threadId?: string + ): Promise { + const { id, email } = user + + const proofPresentationPayload: IGetProofPresentation = { + userId: id, + email, + threadId, } - /** - * Receive invitation by URL - * @param receiveInvitation - * @param res - * @returns Response from agent - */ - @Post('/receive-invitation-url') - @ApiOperation({ summary: 'Receive Invitation by URL', description: 'Endpoint to receive an invitation using a URL for the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Invitation received successfully', type: ApiResponseDto }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async receiveInvitationByUrl( - @Res() res: Response, - @Body() receiveInvitation: ReceiveInvitationUrlDTO, - @User() user: user - ): Promise { - const {email, id} = user; - receiveInvitation.email = email; - receiveInvitation.userId = id; - const receiveInvitationData = await this.cloudWalletService.receiveInvitationByUrl(receiveInvitation); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.cloudWallet.success.receive, - data: receiveInvitationData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); - + const getProofDetails = await this.cloudWalletService.getProofPresentation(proofPresentationPayload) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.getProofPresentation, + data: getProofDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Receive invitation by URL + * @param receiveInvitation + * @param res + * @returns Response from agent + */ + @Post('/receive-invitation-url') + @ApiOperation({ + summary: 'Receive Invitation by URL', + description: 'Endpoint to receive an invitation using a URL for the cloud wallet.', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Invitation received successfully', type: ApiResponseDto }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async receiveInvitationByUrl( + @Res() res: Response, + @Body() receiveInvitation: ReceiveInvitationUrlDTO, + @User() user: user + ): Promise { + const { email, id } = user + receiveInvitation.email = email + receiveInvitation.userId = id + const receiveInvitationData = await this.cloudWalletService.receiveInvitationByUrl(receiveInvitation) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.receive, + data: receiveInvitationData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) + } + + /** + * Accept offer + * @param acceptOffer + * @param res + * @returns Response from agent + */ + @Post('/accept-offer') + @ApiOperation({ + summary: 'Accept Credential Offer', + description: 'Endpoint to accept a credential offer for the cloud wallet.', + }) + @ApiResponse({ + status: HttpStatus.CREATED, + description: 'Credential offer accepted successfully', + type: ApiResponseDto, + }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async acceptOffer(@Res() res: Response, @Body() acceptOffer: AcceptOfferDto, @User() user: user): Promise { + const { email, id } = user + acceptOffer.email = email + acceptOffer.userId = id + const receiveInvitationData = await this.cloudWalletService.acceptOffer(acceptOffer) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.receive, + data: receiveInvitationData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) + } + + /** + * Create did + * @param createDidDto + * @param res + * @returns did + */ + @Post('/did') + @ApiOperation({ + summary: 'Create DID', + description: 'Endpoint to create a new DID (Decentralized Identifier) for the cloud wallet.', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'DID created successfully', type: ApiResponseDto }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async createDid( + @Body() createDidDto: CreateCloudWalletDidDto, + @User() user: user, + @Res() res: Response + ): Promise { + Validator.validateDid(createDidDto) + const { email, id } = user + createDidDto.email = email + createDidDto.userId = id + if (createDidDto.seed && CommonConstants.SEED_LENGTH !== createDidDto.seed.length) { + throw new BadRequestException(ResponseMessages.agent.error.seedChar, { + cause: new Error(), + description: ResponseMessages.errorMessages.badRequest, + }) } - /** - * Accept offer - * @param acceptOffer - * @param res - * @returns Response from agent - */ - @Post('/accept-offer') - @ApiOperation({ summary: 'Accept Credential Offer', description: 'Endpoint to accept a credential offer for the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Credential offer accepted successfully', type: ApiResponseDto }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async acceptOffer( - @Res() res: Response, - @Body() acceptOffer: AcceptOfferDto, - @User() user: user - ): Promise { - const {email, id} = user; - acceptOffer.email = email; - acceptOffer.userId = id; - const receiveInvitationData = await this.cloudWalletService.acceptOffer(acceptOffer); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.cloudWallet.success.receive, - data: receiveInvitationData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + const didDetails = await this.cloudWalletService.createDid(createDidDto) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.agent.success.createDid, + data: didDetails, } - /** - * Create did - * @param createDidDto - * @param res - * @returns did - */ - @Post('/did') - @ApiOperation({ summary: 'Create DID', description: 'Endpoint to create a new DID (Decentralized Identifier) for the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'DID created successfully', type: ApiResponseDto }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async createDid( - @Body() createDidDto: CreateCloudWalletDidDto, - @User() user: user, - @Res() res: Response - ): Promise { - Validator.validateDid(createDidDto); - const {email, id} = user; - createDidDto.email = email; - createDidDto.userId = id; - if (createDidDto.seed && CommonConstants.SEED_LENGTH !== createDidDto.seed.length) { - throw new BadRequestException(ResponseMessages.agent.error.seedChar, { - cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); - } - - const didDetails = await this.cloudWalletService.createDid(createDidDto); - - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.agent.success.createDid, - data: didDetails - }; - - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) + } + + /** + * Get DID list by organization id + * @param res + * @returns DID list + */ + @Get('/did') + @ApiOperation({ + summary: 'Get DID List', + description: 'Endpoint to retrieve the list of DIDs associated with the cloud wallet.', + }) + @ApiResponse({ status: HttpStatus.OK, description: 'DID list retrieved successfully', type: ApiResponseDto }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async getDidList(@Res() res: Response, @User() user: user): Promise { + const { id, email } = user + + const walletDetails: IWalletDetailsForDidList = { + userId: id, + email, } - /** - * Get DID list by organization id - * @param res - * @returns DID list - */ - @Get('/did') - @ApiOperation({ summary: 'Get DID List', description: 'Endpoint to retrieve the list of DIDs associated with the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'DID list retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async getDidList( - @Res() res: Response, - @User() user: user - ): Promise { - const { id, email } = user; - - const walletDetails: IWalletDetailsForDidList = { - userId: id, - email - }; - - const didListDetails = await this.cloudWalletService.getDidList(walletDetails); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.didList, - data: didListDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + const didListDetails = await this.cloudWalletService.getDidList(walletDetails) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.didList, + data: didListDetails, } - - /** - * Create connection invitation - * @param createConnection - * @param res - * @returns success message - */ - @Post('/connections/invitation') - @ApiOperation({ summary: 'Create Connection Invitation', description: 'Endpoint to create a connection invitation for the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Connection invitation created successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async createConnection( - @Res() res: Response, - @Body() createConnection: CreateConnectionDto, - @User() user: user - ): Promise { - const { id, email } = user; - createConnection.userId = id; - createConnection.email = email; - - const createConnectionDetails = await this.cloudWalletService.createConnection(createConnection); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.cloudWallet.success.createConnection, - data: createConnectionDetails - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Create connection invitation + * @param createConnection + * @param res + * @returns success message + */ + @Post('/connections/invitation') + @ApiOperation({ + summary: 'Create Connection Invitation', + description: 'Endpoint to create a connection invitation for the cloud wallet.', + }) + @ApiResponse({ + status: HttpStatus.CREATED, + description: 'Connection invitation created successfully', + type: ApiResponseDto, + }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async createConnection( + @Res() res: Response, + @Body() createConnection: CreateConnectionDto, + @User() user: user + ): Promise { + const { id, email } = user + createConnection.userId = id + createConnection.email = email + + const createConnectionDetails = await this.cloudWalletService.createConnection(createConnection) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.createConnection, + data: createConnectionDetails, } - - /** - * Get connection by connection id - * @param connectionId - * @param res - * @returns connection details - */ - @Get('/connection/:connectionId') - @ApiOperation({ summary: 'Get Connection by ID', description: 'Endpoint to retrieve connection details by connection ID.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Connection details retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async getconnectionById( - @Param('connectionId') connectionId: string, - @Res() res: Response, - @User() user: user - ): Promise { - const { id, email } = user; - - const connectionDetails: IConnectionDetailsById = { - userId: id, - email, - connectionId - }; - - const connectionDetailResponse = await this.cloudWalletService.getconnectionById(connectionDetails); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.connectionById, - data: connectionDetailResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) + } + + /** + * Get connection by connection id + * @param connectionId + * @param res + * @returns connection details + */ + @Get('/connection/:connectionId') + @ApiOperation({ + summary: 'Get Connection by ID', + description: 'Endpoint to retrieve connection details by connection ID.', + }) + @ApiResponse({ + status: HttpStatus.OK, + description: 'Connection details retrieved successfully', + type: ApiResponseDto, + }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async getconnectionById( + @Param('connectionId') connectionId: string, + @Res() res: Response, + @User() user: user + ): Promise { + const { id, email } = user + + const connectionDetails: IConnectionDetailsById = { + userId: id, + email, + connectionId, } - /** - * Get all wallet connections - * @param connectionListQueryOptions - * @param res - * @returns connection list - */ - @Get('/connections') - @ApiOperation({ summary: 'Get All Wallet Connections', description: 'Endpoint to retrieve all connections associated with the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Connections retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async getAllconnectionById( - @Query() connectionListQueryOptions: GetAllCloudWalletConnectionsDto, - @Res() res: Response, - @User() user: user - ): Promise { - const { id, email } = user; - - connectionListQueryOptions.userId = id; - connectionListQueryOptions.email = email; - - const connectionDetailResponse = await this.cloudWalletService.getAllconnectionById(connectionListQueryOptions); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.connectionList, - data: connectionDetailResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + const connectionDetailResponse = await this.cloudWalletService.getconnectionById(connectionDetails) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.connectionById, + data: connectionDetailResponse, } - - /** - * Get credential list by tenant id - * @param credentialListQueryOptions - * @param res - * @returns Credential list - */ - @Get('/credential') - @ApiOperation({ summary: 'Get Credential List', description: 'Endpoint to retrieve the list of credentials associated with the cloud wallet.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Credential list retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async getCredentialList( - @Query() credentialListQueryOptions: CredentialListDto, - @Res() res: Response, - @User() user: user - ): Promise { - const { id, email } = user; - - credentialListQueryOptions.userId = id; - credentialListQueryOptions.email = email; - - const connectionDetailResponse = await this.cloudWalletService.getCredentialList(credentialListQueryOptions); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.credentials, - data: connectionDetailResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Get all wallet connections + * @param connectionListQueryOptions + * @param res + * @returns connection list + */ + @Get('/connections') + @ApiOperation({ + summary: 'Get All Wallet Connections', + description: 'Endpoint to retrieve all connections associated with the cloud wallet.', + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Connections retrieved successfully', type: ApiResponseDto }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async getAllconnectionById( + @Query() connectionListQueryOptions: GetAllCloudWalletConnectionsDto, + @Res() res: Response, + @User() user: user + ): Promise { + const { id, email } = user + + connectionListQueryOptions.userId = id + connectionListQueryOptions.email = email + + const connectionDetailResponse = await this.cloudWalletService.getAllconnectionById(connectionListQueryOptions) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.connectionList, + data: connectionDetailResponse, } - - /** - * Get credential by credential record id - * @param credentialRecordId - * @param res - * @returns Credential details - */ - @Get('/credential/:credentialRecordId') - @ApiOperation({ summary: 'Get Credential by Record ID', description: 'Endpoint to retrieve credential details by credential record ID.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Credential details retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async getCredentialByCredentialRecordId( - @Param('credentialRecordId') credentialRecordId: string, - @Res() res: Response, - @User() user: user - ): Promise { - const { id, email } = user; - - const credentialDetails: ICredentialDetails = { - userId: id, - email, - credentialRecordId - }; - - const connectionDetailResponse = await this.cloudWalletService.getCredentialByCredentialRecordId(credentialDetails); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.credentialByRecordId, - data: connectionDetailResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Get credential list by tenant id + * @param credentialListQueryOptions + * @param res + * @returns Credential list + */ + @Get('/credential') + @ApiOperation({ + summary: 'Get Credential List', + description: 'Endpoint to retrieve the list of credentials associated with the cloud wallet.', + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Credential list retrieved successfully', type: ApiResponseDto }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async getCredentialList( + @Query() credentialListQueryOptions: CredentialListDto, + @Res() res: Response, + @User() user: user + ): Promise { + const { id, email } = user + + credentialListQueryOptions.userId = id + credentialListQueryOptions.email = email + + const connectionDetailResponse = await this.cloudWalletService.getCredentialList(credentialListQueryOptions) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.credentials, + data: connectionDetailResponse, } - - /** - * Get basic message by connection id - * @param connectionId - * @param res - * @returns Basic message details - */ - @Get('/basic-message/:connectionId') - @ApiOperation({ summary: 'Get Basic Message by Connection ID', description: 'Endpoint to retrieve basic message details by connection ID.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Basic message details retrieved successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async getBasicMessageByConnectionId( - @Param('connectionId') connectionId: string, - @Res() res: Response, - @User() user: user - ): Promise { - const { id, email } = user; - - const connectionDetails: IBasicMessage = { - userId: id, - email, - connectionId - }; - - const basicMessageDetailResponse = await this.cloudWalletService.getBasicMessageByConnectionId(connectionDetails); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.cloudWallet.success.basicMessageByConnectionId, - data: basicMessageDetailResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Get credential by credential record id + * @param credentialRecordId + * @param res + * @returns Credential details + */ + @Get('/credential/:credentialRecordId') + @ApiOperation({ + summary: 'Get Credential by Record ID', + description: 'Endpoint to retrieve credential details by credential record ID.', + }) + @ApiResponse({ + status: HttpStatus.OK, + description: 'Credential details retrieved successfully', + type: ApiResponseDto, + }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async getCredentialByCredentialRecordId( + @Param('credentialRecordId') credentialRecordId: string, + @Res() res: Response, + @User() user: user + ): Promise { + const { id, email } = user + + const credentialDetails: ICredentialDetails = { + userId: id, + email, + credentialRecordId, } - /** - * Send basic message - * @param connectionId - * @param messageDetails - * @param res - * @returns success message - */ - @Post('/basic-message/:connectionId') - @ApiOperation({ summary: 'Send Basic Message', description: 'Endpoint to send a basic message to a connection.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Basic message sent successfully', type: ApiResponseDto }) - @UseGuards(AuthGuard('jwt'), UserRoleGuard) - async sendBasicMessage( - @Param('connectionId') connectionId: string, - @Res() res: Response, - @Body() messageDetails: BasicMessageDTO, - @User() user: user - ): Promise { - const { id, email } = user; - messageDetails.userId = id; - messageDetails.email = email; - messageDetails.connectionId = connectionId; - const basicMessageDetails = await this.cloudWalletService.sendBasicMessage(messageDetails); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.cloudWallet.success.basicMessage, - data: basicMessageDetails - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + const connectionDetailResponse = await this.cloudWalletService.getCredentialByCredentialRecordId(credentialDetails) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.credentialByRecordId, + data: connectionDetailResponse, + } + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Get basic message by connection id + * @param connectionId + * @param res + * @returns Basic message details + */ + @Get('/basic-message/:connectionId') + @ApiOperation({ + summary: 'Get Basic Message by Connection ID', + description: 'Endpoint to retrieve basic message details by connection ID.', + }) + @ApiResponse({ + status: HttpStatus.OK, + description: 'Basic message details retrieved successfully', + type: ApiResponseDto, + }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async getBasicMessageByConnectionId( + @Param('connectionId') connectionId: string, + @Res() res: Response, + @User() user: user + ): Promise { + const { id, email } = user + + const connectionDetails: IBasicMessage = { + userId: id, + email, + connectionId, } + const basicMessageDetailResponse = await this.cloudWalletService.getBasicMessageByConnectionId(connectionDetails) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.cloudWallet.success.basicMessageByConnectionId, + data: basicMessageDetailResponse, + } + return res.status(HttpStatus.OK).json(finalResponse) + } + + /** + * Send basic message + * @param connectionId + * @param messageDetails + * @param res + * @returns success message + */ + @Post('/basic-message/:connectionId') + @ApiOperation({ summary: 'Send Basic Message', description: 'Endpoint to send a basic message to a connection.' }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Basic message sent successfully', type: ApiResponseDto }) + @UseGuards(AuthGuard('jwt'), UserRoleGuard) + async sendBasicMessage( + @Param('connectionId') connectionId: string, + @Res() res: Response, + @Body() messageDetails: BasicMessageDTO, + @User() user: user + ): Promise { + const { id, email } = user + messageDetails.userId = id + messageDetails.email = email + messageDetails.connectionId = connectionId + const basicMessageDetails = await this.cloudWalletService.sendBasicMessage(messageDetails) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.cloudWallet.success.basicMessage, + data: basicMessageDetails, + } + return res.status(HttpStatus.CREATED).json(finalResponse) + } } diff --git a/apps/api-gateway/src/cloud-wallet/cloud-wallet.module.ts b/apps/api-gateway/src/cloud-wallet/cloud-wallet.module.ts index fb43a467d..d1284f843 100644 --- a/apps/api-gateway/src/cloud-wallet/cloud-wallet.module.ts +++ b/apps/api-gateway/src/cloud-wallet/cloud-wallet.module.ts @@ -1,25 +1,22 @@ -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CloudWalletController } from './cloud-wallet.controller'; -import { CloudWalletService } from './cloud-wallet.service'; -import { Module } from '@nestjs/common'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { CloudWalletController } from './cloud-wallet.controller' +import { CloudWalletService } from './cloud-wallet.service' @Module({ - imports: [ - - ClientsModule.register([ - { - name: 'NATS_CLIENT', - transport: Transport.NATS, - options: getNatsOptions(CommonConstants.CLOUD_WALLET_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } - ]) - ], - controllers: [CloudWalletController], - providers: [CloudWalletService, NATSClient] + imports: [ + ClientsModule.register([ + { + name: 'NATS_CLIENT', + transport: Transport.NATS, + options: getNatsOptions(CommonConstants.CLOUD_WALLET_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), + ], + controllers: [CloudWalletController], + providers: [CloudWalletService, NATSClient], }) - -export class CloudWalletModule { -} \ No newline at end of file +export class CloudWalletModule {} diff --git a/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts b/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts index 8fb55f4a3..5af04de0d 100644 --- a/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts +++ b/apps/api-gateway/src/cloud-wallet/cloud-wallet.service.ts @@ -1,106 +1,139 @@ - -import { IAcceptOffer, ICreateCloudWallet, ICreateCloudWalletDid, IReceiveInvitation, IAcceptProofRequest, IProofRequestRes, ICloudBaseWalletConfigure, IGetProofPresentation, IGetProofPresentationById, IGetStoredWalletInfo, IStoredWalletDetails, IWalletDetailsForDidList, IConnectionDetailsById, ITenantDetail, ICredentialDetails, ICreateConnection, IConnectionInvitationResponse, GetAllCloudWalletConnections, IBasicMessage, IBasicMessageDetails } from '@credebl/common/interfaces/cloud-wallet.interface'; -import { Inject, Injectable} from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { + GetAllCloudWalletConnections, + IAcceptOffer, + IAcceptProofRequest, + IBasicMessage, + IBasicMessageDetails, + ICloudBaseWalletConfigure, + IConnectionDetailsById, + IConnectionInvitationResponse, + ICreateCloudWallet, + ICreateCloudWalletDid, + ICreateConnection, + ICredentialDetails, + IGetProofPresentation, + IGetProofPresentationById, + IGetStoredWalletInfo, + IProofRequestRes, + IReceiveInvitation, + IStoredWalletDetails, + ITenantDetail, + IWalletDetailsForDidList, +} from '@credebl/common/interfaces/cloud-wallet.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from 'libs/service/base.service' @Injectable() export class CloudWalletService extends BaseService { - constructor(@Inject('NATS_CLIENT') private readonly cloudWalletServiceProxy: ClientProxy, private readonly natsClient : NATSClient) { - super('CloudWalletServiceProxy'); + constructor( + @Inject('NATS_CLIENT') private readonly cloudWalletServiceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('CloudWalletServiceProxy') } - configureBaseWallet( - cloudBaseWalletConfigure: ICloudBaseWalletConfigure - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'configure-cloud-base-wallet', cloudBaseWalletConfigure); + configureBaseWallet(cloudBaseWalletConfigure: ICloudBaseWalletConfigure): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'configure-cloud-base-wallet', + cloudBaseWalletConfigure + ) } - createConnection( - createConnection: ICreateConnection - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'create-connection-by-holder', createConnection); + createConnection(createConnection: ICreateConnection): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'create-connection-by-holder', + createConnection + ) } - acceptProofRequest( - acceptProofRequest: IAcceptProofRequest - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'accept-proof-request-by-holder', acceptProofRequest); + acceptProofRequest(acceptProofRequest: IAcceptProofRequest): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'accept-proof-request-by-holder', + acceptProofRequest + ) } - getProofById( - proofPresentationByIdPayload: IGetProofPresentationById - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'get-proof-by-proof-id-holder', proofPresentationByIdPayload); + getProofById(proofPresentationByIdPayload: IGetProofPresentationById): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'get-proof-by-proof-id-holder', + proofPresentationByIdPayload + ) } - getProofPresentation( - proofPresentationPayload: IGetProofPresentation - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'get-proof-presentation-holder', proofPresentationPayload); + getProofPresentation(proofPresentationPayload: IGetProofPresentation): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'get-proof-presentation-holder', + proofPresentationPayload + ) } - createCloudWallet( - cloudWalletDetails: ICreateCloudWallet - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'create-cloud-wallet', cloudWalletDetails); + createCloudWallet(cloudWalletDetails: ICreateCloudWallet): Promise { + return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'create-cloud-wallet', cloudWalletDetails) } - receiveInvitationByUrl( - ReceiveInvitationDetails: IReceiveInvitation - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'receive-invitation-by-url', ReceiveInvitationDetails); + receiveInvitationByUrl(ReceiveInvitationDetails: IReceiveInvitation): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'receive-invitation-by-url', + ReceiveInvitationDetails + ) } - acceptOffer( - acceptOfferDetails: IAcceptOffer - ): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'accept-credential-offer', acceptOfferDetails); + acceptOffer(acceptOfferDetails: IAcceptOffer): Promise { + return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'accept-credential-offer', acceptOfferDetails) } - createDid(createDidDetails: ICreateCloudWalletDid): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'create-cloud-wallet-did', createDidDetails); -} + createDid(createDidDetails: ICreateCloudWalletDid): Promise { + return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'create-cloud-wallet-did', createDidDetails) + } -getDidList( - walletDetails: IWalletDetailsForDidList -): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'cloud-wallet-did-list', walletDetails); -} + getDidList(walletDetails: IWalletDetailsForDidList): Promise { + return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'cloud-wallet-did-list', walletDetails) + } -getconnectionById( - connectionDetails: IConnectionDetailsById -): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'get-cloud-wallet-connection-by-id', connectionDetails); -} -getAllconnectionById( - connectionDetails: GetAllCloudWalletConnections -): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'get-all-cloud-wallet-connections-list-by-id', connectionDetails); -} + getconnectionById(connectionDetails: IConnectionDetailsById): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'get-cloud-wallet-connection-by-id', + connectionDetails + ) + } + getAllconnectionById(connectionDetails: GetAllCloudWalletConnections): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'get-all-cloud-wallet-connections-list-by-id', + connectionDetails + ) + } -getCredentialList( - tenantDetails: ITenantDetail -): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'wallet-credential-by-id', tenantDetails); -} + getCredentialList(tenantDetails: ITenantDetail): Promise { + return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'wallet-credential-by-id', tenantDetails) + } -getCredentialByCredentialRecordId( - credentialDetails: ICredentialDetails -): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'wallet-credential-by-record-id', credentialDetails); -} + getCredentialByCredentialRecordId(credentialDetails: ICredentialDetails): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'wallet-credential-by-record-id', + credentialDetails + ) + } -getBasicMessageByConnectionId( - connectionDetails: IBasicMessage -): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'basic-message-list-by-connection-id', connectionDetails); -} + getBasicMessageByConnectionId(connectionDetails: IBasicMessage): Promise { + return this.natsClient.sendNatsMessage( + this.cloudWalletServiceProxy, + 'basic-message-list-by-connection-id', + connectionDetails + ) + } -sendBasicMessage( - messageDetails: IBasicMessageDetails -): Promise { - return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'send-basic-message', messageDetails); -} + sendBasicMessage(messageDetails: IBasicMessageDetails): Promise { + return this.natsClient.sendNatsMessage(this.cloudWalletServiceProxy, 'send-basic-message', messageDetails) + } } diff --git a/apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts b/apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts index 291639217..b4937391c 100644 --- a/apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts +++ b/apps/api-gateway/src/cloud-wallet/dtos/accept-proof-request.dto.ts @@ -1,29 +1,29 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator' export class AcceptProofRequestDto { @ApiProperty({ example: '4e687079-273b-447b-b9dd-9589c84dc6dd' }) @IsString({ message: 'proofRecordId must be a string' }) @IsNotEmpty({ message: 'please provide valid proofRecordId' }) @IsUUID() - proofRecordId: string; + proofRecordId: string @ApiPropertyOptional({ example: false }) @IsOptional() @IsBoolean({ message: 'filterByPresentationPreview must be a boolean' }) - filterByPresentationPreview?: boolean; + filterByPresentationPreview?: boolean @ApiPropertyOptional({ example: false }) @IsOptional() @IsBoolean({ message: 'filterByNonRevocationRequirements must be a boolean' }) - filterByNonRevocationRequirements?: boolean; + filterByNonRevocationRequirements?: boolean @ApiPropertyOptional({ example: '' }) @IsOptional() @IsString({ message: 'comment must be a string' }) - comment?: string; + comment?: string - userId: string; + userId: string - email: string; + email: string } diff --git a/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts b/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts index 4dde297c5..6a4258a14 100644 --- a/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts +++ b/apps/api-gateway/src/cloud-wallet/dtos/cloudWallet.dto.ts @@ -1,218 +1,220 @@ -import { IsBoolean, IsInt, IsNotEmpty, IsOptional, IsString, Matches, MaxLength } from 'class-validator'; +import { IsBoolean, IsInt, IsNotEmpty, IsOptional, IsString, Matches, MaxLength } from 'class-validator' -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsNotSQLInjection, trim } from '@credebl/common/cast.helper'; -import { Transform } from 'class-transformer'; +import { IsNotSQLInjection, trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class CreateCloudWalletDto { - @ApiProperty({ example: 'Credential Wallet', description: 'Cloud wallet label' }) - @IsString({ message: 'label must be a string' }) - @IsNotEmpty({ message: 'please provide valid label' }) - @Transform(({ value }) => trim(value)) - @IsNotSQLInjection({ message: 'label is required.' }) - label: string; - - @ApiProperty({ example: 'https://picsum.photos/200', description: 'Connection image URL' }) - @IsString({ message: 'Image URL must be a string' }) - @IsOptional() - @IsNotEmpty({ message: 'please provide valid image URL' }) - @Transform(({ value }) => trim(value)) - @IsNotSQLInjection({ message: 'Image URL is required.' }) - connectionImageUrl?: string; - - email?: string; - - userId?: string; + @ApiProperty({ example: 'Credential Wallet', description: 'Cloud wallet label' }) + @IsString({ message: 'label must be a string' }) + @IsNotEmpty({ message: 'please provide valid label' }) + @Transform(({ value }) => trim(value)) + @IsNotSQLInjection({ message: 'label is required.' }) + label: string + + @ApiProperty({ example: 'https://picsum.photos/200', description: 'Connection image URL' }) + @IsString({ message: 'Image URL must be a string' }) + @IsOptional() + @IsNotEmpty({ message: 'please provide valid image URL' }) + @Transform(({ value }) => trim(value)) + @IsNotSQLInjection({ message: 'Image URL is required.' }) + connectionImageUrl?: string + + email?: string + userId?: string } export class ReceiveInvitationUrlDTO { - @ApiPropertyOptional() - @IsString({ message: 'alias must be a string' }) - @IsOptional() - @IsNotEmpty({ message: 'please provide valid alias' }) - @Transform(({ value }) => trim(value)) - @IsNotSQLInjection({ message: 'alias is required.' }) - alias?: string; - - @ApiPropertyOptional() - @IsString({ message: 'label must be a string' }) - @IsOptional() - @IsNotEmpty({ message: 'please provide valid label' }) - @Transform(({ value }) => trim(value)) - @IsNotSQLInjection({ message: 'label is required.' }) - label?: string; - - @ApiPropertyOptional() - @IsString({ message: 'Image URL must be a string' }) - @IsOptional() - @IsNotEmpty({ message: 'please provide valid image URL' }) - @Transform(({ value }) => trim(value)) - @IsNotSQLInjection({ message: 'Image URL is required.' }) - imageUrl?: string; - - @ApiPropertyOptional() - @IsBoolean({ message: 'autoAcceptConnection must be a boolean' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - autoAcceptConnection?: boolean; - - @ApiPropertyOptional() - @IsBoolean({ message: 'autoAcceptInvitation must be a boolean' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - autoAcceptInvitation?: boolean; - - @ApiPropertyOptional() - @IsBoolean({ message: 'reuseConnection must be a boolean' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - reuseConnection?: boolean; - - @ApiPropertyOptional() - @IsInt({ message: 'acceptInvitationTimeoutMs must be an integer' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - acceptInvitationTimeoutMs?: number; - - @ApiPropertyOptional() - @IsString({ message: 'ourDid must be a string' }) - @IsOptional() - @IsNotEmpty({ message: 'please provide valid ourDid' }) - @Transform(({ value }) => trim(value)) - @IsNotSQLInjection({ message: 'ourDid is required.' }) - ourDid?: string; - - @ApiProperty() - @IsString({ message: 'invitationUrl must be a string' }) - @IsNotEmpty({ message: 'please provide valid invitationUrl' }) - @Transform(({ value }) => trim(value)) - @IsNotSQLInjection({ message: 'invitationUrl is required.' }) - invitationUrl: string; - - email?: string; - - userId?: string; - } - - export class AcceptOfferDto { - @ApiPropertyOptional({ example: 'always', description: 'autoAcceptCredential', enum: ['always', 'contentApproved', 'never'] }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'autoAcceptCredential must be a string' }) - autoAcceptCredential: string; - - @ApiPropertyOptional({ example: 'string', description: 'Comment' }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'comment must be a string' }) - @IsOptional() - comment?: string; - - @ApiProperty({ example: 'string', description: 'Credential record ID' }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'credentialRecordId must be a string' }) - credentialRecordId: string; - - @ApiProperty({ type: Object, description: 'Credential formats' }) - credentialFormats: object; - - email?: string; - - userId?: string; - } - - export class CreateCloudWalletDidDto { - - @ApiProperty({ example: '000000000000000000000000000Seed1' }) - @MaxLength(32, { message: 'seed must be at most 32 characters.' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @ApiPropertyOptional() - @IsString({ message: 'seed must be in string format.' }) - @Matches(/^\S*$/, { - message: 'Spaces are not allowed in seed' - }) - seed?: string; - - @ApiProperty({ example: 'ed25519'}) - @IsNotEmpty({ message: 'key type is required' }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'key type be in string format.' }) - keyType: string; - - @ApiProperty({ example: 'indy'}) - @IsNotEmpty({ message: 'method is required' }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'method must be in string format.' }) - method: string; - - @ApiPropertyOptional({example: 'bcovrin:testnet'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'network must be in string format.' }) - network?: string; - - @ApiPropertyOptional({example: 'www.github.com'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'domain must be in string format.' }) - domain?: string; - - @ApiPropertyOptional({example: 'endorser'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'role must be in string format.' }) - role?: string; - - @ApiPropertyOptional({example: '651727dab6dfdbb4f18afff5f368d13b0dca41fd26bd5e1c7953457524d645e6'}) - @IsOptional() - @IsString({ message: 'private key must be in string format.' }) - @Transform(({ value }) => trim(value)) - privatekey?: string; - - @ApiPropertyOptional({example: 'http://localhost:6006/docs'}) - @IsOptional() - @IsString({ message: 'endpoint must be in string format.' }) - endpoint?: string; - - @ApiPropertyOptional({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'did must be in string format.' }) - did?: string; - - @ApiPropertyOptional({example: 'did:indy:bcovrin:testnet:UEeW111G1tYo1nEkPwMcF'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'endorser did must be in string format.' }) - endorserDid?: string; - - email?: string; - - userId?: string; + @ApiPropertyOptional() + @IsString({ message: 'alias must be a string' }) + @IsOptional() + @IsNotEmpty({ message: 'please provide valid alias' }) + @Transform(({ value }) => trim(value)) + @IsNotSQLInjection({ message: 'alias is required.' }) + alias?: string + + @ApiPropertyOptional() + @IsString({ message: 'label must be a string' }) + @IsOptional() + @IsNotEmpty({ message: 'please provide valid label' }) + @Transform(({ value }) => trim(value)) + @IsNotSQLInjection({ message: 'label is required.' }) + label?: string + + @ApiPropertyOptional() + @IsString({ message: 'Image URL must be a string' }) + @IsOptional() + @IsNotEmpty({ message: 'please provide valid image URL' }) + @Transform(({ value }) => trim(value)) + @IsNotSQLInjection({ message: 'Image URL is required.' }) + imageUrl?: string + + @ApiPropertyOptional() + @IsBoolean({ message: 'autoAcceptConnection must be a boolean' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + autoAcceptConnection?: boolean + + @ApiPropertyOptional() + @IsBoolean({ message: 'autoAcceptInvitation must be a boolean' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + autoAcceptInvitation?: boolean + + @ApiPropertyOptional() + @IsBoolean({ message: 'reuseConnection must be a boolean' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + reuseConnection?: boolean + + @ApiPropertyOptional() + @IsInt({ message: 'acceptInvitationTimeoutMs must be an integer' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + acceptInvitationTimeoutMs?: number + + @ApiPropertyOptional() + @IsString({ message: 'ourDid must be a string' }) + @IsOptional() + @IsNotEmpty({ message: 'please provide valid ourDid' }) + @Transform(({ value }) => trim(value)) + @IsNotSQLInjection({ message: 'ourDid is required.' }) + ourDid?: string + + @ApiProperty() + @IsString({ message: 'invitationUrl must be a string' }) + @IsNotEmpty({ message: 'please provide valid invitationUrl' }) + @Transform(({ value }) => trim(value)) + @IsNotSQLInjection({ message: 'invitationUrl is required.' }) + invitationUrl: string + + email?: string + + userId?: string +} + +export class AcceptOfferDto { + @ApiPropertyOptional({ + example: 'always', + description: 'autoAcceptCredential', + enum: ['always', 'contentApproved', 'never'], + }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'autoAcceptCredential must be a string' }) + autoAcceptCredential: string + + @ApiPropertyOptional({ example: 'string', description: 'Comment' }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'comment must be a string' }) + @IsOptional() + comment?: string + + @ApiProperty({ example: 'string', description: 'Credential record ID' }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'credentialRecordId must be a string' }) + credentialRecordId: string + + @ApiProperty({ type: Object, description: 'Credential formats' }) + credentialFormats: object + + email?: string + + userId?: string +} + +export class CreateCloudWalletDidDto { + @ApiProperty({ example: '000000000000000000000000000Seed1' }) + @MaxLength(32, { message: 'seed must be at most 32 characters.' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @ApiPropertyOptional() + @IsString({ message: 'seed must be in string format.' }) + @Matches(/^\S*$/, { + message: 'Spaces are not allowed in seed', + }) + seed?: string + + @ApiProperty({ example: 'ed25519' }) + @IsNotEmpty({ message: 'key type is required' }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'key type be in string format.' }) + keyType: string + + @ApiProperty({ example: 'indy' }) + @IsNotEmpty({ message: 'method is required' }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'method must be in string format.' }) + method: string + + @ApiPropertyOptional({ example: 'bcovrin:testnet' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'network must be in string format.' }) + network?: string + + @ApiPropertyOptional({ example: 'www.github.com' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'domain must be in string format.' }) + domain?: string + + @ApiPropertyOptional({ example: 'endorser' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'role must be in string format.' }) + role?: string + + @ApiPropertyOptional({ example: '651727dab6dfdbb4f18afff5f368d13b0dca41fd26bd5e1c7953457524d645e6' }) + @IsOptional() + @IsString({ message: 'private key must be in string format.' }) + @Transform(({ value }) => trim(value)) + privatekey?: string + + @ApiPropertyOptional({ example: 'http://localhost:6006/docs' }) + @IsOptional() + @IsString({ message: 'endpoint must be in string format.' }) + endpoint?: string + + @ApiPropertyOptional({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'did must be in string format.' }) + did?: string + + @ApiPropertyOptional({ example: 'did:indy:bcovrin:testnet:UEeW111G1tYo1nEkPwMcF' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'endorser did must be in string format.' }) + endorserDid?: string + + email?: string + + userId?: string } export class CredentialListDto { - @ApiProperty({ required: false}) + @ApiProperty({ required: false }) @IsNotEmpty() @IsOptional() @IsString() - threadId: string; + threadId: string - @ApiProperty({ required: false}) + @ApiProperty({ required: false }) @IsNotEmpty() @IsOptional() @IsString() - connectionId: string; - - @ApiProperty({ required: false}) + connectionId: string + + @ApiProperty({ required: false }) @IsNotEmpty() @IsOptional() @IsString() - state: string; + state: string - email?: string; - - userId?: string; + email?: string + + userId?: string } export class GetAllCloudWalletConnectionsDto { @@ -220,47 +222,47 @@ export class GetAllCloudWalletConnectionsDto { @IsNotEmpty() @IsString() @IsOptional() - outOfBandId: string; + outOfBandId: string @ApiProperty({ required: false, example: 'Test' }) @IsNotEmpty() @IsString() @IsOptional() - alias: string; + alias: string @ApiProperty({ required: false, example: 'did:example:e315f30d-9beb-4068-aea4-abb5fe5eecb1' }) @IsNotEmpty() @IsString() @IsOptional() - myDid: string; + myDid: string @ApiProperty({ required: false, example: 'did:example:e315f30d-9beb-4068-aea4-abb5fe5eecb1' }) @IsNotEmpty() @IsString() @IsOptional() - theirDid: string; + theirDid: string @ApiProperty({ required: false, example: 'Bob' }) @IsNotEmpty() @IsString() @IsOptional() - theirLabel: string; + theirLabel: string + + email?: string - email?: string; - - userId?: string; + userId?: string } export class BasicMessageDTO { - @ApiProperty({ example: 'Message'}) + @ApiProperty({ example: 'Message' }) @IsNotEmpty({ message: 'content is required' }) @Transform(({ value }) => trim(value)) @IsString({ message: 'content should be in string format.' }) - content: string; + content: string - email?: string; - - userId?: string; + email?: string - connectionId: string; -} \ No newline at end of file + userId?: string + + connectionId: string +} diff --git a/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts b/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts index 7c14c928a..97b8675cf 100644 --- a/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts +++ b/apps/api-gateway/src/cloud-wallet/dtos/configure-base-wallet.dto.ts @@ -1,26 +1,26 @@ -import { IsNotEmpty, IsString } from 'class-validator'; +import { IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { IsHostPortOrDomain } from '@credebl/common/cast.helper'; +import { IsHostPortOrDomain } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' export class CloudBaseWalletConfigureDto { @ApiProperty({ example: 'xxx-xxxx-xxxx' }) @IsString({ message: 'walletKey must be a string' }) @IsNotEmpty({ message: 'please provide valid walletKey' }) - walletKey: string; + walletKey: string @ApiProperty({ example: 'xxx-xxxx-xxxx' }) @IsString({ message: 'apiKey must be a string' }) @IsNotEmpty({ message: 'please provide valid apiKey' }) - apiKey: string; + apiKey: string @ApiProperty({ example: 'http://0.0.0.0:4001' }) @IsString({ message: 'agentEndpoint must be a string' }) @IsNotEmpty({ message: 'please provide valid agentEndpoint' }) - @IsHostPortOrDomain({ message: 'Agent Endpoint must be a valid protocol://host:port or domain'}) - agentEndpoint: string; + @IsHostPortOrDomain({ message: 'Agent Endpoint must be a valid protocol://host:port or domain' }) + agentEndpoint: string - userId: string; + userId: string - email: string; + email: string } diff --git a/apps/api-gateway/src/cloud-wallet/dtos/create-connection.dto.ts b/apps/api-gateway/src/cloud-wallet/dtos/create-connection.dto.ts index 2ca7742d9..5496ae9f8 100644 --- a/apps/api-gateway/src/cloud-wallet/dtos/create-connection.dto.ts +++ b/apps/api-gateway/src/cloud-wallet/dtos/create-connection.dto.ts @@ -1,150 +1,150 @@ +import { ApiPropertyOptional } from '@nestjs/swagger' +import { Type } from 'class-transformer' import { - IsString, - IsBoolean, IsArray, - IsOptional, + IsBoolean, + IsISO8601, IsNumber, IsObject, - ValidateNested, + IsOptional, + IsString, IsUrl, - IsISO8601 -} from 'class-validator'; -import { Type } from 'class-transformer'; -import { ApiPropertyOptional } from '@nestjs/swagger'; + ValidateNested, +} from 'class-validator' class Thread { @IsString() @IsOptional() - pthid: string; + pthid: string @IsString() @IsOptional() - thid: string; + thid: string } class Message { @IsString() @IsOptional() - '@type': string; + '@type': string @IsString() @IsOptional() - '@id': string; + '@id': string @ValidateNested() @IsOptional() @Type(() => Thread) - '~thread': Thread; + '~thread': Thread @IsString() @IsOptional() - messageType: string; + messageType: string } class Data { @IsOptional() @IsString() - base64?: string; + base64?: string @IsOptional() @IsString() - json?: string; + json?: string @IsOptional() @IsArray() @IsUrl({}, { each: true }) - links?: string[]; + links?: string[] @IsOptional() @IsObject() jws?: { - header: object; - signature: string; - protected: string; - }; + header: object + signature: string + protected: string + } @IsOptional() @IsString() - sha256?: string; + sha256?: string } class AppendedAttachment { @IsString() @IsOptional() - id: string; + id: string @IsString() @IsOptional() - description: string; + description: string @IsString() @IsOptional() - filename: string; + filename: string @IsString() @IsOptional() - mimeType: string; + mimeType: string @IsISO8601() @IsOptional() - lastmodTime: string; + lastmodTime: string @IsNumber() @IsOptional() - byteCount: number; + byteCount: number @ValidateNested() @IsOptional() @Type(() => Data) - data: Data; + data: Data } export class CreateConnectionDto { @ApiPropertyOptional() @IsString() @IsOptional() - label: string; + label: string @ApiPropertyOptional() @IsString() @IsOptional() - alias: string; + alias: string @ApiPropertyOptional() @IsString() @IsOptional() - imageUrl: string; + imageUrl: string @ApiPropertyOptional({ example: true }) @IsBoolean() @IsOptional() - multiUseInvitation: boolean; + multiUseInvitation: boolean @ApiPropertyOptional({ example: true }) @IsBoolean() @IsOptional() - autoAcceptConnection: boolean; + autoAcceptConnection: boolean @ApiPropertyOptional() @IsString() @IsOptional() - goalCode: string; + goalCode: string @ApiPropertyOptional() @IsString() @IsOptional() - goal: string; + goal: string @ApiPropertyOptional({ example: true }) @IsBoolean() @IsOptional() - handshake: boolean; + handshake: boolean @ApiPropertyOptional({ example: ['https://didcomm.org/didexchange/1.x'] }) @IsOptional() @IsArray() @IsUrl({}, { each: true }) - handshakeProtocols: string[]; + handshakeProtocols: string[] @ApiPropertyOptional({ example: [ @@ -153,20 +153,20 @@ export class CreateConnectionDto { '@id': 'string', '~thread': { pthid: 'string', - thid: 'string' + thid: 'string', }, messageType: 'string', additionalProp1: 'string', additionalProp2: 'string', - additionalProp3: 'string' - } - ] + additionalProp3: 'string', + }, + ], }) @IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => Message) - messages: Message[]; + messages: Message[] @ApiPropertyOptional({ example: [ @@ -184,29 +184,29 @@ export class CreateConnectionDto { jws: { header: {}, signature: 'string', - protected: 'string' + protected: 'string', }, - sha256: 'string' - } - } - ] + sha256: 'string', + }, + }, + ], }) @IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => AppendedAttachment) - appendedAttachments: AppendedAttachment[]; + appendedAttachments: AppendedAttachment[] @ApiPropertyOptional() @IsOptional() @IsString() - invitationDid: string; + invitationDid: string @ApiPropertyOptional() @IsOptional() @IsString() - recipientKey: string; + recipientKey: string - userId: string; - email: string; + userId: string + email: string } diff --git a/apps/api-gateway/src/cloud-wallet/enums/connections.enum.ts b/apps/api-gateway/src/cloud-wallet/enums/connections.enum.ts index a15929cf6..029bcd7b6 100644 --- a/apps/api-gateway/src/cloud-wallet/enums/connections.enum.ts +++ b/apps/api-gateway/src/cloud-wallet/enums/connections.enum.ts @@ -1,4 +1,4 @@ export declare enum HandshakeProtocol { - Connections = "https://didcomm.org/connections/1.0", - DidExchange = "https://didcomm.org/didexchange/1.0" -} \ No newline at end of file + Connections = 'https://didcomm.org/connections/1.0', + DidExchange = 'https://didcomm.org/didexchange/1.0', +} diff --git a/apps/api-gateway/src/connection/connection.controller.ts b/apps/api-gateway/src/connection/connection.controller.ts index e72848f9a..ca7927cae 100644 --- a/apps/api-gateway/src/connection/connection.controller.ts +++ b/apps/api-gateway/src/connection/connection.controller.ts @@ -1,29 +1,58 @@ -import { IResponse } from '@credebl/common/interfaces/response.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { Controller, Post, Logger, Body, UseGuards, HttpStatus, Res, Get, Param, UseFilters, Query, Inject, ParseUUIDPipe, BadRequestException, Delete } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; -import { ApiBearerAuth, ApiExcludeEndpoint, ApiForbiddenResponse, ApiOperation, ApiQuery, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; -import { User } from '../authz/decorators/user.decorator'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ConnectionService } from './connection.service'; -import { ConnectionDto, CreateOutOfBandConnectionInvitation, ReceiveInvitationDto, ReceiveInvitationUrlDto } from './dtos/connection.dto'; -import { IUserRequestInterface } from './interfaces'; -import { Response } from 'express'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { GetAllAgentConnectionsDto, GetAllConnectionsDto } from './dtos/get-all-connections.dto'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; -import { SortFields } from 'apps/connection/src/enum/connection.enum'; -import { ClientProxy} from '@nestjs/microservices'; -import { BasicMessageDto, QuestionAnswerWebhookDto, QuestionDto} from './dtos/question-answer.dto'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import { user } from '@prisma/client'; -import { TrimStringParamPipe } from '@credebl/common/cast.helper'; +import { TrimStringParamPipe } from '@credebl/common/cast.helper' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { + BadRequestException, + Body, + Controller, + Delete, + Get, + HttpStatus, + Inject, + Logger, + Param, + ParseUUIDPipe, + Post, + Query, + Res, + UseFilters, + UseGuards, +} from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { AuthGuard } from '@nestjs/passport' +import { + ApiBearerAuth, + ApiExcludeEndpoint, + ApiForbiddenResponse, + ApiOperation, + ApiQuery, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import type { user } from '@prisma/client' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import { SortFields } from 'apps/connection/src/enum/connection.enum' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface' +import type { ConnectionService } from './connection.service' +import type { + ConnectionDto, + CreateOutOfBandConnectionInvitation, + ReceiveInvitationDto, + ReceiveInvitationUrlDto, +} from './dtos/connection.dto' +import type { GetAllAgentConnectionsDto, GetAllConnectionsDto } from './dtos/get-all-connections.dto' +import type { BasicMessageDto, QuestionAnswerWebhookDto, QuestionDto } from './dtos/question-answer.dto' +import type { IUserRequestInterface } from './interfaces' @UseFilters(CustomExceptionFilter) @Controller() @ApiTags('connections') @@ -31,97 +60,113 @@ import { TrimStringParamPipe } from '@credebl/common/cast.helper'; @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) export class ConnectionController { + private readonly logger = new Logger('Connection') + constructor( + private readonly connectionService: ConnectionService, + @Inject('NATS_CLIENT') private readonly connectionServiceProxy: ClientProxy + ) {} - private readonly logger = new Logger('Connection'); - constructor(private readonly connectionService: ConnectionService, - @Inject('NATS_CLIENT') private readonly connectionServiceProxy: ClientProxy - ) { } - - /** - * Get connection details by connectionId - * @param connectionId The ID of the connection - * @param orgId The ID of the organization - * @returns Connection details by connection Id - */ - @Get('orgs/:orgId/connections/:connectionId') - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) - @ApiOperation({ - summary: `Get connection details by connectionId`, - description: `Retrieve the details of a specific connection by its connectionId for a specific organization.` - }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getConnectionsById( - @User() user: IUserRequest, - @Param('orgId') orgId: string, - @Param('connectionId', TrimStringParamPipe, new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.connection.error.invalidConnectionId); }})) connectionId: string, - @Res() res: Response - ): Promise { - const connectionsDetails = await this.connectionService.getConnectionsById(user, connectionId, orgId); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.connection.success.fetchConnection, - data: connectionsDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Get connection details by connectionId + * @param connectionId The ID of the connection + * @param orgId The ID of the organization + * @returns Connection details by connection Id + */ + @Get('orgs/:orgId/connections/:connectionId') + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) + @ApiOperation({ + summary: 'Get connection details by connectionId', + description: 'Retrieve the details of a specific connection by its connectionId for a specific organization.', + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getConnectionsById( + @User() user: IUserRequest, + @Param('orgId') orgId: string, + @Param( + 'connectionId', + TrimStringParamPipe, + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.connection.error.invalidConnectionId) + }, + }) + ) + connectionId: string, + @Res() res: Response + ): Promise { + const connectionsDetails = await this.connectionService.getConnectionsById(user, connectionId, orgId) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.connection.success.fetchConnection, + data: connectionsDetails, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Get all connections - * @param user The user making the request - * @param orgId The ID of the organization - * @returns List of all connections for a specific organization - */ - @Get('/orgs/:orgId/connections') - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) - @ApiOperation({ - summary: `Fetch all connections by orgId`, - description: `Retrieve all connections for a specific organization. Supports pagination and sorting.` - }) - @ApiQuery({ - name: 'sortField', - enum: SortFields, - required: false - }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getConnections( - @Query() getAllConnectionsDto: GetAllConnectionsDto, - @User() user: IUserRequest, - @Param('orgId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(`Invalid format for orgId`); }})) orgId: string, - @Res() res: Response - ): Promise { - - const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllConnectionsDto; - const connectionSearchCriteria: IConnectionSearchCriteria = { - pageNumber, - searchByText, - pageSize, - sortField, - sortBy - }; - const connectionDetails = await this.connectionService.getConnections(connectionSearchCriteria, user, orgId); + /** + * Get all connections + * @param user The user making the request + * @param orgId The ID of the organization + * @returns List of all connections for a specific organization + */ + @Get('/orgs/:orgId/connections') + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) + @ApiOperation({ + summary: 'Fetch all connections by orgId', + description: 'Retrieve all connections for a specific organization. Supports pagination and sorting.', + }) + @ApiQuery({ + name: 'sortField', + enum: SortFields, + required: false, + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getConnections( + @Query() getAllConnectionsDto: GetAllConnectionsDto, + @User() user: IUserRequest, + @Param( + 'orgId', + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, + @Res() res: Response + ): Promise { + const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllConnectionsDto + const connectionSearchCriteria: IConnectionSearchCriteria = { + pageNumber, + searchByText, + pageSize, + sortField, + sortBy, + } + const connectionDetails = await this.connectionService.getConnections(connectionSearchCriteria, user, orgId) - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.connection.success.fetch, - data: connectionDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.connection.success.fetch, + data: connectionDetails, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Get all connections from agent - * @param user The user making the request - * @param orgId The ID of the organization - * @returns List of all connections from agent for a specific organization - */ + /** + * Get all connections from agent + * @param user The user making the request + * @param orgId The ID of the organization + * @returns List of all connections from agent for a specific organization + */ @Get('/orgs/:orgId/agent/connections') @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @ApiOperation({ - summary: `Fetch all connections from agent by orgId`, - description: `Retrieve all connections from agent for the organization.` + summary: 'Fetch all connections from agent by orgId', + description: 'Retrieve all connections from agent for the organization.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getConnectionListFromAgent( @@ -129,79 +174,84 @@ export class ConnectionController { @Param('orgId') orgId: string, @Res() res: Response ): Promise { - - const connectionDetails = await this.connectionService.getConnectionListFromAgent( - getAllConnectionsDto, - orgId - ); + const connectionDetails = await this.connectionService.getConnectionListFromAgent(getAllConnectionsDto, orgId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.connection.success.fetch, - data: connectionDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: connectionDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } - - /** - * Get question-answer record - * @param orgId The ID of the organization - * @returns Question-answer record for a specific organization - */ - @Get('orgs/:orgId/question-answer/question') - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER, OrgRoles.SUPER_ADMIN, OrgRoles.PLATFORM_ADMIN) - @ApiOperation({ - summary: `Get question-answer record`, - description: `Retrieve the question-answer record for a specific organization.` - }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getQuestionAnswersRecord( - @Param('orgId') orgId: string, - @Res() res: Response - ): Promise { - const record = await this.connectionService.getQuestionAnswersRecord(orgId); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.connection.success.questionAnswerRecord, - data: record - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Get question-answer record + * @param orgId The ID of the organization + * @returns Question-answer record for a specific organization + */ + @Get('orgs/:orgId/question-answer/question') + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles( + OrgRoles.OWNER, + OrgRoles.ADMIN, + OrgRoles.ISSUER, + OrgRoles.VERIFIER, + OrgRoles.MEMBER, + OrgRoles.HOLDER, + OrgRoles.SUPER_ADMIN, + OrgRoles.PLATFORM_ADMIN + ) + @ApiOperation({ + summary: 'Get question-answer record', + description: 'Retrieve the question-answer record for a specific organization.', + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getQuestionAnswersRecord(@Param('orgId') orgId: string, @Res() res: Response): Promise { + const record = await this.connectionService.getQuestionAnswersRecord(orgId) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.connection.success.questionAnswerRecord, + data: record, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Create out-of-band connection invitation - * @param orgId The ID of the organization - * @param createOutOfBandConnectionInvitation The details of the out-of-band connection invitation - * @param reqUser The user making the request - * @param res The response object - * @returns Created out-of-band connection invitation URL - */ - @Post('/orgs/:orgId/connections') - @ApiOperation({ summary: 'Create outbound out-of-band connection invitation', description: 'Create an outbound out-of-band connection invitation for the organization.' }) - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) - async createConnectionInvitation( - @Param('orgId') orgId: string, - @Body() createOutOfBandConnectionInvitation: CreateOutOfBandConnectionInvitation, - @User() reqUser: IUserRequestInterface, - @Res() res: Response - ): Promise { - - createOutOfBandConnectionInvitation.orgId = orgId; - const connectionData = await this.connectionService.createConnectionInvitation(createOutOfBandConnectionInvitation, reqUser); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.connection.success.create, - data: connectionData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); - - } + /** + * Create out-of-band connection invitation + * @param orgId The ID of the organization + * @param createOutOfBandConnectionInvitation The details of the out-of-band connection invitation + * @param reqUser The user making the request + * @param res The response object + * @returns Created out-of-band connection invitation URL + */ + @Post('/orgs/:orgId/connections') + @ApiOperation({ + summary: 'Create outbound out-of-band connection invitation', + description: 'Create an outbound out-of-band connection invitation for the organization.', + }) + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) + async createConnectionInvitation( + @Param('orgId') orgId: string, + @Body() createOutOfBandConnectionInvitation: CreateOutOfBandConnectionInvitation, + @User() reqUser: IUserRequestInterface, + @Res() res: Response + ): Promise { + createOutOfBandConnectionInvitation.orgId = orgId + const connectionData = await this.connectionService.createConnectionInvitation( + createOutOfBandConnectionInvitation, + reqUser + ) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.connection.success.create, + data: connectionData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) + } - /** + /** * Send question * @param orgId The ID of the organization * @param connectionId The ID of the connection @@ -210,31 +260,38 @@ export class ConnectionController { * @param res The response object * @returns The details of the sent question */ - @Post('/orgs/:orgId/question-answer/question/:connectionId') - @ApiOperation({ summary: 'Send question', description: 'Send a question to the connection ID' }) - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER, OrgRoles.SUPER_ADMIN, OrgRoles.PLATFORM_ADMIN) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) - async sendQuestion( - @Param('orgId') orgId: string, - @Param('connectionId', TrimStringParamPipe) connectionId: string, - @Body() questionDto: QuestionDto, - @User() reqUser: IUserRequestInterface, - @Res() res: Response - ): Promise { - - questionDto.orgId = orgId; - questionDto.connectionId = connectionId; - const questionData = await this.connectionService.sendQuestion(questionDto); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.connection.success.questionSend, - data: questionData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); - + @Post('/orgs/:orgId/question-answer/question/:connectionId') + @ApiOperation({ summary: 'Send question', description: 'Send a question to the connection ID' }) + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles( + OrgRoles.OWNER, + OrgRoles.ADMIN, + OrgRoles.ISSUER, + OrgRoles.VERIFIER, + OrgRoles.MEMBER, + OrgRoles.HOLDER, + OrgRoles.SUPER_ADMIN, + OrgRoles.PLATFORM_ADMIN + ) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) + async sendQuestion( + @Param('orgId') orgId: string, + @Param('connectionId', TrimStringParamPipe) connectionId: string, + @Body() questionDto: QuestionDto, + @User() _reqUser: IUserRequestInterface, + @Res() res: Response + ): Promise { + questionDto.orgId = orgId + questionDto.connectionId = connectionId + const questionData = await this.connectionService.sendQuestion(questionDto) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.connection.success.questionSend, + data: questionData, } - /** + return res.status(HttpStatus.CREATED).json(finalResponse) + } + /** * Receive Invitation URL * @param orgId The ID of the organization * @param receiveInvitationUrl The details of the invitation URL @@ -242,27 +299,26 @@ export class ConnectionController { * @param res The response object * @returns The details of the received invitation URL */ - @Post('/orgs/:orgId/receive-invitation-url') - @ApiOperation({ summary: 'Receive Invitation URL', description: 'Receive an invitation URL for the organization.' }) - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) - async receiveInvitationUrl( - @Param('orgId') orgId: string, - @Body() receiveInvitationUrl: ReceiveInvitationUrlDto, - @User() user: IUserRequestInterface, - @Res() res: Response - ): Promise { - - const connectionData = await this.connectionService.receiveInvitationUrl(receiveInvitationUrl, orgId, user); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.connection.success.receivenvitation, - data: connectionData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + @Post('/orgs/:orgId/receive-invitation-url') + @ApiOperation({ summary: 'Receive Invitation URL', description: 'Receive an invitation URL for the organization.' }) + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) + async receiveInvitationUrl( + @Param('orgId') orgId: string, + @Body() receiveInvitationUrl: ReceiveInvitationUrlDto, + @User() user: IUserRequestInterface, + @Res() res: Response + ): Promise { + const connectionData = await this.connectionService.receiveInvitationUrl(receiveInvitationUrl, orgId, user) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.connection.success.receivenvitation, + data: connectionData, } - /** + return res.status(HttpStatus.CREATED).json(finalResponse) + } + /** * Receive Invitation * @param orgId The ID of the organization * @param receiveInvitation The details of the invitation @@ -270,38 +326,40 @@ export class ConnectionController { * @param res The response object * @returns The details of the received invitation */ - @Post('/orgs/:orgId/receive-invitation') - @ApiOperation({ summary: 'Receive Invitation', description: 'Receive an invitation for the organization using the invitation object.' }) - @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) - async receiveInvitation( - @Param('orgId') orgId: string, - @Body() receiveInvitation: ReceiveInvitationDto, - @User() user: IUserRequestInterface, - @Res() res: Response - ): Promise { - - const connectionData = await this.connectionService.receiveInvitation(receiveInvitation, orgId, user); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.connection.success.receivenvitation, - data: connectionData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + @Post('/orgs/:orgId/receive-invitation') + @ApiOperation({ + summary: 'Receive Invitation', + description: 'Receive an invitation for the organization using the invitation object.', + }) + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) + async receiveInvitation( + @Param('orgId') orgId: string, + @Body() receiveInvitation: ReceiveInvitationDto, + @User() user: IUserRequestInterface, + @Res() res: Response + ): Promise { + const connectionData = await this.connectionService.receiveInvitation(receiveInvitation, orgId, user) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.connection.success.receivenvitation, + data: connectionData, } + return res.status(HttpStatus.CREATED).json(finalResponse) + } - /** - * Catch connection webhook responses - * @param connectionDto The details of the connection - * @param orgId The ID of the organization - * @returns Callback URL for connection and created connections details - */ + /** + * Catch connection webhook responses + * @param connectionDto The details of the connection + * @param orgId The ID of the organization + * @returns Callback URL for connection and created connections details + */ @Post('wh/:orgId/connections/') @ApiExcludeEndpoint() @ApiOperation({ summary: 'Catch connection webhook responses', - description: 'Receive connection webhook responses for the organization.' + description: 'Receive connection webhook responses for the organization.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) async getConnectionWebhook( @@ -309,70 +367,74 @@ export class ConnectionController { @Param('orgId') orgId: string, @Res() res: Response ): Promise { - connectionDto.type = 'Connection'; - this.logger.debug(`connectionDto ::: ${JSON.stringify(connectionDto)} ${orgId}`); - - if (orgId && 'default' === connectionDto?.contextCorrelationId) { - connectionDto.orgId = orgId; + connectionDto.type = 'Connection' + this.logger.debug(`connectionDto ::: ${JSON.stringify(connectionDto)} ${orgId}`) + + if (orgId && connectionDto?.contextCorrelationId === 'default') { + connectionDto.orgId = orgId } - const connectionData = await this.connectionService.getConnectionWebhook(connectionDto, orgId).catch(error => { - this.logger.debug(`error in saving connection webhook ::: ${JSON.stringify(error)}`); - }); + const connectionData = await this.connectionService.getConnectionWebhook(connectionDto, orgId).catch((error) => { + this.logger.debug(`error in saving connection webhook ::: ${JSON.stringify(error)}`) + }) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.connection.success.create, - data: connectionData - }; - const webhookUrl = await this.connectionService._getWebhookUrl(connectionDto?.contextCorrelationId, orgId).catch(error => { - this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`); - - }); - if (webhookUrl) { - await this.connectionService._postWebhookResponse(webhookUrl, { data: connectionDto }).catch(error => { - this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`); - }); - } - return res.status(HttpStatus.CREATED).json(finalResponse); + data: connectionData, + } + const webhookUrl = await this.connectionService + ._getWebhookUrl(connectionDto?.contextCorrelationId, orgId) + .catch((error) => { + this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`) + }) + if (webhookUrl) { + await this.connectionService._postWebhookResponse(webhookUrl, { data: connectionDto }).catch((error) => { + this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`) + }) + } + return res.status(HttpStatus.CREATED).json(finalResponse) } -/** - * Catch question-answer webhook responses - * @param questionAnswerWebhookDto The details of the question-answer webhook - * @param orgId The ID of the organization - * @returns Callback URL for question-answer - */ + /** + * Catch question-answer webhook responses + * @param questionAnswerWebhookDto The details of the question-answer webhook + * @param orgId The ID of the organization + * @returns Callback URL for question-answer + */ @Post('wh/:orgId/question-answer/') @ApiExcludeEndpoint() @ApiOperation({ summary: 'Catch question-answer webhook responses', - description: 'Receive question-answer webhook responses for the organization.' + description: 'Receive question-answer webhook responses for the organization.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) async getQuestionAnswerWebhook( - @Body() questionAnswerWebhookDto:QuestionAnswerWebhookDto, + @Body() questionAnswerWebhookDto: QuestionAnswerWebhookDto, @Param('orgId') orgId: string, @Res() res: Response ): Promise { - questionAnswerWebhookDto.type = 'question-answer'; - this.logger.debug(`questionAnswer ::: ${JSON.stringify(questionAnswerWebhookDto)} ${orgId}`); - + questionAnswerWebhookDto.type = 'question-answer' + this.logger.debug(`questionAnswer ::: ${JSON.stringify(questionAnswerWebhookDto)} ${orgId}`) + const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.connection.success.create, - data: '' - }; - const webhookUrl = await this.connectionService._getWebhookUrl(questionAnswerWebhookDto?.contextCorrelationId, orgId).catch(error => { - this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`); - - }); - + data: '', + } + const webhookUrl = await this.connectionService + ._getWebhookUrl(questionAnswerWebhookDto?.contextCorrelationId, orgId) + .catch((error) => { + this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`) + }) + if (webhookUrl) { - await this.connectionService._postWebhookResponse(webhookUrl, { data: questionAnswerWebhookDto }).catch(error => { - this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`); - }); - } - return res.status(HttpStatus.CREATED).json(finalResponse); + await this.connectionService + ._postWebhookResponse(webhookUrl, { data: questionAnswerWebhookDto }) + .catch((error) => { + this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`) + }) + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** * Delete connection record @@ -392,52 +454,71 @@ export class ConnectionController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @User() user: user, @Res() res: Response ): Promise { - await this.connectionService.deleteConnectionRecords(orgId, user); + await this.connectionService.deleteConnectionRecords(orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.connection.success.deleteConnectionRecord - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.connection.success.deleteConnectionRecord, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** - * Send basic message - * @param orgId The ID of the organization - * @param connectionId The ID of the connection - * @param basicMessageDto The details of the basic message - * @param reqUser The user making the request - * @param res The response object - * @returns The details of the sent basic message - */ + * Send basic message + * @param orgId The ID of the organization + * @param connectionId The ID of the connection + * @param basicMessageDto The details of the basic message + * @param reqUser The user making the request + * @param res The response object + * @returns The details of the sent basic message + */ @Post('/orgs/:orgId/basic-message/:connectionId') - @ApiOperation({ summary: 'Send basic message', description: 'Send a basic message to a specific connection for a specific organization.' }) + @ApiOperation({ + summary: 'Send basic message', + description: 'Send a basic message to a specific connection for a specific organization.', + }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER, OrgRoles.SUPER_ADMIN, OrgRoles.PLATFORM_ADMIN) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) - async sendBasicMessage( - @Param('orgId') orgId: string, - @Param('connectionId', TrimStringParamPipe, new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.connection.error.invalidConnectionId); }})) connectionId: string, - @Body() basicMessageDto: BasicMessageDto, - @User() reqUser: IUserRequestInterface, - @Res() res: Response - ): Promise { - - basicMessageDto.orgId = orgId; - basicMessageDto.connectionId = connectionId; - const basicMesgResponse = await this.connectionService.sendBasicMessage(basicMessageDto); - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.connection.success.basicMessage, - data: basicMesgResponse - }; - return res.status(HttpStatus.CREATED).json(finalResponse); - + @Roles( + OrgRoles.OWNER, + OrgRoles.ADMIN, + OrgRoles.ISSUER, + OrgRoles.VERIFIER, + OrgRoles.MEMBER, + OrgRoles.HOLDER, + OrgRoles.SUPER_ADMIN, + OrgRoles.PLATFORM_ADMIN + ) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) + async sendBasicMessage( + @Param('orgId') orgId: string, + @Param( + 'connectionId', + TrimStringParamPipe, + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.connection.error.invalidConnectionId) + }, + }) + ) + connectionId: string, + @Body() basicMessageDto: BasicMessageDto, + @User() _reqUser: IUserRequestInterface, + @Res() res: Response + ): Promise { + basicMessageDto.orgId = orgId + basicMessageDto.connectionId = connectionId + const basicMesgResponse = await this.connectionService.sendBasicMessage(basicMessageDto) + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.connection.success.basicMessage, + data: basicMesgResponse, } + return res.status(HttpStatus.CREATED).json(finalResponse) + } } diff --git a/apps/api-gateway/src/connection/connection.module.ts b/apps/api-gateway/src/connection/connection.module.ts index 0a578b400..baddf1ab6 100644 --- a/apps/api-gateway/src/connection/connection.module.ts +++ b/apps/api-gateway/src/connection/connection.module.ts @@ -1,25 +1,22 @@ -import { getNatsOptions } from '@credebl/common/nats.config'; -import { ConnectionController } from './connection.controller'; -import { ConnectionService } from './connection.service'; -import { Module } from '@nestjs/common'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { ConnectionController } from './connection.controller' +import { ConnectionService } from './connection.service' @Module({ - imports: [ - - ClientsModule.register([ - { - name: 'NATS_CLIENT', - transport: Transport.NATS, - options: getNatsOptions(CommonConstants.CONNECTION_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } - ]) - ], - controllers: [ConnectionController], - providers: [ConnectionService, NATSClient] + imports: [ + ClientsModule.register([ + { + name: 'NATS_CLIENT', + transport: Transport.NATS, + options: getNatsOptions(CommonConstants.CONNECTION_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), + ], + controllers: [ConnectionController], + providers: [ConnectionService, NATSClient], }) - -export class ConnectionModule { -} \ No newline at end of file +export class ConnectionModule {} diff --git a/apps/api-gateway/src/connection/connection.service.ts b/apps/api-gateway/src/connection/connection.service.ts index 215439f31..10848b809 100644 --- a/apps/api-gateway/src/connection/connection.service.ts +++ b/apps/api-gateway/src/connection/connection.service.ts @@ -1,56 +1,65 @@ -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { Inject, Injectable} from '@nestjs/common'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { ConnectionDto, CreateOutOfBandConnectionInvitation, ReceiveInvitationDto, ReceiveInvitationUrlDto } from './dtos/connection.dto'; -import { IReceiveInvitationRes, IUserRequestInterface } from './interfaces'; -import { IConnectionList, IDeletedConnectionsRecord } from '@credebl/common/interfaces/connection.interface'; -import { AgentConnectionSearchCriteria, IConnectionDetailsById, IConnectionSearchCriteria } from '../interfaces/IConnectionSearch.interface'; -import { BasicMessageDto, QuestionDto } from './dtos/question-answer.dto'; -import { user } from '@prisma/client'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { IConnectionList, IDeletedConnectionsRecord } from '@credebl/common/interfaces/connection.interface' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { Inject, Injectable } from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +import type { user } from '@prisma/client' +import { BaseService } from 'libs/service/base.service' +import type { + AgentConnectionSearchCriteria, + IConnectionDetailsById, + IConnectionSearchCriteria, +} from '../interfaces/IConnectionSearch.interface' +import type { + ConnectionDto, + CreateOutOfBandConnectionInvitation, + ReceiveInvitationDto, + ReceiveInvitationUrlDto, +} from './dtos/connection.dto' +import type { BasicMessageDto, QuestionDto } from './dtos/question-answer.dto' +import type { IReceiveInvitationRes, IUserRequestInterface } from './interfaces' @Injectable() export class ConnectionService extends BaseService { - constructor(@Inject('NATS_CLIENT') private readonly connectionServiceProxy: ClientProxy, private readonly natsClient : NATSClient) { - super('ConnectionService'); + constructor( + @Inject('NATS_CLIENT') private readonly connectionServiceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('ConnectionService') } - sendQuestion( - questionDto: QuestionDto - ): Promise { + sendQuestion(questionDto: QuestionDto): Promise { try { - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'send-question', questionDto); + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'send-question', questionDto) } catch (error) { - throw new RpcException(error.response); + throw new RpcException(error.response) } } - sendBasicMessage( - basicMessageDto: BasicMessageDto - ): Promise { + sendBasicMessage(basicMessageDto: BasicMessageDto): Promise { try { - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'send-basic-message-on-connection', basicMessageDto); + return this.natsClient.sendNatsMessage( + this.connectionServiceProxy, + 'send-basic-message-on-connection', + basicMessageDto + ) } catch (error) { - throw new RpcException(error.response); + throw new RpcException(error.response) } } - getConnectionWebhook( - connectionDto: ConnectionDto, - orgId: string - ): Promise { - const payload = { connectionDto, orgId }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'webhook-get-connection', payload); + getConnectionWebhook(connectionDto: ConnectionDto, orgId: string): Promise { + const payload = { connectionDto, orgId } + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'webhook-get-connection', payload) } getUrl(referenceId: string): Promise<{ - response: object; + response: object }> { try { - const connectionDetails = { referenceId }; - return this.natsClient.sendNats(this.connectionServiceProxy, 'get-connection-url', connectionDetails); + const connectionDetails = { referenceId } + return this.natsClient.sendNats(this.connectionServiceProxy, 'get-connection-url', connectionDetails) } catch (error) { - throw new RpcException(error.response); + throw new RpcException(error.response) } } @@ -59,33 +68,29 @@ export class ConnectionService extends BaseService { user: IUserRequest, orgId: string ): Promise { - const payload = { connectionSearchCriteria, user, orgId }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'get-all-connections', payload); + const payload = { connectionSearchCriteria, user, orgId } + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'get-all-connections', payload) } getConnectionListFromAgent( connectionSearchCriteria: AgentConnectionSearchCriteria, orgId: string ): Promise { - const payload = { connectionSearchCriteria, orgId }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'get-all-agent-connection-list', payload); + const payload = { connectionSearchCriteria, orgId } + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'get-all-agent-connection-list', payload) } - getConnectionsById( - user: IUserRequest, - connectionId: string, - orgId: string - ): Promise { - const payload = { user, connectionId, orgId }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'get-connection-details-by-connectionId', payload); + getConnectionsById(user: IUserRequest, connectionId: string, orgId: string): Promise { + const payload = { user, connectionId, orgId } + return this.natsClient.sendNatsMessage( + this.connectionServiceProxy, + 'get-connection-details-by-connectionId', + payload + ) } - - getQuestionAnswersRecord( - orgId: string - ): Promise { - - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'get-question-answer-record', orgId); + getQuestionAnswersRecord(orgId: string): Promise { + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'get-question-answer-record', orgId) } receiveInvitationUrl( @@ -93,8 +98,8 @@ export class ConnectionService extends BaseService { orgId: string, user: IUserRequestInterface ): Promise { - const payload = { user, receiveInvitationUrl, orgId }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'receive-invitation-url', payload); + const payload = { user, receiveInvitationUrl, orgId } + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'receive-invitation-url', payload) } receiveInvitation( @@ -102,36 +107,36 @@ export class ConnectionService extends BaseService { orgId: string, user: IUserRequestInterface ): Promise { - const payload = { user, receiveInvitation, orgId }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'receive-invitation', payload); + const payload = { user, receiveInvitation, orgId } + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'receive-invitation', payload) } async _getWebhookUrl(tenantId?: string, orgId?: string): Promise { - const pattern = { cmd: 'get-webhookurl' }; + const pattern = { cmd: 'get-webhookurl' } + + const payload = { tenantId, orgId } - const payload = { tenantId, orgId }; - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const message = await this.connectionServiceProxy.send(pattern, payload).toPromise(); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.connectionServiceProxy.send(pattern, payload).toPromise() + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw error } } - async _postWebhookResponse(webhookUrl: string, data:object): Promise { - const pattern = { cmd: 'post-webhook-response-to-webhook-url' }; - const payload = { webhookUrl, data }; - + async _postWebhookResponse(webhookUrl: string, data: object): Promise { + const pattern = { cmd: 'post-webhook-response-to-webhook-url' } + const payload = { webhookUrl, data } + try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const message = await this.connectionServiceProxy.send(pattern, payload).toPromise(); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.connectionServiceProxy.send(pattern, payload).toPromise() + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw error } } @@ -139,12 +144,12 @@ export class ConnectionService extends BaseService { createOutOfBandConnectionInvitation: CreateOutOfBandConnectionInvitation, user: IUserRequestInterface ): Promise { - const payload = { user, createOutOfBandConnectionInvitation }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'create-connection-invitation', payload); + const payload = { user, createOutOfBandConnectionInvitation } + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'create-connection-invitation', payload) } async deleteConnectionRecords(orgId: string, userDetails: user): Promise { - const payload = { orgId, userDetails }; - return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'delete-connection-records', payload); + const payload = { orgId, userDetails } + return this.natsClient.sendNatsMessage(this.connectionServiceProxy, 'delete-connection-records', payload) } } diff --git a/apps/api-gateway/src/connection/dtos/connection.dto.ts b/apps/api-gateway/src/connection/dtos/connection.dto.ts index da4cef77d..a3d1f22b2 100644 --- a/apps/api-gateway/src/connection/dtos/connection.dto.ts +++ b/apps/api-gateway/src/connection/dtos/connection.dto.ts @@ -1,369 +1,376 @@ -import { ArrayNotEmpty, IsArray, IsBoolean, IsNotEmpty, IsNumber, IsOptional, IsString, IsUrl, ValidateNested } from 'class-validator'; - -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Type } from 'class-transformer'; -import { HandshakeProtocol } from '../enums/connections.enum'; -import { IsNotSQLInjection } from '@credebl/common/cast.helper'; +import { + ArrayNotEmpty, + IsArray, + IsBoolean, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, + IsUrl, + ValidateNested, +} from 'class-validator' + +import { IsNotSQLInjection } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Type } from 'class-transformer' +import type { HandshakeProtocol } from '../enums/connections.enum' export class CreateOutOfBandConnectionInvitation { - @ApiPropertyOptional() - @IsOptional() - label?: string; - - @ApiPropertyOptional() - @IsOptional() - alias?: string; - - @ApiPropertyOptional() - @IsOptional() - imageUrl?: string; - - @ApiPropertyOptional() - @IsOptional() - goalCode?: string; - - @ApiPropertyOptional() - @IsOptional() - goal?: string; - - @ApiPropertyOptional() - @IsOptional() - handshake?: boolean; - - @ApiPropertyOptional() - @IsOptional() - handshakeProtocols?: HandshakeProtocol[]; - - @ApiPropertyOptional() - @IsOptional() - messages?: object[]; - - @ApiPropertyOptional() - @IsOptional() - multiUseInvitation?: boolean; - - @ApiPropertyOptional() - @IsOptional() - IsReuseConnection?: boolean; - - @ApiPropertyOptional() - @IsOptional() - autoAcceptConnection?: boolean; - - @ApiPropertyOptional() - @IsOptional() - routing?: object; - - @ApiPropertyOptional() - @IsOptional() - appendedAttachments?: object[]; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'Please provide recipientKey' }) - recipientKey: string; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'Please provide invitation did' }) - invitationDid?: string; - - orgId; + @ApiPropertyOptional() + @IsOptional() + label?: string + + @ApiPropertyOptional() + @IsOptional() + alias?: string + + @ApiPropertyOptional() + @IsOptional() + imageUrl?: string + + @ApiPropertyOptional() + @IsOptional() + goalCode?: string + + @ApiPropertyOptional() + @IsOptional() + goal?: string + + @ApiPropertyOptional() + @IsOptional() + handshake?: boolean + + @ApiPropertyOptional() + @IsOptional() + handshakeProtocols?: HandshakeProtocol[] + + @ApiPropertyOptional() + @IsOptional() + messages?: object[] + + @ApiPropertyOptional() + @IsOptional() + multiUseInvitation?: boolean + + @ApiPropertyOptional() + @IsOptional() + IsReuseConnection?: boolean + + @ApiPropertyOptional() + @IsOptional() + autoAcceptConnection?: boolean + + @ApiPropertyOptional() + @IsOptional() + routing?: object + + @ApiPropertyOptional() + @IsOptional() + appendedAttachments?: object[] + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide recipientKey' }) + recipientKey: string + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide invitation did' }) + invitationDid?: string + + orgId } export class CreateConnectionDto { - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'alias must be a string' }) - @IsNotEmpty({ message: 'please provide valid alias' }) - @IsNotSQLInjection({ message: 'alias is required.' }) - alias: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'label must be a string' }) - @IsNotEmpty({ message: 'please provide valid label' }) - @IsNotSQLInjection({ message: 'label is required.' }) - label: string; - - @ApiPropertyOptional() - @IsOptional() - @IsNotEmpty({ message: 'please provide valid imageUrl' }) - @IsString({ message: 'imageUrl must be a string' }) - imageUrl: string; - - @ApiPropertyOptional() - @IsBoolean() - @IsOptional() - @IsNotEmpty({ message: 'please provide multiUseInvitation' }) - multiUseInvitation: boolean; - - @ApiPropertyOptional() - @IsBoolean() - @IsOptional() - @IsNotEmpty({ message: 'Please provide autoAcceptConnection' }) - autoAcceptConnection: boolean; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'Please provide goalCode' }) - goalCode: string; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'Please provide goal' }) - goal: string; - - @ApiPropertyOptional() - @IsBoolean() - @IsOptional() - @IsNotEmpty({ message: 'Please provide handshake' }) - handshake: boolean; - - @ApiPropertyOptional() - @IsArray() - @ArrayNotEmpty() - @IsOptional() - @IsString({ each: true }) - handshakeProtocols: string[]; - - orgId: string; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'Please provide recipientKey' }) - recipientKey: string; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'Please provide invitation did' }) - invitationDid?: string; + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'alias must be a string' }) + @IsNotEmpty({ message: 'please provide valid alias' }) + @IsNotSQLInjection({ message: 'alias is required.' }) + alias: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'label must be a string' }) + @IsNotEmpty({ message: 'please provide valid label' }) + @IsNotSQLInjection({ message: 'label is required.' }) + label: string + + @ApiPropertyOptional() + @IsOptional() + @IsNotEmpty({ message: 'please provide valid imageUrl' }) + @IsString({ message: 'imageUrl must be a string' }) + imageUrl: string + + @ApiPropertyOptional() + @IsBoolean() + @IsOptional() + @IsNotEmpty({ message: 'please provide multiUseInvitation' }) + multiUseInvitation: boolean + + @ApiPropertyOptional() + @IsBoolean() + @IsOptional() + @IsNotEmpty({ message: 'Please provide autoAcceptConnection' }) + autoAcceptConnection: boolean + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide goalCode' }) + goalCode: string + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide goal' }) + goal: string + + @ApiPropertyOptional() + @IsBoolean() + @IsOptional() + @IsNotEmpty({ message: 'Please provide handshake' }) + handshake: boolean + + @ApiPropertyOptional() + @IsArray() + @ArrayNotEmpty() + @IsOptional() + @IsString({ each: true }) + handshakeProtocols: string[] + + orgId: string + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide recipientKey' }) + recipientKey: string + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'Please provide invitation did' }) + invitationDid?: string } export class ConnectionDto { - @ApiPropertyOptional() - @IsOptional() - id: string; + @ApiPropertyOptional() + @IsOptional() + id: string - @ApiPropertyOptional() - @IsOptional() - createdAt: string; + @ApiPropertyOptional() + @IsOptional() + createdAt: string - @ApiPropertyOptional() - @IsOptional() - did: string; + @ApiPropertyOptional() + @IsOptional() + did: string - @ApiPropertyOptional() - @IsOptional() - theirDid: string; + @ApiPropertyOptional() + @IsOptional() + theirDid: string - @ApiPropertyOptional() - @IsOptional() - theirLabel: string; + @ApiPropertyOptional() + @IsOptional() + theirLabel: string - @ApiPropertyOptional() - @IsOptional() - state: string; + @ApiPropertyOptional() + @IsOptional() + state: string - @ApiPropertyOptional() - @IsOptional() - role: string; + @ApiPropertyOptional() + @IsOptional() + role: string - @ApiPropertyOptional() - @IsOptional() - imageUrl: string; + @ApiPropertyOptional() + @IsOptional() + imageUrl: string - @ApiPropertyOptional() - @IsOptional() - autoAcceptConnection: boolean; + @ApiPropertyOptional() + @IsOptional() + autoAcceptConnection: boolean - @ApiPropertyOptional() - @IsOptional() - threadId: string; + @ApiPropertyOptional() + @IsOptional() + threadId: string - @ApiPropertyOptional() - @IsOptional() - protocol: string; + @ApiPropertyOptional() + @IsOptional() + protocol: string - @ApiPropertyOptional() - @IsOptional() - outOfBandId: string; + @ApiPropertyOptional() + @IsOptional() + outOfBandId: string - @ApiPropertyOptional() - @IsOptional() - updatedAt: string; + @ApiPropertyOptional() + @IsOptional() + updatedAt: string - @ApiPropertyOptional() - @IsOptional() - contextCorrelationId: string; + @ApiPropertyOptional() + @IsOptional() + contextCorrelationId: string - @ApiPropertyOptional() - @IsOptional() - type: string; + @ApiPropertyOptional() + @IsOptional() + type: string - @ApiPropertyOptional() - @IsOptional() - orgId: string; + @ApiPropertyOptional() + @IsOptional() + orgId: string - @ApiPropertyOptional() - @IsOptional() - outOfBandRecord?: object; + @ApiPropertyOptional() + @IsOptional() + outOfBandRecord?: object - @ApiPropertyOptional() - @IsOptional() - reuseThreadId?: string; + @ApiPropertyOptional() + @IsOptional() + reuseThreadId?: string } class ReceiveInvitationCommonDto { - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'alias must be a string' }) - @IsNotEmpty({ message: 'please provide valid alias' }) - alias: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'label must be a string' }) - @IsNotEmpty({ message: 'please provide valid label' }) - label: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'imageUrl must be a string' }) - @IsNotEmpty({ message: 'please provide valid imageUrl' }) - @IsString() - imageUrl: string; - - @ApiPropertyOptional() - @IsOptional() - @IsBoolean({ message: 'autoAcceptConnection must be a boolean' }) - @IsNotEmpty({ message: 'please provide valid autoAcceptConnection' }) - autoAcceptConnection: boolean; - - @ApiPropertyOptional() - @IsOptional() - @IsBoolean({ message: 'autoAcceptInvitation must be a boolean' }) - @IsNotEmpty({ message: 'please provide valid autoAcceptInvitation' }) - autoAcceptInvitation: boolean; - - @ApiPropertyOptional() - @IsOptional() - @IsBoolean({ message: 'reuseConnection must be a boolean' }) - @IsNotEmpty({ message: 'please provide valid reuseConnection' }) - reuseConnection: boolean; - - @ApiPropertyOptional() - @IsOptional() - @IsNumber() - @IsNotEmpty({ message: 'please provide valid acceptInvitationTimeoutMs' }) - acceptInvitationTimeoutMs: number; + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'alias must be a string' }) + @IsNotEmpty({ message: 'please provide valid alias' }) + alias: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'label must be a string' }) + @IsNotEmpty({ message: 'please provide valid label' }) + label: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'imageUrl must be a string' }) + @IsNotEmpty({ message: 'please provide valid imageUrl' }) + @IsString() + imageUrl: string + + @ApiPropertyOptional() + @IsOptional() + @IsBoolean({ message: 'autoAcceptConnection must be a boolean' }) + @IsNotEmpty({ message: 'please provide valid autoAcceptConnection' }) + autoAcceptConnection: boolean + + @ApiPropertyOptional() + @IsOptional() + @IsBoolean({ message: 'autoAcceptInvitation must be a boolean' }) + @IsNotEmpty({ message: 'please provide valid autoAcceptInvitation' }) + autoAcceptInvitation: boolean + + @ApiPropertyOptional() + @IsOptional() + @IsBoolean({ message: 'reuseConnection must be a boolean' }) + @IsNotEmpty({ message: 'please provide valid reuseConnection' }) + reuseConnection: boolean + + @ApiPropertyOptional() + @IsOptional() + @IsNumber() + @IsNotEmpty({ message: 'please provide valid acceptInvitationTimeoutMs' }) + acceptInvitationTimeoutMs: number } export class ReceiveInvitationUrlDto extends ReceiveInvitationCommonDto { - - @ApiProperty() - @IsOptional() - @IsString({ message: 'invitationUrl must be a string' }) - @IsNotEmpty({ message: 'please provide valid invitationUrl' }) - invitationUrl: string; + @ApiProperty() + @IsOptional() + @IsString({ message: 'invitationUrl must be a string' }) + @IsNotEmpty({ message: 'please provide valid invitationUrl' }) + invitationUrl: string } - class ServiceDto { - @ApiProperty() - @IsString() - @IsNotEmpty({ message: 'please provide valid id' }) - id: string; - - @ApiProperty() - @IsString() - @IsNotEmpty({ message: 'please provide valid serviceEndpoint' }) - @IsUrl({}, { message: 'Invalid serviceEndpoint format' }) - serviceEndpoint: string; - - @ApiProperty() - @IsString() - @IsNotEmpty({ message: 'please provide valid type' }) - type: string; - - @ApiProperty() - @IsString({ each: true }) - recipientKeys: string[]; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ each: true }) - routingKeys: string[]; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ each: true }) - accept: string[]; + @ApiProperty() + @IsString() + @IsNotEmpty({ message: 'please provide valid id' }) + id: string + + @ApiProperty() + @IsString() + @IsNotEmpty({ message: 'please provide valid serviceEndpoint' }) + @IsUrl({}, { message: 'Invalid serviceEndpoint format' }) + serviceEndpoint: string + + @ApiProperty() + @IsString() + @IsNotEmpty({ message: 'please provide valid type' }) + type: string + + @ApiProperty() + @IsString({ each: true }) + recipientKeys: string[] + + @ApiPropertyOptional() + @IsOptional() + @IsString({ each: true }) + routingKeys: string[] + + @ApiPropertyOptional() + @IsOptional() + @IsString({ each: true }) + accept: string[] } class InvitationDto { - @ApiPropertyOptional() - @IsOptional() - @IsString() - @IsNotEmpty({ message: 'please provide valid @id' }) - '@id': string; - - @ApiProperty() - @IsString() - @IsNotEmpty({ message: 'please provide valid @type' }) - '@type': string; - - @ApiProperty() - @IsString() - @IsNotEmpty({ message: 'please provide valid label' }) - label: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString() - @IsNotEmpty({ message: 'please provide valid goalCode' }) - goalCode: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString() - @IsNotEmpty({ message: 'please provide valid goal' }) - goal: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ each: true }) - accept: string[]; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ each: true }) - // eslint-disable-next-line camelcase - handshake_protocols: string[]; - - @ApiProperty() - @ValidateNested({ each: true }) - @Type(() => ServiceDto) - services: ServiceDto[]; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'please provide valid imageUrl' }) - @IsString() - imageUrl?: string; + @ApiPropertyOptional() + @IsOptional() + @IsString() + @IsNotEmpty({ message: 'please provide valid @id' }) + '@id': string + + @ApiProperty() + @IsString() + @IsNotEmpty({ message: 'please provide valid @type' }) + '@type': string + + @ApiProperty() + @IsString() + @IsNotEmpty({ message: 'please provide valid label' }) + label: string + + @ApiPropertyOptional() + @IsOptional() + @IsString() + @IsNotEmpty({ message: 'please provide valid goalCode' }) + goalCode: string + + @ApiPropertyOptional() + @IsOptional() + @IsString() + @IsNotEmpty({ message: 'please provide valid goal' }) + goal: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ each: true }) + accept: string[] + + @ApiPropertyOptional() + @IsOptional() + @IsString({ each: true }) + // eslint-disable-next-line camelcase + handshake_protocols: string[] + + @ApiProperty() + @ValidateNested({ each: true }) + @Type(() => ServiceDto) + services: ServiceDto[] + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'please provide valid imageUrl' }) + @IsString() + imageUrl?: string } export class ReceiveInvitationDto extends ReceiveInvitationCommonDto { - - @ApiProperty() - @ValidateNested() - @Type(() => InvitationDto) - invitation: InvitationDto; -} \ No newline at end of file + @ApiProperty() + @ValidateNested() + @Type(() => InvitationDto) + invitation: InvitationDto +} 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 08e97b3b3..ae07b2637 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,65 +1,65 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Transform, Type } from 'class-transformer'; -import { IsEnum, IsOptional, Max, Min } from 'class-validator'; -import { SortValue } from '../../enum'; -import { toNumber, trim } from '@credebl/common/cast.helper'; -import { SortFields } from 'apps/connection/src/enum/connection.enum'; +import { toNumber, trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { SortFields } from 'apps/connection/src/enum/connection.enum' +import { Transform, Type } from 'class-transformer' +import { IsEnum, IsOptional, Max, Min } from 'class-validator' +import { SortValue } from '../../enum' export class GetAllConnectionsDto { @ApiProperty({ required: false, example: '1' }) @Transform(({ value }) => toNumber(value)) @IsOptional() - pageNumber: number = 1; + pageNumber = 1 @ApiProperty({ required: false, example: '10' }) @IsOptional() @Transform(({ value }) => toNumber(value)) @Min(1, { message: 'Page size must be greater than 0' }) @Max(100, { message: 'Page size must be less than 100' }) - pageSize: number = 10; + pageSize = 10 @ApiProperty({ required: false }) @IsOptional() @Transform(({ value }) => trim(value)) @Type(() => String) - searchByText: string = ''; + searchByText = '' @ApiProperty({ - required: false + required: false, }) @Transform(({ value }) => trim(value)) @IsOptional() @IsEnum(SortFields) - sortField: string = SortFields.CREATED_DATE_TIME; + sortField: string = SortFields.CREATED_DATE_TIME @ApiProperty({ enum: [SortValue.DESC, SortValue.ASC], - required: false + required: false, }) @Transform(({ value }) => trim(value)) @IsOptional() @IsEnum(SortValue) - sortBy: string = SortValue.DESC; + sortBy: string = SortValue.DESC } export class GetAllAgentConnectionsDto { @ApiProperty({ required: false, example: 'e315f30d-9beb-4068-aea4-abb5fe5eecb1' }) @IsOptional() - outOfBandId: string = ''; + outOfBandId = '' @ApiProperty({ required: false, example: 'Test' }) @IsOptional() - alias: string = ''; + alias = '' @ApiProperty({ required: false, example: 'did:example:e315f30d-9beb-4068-aea4-abb5fe5eecb1' }) @IsOptional() - myDid: string = ''; + myDid = '' @ApiProperty({ required: false, example: 'did:example:e315f30d-9beb-4068-aea4-abb5fe5eecb1' }) @IsOptional() - theirDid: string = ''; + theirDid = '' @ApiProperty({ required: false, example: 'Bob' }) @IsOptional() - theirLabel: string = ''; + theirLabel = '' } diff --git a/apps/api-gateway/src/connection/dtos/question-answer.dto.ts b/apps/api-gateway/src/connection/dtos/question-answer.dto.ts index d9deb3dfc..12a65da7f 100644 --- a/apps/api-gateway/src/connection/dtos/question-answer.dto.ts +++ b/apps/api-gateway/src/connection/dtos/question-answer.dto.ts @@ -1,105 +1,102 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform, Type } from 'class-transformer'; -import { IsArray, IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform, Type } from 'class-transformer' +import { IsArray, IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator' class ValidResponses { - @ApiProperty({ example: 'Emma' }) - @IsNotEmpty({ message: 'text is required' }) - @IsString({ message: 'text should be a string' }) - @Transform(({ value }) => trim(value)) - @Type(() => String) - text: string; + @ApiProperty({ example: 'Emma' }) + @IsNotEmpty({ message: 'text is required' }) + @IsString({ message: 'text should be a string' }) + @Transform(({ value }) => trim(value)) + @Type(() => String) + text: string } export class QuestionDto { - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'detail must be a string' }) - @IsNotEmpty({ message: 'please provide valid detail' }) - detail: string; - - @ApiProperty({ example: [{ 'text': 'Emma'}, { 'text': 'Kiva'}] }) - @IsNotEmpty({ message: 'Please provide valid responses' }) - @IsArray({ message: 'Responses should be array' }) - @ValidateNested({ each: true }) - @Type(() => ValidResponses) - validResponses: ValidResponses[]; - - @ApiProperty({ example: 'What is your name'}) - @IsNotEmpty({ message: 'question is required' }) - @IsString({ message: 'question must be a string' }) - @IsNotEmpty({ message: 'please provide valid question' }) - question: string; - - orgId: string; - connectionId: string; + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'detail must be a string' }) + @IsNotEmpty({ message: 'please provide valid detail' }) + detail: string + + @ApiProperty({ example: [{ text: 'Emma' }, { text: 'Kiva' }] }) + @IsNotEmpty({ message: 'Please provide valid responses' }) + @IsArray({ message: 'Responses should be array' }) + @ValidateNested({ each: true }) + @Type(() => ValidResponses) + validResponses: ValidResponses[] + + @ApiProperty({ example: 'What is your name' }) + @IsNotEmpty({ message: 'question is required' }) + @IsString({ message: 'question must be a string' }) + @IsNotEmpty({ message: 'please provide valid question' }) + question: string + + orgId: string + connectionId: string } export class BasicMessageDto { - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'content must be a string' }) - @IsNotEmpty({ message: 'please provide valid content' }) - content: string; - - orgId: string; - connectionId: string; + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'content must be a string' }) + @IsNotEmpty({ message: 'please provide valid content' }) + content: string + + orgId: string + connectionId: string } export class QuestionAnswerWebhookDto { - - - @ApiPropertyOptional() - @IsOptional() - id: string; - - @ApiPropertyOptional() - @IsOptional() - createdAt: string; - - @ApiPropertyOptional() - @IsOptional() - questionText: string; - - @ApiPropertyOptional() - @IsOptional() - questionDetail: string; - - @ApiPropertyOptional() - @IsOptional() - // eslint-disable-next-line @typescript-eslint/no-explicit-any - validResponses:any; - - @ApiPropertyOptional() - @IsOptional() - connectionId: string; - - @ApiPropertyOptional() - @IsOptional() - role: string; - - @ApiPropertyOptional() - @IsOptional() - signatureRequired: boolean; - - @ApiPropertyOptional() - @IsOptional() - state: boolean; - - @ApiPropertyOptional() - @IsOptional() - threadId: string; - - @ApiPropertyOptional() - @IsOptional() - updatedAt: string; - - @ApiPropertyOptional() - @IsOptional() - contextCorrelationId: string; - - @ApiPropertyOptional() - @IsOptional() - type: string; - -} \ No newline at end of file + @ApiPropertyOptional() + @IsOptional() + id: string + + @ApiPropertyOptional() + @IsOptional() + createdAt: string + + @ApiPropertyOptional() + @IsOptional() + questionText: string + + @ApiPropertyOptional() + @IsOptional() + questionDetail: string + + @ApiPropertyOptional() + @IsOptional() + // biome-ignore lint/suspicious/noExplicitAny: + validResponses: any + + @ApiPropertyOptional() + @IsOptional() + connectionId: string + + @ApiPropertyOptional() + @IsOptional() + role: string + + @ApiPropertyOptional() + @IsOptional() + signatureRequired: boolean + + @ApiPropertyOptional() + @IsOptional() + state: boolean + + @ApiPropertyOptional() + @IsOptional() + threadId: string + + @ApiPropertyOptional() + @IsOptional() + updatedAt: string + + @ApiPropertyOptional() + @IsOptional() + contextCorrelationId: string + + @ApiPropertyOptional() + @IsOptional() + type: string +} diff --git a/apps/api-gateway/src/connection/enums/connections.enum.ts b/apps/api-gateway/src/connection/enums/connections.enum.ts index a15929cf6..029bcd7b6 100644 --- a/apps/api-gateway/src/connection/enums/connections.enum.ts +++ b/apps/api-gateway/src/connection/enums/connections.enum.ts @@ -1,4 +1,4 @@ export declare enum HandshakeProtocol { - Connections = "https://didcomm.org/connections/1.0", - DidExchange = "https://didcomm.org/didexchange/1.0" -} \ No newline at end of file + Connections = 'https://didcomm.org/connections/1.0', + DidExchange = 'https://didcomm.org/didexchange/1.0', +} diff --git a/apps/api-gateway/src/connection/interfaces/index.ts b/apps/api-gateway/src/connection/interfaces/index.ts index 20f8f584b..6302dba13 100644 --- a/apps/api-gateway/src/connection/interfaces/index.ts +++ b/apps/api-gateway/src/connection/interfaces/index.ts @@ -1,117 +1,115 @@ -import { UserRoleOrgPermsDto } from '../../dtos/user-role-org-perms.dto'; +import type { UserRoleOrgPermsDto } from '../../dtos/user-role-org-perms.dto' export interface IUserRequestInterface { - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?: string; - selectedOrg: ISelectedOrgInterface; + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string + selectedOrg: ISelectedOrgInterface } export interface ISelectedOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: object; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: object } export interface IOrganizationInterface { - name: string; - description: string; + name: string + description: string org_agents: IOrgAgentInterface[] - } export interface IOrgAgentInterface { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } - export class IConnectionInterface { - tag: object; - createdAt: string; - updatedAt: string; - connectionId: string; - state: string; - orgDid: string; - theirLabel: string; - autoAcceptConnection: boolean; - outOfBandId: string; - orgId: string; + tag: object + createdAt: string + updatedAt: string + connectionId: string + state: string + orgDid: string + theirLabel: string + autoAcceptConnection: boolean + outOfBandId: string + orgId: string } interface Tags { - invitationId: string; - recipientKeyFingerprints: string[]; - role: string; - state: string; - threadId: string; + invitationId: string + recipientKeyFingerprints: string[] + role: string + state: string + threadId: string } interface IOutOfBandInvitationService { - id: string; - serviceEndpoint: string; - type: string; - recipientKeys: string[]; - routingKeys: string[]; + id: string + serviceEndpoint: string + type: string + recipientKeys: string[] + routingKeys: string[] } interface IOutOfBandInvitation { - "@type": string; - "@id": string; - label: string; - accept: string[]; - handshake_protocols: string[]; - services: IOutOfBandInvitationService[]; + '@type': string + '@id': string + label: string + accept: string[] + handshake_protocols: string[] + services: IOutOfBandInvitationService[] } interface IOutOfBandRecord { - _tags: Tags; - metadata?: { [key: string]: string }; - id: string; - createdAt: string; - outOfBandInvitation: IOutOfBandInvitation; - role: string; - state: string; - autoAcceptConnection: boolean; - reusable: boolean; - updatedAt: string; + _tags: Tags + metadata?: { [key: string]: string } + id: string + createdAt: string + outOfBandInvitation: IOutOfBandInvitation + role: string + state: string + autoAcceptConnection: boolean + reusable: boolean + updatedAt: string } interface IConnectionRecord { - _tags: { [key: string]: string }; - metadata: { [key: string]: string }; - connectionTypes: string[]; - id: string; - createdAt: string; - did: string; - invitationDid: string; - theirLabel: string; - state: string; - role: string; - alias: string; - autoAcceptConnection: boolean; - threadId: string; - protocol: string; - outOfBandId: string; - updatedAt: string; + _tags: { [key: string]: string } + metadata: { [key: string]: string } + connectionTypes: string[] + id: string + createdAt: string + did: string + invitationDid: string + theirLabel: string + state: string + role: string + alias: string + autoAcceptConnection: boolean + threadId: string + protocol: string + outOfBandId: string + updatedAt: string } export interface IReceiveInvitationRes { - outOfBandRecord: IOutOfBandRecord; - connectionRecord: IConnectionRecord; -} \ No newline at end of file + outOfBandRecord: IOutOfBandRecord + connectionRecord: IConnectionRecord +} diff --git a/apps/api-gateway/src/credential-definition/credential-definition.controller.spec.ts b/apps/api-gateway/src/credential-definition/credential-definition.controller.spec.ts index 2ad6e017a..b39e50fd1 100644 --- a/apps/api-gateway/src/credential-definition/credential-definition.controller.spec.ts +++ b/apps/api-gateway/src/credential-definition/credential-definition.controller.spec.ts @@ -1,123 +1,112 @@ -import { Test, TestingModule } from '@nestjs/testing'; - -import { Any } from 'typeorm'; -import { CredentialDefinitionController } from './credential-definition.controller'; -import { CredentialDefinitionService } from './credential-definition.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { CredentialDefinitionController } from './credential-definition.controller' +import { CredentialDefinitionService } from './credential-definition.service' describe('CredentialDefinitionController Test Cases', () => { - let controller: CredentialDefinitionController; - const mockCredentialDefinitionService = { - createCredentialDefinition: jest.fn(() => ({})), - getAllCredDefsByOrgId: jest.fn(() => ({})), - getCredDefsByCredId: jest.fn(() => ({})), - getAllCredentialDefinitionForHolder: jest.fn(() => ({})) - }; + let controller: CredentialDefinitionController + const mockCredentialDefinitionService = { + createCredentialDefinition: jest.fn(() => ({})), + getAllCredDefsByOrgId: jest.fn(() => ({})), + getCredDefsByCredId: jest.fn(() => ({})), + getAllCredentialDefinitionForHolder: jest.fn(() => ({})), + } - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [CredentialDefinitionController], - providers: [CredentialDefinitionService] - }) - .overrideProvider(CredentialDefinitionService) - .useValue(mockCredentialDefinitionService) - .compile(); - controller = module.get( - CredentialDefinitionController - ); - }); + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [CredentialDefinitionController], + providers: [CredentialDefinitionService], + }) + .overrideProvider(CredentialDefinitionService) + .useValue(mockCredentialDefinitionService) + .compile() + controller = module.get(CredentialDefinitionController) + }) describe('createCredential', () => { - const user: any = {}; - user.orgId = 1234; + const user: any = {} + user.orgId = 1234 const createCredentialDefinition: any = { schema_id: 'Test', tag: 'Test', support_revocation: true, support_auto_issue: true, - revocation_registry_size: 0 - }; + revocation_registry_size: 0, + } it('should return an expected credentialdefinition', async () => { - const result = await controller.createCredential( - user, - createCredentialDefinition - ); - expect(result).toEqual({}); - }); + const result = await controller.createCredential(user, createCredentialDefinition) + expect(result).toEqual({}) + }) it('should check returned credentialdefinition is not to be null', async () => { - const result = await controller.createCredential( - user, - createCredentialDefinition - ); - expect(result).not.toBeNull(); - }); + const result = await controller.createCredential(user, createCredentialDefinition) + expect(result).not.toBeNull() + }) it('should hit error if support_auto_issue is number', async () => { - createCredentialDefinition.support_auto_issue = 1234; + createCredentialDefinition.support_auto_issue = 1234 const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Support auto issue should be boolean.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Support auto issue should be boolean.') + }) it('should hit error if support_auto_issue is empty', async () => { - createCredentialDefinition.support_auto_issue = ''; + createCredentialDefinition.support_auto_issue = '' const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Please provide support auto issue data.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Please provide support auto issue data.') + }) it('should hit error if support_revocation is empty', async () => { - createCredentialDefinition.support_revocation = ''; + createCredentialDefinition.support_revocation = '' const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Please provide support revocation data.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Please provide support revocation data.') + }) it('should hit error if support_revocation is number', async () => { - createCredentialDefinition.support_revocation = 1234; + createCredentialDefinition.support_revocation = 1234 const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Support revocation should be boolean.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Support revocation should be boolean.') + }) it('should hit error if tag is empty', async () => { - createCredentialDefinition.tag = ''; + createCredentialDefinition.tag = '' const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Please provide a valid tag.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Please provide a valid tag.') + }) it('should hit error if tag is number', async () => { - createCredentialDefinition.tag = 1234; + createCredentialDefinition.tag = 1234 const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Tag should be a string.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Tag should be a string.') + }) it('should hit error if schema_id is empty', async () => { - createCredentialDefinition.schema_id = ''; + createCredentialDefinition.schema_id = '' const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Please provide a schema id.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Please provide a schema id.') + }) it('should hit error if schema_id is number', async () => { - createCredentialDefinition.schema_id = 1234; + createCredentialDefinition.schema_id = 1234 const result = await (() => { - controller.createCredential(user, createCredentialDefinition); - }); - expect(result).toThrowError('Schema id should be a string.'); - }); + controller.createCredential(user, createCredentialDefinition) + }) + expect(result).toThrowError('Schema id should be a string.') + }) //createCredential test case - - }); + }) describe('getAllCredDefsByOrgId', () => { - const page: any = 'hello'; - const search_text: any = 'Test'; - const items_per_page: any = 1234; - const orgId: any = 1234; - const credDefSortBy: any = 1234; - const sortValue: any = 1234; - const supportRevocation: any = 'Test'; - const user: any = 1234; + const page: any = 'hello' + const search_text: any = 'Test' + const items_per_page: any = 1234 + const orgId: any = 1234 + const credDefSortBy: any = 1234 + const sortValue: any = 1234 + const supportRevocation: any = 'Test' + const user: any = 1234 it('should return an expected credentialdefinition', async () => { const result = await controller.getAllCredDefsByOrgId( page, @@ -128,9 +117,9 @@ describe('CredentialDefinitionController Test Cases', () => { sortValue, supportRevocation, user - ); - expect(result).toEqual({}); - }); + ) + expect(result).toEqual({}) + }) it('should return an expected credentialdefinition', async () => { const result = await controller.getAllCredDefsByOrgId( page, @@ -141,18 +130,18 @@ describe('CredentialDefinitionController Test Cases', () => { sortValue, supportRevocation, user - ); - expect(result).not.toBeNull(); - }); - }); + ) + expect(result).not.toBeNull() + }) + }) // describe("getAllCredDefsByOrgId", () => { // let page: any = "hello"; - + // it("should return an expected credentialdefinition", async () => { // const result = await controller.getCredDefsByCredId( // page, // search_text, - + // ); // expect(result).toEqual({}); // }); @@ -160,20 +149,20 @@ describe('CredentialDefinitionController Test Cases', () => { // const result = await controller.getCredDefsByCredId( // page, // search_text, - + // ); // expect(result).not.toBeNull(); // }); // }); describe('getAllCredentialDefinitionForHolder', () => { - const page: any = 'hello'; - const search_text: any = 'Test'; - const items_per_page: any = 1234; - const orgId: any = 1234; - const credDefSortBy: any = 1234; - const sortValue: any = 1234; - const supportRevocation: any = 'Test'; - const user: any = 1234; + const page: any = 'hello' + const search_text: any = 'Test' + const items_per_page: any = 1234 + const orgId: any = 1234 + const credDefSortBy: any = 1234 + const sortValue: any = 1234 + const supportRevocation: any = 'Test' + const user: any = 1234 it('should return an expected credentialdefinition', async () => { const result = await controller.getAllCredentialDefinitionForHolder( page, @@ -184,9 +173,9 @@ describe('CredentialDefinitionController Test Cases', () => { sortValue, supportRevocation, user - ); - expect(result).toEqual({}); - }); + ) + expect(result).toEqual({}) + }) it('should return an expected credentialdefinition', async () => { const result = await controller.getAllCredDefsByOrgId( page, @@ -197,8 +186,8 @@ describe('CredentialDefinitionController Test Cases', () => { sortValue, supportRevocation, user - ); - expect(result).not.toBeNull(); - }); - }); -}); + ) + expect(result).not.toBeNull() + }) + }) +}) diff --git a/apps/api-gateway/src/credential-definition/credential-definition.controller.ts b/apps/api-gateway/src/credential-definition/credential-definition.controller.ts index 23eb3b36b..948b019c5 100644 --- a/apps/api-gateway/src/credential-definition/credential-definition.controller.ts +++ b/apps/api-gateway/src/credential-definition/credential-definition.controller.ts @@ -1,23 +1,43 @@ -import { Controller, Logger, Post, Body, UseGuards, Get, Query, HttpStatus, Res, Param, UseFilters, ParseUUIDPipe, BadRequestException } from '@nestjs/common'; -import { CredentialDefinitionService } from './credential-definition.service'; -import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiUnauthorizedResponse, ApiForbiddenResponse } from '@nestjs/swagger'; -import { ApiResponseDto } from 'apps/api-gateway/src/dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from 'apps/api-gateway/src/dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from 'apps/api-gateway/src/dtos/forbidden-error.dto'; -import { User } from '../authz/decorators/user.decorator'; -import { AuthGuard } from '@nestjs/passport'; -import { IResponse } from '@credebl/common/interfaces/response.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { Response } from 'express'; -import { GetAllCredDefsDto } from './dto/get-all-cred-defs.dto'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { IUserRequestInterface } from '../interfaces/IUserRequestInterface'; -import { CreateCredentialDefinitionDto } from './dto/create-cred-defs.dto'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { EmptyStringParamPipe, TrimStringParamPipe } from '@credebl/common/cast.helper'; - +import { EmptyStringParamPipe, TrimStringParamPipe } from '@credebl/common/cast.helper' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { + BadRequestException, + Body, + Controller, + Get, + HttpStatus, + Logger, + Param, + ParseUUIDPipe, + Post, + Query, + Res, + UseFilters, + UseGuards, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' +import { + ApiBearerAuth, + ApiForbiddenResponse, + ApiOperation, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import { ApiResponseDto } from 'apps/api-gateway/src/dtos/apiResponse.dto' +import { ForbiddenErrorDto } from 'apps/api-gateway/src/dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from 'apps/api-gateway/src/dtos/unauthorized-error.dto' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import type { IUserRequestInterface } from '../interfaces/IUserRequestInterface' +import type { CredentialDefinitionService } from './credential-definition.service' +import type { CreateCredentialDefinitionDto } from './dto/create-cred-defs.dto' +import type { GetAllCredDefsDto } from './dto/get-all-cred-defs.dto' @ApiBearerAuth() @ApiTags('credential-definitions') @@ -26,9 +46,8 @@ import { EmptyStringParamPipe, TrimStringParamPipe } from '@credebl/common/cast. @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) @UseFilters(CustomExceptionFilter) export class CredentialDefinitionController { - - constructor(private readonly credentialDefinitionService: CredentialDefinitionService) { } - private readonly logger = new Logger('CredentialDefinitionController'); + constructor(private readonly credentialDefinitionService: CredentialDefinitionService) {} + private readonly logger = new Logger('CredentialDefinitionController') /** * Retrieves the details of a specific credential definition. @@ -40,7 +59,8 @@ export class CredentialDefinitionController { @Get('/orgs/:orgId/cred-defs/:credDefId') @ApiOperation({ summary: 'Get credential definition by credential definition Id', - description: 'Fetches the details of a specific credential definition using its ID available credential definitions on platform.' + description: + 'Fetches the details of a specific credential definition using its ID available credential definitions on platform.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @@ -50,16 +70,19 @@ export class CredentialDefinitionController { @Param('credDefId', TrimStringParamPipe, EmptyStringParamPipe.forParam('credDefId')) credentialDefinitionId: string, @Res() res: Response ): Promise { - const credentialsDefinitionDetails = await this.credentialDefinitionService.getCredentialDefinitionById(credentialDefinitionId, orgId); + const credentialsDefinitionDetails = await this.credentialDefinitionService.getCredentialDefinitionById( + credentialDefinitionId, + orgId + ) const credDefResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.credentialDefinition.success.fetch, - data: credentialsDefinitionDetails - }; - return res.status(HttpStatus.OK).json(credDefResponse); + data: credentialsDefinitionDetails, + } + return res.status(HttpStatus.OK).json(credDefResponse) } - /** + /** * Retrieves all credential definitions linked to a specific schema. * * @param schemaId The unique identifier of the schema. @@ -68,7 +91,8 @@ export class CredentialDefinitionController { @Get('/verifiation/cred-defs/:schemaId') @ApiOperation({ summary: 'Get all credential definitions by schema Id', - description: 'Fetches all credential definitions associated with a specific schema ID available credential definitions on platform.' + description: + 'Fetches all credential definitions associated with a specific schema ID available credential definitions on platform.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt')) @@ -76,35 +100,42 @@ export class CredentialDefinitionController { @Param('schemaId', TrimStringParamPipe) schemaId: string, @Res() res: Response ): Promise { - if (!schemaId) { - throw new BadRequestException(ResponseMessages.schema.error.invalidSchemaId); + throw new BadRequestException(ResponseMessages.schema.error.invalidSchemaId) } - const credentialsDefinitions = await this.credentialDefinitionService.getCredentialDefinitionBySchemaId(schemaId); + const credentialsDefinitions = await this.credentialDefinitionService.getCredentialDefinitionBySchemaId(schemaId) const credDefResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.credentialDefinition.success.fetch, - data: credentialsDefinitions - }; - return res.status(HttpStatus.OK).json(credDefResponse); + data: credentialsDefinitions, + } + return res.status(HttpStatus.OK).json(credDefResponse) } - /** - * Retrieves all credential definitions for a given organization. - * - * @param orgId The unique identifier of the organization. - * @returns A paginated list of credential definitions for the organization. + /** + * Retrieves all credential definitions for a given organization. + * + * @param orgId The unique identifier of the organization. + * @returns A paginated list of credential definitions for the organization. */ @Get('/orgs/:orgId/cred-defs') @ApiOperation({ summary: 'Fetch all credential definitions by organization Id', - description: 'Fetches all credential definitions belonging to a specific organization created on the platform.' + description: 'Fetches all credential definitions belonging to a specific organization created on the platform.', }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) async getAllCredDefs( - @Param('orgId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); }})) orgId: string, + @Param( + 'orgId', + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, @Query() getAllCredDefs: GetAllCredDefsDto, @User() user: IUserRequestInterface, @Res() res: Response @@ -113,16 +144,16 @@ export class CredentialDefinitionController { getAllCredDefs, user, orgId - ); + ) const credDefResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.credentialDefinition.success.fetch, - data: credentialsDefinitionDetails - }; - return res.status(HttpStatus.OK).json(credDefResponse); + data: credentialsDefinitionDetails, + } + return res.status(HttpStatus.OK).json(credDefResponse) } - /** + /** * Creates a new credential definition and submits it to the ledger. * * @param orgId The unique identifier of the organization. @@ -132,7 +163,7 @@ export class CredentialDefinitionController { @Post('/orgs/:orgId/cred-defs') @ApiOperation({ summary: 'Sends a credential definition to ledger', - description: 'Creates a new credential definition and submits it to the ledger.' + description: 'Creates a new credential definition and submits it to the ledger.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @@ -140,18 +171,27 @@ export class CredentialDefinitionController { async createCredentialDefinition( @User() user: IUserRequestInterface, @Body() credDef: CreateCredentialDefinitionDto, - @Param('orgId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); }})) orgId: string, + @Param( + 'orgId', + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, @Res() res: Response ): Promise { - - credDef.orgId = orgId; - const credentialsDefinitionDetails = await this.credentialDefinitionService.createCredentialDefinition(credDef, user); + credDef.orgId = orgId + const credentialsDefinitionDetails = await this.credentialDefinitionService.createCredentialDefinition( + credDef, + user + ) const credDefResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.credentialDefinition.success.create, - data: credentialsDefinitionDetails - }; - return res.status(HttpStatus.CREATED).json(credDefResponse); + data: credentialsDefinitionDetails, + } + return res.status(HttpStatus.CREATED).json(credDefResponse) } - -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/credential-definition/credential-definition.module.ts b/apps/api-gateway/src/credential-definition/credential-definition.module.ts index cd99e5b3f..6238930c9 100644 --- a/apps/api-gateway/src/credential-definition/credential-definition.module.ts +++ b/apps/api-gateway/src/credential-definition/credential-definition.module.ts @@ -1,28 +1,27 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Logger, Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' -import { CredentialDefinitionController } from './credential-definition.controller'; -import { CredentialDefinitionService } from './credential-definition.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { CredentialDefinitionController } from './credential-definition.controller' +import { CredentialDefinitionService } from './credential-definition.service' @Module({ - imports:[ + imports: [ ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.CREDENTIAL_DEFINITION_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } - ]) + options: getNatsOptions(CommonConstants.CREDENTIAL_DEFINITION_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [CredentialDefinitionController], - providers: [CredentialDefinitionService, NATSClient] + providers: [CredentialDefinitionService, NATSClient], }) export class CredentialDefinitionModule { constructor() { - Logger.log('API Gateway - CredDef loaded...'); - + Logger.log('API Gateway - CredDef loaded...') } } diff --git a/apps/api-gateway/src/credential-definition/credential-definition.service.spec.ts b/apps/api-gateway/src/credential-definition/credential-definition.service.spec.ts index 8d6322afc..469706d6c 100644 --- a/apps/api-gateway/src/credential-definition/credential-definition.service.spec.ts +++ b/apps/api-gateway/src/credential-definition/credential-definition.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { CredentialDefinitionService } from './credential-definition.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { CredentialDefinitionService } from './credential-definition.service' describe('CredentialDefinitionService', () => { - let service: CredentialDefinitionService; + let service: CredentialDefinitionService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [CredentialDefinitionService] - }).compile(); + providers: [CredentialDefinitionService], + }).compile() - service = module.get(CredentialDefinitionService); - }); + service = module.get(CredentialDefinitionService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/apps/api-gateway/src/credential-definition/credential-definition.service.ts b/apps/api-gateway/src/credential-definition/credential-definition.service.ts index 330e6d200..58ad930ae 100644 --- a/apps/api-gateway/src/credential-definition/credential-definition.service.ts +++ b/apps/api-gateway/src/credential-definition/credential-definition.service.ts @@ -1,40 +1,47 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { CreateCredentialDefinitionDto } from './dto/create-cred-defs.dto'; -import { BaseService } from '../../../../libs/service/base.service'; -import { IUserRequestInterface } from '../interfaces/IUserRequestInterface'; -import { GetAllCredDefsDto } from '../dtos/get-cred-defs.dto'; -import { ICredDef, ICredDefs } from './interfaces'; -import { ICredDefData } from '@credebl/common/interfaces/cred-def.interface'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { ICredDefData } from '@credebl/common/interfaces/cred-def.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from '../../../../libs/service/base.service' +import type { GetAllCredDefsDto } from '../dtos/get-cred-defs.dto' +import type { IUserRequestInterface } from '../interfaces/IUserRequestInterface' +import type { CreateCredentialDefinitionDto } from './dto/create-cred-defs.dto' +import type { ICredDef, ICredDefs } from './interfaces' @Injectable() export class CredentialDefinitionService extends BaseService { - constructor( @Inject('NATS_CLIENT') private readonly credDefServiceProxy: ClientProxy, - private readonly natsClient : NATSClient + private readonly natsClient: NATSClient ) { - super('CredentialDefinitionService'); + super('CredentialDefinitionService') } createCredentialDefinition(credDef: CreateCredentialDefinitionDto, user: IUserRequestInterface): Promise { - const payload = { credDef, user }; - return this.natsClient.sendNatsMessage(this.credDefServiceProxy, 'create-credential-definition', payload); + const payload = { credDef, user } + return this.natsClient.sendNatsMessage(this.credDefServiceProxy, 'create-credential-definition', payload) } getCredentialDefinitionById(credentialDefinitionId: string, orgId: string): Promise { - const payload = { credentialDefinitionId, orgId }; - return this.natsClient.sendNatsMessage(this.credDefServiceProxy, 'get-credential-definition-by-id', payload); + const payload = { credentialDefinitionId, orgId } + return this.natsClient.sendNatsMessage(this.credDefServiceProxy, 'get-credential-definition-by-id', payload) } - getAllCredDefs(credDefSearchCriteria: GetAllCredDefsDto, user: IUserRequestInterface, orgId: string): Promise { - const payload = { credDefSearchCriteria, user, orgId }; - return this.natsClient.sendNatsMessage(this.credDefServiceProxy, 'get-all-credential-definitions', payload); + getAllCredDefs( + credDefSearchCriteria: GetAllCredDefsDto, + user: IUserRequestInterface, + orgId: string + ): Promise { + const payload = { credDefSearchCriteria, user, orgId } + return this.natsClient.sendNatsMessage(this.credDefServiceProxy, 'get-all-credential-definitions', payload) } getCredentialDefinitionBySchemaId(schemaId: string): Promise { - const payload = { schemaId }; - return this.natsClient.sendNatsMessage(this.credDefServiceProxy, 'get-all-credential-definitions-by-schema-id', payload); + const payload = { schemaId } + return this.natsClient.sendNatsMessage( + this.credDefServiceProxy, + 'get-all-credential-definitions-by-schema-id', + payload + ) } } diff --git a/apps/api-gateway/src/credential-definition/dto/create-cred-defs.dto.ts b/apps/api-gateway/src/credential-definition/dto/create-cred-defs.dto.ts index 2187ad362..fd6fdd262 100644 --- a/apps/api-gateway/src/credential-definition/dto/create-cred-defs.dto.ts +++ b/apps/api-gateway/src/credential-definition/dto/create-cred-defs.dto.ts @@ -1,33 +1,32 @@ -import { IsBoolean, IsDefined, IsNotEmpty, IsOptional, IsString } from 'class-validator'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsBoolean, IsDefined, IsNotEmpty, IsOptional, IsString } from 'class-validator' export class CreateCredentialDefinitionDto { + @ApiProperty({ example: 'default' }) + @IsDefined({ message: 'Tag is required' }) + @IsNotEmpty({ message: 'Please provide a tag' }) + @IsString({ message: 'Tag should be string' }) + tag: string - @ApiProperty({ 'example': 'default' }) - @IsDefined({ message: 'Tag is required' }) - @IsNotEmpty({ message: 'Please provide a tag' }) - @IsString({ message: 'Tag should be string' }) - tag: string; + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0' }) + @IsDefined({ message: 'schemaLedgerId is required' }) + @IsNotEmpty({ message: 'Please provide valid schema ledger Id' }) + @Transform(({ value }) => trim(value)) + @IsString({ message: 'Schema id should be string' }) + schemaLedgerId: string - @ApiProperty({ 'example': 'WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0' }) - @IsDefined({ message: 'schemaLedgerId is required' }) - @IsNotEmpty({ message: 'Please provide valid schema ledger Id' }) - @Transform(({ value }) => trim(value)) - @IsString({ message: 'Schema id should be string' }) - schemaLedgerId: string; + orgId: string - orgId: string; + @ApiProperty({ required: false }) + @IsOptional() + @IsString({ message: 'orgDid must be a string' }) + orgDid: string - @ApiProperty({ required: false }) - @IsOptional() - @IsString({ message: 'orgDid must be a string' }) - orgDid: string; - - @ApiProperty({ default: false }) - @IsDefined({ message: 'Revocable is required.' }) - @IsBoolean({ message: 'Revocable must be a boolean value.' }) - @IsNotEmpty({ message: 'Please provide whether the revocable must be true or false' }) - revocable: boolean; + @ApiProperty({ default: false }) + @IsDefined({ message: 'Revocable is required.' }) + @IsBoolean({ message: 'Revocable must be a boolean value.' }) + @IsNotEmpty({ message: 'Please provide whether the revocable must be true or false' }) + revocable: boolean } diff --git a/apps/api-gateway/src/credential-definition/dto/get-all-cred-defs.dto.ts b/apps/api-gateway/src/credential-definition/dto/get-all-cred-defs.dto.ts index 475519e93..598003ff8 100644 --- a/apps/api-gateway/src/credential-definition/dto/get-all-cred-defs.dto.ts +++ b/apps/api-gateway/src/credential-definition/dto/get-all-cred-defs.dto.ts @@ -1,39 +1,38 @@ +import { toNumber } from '@credebl/common/cast.helper' /* eslint-disable @typescript-eslint/no-inferrable-types */ /* eslint-disable camelcase */ -import { ApiProperty } from '@nestjs/swagger'; -import { SortValue } from '../../enum'; -import { Transform, Type } from 'class-transformer'; -import { IsOptional, Max, Min } from 'class-validator'; -import { toNumber } from '@credebl/common/cast.helper'; +import { ApiProperty } from '@nestjs/swagger' +import { Transform, Type } from 'class-transformer' +import { IsOptional, Max, Min } from 'class-validator' +import { SortValue } from '../../enum' export class GetAllCredDefsDto { - @ApiProperty({ required: false, default: 1 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - pageNumber: number = 1; + @ApiProperty({ required: false, default: 1 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + pageNumber = 1 - @ApiProperty({ required: false }) - @IsOptional() - @Type(() => String) - searchByText: string = ''; + @ApiProperty({ required: false }) + @IsOptional() + @Type(() => String) + searchByText = '' - @ApiProperty({ required: false, default: 10 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - @Min(1, { message: 'Page size must be greater than 0' }) - @Max(100, { message: 'Page size must be less than 100' }) - pageSize: number = 10; + @ApiProperty({ required: false, default: 10 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + @Min(1, { message: 'Page size must be greater than 0' }) + @Max(100, { message: 'Page size must be less than 100' }) + pageSize = 10 - @ApiProperty({ required: false }) - @IsOptional() - sorting: string = 'id'; + @ApiProperty({ required: false }) + @IsOptional() + sorting = 'id' - @ApiProperty({ required: false }) - @IsOptional() - sortByValue: string = SortValue.DESC; + @ApiProperty({ required: false }) + @IsOptional() + sortByValue: string = SortValue.DESC - @ApiProperty({ required: false }) - @IsOptional() - revocable: boolean = true; + @ApiProperty({ required: false }) + @IsOptional() + revocable = true } - diff --git a/apps/api-gateway/src/credential-definition/dto/get-all-platform-cred-defs.dto.ts b/apps/api-gateway/src/credential-definition/dto/get-all-platform-cred-defs.dto.ts index 20f4fb34c..c7a138f7c 100644 --- a/apps/api-gateway/src/credential-definition/dto/get-all-platform-cred-defs.dto.ts +++ b/apps/api-gateway/src/credential-definition/dto/get-all-platform-cred-defs.dto.ts @@ -1,30 +1,28 @@ -import { trim } from '@credebl/common/cast.helper'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; -import { CredDefSortFields, SortValue } from '@credebl/enum/enum'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsEnum, IsOptional, IsUUID } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import { CredDefSortFields, SortValue } from '@credebl/enum/enum' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsEnum, IsOptional, IsUUID } from 'class-validator' export class GetAllPlatformCredDefsDto extends PaginationDto { + @ApiProperty({ example: '1a7eac11-ff05-40d7-8351-4d7467687cad' }) + @ApiPropertyOptional() + @Transform(({ value }) => (typeof value === 'string' && value.trim() === '' ? undefined : value.trim())) + @IsOptional() + @IsUUID('4', { message: 'Invalid format of ledgerId' }) + ledgerId?: string - @ApiProperty({ example: '1a7eac11-ff05-40d7-8351-4d7467687cad'}) - @ApiPropertyOptional() - @Transform(({ value }) => ('string' === typeof value && '' === value.trim() ? undefined : value.trim())) - @IsOptional() - @IsUUID('4', { message: 'Invalid format of ledgerId' }) - ledgerId?: string; - - @ApiProperty({ - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(CredDefSortFields) - sortField: string = CredDefSortFields.CREATED_DATE_TIME; + @ApiProperty({ + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(CredDefSortFields) + sortField: string = CredDefSortFields.CREATED_DATE_TIME - @ApiProperty({ required: false }) - @Transform(({ value }) => trim(value)) - @IsOptional() - sortBy: string = SortValue.DESC; - + @ApiProperty({ required: false }) + @Transform(({ value }) => trim(value)) + @IsOptional() + sortBy: string = SortValue.DESC } diff --git a/apps/api-gateway/src/credential-definition/interfaces/index.ts b/apps/api-gateway/src/credential-definition/interfaces/index.ts index f196534e6..0289ad062 100644 --- a/apps/api-gateway/src/credential-definition/interfaces/index.ts +++ b/apps/api-gateway/src/credential-definition/interfaces/index.ts @@ -1,66 +1,65 @@ -import { UserRoleOrgPermsDto } from '../../dtos/user-role-org-perms.dto'; +import type { UserRoleOrgPermsDto } from '../../dtos/user-role-org-perms.dto' export interface IUserRequestInterface { - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?: string; - selectedOrg: ISelectedOrgInterface; + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string + selectedOrg: ISelectedOrgInterface } export interface ISelectedOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: object; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: object } export interface IOrganizationInterface { - name: string; - description: string; + name: string + description: string org_agents: IOrgAgentInterface[] - } export interface IOrgAgentInterface { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } export interface ICredDef { - id: string; - createDateTime: string; - createdBy: string; - credentialDefinitionId: string; - tag: string; - schemaLedgerId: string; - schemaId: string; - revocable: boolean; - orgId: string; + id: string + createDateTime: string + createdBy: string + credentialDefinitionId: string + tag: string + schemaLedgerId: string + schemaId: string + revocable: boolean + orgId: string } -export interface ICredDefs extends ICredDef{ - lastChangedDateTime: string; - lastChangedBy: string; +export interface ICredDefs extends ICredDef { + lastChangedDateTime: string + lastChangedBy: string } export interface ICredentialDefinition { - credentialDefinitionId: string; - schemaCredDefName: string; - schemaName: string; - schemaVersion: string; - schemaAttributes: string; - credentialDefinition: string; + credentialDefinitionId: string + schemaCredDefName: string + schemaName: string + schemaVersion: string + schemaAttributes: string + credentialDefinition: string } diff --git a/apps/api-gateway/src/dtos/PresentProof.dto.ts b/apps/api-gateway/src/dtos/PresentProof.dto.ts index 20fd37643..cf014d469 100644 --- a/apps/api-gateway/src/dtos/PresentProof.dto.ts +++ b/apps/api-gateway/src/dtos/PresentProof.dto.ts @@ -1,3 +1,3 @@ export class PresentProofDto { - credDef?: string; -} \ No newline at end of file + credDef?: string +} diff --git a/apps/api-gateway/src/dtos/UpdateNonAdminUser.dto.ts b/apps/api-gateway/src/dtos/UpdateNonAdminUser.dto.ts index 0d9c866f1..119a43699 100644 --- a/apps/api-gateway/src/dtos/UpdateNonAdminUser.dto.ts +++ b/apps/api-gateway/src/dtos/UpdateNonAdminUser.dto.ts @@ -1,15 +1,15 @@ -import { IsBoolean, IsInt, IsNotEmpty } from 'class-validator'; +import { IsBoolean, IsInt, IsNotEmpty } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class UpdateNonAdminUserDto { - @ApiProperty() - @IsNotEmpty({ message: 'Please provide valid organization id.' }) - @IsInt({ message: 'Organization id should be number.' }) - id: number; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid organization id.' }) + @IsInt({ message: 'Organization id should be number.' }) + id: number - @ApiProperty() - @IsNotEmpty({ message: 'Please provide valid status.' }) - @IsBoolean({ message: 'Status should be boolean.' }) - isActive: boolean; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid status.' }) + @IsBoolean({ message: 'Status should be boolean.' }) + isActive: boolean } diff --git a/apps/api-gateway/src/dtos/admin-onboard-user.dto.ts b/apps/api-gateway/src/dtos/admin-onboard-user.dto.ts index c15e3f6bd..17cce9619 100644 --- a/apps/api-gateway/src/dtos/admin-onboard-user.dto.ts +++ b/apps/api-gateway/src/dtos/admin-onboard-user.dto.ts @@ -1,67 +1,66 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsInt } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsInt, IsString } from 'class-validator' export class AdminOnBoardUserDto { - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid orgName'}) - @IsString({message:'OrgName should be string'}) - orgName: string; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid orgName'}) + @IsString({ message: 'OrgName should be string' }) + orgName: string - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid description'}) - @IsString({message:'Description should be string'}) - description: string; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid description'}) + @IsString({ message: 'Description should be string' }) + description: string - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid displayName'}) - @IsString({message:'DisplayName should be string'}) - displayName: string; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid displayName'}) + @IsString({ message: 'DisplayName should be string' }) + displayName: string - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid logoUrl'}) - @IsString({message:'LogoUrl should be string'}) - logoUrl: string; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid logoUrl'}) + @IsString({ message: 'LogoUrl should be string' }) + logoUrl: string - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid address'}) - @IsString({message:'Address should be string'}) - address: string; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid address'}) + @IsString({ message: 'Address should be string' }) + address: string - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid adminEmail'}) - @IsString({message:'AdminEmail should be string'}) - adminEmail: string; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid adminEmail'}) + @IsString({ message: 'AdminEmail should be string' }) + adminEmail: string - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid adminContact'}) - @IsString({message:'AdminContact should be string'}) - adminContact: string; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid adminContact'}) + @IsString({ message: 'AdminContact should be string' }) + adminContact: string - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid noOfUsers'}) - @IsInt({message:'NoOfUsers should be number'}) - noOfUsers: number; + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid noOfUsers'}) + @IsInt({ message: 'NoOfUsers should be number' }) + noOfUsers: number - @ApiProperty() - @IsInt({message:'NoOfSchemas should be number'}) - noOfSchemas: number; + @ApiProperty() + @IsInt({ message: 'NoOfSchemas should be number' }) + noOfSchemas: number - @ApiProperty() - @IsInt({message:'NoOfCredentials should be number'}) - noOfCredentials: number; + @ApiProperty() + @IsInt({ message: 'NoOfCredentials should be number' }) + noOfCredentials: number - @ApiProperty() - @IsString({message:'AdminPassword should be string'}) - adminPassword: string; + @ApiProperty() + @IsString({ message: 'AdminPassword should be string' }) + adminPassword: string - @ApiProperty() - @IsString({message:'AdminUsername should be string'}) - adminUsername: string; + @ApiProperty() + @IsString({ message: 'AdminUsername should be string' }) + adminUsername: string - @ApiProperty() - @IsInt({message:'OrgCategory should be number'}) - orgCategory: number; - - @IsString({message:'ByAdmin should be string'}) - byAdmin?: string; + @ApiProperty() + @IsInt({ message: 'OrgCategory should be number' }) + orgCategory: number + @IsString({ message: 'ByAdmin should be string' }) + byAdmin?: string } diff --git a/apps/api-gateway/src/dtos/admin-profile-update.dto.ts b/apps/api-gateway/src/dtos/admin-profile-update.dto.ts index 4f9533747..b310b436b 100644 --- a/apps/api-gateway/src/dtos/admin-profile-update.dto.ts +++ b/apps/api-gateway/src/dtos/admin-profile-update.dto.ts @@ -1,49 +1,49 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class AdminProfileDto { - @ApiProperty() - @IsNotEmpty({message:'Please provide valid displayName'}) - @IsString({message:'DisplayName should be string'}) - displayName?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid description'}) - @IsString({message:'Description should be string'}) - description?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid adminContact'}) - @IsString({message:'AdminContact should be string'}) - adminContact?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid address'}) - @IsString({message:'Address should be string'}) - address?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid logoUrl'}) - @IsString({message:'LogoUrl should be string'}) - logoUrl?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid website'}) - @IsString({message:'Website should be string'}) - website?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid solutionTitle'}) - @IsString({message:'SolutionTitle should be string'}) - solutionTitle?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid solutionDesc'}) - @IsString({message:'SolutionDesc should be string'}) - solutionDesc?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid tags'}) - @IsString({message:'Tags should be string'}) - tags?: string; -} \ No newline at end of file + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid displayName' }) + @IsString({ message: 'DisplayName should be string' }) + displayName?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid description' }) + @IsString({ message: 'Description should be string' }) + description?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid adminContact' }) + @IsString({ message: 'AdminContact should be string' }) + adminContact?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid address' }) + @IsString({ message: 'Address should be string' }) + address?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid logoUrl' }) + @IsString({ message: 'LogoUrl should be string' }) + logoUrl?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid website' }) + @IsString({ message: 'Website should be string' }) + website?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid solutionTitle' }) + @IsString({ message: 'SolutionTitle should be string' }) + solutionTitle?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid solutionDesc' }) + @IsString({ message: 'SolutionDesc should be string' }) + solutionDesc?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid tags' }) + @IsString({ message: 'Tags should be string' }) + tags?: string +} diff --git a/apps/api-gateway/src/dtos/apiResponse.dto copy.ts b/apps/api-gateway/src/dtos/apiResponse.dto copy.ts index 60fa37163..d77b1d9b6 100644 --- a/apps/api-gateway/src/dtos/apiResponse.dto copy.ts +++ b/apps/api-gateway/src/dtos/apiResponse.dto copy.ts @@ -1,15 +1,15 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class ApiResponseDto { - @ApiProperty({ example: 'Success' }) - message: string; + @ApiProperty({ example: 'Success' }) + message: string - @ApiProperty() - success: boolean; + @ApiProperty() + success: boolean - @ApiProperty() - data?: any; + @ApiProperty() + data?: unknown - @ApiProperty({ example: 200 }) - code?: number; + @ApiProperty({ example: 200 }) + code?: number } diff --git a/apps/api-gateway/src/dtos/apiResponse.dto.ts b/apps/api-gateway/src/dtos/apiResponse.dto.ts index 4e15f1f71..7d53e72f0 100644 --- a/apps/api-gateway/src/dtos/apiResponse.dto.ts +++ b/apps/api-gateway/src/dtos/apiResponse.dto.ts @@ -1,15 +1,15 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class ApiResponseDto { - @ApiProperty({ example: 'Success' }) - message: string; + @ApiProperty({ example: 'Success' }) + message: string - @ApiProperty() - success: boolean; + @ApiProperty() + success: boolean - @ApiProperty() - data?: object; + @ApiProperty() + data?: object - @ApiProperty({ example: 200 }) - statusCode?: number; + @ApiProperty({ example: 200 }) + statusCode?: number } diff --git a/apps/api-gateway/src/dtos/approval-status.dto.ts b/apps/api-gateway/src/dtos/approval-status.dto.ts index a8113edbb..1df2baf50 100644 --- a/apps/api-gateway/src/dtos/approval-status.dto.ts +++ b/apps/api-gateway/src/dtos/approval-status.dto.ts @@ -1,7 +1,6 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class ApprovalStatusDto { - - @ApiProperty() - approvalStatus: boolean; + @ApiProperty() + approvalStatus: boolean } diff --git a/apps/api-gateway/src/dtos/authDto.dto.ts b/apps/api-gateway/src/dtos/authDto.dto.ts index 39a6d00a0..d05b3c947 100644 --- a/apps/api-gateway/src/dtos/authDto.dto.ts +++ b/apps/api-gateway/src/dtos/authDto.dto.ts @@ -1,24 +1,24 @@ -import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class AuthDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @IsOptional() - @IsBoolean({ message: 'flag should be boolean' }) - flag: boolean; + @IsOptional() + @IsBoolean({ message: 'flag should be boolean' }) + flag: boolean - @IsOptional() - @ApiProperty({ example: 'Password@1' }) - @IsNotEmpty({ message: 'Please provide valid password' }) - @IsString({ message: 'password should be string' }) - password: string; + @IsOptional() + @ApiProperty({ example: 'Password@1' }) + @IsNotEmpty({ message: 'Please provide valid password' }) + @IsString({ message: 'password should be string' }) + password: string } diff --git a/apps/api-gateway/src/dtos/bad-request-error.dto.ts b/apps/api-gateway/src/dtos/bad-request-error.dto.ts index 8a1669de5..5af98494a 100644 --- a/apps/api-gateway/src/dtos/bad-request-error.dto.ts +++ b/apps/api-gateway/src/dtos/bad-request-error.dto.ts @@ -1,14 +1,13 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { HttpStatus } from '@nestjs/common'; +import { HttpStatus } from '@nestjs/common' +import { ApiProperty } from '@nestjs/swagger' export class BadRequestErrorDto { + @ApiProperty({ example: HttpStatus.BAD_REQUEST }) + statusCode: number - @ApiProperty({ example: HttpStatus.BAD_REQUEST }) - statusCode: number; + @ApiProperty({ example: 'Please provide valid data' }) + message: string - @ApiProperty({ example: 'Please provide valid data' }) - message: string; - - @ApiProperty({ example: 'Bad Request' }) - error: string; + @ApiProperty({ example: 'Bad Request' }) + error: string } diff --git a/apps/api-gateway/src/dtos/category.dto.ts b/apps/api-gateway/src/dtos/category.dto.ts index f3bfb7a6e..6c033916b 100644 --- a/apps/api-gateway/src/dtos/category.dto.ts +++ b/apps/api-gateway/src/dtos/category.dto.ts @@ -1,22 +1,22 @@ -import { IsBoolean, IsNotEmpty, IsString, MaxLength, MinLength } from 'class-validator'; +import { IsBoolean, IsNotEmpty, IsString, MaxLength, MinLength } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class CategoryDto { - @ApiProperty() - @IsString({ message: 'name must be a string' }) - @IsNotEmpty({ message: 'please provide valid name' }) - name: string; + @ApiProperty() + @IsString({ message: 'name must be a string' }) + @IsNotEmpty({ message: 'please provide valid name' }) + name: string - @ApiProperty() - @IsString({ message: 'description must be a string' }) - @MaxLength(150) - @MinLength(2) - @IsNotEmpty({ message: 'please provide valid description' }) - description: string; + @ApiProperty() + @IsString({ message: 'description must be a string' }) + @MaxLength(150) + @MinLength(2) + @IsNotEmpty({ message: 'please provide valid description' }) + description: string - @ApiProperty() - @IsNotEmpty({ message: 'Please provide a isActive' }) - @IsBoolean({ message: 'isActive id should be boolean' }) - isActive: boolean; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide a isActive' }) + @IsBoolean({ message: 'isActive id should be boolean' }) + isActive: boolean } diff --git a/apps/api-gateway/src/dtos/connection-out-of-band.dto.ts b/apps/api-gateway/src/dtos/connection-out-of-band.dto.ts index bdfc6f1fc..c43a8e866 100644 --- a/apps/api-gateway/src/dtos/connection-out-of-band.dto.ts +++ b/apps/api-gateway/src/dtos/connection-out-of-band.dto.ts @@ -1,28 +1,26 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsString, IsNotEmpty, IsObject, IsNegative } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsArray, IsNotEmpty } from 'class-validator' - -interface attachmentsObject{ -id:string, -type:string +interface attachmentsObject { + id: string + type: string } export class ConnectionOutOfBandDto { + @ApiProperty({ example: '' }) + alias?: string - @ApiProperty({'example':''}) - alias?:string; + @ApiProperty({ example: '[{id:107ad6d1-5312-4b2b-bbfa-6becf6155e23,type:credential-offer}]' }) + @IsArray({ message: 'attachemnts must be in array' }) + @IsNotEmpty({ message: 'Please provide valid attachments' }) + attachments: attachmentsObject[] - @ApiProperty({'example':'[{id:107ad6d1-5312-4b2b-bbfa-6becf6155e23,type:credential-offer}]'}) - @IsArray({message:'attachemnts must be in array'}) - @IsNotEmpty({message:'Please provide valid attachments'}) - attachments:attachmentsObject[]; + @ApiProperty({ example: '["did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0"]' }) + handshake_protocols: string[] - @ApiProperty({'example':'["did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0"]'}) - handshake_protocols : string[]; + @ApiProperty({ example: '' }) + my_label?: string - @ApiProperty({'example':''}) - my_label?: string; - - @ApiProperty({'example': false}) - use_public_did : boolean; -} \ No newline at end of file + @ApiProperty({ example: false }) + use_public_did: boolean +} diff --git a/apps/api-gateway/src/dtos/connection.dto.ts b/apps/api-gateway/src/dtos/connection.dto.ts index 3df7acb17..27cbbc29d 100644 --- a/apps/api-gateway/src/dtos/connection.dto.ts +++ b/apps/api-gateway/src/dtos/connection.dto.ts @@ -1,49 +1,48 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class ConnectionDto { + @ApiProperty() + // tslint:disable-next-line: variable-name + connection_id: string - @ApiProperty() - // tslint:disable-next-line: variable-name - connection_id: string; + @ApiProperty() + state: string - @ApiProperty() - state: string; + @ApiProperty() + // tslint:disable-next-line: variable-name + my_did: string - @ApiProperty() - // tslint:disable-next-line: variable-name - my_did: string; + @ApiProperty() + // tslint:disable-next-line: variable-name + their_did: string - @ApiProperty() - // tslint:disable-next-line: variable-name - their_did: string; + @ApiProperty() + // tslint:disable-next-line: variable-name + their_label: string - @ApiProperty() - // tslint:disable-next-line: variable-name - their_label: string; + @ApiProperty() + initiator: string - @ApiProperty() - initiator: string; + @ApiProperty() + // tslint:disable-next-line: variable-name + invitation_key: string - @ApiProperty() - // tslint:disable-next-line: variable-name - invitation_key: string; + @ApiProperty() + // tslint:disable-next-line: variable-name + routing_state: string - @ApiProperty() - // tslint:disable-next-line: variable-name - routing_state: string; + @ApiProperty() + accept: string - @ApiProperty() - accept: string; + @ApiProperty() + // tslint:disable-next-line: variable-name + invitation_mode: string - @ApiProperty() - // tslint:disable-next-line: variable-name - invitation_mode: string; + @ApiProperty() + // tslint:disable-next-line: variable-name + updated_at: string - @ApiProperty() - // tslint:disable-next-line: variable-name - updated_at: string; - - @ApiProperty() - // tslint:disable-next-line: variable-name - created_at: string; -} \ No newline at end of file + @ApiProperty() + // tslint:disable-next-line: variable-name + created_at: string +} diff --git a/apps/api-gateway/src/dtos/create-credential-definition.dto.ts b/apps/api-gateway/src/dtos/create-credential-definition.dto.ts index dda18b786..4a77bc033 100644 --- a/apps/api-gateway/src/dtos/create-credential-definition.dto.ts +++ b/apps/api-gateway/src/dtos/create-credential-definition.dto.ts @@ -1,32 +1,31 @@ -import { IsBoolean, IsDefined, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { IsBoolean, IsDefined, IsNotEmpty, IsOptional, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class CreateCredentialDefinitionDto { + @ApiProperty({ example: 'default' }) + @IsNotEmpty({ message: 'Please provide a tag' }) + @IsString({ message: 'Tag id should be string' }) + tag: string - @ApiProperty({ 'example': 'default' }) - @IsNotEmpty({ message: 'Please provide a tag' }) - @IsString({ message: 'Tag id should be string' }) - tag: string; + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0' }) + @IsNotEmpty({ message: 'Please provide a schema id' }) + @IsString({ message: 'Schema id should be string' }) + schemaLedgerId: string - @ApiProperty({ 'example': 'WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0' }) - @IsNotEmpty({ message: 'Please provide a schema id' }) - @IsString({ message: 'Schema id should be string' }) - schemaLedgerId: string; + @ApiProperty() - @ApiProperty() - - @IsNotEmpty({ message: 'Please provide orgId' }) - orgId: string; + @IsNotEmpty({ message: 'Please provide orgId' }) + orgId: string - @ApiProperty({ required: false }) - @IsOptional() - @IsString({ message: 'orgDid must be a string' }) - orgDid: string; + @ApiProperty({ required: false }) + @IsOptional() + @IsString({ message: 'orgDid must be a string' }) + orgDid: string - @ApiProperty({ default: true }) - @IsDefined({ message: 'Revocable is required.' }) - @IsBoolean({ message: 'Revocable must be a boolean value.' }) - @IsNotEmpty({ message: 'Please provide whether the revocable must be true or false' }) - revocable = true; + @ApiProperty({ default: true }) + @IsDefined({ message: 'Revocable is required.' }) + @IsBoolean({ message: 'Revocable must be a boolean value.' }) + @IsNotEmpty({ message: 'Please provide whether the revocable must be true or false' }) + revocable = true } diff --git a/apps/api-gateway/src/dtos/create-feature-price.dto.ts b/apps/api-gateway/src/dtos/create-feature-price.dto.ts index c88a81037..9a0a4e4f0 100644 --- a/apps/api-gateway/src/dtos/create-feature-price.dto.ts +++ b/apps/api-gateway/src/dtos/create-feature-price.dto.ts @@ -1,31 +1,30 @@ -import { IsArray, IsInt, IsNotEmpty } from 'class-validator'; +import { IsArray, IsInt, IsNotEmpty } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' interface featurePriceData { - featureId: number, - featurePrice: number + featureId: number + featurePrice: number } export class CreateFeaturePriceDto { + @ApiProperty({ example: 1 }) + @IsNotEmpty({ message: 'Please provide network id.' }) + @IsInt({ message: 'Please provide valid network id.' }) + networkID: number - @ApiProperty({ 'example': 1 }) - @IsNotEmpty({ message: 'Please provide network id.' }) - @IsInt({ message: 'Please provide valid network id.' }) - networkID: number; - - @ApiProperty({ - 'example': [ -{ - featureId: 1, - featurePrice: 200 - }, - { - featureId: 2, - featurePrice: 400 - } -] - }) - @IsNotEmpty({ message: 'Please provide featureId and price.' }) - @IsArray({ message: 'FeatureId and price should be in array format.' }) - featurePrice: featurePriceData[]; + @ApiProperty({ + example: [ + { + featureId: 1, + featurePrice: 200, + }, + { + featureId: 2, + featurePrice: 400, + }, + ], + }) + @IsNotEmpty({ message: 'Please provide featureId and price.' }) + @IsArray({ message: 'FeatureId and price should be in array format.' }) + featurePrice: featurePriceData[] } diff --git a/apps/api-gateway/src/dtos/create-proof-request.dto.ts b/apps/api-gateway/src/dtos/create-proof-request.dto.ts index ac5c5a4c4..6b549172f 100644 --- a/apps/api-gateway/src/dtos/create-proof-request.dto.ts +++ b/apps/api-gateway/src/dtos/create-proof-request.dto.ts @@ -1,20 +1,20 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class CreateProofRequest { - @ApiProperty({'example': 'comments'}) - comment: string; + @ApiProperty({ example: 'comments' }) + comment: string - @ApiProperty({ 'example': 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) - credDefId?: string; + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) + credDefId?: string - @ApiProperty({ - 'example': [ -{ - attributeName: 'attributeName', - condition: '>=', - value: 'predicates' - } -] - }) - attributes: object[]; -} \ No newline at end of file + @ApiProperty({ + example: [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + }, + ], + }) + attributes: object[] +} diff --git a/apps/api-gateway/src/dtos/create-revocation-registry.dto.ts b/apps/api-gateway/src/dtos/create-revocation-registry.dto.ts index efc0cc2b9..9bf5366b4 100644 --- a/apps/api-gateway/src/dtos/create-revocation-registry.dto.ts +++ b/apps/api-gateway/src/dtos/create-revocation-registry.dto.ts @@ -1,13 +1,12 @@ -import { ApiProperty } from '@nestjs/swagger'; - +import { ApiProperty } from '@nestjs/swagger' export class CreateRevocationRegistryDto { - @ApiProperty({ example: 100 }) - max_cred_num: number; + @ApiProperty({ example: 100 }) + max_cred_num: number - @ApiProperty({ example: true }) - issuance_by_default: boolean; + @ApiProperty({ example: true }) + issuance_by_default: boolean - @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) - credential_definition_id: string; -} \ No newline at end of file + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) + credential_definition_id: string +} diff --git a/apps/api-gateway/src/dtos/create-schema.dto.ts b/apps/api-gateway/src/dtos/create-schema.dto.ts index 91674834d..77263b239 100644 --- a/apps/api-gateway/src/dtos/create-schema.dto.ts +++ b/apps/api-gateway/src/dtos/create-schema.dto.ts @@ -1,4 +1,7 @@ -import { ApiExtraModels, ApiProperty, ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger'; +import { IsNotSQLInjection, ValidateNestedStructureFields, trim } from '@credebl/common/cast.helper' +import { IndySchemaDataType, JSONSchemaType, SchemaTypeEnum, W3CSchemaDataType } from '@credebl/enum/enum' +import { ApiExtraModels, ApiProperty, ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger' +import { Transform, Type, plainToClass } from 'class-transformer' import { ArrayMinSize, IsArray, @@ -12,114 +15,111 @@ import { IsString, Min, ValidateIf, - ValidateNested -} from 'class-validator'; -import { IndySchemaDataType, JSONSchemaType, SchemaTypeEnum, W3CSchemaDataType } from '@credebl/enum/enum'; -import { IsNotSQLInjection, ValidateNestedStructureFields, trim } from '@credebl/common/cast.helper'; -import { Transform, Type, plainToClass } from 'class-transformer'; + ValidateNested, +} from 'class-validator' export class W3CAttributeValue { @ApiProperty() @IsString() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'attributeName is required' }) - attributeName: string; + attributeName: string @ApiProperty() @IsString() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'displayName is required' }) - displayName: string; + displayName: string @ApiProperty({ description: 'The type of the schema', enum: W3CSchemaDataType, - example: W3CSchemaDataType.STRING + example: W3CSchemaDataType.STRING, }) @IsEnum(W3CSchemaDataType, { - message: `Schema data type must be one of [${Object.values(W3CSchemaDataType).join(', ')}]` + message: `Schema data type must be one of [${Object.values(W3CSchemaDataType).join(', ')}]`, }) @ValidateNestedStructureFields() - schemaDataType: W3CSchemaDataType; + schemaDataType: W3CSchemaDataType @ApiProperty() @IsBoolean() @IsNotEmpty({ message: 'isRequired property is required' }) - isRequired: boolean; + isRequired: boolean @ApiPropertyOptional() @IsOptional() - description?: string; + description?: string @ApiPropertyOptional({ description: 'Minimum length for string values' }) @IsOptional() @IsInt() @Min(0) @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.STRING) - minLength?: number; + minLength?: number @ApiPropertyOptional({ description: 'Maximum length for string values' }) @IsOptional() @IsInt() @Min(1) @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.STRING) - maxLength?: number; + maxLength?: number @ApiPropertyOptional({ description: 'Regular expression pattern for string values' }) @IsOptional() @IsString() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.STRING) - pattern?: string; + pattern?: string @ApiPropertyOptional({ description: 'Enumerated values for string type' }) @IsOptional() @IsArray() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.STRING) - enum?: string[]; + enum?: string[] @ApiPropertyOptional({ description: 'Content encoding (e.g., base64)' }) @IsOptional() @IsString() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.STRING) - contentEncoding?: string; + contentEncoding?: string @ApiPropertyOptional({ description: 'Content media type (e.g., image/png)' }) @IsOptional() @IsString() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.STRING) - contentMediaType?: string; + contentMediaType?: string // Number type specific validations @ApiPropertyOptional({ description: 'Minimum value (inclusive) for number values' }) @IsOptional() @IsNumber() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.NUMBER) - minimum?: number; + minimum?: number @ApiPropertyOptional({ description: 'Maximum value (inclusive) for number values' }) @IsOptional() @IsNumber() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.NUMBER) - maximum?: number; + maximum?: number @ApiPropertyOptional({ description: 'Minimum value (exclusive) for number values' }) @IsOptional() @IsNumber() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.NUMBER) - exclusiveMinimum?: number; + exclusiveMinimum?: number @ApiPropertyOptional({ description: 'Maximum value (exclusive) for number values' }) @IsOptional() @IsNumber() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.NUMBER) - exclusiveMaximum?: number; + exclusiveMaximum?: number @ApiPropertyOptional({ description: 'Number must be a multiple of this value' }) @IsOptional() @IsNumber() @IsPositive() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.NUMBER) - multipleOf?: number; + multipleOf?: number // Array type specific validations @ApiPropertyOptional({ description: 'Minimum number of items in array' }) @@ -127,20 +127,20 @@ export class W3CAttributeValue { @IsInt() @Min(0) @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.ARRAY) - minItems?: number; + minItems?: number @ApiPropertyOptional({ description: 'Maximum number of items in array' }) @IsOptional() @IsInt() @Min(1) @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.ARRAY) - maxItems?: number; + maxItems?: number @ApiPropertyOptional({ description: 'Whether array items must be unique' }) @IsOptional() @IsBoolean() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.ARRAY) - uniqueItems?: boolean; + uniqueItems?: boolean @ApiPropertyOptional({ description: 'Array of items', type: [W3CAttributeValue] }) @IsArray() @@ -148,7 +148,7 @@ export class W3CAttributeValue { @ValidateNested({ each: true }) @Type(() => W3CAttributeValue) @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.ARRAY) - items?: W3CAttributeValue[]; + items?: W3CAttributeValue[] // Object type specific validations @ApiPropertyOptional({ description: 'Minimum number of properties in object' }) @@ -156,48 +156,49 @@ export class W3CAttributeValue { @IsInt() @Min(0) @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.OBJECT) - minProperties?: number; + minProperties?: number @ApiPropertyOptional({ description: 'Maximum number of properties in object' }) @IsOptional() @IsInt() @Min(1) @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.OBJECT) - maxProperties?: number; + maxProperties?: number @ApiPropertyOptional({ description: 'additional properties must be boolean' }) @IsOptional() @IsBoolean() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.OBJECT) - additionalProperties?: boolean; + additionalProperties?: boolean @ApiPropertyOptional({ description: 'Required properties for object type' }) @IsOptional() @IsArray() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.OBJECT) - required?: string[]; + required?: string[] @ApiPropertyOptional({ description: 'Dependent required properties' }) @IsOptional() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.OBJECT) - dependentRequired?: Record; + dependentRequired?: Record @ApiPropertyOptional({ description: 'Object with dynamic properties' }) @IsOptional() @ValidateIf((o) => o.schemaDataType === W3CSchemaDataType.OBJECT) @Transform(({ value }) => { - if (value && 'object' === typeof value) { - const result = {}; + if (value && typeof value === 'object') { + const result = {} + // biome-ignore lint/complexity/noForEach: Object.entries(value).forEach(([key, propValue]) => { result[key] = plainToClass(W3CAttributeValue, propValue, { - enableImplicitConversion: false - }); - }); - return result; + enableImplicitConversion: false, + }) + }) + return result } - return value; + return value }) - properties?: Record; + properties?: Record } class AttributeValue { @@ -205,30 +206,30 @@ class AttributeValue { @IsString() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'attributeName is required' }) - attributeName: string; + attributeName: string @ApiProperty({ description: 'The type of the schema', enum: IndySchemaDataType, - example: IndySchemaDataType.STRING + example: IndySchemaDataType.STRING, }) @IsString() @Transform(({ value }) => trim(value)) @IsEnum(IndySchemaDataType, { - message: `Schema data type must be one of [${Object.values(IndySchemaDataType).join(', ')}]` + message: `Schema data type must be one of [${Object.values(IndySchemaDataType).join(', ')}]`, }) - schemaDataType: IndySchemaDataType; + schemaDataType: IndySchemaDataType @ApiProperty() @IsString() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'displayName is required' }) - displayName: string; + displayName: string @ApiProperty() @IsBoolean() @IsNotEmpty({ message: 'isRequired property is required' }) - isRequired: boolean; + isRequired: boolean } export class CreateSchemaDto { @@ -236,14 +237,14 @@ export class CreateSchemaDto { @IsString({ message: 'schemaVersion must be a string' }) @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'schemaVersion is required' }) - schemaVersion: string; + schemaVersion: string @ApiProperty() @IsString({ message: 'schemaName must be a string' }) @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'schemaName is required' }) @IsNotSQLInjection({ message: 'SchemaName is required.' }) - schemaName: string; + schemaName: string @ApiProperty({ type: [AttributeValue], @@ -252,25 +253,25 @@ export class CreateSchemaDto { attributeName: 'name', schemaDataType: 'string', displayName: 'Name', - isRequired: true - } - ] + isRequired: true, + }, + ], }) @IsArray({ message: 'attributes must be an array' }) @IsNotEmpty({ message: 'attributes are required' }) @ArrayMinSize(1) @ValidateNested({ each: true }) @Type(() => AttributeValue) - attributes: AttributeValue[]; + attributes: AttributeValue[] - orgId: string; + orgId: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) @IsOptional() @IsNotEmpty({ message: 'orgDid should not be empty' }) @IsString({ message: 'orgDid must be a string' }) - orgDid: string; + orgDid: string } export class CreateW3CSchemaDto { @@ -281,36 +282,36 @@ export class CreateW3CSchemaDto { attributeName: 'name', schemaDataType: 'string', displayName: 'Name', - isRequired: true - } - ] + isRequired: true, + }, + ], }) @ValidateNested({ each: true }) @Type(() => W3CAttributeValue) @IsArray({ message: 'attributes must be an array' }) @ArrayMinSize(1) @IsNotEmpty() - attributes: W3CAttributeValue[]; + attributes: W3CAttributeValue[] @ApiProperty() @IsString({ message: 'schemaName must be a string' }) @Transform(({ value }) => value.trim()) @IsNotEmpty({ message: 'schemaName is required' }) - schemaName: string; + schemaName: string @ApiProperty() @IsString({ message: 'description must be a string' }) @IsNotEmpty({ message: 'description is required' }) - description: string; + description: string @ApiProperty({ description: 'The type of the schema', enum: JSONSchemaType, - example: JSONSchemaType.POLYGON_W3C + example: JSONSchemaType.POLYGON_W3C, }) @IsEnum(JSONSchemaType, { message: 'Schema type must be a valid schema type' }) @IsNotEmpty({ message: 'Type is required' }) - schemaType: JSONSchemaType; + schemaType: JSONSchemaType } @ApiExtraModels(CreateSchemaDto, CreateW3CSchemaDto) @@ -318,30 +319,31 @@ export class GenericSchemaDTO { @ApiProperty({ description: 'The type of the schema', enum: SchemaTypeEnum, - example: SchemaTypeEnum.INDY + example: SchemaTypeEnum.INDY, }) @IsEnum(SchemaTypeEnum, { message: 'Type must be a valid schema type' }) @IsNotEmpty({ message: 'Type is required' }) - type: SchemaTypeEnum; + type: SchemaTypeEnum @ApiPropertyOptional() @Transform(({ value }) => trim(value)) @IsOptional() @IsString({ message: 'alias must be a string' }) @IsNotEmpty({ message: 'alias is required' }) - alias: string; + alias: string @ApiProperty({ type: Object, - oneOf: [{ $ref: getSchemaPath(CreateSchemaDto) }, { $ref: getSchemaPath(CreateW3CSchemaDto) }] + oneOf: [{ $ref: getSchemaPath(CreateSchemaDto) }, { $ref: getSchemaPath(CreateW3CSchemaDto) }], }) @ValidateNested() @Type(({ object }) => { if (object.type === SchemaTypeEnum.INDY) { - return CreateSchemaDto; - } else if (object.type === SchemaTypeEnum.JSON) { - return CreateW3CSchemaDto; + return CreateSchemaDto + } + if (object.type === SchemaTypeEnum.JSON) { + return CreateW3CSchemaDto } }) - schemaPayload: CreateSchemaDto | CreateW3CSchemaDto; + schemaPayload: CreateSchemaDto | CreateW3CSchemaDto } diff --git a/apps/api-gateway/src/dtos/createEnterprise-query.dto.ts b/apps/api-gateway/src/dtos/createEnterprise-query.dto.ts index 37af0253f..3453dbaeb 100644 --- a/apps/api-gateway/src/dtos/createEnterprise-query.dto.ts +++ b/apps/api-gateway/src/dtos/createEnterprise-query.dto.ts @@ -1,38 +1,36 @@ -import {IsNotEmpty, IsString, IsOptional } from 'class-validator'; +import { IsNotEmpty, IsOptional, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class CreateEnterpriseQueryDto { - - @ApiProperty({ example: 'Name' }) - @IsNotEmpty({ message: 'Please provide valid first name' }) - @IsString({ message: 'First name should be a string' }) - firstName: string; - - @ApiProperty({ example: 'Last name' }) - @IsNotEmpty({ message: 'Please provide valid last name' }) - @IsString({ message: 'Last name should be a string' }) - lastName: string; - - @ApiProperty({ example: 'email@example.com' }) - @IsNotEmpty({ message: 'Please provide valid email address' }) - // @IsEmail({ message: 'Please provide valid email address' }) - emailAddress: string; - - @IsOptional() - @ApiProperty({ example: '1234567890' }) - mobileNumber: string; - - @IsOptional() - @ApiProperty({ example: 'Organization Name' }) - organizationName: string; - - @IsOptional() - @ApiProperty({ example: 'Role in organization' }) - roleInOrganization: string; - - @IsOptional() - @ApiProperty({ example: 'Your query' }) - query: string; - -} \ No newline at end of file + @ApiProperty({ example: 'Name' }) + @IsNotEmpty({ message: 'Please provide valid first name' }) + @IsString({ message: 'First name should be a string' }) + firstName: string + + @ApiProperty({ example: 'Last name' }) + @IsNotEmpty({ message: 'Please provide valid last name' }) + @IsString({ message: 'Last name should be a string' }) + lastName: string + + @ApiProperty({ example: 'email@example.com' }) + @IsNotEmpty({ message: 'Please provide valid email address' }) + // @IsEmail({ message: 'Please provide valid email address' }) + emailAddress: string + + @IsOptional() + @ApiProperty({ example: '1234567890' }) + mobileNumber: string + + @IsOptional() + @ApiProperty({ example: 'Organization Name' }) + organizationName: string + + @IsOptional() + @ApiProperty({ example: 'Role in organization' }) + roleInOrganization: string + + @IsOptional() + @ApiProperty({ example: 'Your query' }) + query: string +} diff --git a/apps/api-gateway/src/dtos/created-response-dto.ts b/apps/api-gateway/src/dtos/created-response-dto.ts index 3c3beeb36..4cd06a904 100644 --- a/apps/api-gateway/src/dtos/created-response-dto.ts +++ b/apps/api-gateway/src/dtos/created-response-dto.ts @@ -1,16 +1,16 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { HttpStatus } from '@nestjs/common'; +import { HttpStatus } from '@nestjs/common' +import { ApiProperty } from '@nestjs/swagger' export class CreatedResponseDto { - @ApiProperty({ example: 'Created' }) - message: string; + @ApiProperty({ example: 'Created' }) + message: string - @ApiProperty() - success: boolean; + @ApiProperty() + success: boolean - @ApiProperty() - data?: any; + @ApiProperty() + data?: unknown - @ApiProperty({ example: HttpStatus.CREATED }) - code?: number; + @ApiProperty({ example: HttpStatus.CREATED }) + code?: number } diff --git a/apps/api-gateway/src/dtos/credential-offer.dto.ts b/apps/api-gateway/src/dtos/credential-offer.dto.ts index c59e54406..2dd2afd7d 100644 --- a/apps/api-gateway/src/dtos/credential-offer.dto.ts +++ b/apps/api-gateway/src/dtos/credential-offer.dto.ts @@ -1,40 +1,39 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsArray, IsNotEmpty, IsString } from "class-validator"; +import { ApiProperty } from '@nestjs/swagger' +import { IsArray, IsNotEmpty, IsString } from 'class-validator' interface attributeValue { - name: string, - value: string, + name: string + value: string } export class IssueCredentialOffer { + @ApiProperty({ example: { protocolVersion: 'v1' } }) + @IsNotEmpty({ message: 'Please provide valid protocol-version' }) + @IsString({ message: 'protocol-version should be string' }) + protocolVersion: string - @ApiProperty({ example: { 'protocolVersion': 'v1' } }) - @IsNotEmpty({ message: 'Please provide valid protocol-version' }) - @IsString({ message: 'protocol-version should be string' }) - protocolVersion: string; - - @ApiProperty({ example: { 'attributes': [{ 'value': 'string', 'name': 'string' }] } }) - @IsNotEmpty({ message: 'Please provide valid attributes' }) - @IsArray({ message: 'attributes should be array' }) - attributes: attributeValue[]; + @ApiProperty({ example: { attributes: [{ value: 'string', name: 'string' }] } }) + @IsNotEmpty({ message: 'Please provide valid attributes' }) + @IsArray({ message: 'attributes should be array' }) + attributes: attributeValue[] - @ApiProperty({ example: { 'credentialDefinitionId': 'string' } }) - @IsNotEmpty({ message: 'Please provide valid credentialDefinitionId' }) - @IsString({ message: 'credentialDefinitionId should be string' }) - credentialDefinitionId: string; + @ApiProperty({ example: { credentialDefinitionId: 'string' } }) + @IsNotEmpty({ message: 'Please provide valid credentialDefinitionId' }) + @IsString({ message: 'credentialDefinitionId should be string' }) + credentialDefinitionId: string - @ApiProperty({ example: { autoAcceptCredential: 'always' } }) - @IsNotEmpty({ message: 'Please provide valid autoAcceptCredential' }) - @IsString({ message: 'autoAcceptCredential should be string' }) - autoAcceptCredential: string; + @ApiProperty({ example: { autoAcceptCredential: 'always' } }) + @IsNotEmpty({ message: 'Please provide valid autoAcceptCredential' }) + @IsString({ message: 'autoAcceptCredential should be string' }) + autoAcceptCredential: string - @ApiProperty({ example: { comment: 'string' } }) - @IsNotEmpty({ message: 'Please provide valid comment' }) - @IsString({ message: 'comment should be string' }) - comment: string; + @ApiProperty({ example: { comment: 'string' } }) + @IsNotEmpty({ message: 'Please provide valid comment' }) + @IsString({ message: 'comment should be string' }) + comment: string - @ApiProperty({ example: { connectionId: '3fa85f64-5717-4562-b3fc-2c963f66afa6' } }) - @IsNotEmpty({ message: 'Please provide valid connection-id' }) - @IsString({ message: 'Connection-id should be string' }) - connectionId: string; + @ApiProperty({ example: { connectionId: '3fa85f64-5717-4562-b3fc-2c963f66afa6' } }) + @IsNotEmpty({ message: 'Please provide valid connection-id' }) + @IsString({ message: 'Connection-id should be string' }) + connectionId: string } diff --git a/apps/api-gateway/src/dtos/credential-send-offer.dto.ts b/apps/api-gateway/src/dtos/credential-send-offer.dto.ts index 1467ef6af..0a169aec2 100644 --- a/apps/api-gateway/src/dtos/credential-send-offer.dto.ts +++ b/apps/api-gateway/src/dtos/credential-send-offer.dto.ts @@ -1,10 +1,9 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsString } from "class-validator"; +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class CredentialSendOffer { - - @ApiProperty({ example: 'string' }) - @IsNotEmpty({ message: 'Please provide valid credentialRecordId' }) - @IsString({ message: 'credentialRecordId should be string' }) - credentialRecordId: string; + @ApiProperty({ example: 'string' }) + @IsNotEmpty({ message: 'Please provide valid credentialRecordId' }) + @IsString({ message: 'credentialRecordId should be string' }) + credentialRecordId: string } diff --git a/apps/api-gateway/src/dtos/email-validator.dto.ts b/apps/api-gateway/src/dtos/email-validator.dto.ts index 1ba458fcf..59d8cbef9 100644 --- a/apps/api-gateway/src/dtos/email-validator.dto.ts +++ b/apps/api-gateway/src/dtos/email-validator.dto.ts @@ -1,16 +1,14 @@ - -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsEmail, IsNotEmpty, IsString, MaxLength } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsEmail, IsNotEmpty, IsString, MaxLength } from 'class-validator' export class EmailValidator { - @ApiProperty({ example: 'awqx@yopmail.com' }) @IsEmail({}, { message: 'Please provide a valid email' }) @IsNotEmpty({ message: 'Email is required' }) @IsString({ message: 'Email should be a string' }) @Transform(({ value }) => trim(value)) @MaxLength(256, { message: 'Email must be at most 256 character' }) - email: string; -} \ No newline at end of file + email: string +} diff --git a/apps/api-gateway/src/dtos/email.dto.ts b/apps/api-gateway/src/dtos/email.dto.ts index 457f050c5..90ac8f377 100644 --- a/apps/api-gateway/src/dtos/email.dto.ts +++ b/apps/api-gateway/src/dtos/email.dto.ts @@ -1,18 +1,18 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class EmailDto { - @ApiProperty() - emailFrom: string; + @ApiProperty() + emailFrom: string - @ApiProperty() - emailTo: string; + @ApiProperty() + emailTo: string - @ApiProperty() - emailSubject: string; + @ApiProperty() + emailSubject: string - @ApiProperty() - emailText: string; - - @ApiProperty() - emailHtml: string; -} \ No newline at end of file + @ApiProperty() + emailText: string + + @ApiProperty() + emailHtml: string +} diff --git a/apps/api-gateway/src/dtos/endorse-transaction.dto.ts b/apps/api-gateway/src/dtos/endorse-transaction.dto.ts index ea0b7c345..b01180cbb 100644 --- a/apps/api-gateway/src/dtos/endorse-transaction.dto.ts +++ b/apps/api-gateway/src/dtos/endorse-transaction.dto.ts @@ -1,6 +1,6 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class EndorseTransactionDto { @ApiProperty() - transactionId: string; + transactionId: string } diff --git a/apps/api-gateway/src/dtos/enums.ts b/apps/api-gateway/src/dtos/enums.ts index ea8b3ebd9..b84d01bbd 100644 --- a/apps/api-gateway/src/dtos/enums.ts +++ b/apps/api-gateway/src/dtos/enums.ts @@ -1,51 +1,51 @@ export enum OrgRequestStatus { - All = 'all', - Accepted = 'accepted', - Pending = 'pending', - Rejected = 'rejected', + All = 'all', + Accepted = 'accepted', + Pending = 'pending', + Rejected = 'rejected', } export enum ActiveFlags { - All = 'all', - True = 'true', - False = 'false', + All = 'all', + True = 'true', + False = 'false', } export enum NonAdminUserStae { - All = 'all', - Active = 'active', - InActive = 'inactive', - Pending = 'pending' + All = 'all', + Active = 'active', + InActive = 'inactive', + Pending = 'pending', } export enum IssueCredStatus { - All = 'all', - Credential_issued = 'credential_issued', - Credential_revoke = 'credential_revoke', - Non_revoke = 'non_revoke' + All = 'all', + Credential_issued = 'credential_issued', + Credential_revoke = 'credential_revoke', + Non_revoke = 'non_revoke', } export enum AgentActions { - Start = 'START', - Stop = 'STOP', - Status = 'STATUS', + Start = 'START', + Stop = 'STOP', + Status = 'STATUS', } export enum TenantStatus { - All = 'all', - Accepted = 'accepted', - Pending = 'pending', - Rejected = 'rejected', + All = 'all', + Accepted = 'accepted', + Pending = 'pending', + Rejected = 'rejected', } export enum OrgInvitationStatus { - All = 'all', - Accepted = 'accepted', - Pending = 'pending' + All = 'all', + Accepted = 'accepted', + Pending = 'pending', } export enum FileRecordStatus { - All = 'ALL', - Success = 'SUCCESS', - Error = 'ERROR' + All = 'ALL', + Success = 'SUCCESS', + Error = 'ERROR', } diff --git a/apps/api-gateway/src/dtos/fido-user.dto.ts b/apps/api-gateway/src/dtos/fido-user.dto.ts index 54635b27f..91f94a8cd 100644 --- a/apps/api-gateway/src/dtos/fido-user.dto.ts +++ b/apps/api-gateway/src/dtos/fido-user.dto.ts @@ -1,132 +1,130 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsBoolean, IsOptional, IsString, ValidateNested } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsArray, IsBoolean, IsOptional, IsString, ValidateNested } from 'class-validator' export class GenerateRegistrationDto { - @IsOptional() @ApiProperty({ example: 'false' }) @IsBoolean({ message: 'isPasskey should be boolean' }) - deviceFlag: boolean; + deviceFlag: boolean } export class ResponseDto { @ApiProperty() @IsString() - attestationObject: string; + attestationObject: string @ApiProperty() @IsString() - clientDataJSON: string; + clientDataJSON: string @ApiProperty() @IsArray() - transports: string[]; + transports: string[] } export class ClientExtensionResultsDto { @ValidateNested() - credProps: Record; + credProps: Record } export class VerifyRegistrationDto { @ApiProperty() @IsString() - id: string; + id: string @ApiProperty() @IsString() - rawId: string; + rawId: string - @ApiProperty({ type: ResponseDto, nullable: true }) + @ApiProperty({ type: ResponseDto, nullable: true }) @IsOptional() - response: ResponseDto; + response: ResponseDto @ApiProperty() @IsString() - type: string; + type: string - @ApiProperty() - clientExtensionResults: ClientExtensionResultsDto; + @ApiProperty() + clientExtensionResults: ClientExtensionResultsDto @ApiProperty() @IsString() - authenticatorAttachment: string; + authenticatorAttachment: string @ApiProperty() @IsString() - challangeId: string; + challangeId: string } export class UpdateFidoUserDetailsDto { @ApiProperty() @IsString() - userName: string; + userName: string @ApiProperty() @IsString() - credentialId: string; + credentialId: string @ApiProperty() @IsString() - deviceFriendlyName: string; + deviceFriendlyName: string } export class GenerateAuthenticationDto { @ApiProperty({ example: 'abc@vomoto.com' }) @IsString() - userName: string; + userName: string } class VerifyAuthenticationResponseDto { - @ApiProperty() - @IsString() - authenticatorData: string; - - @ApiProperty() - @IsString() - clientDataJSON: string; - - @ApiProperty() - @IsString() - signature: string; - - @ApiProperty() - @IsString() - userHandle: string; - } - - - export class VerifyAuthenticationDto { - @ApiProperty() - @IsString() - id: string; - - @ApiProperty() - @IsString() - rawId: string; - - @ApiProperty() - @IsOptional() - response: VerifyAuthenticationResponseDto; - - @ApiProperty() - @IsString() - type: string; - - @ApiProperty() - clientExtensionResults?: ClientExtensionResultsDto; - - @ApiProperty() - @IsString() - authenticatorAttachment: string; - - @ApiProperty() - @IsString() - challangeId: string; - } - - export class UserNameDto { - @ApiProperty() - @IsString() - userName: string; - } \ No newline at end of file + @ApiProperty() + @IsString() + authenticatorData: string + + @ApiProperty() + @IsString() + clientDataJSON: string + + @ApiProperty() + @IsString() + signature: string + + @ApiProperty() + @IsString() + userHandle: string +} + +export class VerifyAuthenticationDto { + @ApiProperty() + @IsString() + id: string + + @ApiProperty() + @IsString() + rawId: string + + @ApiProperty() + @IsOptional() + response: VerifyAuthenticationResponseDto + + @ApiProperty() + @IsString() + type: string + + @ApiProperty() + clientExtensionResults?: ClientExtensionResultsDto + + @ApiProperty() + @IsString() + authenticatorAttachment: string + + @ApiProperty() + @IsString() + challangeId: string +} + +export class UserNameDto { + @ApiProperty() + @IsString() + userName: string +} diff --git a/apps/api-gateway/src/dtos/forbidden-error.dto copy.ts b/apps/api-gateway/src/dtos/forbidden-error.dto copy.ts index d02512b73..5d0572216 100644 --- a/apps/api-gateway/src/dtos/forbidden-error.dto copy.ts +++ b/apps/api-gateway/src/dtos/forbidden-error.dto copy.ts @@ -1,10 +1,9 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class ForbiddenErrorDto { + @ApiProperty({ example: 403 }) + statusCode: number - @ApiProperty({ example: 403 }) - statusCode: number; - - @ApiProperty({ example: 'Forbidden' }) - error: string; + @ApiProperty({ example: 'Forbidden' }) + error: string } diff --git a/apps/api-gateway/src/dtos/forbidden-error.dto.ts b/apps/api-gateway/src/dtos/forbidden-error.dto.ts index d02512b73..5d0572216 100644 --- a/apps/api-gateway/src/dtos/forbidden-error.dto.ts +++ b/apps/api-gateway/src/dtos/forbidden-error.dto.ts @@ -1,10 +1,9 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class ForbiddenErrorDto { + @ApiProperty({ example: 403 }) + statusCode: number - @ApiProperty({ example: 403 }) - statusCode: number; - - @ApiProperty({ example: 'Forbidden' }) - error: string; + @ApiProperty({ example: 'Forbidden' }) + error: string } diff --git a/apps/api-gateway/src/dtos/forgot-password.dto.ts b/apps/api-gateway/src/dtos/forgot-password.dto.ts index f2f68f18a..7c15069b5 100644 --- a/apps/api-gateway/src/dtos/forgot-password.dto.ts +++ b/apps/api-gateway/src/dtos/forgot-password.dto.ts @@ -1,20 +1,19 @@ -import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class ForgotPasswordDto { + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + username: string - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - username: string; - - @ApiProperty() - @IsNotEmpty({ message: 'Please provide valid password' }) - @IsString({ message: 'password should be string' }) - password: string; -} \ No newline at end of file + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid password' }) + @IsString({ message: 'password should be string' }) + password: string +} diff --git a/apps/api-gateway/src/dtos/geo-location-dto.ts b/apps/api-gateway/src/dtos/geo-location-dto.ts index 06a3cf3ca..8c09141ed 100644 --- a/apps/api-gateway/src/dtos/geo-location-dto.ts +++ b/apps/api-gateway/src/dtos/geo-location-dto.ts @@ -1,5 +1,5 @@ -import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsNotEmpty, IsNumber, IsOptional } from 'class-validator'; +import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger' +import { IsNotEmpty, IsNumber, IsOptional } from 'class-validator' @ApiExtraModels() export class GeoLocationDto { @@ -7,17 +7,17 @@ export class GeoLocationDto { @IsOptional() @IsNotEmpty({ message: 'country is required' }) @IsNumber({}, { message: 'countryId must be a number' }) - countryId?: number; + countryId?: number @ApiPropertyOptional({ example: 4008 }) @IsOptional() @IsNotEmpty({ message: 'state is required' }) @IsNumber({}, { message: 'stateId must be a number' }) - stateId?: number; + stateId?: number @ApiPropertyOptional({ example: 1000 }) @IsOptional() @IsNotEmpty({ message: 'city is required' }) @IsNumber({}, { message: 'cityId must be a number' }) - cityId?: number; + cityId?: number } diff --git a/apps/api-gateway/src/dtos/get-cred-defs.dto.ts b/apps/api-gateway/src/dtos/get-cred-defs.dto.ts index ab341ef7d..56e15d07a 100644 --- a/apps/api-gateway/src/dtos/get-cred-defs.dto.ts +++ b/apps/api-gateway/src/dtos/get-cred-defs.dto.ts @@ -1,10 +1,10 @@ // import { SortValue } from '@credebl/enum/enum'; export class GetAllCredDefsDto { - pageSize?: number; - pageNumber?: number; - searchByText?: string; - sorting?: string; - revocable?: boolean; - sortByValue?: string; -} \ No newline at end of file + pageSize?: number + pageNumber?: number + searchByText?: string + sorting?: string + revocable?: boolean + sortByValue?: string +} diff --git a/apps/api-gateway/src/dtos/holder-details.dto.ts b/apps/api-gateway/src/dtos/holder-details.dto.ts index b3fb3c009..42917c40b 100644 --- a/apps/api-gateway/src/dtos/holder-details.dto.ts +++ b/apps/api-gateway/src/dtos/holder-details.dto.ts @@ -1,68 +1,68 @@ -import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class HolderDetailsDto { - @ApiProperty({ example: 'Alen' }) - @IsNotEmpty({ message: 'Please provide valid firstName' }) - @IsString({ message: 'firstName should be string' }) - firstName: string; + @ApiProperty({ example: 'Alen' }) + @IsNotEmpty({ message: 'Please provide valid firstName' }) + @IsString({ message: 'firstName should be string' }) + firstName: string - @ApiProperty({ example: 'Harvey' }) - @IsNotEmpty({ message: 'Please provide valid lastName' }) - @IsString({ message: 'lastName should be string' }) - lastName: string; + @ApiProperty({ example: 'Harvey' }) + @IsNotEmpty({ message: 'Please provide valid lastName' }) + @IsString({ message: 'lastName should be string' }) + lastName: string - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiProperty({ example: 'awqx@example.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Please provide valid username' }) - @IsString({ message: 'username should be string' }) - username: string; + @ApiProperty({ example: 'awqx@example.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Please provide valid username' }) + @IsString({ message: 'username should be string' }) + username: string - @ApiProperty({ example: 'your-secret-password' }) - @IsNotEmpty({ message: 'Please provide valid password' }) - @IsString({ message: 'password should be string' }) - password: string; + @ApiProperty({ example: 'your-secret-password' }) + @IsNotEmpty({ message: 'Please provide valid password' }) + @IsString({ message: 'password should be string' }) + password: string - @ApiProperty({ example: 'GamoraPlus' }) - @IsNotEmpty({ message: 'Please provide valid deviceId' }) - @IsString({ message: 'deviceId should be string' }) - deviceId: string; + @ApiProperty({ example: 'GamoraPlus' }) + @IsNotEmpty({ message: 'Please provide valid deviceId' }) + @IsString({ message: 'deviceId should be string' }) + deviceId: string - @ApiProperty({ example: 'Nokia C3' }) - @IsNotEmpty({ message: 'Please provide valid model' }) - @IsString({ message: 'model should be string' }) - model: string; + @ApiProperty({ example: 'Nokia C3' }) + @IsNotEmpty({ message: 'Please provide valid model' }) + @IsString({ message: 'model should be string' }) + model: string - @ApiProperty({ example: 'Nokia' }) - @IsNotEmpty({ message: 'Please provide valid type' }) - @IsString({ message: 'type should be string' }) - type: string; + @ApiProperty({ example: 'Nokia' }) + @IsNotEmpty({ message: 'Please provide valid type' }) + @IsString({ message: 'type should be string' }) + type: string - @ApiProperty({ example: 'Android' }) - @IsNotEmpty({ message: 'Please provide valid os' }) - @IsString({ message: 'os should be string' }) - os: string; + @ApiProperty({ example: 'Android' }) + @IsNotEmpty({ message: 'Please provide valid os' }) + @IsString({ message: 'os should be string' }) + os: string - // @ApiProperty() - // mediatorId?: number; + // @ApiProperty() + // mediatorId?: number; - @ApiProperty({ example: 'https://yourdomain.com/my-profile-logo.png' }) - // @IsNotEmpty({ message: 'Please provide valid profileLogoUrl' }) - // @IsString({ message: 'profileLogoUrl should be string' }) - profileLogoUrl: string; + @ApiProperty({ example: 'https://yourdomain.com/my-profile-logo.png' }) + // @IsNotEmpty({ message: 'Please provide valid profileLogoUrl' }) + // @IsString({ message: 'profileLogoUrl should be string' }) + profileLogoUrl: string - @ApiProperty({ example: 'your-firebase-token' }) - @IsNotEmpty({ message: 'Please provide valid firebaseToken' }) - @IsString({ message: 'firebaseToken should be string' }) - firebaseToken: string; -} \ No newline at end of file + @ApiProperty({ example: 'your-firebase-token' }) + @IsNotEmpty({ message: 'Please provide valid firebaseToken' }) + @IsString({ message: 'firebaseToken should be string' }) + firebaseToken: string +} diff --git a/apps/api-gateway/src/dtos/holder-reset-password.ts b/apps/api-gateway/src/dtos/holder-reset-password.ts index dbd25709e..178a5770a 100644 --- a/apps/api-gateway/src/dtos/holder-reset-password.ts +++ b/apps/api-gateway/src/dtos/holder-reset-password.ts @@ -1,25 +1,24 @@ -import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class HolderResetPasswordDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiProperty({ example: '$2b$10$.NcA4.oN.a8otc5TgGuO5OvH.hbaF/AWNvVfA1t7g3N9jstvzJTlm' }) - @IsNotEmpty({ message: 'Please provide valid password' }) - @IsString({ message: 'password should be string' }) - password: string; + @ApiProperty({ example: '$2b$10$.NcA4.oN.a8otc5TgGuO5OvH.hbaF/AWNvVfA1t7g3N9jstvzJTlm' }) + @IsNotEmpty({ message: 'Please provide valid password' }) + @IsString({ message: 'password should be string' }) + password: string - - @ApiProperty({ example: '647bf6c8b888b6a269ca' }) - @IsNotEmpty({ message: 'Please provide valid token' }) - @IsString({ message: 'token should be string' }) - token: string; -} \ No newline at end of file + @ApiProperty({ example: '647bf6c8b888b6a269ca' }) + @IsNotEmpty({ message: 'Please provide valid token' }) + @IsString({ message: 'token should be string' }) + token: string +} diff --git a/apps/api-gateway/src/dtos/internal-server-error-res.dto.ts b/apps/api-gateway/src/dtos/internal-server-error-res.dto.ts index 9b1d4afe5..9df57892b 100644 --- a/apps/api-gateway/src/dtos/internal-server-error-res.dto.ts +++ b/apps/api-gateway/src/dtos/internal-server-error-res.dto.ts @@ -1,10 +1,9 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class InternalServerErrorDto { + @ApiProperty({ example: 500 }) + statusCode: number - @ApiProperty({ example: 500 }) - statusCode: number; - - @ApiProperty({ example: 'Internal server error' }) - error: string; + @ApiProperty({ example: 'Internal server error' }) + error: string } diff --git a/apps/api-gateway/src/dtos/issue-credential-offer.dto .ts b/apps/api-gateway/src/dtos/issue-credential-offer.dto .ts index 9eed1f5ed..66da5bc07 100644 --- a/apps/api-gateway/src/dtos/issue-credential-offer.dto .ts +++ b/apps/api-gateway/src/dtos/issue-credential-offer.dto .ts @@ -1,64 +1,60 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty, IsBoolean, IsNotEmptyObject, IsObject } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsBoolean, IsNotEmpty, IsObject, IsString } from 'class-validator' interface ICredAttrSpec { - 'mime-type': string, - name: string, - value: string + 'mime-type': string + name: string + value: string } interface ICredentialPreview { - '@type': string, - attributes: ICredAttrSpec[] + '@type': string + attributes: ICredAttrSpec[] } export class IssueCredentialOfferDto { - - @ApiProperty({ example: true }) - @IsNotEmpty({message:'Please provide valid auto-issue'}) - @IsBoolean({message:'Auto-issue should be boolean'}) - auto_issue: boolean; - - @ApiProperty({ example: true }) - @IsNotEmpty({message:'Please provide valid auto-remove'}) - @IsBoolean({message:'Auto-remove should be boolean'}) - auto_remove: boolean; - - @ApiProperty({ example: 'comments' }) - @IsNotEmpty({message:'Please provide valid comment'}) - @IsString({message:'Comment should be string'}) - comment: string; - - @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) - @IsNotEmpty({message:'Please provide valid cred-def-id'}) - @IsString({message:'Cred-def-id should be string'}) - cred_def_id: string; - - @ApiProperty({ example: '3fa85f64-5717-4562-b3fc-2c963f66afa6' }) - @IsNotEmpty({message:'Please provide valid connection-id'}) - @IsString({message:'Connection-id should be string'}) - connection_id: string; - - @ApiProperty({ example: false }) - @IsNotEmpty({message:'Please provide valid trace'}) - @IsBoolean({message:'Trace should be boolean'}) - trace: boolean; - - - @ApiProperty({ - example: { - '@type': 'issue-credential/1.0/credential-preview', - 'attributes': [ - { - 'mime-type': 'image/jpeg', - 'name': 'favourite_drink', - 'value': 'martini' - } - ] - } - } - ) - - @IsObject({message:'Credential-preview should be object'}) - credential_preview: ICredentialPreview; + @ApiProperty({ example: true }) + @IsNotEmpty({ message: 'Please provide valid auto-issue' }) + @IsBoolean({ message: 'Auto-issue should be boolean' }) + auto_issue: boolean + + @ApiProperty({ example: true }) + @IsNotEmpty({ message: 'Please provide valid auto-remove' }) + @IsBoolean({ message: 'Auto-remove should be boolean' }) + auto_remove: boolean + + @ApiProperty({ example: 'comments' }) + @IsNotEmpty({ message: 'Please provide valid comment' }) + @IsString({ message: 'Comment should be string' }) + comment: string + + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) + @IsNotEmpty({ message: 'Please provide valid cred-def-id' }) + @IsString({ message: 'Cred-def-id should be string' }) + cred_def_id: string + + @ApiProperty({ example: '3fa85f64-5717-4562-b3fc-2c963f66afa6' }) + @IsNotEmpty({ message: 'Please provide valid connection-id' }) + @IsString({ message: 'Connection-id should be string' }) + connection_id: string + + @ApiProperty({ example: false }) + @IsNotEmpty({ message: 'Please provide valid trace' }) + @IsBoolean({ message: 'Trace should be boolean' }) + trace: boolean + + @ApiProperty({ + example: { + '@type': 'issue-credential/1.0/credential-preview', + attributes: [ + { + 'mime-type': 'image/jpeg', + name: 'favourite_drink', + value: 'martini', + }, + ], + }, + }) + + @IsObject({ message: 'Credential-preview should be object' }) + credential_preview: ICredentialPreview } - diff --git a/apps/api-gateway/src/dtos/issue-credential-out-of-band.dto.ts b/apps/api-gateway/src/dtos/issue-credential-out-of-band.dto.ts index d412d28a8..9691a2146 100644 --- a/apps/api-gateway/src/dtos/issue-credential-out-of-band.dto.ts +++ b/apps/api-gateway/src/dtos/issue-credential-out-of-band.dto.ts @@ -1,61 +1,59 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsString, IsNotEmpty, IsObject } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsObject, IsString } from 'class-validator' interface IssueCredAttrSpec { - 'mime-type': string, - name: string, - value: string + 'mime-type': string + name: string + value: string } interface IssueCredPreview { - '@type': string, - attributes: IssueCredAttrSpec[] + '@type': string + attributes: IssueCredAttrSpec[] } - export class IssueCredentialOutOfBandDto { - - @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) - cred_def_id: string; - - @ApiProperty({example: { - '@type': 'issue-credential/1.0/credential-preview', - 'attributes': [ - { - 'mime-type': 'image/jpeg', - 'name': '', - 'value': 'i' - } - ] - } - }) - @IsObject({message:'credential_proposal must be a object'}) - @IsNotEmpty({message:'please provide valid credential_proposal'}) - credential_proposal: IssueCredPreview; - - @ApiProperty({example: 'WgWxqztrNooG92RXvxSTWv'}) - @IsString({message:'issuer_did must be a string'}) - @IsNotEmpty({message:'please provide valid issuer_did'}) - issuer_did: string; - - @ApiProperty({example:'WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0'}) - @IsString({message:'schema_id must be a string'}) - @IsNotEmpty({message:'please provide valid schema_id'}) - schema_id: string; - - @ApiProperty({example:'WgWxqztrNooG92RXvxSTWv'}) - @IsString({message:'schema_iisuer_did name must be a string'}) - @IsNotEmpty({message:'please provide valid schema_issuer_did'}) - schema_issuer_did:string; - - @ApiProperty({example:'preferences'}) - @IsString({message:'schema name must be a string'}) - @IsNotEmpty({message:'please provide valid schema_name'}) - schema_name: string; - - @ApiProperty({example:'1.0'}) - @IsString({message:'schema version must be a string'}) - @IsNotEmpty({message:'please provide valid schema_version'}) - schema_version: string; - -} \ No newline at end of file + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) + cred_def_id: string + + @ApiProperty({ + example: { + '@type': 'issue-credential/1.0/credential-preview', + attributes: [ + { + 'mime-type': 'image/jpeg', + name: '', + value: 'i', + }, + ], + }, + }) + @IsObject({ message: 'credential_proposal must be a object' }) + @IsNotEmpty({ message: 'please provide valid credential_proposal' }) + credential_proposal: IssueCredPreview + + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv' }) + @IsString({ message: 'issuer_did must be a string' }) + @IsNotEmpty({ message: 'please provide valid issuer_did' }) + issuer_did: string + + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0' }) + @IsString({ message: 'schema_id must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema_id' }) + schema_id: string + + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv' }) + @IsString({ message: 'schema_iisuer_did name must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema_issuer_did' }) + schema_issuer_did: string + + @ApiProperty({ example: 'preferences' }) + @IsString({ message: 'schema name must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema_name' }) + schema_name: string + + @ApiProperty({ example: '1.0' }) + @IsString({ message: 'schema version must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema_version' }) + schema_version: string +} diff --git a/apps/api-gateway/src/dtos/issue-credential-save.dto.ts b/apps/api-gateway/src/dtos/issue-credential-save.dto.ts index 0026cbfbd..efbbe1cfb 100644 --- a/apps/api-gateway/src/dtos/issue-credential-save.dto.ts +++ b/apps/api-gateway/src/dtos/issue-credential-save.dto.ts @@ -1,69 +1,68 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsOptional } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsOptional } from 'class-validator' interface ITags { - state: string; - connectionId: string; - threadId: string; + state: string + connectionId: string + threadId: string } interface IndyCredential { - schemaId: string; - credentialDefinitionId: string; + schemaId: string + credentialDefinitionId: string } interface ICredentialAttributes { - 'mime-type': string; - name: string; - value: string; + 'mime-type': string + name: string + value: string } interface IMetadata { - '_internal/indyCredential': IndyCredential; + '_internal/indyCredential': IndyCredential } export class IssueCredentialSaveDto { + @ApiProperty() + @IsOptional() + _tags: ITags - @ApiProperty() - @IsOptional() - _tags: ITags; + @ApiProperty() + @IsOptional() + metadata: IMetadata - @ApiProperty() - @IsOptional() - metadata: IMetadata; + @ApiProperty() + @IsOptional() + credentials: [] - @ApiProperty() - @IsOptional() - credentials: []; + @ApiProperty() + @IsOptional() + id: string - @ApiProperty() - @IsOptional() - id: string; + @ApiProperty() + @IsOptional() + createdAt: string - @ApiProperty() - @IsOptional() - createdAt: string; + @ApiProperty() + @IsOptional() + state: string - @ApiProperty() - @IsOptional() - state: string; + @ApiProperty() + @IsOptional() + connectionId: string - @ApiProperty() - @IsOptional() - connectionId: string; + @ApiProperty() + @IsOptional() + threadId: string - @ApiProperty() - @IsOptional() - threadId: string; + @ApiProperty() + @IsOptional() + protocolVersion: string - @ApiProperty() - @IsOptional() - protocolVersion: string; + @ApiProperty() + @IsOptional() + credentialAttributes: ICredentialAttributes[] - @ApiProperty() - @IsOptional() - credentialAttributes: ICredentialAttributes[]; - - @ApiProperty() - @IsOptional() - autoAcceptCredential: string; -} \ No newline at end of file + @ApiProperty() + @IsOptional() + autoAcceptCredential: string +} diff --git a/apps/api-gateway/src/dtos/issue-credential.dto.ts b/apps/api-gateway/src/dtos/issue-credential.dto.ts index 173c3731e..b04e66e37 100644 --- a/apps/api-gateway/src/dtos/issue-credential.dto.ts +++ b/apps/api-gateway/src/dtos/issue-credential.dto.ts @@ -1,40 +1,38 @@ -import { IsArray, IsNotEmpty, IsString } from 'class-validator'; -import { ApiProperty } from '@nestjs/swagger'; -import { toLowerCase, trim } from '@credebl/common/cast.helper'; -import { Transform } from 'class-transformer'; +import { toLowerCase, trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsArray, IsNotEmpty, IsString } from 'class-validator' interface attribute { - name: string; - value: string; + name: string + value: string } export class IssueCredentialDto { - - - @ApiProperty({ example: 'v1' }) - @Transform(({ value }) => trim(value)) - @Transform(({ value }) => toLowerCase(value)) - @IsNotEmpty({ message: 'Please provide valid protocolVersion' }) - @IsString({ message: 'protocolVersion should be string' }) - protocolVersion: string; - - @ApiProperty({ example: [{ 'value': 'string', 'name': 'string' }] }) - @IsNotEmpty({ message: 'Please provide valid attributes' }) - @IsArray({ message: 'attributes should be array' }) - attributes: attribute[]; - - @ApiProperty({ example: 'string' }) - @IsNotEmpty({ message: 'Please provide valid credentialDefinitionId' }) - @IsString({ message: 'credentialDefinitionId should be string' }) - credentialDefinitionId: string; - - @ApiProperty({ example: 'string' }) - @IsNotEmpty({ message: 'Please provide valid comment' }) - @IsString({ message: 'comment should be string' }) - comment: string; - - @ApiProperty({ example: '3fa85f64-5717-4562-b3fc-2c963f66afa6' }) - @IsNotEmpty({ message: 'Please provide valid connectionId' }) - @IsString({ message: 'connectionId should be string' }) - connectionId: string; -} \ No newline at end of file + @ApiProperty({ example: 'v1' }) + @Transform(({ value }) => trim(value)) + @Transform(({ value }) => toLowerCase(value)) + @IsNotEmpty({ message: 'Please provide valid protocolVersion' }) + @IsString({ message: 'protocolVersion should be string' }) + protocolVersion: string + + @ApiProperty({ example: [{ value: 'string', name: 'string' }] }) + @IsNotEmpty({ message: 'Please provide valid attributes' }) + @IsArray({ message: 'attributes should be array' }) + attributes: attribute[] + + @ApiProperty({ example: 'string' }) + @IsNotEmpty({ message: 'Please provide valid credentialDefinitionId' }) + @IsString({ message: 'credentialDefinitionId should be string' }) + credentialDefinitionId: string + + @ApiProperty({ example: 'string' }) + @IsNotEmpty({ message: 'Please provide valid comment' }) + @IsString({ message: 'comment should be string' }) + comment: string + + @ApiProperty({ example: '3fa85f64-5717-4562-b3fc-2c963f66afa6' }) + @IsNotEmpty({ message: 'Please provide valid connectionId' }) + @IsString({ message: 'connectionId should be string' }) + connectionId: string +} diff --git a/apps/api-gateway/src/dtos/label-editor.dto.ts b/apps/api-gateway/src/dtos/label-editor.dto.ts index ceac8fb0f..500eff65f 100644 --- a/apps/api-gateway/src/dtos/label-editor.dto.ts +++ b/apps/api-gateway/src/dtos/label-editor.dto.ts @@ -1,12 +1,12 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class LabelEditorDto { - @ApiProperty() - labelId : number; + @ApiProperty() + labelId: number - @ApiProperty() - labelName?: string; + @ApiProperty() + labelName?: string - @ApiProperty() - description?: string; -} \ No newline at end of file + @ApiProperty() + description?: string +} diff --git a/apps/api-gateway/src/dtos/not-found-error.dto.ts b/apps/api-gateway/src/dtos/not-found-error.dto.ts index 3ea199978..3e3f23144 100644 --- a/apps/api-gateway/src/dtos/not-found-error.dto.ts +++ b/apps/api-gateway/src/dtos/not-found-error.dto.ts @@ -1,22 +1,21 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class NotFoundErrorDto { + @ApiProperty({ example: 404 }) + statusCode: number - @ApiProperty({ example: 404 }) - statusCode: number; + @ApiProperty({ example: 'Not Found' }) + error: string - @ApiProperty({ example: 'Not Found' }) - error: string; + @ApiProperty({ example: 'Not Found' }) + message: string - @ApiProperty({ example: 'Not Found' }) - message: string; + @ApiProperty() + success: boolean - @ApiProperty() - success: boolean; + @ApiProperty() + data?: boolean | object | [] - @ApiProperty() - data?: boolean | {} | []; - - @ApiProperty({ example: 404 }) - code: number; + @ApiProperty({ example: 404 }) + code: number } diff --git a/apps/api-gateway/src/dtos/org-name-check.dto.ts b/apps/api-gateway/src/dtos/org-name-check.dto.ts index 717a3617e..b18ec82d7 100644 --- a/apps/api-gateway/src/dtos/org-name-check.dto.ts +++ b/apps/api-gateway/src/dtos/org-name-check.dto.ts @@ -1,16 +1,15 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { IsNotEmpty, IsOptional, IsString } from 'class-validator' export class OrgNameCheckDto { - @ApiProperty({example:'Organization name'}) - @IsNotEmpty({message:'Please provide valid organization Name'}) - @IsString({message:'Organization Name should be string'}) - orgName: string; + @ApiProperty({ example: 'Organization name' }) + @IsNotEmpty({ message: 'Please provide valid organization Name' }) + @IsString({ message: 'Organization Name should be string' }) + orgName: string - @IsOptional() - @ApiPropertyOptional({example:'1'}) - @IsNotEmpty({message:'Please provide valid id of organization'}) - // @IsNumberString({message:'Organization id should be number'}) - orgId?: string; - -} \ No newline at end of file + @IsOptional() + @ApiPropertyOptional({ example: '1' }) + @IsNotEmpty({ message: 'Please provide valid id of organization' }) + // @IsNumberString({message:'Organization id should be number'}) + orgId?: string +} diff --git a/apps/api-gateway/src/dtos/platform-config.dto.ts b/apps/api-gateway/src/dtos/platform-config.dto.ts index dfaed867e..a1ec87f1c 100644 --- a/apps/api-gateway/src/dtos/platform-config.dto.ts +++ b/apps/api-gateway/src/dtos/platform-config.dto.ts @@ -1,21 +1,21 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class PlatformConfigDto { - @ApiProperty() - externalIP: string; + @ApiProperty() + externalIP: string - @ApiProperty() - genesisURL: string; + @ApiProperty() + genesisURL: string - @ApiProperty() - lastInternalIP: string; + @ApiProperty() + lastInternalIP: string - @ApiProperty() - sgUsername: string; + @ApiProperty() + sgUsername: string - @ApiProperty() - sgApiKey: string; + @ApiProperty() + sgApiKey: string - @ApiProperty() - sgEmailFrom: string; + @ApiProperty() + sgEmailFrom: string } diff --git a/apps/api-gateway/src/dtos/platform-connection.dtos.ts b/apps/api-gateway/src/dtos/platform-connection.dtos.ts index 9aa8eb580..bad666b74 100644 --- a/apps/api-gateway/src/dtos/platform-connection.dtos.ts +++ b/apps/api-gateway/src/dtos/platform-connection.dtos.ts @@ -1,27 +1,25 @@ - // export class ConnectionDto { // @IsNotEmpty() // @IsNumberString() // itemsPerPage: number; - - // @IsNumber() - // page: number; - // @IsString() - // searchText: string; - - // @IsNotEmpty({message:"Please provide valid org Id"}) - // @IsNumber() - // orgId: number +// @IsNumber() +// page: number; + +// @IsString() +// searchText: string; + +// @IsNotEmpty({message:"Please provide valid org Id"}) +// @IsNumber() +// orgId: number - // @IsString() - // connectionSortBy: string +// @IsString() +// connectionSortBy: string - // @IsString() - // sortValue: string +// @IsString() +// sortValue: string // } export class Org { - - orgId: string; -} \ No newline at end of file + orgId: string +} diff --git a/apps/api-gateway/src/dtos/printable-form-details.dto.ts b/apps/api-gateway/src/dtos/printable-form-details.dto.ts index 50bead236..a31467ca2 100644 --- a/apps/api-gateway/src/dtos/printable-form-details.dto.ts +++ b/apps/api-gateway/src/dtos/printable-form-details.dto.ts @@ -1,12 +1,12 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class PrintableFormDto { - @ApiProperty() - credDefId: string; + @ApiProperty() + credDefId: string - @ApiProperty() - schemaId: string; + @ApiProperty() + schemaId: string - @ApiProperty() - theirDid: string; -} \ No newline at end of file + @ApiProperty() + theirDid: string +} diff --git a/apps/api-gateway/src/dtos/register-non-admin-user.dto.ts b/apps/api-gateway/src/dtos/register-non-admin-user.dto.ts index ec9f3876e..de57d5571 100644 --- a/apps/api-gateway/src/dtos/register-non-admin-user.dto.ts +++ b/apps/api-gateway/src/dtos/register-non-admin-user.dto.ts @@ -1,44 +1,42 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsArray, IsEmail, IsInt, IsNotEmpty, IsString } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsArray, IsEmail, IsInt, IsNotEmpty, IsString } from 'class-validator' export class RegisterNonAdminUserDto { - @ApiProperty() - @IsNotEmpty({message:'Please provide valid firstName'}) - @IsString({message:'FirstName should be string'}) - firstName: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid lastName'}) - @IsString({message:'LastName should be string'}) - lastName: string; - - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; - - @ApiPropertyOptional() - // @IsNotEmpty({message:'Please provide valid username'}) - // @IsString({message:'Username should be string'}) - username: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid password'}) - @IsString({message:'Password should be string'}) - password: string; - - @ApiProperty() - @IsNotEmpty({message:'Role should be array of number'}) - @IsArray({message:'Role should be number'}) - @IsInt({ each: true }) - - // @IsInt({message:'Role should be number'}) - role:number; - - featureId: number; - + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid firstName' }) + @IsString({ message: 'FirstName should be string' }) + firstName: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid lastName' }) + @IsString({ message: 'LastName should be string' }) + lastName: string + + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string + + @ApiPropertyOptional() + // @IsNotEmpty({message:'Please provide valid username'}) + // @IsString({message:'Username should be string'}) + username: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid password' }) + @IsString({ message: 'Password should be string' }) + password: string + + @ApiProperty() + @IsNotEmpty({ message: 'Role should be array of number' }) + @IsArray({ message: 'Role should be number' }) + @IsInt({ each: true }) + // @IsInt({message:'Role should be number'}) + role: number + + featureId: number } diff --git a/apps/api-gateway/src/dtos/register-tenant.dto.ts b/apps/api-gateway/src/dtos/register-tenant.dto.ts index 22bbbb89a..6282448e9 100644 --- a/apps/api-gateway/src/dtos/register-tenant.dto.ts +++ b/apps/api-gateway/src/dtos/register-tenant.dto.ts @@ -1,14 +1,12 @@ /* eslint-disable camelcase */ -import { ApiExtraModels, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsEmail, IsNotEmpty, IsNumberString, IsString, MaxLength, MinLength } from 'class-validator'; - -import { Transform } from 'class-transformer'; -import { toLowerCase, trim } from '@credebl/common/cast.helper'; +import { ApiExtraModels, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { IsEmail, IsNotEmpty, IsNumberString, IsString, MaxLength, MinLength } from 'class-validator' +import { toLowerCase, trim } from '@credebl/common/cast.helper' +import { Transform } from 'class-transformer' @ApiExtraModels() export class RegisterTenantDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) @Transform(({ value }) => toLowerCase(value)) @IsNotEmpty({ message: 'Email is required.' }) @@ -16,12 +14,12 @@ export class RegisterTenantDto { @IsEmail({}, { message: 'Please provide a valid email' }) @IsString({ message: 'Email should be a string' }) @Transform(({ value }) => trim(value)) - email: string; + email: string @ApiProperty() @Transform(({ value }) => trim(value)) @IsNotEmpty({ message: 'Password is required.' }) - password: string; + password: string @ApiProperty() @Transform(({ value }) => trim(value)) @@ -29,7 +27,7 @@ export class RegisterTenantDto { @MinLength(2, { message: 'Organization name must be at least 2 characters.' }) @MaxLength(50, { message: 'Organization name must be at most 50 characters.' }) @IsString({ message: 'Organization name must be in string format.' }) - orgName: string; + orgName: string @ApiProperty() @Transform(({ value }) => trim(value)) @@ -37,7 +35,7 @@ export class RegisterTenantDto { @MinLength(1, { message: 'First name must be at least 2 characters.' }) @MaxLength(50, { message: 'First name must be at most 50 characters.' }) @IsString({ message: 'First name must be in string format.' }) - firstName: string; + firstName: string @ApiProperty() @Transform(({ value }) => trim(value)) @@ -45,38 +43,37 @@ export class RegisterTenantDto { @MinLength(1, { message: 'Last name must be at least 2 characters.' }) @MaxLength(50, { message: 'Last name must be at most 50 characters.' }) @IsString({ message: 'Last name must be in string format.' }) - lastName: string; + lastName: string @ApiProperty() @IsNotEmpty({ message: 'Organization categoty is required.' }) @IsNumberString() - orgCategory: number; + orgCategory: number @ApiPropertyOptional() - logoUri?: string; - + logoUri?: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) - solutionTitle?: string; + solutionTitle?: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) - solutionDesc?: string; + solutionDesc?: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) - address?: string; + address?: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) - website?: string; + website?: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) - tags?: string; + tags?: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) - Keywords: string; + Keywords: string } diff --git a/apps/api-gateway/src/dtos/register-user.dto.ts b/apps/api-gateway/src/dtos/register-user.dto.ts index 3bfb15ad2..f9101b2f0 100644 --- a/apps/api-gateway/src/dtos/register-user.dto.ts +++ b/apps/api-gateway/src/dtos/register-user.dto.ts @@ -1,114 +1,113 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsString } from 'class-validator' export class RegisterUserDto { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - attribute: any; - - - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - adminEmail: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid orgName'}) - @IsString({message:'OrgName should be string'}) - orgName: string; - - @ApiProperty() - // @IsNotEmpty({message:'Please provide valid adminPassword'}) - @IsString({message:'AdminPassword should be string'}) - adminPassword?: string; - - @ApiProperty() - @IsNotEmpty({message:'Please provide valid orgCategory'}) - // @IsInt({message:'OrgCategory should be number'}) - orgCategory: number; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'FirstName should be string'}) - firstName: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'LastName should be string'}) - lastName: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'Description should be string'}) - description: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'DisplayName should be string'}) - displayName: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'LogoUrl should be string'}) - logoUrl: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'Address should be string'}) - address: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'AdminContact should be string'}) - adminContact: string; - - @ApiPropertyOptional() - @IsOptional() - // @IsInt({message:'NoOfUsers should be number'}) - noOfUsers: number; - - @ApiPropertyOptional() - @IsOptional() - // @IsInt({message:'NoOfSchemas should be number'}) - noOfSchemas: number; - - @ApiPropertyOptional() - @IsOptional() - // @IsInt({message:'NoOfCredentials should be number'}) - noOfCredentials: number; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'AdminUsername should be string'}) - adminUsername: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({message:'Keywords should be string'}) - Keywords: string; - - @IsOptional() - @IsString({message:'ByAdmin should be string'}) - byAdmin?: string; - - @IsOptional() - // @IsInt({message:'TenantId should be number'}) - tenantId?: string; - - @IsOptional() - @IsString({message:'Tags should be string'}) - tags?: string; - - @IsOptional() - // @IsInt({message:'InviteId should be number'}) - inviteId: number; - - @IsOptional() - @IsInt({message:'OnBoardingType should be number'}) - onBoardingType?: number; - - featureId: number; + // biome-ignore lint/suspicious/noExplicitAny: + attribute: any + + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + adminEmail: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid orgName' }) + @IsString({ message: 'OrgName should be string' }) + orgName: string + + @ApiProperty() + // @IsNotEmpty({message:'Please provide valid adminPassword'}) + @IsString({ message: 'AdminPassword should be string' }) + adminPassword?: string + + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid orgCategory' }) + // @IsInt({message:'OrgCategory should be number'}) + orgCategory: number + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'FirstName should be string' }) + firstName: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'LastName should be string' }) + lastName: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'Description should be string' }) + description: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'DisplayName should be string' }) + displayName: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'LogoUrl should be string' }) + logoUrl: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'Address should be string' }) + address: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'AdminContact should be string' }) + adminContact: string + + @ApiPropertyOptional() + @IsOptional() + // @IsInt({message:'NoOfUsers should be number'}) + noOfUsers: number + + @ApiPropertyOptional() + @IsOptional() + // @IsInt({message:'NoOfSchemas should be number'}) + noOfSchemas: number + + @ApiPropertyOptional() + @IsOptional() + // @IsInt({message:'NoOfCredentials should be number'}) + noOfCredentials: number + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'AdminUsername should be string' }) + adminUsername: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'Keywords should be string' }) + Keywords: string + + @IsOptional() + @IsString({ message: 'ByAdmin should be string' }) + byAdmin?: string + + @IsOptional() + // @IsInt({message:'TenantId should be number'}) + tenantId?: string + + @IsOptional() + @IsString({ message: 'Tags should be string' }) + tags?: string + + @IsOptional() + // @IsInt({message:'InviteId should be number'}) + inviteId: number + + @IsOptional() + @IsInt({ message: 'OnBoardingType should be number' }) + onBoardingType?: number + + featureId: number } diff --git a/apps/api-gateway/src/dtos/remote-get-credential.dto.ts b/apps/api-gateway/src/dtos/remote-get-credential.dto.ts index 7a14ea484..4212779da 100644 --- a/apps/api-gateway/src/dtos/remote-get-credential.dto.ts +++ b/apps/api-gateway/src/dtos/remote-get-credential.dto.ts @@ -1,16 +1,15 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class GetRemoteCredentials { + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv' }) + pairwiseDid: string - @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv' }) - pairwiseDid: string; + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) + credDefId: string - @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:3:CL:20:tag' }) - credDefId: string; + @ApiProperty() + holderId: string - @ApiProperty() - holderId: string; - - @ApiProperty() - verifierId: string; -} \ No newline at end of file + @ApiProperty() + verifierId: string +} diff --git a/apps/api-gateway/src/dtos/remove-holder.dto.ts b/apps/api-gateway/src/dtos/remove-holder.dto.ts index 11ebbc04f..3596e7ac4 100644 --- a/apps/api-gateway/src/dtos/remove-holder.dto.ts +++ b/apps/api-gateway/src/dtos/remove-holder.dto.ts @@ -1,13 +1,13 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class RemoveHolderDto { - @ApiProperty() - @IsNotEmpty({message:'Please provide valid username'}) - @IsString({message:'Username should be string'}) - username: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid username' }) + @IsString({ message: 'Username should be string' }) + username: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid password'}) - @IsString({message:'Password should be string'}) - password: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid password' }) + @IsString({ message: 'Password should be string' }) + password: string } diff --git a/apps/api-gateway/src/dtos/reset-password.dto.ts b/apps/api-gateway/src/dtos/reset-password.dto.ts index cc855fa93..92095aeb6 100644 --- a/apps/api-gateway/src/dtos/reset-password.dto.ts +++ b/apps/api-gateway/src/dtos/reset-password.dto.ts @@ -1,22 +1,22 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsString, IsNotEmpty, IsEmail } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsEmail, IsNotEmpty, IsString } from 'class-validator' export class ResetPasswordDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid oldPassword'}) - @IsString({message:'oldPassword should be string'}) - oldPassword: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid oldPassword' }) + @IsString({ message: 'oldPassword should be string' }) + oldPassword: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid newPassword'}) - @IsString({message:'newPassword should be string'}) - newPassword: string; -} \ No newline at end of file + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid newPassword' }) + @IsString({ message: 'newPassword should be string' }) + newPassword: string +} diff --git a/apps/api-gateway/src/dtos/revoke-credential.dto.ts b/apps/api-gateway/src/dtos/revoke-credential.dto.ts index 305ec6d10..cb5e9e68b 100644 --- a/apps/api-gateway/src/dtos/revoke-credential.dto.ts +++ b/apps/api-gateway/src/dtos/revoke-credential.dto.ts @@ -1,36 +1,38 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty, IsBoolean, IsNumber } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsBoolean, IsNotEmpty, IsNumber, IsString } from 'class-validator' export class RevokeCredentialDto { + @ApiProperty({ example: 1 }) + @IsNotEmpty({ message: 'Please provide valid cred-rev-id' }) + @IsNumber() + cred_rev_id: number - @ApiProperty({ example: 1 }) - @IsNotEmpty({message:'Please provide valid cred-rev-id'}) - @IsNumber() - cred_rev_id: number; + @ApiProperty({ example: true }) + @IsNotEmpty({ message: 'Please provide valid publish' }) + @IsBoolean({ message: 'Publish should be boolean' }) + publish?: boolean - @ApiProperty({ example: true }) - @IsNotEmpty({message:'Please provide valid publish'}) - @IsBoolean({message:'Publish should be boolean'}) - publish?: boolean; + @ApiProperty({ + example: + 'Th7MpTaRZVRYnPiabds81Y:4:Th7MpTaRZVRYnPiabds81Y:3:CL:185:aadhar1:CL_ACCUM:0296a307-9127-481f-ba4f-c43f89f1420e', + }) + @IsNotEmpty({ message: 'Please provide valid rev-reg-id' }) + @IsString({ message: 'Rev-reg-id should be string' }) + rev_reg_id: string - @ApiProperty({ example: 'Th7MpTaRZVRYnPiabds81Y:4:Th7MpTaRZVRYnPiabds81Y:3:CL:185:aadhar1:CL_ACCUM:0296a307-9127-481f-ba4f-c43f89f1420e' }) - @IsNotEmpty({message:'Please provide valid rev-reg-id'}) - @IsString({message:'Rev-reg-id should be string'}) - rev_reg_id: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid cred-ex-id' }) + @IsString({ message: 'Cred-ex-id should be string' }) + cred_ex_id?: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid cred-ex-id'}) - @IsString({message:'Cred-ex-id should be string'}) - cred_ex_id?: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid email' }) + @IsString({ message: 'Email should be string' }) + email: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid email'}) - @IsString({message:'Email should be string'}) - email: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid password' }) + @IsString({ message: 'Password should be string' }) + password: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid password'}) - @IsString({message:'Password should be string'}) - password: string; - - featureId: number; -} \ No newline at end of file + featureId: number +} diff --git a/apps/api-gateway/src/dtos/save-roles-permissions.dto.ts b/apps/api-gateway/src/dtos/save-roles-permissions.dto.ts index ce01ac99a..b01c86b86 100644 --- a/apps/api-gateway/src/dtos/save-roles-permissions.dto.ts +++ b/apps/api-gateway/src/dtos/save-roles-permissions.dto.ts @@ -1,14 +1,14 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class RolesPermissionsObj { - @ApiProperty() - roleId: string; + @ApiProperty() + roleId: string - @ApiProperty({ type: [] }) - permissionsId: number; + @ApiProperty({ type: [] }) + permissionsId: number } export class SaveRolesPermissionsDto { - @ApiProperty({ type: [] }) - data: RolesPermissionsObj; + @ApiProperty({ type: [] }) + data: RolesPermissionsObj } diff --git a/apps/api-gateway/src/dtos/schemasearch.dto.ts b/apps/api-gateway/src/dtos/schemasearch.dto.ts index 36e578d4a..4b20613b5 100644 --- a/apps/api-gateway/src/dtos/schemasearch.dto.ts +++ b/apps/api-gateway/src/dtos/schemasearch.dto.ts @@ -1,37 +1,36 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class SchemaSearchDto { - @ApiProperty() - // tslint:disable-next-line: variable-name - schema_version?: string; - - @ApiProperty() - // tslint:disable-next-line: variable-name - schema_name?: string; - - @ApiProperty() - attributes?: string; - - @ApiProperty() - // tslint:disable-next-line: variable-name - schema_ledger_id?: string; - - @ApiProperty() - // tslint:disable-next-line: variable-name - issuer_did?: string; - - - // tslint:disable-next-line: variable-name - @ApiProperty() - search_text: string; - - // tslint:disable-next-line: variable-name - @ApiProperty() - items_per_page: number; - - @ApiProperty() - page: number; - - @ApiProperty() - filter_value : boolean; + @ApiProperty() + // tslint:disable-next-line: variable-name + schema_version?: string + + @ApiProperty() + // tslint:disable-next-line: variable-name + schema_name?: string + + @ApiProperty() + attributes?: string + + @ApiProperty() + // tslint:disable-next-line: variable-name + schema_ledger_id?: string + + @ApiProperty() + // tslint:disable-next-line: variable-name + issuer_did?: string + + // tslint:disable-next-line: variable-name + @ApiProperty() + search_text: string + + // tslint:disable-next-line: variable-name + @ApiProperty() + items_per_page: number + + @ApiProperty() + page: number + + @ApiProperty() + filter_value: boolean } diff --git a/apps/api-gateway/src/dtos/send-invite-toOrg.dto.ts b/apps/api-gateway/src/dtos/send-invite-toOrg.dto.ts index e09c10b19..58bde184b 100644 --- a/apps/api-gateway/src/dtos/send-invite-toOrg.dto.ts +++ b/apps/api-gateway/src/dtos/send-invite-toOrg.dto.ts @@ -1,25 +1,21 @@ -import { IsArray, IsNotEmpty, IsString } from 'class-validator'; +import { IsArray, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class SendInviteToOrgDto { - - @ApiProperty({ 'example': '[{"orgName":"xyz","orgEmail":"xyz@gmail.com","orgRole": 1}]' }) - @IsArray({ message: 'attributes must be an array' }) - // @IsString({ each: true }) - @IsNotEmpty({ message: 'please provide valid attributes' }) - emails : InvitationEmailIds[]; - - @ApiProperty() - @IsString({ message: 'description must be a string' }) - description :string; - + @ApiProperty({ example: '[{"orgName":"xyz","orgEmail":"xyz@gmail.com","orgRole": 1}]' }) + @IsArray({ message: 'attributes must be an array' }) + // @IsString({ each: true }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + emails: InvitationEmailIds[] + + @ApiProperty() + @IsString({ message: 'description must be a string' }) + description: string } export class InvitationEmailIds { - - orgName : string; - orgEmail : string; - orgRole : string[]; - -} \ No newline at end of file + orgName: string + orgEmail: string + orgRole: string[] +} diff --git a/apps/api-gateway/src/dtos/send-proof-request.dto.ts b/apps/api-gateway/src/dtos/send-proof-request.dto.ts index a8d1600f5..853214a6e 100644 --- a/apps/api-gateway/src/dtos/send-proof-request.dto.ts +++ b/apps/api-gateway/src/dtos/send-proof-request.dto.ts @@ -1,26 +1,25 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsString, IsNotEmpty, IsObject } from 'class-validator'; - +import { ApiProperty } from '@nestjs/swagger' +import { IsArray, IsNotEmpty, IsObject, IsString } from 'class-validator' export class SendProofRequest { - @ApiProperty({ 'example': '3fa85f64-5717-4562-b3fc-2c963f66afa6' }) - @IsString({ message: 'connection id must be string' }) - @IsNotEmpty({ message: 'please provide valid connection Id' }) - connectionId: string; + @ApiProperty({ example: '3fa85f64-5717-4562-b3fc-2c963f66afa6' }) + @IsString({ message: 'connection id must be string' }) + @IsNotEmpty({ message: 'please provide valid connection Id' }) + connectionId: string - @ApiProperty({ - 'example': [ - { - attributeName: 'attributeName', - condition: '>=', - value: 'predicates', - credDefId: '', - credentialName: '' - } - ] - }) - @IsArray({ message: 'attributes must be in array' }) - @IsObject({ each: true }) - @IsNotEmpty({ message: 'please provide valid attributes' }) - attributes: object[]; -} \ No newline at end of file + @ApiProperty({ + example: [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: '', + credentialName: '', + }, + ], + }) + @IsArray({ message: 'attributes must be in array' }) + @IsObject({ each: true }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + attributes: object[] +} diff --git a/apps/api-gateway/src/dtos/subscription.dto.ts b/apps/api-gateway/src/dtos/subscription.dto.ts index 857000553..4e93666f6 100644 --- a/apps/api-gateway/src/dtos/subscription.dto.ts +++ b/apps/api-gateway/src/dtos/subscription.dto.ts @@ -1,10 +1,9 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class SubscriptionDto { + @ApiProperty() + name: string - @ApiProperty() - name: string; - - @ApiProperty() - description: string; + @ApiProperty() + description: string } diff --git a/apps/api-gateway/src/dtos/unauthorized-error.dto.ts b/apps/api-gateway/src/dtos/unauthorized-error.dto.ts index 5269ddd5c..b6fa9a332 100644 --- a/apps/api-gateway/src/dtos/unauthorized-error.dto.ts +++ b/apps/api-gateway/src/dtos/unauthorized-error.dto.ts @@ -1,10 +1,9 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class UnauthorizedErrorDto { + @ApiProperty({ example: 401 }) + statusCode: number - @ApiProperty({ example: 401 }) - statusCode: number; - - @ApiProperty({ example: 'Unauthorized' }) - error: string; + @ApiProperty({ example: 'Unauthorized' }) + error: string } diff --git a/apps/api-gateway/src/dtos/update-profile.dto.ts b/apps/api-gateway/src/dtos/update-profile.dto.ts index a46246007..cdae9dee9 100644 --- a/apps/api-gateway/src/dtos/update-profile.dto.ts +++ b/apps/api-gateway/src/dtos/update-profile.dto.ts @@ -1,24 +1,23 @@ -import { IsNotEmpty, IsString } from 'class-validator'; +import { IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { trim } from '@credebl/common/cast.helper'; -import { Transform } from 'class-transformer'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class UpdateProfileDto { + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid firstName' }) + @IsString({ message: 'FirstName should be string' }) + firstName: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid firstName'}) - @IsString({message:'FirstName should be string'}) - firstName: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid lastName' }) + @IsString({ message: 'LastName should be string' }) + lastName: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid lastName'}) - @IsString({message:'LastName should be string'}) - lastName: string; - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({message:'Please provide valid profileLogoUrl'}) - @IsString({message:'ProfileLogoUrl should be string'}) - profileLogoUrl?: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Please provide valid profileLogoUrl' }) + @IsString({ message: 'ProfileLogoUrl should be string' }) + profileLogoUrl?: string } diff --git a/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts b/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts index 1449172a0..a172ad811 100644 --- a/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts +++ b/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts @@ -1,10 +1,13 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class UpdateRevocationRegistryUriDto { - @ApiProperty({ 'example': 'WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0' }) - // tslint:disable-next-line: variable-name - revoc_reg_id?: string; - @ApiProperty({ 'example': 'http://192.168.56.133:5000/revocation/registry/WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0/tails-file' }) - // tslint:disable-next-line: variable-name - path?: string; -} \ No newline at end of file + @ApiProperty({ example: 'WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0' }) + // tslint:disable-next-line: variable-name + revoc_reg_id?: string + @ApiProperty({ + example: + 'http://192.168.56.133:5000/revocation/registry/WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0/tails-file', + }) + // tslint:disable-next-line: variable-name + path?: string +} diff --git a/apps/api-gateway/src/dtos/user-counts.dto.ts b/apps/api-gateway/src/dtos/user-counts.dto.ts index 106178fa5..1ef1dd348 100644 --- a/apps/api-gateway/src/dtos/user-counts.dto.ts +++ b/apps/api-gateway/src/dtos/user-counts.dto.ts @@ -1,9 +1,9 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class UserCountsDto { - @ApiProperty() - totalUser: number; + @ApiProperty() + totalUser: number - @ApiProperty() - activeUser: number; + @ApiProperty() + activeUser: number } diff --git a/apps/api-gateway/src/dtos/user-profile-update.dto.ts b/apps/api-gateway/src/dtos/user-profile-update.dto.ts index 1b161c5b6..a108322ed 100644 --- a/apps/api-gateway/src/dtos/user-profile-update.dto.ts +++ b/apps/api-gateway/src/dtos/user-profile-update.dto.ts @@ -1,14 +1,14 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class UserOrgProfileDto { - @ApiProperty() - @IsNotEmpty({message:'Please provide valid firstName'}) - @IsString({message:'FirstName should be string'}) - firstName?: string; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid firstName' }) + @IsString({ message: 'FirstName should be string' }) + firstName?: string - @ApiProperty() - @IsNotEmpty({message:'Please provide valid lastName'}) - @IsString({message:'LastName should be string'}) - lastName?: string; -} \ No newline at end of file + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid lastName' }) + @IsString({ message: 'LastName should be string' }) + lastName?: string +} diff --git a/apps/api-gateway/src/dtos/user-role-org-perms.dto.ts b/apps/api-gateway/src/dtos/user-role-org-perms.dto.ts index ed06cf3ec..81ffa2636 100644 --- a/apps/api-gateway/src/dtos/user-role-org-perms.dto.ts +++ b/apps/api-gateway/src/dtos/user-role-org-perms.dto.ts @@ -1,18 +1,16 @@ -export class UserRoleOrgPermsDto { - id :string; - role : userRoleDto; - Organization: userOrgDto; -} - -export class userRoleDto { - id: string; - name : string; - permissions :string[]; - -} - -export class userOrgDto { - id: string; - orgName :string; -} - +export class UserRoleOrgPermsDto { + id: string + role: userRoleDto + Organization: userOrgDto +} + +export class userRoleDto { + id: string + name: string + permissions: string[] +} + +export class userOrgDto { + id: string + orgName: string +} diff --git a/apps/api-gateway/src/dtos/wallet-details.dto.ts b/apps/api-gateway/src/dtos/wallet-details.dto.ts index d9bc141dc..0040b77ac 100644 --- a/apps/api-gateway/src/dtos/wallet-details.dto.ts +++ b/apps/api-gateway/src/dtos/wallet-details.dto.ts @@ -1,17 +1,15 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class WalletDetailsDto { + @ApiProperty() + walletName: string - @ApiProperty() - walletName: string; + @ApiProperty() + walletPassword: string - @ApiProperty() - walletPassword: string; + @ApiProperty() + ledgerId: string - @ApiProperty() - ledgerId: string; - - @ApiProperty() - transactionApproval?: string; - -} \ No newline at end of file + @ApiProperty() + transactionApproval?: string +} diff --git a/apps/api-gateway/src/enum.ts b/apps/api-gateway/src/enum.ts index dd8cadd70..e1bc723a2 100644 --- a/apps/api-gateway/src/enum.ts +++ b/apps/api-gateway/src/enum.ts @@ -1,39 +1,39 @@ export enum sortValue { - ASC = 'asc', - DESC = 'desc', + ASC = 'asc', + DESC = 'desc', } export enum SortValue { - ASC = 'asc', - DESC = 'desc', + ASC = 'asc', + DESC = 'desc', } export enum onboardRequestSort { - id = 'id', - orgName = 'orgName', - createDateTime = 'createDateTime', - isEmailVerified = 'isEmailVerified', - lastChangedDateTime = 'lastChangedDateTime' + id = 'id', + orgName = 'orgName', + createDateTime = 'createDateTime', + isEmailVerified = 'isEmailVerified', + lastChangedDateTime = 'lastChangedDateTime', } export enum schemaSortBy { - id = 'id', - schemaName = 'schemaName', - createDateTime = 'createDateTime' + id = 'id', + schemaName = 'schemaName', + createDateTime = 'createDateTime', } export enum credDefSortBy { - id = 'id', - createDateTime = 'createDateTime', - tag = 'tag' + id = 'id', + createDateTime = 'createDateTime', + tag = 'tag', } export enum connectionSortBy { - id = 'id', - theirLabel = 'theirLabel', - createDateTime = 'createdAt' + id = 'id', + theirLabel = 'theirLabel', + createDateTime = 'createdAt', } export enum credentialSortBy { - id = 'id', - createDateTime = 'createDateTime' + id = 'id', + createDateTime = 'createDateTime', } // export enum credRevokeStatus { @@ -43,88 +43,87 @@ export enum credentialSortBy { // } export enum booleanStatus { - all = 'all', - true = 'true', - false = 'false' + all = 'all', + true = 'true', + false = 'false', } export enum orgPresentProofRequestsSort { - id = 'id', - holderName = 'theirLabel', - createDateTime = 'createDateTime' + id = 'id', + holderName = 'theirLabel', + createDateTime = 'createDateTime', } export enum orgHolderRequestsSort { - id = 'id', - holderName = 'theirLabel', - createDateTime = 'createDateTime' + id = 'id', + holderName = 'theirLabel', + createDateTime = 'createDateTime', } export enum holderProofRequestsSort { - id = 'id', - createDateTime = 'createDateTime' + id = 'id', + createDateTime = 'createDateTime', } - export enum OnboardRequestSort { - id = 'id', - createDateTime = 'createDateTime', - orgName = 'orgName' + id = 'id', + createDateTime = 'createDateTime', + orgName = 'orgName', } export enum CategorySortBy { - id = 'id', - Name = 'name' + id = 'id', + Name = 'name', } export enum CredDefSortBy { - id = 'id', - createDateTime = 'createDateTime', - tag = 'tag' + id = 'id', + createDateTime = 'createDateTime', + tag = 'tag', } export enum transactionSort { - id = 'id', - createDateTime = 'createDateTime', + id = 'id', + createDateTime = 'createDateTime', } export enum ConnectionAlias { - endorser = 'ENDORSER', - author = 'AUTHOR', + endorser = 'ENDORSER', + author = 'AUTHOR', } export enum TransactionRole { - transactionAuthor = 'TRANSACTION_AUTHOR', - transactionEndorser = 'TRANSACTION_ENDORSER', + transactionAuthor = 'TRANSACTION_AUTHOR', + transactionEndorser = 'TRANSACTION_ENDORSER', } export enum TransactionType { - schema = 'SCHEMA', - credDef = 'CREDENTIAL_DEF', + schema = 'SCHEMA', + credDef = 'CREDENTIAL_DEF', } export enum OrderBy { - ASC = 'ASC', - DESC = 'DESC', + ASC = 'ASC', + DESC = 'DESC', } export enum EmailAuditOrderByColumns { - CreatedDateTime = 'createDateTime', - Id = 'id', + CreatedDateTime = 'createDateTime', + Id = 'id', } export enum ExpiredSubscriptionSortBy { - startDate = 'startDate', - endDate = 'endDate', - id = 'id', + startDate = 'startDate', + endDate = 'endDate', + id = 'id', } export enum FileUploadType { - Issuance = 'ISSUANCE' + Issuance = 'ISSUANCE', } export enum FileUploadStatus { - started = 'PROCESS_STARTED', - completed = 'PROCESS_COMPLETED', - interrupted= 'PROCESS_INTERRUPTED', - retry= 'PROCESS_REINITIATED', - partially_completed= 'PARTIALLY_COMPLETED' + started = 'PROCESS_STARTED', + completed = 'PROCESS_COMPLETED', + interrupted = 'PROCESS_INTERRUPTED', + retry = 'PROCESS_REINITIATED', + partially_completed = 'PARTIALLY_COMPLETED', } diff --git a/apps/api-gateway/src/fido/dto/fido-user.dto.ts b/apps/api-gateway/src/fido/dto/fido-user.dto.ts index 50783e6a7..da3f51730 100644 --- a/apps/api-gateway/src/fido/dto/fido-user.dto.ts +++ b/apps/api-gateway/src/fido/dto/fido-user.dto.ts @@ -1,103 +1,96 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsBoolean, IsEmail, IsNotEmpty, IsOptional } from 'class-validator'; - +import { ApiProperty } from '@nestjs/swagger' +import { IsBoolean, IsEmail, IsNotEmpty, IsOptional } from 'class-validator' export class GenerateRegistrationDto { - @ApiProperty({ example: 'abc@vomoto.com' }) - @IsNotEmpty({ message: 'Email is required.' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - userName: string; - - @IsOptional() - @ApiProperty({ example: 'false' }) - @IsBoolean({ message: 'isPasskey should be boolean' }) - deviceFlag: boolean; + @ApiProperty({ example: 'abc@vomoto.com' }) + @IsNotEmpty({ message: 'Email is required.' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + userName: string + + @IsOptional() + @ApiProperty({ example: 'false' }) + @IsBoolean({ message: 'isPasskey should be boolean' }) + deviceFlag: boolean } export class VerifyRegistrationDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string - @ApiProperty() - rawId: string; + @ApiProperty() + rawId: string - @ApiProperty() - response: Response; + @ApiProperty() + response: Response - @ApiProperty() - type: string; + @ApiProperty() + type: string - @ApiProperty() - clientExtensionResults: ClientExtensionResults; + @ApiProperty() + clientExtensionResults: ClientExtensionResults - @ApiProperty() - authenticatorAttachment: string; + @ApiProperty() + authenticatorAttachment: string - @ApiProperty() - challangeId: string; + @ApiProperty() + challangeId: string } export interface Response { - attestationObject: string - clientDataJSON: string - transports: [] + attestationObject: string + clientDataJSON: string + transports: [] } export interface ClientExtensionResults { - credProps: CredProps + credProps: CredProps } -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface CredProps { } - +// biome-ignore lint/complexity/noBannedTypes: +export type CredProps = {} export class VerifyAuthenticationDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string - @ApiProperty() - rawId: string; + @ApiProperty() + rawId: string - @ApiProperty() - response: Response; + @ApiProperty() + response: Response - @ApiProperty() - type: string; + @ApiProperty() + type: string - @ApiProperty() - clientExtensionResults: ClientExtensionResults; + @ApiProperty() + clientExtensionResults: ClientExtensionResults - @ApiProperty() - authenticatorAttachment: string; + @ApiProperty() + authenticatorAttachment: string - @ApiProperty() - challangeId: string; + @ApiProperty() + challangeId: string } export interface Response { - authenticatorData: string - clientDataJSON: string - signature: string - userHandle: string + authenticatorData: string + clientDataJSON: string + signature: string + userHandle: string } -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ClientExtensionResults { } - - export class UpdateFidoUserDetailsDto { - @ApiProperty() - userName: string; - - @ApiProperty() - credentialId: string; + @ApiProperty() + userName: string - @ApiProperty() - deviceFriendlyName: string; + @ApiProperty() + credentialId: string + @ApiProperty() + deviceFriendlyName: string } export class GenerateAuthenticationDto { - @ApiProperty({ example: 'abc@vomoto.com' }) - userName: string; + @ApiProperty({ example: 'abc@vomoto.com' }) + userName: string } diff --git a/apps/api-gateway/src/fido/fido.controller.ts b/apps/api-gateway/src/fido/fido.controller.ts index 37e11a0f8..c6747dff2 100644 --- a/apps/api-gateway/src/fido/fido.controller.ts +++ b/apps/api-gateway/src/fido/fido.controller.ts @@ -1,17 +1,47 @@ -import { Body, Controller, Delete, Get, HttpStatus, Logger, Param, Post, Put, Query, Request, Res, UseFilters } from '@nestjs/common'; -import { ApiBadRequestResponse, ApiBearerAuth, ApiExcludeEndpoint, ApiForbiddenResponse, ApiOperation, ApiQuery, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { BadRequestErrorDto } from '../dtos/bad-request-error.dto'; -import { GenerateAuthenticationDto, GenerateRegistrationDto, UpdateFidoUserDetailsDto, VerifyRegistrationDto, VerifyAuthenticationDto } from '../dtos/fido-user.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { FidoService } from './fido.service'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import IResponseType from '@credebl/common/interfaces/response.interface'; -import { Response } from 'express'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; +import type IResponseType from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { + Body, + Controller, + Delete, + Get, + HttpStatus, + Logger, + Param, + Post, + Put, + Query, + Request, + Res, + UseFilters, +} from '@nestjs/common' +import { + ApiBadRequestResponse, + ApiBearerAuth, + ApiExcludeEndpoint, + ApiForbiddenResponse, + ApiOperation, + ApiQuery, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { BadRequestErrorDto } from '../dtos/bad-request-error.dto' +import type { + GenerateAuthenticationDto, + GenerateRegistrationDto, + UpdateFidoUserDetailsDto, + VerifyAuthenticationDto, + VerifyRegistrationDto, +} from '../dtos/fido-user.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { FidoService } from './fido.service' @UseFilters(CustomExceptionFilter) @Controller('auth') @@ -20,198 +50,243 @@ import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) @ApiBadRequestResponse({ status: 400, description: 'Bad Request', type: BadRequestErrorDto }) export class FidoController { - private logger = new Logger('FidoController'); - constructor(private readonly fidoService: FidoService) { } + private logger = new Logger('FidoController') + constructor(private readonly fidoService: FidoService) {} - /** - * Fetch fido user details - * @param email The email of the user - * @param res The response object - * @returns User details - */ - @Get('/passkey/:email') - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.HOLDER, OrgRoles.ISSUER, OrgRoles.SUPER_ADMIN, OrgRoles.MEMBER) - @ApiBearerAuth() - @ApiOperation({ summary: 'Fetch fido user details', description: 'Retrieve the details of a FIDO user by their email address.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) - @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - @ApiBadRequestResponse({ status: 400, description: 'Bad Request', type: BadRequestErrorDto }) - async fetchFidoUserDetails(@Request() req, @Param('email') email: string, @Res() res: Response): Promise { - try { - const fidoUserDetails = await this.fidoService.fetchFidoUserDetails(req.params.email.toLowerCase()); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.fetchUsers, - data: fidoUserDetails.response - }; - return res.status(HttpStatus.OK).json(finalResponse); - } catch (error) { - this.logger.error(`Error::${error}`); - throw error; - } + /** + * Fetch fido user details + * @param email The email of the user + * @param res The response object + * @returns User details + */ + @Get('/passkey/:email') + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.HOLDER, OrgRoles.ISSUER, OrgRoles.SUPER_ADMIN, OrgRoles.MEMBER) + @ApiBearerAuth() + @ApiOperation({ + summary: 'Fetch fido user details', + description: 'Retrieve the details of a FIDO user by their email address.', + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) + @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) + @ApiBadRequestResponse({ status: 400, description: 'Bad Request', type: BadRequestErrorDto }) + async fetchFidoUserDetails(@Request() req, @Param('email') _email: string, @Res() res: Response): Promise { + try { + const fidoUserDetails = await this.fidoService.fetchFidoUserDetails(req.params.email.toLowerCase()) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.user.success.fetchUsers, + data: fidoUserDetails.response, + } + return res.status(HttpStatus.OK).json(finalResponse) + } catch (error) { + this.logger.error(`Error::${error}`) + throw error } + } - /** - * Generate registration option - * @param GenerateRegistrationDto The registration details - * @param email The email of the user - * @param res The response object - * @returns Registration options - */ - @Post('/passkey/generate-registration/:email') - @ApiExcludeEndpoint() - @ApiOperation({ summary: 'Generate registration option', description: 'Generate registration options for a FIDO user.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) - async generateRegistrationOption(@Body() body: GenerateRegistrationDto, @Param('email') email: string, @Res() res: Response): Promise { - try { - const { deviceFlag } = body; - const registrationOption = await this.fidoService.generateRegistrationOption(deviceFlag, email.toLowerCase()); - const finalResponse: IResponseType = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.fido.success.RegistrationOption, - data: registrationOption.response - }; - return res.status(HttpStatus.CREATED).json(finalResponse); - } catch (error) { - this.logger.error(`Error::${error}`); - } + /** + * Generate registration option + * @param GenerateRegistrationDto The registration details + * @param email The email of the user + * @param res The response object + * @returns Registration options + */ + @Post('/passkey/generate-registration/:email') + @ApiExcludeEndpoint() + @ApiOperation({ + summary: 'Generate registration option', + description: 'Generate registration options for a FIDO user.', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) + async generateRegistrationOption( + @Body() body: GenerateRegistrationDto, + @Param('email') email: string, + @Res() res: Response + ): Promise { + try { + const { deviceFlag } = body + const registrationOption = await this.fidoService.generateRegistrationOption(deviceFlag, email.toLowerCase()) + const finalResponse: IResponseType = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.fido.success.RegistrationOption, + data: registrationOption.response, + } + return res.status(HttpStatus.CREATED).json(finalResponse) + } catch (error) { + this.logger.error(`Error::${error}`) } + } - /** - * Verify registration - * @param verifyRegistrationDto The registration verification details - * @param email The email of the user - * @param res The response object - * @returns Verification result - */ - @Post('/passkey/verify-registration/:email') - @ApiExcludeEndpoint() - @ApiOperation({ summary: 'Verify registration', description: 'Verify the registration of a FIDO user.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async verifyRegistration(@Request() req, @Body() verifyRegistrationDto: VerifyRegistrationDto, @Param('email') email: string, @Res() res: Response): Promise { - const verifyRegistration = await this.fidoService.verifyRegistration(verifyRegistrationDto, req.params.email.toLowerCase()); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.fido.success.verifyRegistration, - data: verifyRegistration.response - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Verify registration + * @param verifyRegistrationDto The registration verification details + * @param email The email of the user + * @param res The response object + * @returns Verification result + */ + @Post('/passkey/verify-registration/:email') + @ApiExcludeEndpoint() + @ApiOperation({ summary: 'Verify registration', description: 'Verify the registration of a FIDO user.' }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async verifyRegistration( + @Request() req, + @Body() verifyRegistrationDto: VerifyRegistrationDto, + @Param('email') _email: string, + @Res() res: Response + ): Promise { + const verifyRegistration = await this.fidoService.verifyRegistration( + verifyRegistrationDto, + req.params.email.toLowerCase() + ) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.fido.success.verifyRegistration, + data: verifyRegistration.response, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Generate authentication option - * @param GenerateAuthenticationDto The authentication details - * @param res The response object - * @returns Authentication options - */ - @Post('/passkey/authentication-options') - @ApiExcludeEndpoint() - @ApiOperation({ summary: 'Generate authentication option', description: 'Generate authentication options for a FIDO user.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) - async generateAuthenticationOption(@Body() body: GenerateAuthenticationDto, @Request() req, @Res() res: Response): Promise { - const generateAuthentication = await this.fidoService.generateAuthenticationOption(body); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.fido.success.generateAuthenticationOption, - data: generateAuthentication.response - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Generate authentication option + * @param GenerateAuthenticationDto The authentication details + * @param res The response object + * @returns Authentication options + */ + @Post('/passkey/authentication-options') + @ApiExcludeEndpoint() + @ApiOperation({ + summary: 'Generate authentication option', + description: 'Generate authentication options for a FIDO user.', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) + async generateAuthenticationOption( + @Body() body: GenerateAuthenticationDto, + @Request() _req, + @Res() res: Response + ): Promise { + const generateAuthentication = await this.fidoService.generateAuthenticationOption(body) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.fido.success.generateAuthenticationOption, + data: generateAuthentication.response, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Verify authentication - * @param verifyAuthenticationDto The authentication verification details - * @param email The email of the user - * @param res The response object - * @returns Verification result - */ - @Post('/passkey/verify-authentication/:email') - @ApiExcludeEndpoint() - @ApiOperation({ summary: 'Verify authentication', description: 'Verify the authentication of a FIDO user.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async verifyAuthentication(@Request() req, @Body() verifyAuthenticationDto: VerifyAuthenticationDto, @Param('email') email: string, @Res() res: Response): Promise { - const verifyAuthentication = await this.fidoService.verifyAuthentication(verifyAuthenticationDto, req.params.email.toLowerCase()); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.fido.success.login, - data: verifyAuthentication.response - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Verify authentication + * @param verifyAuthenticationDto The authentication verification details + * @param email The email of the user + * @param res The response object + * @returns Verification result + */ + @Post('/passkey/verify-authentication/:email') + @ApiExcludeEndpoint() + @ApiOperation({ summary: 'Verify authentication', description: 'Verify the authentication of a FIDO user.' }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async verifyAuthentication( + @Request() req, + @Body() verifyAuthenticationDto: VerifyAuthenticationDto, + @Param('email') _email: string, + @Res() res: Response + ): Promise { + const verifyAuthentication = await this.fidoService.verifyAuthentication( + verifyAuthenticationDto, + req.params.email.toLowerCase() + ) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.fido.success.login, + data: verifyAuthentication.response, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Update fido user details - * @param updateFidoUserDetailsDto The user details to be updated - * @param credentialId The credential ID of the user - * @param res The response object - * @returns Updated user details - */ - @Put('/passkey/user-details/:credentialId') - @ApiExcludeEndpoint() - @ApiOperation({ summary: 'Update fido user details', description: 'Update the details of a FIDO user.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async updateFidoUser(@Request() req, @Body() updateFidoUserDetailsDto: UpdateFidoUserDetailsDto, @Param('credentialId') credentialId: string, @Res() res: Response): Promise { - const verifyRegistration = await this.fidoService.updateFidoUser(updateFidoUserDetailsDto, decodeURIComponent(credentialId)); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.fido.success.updateUserDetails, - data: verifyRegistration.response - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Update fido user details + * @param updateFidoUserDetailsDto The user details to be updated + * @param credentialId The credential ID of the user + * @param res The response object + * @returns Updated user details + */ + @Put('/passkey/user-details/:credentialId') + @ApiExcludeEndpoint() + @ApiOperation({ summary: 'Update fido user details', description: 'Update the details of a FIDO user.' }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async updateFidoUser( + @Request() _req, + @Body() updateFidoUserDetailsDto: UpdateFidoUserDetailsDto, + @Param('credentialId') credentialId: string, + @Res() res: Response + ): Promise { + const verifyRegistration = await this.fidoService.updateFidoUser( + updateFidoUserDetailsDto, + decodeURIComponent(credentialId) + ) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.fido.success.updateUserDetails, + data: verifyRegistration.response, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Update fido user device name - * @param credentialId The credential ID of the user - * @param deviceName The new device name - * @param res The response object - * @returns Updated device name - */ - @Put('/passkey/:credentialId') - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.HOLDER, OrgRoles.ISSUER, OrgRoles.SUPER_ADMIN, OrgRoles.MEMBER) - @ApiBearerAuth() - @ApiOperation({ summary: 'Update fido user device name', description: 'Update the device name of a FIDO user.' }) - @ApiQuery({ name: 'deviceName', required: true }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async updateFidoUserDeviceName(@Param('credentialId') credentialId: string, @Query('deviceName') deviceName: string, @Res() res: Response): Promise { - try { - const updateDeviceName = await this.fidoService.updateFidoUserDeviceName(credentialId, deviceName); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.fido.success.updateDeviceName, - data: updateDeviceName.response - }; - return res.status(HttpStatus.OK).json(finalResponse); - } catch (error) { - this.logger.error(`Error::${error}`); - throw error; - } + /** + * Update fido user device name + * @param credentialId The credential ID of the user + * @param deviceName The new device name + * @param res The response object + * @returns Updated device name + */ + @Put('/passkey/:credentialId') + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.HOLDER, OrgRoles.ISSUER, OrgRoles.SUPER_ADMIN, OrgRoles.MEMBER) + @ApiBearerAuth() + @ApiOperation({ summary: 'Update fido user device name', description: 'Update the device name of a FIDO user.' }) + @ApiQuery({ name: 'deviceName', required: true }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async updateFidoUserDeviceName( + @Param('credentialId') credentialId: string, + @Query('deviceName') deviceName: string, + @Res() res: Response + ): Promise { + try { + const updateDeviceName = await this.fidoService.updateFidoUserDeviceName(credentialId, deviceName) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.fido.success.updateDeviceName, + data: updateDeviceName.response, + } + return res.status(HttpStatus.OK).json(finalResponse) + } catch (error) { + this.logger.error(`Error::${error}`) + throw error } + } - /** - * Delete fido user device - * @param credentialId The credential ID of the user - * @param res The response object - * @returns Success message - */ - @Delete('/passkey/:credentialId') - @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.HOLDER, OrgRoles.ISSUER, OrgRoles.SUPER_ADMIN, OrgRoles.MEMBER) - @ApiBearerAuth() - @ApiOperation({ summary: 'Delete fido user device', description: 'Delete a FIDO user device by its credential ID.' }) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async deleteFidoUserDevice(@Param('credentialId') credentialId: string, @Res() res: Response): Promise { - try { - const deleteFidoUser = await this.fidoService.deleteFidoUserDevice(credentialId); - const finalResponse: IResponseType = { - statusCode: HttpStatus.OK, - message: ResponseMessages.fido.success.deleteDevice, - data: deleteFidoUser.response - }; - return res.status(HttpStatus.OK).json(finalResponse); - } catch (error) { - this.logger.error(`Error::${error}`); - throw error; - } + /** + * Delete fido user device + * @param credentialId The credential ID of the user + * @param res The response object + * @returns Success message + */ + @Delete('/passkey/:credentialId') + @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.HOLDER, OrgRoles.ISSUER, OrgRoles.SUPER_ADMIN, OrgRoles.MEMBER) + @ApiBearerAuth() + @ApiOperation({ summary: 'Delete fido user device', description: 'Delete a FIDO user device by its credential ID.' }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async deleteFidoUserDevice(@Param('credentialId') credentialId: string, @Res() res: Response): Promise { + try { + const deleteFidoUser = await this.fidoService.deleteFidoUserDevice(credentialId) + const finalResponse: IResponseType = { + statusCode: HttpStatus.OK, + message: ResponseMessages.fido.success.deleteDevice, + data: deleteFidoUser.response, + } + return res.status(HttpStatus.OK).json(finalResponse) + } catch (error) { + this.logger.error(`Error::${error}`) + throw error } + } } diff --git a/apps/api-gateway/src/fido/fido.module.ts b/apps/api-gateway/src/fido/fido.module.ts index 6f05ce04d..e015601ef 100644 --- a/apps/api-gateway/src/fido/fido.module.ts +++ b/apps/api-gateway/src/fido/fido.module.ts @@ -1,23 +1,22 @@ -import { Module } from '@nestjs/common'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { FidoController } from './fido.controller'; -import { FidoService } from './fido.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { FidoController } from './fido.controller' +import { FidoService } from './fido.service' @Module({ - imports:[ + imports: [ ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.FIDO_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - - } - ]) + options: getNatsOptions(CommonConstants.FIDO_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [FidoController], - providers: [FidoService, NATSClient] + providers: [FidoService, NATSClient], }) -export class FidoModule { } +export class FidoModule {} diff --git a/apps/api-gateway/src/fido/fido.service.ts b/apps/api-gateway/src/fido/fido.service.ts index e746b3930..60629a676 100644 --- a/apps/api-gateway/src/fido/fido.service.ts +++ b/apps/api-gateway/src/fido/fido.service.ts @@ -1,61 +1,70 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { UpdateFidoUserDetailsDto, VerifyRegistrationDto, GenerateAuthenticationDto, VerifyAuthenticationDto } from '../dtos/fido-user.dto'; -import { NATSClient } from '@credebl/common/NATSClient'; - +import type { NATSClient } from '@credebl/common/NATSClient' +import { Inject, Injectable } from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +import { BaseService } from 'libs/service/base.service' +import type { + GenerateAuthenticationDto, + UpdateFidoUserDetailsDto, + VerifyAuthenticationDto, + VerifyRegistrationDto, +} from '../dtos/fido-user.dto' @Injectable() export class FidoService extends BaseService { - constructor( - @Inject('NATS_CLIENT') private readonly fidoServiceProxy: ClientProxy, - private readonly natsClient : NATSClient - ) { - super('FidoService'); - } - async generateRegistrationOption(deviceFlag: boolean, email:string): Promise<{response: object}> { - try { - const payload = { deviceFlag, email }; - return await this.natsClient.sendNats(this.fidoServiceProxy, 'generate-registration-options', payload); - } catch (error) { - throw new RpcException(error.response); - } - + constructor( + @Inject('NATS_CLIENT') private readonly fidoServiceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('FidoService') + } + async generateRegistrationOption(deviceFlag: boolean, email: string): Promise<{ response: object }> { + try { + const payload = { deviceFlag, email } + return await this.natsClient.sendNats(this.fidoServiceProxy, 'generate-registration-options', payload) + } catch (error) { + throw new RpcException(error.response) } + } - async verifyRegistration(verifyRegistrationDto: VerifyRegistrationDto, email: string): Promise<{response: object}> { - const payload = { verifyRegistrationDetails: verifyRegistrationDto, email }; - return this.natsClient.sendNats(this.fidoServiceProxy, 'verify-registration', payload); - } + async verifyRegistration(verifyRegistrationDto: VerifyRegistrationDto, email: string): Promise<{ response: object }> { + const payload = { verifyRegistrationDetails: verifyRegistrationDto, email } + return this.natsClient.sendNats(this.fidoServiceProxy, 'verify-registration', payload) + } - async generateAuthenticationOption(generateAuthentication: GenerateAuthenticationDto) : Promise<{response: object}> { - const {userName} = generateAuthentication; - const payload = { userName }; - return this.natsClient.sendNats(this.fidoServiceProxy, 'generate-authentication-options', payload); - } + async generateAuthenticationOption(generateAuthentication: GenerateAuthenticationDto): Promise<{ response: object }> { + const { userName } = generateAuthentication + const payload = { userName } + return this.natsClient.sendNats(this.fidoServiceProxy, 'generate-authentication-options', payload) + } - async verifyAuthentication(verifyAuthenticationDto: VerifyAuthenticationDto, email: string): Promise<{response: object}> { - const payload = { verifyAuthenticationDetails: verifyAuthenticationDto, email }; - return this.natsClient.sendNats(this.fidoServiceProxy, 'verify-authentication', payload); - } + async verifyAuthentication( + verifyAuthenticationDto: VerifyAuthenticationDto, + email: string + ): Promise<{ response: object }> { + const payload = { verifyAuthenticationDetails: verifyAuthenticationDto, email } + return this.natsClient.sendNats(this.fidoServiceProxy, 'verify-authentication', payload) + } - async updateFidoUser(updateFidoUserDetailsDto: UpdateFidoUserDetailsDto, credentialId: string) : Promise<{response: object}> { - const payload = {updateFidoUserDetailsDto, credentialId}; - return this.natsClient.sendNats(this.fidoServiceProxy, 'update-user', payload); - } + async updateFidoUser( + updateFidoUserDetailsDto: UpdateFidoUserDetailsDto, + credentialId: string + ): Promise<{ response: object }> { + const payload = { updateFidoUserDetailsDto, credentialId } + return this.natsClient.sendNats(this.fidoServiceProxy, 'update-user', payload) + } - async fetchFidoUserDetails(email: string): Promise<{response: string}> { - const payload = { email }; - return this.natsClient.sendNats(this.fidoServiceProxy, 'fetch-fido-user-details', payload); - } + async fetchFidoUserDetails(email: string): Promise<{ response: string }> { + const payload = { email } + return this.natsClient.sendNats(this.fidoServiceProxy, 'fetch-fido-user-details', payload) + } - async deleteFidoUserDevice(credentialId: string): Promise<{response: object}> { - const payload = { credentialId }; - return this.natsClient.sendNats(this.fidoServiceProxy, 'delete-fido-user-device', payload); - } + async deleteFidoUserDevice(credentialId: string): Promise<{ response: object }> { + const payload = { credentialId } + return this.natsClient.sendNats(this.fidoServiceProxy, 'delete-fido-user-device', payload) + } - async updateFidoUserDeviceName(credentialId: string, deviceName: string): Promise<{response: string}> { - const payload = { credentialId, deviceName }; - return this.natsClient.sendNats(this.fidoServiceProxy, 'update-fido-user-device-name', payload); - } + async updateFidoUserDeviceName(credentialId: string, deviceName: string): Promise<{ response: string }> { + const payload = { credentialId, deviceName } + return this.natsClient.sendNats(this.fidoServiceProxy, 'update-fido-user-device-name', payload) + } } diff --git a/apps/api-gateway/src/geo-location/geo-location.controller.ts b/apps/api-gateway/src/geo-location/geo-location.controller.ts index 2bca8eecc..f4d778db2 100644 --- a/apps/api-gateway/src/geo-location/geo-location.controller.ts +++ b/apps/api-gateway/src/geo-location/geo-location.controller.ts @@ -1,11 +1,11 @@ -import { Controller, Get, HttpStatus, Logger, Param, Res, UseFilters } from '@nestjs/common'; -import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { GeoLocationService } from './geo-location.service'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import IResponseType from '@credebl/common/interfaces/response.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { Response } from 'express'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; +import type IResponseType from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Controller, Get, HttpStatus, type Logger, Param, Res, UseFilters } from '@nestjs/common' +import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import type { GeoLocationService } from './geo-location.service' @UseFilters(CustomExceptionFilter) @Controller('/') @@ -21,16 +21,19 @@ export class GeoLocationController { * @returns A list of all available countries */ @Get('countries') - @ApiOperation({ summary: 'Retrieve a list of all countries', description: 'Fetches and returns the details of all available countries.' }) + @ApiOperation({ + summary: 'Retrieve a list of all countries', + description: 'Fetches and returns the details of all available countries.', + }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getAllCountries(@Res() res: Response): Promise { - const countriesDetails = await this.geolocationService.getAllCountries(); + const countriesDetails = await this.geolocationService.getAllCountries() const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.geolocation.success.countriesVerificationCode, - data: countriesDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: countriesDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -39,16 +42,19 @@ export class GeoLocationController { * @returns A list of all states associated with the given countryId */ @Get('countries/:countryId/states') - @ApiOperation({ summary: 'Retrieve a list of all states within a specified country', description: 'Fetches and returns the details of all states associated with a given countryId.' }) + @ApiOperation({ + summary: 'Retrieve a list of all states within a specified country', + description: 'Fetches and returns the details of all states associated with a given countryId.', + }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getStatesByCountryId(@Param('countryId') countryId: number, @Res() res: Response): Promise { - const statesDetails = await this.geolocationService.getStatesByCountryId(countryId); + const statesDetails = await this.geolocationService.getStatesByCountryId(countryId) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.geolocation.success.stateVerificationCode, - data: statesDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: statesDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -58,15 +64,22 @@ export class GeoLocationController { * @returns A list of all cities associated with the given countryId and stateId */ @Get('countries/:countryId/states/:stateId/cities') - @ApiOperation({ summary: 'Retrieve a list of all cities within a specified state and country', description: 'Fetches and returns the details of all cities associated with a given countryId and stateId.' }) + @ApiOperation({ + summary: 'Retrieve a list of all cities within a specified state and country', + description: 'Fetches and returns the details of all cities associated with a given countryId and stateId.', + }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getCitiesByStateAndCountry(@Param('countryId') countryId: number, @Param('stateId') stateId: number, @Res() res: Response): Promise { - const citiesDetails = await this.geolocationService.getCitiesByStateAndCountry(countryId, stateId); + async getCitiesByStateAndCountry( + @Param('countryId') countryId: number, + @Param('stateId') stateId: number, + @Res() res: Response + ): Promise { + const citiesDetails = await this.geolocationService.getCitiesByStateAndCountry(countryId, stateId) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.geolocation.success.cityVerificationCode, - data: citiesDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: citiesDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } } diff --git a/apps/api-gateway/src/geo-location/geo-location.module.ts b/apps/api-gateway/src/geo-location/geo-location.module.ts index 0f5db4d68..f6b93f2fc 100644 --- a/apps/api-gateway/src/geo-location/geo-location.module.ts +++ b/apps/api-gateway/src/geo-location/geo-location.module.ts @@ -1,12 +1,12 @@ -import { Logger, Module } from '@nestjs/common'; -import { GeoLocationController } from './geo-location.controller'; -import { GeoLocationService } from './geo-location.service'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { RateLimiterModule, RateLimiterGuard } from 'nestjs-rate-limiter'; -import { APP_GUARD } from '@nestjs/core'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Logger, Module } from '@nestjs/common' +import { APP_GUARD } from '@nestjs/core' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { RateLimiterGuard, RateLimiterModule } from 'nestjs-rate-limiter' +import { GeoLocationController } from './geo-location.controller' +import { GeoLocationService } from './geo-location.service' @Module({ imports: [ @@ -14,15 +14,15 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.GEO_LOCATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.GEO_LOCATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, ]), RateLimiterModule.register({ points: 50, duration: 1, keyPrefix: 'rateLimiter', - errorMessage: 'Rate limit exceeded, please try again later.' - }) + errorMessage: 'Rate limit exceeded, please try again later.', + }), ], controllers: [GeoLocationController], providers: [ @@ -30,9 +30,9 @@ import { NATSClient } from '@credebl/common/NATSClient'; Logger, { provide: APP_GUARD, - useClass: RateLimiterGuard + useClass: RateLimiterGuard, }, - NATSClient - ] + NATSClient, + ], }) export class GeoLocationModule {} diff --git a/apps/api-gateway/src/geo-location/geo-location.service.ts b/apps/api-gateway/src/geo-location/geo-location.service.ts index ab8f92f7b..d4de02be4 100644 --- a/apps/api-gateway/src/geo-location/geo-location.service.ts +++ b/apps/api-gateway/src/geo-location/geo-location.service.ts @@ -1,13 +1,16 @@ -import { CountryInterface, StateInterface, CityInterface } from '@credebl/common/interfaces/geolocation.interface'; -import { Inject, Injectable } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { CityInterface, CountryInterface, StateInterface } from '@credebl/common/interfaces/geolocation.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from 'libs/service/base.service' @Injectable() export class GeoLocationService extends BaseService { - constructor(@Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, private readonly natsClient : NATSClient) { - super('GeoLocationService'); + constructor( + @Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('GeoLocationService') } /** @@ -16,8 +19,8 @@ export class GeoLocationService extends BaseService { * @returns Get all Countries list */ async getAllCountries(): Promise { - this.logger.log(`Finding all countries,GeoLocationService::getAllCountries`); - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-all-countries', ''); + this.logger.log('Finding all countries,GeoLocationService::getAllCountries') + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-all-countries', '') } /** @@ -26,9 +29,9 @@ export class GeoLocationService extends BaseService { * @returns Get all states list by using countryId */ async getStatesByCountryId(countryId: number): Promise { - const payload = { countryId }; - this.logger.log(`Finding cities for countryId= ${countryId},GeoLocationService::getCitiesByStateAndCountry`); - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-all-states', payload); + const payload = { countryId } + this.logger.log(`Finding cities for countryId= ${countryId},GeoLocationService::getCitiesByStateAndCountry`) + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-all-states', payload) } /** @@ -38,10 +41,10 @@ export class GeoLocationService extends BaseService { */ async getCitiesByStateAndCountry(countryId: number, stateId: number): Promise { - const payload = { countryId, stateId }; + const payload = { countryId, stateId } this.logger.log( `Finding cities for stateId= ${stateId} and countryId= ${countryId},GeoLocationService::getCitiesByStateAndCountry` - ); - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-all-cities', payload); + ) + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-all-cities', payload) } } diff --git a/apps/api-gateway/src/helper-files/file-operation.helper.ts b/apps/api-gateway/src/helper-files/file-operation.helper.ts index e02d7315b..b6bb6d60a 100644 --- a/apps/api-gateway/src/helper-files/file-operation.helper.ts +++ b/apps/api-gateway/src/helper-files/file-operation.helper.ts @@ -1,36 +1,26 @@ -import { promisify } from "util"; -import * as fs from "fs"; +import * as fs from 'fs' +import { promisify } from 'util' +export const createFile = async (path: string, fileName: string, data: string): Promise => { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + if (!checkIfFileOrDirectoryExists(path)) { + fs.mkdirSync(path) + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _writeFile = promisify(fs.writeFile) + return fs.writeFileSync(`${path}/${fileName}`, data, 'utf8') +} -export const createFile = async ( - path: string, - fileName: string, - data: string - ): Promise => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - if (!checkIfFileOrDirectoryExists(path)) { - - fs.mkdirSync(path); - } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const writeFile = promisify(fs.writeFile); - return fs.writeFileSync(`${path}/${fileName}`, data, 'utf8'); - }; +export const checkIfFileOrDirectoryExists = (path: string): boolean => fs.existsSync(path) - export const checkIfFileOrDirectoryExists = (path: string): boolean => fs.existsSync(path); - - export const getFile = async ( - path: string, - encoding: BufferEncoding - ): Promise => { - const readFile = promisify(fs.readFile); - - return encoding ? readFile(path, {encoding}) : readFile(path, {}); - }; +export const getFile = async (path: string, encoding: BufferEncoding): Promise => { + const readFile = promisify(fs.readFile) + return encoding ? readFile(path, { encoding }) : readFile(path, {}) +} - export const deleteFile = async (path: string): Promise => { - const unlink = promisify(fs.unlink); - - return unlink(path); - }; \ No newline at end of file +export const deleteFile = async (path: string): Promise => { + const unlink = promisify(fs.unlink) + + return unlink(path) +} diff --git a/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts b/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts index a228ae636..eddf1bd32 100644 --- a/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/IConnectionSearch.interface.ts @@ -1,34 +1,34 @@ -import { IUserRequestInterface } from './IUserRequestInterface'; +import type { IUserRequestInterface } from './IUserRequestInterface' export interface IConnectionSearchCriteria { - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - searchByText: string; - user?: IUserRequestInterface; + pageNumber: number + pageSize: number + sortField: string + 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; + id: string + createdAt: string + did: string + theirDid: string + theirLabel: string + state: string + role: string + autoAcceptConnection: boolean + threadId: string + protocol: string + outOfBandId: string + updatedAt: string } export interface AgentConnectionSearchCriteria { - outOfBandId?: string; - alias?: string; - state?: string; - myDid?: string; - theirDid?: string; - theirLabel?: string; + outOfBandId?: string + alias?: string + state?: string + myDid?: string + theirDid?: string + theirLabel?: string } diff --git a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts index 5d92e5b61..5c0dcfabf 100644 --- a/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts +++ b/apps/api-gateway/src/interfaces/ISchemaSearch.interface.ts @@ -1,40 +1,38 @@ -import { SchemaType } from '@credebl/enum/enum'; -import { IUserRequestInterface } from '../schema/interfaces'; +import type { SchemaType } from '@credebl/enum/enum' +import type { IUserRequestInterface } from '../schema/interfaces' export interface ISchemaSearchPayload { - ledgerId?: string; - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - searchByText?: string; - schemaType?: SchemaType; - user?: IUserRequestInterface + ledgerId?: string + pageNumber: number + pageSize: number + sortField: string + sortBy: string + searchByText?: string + schemaType?: SchemaType + user?: IUserRequestInterface } - export interface W3CSchemaPayload { - schemaAttributes: W3CSchemaAttributes []; - schemaName: string; - did: string; - } + schemaAttributes: W3CSchemaAttributes[] + schemaName: string + did: string +} - interface W3CSchemaAttributes { - type: string, - title: string - } +interface W3CSchemaAttributes { + type: string + title: string +} - export interface ILedgers { - id: string; - createDateTime: string; - lastChangedDateTime: string; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - nymTxnEndpoint: string; - indyNamespace: string; - networkUrl: string | null; - } - \ No newline at end of file +export interface ILedgers { + id: string + createDateTime: string + lastChangedDateTime: string + name: string + networkType: string + poolConfig: string + isActive: boolean + networkString: string + nymTxnEndpoint: string + indyNamespace: string + networkUrl: string | null +} diff --git a/apps/api-gateway/src/interfaces/ISocket.interface.ts b/apps/api-gateway/src/interfaces/ISocket.interface.ts index 6ca13fc68..671554258 100644 --- a/apps/api-gateway/src/interfaces/ISocket.interface.ts +++ b/apps/api-gateway/src/interfaces/ISocket.interface.ts @@ -1,14 +1,14 @@ interface IError { - error: string + error: string } export interface ISocketInterface { - token?: string; - message?: string; - clientSocketId?: string; - clientId?: string; - error?: string | IError; - connectionId?: string; - demoFlow?: string; - fileUploadId?: string; -} \ No newline at end of file + token?: string + message?: string + clientSocketId?: string + clientId?: string + error?: string | IError + connectionId?: string + demoFlow?: string + fileUploadId?: string +} diff --git a/apps/api-gateway/src/interfaces/IUserRequestInterface.ts b/apps/api-gateway/src/interfaces/IUserRequestInterface.ts index dbda90cec..1af16503f 100644 --- a/apps/api-gateway/src/interfaces/IUserRequestInterface.ts +++ b/apps/api-gateway/src/interfaces/IUserRequestInterface.ts @@ -1,16 +1,15 @@ -import { UserRoleOrgPermsDto } from '../authz/dtos/user-role-org-perms.dto'; +import type { UserRoleOrgPermsDto } from '../authz/dtos/user-role-org-perms.dto' export interface IUserRequestInterface { - id: string; - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?:string + id: string + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string } - diff --git a/apps/api-gateway/src/interfaces/fileExport.interface.ts b/apps/api-gateway/src/interfaces/fileExport.interface.ts index 4cc78a3c3..c91ae0e66 100644 --- a/apps/api-gateway/src/interfaces/fileExport.interface.ts +++ b/apps/api-gateway/src/interfaces/fileExport.interface.ts @@ -1,13 +1,13 @@ -import { IUserRequestInterface } from './IUserRequestInterface'; +import type { IUserRequestInterface } from './IUserRequestInterface' export interface FileExportResponse { - fileContent: string; - fileName : string + fileContent: string + fileName: string } export interface FileImportRequest { - filePath: string; - fileName : string; - credDefId: string; - user : IUserRequestInterface -} \ No newline at end of file + filePath: string + fileName: string + credDefId: string + user: IUserRequestInterface +} 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 37be22275..eba38d254 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,22 +1,21 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsEnum, IsOptional } from 'class-validator'; -import { SortValue } from '../../enum'; -import { trim } from '@credebl/common/cast.helper'; -import { SortFields } from 'apps/issuance/enum/issuance.enum'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; +import { trim } from '@credebl/common/cast.helper' +import { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import { ApiProperty } from '@nestjs/swagger' +import { SortFields } from 'apps/issuance/enum/issuance.enum' +import { Transform } from 'class-transformer' +import { IsEnum, IsOptional } from 'class-validator' +import { SortValue } from '../../enum' export class IGetAllIssuedCredentialsDto extends PaginationDto { - @ApiProperty({ required: false, enum: SortFields }) @Transform(({ value }) => trim(value)) @IsOptional() @IsEnum(SortFields) - sortField: string = SortFields.CREATED_DATE_TIME; + sortField: string = SortFields.CREATED_DATE_TIME @ApiProperty({ required: false, enum: SortValue }) @Transform(({ value }) => trim(value)) @IsOptional() @IsEnum(SortValue) - sortBy: string = SortValue.DESC; + sortBy: string = SortValue.DESC } diff --git a/apps/api-gateway/src/issuance/dtos/issuance.dto.ts b/apps/api-gateway/src/issuance/dtos/issuance.dto.ts index 26b5e5ca4..873a807b1 100644 --- a/apps/api-gateway/src/issuance/dtos/issuance.dto.ts +++ b/apps/api-gateway/src/issuance/dtos/issuance.dto.ts @@ -1,6 +1,8 @@ /* eslint-disable @typescript-eslint/array-type */ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { AutoAccept, SchemaType, SortValue } from '@credebl/enum/enum' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform, Type } from 'class-transformer' import { ArrayMaxSize, ArrayMinSize, @@ -16,26 +18,24 @@ import { IsUUID, IsUrl, MaxLength, - ValidateNested -} from 'class-validator'; -import { AutoAccept, SchemaType, SortValue } from '@credebl/enum/enum'; -import { IsCredentialJsonLdContext, SingleOrArray } from '../utils/helper'; -import { + ValidateNested, +} from 'class-validator' +import type { IssueCredentialType, JsonLdCredentialDetailCredentialStatusOptions, JsonLdCredentialDetailOptionsOptions, - JsonObject -} from '../interfaces'; -import { Transform, Type } from 'class-transformer'; + JsonObject, +} from '../interfaces' +import { IsCredentialJsonLdContext, type SingleOrArray } from '../utils/helper' -import { SortFields } from 'apps/connection/src/enum/connection.enum'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { SortFields } from 'apps/connection/src/enum/connection.enum' class Issuer { @ApiProperty() @IsNotEmpty({ message: 'id is required' }) @Type(() => String) - id: string | { id?: string }; + id: string | { id?: string } } class PrettyVc { @@ -43,122 +43,122 @@ class PrettyVc { @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'Certificate must be in string format.' }) - certificate: string; + certificate: string @ApiPropertyOptional({ example: 'a4' }) @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'Size must be in string format.' }) - size: string; + size: string @ApiPropertyOptional({ example: 'landscape' }) @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'orientation must be in string format.' }) - orientation: string; + orientation: string @ApiPropertyOptional({ example: '60px' }) @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'height must be in string format.' }) - height?: string; + height?: string @ApiPropertyOptional({ example: '60px' }) @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'width must be in string format.' }) - width?: string; + width?: string } export class Credential { @ApiProperty() @IsNotEmpty({ message: 'context is required' }) @IsCredentialJsonLdContext() - '@context': Array; + '@context': Array @ApiProperty() @IsNotEmpty({ message: 'type is required' }) - type: string[]; + type: string[] @ApiProperty() @IsString({ message: 'id should be string' }) @IsNotEmpty({ message: 'id is required' }) @Type(() => String) @IsOptional() - id?: string; + id?: string @ApiProperty() @ValidateNested({ each: true }) @Type(() => Issuer) - issuer: Issuer; + issuer: Issuer @ApiProperty() @IsString({ message: 'issuance date should be string' }) @IsNotEmpty({ message: 'issuance date is required' }) @Type(() => String) - issuanceDate: string; + issuanceDate: string @ApiPropertyOptional() @IsOptional() @Type(() => PrettyVc) - prettyVc?: PrettyVc; + prettyVc?: PrettyVc @ApiProperty() @IsString({ message: 'expiration date should be string' }) @IsNotEmpty({ message: 'expiration date is required' }) @Type(() => String) @IsOptional() - expirationDate?: string; + expirationDate?: string @ApiProperty() @IsNotEmpty({ message: ' credential subject required' }) credentialSubject: SingleOrArray; - [key: string]: unknown; + [key: string]: unknown } export class JsonLdCredentialDetailCredentialStatus { public constructor(options: JsonLdCredentialDetailCredentialStatusOptions) { if (options) { - this.type = options.type; + this.type = options.type } } @IsString() - public type!: string; + public type!: string } export class JsonLdCredentialDetailOptions { public constructor(options: JsonLdCredentialDetailOptionsOptions) { if (options) { - this.proofPurpose = options.proofPurpose; - this.created = options.created; - this.domain = options.domain; - this.challenge = options.challenge; - this.credentialStatus = options.credentialStatus; - this.proofType = options.proofType; + this.proofPurpose = options.proofPurpose + this.created = options.created + this.domain = options.domain + this.challenge = options.challenge + this.credentialStatus = options.credentialStatus + this.proofType = options.proofType } } @IsString() @IsNotEmpty({ message: 'proof purpose is required' }) - public proofPurpose!: string; + public proofPurpose!: string @IsString() @IsOptional() - public created?: string; + public created?: string @IsString() @IsOptional() - public domain?: string; + public domain?: string @IsString() @IsOptional() - public challenge?: string; + public challenge?: string @IsString() @IsNotEmpty({ message: 'proof type is required' }) - public proofType!: string; + public proofType!: string @IsOptional() @IsObject() - public credentialStatus?: JsonLdCredentialDetailCredentialStatus; + public credentialStatus?: JsonLdCredentialDetailCredentialStatus } export class Attribute { @ApiProperty() @@ -166,17 +166,17 @@ export class Attribute { @IsNotEmpty({ message: 'Attribute name is required' }) @Transform(({ value }) => trim(value)) @Type(() => String) - name: string; + name: string @ApiProperty() @IsDefined() @Transform(({ value }) => trim(value)) - value: string; + value: string @ApiProperty({ default: false }) @IsBoolean() @IsOptional() - isRequired?: boolean = false; + isRequired?: boolean = false } export class CredentialsIssuanceDto { @ApiProperty({ example: 'string' }) @@ -184,74 +184,74 @@ export class CredentialsIssuanceDto { @IsString({ message: 'Credential definition id should be string' }) @Transform(({ value }) => value.trim()) @IsOptional() - credentialDefinitionId?: string; + credentialDefinitionId?: string @ApiProperty({ example: 'string' }) @IsNotEmpty({ message: 'Please provide valid comment' }) @IsString({ message: 'comment should be string' }) @IsOptional() - comment: string; + comment: string @ApiPropertyOptional({ example: 'v1' }) @IsOptional() @IsNotEmpty({ message: 'Please provide valid protocol version' }) @IsString({ message: 'protocol version should be string' }) - protocolVersion?: string; + protocolVersion?: string @ApiPropertyOptional() @IsOptional() @IsNotEmpty({ message: 'Please provide valid goal code' }) @IsString({ message: 'goal code should be string' }) - goalCode?: string; + goalCode?: string @ApiPropertyOptional() @IsOptional() @IsNotEmpty({ message: 'Please provide valid parent thread id' }) @IsString({ message: 'parent thread id should be string' }) - parentThreadId?: string; + parentThreadId?: string @ApiPropertyOptional() @IsOptional() @IsNotEmpty({ message: 'Please provide valid willConfirm' }) @IsBoolean({ message: 'willConfirm should be boolean' }) - willConfirm?: boolean; + willConfirm?: boolean @ApiPropertyOptional() @IsOptional() @IsNotEmpty({ message: 'Please provide valid label' }) @IsString({ message: 'label should be string' }) - label?: string; + label?: string @ApiPropertyOptional() @IsOptional() @IsNotEmpty({ message: 'please provide valid imageUrl' }) @IsString({ message: 'imageUrl must be a string' }) - imageUrl?: string; + imageUrl?: string @ApiPropertyOptional() @IsOptional() @IsString({ message: 'auto accept proof must be in string' }) @IsNotEmpty({ message: 'please provide valid auto accept proof' }) @IsEnum(AutoAccept, { - message: `Invalid auto accept credential. It should be one of: ${Object.values(AutoAccept).join(', ')}` + message: `Invalid auto accept credential. It should be one of: ${Object.values(AutoAccept).join(', ')}`, }) - autoAcceptCredential?: string; + autoAcceptCredential?: string @ApiProperty({ example: 'jsonld' }) @IsNotEmpty({ message: 'Please provide credential type ' }) @Transform(({ value }) => trim(value).toLocaleLowerCase()) @IsOptional() - credentialType: IssueCredentialType; + credentialType: IssueCredentialType @ApiPropertyOptional({ default: true }) @IsOptional() @IsNotEmpty({ message: 'please provide valid value for reuseConnection' }) @IsBoolean({ message: 'reuseConnection must be a boolean' }) - reuseConnection?: boolean; + reuseConnection?: boolean - orgId: string; + orgId: string - isValidateSchema?: boolean; + isValidateSchema?: boolean } export class OOBIssueCredentialDto extends CredentialsIssuanceDto { @@ -259,9 +259,9 @@ export class OOBIssueCredentialDto extends CredentialsIssuanceDto { example: [ { value: 'string', - name: 'string' - } - ] + name: 'string', + }, + ], }) @IsArray() @ValidateNested({ each: true }) @@ -269,15 +269,15 @@ export class OOBIssueCredentialDto extends CredentialsIssuanceDto { @IsOptional() @IsNotEmpty({ message: 'Please provide valid attributes' }) @Type(() => Attribute) - attributes?: Attribute[]; + attributes?: Attribute[] @ApiProperty({ - example: false + example: false, }) @IsOptional() @IsNotEmpty() @IsBoolean({ message: 'isShortenUrl must be boolean' }) - isShortenUrl?: boolean; + isShortenUrl?: boolean @ApiProperty() @IsNotEmpty({ message: 'Please provide valid credential' }) @@ -285,7 +285,7 @@ export class OOBIssueCredentialDto extends CredentialsIssuanceDto { @Type(() => Credential) @IsOptional() @ValidateNested({ each: true }) - credential?: Credential; + credential?: Credential @ApiProperty() @IsOptional() @@ -293,7 +293,7 @@ export class OOBIssueCredentialDto extends CredentialsIssuanceDto { @IsObject({ message: 'options should be an object' }) @ValidateNested({ each: true }) @Type(() => JsonLdCredentialDetailOptions) - options?: JsonLdCredentialDetailOptions; + options?: JsonLdCredentialDetailOptions } class CredentialOffer { @@ -303,7 +303,7 @@ class CredentialOffer { @ValidateNested({ each: true }) @Type(() => Attribute) @IsOptional() - attributes?: Attribute[]; + attributes?: Attribute[] @ApiProperty({ example: 'testmail@xyz.com' }) @IsEmail({}, { message: 'Please provide a valid email' }) @@ -312,14 +312,14 @@ class CredentialOffer { @MaxLength(256, { message: 'Email must be at most 256 character' }) @Transform(({ value }) => trim(value)) @Type(() => String) - emailId: string; + emailId: string @IsNotEmpty({ message: 'Please provide valid credential' }) @IsObject({ message: 'credential should be an object' }) @Type(() => Credential) @IsOptional() @ValidateNested({ each: true }) - credential?: Credential; + credential?: Credential @ApiProperty() @IsOptional() @@ -327,95 +327,95 @@ class CredentialOffer { @IsObject({ message: 'options should be an object' }) @ValidateNested({ each: true }) @Type(() => JsonLdCredentialDetailOptions) - options?: JsonLdCredentialDetailOptions; + options?: JsonLdCredentialDetailOptions } export class IssuanceDto { @ApiProperty() @IsOptional() - _tags?: object; + _tags?: object @ApiProperty() @IsOptional() - metadata?: object; + metadata?: object @ApiProperty() @IsOptional() - credentials: object[]; + credentials: object[] @ApiProperty() @IsOptional() - id: string; + id: string @ApiProperty() @IsOptional() - createdAt: string; + createdAt: string @ApiProperty() @IsOptional() - state: string; + state: string @ApiProperty() @IsOptional() - connectionId: string; + connectionId: string @ApiProperty() @IsOptional() - protocolVersion: string; + protocolVersion: string @ApiProperty() @IsOptional() - threadId: string; + threadId: string @ApiProperty() @IsOptional() - schemaId: string; + schemaId: string @ApiProperty() @IsOptional() - credDefId: string; + credDefId: string @ApiProperty() @IsOptional() - credentialAttributes: CredentialAttributes[]; + credentialAttributes: CredentialAttributes[] @ApiProperty() @IsOptional() - autoAcceptCredential: string; + autoAcceptCredential: string @ApiProperty() @IsOptional() - contextCorrelationId: string; + contextCorrelationId: string @ApiPropertyOptional() @IsOptional() - type: string; + type: string @ApiProperty() @IsOptional() - outOfBandId: string | null; + outOfBandId: string | null @ApiProperty() @IsOptional() - credentialData: object; + credentialData: object @ApiProperty() @IsOptional() - orgId: string; + orgId: string } export class CredentialAttributes { @ApiProperty() @IsOptional() - 'mime-type'?: string; + 'mime-type'?: string @ApiProperty() @IsOptional() - name?: string; + name?: string @ApiProperty() @IsOptional() - value: string; + value: string } export class OOBCredentialDtoWithEmail { @@ -427,137 +427,137 @@ export class OOBCredentialDtoWithEmail { '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1'], type: ['VerifiableCredential', 'UniversityDegreeCredential'], issuer: { - id: 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM' + id: 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM', }, issuanceDate: '2019-10-12T07:20:50.52Z', credentialSubject: { id: 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM', degree: { type: 'BachelorDegree', - name: 'Bachelor of Science and Arts' - } - } + name: 'Bachelor of Science and Arts', + }, + }, }, options: { proofType: 'Ed25519Signature2018', - proofPurpose: 'assertionMethod' - } - } - ] + proofPurpose: 'assertionMethod', + }, + }, + ], }) @IsNotEmpty({ message: 'Please provide valid attributes' }) @IsArray({ message: 'attributes should be array' }) @ArrayMaxSize(Number(process.env.OOB_BATCH_SIZE), { - message: `Limit reached (${process.env.OOB_BATCH_SIZE} credentials max). Easily handle larger batches via seamless CSV file uploads` + message: `Limit reached (${process.env.OOB_BATCH_SIZE} credentials max). Easily handle larger batches via seamless CSV file uploads`, }) @ValidateNested({ each: true }) @Type(() => CredentialOffer) - credentialOffer: CredentialOffer[]; + credentialOffer: CredentialOffer[] @ApiProperty({ example: 'string' }) @IsNotEmpty({ message: 'Please provide valid credential definition id' }) @IsString({ message: 'credential definition id should be string' }) @IsOptional() @Transform(({ value }) => value.trim()) - credentialDefinitionId?: string; + credentialDefinitionId?: string @ApiProperty({ example: 'string' }) @IsOptional() @IsNotEmpty({ message: 'Please provide valid comment' }) @IsString({ message: 'comment should be string' }) - comment?: string; + comment?: string @ApiProperty({ example: 'v1' }) @IsOptional() @IsNotEmpty({ message: 'Please provide valid protocol version' }) @IsString({ message: 'protocol version should be string' }) - protocolVersion?: string; + protocolVersion?: string @ApiProperty({ example: 'jsonld' }) @IsNotEmpty({ message: 'Please provide credential type ' }) @Transform(({ value }) => trim(value).toLocaleLowerCase()) @IsOptional() - credentialType: IssueCredentialType; + credentialType: IssueCredentialType @ApiPropertyOptional({ default: true }) @IsOptional() @IsNotEmpty({ message: 'please provide valid value for isReuseConnection' }) @IsBoolean({ message: 'isReuseConnection must be a boolean' }) - isReuseConnection?: boolean; + isReuseConnection?: boolean - imageUrl?: string; + imageUrl?: string - isValidateSchema?: boolean; + isValidateSchema?: boolean - orgId: string; + orgId: string } export class PreviewFileDetails { @ApiProperty({ required: false, example: '1' }) @IsOptional() - pageNumber: number = 1; + pageNumber = 1 @ApiProperty({ required: false, example: '10' }) @IsOptional() - pageSize: number = 10; + pageSize = 10 @ApiProperty({ required: false }) @IsOptional() @Transform(({ value }) => trim(value)) @Type(() => String) - searchByText: string = ''; + searchByText = '' } export class FileParameter { @ApiProperty({ required: false, example: '10' }) @IsOptional() - pageSize: number = 10; + pageSize = 10 @ApiProperty({ required: false, example: '1' }) @IsOptional() - pageNumber: number = 1; + pageNumber = 1 @ApiProperty({ - required: false + required: false, }) @Transform(({ value }) => trim(value)) @IsOptional() @IsEnum(SortFields) - sortField: string = SortFields.CREATED_DATE_TIME; + sortField: string = SortFields.CREATED_DATE_TIME @ApiProperty({ enum: [SortValue.DESC, SortValue.ASC], - required: false + required: false, }) @Transform(({ value }) => trim(value)) @IsOptional() @IsEnum(SortValue) - sortBy: string = SortValue.DESC; + sortBy: string = SortValue.DESC @ApiProperty({ required: false }) @IsOptional() @Transform(({ value }) => trim(value)) @Type(() => String) - searchByText: string = ''; + searchByText = '' } export class ClientDetails { @ApiProperty({ required: false, example: '68y647ayAv79879' }) @IsOptional() @Type(() => String) - clientId = ''; + clientId = '' @ApiProperty({ required: false, example: 'issue-data.csv' }) @IsOptional() @Type(() => String) - fileName = ''; + fileName = '' @ApiProperty({ required: false }) @IsOptional() @Type(() => Boolean) - isSelectiveIssuance?: boolean = false; + isSelectiveIssuance?: boolean = false - userId?: string; + userId?: string @ApiPropertyOptional({ example: 'https://example.com/logo.png' }) @Transform(({ value }) => trim(value)) @@ -567,47 +567,47 @@ export class ClientDetails { // eslint-disable-next-line camelcase require_protocol: true, // eslint-disable-next-line camelcase - require_tld: true + require_tld: true, }, { message: 'brandLogoUrl should be a valid URL' } ) - organizationLogoUrl?: string; + organizationLogoUrl?: string @ApiPropertyOptional({ example: 'MyPlatform' }) @Transform(({ value }) => trim(value)) @IsOptional() @IsString({ message: 'platformName should be string' }) - platformName?: string; + platformName?: string @ApiPropertyOptional() @Transform(({ value }) => trim(value)) @IsOptional() @IsString({ message: 'Certificate should be string' }) - certificate?: string; + certificate?: string @ApiPropertyOptional({ example: 'a4' }) @Transform(({ value }) => trim(value)) @IsOptional() @IsString({ message: 'Size should be string' }) - size?: string; + size?: string @ApiPropertyOptional({ example: 'landscape' }) @Transform(({ value }) => trim(value)) @IsOptional() @IsString({ message: 'Orientation should be string' }) - orientation?: string; + orientation?: string @ApiPropertyOptional({ example: '60px' }) @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'height must be in string format.' }) - height?: string; + height?: string @ApiPropertyOptional({ example: '60px' }) @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'width must be in string format.' }) - width?: string; + width?: string } export class TemplateDetails { @@ -616,18 +616,18 @@ export class TemplateDetails { @IsString({ message: 'templateId should be string' }) @IsNotEmpty({ message: 'Template Id is required' }) @Transform(({ value }) => trim(value)) - templateId: string = ''; + templateId = '' @ApiProperty({ enum: SchemaType, required: true }) @IsEnum(SchemaType, { message: 'Schema type should be a valid' }) - schemaType: SchemaType; + schemaType: SchemaType } export class FileUploadDetails extends TemplateDetails { @ApiProperty({ required: false, example: 'CSV file' }) @IsOptional() @IsString({ message: 'fileName should be string' }) - fileName: string; + fileName: string } export class CredentialQuery { @@ -636,7 +636,7 @@ export class CredentialQuery { @IsString({ message: 'Cred def Id should be string' }) @IsNotEmpty({ message: 'Cred def Id is required' }) @Transform(({ value }) => trim(value)) - credDefId?: string; + credDefId?: string } export class TemplateQuery { @@ -644,7 +644,7 @@ export class TemplateQuery { @IsString({ message: 'templateId should be string' }) @IsNotEmpty({ message: 'Template Id is required' }) @Transform(({ value }) => trim(value)) - templateId: string; + templateId: string } export class FileQuery { @ApiProperty({ required: true }) @@ -652,7 +652,7 @@ export class FileQuery { @IsNotEmpty({ message: 'fileId Id is required' }) @IsUUID('4', { message: 'Invalid format for file Id' }) @Transform(({ value }) => trim(value)) - fileId: string; + fileId: string } export class RequestIdQuery { @@ -660,5 +660,5 @@ export class RequestIdQuery { @IsString({ message: 'requestId should be string' }) @IsNotEmpty({ message: 'requestId Id is required' }) @Transform(({ value }) => trim(value)) - requestId: string; + requestId: string } diff --git a/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts b/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts index 23a4f56f0..b7e965fae 100644 --- a/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts +++ b/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts @@ -1,114 +1,118 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { ArrayMaxSize, ArrayMinSize, IsArray, IsBoolean, IsEnum, IsNotEmpty, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator'; -import { Transform, Type } from 'class-transformer'; -import { AutoAccept } from '@credebl/enum/enum'; -import { trim } from '@credebl/common/cast.helper'; -import { Attribute, Credential, CredentialsIssuanceDto, JsonLdCredentialDetailOptions } from './issuance.dto'; +import { trim } from '@credebl/common/cast.helper' +import { AutoAccept } from '@credebl/enum/enum' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform, Type } from 'class-transformer' +import { + ArrayMaxSize, + ArrayMinSize, + IsArray, + IsBoolean, + IsEnum, + IsNotEmpty, + IsObject, + IsOptional, + IsString, + ValidateNested, +} from 'class-validator' +import { Attribute, Credential, CredentialsIssuanceDto, JsonLdCredentialDetailOptions } from './issuance.dto' class ConnectionAttributes { - @ApiProperty({ example: 'string' }) - @IsNotEmpty({ message: 'connectionId is required' }) - @IsString({ message: 'connectionId should be string' }) - @Transform(({ value }) => trim(value)) - connectionId: string; + @ApiProperty({ example: 'string' }) + @IsNotEmpty({ message: 'connectionId is required' }) + @IsString({ message: 'connectionId should be string' }) + @Transform(({ value }) => trim(value)) + connectionId: string - @ApiProperty({ - example: [ - { - value: 'string', - name: 'string' - } - ] - }) - @IsArray() - @ValidateNested({ each: true }) - @ArrayMinSize(1) - @IsNotEmpty({ message: 'Please provide valid attributes' }) - @Type(() => Attribute) - @IsOptional() - attributes?: Attribute[]; + @ApiProperty({ + example: [ + { + value: 'string', + name: 'string', + }, + ], + }) + @IsArray() + @ValidateNested({ each: true }) + @ArrayMinSize(1) + @IsNotEmpty({ message: 'Please provide valid attributes' }) + @Type(() => Attribute) + @IsOptional() + attributes?: Attribute[] - @ApiProperty() - @IsNotEmpty({ message: 'Please provide valid credential' }) - @IsObject({ message: 'credential should be an object' }) - @Type(() => Credential) - @IsOptional() - @ValidateNested({ each: true }) - credential?: Credential; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid credential' }) + @IsObject({ message: 'credential should be an object' }) + @Type(() => Credential) + @IsOptional() + @ValidateNested({ each: true }) + credential?: Credential - @ApiProperty() - @IsNotEmpty({ message: 'Please provide valid options' }) - @IsObject({ message: 'options should be an object' }) - @Type(() => JsonLdCredentialDetailOptions) - @IsOptional() - @ValidateNested({ each: true }) - options?:JsonLdCredentialDetailOptions; + @ApiProperty() + @IsNotEmpty({ message: 'Please provide valid options' }) + @IsObject({ message: 'options should be an object' }) + @Type(() => JsonLdCredentialDetailOptions) + @IsOptional() + @ValidateNested({ each: true }) + options?: JsonLdCredentialDetailOptions } export class IssueCredentialDto extends CredentialsIssuanceDto { - @ApiProperty({ - example: [ + @ApiProperty({ + example: [ + { + connectionId: 'string', + attributes: [ { - 'connectionId': 'string', - 'attributes': [ - { - 'value': 'string', - 'name': 'string' - } - ], - 'credential': { - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - 'https://www.w3.org/2018/credentials/examples/v1' - ], - 'type': [ - 'VerifiableCredential', - 'UniversityDegreeCredential' - ], - 'issuer': { - 'id': 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM' - }, - 'issuanceDate': '2019-10-12T07:20:50.52Z', - 'credentialSubject': { - 'id': 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM', - 'degree': { - 'type': 'BachelorDegree', - 'name': 'Bachelor of Science and Arts' - } - } - }, - 'options': { - 'proofType': 'Ed25519Signature2018', - 'proofPurpose': 'assertionMethod' - } - - } - ] - - }) - @IsArray() - @ValidateNested({ each: true }) - @ArrayMinSize(1) - @ArrayMaxSize(Number(process.env.OOB_BATCH_SIZE), { message: `Limit reached (${process.env.OOB_BATCH_SIZE} connections max).` }) - @IsNotEmpty({ message: 'credentialData is required' }) - @Type(() => ConnectionAttributes) - credentialData: ConnectionAttributes[]; + value: 'string', + name: 'string', + }, + ], + credential: { + '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1'], + type: ['VerifiableCredential', 'UniversityDegreeCredential'], + issuer: { + id: 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM', + }, + issuanceDate: '2019-10-12T07:20:50.52Z', + credentialSubject: { + id: 'did:key:z6Mkn72LVp3mq1fWSefkSMh5V7qrmGfCV4KH3K6SoTM21ouM', + degree: { + type: 'BachelorDegree', + name: 'Bachelor of Science and Arts', + }, + }, + }, + options: { + proofType: 'Ed25519Signature2018', + proofPurpose: 'assertionMethod', + }, + }, + ], + }) + @IsArray() + @ValidateNested({ each: true }) + @ArrayMinSize(1) + @ArrayMaxSize(Number(process.env.OOB_BATCH_SIZE), { + message: `Limit reached (${process.env.OOB_BATCH_SIZE} connections max).`, + }) + @IsNotEmpty({ message: 'credentialData is required' }) + @Type(() => ConnectionAttributes) + credentialData: ConnectionAttributes[] - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'auto accept proof must be in string' }) - @IsNotEmpty({ message: 'please provide valid auto accept proof' }) - @IsEnum(AutoAccept, { - message: `Invalid auto accept credential. It should be one of: ${Object.values(AutoAccept).join(', ')}` - }) - autoAcceptCredential?: string; + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'auto accept proof must be in string' }) + @IsNotEmpty({ message: 'please provide valid auto accept proof' }) + @IsEnum(AutoAccept, { + message: `Invalid auto accept credential. It should be one of: ${Object.values(AutoAccept).join(', ')}`, + }) + autoAcceptCredential?: string - @ApiProperty({ - example: false - }) - @IsOptional() - @IsNotEmpty() - @IsBoolean({message: 'isShortenUrl must be boolean'}) - isShortenUrl?: boolean; - + @ApiProperty({ + example: false, + }) + @IsOptional() + @IsNotEmpty() + @IsBoolean({ message: 'isShortenUrl must be boolean' }) + isShortenUrl?: boolean } diff --git a/apps/api-gateway/src/issuance/interfaces/index.ts b/apps/api-gateway/src/issuance/interfaces/index.ts index 06d30d3ff..2e27e5f4c 100644 --- a/apps/api-gateway/src/issuance/interfaces/index.ts +++ b/apps/api-gateway/src/issuance/interfaces/index.ts @@ -1,119 +1,118 @@ -import { SchemaType } from '@credebl/enum/enum'; -import { JsonLdCredentialDetailCredentialStatus } from '../dtos/issuance.dto'; -import { JsonValue } from '../utils/helper'; +import type { SchemaType } from '@credebl/enum/enum' +import type { JsonLdCredentialDetailCredentialStatus } from '../dtos/issuance.dto' +import type { JsonValue } from '../utils/helper' export interface IUserRequestInterface { - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: IUserRoleOrgPerms[]; - orgName?: string; - selectedOrg: ISelectedOrg; + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: IUserRoleOrgPerms[] + orgName?: string + selectedOrg: ISelectedOrg } export interface ISelectedOrg { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: object; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: object } export interface IOrganization { - name: string; - description: string; - org_agents: IOrgAgent[] - + name: string + description: string + org_agents: IOrgAgent[] } export interface IOrgAgent { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } export class IUserRoleOrgPerms { - id: number; - role: IUserRole; - Organization: IUserOrg; + id: number + role: IUserRole + Organization: IUserOrg } export class IUserRole { - id: number; - name: string; - permissions: string[]; - + id: number + name: string + permissions: string[] } export class IUserOrg { - id: number; - orgName: string; + id: number + orgName: string } export interface FileExportResponse { - response: unknown; - fileContent: string; - fileName: string + response: unknown + fileContent: string + fileName: string } export interface UploadedFileDetails { - templateId: string; - fileKey: string; - fileName: string; - type: SchemaType; - isValidateSchema?: boolean; + templateId: string + fileKey: string + fileName: string + type: SchemaType + isValidateSchema?: boolean } export interface IIssuedCredentialSearchParams { - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - search: string; + pageNumber: number + pageSize: number + sortField: string + sortBy: string + search: string } export enum IssueCredentialType { - JSONLD = 'jsonld', - INDY = 'indy' + JSONLD = 'jsonld', + INDY = 'indy', } export interface JsonObject { - [property: string]: JsonValue - } + [property: string]: JsonValue +} - export interface JsonLdCredentialDetailCredentialStatusOptions { - type: string - } +export interface JsonLdCredentialDetailCredentialStatusOptions { + type: string +} - export interface JsonLdCredentialDetailOptionsOptions { - proofPurpose: string - created?: string - domain?: string - challenge?: string - credentialStatus?: JsonLdCredentialDetailCredentialStatus - proofType: string - } +export interface JsonLdCredentialDetailOptionsOptions { + proofPurpose: string + created?: string + domain?: string + challenge?: string + credentialStatus?: JsonLdCredentialDetailCredentialStatus + proofType: string +} - export interface ITemplateFormat { - credentialDefinitionId: string; - schemaCredDefName: string; - schemaName: string; - schemaVersion: string; - schemaAttributes: string; - credentialDefinition: string; - } +export interface ITemplateFormat { + credentialDefinitionId: string + schemaCredDefName: string + schemaName: string + schemaVersion: string + schemaAttributes: string + credentialDefinition: string +} - export interface IReqPayload { - credDefId: string; - fileKey: string | null; - fileName: string; - } \ No newline at end of file +export interface IReqPayload { + templateId: string + fileKey: string | null + fileName: string + type: string +} diff --git a/apps/api-gateway/src/issuance/issuance.controller.ts b/apps/api-gateway/src/issuance/issuance.controller.ts index 61eadf5a2..36fc2bfb8 100644 --- a/apps/api-gateway/src/issuance/issuance.controller.ts +++ b/apps/api-gateway/src/issuance/issuance.controller.ts @@ -1,49 +1,67 @@ +import type { AwsService } from '@credebl/aws' +import { TrimStringParamPipe } from '@credebl/common/cast.helper' +import type IResponseType from '@credebl/common/interfaces/response.interface' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { SchemaType } from '@credebl/enum/enum' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' /* eslint-disable default-param-last */ /* eslint-disable no-param-reassign */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable camelcase */ import { - Controller, - Post, + BadRequestException, Body, - UseGuards, - HttpStatus, - Res, - Query, + Controller, + Delete, Get, - Param, - UseFilters, Header, - UploadedFile, - UseInterceptors, + HttpStatus, Logger, - BadRequestException, NotFoundException, + Param, ParseUUIDPipe, - Delete, - ValidationPipe -} from '@nestjs/common'; + Post, + Query, + Res, + UploadedFile, + UseFilters, + UseGuards, + UseInterceptors, + ValidationPipe, +} from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' +import { AuthGuard } from '@nestjs/passport' +import { FileInterceptor } from '@nestjs/platform-express' import { - ApiTags, - ApiOperation, - ApiResponse, ApiBearerAuth, + ApiBody, + ApiConsumes, + ApiExcludeEndpoint, ApiForbiddenResponse, - ApiUnauthorizedResponse, + ApiNotFoundResponse, + ApiOperation, ApiQuery, - ApiExcludeEndpoint, - ApiConsumes, - ApiBody, - ApiNotFoundResponse -} from '@nestjs/swagger'; -import { AuthGuard } from '@nestjs/passport'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { Response } from 'express'; -import IResponseType, { IResponse } from '@credebl/common/interfaces/response.interface'; -import { IssuanceService } from './issuance.service'; -import { + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +/* eslint-disable @typescript-eslint/no-unused-vars */ +import type { user } from '@prisma/client' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { v4 as uuidv4 } from 'uuid' +import { CommonConstants } from '../../../../libs/common/src/common.constant' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { NotFoundErrorDto } from '../dtos/not-found-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { IGetAllIssuedCredentialsDto } from './dtos/get-all-issued-credentials.dto' +import type { ClientDetails, CredentialQuery, FileParameter, @@ -54,33 +72,17 @@ import { PreviewFileDetails, RequestIdQuery, TemplateDetails, - TemplateQuery -} from './dtos/issuance.dto'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { User } from '../authz/decorators/user.decorator'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; + TemplateQuery, +} from './dtos/issuance.dto' +import type { IssueCredentialDto } from './dtos/multi-connection.dto' import { - FileExportResponse, - IIssuedCredentialSearchParams, + type FileExportResponse, + type IIssuedCredentialSearchParams, + IReqPayload, IssueCredentialType, - UploadedFileDetails -} 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 { IGetAllIssuedCredentialsDto } from './dtos/get-all-issued-credentials.dto'; -import { IssueCredentialDto } from './dtos/multi-connection.dto'; -import { SchemaType } from '@credebl/enum/enum'; -import { CommonConstants } from '../../../../libs/common/src/common.constant'; -import { TrimStringParamPipe } from '@credebl/common/cast.helper'; -import { NotFoundErrorDto } from '../dtos/not-found-error.dto'; + type UploadedFileDetails, +} from './interfaces' +import type { IssuanceService } from './issuance.service' @Controller() @UseFilters(CustomExceptionFilter) @ApiTags('credentials') @@ -91,7 +93,7 @@ export class IssuanceController { private readonly issueCredentialService: IssuanceService, private readonly awsService: AwsService ) {} - private readonly logger = new Logger('IssuanceController'); + private readonly logger = new Logger('IssuanceController') /** * Get all issued credentials for a specific organization @@ -106,23 +108,23 @@ export class IssuanceController { @UseGuards(AuthGuard('jwt')) @ApiBearerAuth() @ApiOperation({ - summary: `Get all issued credentials for a specific organization`, - description: `Retrieve all issued credentials for a specific organization. Supports pagination and search.` + summary: 'Get all issued credentials for a specific organization', + description: 'Retrieve all issued credentials for a specific organization. Supports pagination and search.', }) @ApiQuery({ name: 'pageNumber', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'pageSize', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'search', type: String, - required: false + required: false, }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiBearerAuth() @@ -134,27 +136,27 @@ export class IssuanceController { @Param('orgId') orgId: string, @Res() res: Response ): Promise { - const { pageSize, search, pageNumber, sortField, sortBy } = getAllIssuedCredentials; + const { pageSize, search, pageNumber, sortField, sortBy } = getAllIssuedCredentials const issuedCredentialsSearchCriteria: IIssuedCredentialSearchParams = { pageNumber, search, pageSize, sortField, - sortBy - }; + sortBy, + } const getCredentialDetails = await this.issueCredentialService.getIssueCredentials( issuedCredentialsSearchCriteria, user, orgId - ); + ) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.issuance.success.fetch, - data: getCredentialDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getCredentialDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -169,8 +171,8 @@ export class IssuanceController { @Get('/orgs/:orgId/credentials/:credentialRecordId') @ApiBearerAuth() @ApiOperation({ - summary: `Fetch credentials by credentialRecordId`, - description: `Retrieve the details of a specific credential by its credentialRecordId.` + summary: 'Fetch credentials by credentialRecordId', + description: 'Retrieve the details of a specific credential by its credentialRecordId.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -182,8 +184,8 @@ export class IssuanceController { TrimStringParamPipe, new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.issuance.error.invalidCredentialRecordId); - } + throw new BadRequestException(ResponseMessages.issuance.error.invalidCredentialRecordId) + }, }) ) credentialRecordId: string, @@ -194,14 +196,14 @@ export class IssuanceController { user, credentialRecordId, orgId - ); + ) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.issuance.success.fetch, - data: getCredentialDetails.response - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getCredentialDetails.response, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -214,11 +216,11 @@ export class IssuanceController { @Get('/orgs/:orgId/credentials/bulk/template') @ApiOperation({ summary: 'Fetch all templates for bulk operation', - description: 'Retrieve all templates for a specific organization for bulk operation.' + description: 'Retrieve all templates for a specific organization for bulk operation.', }) @ApiQuery({ name: 'schemaType', - enum: SchemaType + enum: SchemaType, }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiBearerAuth() @@ -229,21 +231,21 @@ export class IssuanceController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @Res() res: Response, @Query('schemaType') schemaType: SchemaType = SchemaType.INDY ): Promise { - const templateList = await this.issueCredentialService.getAllCredentialTemplates(orgId, schemaType); + const templateList = await this.issueCredentialService.getAllCredentialTemplates(orgId, schemaType) const credDefResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.credentialDefinition.success.template, - data: templateList - }; - return res.status(HttpStatus.OK).json(credDefResponse); + data: templateList, + } + return res.status(HttpStatus.OK).json(credDefResponse) } /** @@ -265,15 +267,15 @@ export class IssuanceController { @Header('Content-Type', 'application/csv') @ApiOperation({ summary: 'Download csv template for bulk-issuance', - description: 'Download csv template for a specific organization bulk-issuance using template details.' + description: 'Download csv template for a specific organization bulk-issuance using template details.', }) async downloadBulkIssuanceCSVTemplate( @Param( 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @@ -284,17 +286,17 @@ export class IssuanceController { const templateData: FileExportResponse = await this.issueCredentialService.downloadBulkIssuanceCSVTemplate( orgId, templateDetails - ); + ) return res .header('Content-Disposition', `attachment; filename="${templateData.fileName}"`) .status(HttpStatus.OK) - .send(templateData.fileContent); + .send(templateData.fileContent) } catch (error) { return res .status(error.statusCode || HttpStatus.INTERNAL_SERVER_ERROR) .header('Content-Type', 'application/json') .header('Content-Disposition', '') - .send(error); + .send(error) } } /** @@ -312,18 +314,18 @@ export class IssuanceController { @ApiBearerAuth() @ApiOperation({ summary: 'Upload file for bulk issuance', - description: 'Upload a filled CSV file for bulk issuance.' + description: 'Upload a filled CSV file for bulk issuance.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', - type: UnauthorizedErrorDto + type: UnauthorizedErrorDto, }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', - type: ForbiddenErrorDto + type: ForbiddenErrorDto, }) @ApiConsumes('multipart/form-data') @ApiBody({ @@ -334,22 +336,22 @@ export class IssuanceController { properties: { file: { type: 'string', - format: 'binary' - } - } + format: 'binary', + }, + }, }, - required: true + required: true, }) @ApiQuery({ name: 'schemaType', enum: SchemaType, required: true, - description: 'The type of schema to be used' + description: 'The type of schema to be used', }) @ApiQuery({ name: 'isValidateSchema', type: Boolean, - required: false + required: false, }) @UseInterceptors(FileInterceptor('file')) async uploadCSVTemplate( @@ -357,43 +359,45 @@ export class IssuanceController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @Query(new ValidationPipe({ transform: true })) query: TemplateQuery, @UploadedFile() file: Express.Multer.File, + // TODO: Add type @Body() fileDetails: object, @Res() res: Response, @Query('schemaType') schemaType: SchemaType = SchemaType.INDY, - @Query('isValidateSchema') isValidateSchema: boolean = true + @Query('isValidateSchema') isValidateSchema = true ): Promise { - const { templateId } = query; + const { templateId } = query if (file) { - const fileKey: string = uuidv4(); + const fileKey: string = uuidv4() try { - await this.awsService.uploadCsvFile(fileKey, file?.buffer); + await this.awsService.uploadCsvFile(fileKey, file?.buffer) } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } const uploadedfileDetails: UploadedFileDetails = { type: schemaType, templateId, fileKey, + // biome-ignore lint/complexity/useLiteralKeys: fileName: fileDetails['fileName'] || file?.filename || file?.originalname, - isValidateSchema - }; + isValidateSchema, + } - const importCsvDetails = await this.issueCredentialService.uploadCSVTemplate(uploadedfileDetails, orgId); + const importCsvDetails = await this.issueCredentialService.uploadCSVTemplate(uploadedfileDetails, orgId) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.importCSV, - data: importCsvDetails.response - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: importCsvDetails.response, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } } /** @@ -412,32 +416,32 @@ export class IssuanceController { @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', - type: UnauthorizedErrorDto + type: UnauthorizedErrorDto, }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', - type: ForbiddenErrorDto + type: ForbiddenErrorDto, }) @ApiOperation({ summary: 'Preview uploaded file details', - description: 'Preview uploaded CSV file details for bulk issuance.' + description: 'Preview uploaded CSV file details for bulk issuance.', }) @ApiQuery({ name: 'pageNumber', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'searchByText', type: String, - required: false + required: false, }) @ApiQuery({ name: 'pageSize', type: Number, - required: false + required: false, }) async previewFileDataForIssuance( @Param('orgId') orgId: string, @@ -445,14 +449,14 @@ export class IssuanceController { @Query() previewFileDetails: PreviewFileDetails, @Res() res: Response ): Promise { - const { requestId } = query; - const previewCSVDetails = await this.issueCredentialService.previewCSVDetails(requestId, orgId, previewFileDetails); + const { requestId } = query + const previewCSVDetails = await this.issueCredentialService.previewCSVDetails(requestId, orgId, previewFileDetails) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.issuance.success.previewCSV, - data: previewCSVDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: previewCSVDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -474,21 +478,21 @@ export class IssuanceController { @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', - type: UnauthorizedErrorDto + type: UnauthorizedErrorDto, }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', - type: ForbiddenErrorDto + type: ForbiddenErrorDto, }) @ApiOperation({ summary: 'bulk issue credential', - description: 'Start bulk-issuance process for a specific requestId.' + description: 'Start bulk-issuance process for a specific requestId.', }) @ApiQuery({ name: 'isValidateSchema', type: Boolean, - required: false + required: false, }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiConsumes('multipart/form-data') @@ -500,15 +504,15 @@ export class IssuanceController { properties: { file: { type: 'string', - format: 'binary' - } - } + format: 'binary', + }, + }, }, - required: true + required: true, }) @UseInterceptors( FileInterceptor('file', { - limits: { fieldSize: Number(process.env.FIELD_UPLOAD_SIZE) || CommonConstants.DEFAULT_FIELD_UPLOAD_SIZE } + limits: { fieldSize: Number(process.env.FIELD_UPLOAD_SIZE) || CommonConstants.DEFAULT_FIELD_UPLOAD_SIZE }, }) ) async issueBulkCredentials( @@ -517,29 +521,31 @@ export class IssuanceController { @Param('orgId') orgId: string, @User() user: user, @Query(new ValidationPipe({ transform: true })) query: CredentialQuery, - @Query('isValidateSchema') isValidateSchema: boolean = true, @Res() res: Response, @Body() fileDetails?: object, - @UploadedFile() file?: Express.Multer.File + @UploadedFile() file?: Express.Multer.File, + @Query('isValidateSchema') isValidateSchema = true ): Promise { - const { credDefId } = query; - clientDetails.userId = user.id; - let reqPayload; + const { credDefId } = query + clientDetails.userId = user.id + let reqPayload: IReqPayload // Need to update logic for University DEMO if (file && clientDetails?.isSelectiveIssuance) { - const fileKey: string = uuidv4(); + const fileKey: string = uuidv4() try { - await this.awsService.uploadCsvFile(fileKey, file.buffer); + await this.awsService.uploadCsvFile(fileKey, file.buffer) } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } reqPayload = { templateId: credDefId, fileKey, + // biome-ignore lint/complexity/useLiteralKeys: fileName: fileDetails['fileName'] || file?.filename || file?.originalname, - type: fileDetails?.['type'] - }; + // biome-ignore lint/complexity/useLiteralKeys: + type: fileDetails?.['type'], + } } const bulkIssuanceDetails = await this.issueCredentialService.issueBulkCredential( requestId, @@ -547,14 +553,14 @@ export class IssuanceController { clientDetails, reqPayload, isValidateSchema - ); + ) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.bulkIssuance, - data: bulkIssuanceDetails - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: bulkIssuanceDetails, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -572,29 +578,29 @@ export class IssuanceController { @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', - type: UnauthorizedErrorDto + type: UnauthorizedErrorDto, }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', - type: ForbiddenErrorDto + type: ForbiddenErrorDto, }) @ApiOperation({ summary: 'Get all file list uploaded for bulk operation', - description: 'Retrieve the list of all files uploaded for bulk operation for a specific organization.' + description: 'Retrieve the list of all files uploaded for bulk operation for a specific organization.', }) async issuedFileDetails( @Param('orgId') orgId: string, @Query() fileParameter: FileParameter, @Res() res: Response ): Promise { - const issuedFileDetails = await this.issueCredentialService.issuedFileDetails(orgId, fileParameter); + const issuedFileDetails = await this.issueCredentialService.issuedFileDetails(orgId, fileParameter) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.issuance.success.previewCSV, - data: issuedFileDetails.response - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: issuedFileDetails.response, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -614,16 +620,16 @@ export class IssuanceController { @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', - type: UnauthorizedErrorDto + type: UnauthorizedErrorDto, }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', - type: ForbiddenErrorDto + type: ForbiddenErrorDto, }) @ApiOperation({ summary: 'Get uploaded file details by file ID', - description: 'Retrieve the details of an uploaded file by its file ID for a specific organization.' + description: 'Retrieve the details of an uploaded file by its file ID for a specific organization.', }) async getFileDetailsByFileId( @Param('orgId') orgId: string, @@ -631,14 +637,14 @@ export class IssuanceController { @Query() fileParameter: FileParameter, @Res() res: Response ): Promise { - const { fileId } = query; - const issuedFileDetails = await this.issueCredentialService.getFileDetailsByFileId(orgId, fileId, fileParameter); + const { fileId } = query + const issuedFileDetails = await this.issueCredentialService.getFileDetailsByFileId(orgId, fileId, fileParameter) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.issuance.success.previewCSV, - data: issuedFileDetails.response - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: issuedFileDetails.response, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -655,31 +661,31 @@ export class IssuanceController { @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', - type: UnauthorizedErrorDto + type: UnauthorizedErrorDto, }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', - type: ForbiddenErrorDto + type: ForbiddenErrorDto, }) @ApiOperation({ summary: 'Get all file details and file data by file ID', - description: 'Retrieve all details and data of an uploaded file by its file ID for a specific organization.' + description: 'Retrieve all details and data of an uploaded file by its file ID for a specific organization.', }) async getFileDetailsAndFileDataByFileId( @Param('orgId') orgId: string, @Param(new ValidationPipe({ transform: true })) query: FileQuery, @Res() res: Response ): Promise { - const { fileId } = query; - const issuedFileDetails = await this.issueCredentialService.getFileDetailsAndFileDataByFileId(orgId, fileId); + const { fileId } = query + const issuedFileDetails = await this.issueCredentialService.getFileDetailsAndFileDataByFileId(orgId, fileId) const finalResponse: IResponseType = { statusCode: HttpStatus.OK, message: ResponseMessages.issuance.success.fileDetailsAndFileData, - data: issuedFileDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: issuedFileDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** * Retry bulk issue credential @@ -698,41 +704,41 @@ export class IssuanceController { @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', - type: UnauthorizedErrorDto + type: UnauthorizedErrorDto, }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', - type: ForbiddenErrorDto + type: ForbiddenErrorDto, }) @ApiOperation({ summary: 'Retry bulk issue credential', - description: 'Retry the bulk issuance of credentials for a specific file ID and organization.' + description: 'Retry the bulk issuance of credentials for a specific file ID and organization.', }) @ApiQuery({ name: 'isValidateSchema', type: Boolean, - required: false + required: false, }) async retryBulkCredentials( @Param('fileId') fileId: string, @Param('orgId') orgId: string, - @Query('isValidateSchema') isValidateSchema: boolean = true, @Res() res: Response, - @Body() clientDetails: ClientDetails + @Body() clientDetails: ClientDetails, + @Query('isValidateSchema') isValidateSchema = true ): Promise { const bulkIssuanceDetails = await this.issueCredentialService.retryBulkCredential( fileId, orgId, clientDetails, isValidateSchema - ); + ) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.bulkIssuance, - data: bulkIssuanceDetails - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: bulkIssuanceDetails, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -747,17 +753,17 @@ export class IssuanceController { @Post('/orgs/:orgId/credentials/offer') @ApiBearerAuth() @ApiOperation({ - summary: `Issuer create a credential offer`, - description: `Issuer creates a credential offer and sends it to the holder` + summary: 'Issuer create a credential offer', + description: 'Issuer creates a credential offer and sends it to the holder', }) @ApiQuery({ name: 'isValidateSchema', type: Boolean, - required: false + required: false, }) @ApiQuery({ name: 'credentialType', - enum: IssueCredentialType + enum: IssueCredentialType, }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER) @@ -768,60 +774,60 @@ export class IssuanceController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(`Invalid format for orgId`); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @Body() issueCredentialDto: IssueCredentialDto, @Res() res: Response, @Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY, - @Query('isValidateSchema') isValidateSchema: boolean = true + @Query('isValidateSchema') isValidateSchema = true ): Promise { - issueCredentialDto.orgId = orgId; - issueCredentialDto.credentialType = credentialType; - issueCredentialDto.isValidateSchema = isValidateSchema; + issueCredentialDto.orgId = orgId + issueCredentialDto.credentialType = credentialType + issueCredentialDto.isValidateSchema = isValidateSchema - const credOffer = issueCredentialDto?.credentialData || []; + const credOffer = issueCredentialDto?.credentialData || [] if (IssueCredentialType.INDY !== credentialType && IssueCredentialType.JSONLD !== credentialType) { - throw new NotFoundException(ResponseMessages.issuance.error.invalidCredentialType); + throw new NotFoundException(ResponseMessages.issuance.error.invalidCredentialType) } if (credentialType === IssueCredentialType.INDY && !issueCredentialDto.credentialDefinitionId) { - throw new BadRequestException(ResponseMessages.credentialDefinition.error.isRequired); + throw new BadRequestException(ResponseMessages.credentialDefinition.error.isRequired) } if ( issueCredentialDto.credentialType !== IssueCredentialType.INDY && - !credOffer.every((offer) => !offer?.attributes || 0 === Object.keys(offer?.attributes).length) + !credOffer.every((offer) => !offer?.attributes || Object.keys(offer?.attributes).length === 0) ) { - throw new BadRequestException(ResponseMessages.issuance.error.attributesAreRequired); + throw new BadRequestException(ResponseMessages.issuance.error.attributesAreRequired) } if ( issueCredentialDto.credentialType === IssueCredentialType.JSONLD && - credOffer.every((offer) => !offer?.credential || 0 === Object.keys(offer?.credential).length) + credOffer.every((offer) => !offer?.credential || Object.keys(offer?.credential).length === 0) ) { - throw new BadRequestException(ResponseMessages.issuance.error.credentialNotPresent); + throw new BadRequestException(ResponseMessages.issuance.error.credentialNotPresent) } if ( issueCredentialDto.credentialType === IssueCredentialType.JSONLD && - credOffer.every((offer) => !offer?.options || 0 === Object.keys(offer?.options).length) + credOffer.every((offer) => !offer?.options || Object.keys(offer?.options).length === 0) ) { - throw new BadRequestException(ResponseMessages.issuance.error.optionsNotPresent); + throw new BadRequestException(ResponseMessages.issuance.error.optionsNotPresent) } - const getCredentialDetails = await this.issueCredentialService.sendCredentialCreateOffer(issueCredentialDto, user); - const { statusCode, message, data } = getCredentialDetails; + const getCredentialDetails = await this.issueCredentialService.sendCredentialCreateOffer(issueCredentialDto, user) + const { statusCode, message, data } = getCredentialDetails const finalResponse: IResponse = { statusCode, message, - data - }; + data, + } - return res.status(statusCode).json(finalResponse); + return res.status(statusCode).json(finalResponse) } /** * Creates a out-of-band credential offer and sends them via emails @@ -835,8 +841,8 @@ export class IssuanceController { @Post('/orgs/:orgId/credentials/oob/email') @UseGuards(AuthGuard('jwt')) @ApiOperation({ - summary: `Creates a out-of-band credential offer and sends them via emails`, - description: `Issuer creates a out-of-band credential offers and sends them to holders via emails` + summary: 'Creates a out-of-band credential offer and sends them via emails', + description: 'Issuer creates a out-of-band credential offers and sends them to holders via emails', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) @ApiBearerAuth() @@ -844,12 +850,12 @@ export class IssuanceController { @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER) @ApiQuery({ name: 'credentialType', - enum: IssueCredentialType + enum: IssueCredentialType, }) @ApiQuery({ name: 'isValidateSchema', type: Boolean, - required: false + required: false, }) async outOfBandCredentialOffer( @User() user: IUserRequest, @@ -857,40 +863,40 @@ export class IssuanceController { @Param('orgId') orgId: string, @Res() res: Response, @Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY, - @Query('isValidateSchema') isValidateSchema: boolean = true + @Query('isValidateSchema') isValidateSchema = true ): Promise { - outOfBandCredentialDto.orgId = orgId; - outOfBandCredentialDto.credentialType = credentialType; - outOfBandCredentialDto.isValidateSchema = isValidateSchema; + outOfBandCredentialDto.orgId = orgId + outOfBandCredentialDto.credentialType = credentialType + outOfBandCredentialDto.isValidateSchema = isValidateSchema - const credOffer = outOfBandCredentialDto?.credentialOffer || []; + const credOffer = outOfBandCredentialDto?.credentialOffer || [] if (IssueCredentialType.INDY !== credentialType && IssueCredentialType.JSONLD !== credentialType) { - throw new NotFoundException(ResponseMessages.issuance.error.invalidCredentialType); + throw new NotFoundException(ResponseMessages.issuance.error.invalidCredentialType) } if ( outOfBandCredentialDto.credentialType === IssueCredentialType.JSONLD && - credOffer.every((offer) => !offer?.credential || 0 === Object.keys(offer?.credential).length) + credOffer.every((offer) => !offer?.credential || Object.keys(offer?.credential).length === 0) ) { - throw new BadRequestException(ResponseMessages.issuance.error.credentialNotPresent); + throw new BadRequestException(ResponseMessages.issuance.error.credentialNotPresent) } if ( outOfBandCredentialDto.credentialType === IssueCredentialType.JSONLD && - credOffer.every((offer) => !offer?.options || 0 === Object.keys(offer?.options).length) + credOffer.every((offer) => !offer?.options || Object.keys(offer?.options).length === 0) ) { - throw new BadRequestException(ResponseMessages.issuance.error.optionsNotPresent); + throw new BadRequestException(ResponseMessages.issuance.error.optionsNotPresent) } const getCredentialDetails = await this.issueCredentialService.outOfBandCredentialOffer( user, outOfBandCredentialDto - ); + ) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.createOOB, - data: getCredentialDetails.response - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: getCredentialDetails.response, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -906,38 +912,38 @@ export class IssuanceController { @Post('/orgs/:orgId/credentials/oob/offer') @ApiBearerAuth() @ApiOperation({ - summary: `Create out-of-band credential offer`, - description: `Creates an out-of-band credential offer` + summary: 'Create out-of-band credential offer', + description: 'Creates an out-of-band credential offer', }) @ApiQuery({ name: 'credentialType', - enum: IssueCredentialType + enum: IssueCredentialType, }) @ApiQuery({ name: 'isValidateSchema', type: Boolean, - required: false + required: false, }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) async createOOBCredentialOffer( - @Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY, - @Query('isValidateSchema') isValidateSchema: boolean = true, @Param('orgId') orgId: string, @Body() issueCredentialDto: OOBIssueCredentialDto, - @Res() res: Response + @Res() res: Response, + @Query('credentialType') credentialType: IssueCredentialType = IssueCredentialType.INDY, + @Query('isValidateSchema') isValidateSchema = true ): Promise { - issueCredentialDto.orgId = orgId; - issueCredentialDto.credentialType = credentialType; - issueCredentialDto.isValidateSchema = isValidateSchema; - const getCredentialDetails = await this.issueCredentialService.sendCredentialOutOfBand(issueCredentialDto); + issueCredentialDto.orgId = orgId + issueCredentialDto.credentialType = credentialType + issueCredentialDto.isValidateSchema = isValidateSchema + const getCredentialDetails = await this.issueCredentialService.sendCredentialOutOfBand(issueCredentialDto) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.create, - data: getCredentialDetails.response - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: getCredentialDetails.response, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -951,43 +957,43 @@ export class IssuanceController { @ApiExcludeEndpoint() @ApiOperation({ summary: 'Catch issue credential webhook responses', - description: 'Callback URL for issue credential' + description: 'Callback URL for issue credential', }) async getIssueCredentialWebhook( @Body() issueCredentialDto: IssuanceDto, @Param('id') id: string, @Res() res: Response ): Promise { - issueCredentialDto.type = 'Issuance'; + issueCredentialDto.type = 'Issuance' - if (id && 'default' === issueCredentialDto.contextCorrelationId) { - issueCredentialDto.orgId = id; + if (id && issueCredentialDto.contextCorrelationId === 'default') { + issueCredentialDto.orgId = id } const getCredentialDetails = await this.issueCredentialService .getIssueCredentialWebhook(issueCredentialDto, id) .catch((error) => { - this.logger.debug(`error in saving issuance webhook ::: ${JSON.stringify(error)}`); - }); + this.logger.debug(`error in saving issuance webhook ::: ${JSON.stringify(error)}`) + }) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.create, - data: getCredentialDetails - }; + data: getCredentialDetails, + } const webhookUrl = await this.issueCredentialService ._getWebhookUrl(issueCredentialDto.contextCorrelationId, id) .catch((error) => { - this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`); - }); + this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`) + }) if (webhookUrl) { - const plainIssuanceDto = JSON.parse(JSON.stringify(issueCredentialDto)); + const plainIssuanceDto = JSON.parse(JSON.stringify(issueCredentialDto)) await this.issueCredentialService._postWebhookResponse(webhookUrl, { data: plainIssuanceDto }).catch((error) => { - this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`); - }); + this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`) + }) } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -1008,19 +1014,19 @@ export class IssuanceController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @User() user: user, @Res() res: Response ): Promise { - await this.issueCredentialService.deleteIssuanceRecords(orgId, user); + await this.issueCredentialService.deleteIssuanceRecords(orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.issuance.success.deleteIssuanceRecords - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.issuance.success.deleteIssuanceRecords, + } + return res.status(HttpStatus.OK).json(finalResponse) } } diff --git a/apps/api-gateway/src/issuance/issuance.module.ts b/apps/api-gateway/src/issuance/issuance.module.ts index d5f184d16..de3868120 100644 --- a/apps/api-gateway/src/issuance/issuance.module.ts +++ b/apps/api-gateway/src/issuance/issuance.module.ts @@ -1,13 +1,13 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Module } from '@nestjs/common'; -import { IssuanceController } from './issuance.controller'; -import { IssuanceService } from './issuance.service'; -import { CommonService } from '@credebl/common'; -import { HttpModule } from '@nestjs/axios'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { AwsService } from '@credebl/aws'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { CommonService } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { IssuanceController } from './issuance.controller' +import { IssuanceService } from './issuance.service' @Module({ imports: [ @@ -16,11 +16,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.ISSUANCE_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } - ]) + options: getNatsOptions(CommonConstants.ISSUANCE_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [IssuanceController], - providers: [IssuanceService, CommonService, AwsService, NATSClient] + providers: [IssuanceService, CommonService, AwsService, NATSClient], }) export class IssuanceModule {} diff --git a/apps/api-gateway/src/issuance/issuance.service.ts b/apps/api-gateway/src/issuance/issuance.service.ts index dd791f7e8..025402fcc 100644 --- a/apps/api-gateway/src/issuance/issuance.service.ts +++ b/apps/api-gateway/src/issuance/issuance.service.ts @@ -1,40 +1,40 @@ +import type { NATSClient } from '@credebl/common/NATSClient' +import type { + ICredentialOfferResponse, + IDeletedIssuanceRecords, + IIssuedCredential, +} from '@credebl/common/interfaces/issuance.interface' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' /* eslint-disable camelcase */ -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 { +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { user } from '@prisma/client' +import { BaseService } from 'libs/service/base.service' +import type { ClientDetails, FileParameter, IssuanceDto, OOBCredentialDtoWithEmail, OOBIssueCredentialDto, PreviewFileDetails, - TemplateDetails -} from './dtos/issuance.dto'; + TemplateDetails, +} from './dtos/issuance.dto' +import type { IssueCredentialDto } from './dtos/multi-connection.dto' import { - FileExportResponse, - IIssuedCredentialSearchParams, - IReqPayload, - ITemplateFormat, + type FileExportResponse, + type IIssuedCredentialSearchParams, + type IReqPayload, + type ITemplateFormat, IssueCredentialType, - UploadedFileDetails -} from './interfaces'; -import { - ICredentialOfferResponse, - IDeletedIssuanceRecords, - IIssuedCredential -} from '@credebl/common/interfaces/issuance.interface'; -import { IssueCredentialDto } from './dtos/multi-connection.dto'; -import { user } from '@prisma/client'; -import { NATSClient } from '@credebl/common/NATSClient'; + type UploadedFileDetails, +} from './interfaces' @Injectable() export class IssuanceService extends BaseService { constructor( @Inject('NATS_CLIENT') private readonly issuanceProxy: ClientProxy, private readonly natsClient: NATSClient ) { - super('IssuanceService'); + super('IssuanceService') } sendCredentialCreateOffer( @@ -50,14 +50,15 @@ export class IssuanceService extends BaseService { autoAcceptCredential: issueCredentialDto.autoAcceptCredential, credentialType: issueCredentialDto.credentialType, isValidateSchema: issueCredentialDto.isValidateSchema, - user - }; + user, + } - return this.natsClient.sendNatsMessage(this.issuanceProxy, 'send-credential-create-offer', payload); + return this.natsClient.sendNatsMessage(this.issuanceProxy, 'send-credential-create-offer', payload) } + // TODO: add Types here instead of large objects sendCredentialOutOfBand(issueCredentialDto: OOBIssueCredentialDto): Promise<{ - response: object; + response: object }> { const { attributes, @@ -75,10 +76,11 @@ export class IssuanceService extends BaseService { isShortenUrl, reuseConnection, credential, - isValidateSchema - } = issueCredentialDto; + isValidateSchema, + } = issueCredentialDto - let payload; + // biome-ignore lint/suspicious/noImplicitAnyLet: + let payload if (IssueCredentialType.INDY === issueCredentialDto.credentialType) { payload = { attributes, @@ -93,8 +95,8 @@ export class IssuanceService extends BaseService { autoAcceptCredential, credentialType, isShortenUrl, - reuseConnection - }; + reuseConnection, + } } if (IssueCredentialType.JSONLD === issueCredentialDto.credentialType) { payload = { @@ -111,11 +113,11 @@ export class IssuanceService extends BaseService { credentialType, isShortenUrl, reuseConnection, - isValidateSchema - }; + isValidateSchema, + } } - return this.natsClient.sendNats(this.issuanceProxy, 'send-credential-create-offer-oob', payload); + return this.natsClient.sendNats(this.issuanceProxy, 'send-credential-create-offer-oob', payload) } getIssueCredentials( @@ -123,8 +125,8 @@ export class IssuanceService extends BaseService { user: IUserRequest, orgId: string ): Promise { - const payload = { issuedCredentialsSearchCriteria, user, orgId }; - return this.natsClient.sendNatsMessage(this.issuanceProxy, 'get-all-issued-credentials', payload); + const payload = { issuedCredentialsSearchCriteria, user, orgId } + return this.natsClient.sendNatsMessage(this.issuanceProxy, 'get-all-issued-credentials', payload) } getIssueCredentialsbyCredentialRecordId( @@ -132,67 +134,67 @@ export class IssuanceService extends BaseService { credentialRecordId: string, orgId: string ): Promise<{ - response: object; + response: object }> { - const payload = { user, credentialRecordId, orgId }; - return this.natsClient.sendNats(this.issuanceProxy, 'get-issued-credentials-by-credentialDefinitionId', payload); + const payload = { user, credentialRecordId, orgId } + return this.natsClient.sendNats(this.issuanceProxy, 'get-issued-credentials-by-credentialDefinitionId', payload) } getIssueCredentialWebhook( issueCredentialDto: IssuanceDto, id: string ): Promise<{ - response: object; + response: object }> { - const payload = { issueCredentialDto, id }; - return this.natsClient.sendNats(this.issuanceProxy, 'webhook-get-issue-credential', payload); + const payload = { issueCredentialDto, id } + return this.natsClient.sendNats(this.issuanceProxy, 'webhook-get-issue-credential', payload) } outOfBandCredentialOffer( user: IUserRequest, outOfBandCredentialDto: OOBCredentialDtoWithEmail ): Promise<{ - response: object; + response: object }> { - const payload = { user, outOfBandCredentialDto }; - return this.natsClient.sendNats(this.issuanceProxy, 'out-of-band-credential-offer', payload); + const payload = { user, outOfBandCredentialDto } + return this.natsClient.sendNats(this.issuanceProxy, 'out-of-band-credential-offer', payload) } getAllCredentialTemplates(orgId: string, schemaType: string): Promise { - const payload = { orgId, schemaType }; + const payload = { orgId, schemaType } return this.natsClient.sendNatsMessage( this.issuanceProxy, 'get-all-credential-template-for-bulk-operation', payload - ); + ) } async downloadBulkIssuanceCSVTemplate(orgId: string, templateDetails: TemplateDetails): Promise { - const payload = { orgId, templateDetails }; + const payload = { orgId, templateDetails } return (await this.natsClient.sendNats(this.issuanceProxy, 'download-csv-template-for-bulk-operation', payload)) - .response; + .response } async uploadCSVTemplate(importFileDetails: UploadedFileDetails, orgId: string): Promise<{ response: object }> { - const payload = { importFileDetails, orgId }; - return this.natsClient.sendNats(this.issuanceProxy, 'upload-csv-template', payload); + const payload = { importFileDetails, orgId } + return this.natsClient.sendNats(this.issuanceProxy, 'upload-csv-template', payload) } async previewCSVDetails(requestId: string, orgId: string, previewFileDetails: PreviewFileDetails): Promise { const payload = { requestId, orgId, - previewFileDetails - }; - return this.natsClient.sendNats(this.issuanceProxy, 'preview-csv-details', payload); + previewFileDetails, + } + return this.natsClient.sendNats(this.issuanceProxy, 'preview-csv-details', payload) } async issuedFileDetails(orgId: string, fileParameter: FileParameter): Promise<{ response: object }> { const payload = { orgId, - fileParameter - }; - return this.natsClient.sendNats(this.issuanceProxy, 'issued-file-details', payload); + fileParameter, + } + return this.natsClient.sendNats(this.issuanceProxy, 'issued-file-details', payload) } async getFileDetailsByFileId( @@ -203,9 +205,9 @@ export class IssuanceService extends BaseService { const payload = { orgId, fileId, - fileParameter - }; - return this.natsClient.sendNats(this.issuanceProxy, 'issued-file-data', payload); + fileParameter, + } + return this.natsClient.sendNats(this.issuanceProxy, 'issued-file-data', payload) } async issueBulkCredential( @@ -215,9 +217,9 @@ export class IssuanceService extends BaseService { reqPayload: IReqPayload, isValidateSchema: boolean ): Promise { - const payload = { requestId, orgId, clientDetails, reqPayload, isValidateSchema }; + const payload = { requestId, orgId, clientDetails, reqPayload, isValidateSchema } - return this.natsClient.sendNatsMessage(this.issuanceProxy, 'issue-bulk-credentials', payload); + return this.natsClient.sendNatsMessage(this.issuanceProxy, 'issue-bulk-credentials', payload) } async retryBulkCredential( @@ -226,48 +228,48 @@ export class IssuanceService extends BaseService { clientDetails: ClientDetails, isValidateSchema?: boolean ): Promise { - const payload = { fileId, orgId, clientDetails, isValidateSchema }; - return this.natsClient.sendNatsMessage(this.issuanceProxy, 'retry-bulk-credentials', payload); + const payload = { fileId, orgId, clientDetails, isValidateSchema } + return this.natsClient.sendNatsMessage(this.issuanceProxy, 'retry-bulk-credentials', payload) } async _getWebhookUrl(tenantId?: string, orgId?: string): Promise { - const pattern = { cmd: 'get-webhookurl' }; - const payload = { tenantId, orgId }; + const pattern = { cmd: 'get-webhookurl' } + const payload = { tenantId, orgId } try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const message = await this.issuanceProxy.send(pattern, payload).toPromise(); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.issuanceProxy.send(pattern, payload).toPromise() + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw error } } async _postWebhookResponse(webhookUrl: string, data: object): Promise { - const pattern = { cmd: 'post-webhook-response-to-webhook-url' }; - const payload = { webhookUrl, data }; + const pattern = { cmd: 'post-webhook-response-to-webhook-url' } + const payload = { webhookUrl, data } try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const message = await this.issuanceProxy.send(pattern, payload).toPromise(); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.issuanceProxy.send(pattern, payload).toPromise() + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) - throw error; + throw error } } async deleteIssuanceRecords(orgId: string, userDetails: user): Promise { - const payload = { orgId, userDetails }; - return this.natsClient.sendNatsMessage(this.issuanceProxy, 'delete-issuance-records', payload); + const payload = { orgId, userDetails } + return this.natsClient.sendNatsMessage(this.issuanceProxy, 'delete-issuance-records', payload) } async getFileDetailsAndFileDataByFileId(orgId: string, fileId: string): Promise { const payload = { orgId, - fileId - }; - return this.natsClient.sendNatsMessage(this.issuanceProxy, 'issued-file-data-and-file-details', payload); + fileId, + } + return this.natsClient.sendNatsMessage(this.issuanceProxy, 'issued-file-data-and-file-details', payload) } } diff --git a/apps/api-gateway/src/issuance/utils/helper.ts b/apps/api-gateway/src/issuance/utils/helper.ts index 574e5eb69..49175385c 100644 --- a/apps/api-gateway/src/issuance/utils/helper.ts +++ b/apps/api-gateway/src/issuance/utils/helper.ts @@ -1,33 +1,39 @@ /* eslint-disable @typescript-eslint/array-type */ -import { ValidateBy, ValidationOptions, buildMessage, isString, isURL } from 'class-validator'; -import { JsonObject } from '../interfaces'; +import { ValidateBy, type ValidationOptions, buildMessage, isString, isURL } from 'class-validator' +import type { JsonObject } from '../interfaces' export type SingleOrArray = T | T[] export type JsonValue = string | number | boolean | null | JsonObject | JsonArray export type JsonArray = Array - -export const isJsonObject = (value: unknown): value is JsonObject => value !== undefined && 'object' === typeof value && null !== value && !Array.isArray(value); -export const CREDENTIALS_CONTEXT_V1_URL = 'https://www.w3.org/2018/credentials/v1'; +export const isJsonObject = (value: unknown): value is JsonObject => + value !== undefined && typeof value === 'object' && value !== null && !Array.isArray(value) +export const CREDENTIALS_CONTEXT_V1_URL = 'https://www.w3.org/2018/credentials/v1' export function IsCredentialJsonLdContext(validationOptions?: ValidationOptions): PropertyDecorator { return ValidateBy( { name: 'IsCredentialJsonLdContext', validator: { validate: (value): boolean => { - if (!Array.isArray(value)) { return false; } + if (!Array.isArray(value)) { + return false + } // First item must be the verifiable credential context - if (value[0] !== CREDENTIALS_CONTEXT_V1_URL) { return false; } + if (value[0] !== CREDENTIALS_CONTEXT_V1_URL) { + return false + } - return value.every((v) => (isString(v) && isURL(v)) || isJsonObject(v)); + return value.every((v) => (isString(v) && isURL(v)) || isJsonObject(v)) }, defaultMessage: buildMessage( - (eachPrefix) => `${eachPrefix + (eachPrefix) => + `${ + eachPrefix }$property must be an array of strings or objects, where the first item is the verifiable credential context URL.`, validationOptions - ) - } + ), + }, }, validationOptions - ); -} \ No newline at end of file + ) +} diff --git a/apps/api-gateway/src/main.ts b/apps/api-gateway/src/main.ts index 3d47d558b..0eaea0021 100644 --- a/apps/api-gateway/src/main.ts +++ b/apps/api-gateway/src/main.ts @@ -1,48 +1,48 @@ -import * as dotenv from 'dotenv'; -import * as express from 'express'; +import * as dotenv from 'dotenv' +import * as express from 'express' -import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; -import { Logger, ValidationPipe, VERSION_NEUTRAL, VersioningType } from '@nestjs/common'; +import { Logger, VERSION_NEUTRAL, ValidationPipe, VersioningType } from '@nestjs/common' +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger' -import { AppModule } from './app.module'; -import { HttpAdapterHost, NestFactory } from '@nestjs/core'; -import { AllExceptionsFilter } from '@credebl/common/exception-handler'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; +import { AllExceptionsFilter } from '@credebl/common/exception-handler' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpAdapterHost, NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { AppModule } from './app.module' -import helmet from 'helmet'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; -import { NatsInterceptor } from '@credebl/common'; -dotenv.config(); +import { NatsInterceptor } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import helmet from 'helmet' +dotenv.config() async function bootstrap(): Promise { - const app = await NestFactory.create(AppModule); + const app = await NestFactory.create(AppModule) - app.useLogger(app.get(NestjsLoggerServiceAdapter)); + app.useLogger(app.get(NestjsLoggerServiceAdapter)) app.connectMicroservice({ transport: Transport.NATS, - options: getNatsOptions(CommonConstants.API_GATEWAY_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - }); + options: getNatsOptions(CommonConstants.API_GATEWAY_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }) - const expressApp = app.getHttpAdapter().getInstance(); - expressApp.set('x-powered-by', false); - app.use(express.json({ limit: '100mb' })); - app.use(express.urlencoded({ limit: '100mb', extended: true })); + const expressApp = app.getHttpAdapter().getInstance() + expressApp.set('x-powered-by', false) + app.use(express.json({ limit: '100mb' })) + app.use(express.urlencoded({ limit: '100mb', extended: true })) - app.use(function (req, res, next) { - let err = null; + app.use((req, res, next) => { + let err = null try { - decodeURIComponent(req.path); + decodeURIComponent(req.path) } catch (e) { - err = e; + err = e } if (err) { - return res.status(500).json({ message: 'Invalid URL' }); + return res.status(500).json({ message: 'Invalid URL' }) } - next(); - }); + next() + }) const options = new DocumentBuilder() .setTitle(`${process.env.PLATFORM_NAME}`) @@ -56,48 +56,48 @@ async function bootstrap(): Promise { .addServer(`${process.env.PUBLIC_SANDBOX_API_URL}`) .addServer(`${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}`) .addServer(`${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_GATEWAY_HOST}`) - .build(); + .build() app.enableVersioning({ type: VersioningType.URI, - defaultVersion: ['1'] - }); + defaultVersion: ['1'], + }) - const document = SwaggerModule.createDocument(app, options); - SwaggerModule.setup('api', app, document); - const httpAdapter = app.get(HttpAdapterHost); - app.useGlobalFilters(new AllExceptionsFilter(httpAdapter)); - const { ENABLE_CORS_IP_LIST } = process.env || {}; - if (ENABLE_CORS_IP_LIST && '' !== ENABLE_CORS_IP_LIST) { + const document = SwaggerModule.createDocument(app, options) + SwaggerModule.setup('api', app, document) + const httpAdapter = app.get(HttpAdapterHost) + app.useGlobalFilters(new AllExceptionsFilter(httpAdapter)) + const { ENABLE_CORS_IP_LIST } = process.env || {} + if (ENABLE_CORS_IP_LIST && ENABLE_CORS_IP_LIST !== '') { app.enableCors({ origin: ENABLE_CORS_IP_LIST.split(','), methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', - credentials: true - }); + credentials: true, + }) } app.enableVersioning({ type: VersioningType.URI, - defaultVersion: ['1', VERSION_NEUTRAL] - }); + defaultVersion: ['1', VERSION_NEUTRAL], + }) - app.use(express.static('uploadedFiles/holder-profile')); - app.use(express.static('uploadedFiles/org-logo')); - app.use(express.static('uploadedFiles/tenant-logo')); - app.use(express.static('uploadedFiles/exports')); - app.use(express.static('resources')); - app.use(express.static('genesis-file')); - app.use(express.static('invoice-pdf')); - app.use(express.static('uploadedFiles/bulk-verification-templates')); - app.use(express.static('uploadedFiles/import')); - app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true })); + app.use(express.static('uploadedFiles/holder-profile')) + app.use(express.static('uploadedFiles/org-logo')) + app.use(express.static('uploadedFiles/tenant-logo')) + app.use(express.static('uploadedFiles/exports')) + app.use(express.static('resources')) + app.use(express.static('genesis-file')) + app.use(express.static('invoice-pdf')) + app.use(express.static('uploadedFiles/bulk-verification-templates')) + app.use(express.static('uploadedFiles/import')) + app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true })) app.use( helmet({ - xssFilter: true + xssFilter: true, }) - ); - app.useGlobalInterceptors(new NatsInterceptor()); - await app.listen(process.env.API_GATEWAY_PORT, `${process.env.API_GATEWAY_HOST}`); - Logger.log(`API Gateway is listening on port ${process.env.API_GATEWAY_PORT}`); + ) + app.useGlobalInterceptors(new NatsInterceptor()) + await app.listen(process.env.API_GATEWAY_PORT, `${process.env.API_GATEWAY_HOST}`) + Logger.log(`API Gateway is listening on port ${process.env.API_GATEWAY_PORT}`) } -bootstrap(); +bootstrap() diff --git a/apps/api-gateway/src/notification/dtos/notification.dto.ts b/apps/api-gateway/src/notification/dtos/notification.dto.ts index 8ddef46d3..e92484916 100644 --- a/apps/api-gateway/src/notification/dtos/notification.dto.ts +++ b/apps/api-gateway/src/notification/dtos/notification.dto.ts @@ -1,85 +1,80 @@ -import { ApiExtraModels, ApiProperty } from '@nestjs/swagger'; -import { IsNotEmpty, IsString, IsUrl } from 'class-validator'; +import { ApiExtraModels, ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString, IsUrl } from 'class-validator' -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { Transform } from 'class-transformer' @ApiExtraModels() export class RegisterHolderCredentalsDto { + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'fcmToken is required.' }) + @IsString({ message: 'fcmToken must be in string format.' }) + fcmToken: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'fcmToken is required.' }) - @IsString({ message: 'fcmToken must be in string format.' }) - fcmToken: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'orgId is required.' }) + @IsString({ message: 'orgId must be in string format.' }) + orgId: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'orgId is required.' }) - @IsString({ message: 'orgId must be in string format.' }) - orgId: string; - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'userKey is required.' }) - @IsString({ message: 'userKey must be in string format.' }) - userKey: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'userKey is required.' }) + @IsString({ message: 'userKey must be in string format.' }) + userKey: string } export class RegisterOrgWebhhookEndpointDto { + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'orgId is required.' }) + @IsString({ message: 'orgId must be in string format.' }) + orgId: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'orgId is required.' }) - @IsString({ message: 'orgId must be in string format.' }) - orgId: string; - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'notificationWebhook is required.' }) - @IsString({ message: 'notificationWebhook must be in string format.' }) - @IsUrl({ - // eslint-disable-next-line camelcase - require_protocol: true, // require URL protocol (e.g., http:// or https://) - // eslint-disable-next-line camelcase - require_tld: true // require top-level domain (e.g., .com, .net) - - }) - notificationWebhook: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'notificationWebhook is required.' }) + @IsString({ message: 'notificationWebhook must be in string format.' }) + @IsUrl({ + // eslint-disable-next-line camelcase + require_protocol: true, // require URL protocol (e.g., http:// or https://) + // eslint-disable-next-line camelcase + require_tld: true, // require top-level domain (e.g., .com, .net) + }) + notificationWebhook: string } export class SendNotificationDto { + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'fcmToken is required.' }) + @IsString({ message: 'fcmToken must be in string format.' }) + fcmToken: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'fcmToken is required.' }) - @IsString({ message: 'fcmToken must be in string format.' }) - fcmToken: string; - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'messageType is required.' }) - @IsString({ message: 'messageType must be in string format.' }) - messageType: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'messageType is required.' }) + @IsString({ message: 'messageType must be in string format.' }) + messageType: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'clientCode is required.' }) - @IsString({ message: 'clientCode must be in string format.' }) - clientCode: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'clientCode is required.' }) + @IsString({ message: 'clientCode must be in string format.' }) + clientCode: string } export class GetNotificationDto { + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'fcmToken is required.' }) + @IsString({ message: 'fcmToken must be in string format.' }) + fcmToken: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'fcmToken is required.' }) - @IsString({ message: 'fcmToken must be in string format.' }) - fcmToken: string; - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'messageType is required.' }) - @IsString({ message: 'messageType must be in string format.' }) - messageType: string; -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'messageType is required.' }) + @IsString({ message: 'messageType must be in string format.' }) + messageType: string +} diff --git a/apps/api-gateway/src/notification/interfaces/notification.interfaces.ts b/apps/api-gateway/src/notification/interfaces/notification.interfaces.ts index a2b4aa1a3..43a285660 100644 --- a/apps/api-gateway/src/notification/interfaces/notification.interfaces.ts +++ b/apps/api-gateway/src/notification/interfaces/notification.interfaces.ts @@ -1,5 +1,5 @@ export interface INotification { - id: string; - orgId: string; - webhookEndpoint: string; -} \ No newline at end of file + id: string + orgId: string + webhookEndpoint: string +} diff --git a/apps/api-gateway/src/notification/notification.controller.ts b/apps/api-gateway/src/notification/notification.controller.ts index c435d1eaa..4892c659e 100644 --- a/apps/api-gateway/src/notification/notification.controller.ts +++ b/apps/api-gateway/src/notification/notification.controller.ts @@ -1,15 +1,21 @@ -import { CustomExceptionFilter } from '@credebl/common/exception-handler'; -import { Body, Controller, HttpStatus, Logger, Post, Res, UseFilters } from '@nestjs/common'; -import { ApiExcludeEndpoint, ApiForbiddenResponse, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { RegisterOrgWebhhookEndpointDto, SendNotificationDto } from './dtos/notification.dto'; -import { IResponse } from '@credebl/common/interfaces/response.interface'; -import { Response } from 'express'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { NotificationService } from './notification.service'; - +import { CustomExceptionFilter } from '@credebl/common/exception-handler' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Body, Controller, HttpStatus, Logger, Post, Res, UseFilters } from '@nestjs/common' +import { + ApiExcludeEndpoint, + ApiForbiddenResponse, + ApiOperation, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import type { Response } from 'express' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { RegisterOrgWebhhookEndpointDto, SendNotificationDto } from './dtos/notification.dto' +import type { NotificationService } from './notification.service' @Controller('notification') @UseFilters(CustomExceptionFilter) @@ -17,68 +23,61 @@ import { NotificationService } from './notification.service'; @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) export class NotificationController { - constructor( - private readonly notificationService: NotificationService - ) { } - private readonly logger = new Logger('NotificationController'); - - /** - * Register organization webhook endpoint - * @param registerOrgWebhhookEndpointDto - * @param res - * @returns Stored notification data - */ - @Post('/register/webhook-endpoint') - @ApiExcludeEndpoint() - @ApiOperation({ - summary: `Register organization webhook endpoint for notification`, - description: `Register organization webhook endpoint for notification` - }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) - async registerOrgWebhookEndpoint( - @Body() registerOrgWebhhookEndpointDto: RegisterOrgWebhhookEndpointDto, - @Res() res: Response - ): Promise { + constructor(private readonly notificationService: NotificationService) {} + private readonly logger = new Logger('NotificationController') - const registerUserEndpoint = await this.notificationService.registerOrgWebhookEndpoint( - registerOrgWebhhookEndpointDto - ); + /** + * Register organization webhook endpoint + * @param registerOrgWebhhookEndpointDto + * @param res + * @returns Stored notification data + */ + @Post('/register/webhook-endpoint') + @ApiExcludeEndpoint() + @ApiOperation({ + summary: 'Register organization webhook endpoint for notification', + description: 'Register organization webhook endpoint for notification', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) + async registerOrgWebhookEndpoint( + @Body() registerOrgWebhhookEndpointDto: RegisterOrgWebhhookEndpointDto, + @Res() res: Response + ): Promise { + const registerUserEndpoint = + await this.notificationService.registerOrgWebhookEndpoint(registerOrgWebhhookEndpointDto) - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.notification.success.register, - data: registerUserEndpoint - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.notification.success.register, + data: registerUserEndpoint, } + return res.status(HttpStatus.CREATED).json(finalResponse) + } - /** - * Send notification for holder - * @param sendNotificationDto - * @param res - * @returns Get notification details - */ - @Post('/') - @ApiExcludeEndpoint() - @ApiOperation({ - summary: `Send notification for holder`, - description: `Send notification for holder` - }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) - async sendNotification( - @Body() notificationRequestBody: SendNotificationDto, - @Res() res: Response - ): Promise { - - const sendNotification = await this.notificationService.sendNotification( - notificationRequestBody - ); + /** + * Send notification for holder + * @param sendNotificationDto + * @param res + * @returns Get notification details + */ + @Post('/') + @ApiExcludeEndpoint() + @ApiOperation({ + summary: 'Send notification for holder', + description: 'Send notification for holder', + }) + @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) + async sendNotification( + @Body() notificationRequestBody: SendNotificationDto, + @Res() res: Response + ): Promise { + const sendNotification = await this.notificationService.sendNotification(notificationRequestBody) - const finalResponse: IResponse = { - statusCode: HttpStatus.CREATED, - message: ResponseMessages.notification.success.sendNotification, - data: sendNotification - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + const finalResponse: IResponse = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.notification.success.sendNotification, + data: sendNotification, } -} \ No newline at end of file + return res.status(HttpStatus.CREATED).json(finalResponse) + } +} diff --git a/apps/api-gateway/src/notification/notification.module.ts b/apps/api-gateway/src/notification/notification.module.ts index 72fbc9400..94083e328 100644 --- a/apps/api-gateway/src/notification/notification.module.ts +++ b/apps/api-gateway/src/notification/notification.module.ts @@ -1,14 +1,13 @@ - -import { CommonModule, CommonService } from '@credebl/common'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { ConfigModule } from '@nestjs/config'; -import { HttpModule } from '@nestjs/axios'; -import { Module } from '@nestjs/common'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { NotificationController } from './notification.controller'; -import { NotificationService } from './notification.service'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { CommonModule, CommonService } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { NotificationController } from './notification.controller' +import { NotificationService } from './notification.service' @Module({ imports: [ @@ -18,13 +17,12 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.NOTIFICATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - + options: getNatsOptions(CommonConstants.NOTIFICATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED), }, - CommonModule - ]) + CommonModule, + ]), ], controllers: [NotificationController], - providers: [NotificationService, CommonService, NATSClient] + providers: [NotificationService, CommonService, NATSClient], }) -export class NotificationModule { } +export class NotificationModule {} diff --git a/apps/api-gateway/src/notification/notification.service.ts b/apps/api-gateway/src/notification/notification.service.ts index 130012fc2..437d9dd4a 100644 --- a/apps/api-gateway/src/notification/notification.service.ts +++ b/apps/api-gateway/src/notification/notification.service.ts @@ -1,31 +1,40 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { RegisterOrgWebhhookEndpointDto, SendNotificationDto } from './dtos/notification.dto'; -import { INotification } from './interfaces/notification.interfaces'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from 'libs/service/base.service' +import type { RegisterOrgWebhhookEndpointDto, SendNotificationDto } from './dtos/notification.dto' +import type { INotification } from './interfaces/notification.interfaces' @Injectable() export class NotificationService extends BaseService { - constructor(@Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, private readonly natsClient : NATSClient) { - super('NotificationService'); - } + constructor( + @Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('NotificationService') + } - /** - * Register organization webhook endpoint - * @param registerOrgWebhhookEndpointDto - * @returns Stored notification data - */ - async registerOrgWebhookEndpoint(registerOrgWebhhookEndpointDto: RegisterOrgWebhhookEndpointDto): Promise { - return this.natsClient.sendNatsMessage(this.serviceProxy, 'register-org-webhook-endpoint-for-notification', registerOrgWebhhookEndpointDto); - } + /** + * Register organization webhook endpoint + * @param registerOrgWebhhookEndpointDto + * @returns Stored notification data + */ + async registerOrgWebhookEndpoint( + registerOrgWebhhookEndpointDto: RegisterOrgWebhhookEndpointDto + ): Promise { + return this.natsClient.sendNatsMessage( + this.serviceProxy, + 'register-org-webhook-endpoint-for-notification', + registerOrgWebhhookEndpointDto + ) + } - /** - * Send notification for holder - * @param sendNotificationDto - * @returns Get notification details - */ - async sendNotification(notificationRequestBody: SendNotificationDto): Promise { - return this.natsClient.sendNatsMessage(this.serviceProxy, 'send-notification', notificationRequestBody); - } -} \ No newline at end of file + /** + * Send notification for holder + * @param sendNotificationDto + * @returns Get notification details + */ + async sendNotification(notificationRequestBody: SendNotificationDto): Promise { + return this.natsClient.sendNatsMessage(this.serviceProxy, 'send-notification', notificationRequestBody) + } +} diff --git a/apps/api-gateway/src/organization/dtos/client-credentials.dto.ts b/apps/api-gateway/src/organization/dtos/client-credentials.dto.ts index 9c2ad15d3..201ae580d 100644 --- a/apps/api-gateway/src/organization/dtos/client-credentials.dto.ts +++ b/apps/api-gateway/src/organization/dtos/client-credentials.dto.ts @@ -1,18 +1,16 @@ -import { ApiExtraModels, ApiProperty } from '@nestjs/swagger'; -import { IsNotEmpty, IsString } from 'class-validator'; +import { ApiExtraModels, ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { Transform } from 'class-transformer' @ApiExtraModels() export class ClientCredentialsDto { + clientId: string - clientId: string; - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'clientSecret is required.' }) - @IsString({ message: 'clientSecret must be in string format.' }) - clientSecret: string; - -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'clientSecret is required.' }) + @IsString({ message: 'clientSecret must be in string format.' }) + clientSecret: string +} diff --git a/apps/api-gateway/src/organization/dtos/create-organization-dto.ts b/apps/api-gateway/src/organization/dtos/create-organization-dto.ts index 47d1f987b..166ed1a8d 100644 --- a/apps/api-gateway/src/organization/dtos/create-organization-dto.ts +++ b/apps/api-gateway/src/organization/dtos/create-organization-dto.ts @@ -1,9 +1,9 @@ -import { ApiExtraModels, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsNotEmpty, IsOptional, IsString, IsUrl, MaxLength, MinLength } from 'class-validator'; +import { ApiExtraModels, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { IsNotEmpty, IsOptional, IsString, IsUrl, MaxLength, MinLength } from 'class-validator' -import { Transform } from 'class-transformer'; -import { IsNotSQLInjection, trim } from '@credebl/common/cast.helper'; -import { GeoLocationDto } from '../../dtos/geo-location-dto'; +import { IsNotSQLInjection, trim } from '@credebl/common/cast.helper' +import { Transform } from 'class-transformer' +import { GeoLocationDto } from '../../dtos/geo-location-dto' @ApiExtraModels() export class CreateOrganizationDto extends GeoLocationDto { @@ -14,7 +14,7 @@ export class CreateOrganizationDto extends GeoLocationDto { @MaxLength(200, { message: 'Organization name must be at most 200 characters.' }) @IsString({ message: 'Organization name must be in string format.' }) @IsNotSQLInjection({ message: 'Incorrect pattern for organization name.' }) - name: string; + name: string @ApiProperty() @Transform(({ value }) => trim(value)) @@ -22,12 +22,12 @@ export class CreateOrganizationDto extends GeoLocationDto { @MinLength(2, { message: 'Description must be at least 2 characters.' }) @MaxLength(1000, { message: 'Description must be at most 1000 characters.' }) @IsString({ message: 'Description must be in string format.' }) - description: string; + description: string @ApiPropertyOptional() @IsOptional() @Transform(({ value }) => trim(value)) - website?: string; + website?: string @ApiPropertyOptional() @IsOptional() @@ -38,19 +38,19 @@ export class CreateOrganizationDto extends GeoLocationDto { // eslint-disable-next-line camelcase require_protocol: true, // require URL protocol (e.g., http:// or https://) // eslint-disable-next-line camelcase - require_tld: true // require top-level domain (e.g., .com, .net) + require_tld: true, // require top-level domain (e.g., .com, .net) }) - notificationWebhook?: string; + notificationWebhook?: string @ApiPropertyOptional() @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'logo must be in string format.' }) - logo?: string = ''; + logo?: string = '' @ApiPropertyOptional() @IsOptional() @Transform(({ value }) => trim(value)) @IsString({ message: 'registrationNumber must be in string format.' }) - registrationNumber?: string; + registrationNumber?: string } diff --git a/apps/api-gateway/src/organization/dtos/get-organizations.dto.ts b/apps/api-gateway/src/organization/dtos/get-organizations.dto.ts index 4a4b35ddd..202dd4d5b 100644 --- a/apps/api-gateway/src/organization/dtos/get-organizations.dto.ts +++ b/apps/api-gateway/src/organization/dtos/get-organizations.dto.ts @@ -1,14 +1,14 @@ -import { trim } from '@credebl/common/cast.helper'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsEnum, IsOptional } from 'class-validator'; -import { OrgRoles } from 'libs/org-roles/enums'; +import { trim } from '@credebl/common/cast.helper' +import { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsEnum, IsOptional } from 'class-validator' +import { OrgRoles } from 'libs/org-roles/enums' export class GetAllOrganizationsDto extends PaginationDto { - @ApiProperty({ required: false, enum: OrgRoles }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(OrgRoles) - role: string; + @ApiProperty({ required: false, enum: OrgRoles }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(OrgRoles) + role: string } diff --git a/apps/api-gateway/src/organization/dtos/send-invitation.dto.ts b/apps/api-gateway/src/organization/dtos/send-invitation.dto.ts index b5c6295bd..53cc18bed 100644 --- a/apps/api-gateway/src/organization/dtos/send-invitation.dto.ts +++ b/apps/api-gateway/src/organization/dtos/send-invitation.dto.ts @@ -1,41 +1,38 @@ -import { ApiExtraModels, ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsEmail, IsNotEmpty, IsString, IsUUID, ValidateNested } from 'class-validator'; -import { Transform, Type } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiExtraModels, ApiProperty } from '@nestjs/swagger' +import { Transform, Type } from 'class-transformer' +import { IsArray, IsEmail, IsNotEmpty, IsString, IsUUID, ValidateNested } from 'class-validator' @ApiExtraModels() export class SendInvitationDto { + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; - - @ApiProperty({ example: ['1a7eac11-ff05-40d7-8351-4d7467687cad'] }) - @IsNotEmpty({ message: 'Please provide valid orgRoleId' }) - @IsArray() - @IsUUID('4', { each: true, message: 'Invalid format of orgRoleId' }) - orgRoleId: string[]; - + @ApiProperty({ example: ['1a7eac11-ff05-40d7-8351-4d7467687cad'] }) + @IsNotEmpty({ message: 'Please provide valid orgRoleId' }) + @IsArray() + @IsUUID('4', { each: true, message: 'Invalid format of orgRoleId' }) + orgRoleId: string[] } @ApiExtraModels() export class BulkSendInvitationDto { + @ApiProperty({ + example: [ + { + email: 'awqx@yopmail.com', + orgRoleId: ['1a7eac11-ff05-40d7-8351-4d7467687cad'], + }, + ], + }) + @IsArray() + @ValidateNested({ each: true }) + @Type(() => SendInvitationDto) + invitations: SendInvitationDto[] - @ApiProperty({ - example: [ - { - email: 'awqx@yopmail.com', - orgRoleId: ['1a7eac11-ff05-40d7-8351-4d7467687cad'] - } - ] - }) - @IsArray() - @ValidateNested({ each: true }) - @Type(() => SendInvitationDto) - invitations: SendInvitationDto[]; - - orgId: string; + orgId: string } diff --git a/apps/api-gateway/src/organization/dtos/set-primary-did.dto.ts b/apps/api-gateway/src/organization/dtos/set-primary-did.dto.ts index ccac22c94..31e1ec8cf 100644 --- a/apps/api-gateway/src/organization/dtos/set-primary-did.dto.ts +++ b/apps/api-gateway/src/organization/dtos/set-primary-did.dto.ts @@ -1,22 +1,20 @@ -import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsNotEmpty, IsString} from 'class-validator'; +import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { Transform } from 'class-transformer' @ApiExtraModels() export class PrimaryDid { - - @ApiPropertyOptional() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Did is required.' }) - @IsString({ message: 'Did must be in string format.' }) - did: string; + @ApiPropertyOptional() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Did is required.' }) + @IsString({ message: 'Did must be in string format.' }) + did: string - @ApiPropertyOptional() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Id is required.' }) - @IsString({ message: 'Id must be in string format.' }) - id: string; - -} \ No newline at end of file + @ApiPropertyOptional() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Id is required.' }) + @IsString({ message: 'Id must be in string format.' }) + id: string +} diff --git a/apps/api-gateway/src/organization/dtos/update-organization-dto.ts b/apps/api-gateway/src/organization/dtos/update-organization-dto.ts index ca6e2dc8b..fd8155092 100644 --- a/apps/api-gateway/src/organization/dtos/update-organization-dto.ts +++ b/apps/api-gateway/src/organization/dtos/update-organization-dto.ts @@ -1,13 +1,13 @@ -import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsNotEmpty, IsOptional, IsString, IsBoolean, MaxLength, MinLength, Validate } from 'class-validator'; +import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger' +import { IsBoolean, IsNotEmpty, IsOptional, IsString, MaxLength, MinLength, Validate } from 'class-validator' -import { Transform } from 'class-transformer'; -import { ImageBase64Validator, IsNotSQLInjection, trim } from '@credebl/common/cast.helper'; -import { GeoLocationDto } from '../../dtos/geo-location-dto'; +import { ImageBase64Validator, IsNotSQLInjection, trim } from '@credebl/common/cast.helper' +import { Transform } from 'class-transformer' +import { GeoLocationDto } from '../../dtos/geo-location-dto' @ApiExtraModels() export class UpdateOrganizationDto extends GeoLocationDto { - orgId: string; + orgId: string @ApiPropertyOptional() @IsOptional() @@ -17,7 +17,7 @@ export class UpdateOrganizationDto extends GeoLocationDto { @MaxLength(200, { message: 'Organization name must be at most 200 characters.' }) @IsString({ message: 'Organization name must be in string format.' }) @IsNotSQLInjection({ message: 'Incorrect pattern for organization name.' }) - name: string; + name: string @ApiPropertyOptional() @IsOptional() @@ -26,21 +26,21 @@ export class UpdateOrganizationDto extends GeoLocationDto { @MinLength(2, { message: 'Description must be at least 2 characters.' }) @MaxLength(1000, { message: 'Description must be at most 1000 characters.' }) @IsString({ message: 'Description must be in string format.' }) - description: string; + description: string @ApiPropertyOptional() @IsOptional() @Transform(({ value }) => trim(value)) @Validate(ImageBase64Validator) - logo?: string = ''; + logo?: string = '' @ApiPropertyOptional() @IsOptional() - website?: string; + website?: string @ApiPropertyOptional({ example: true }) @IsOptional() @IsBoolean({ message: 'isPublic should be boolean' }) @IsOptional() - isPublic?: boolean = false; + isPublic?: boolean = false } diff --git a/apps/api-gateway/src/organization/dtos/update-user-roles.dto.ts b/apps/api-gateway/src/organization/dtos/update-user-roles.dto.ts index 402084c84..974d880f2 100644 --- a/apps/api-gateway/src/organization/dtos/update-user-roles.dto.ts +++ b/apps/api-gateway/src/organization/dtos/update-user-roles.dto.ts @@ -1,20 +1,19 @@ -import { ArrayNotEmpty, IsArray, IsNotEmpty, IsUUID, MinLength} from 'class-validator'; +import { ArrayNotEmpty, IsArray, IsNotEmpty, IsUUID, MinLength } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class UpdateUserRolesDto { + orgId: string + userId: string - orgId: string; - userId: string; + @ApiProperty({ + example: ['2', '1', '3'], + }) - @ApiProperty({ - example: ['2', '1', '3'] - }) - - @IsArray() - @ArrayNotEmpty() - @MinLength(0, {each: true}) - @IsNotEmpty({each: true}) - @IsUUID('4', { each: true, message: 'Invalid format of orgRoleId' }) - orgRoleId: string[]; -} \ No newline at end of file + @IsArray() + @ArrayNotEmpty() + @MinLength(0, { each: true }) + @IsNotEmpty({ each: true }) + @IsUUID('4', { each: true, message: 'Invalid format of orgRoleId' }) + orgRoleId: string[] +} diff --git a/apps/api-gateway/src/organization/organization.controller.ts b/apps/api-gateway/src/organization/organization.controller.ts index 72f012fe4..36ad73982 100644 --- a/apps/api-gateway/src/organization/organization.controller.ts +++ b/apps/api-gateway/src/organization/organization.controller.ts @@ -1,3 +1,27 @@ +import type { CommonService } from '@credebl/common' +import { TrimStringParamPipe } from '@credebl/common/cast.helper' +import type { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import type IResponse from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { + BadRequestException, + Body, + Controller, + Delete, + Get, + HttpStatus, + Param, + ParseUUIDPipe, + Post, + Put, + Query, + Res, + UseFilters, + UseGuards, + UsePipes, + ValidationPipe, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' import { ApiBearerAuth, ApiExcludeEndpoint, @@ -7,53 +31,29 @@ import { ApiQuery, ApiResponse, ApiTags, - ApiUnauthorizedResponse -} from '@nestjs/swagger'; -import { CommonService } from '@credebl/common'; -import { - Controller, - Get, - Put, - Param, - UseGuards, - UseFilters, - Post, - Body, - Res, - HttpStatus, - Query, - Delete, - ParseUUIDPipe, - BadRequestException, - ValidationPipe, - UsePipes -} from '@nestjs/common'; -import { OrganizationService } from './organization.service'; -import { CreateOrganizationDto } from './dtos/create-organization-dto'; -import IResponse from '@credebl/common/interfaces/response.interface'; -import { Response } from 'express'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { AuthGuard } from '@nestjs/passport'; -import { User } from '../authz/decorators/user.decorator'; -import { user } from '@prisma/client'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { BulkSendInvitationDto } from './dtos/send-invitation.dto'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { UpdateUserRolesDto } from './dtos/update-user-roles.dto'; -import { UpdateOrganizationDto } from './dtos/update-organization-dto'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { IUserRequestInterface } from '../interfaces/IUserRequestInterface'; -import { ClientCredentialsDto } from './dtos/client-credentials.dto'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; -import { validate as isValidUUID } from 'uuid'; -import { UserAccessGuard } from '../authz/guards/user-access-guard'; -import { GetAllOrganizationsDto } from './dtos/get-organizations.dto'; -import { PrimaryDid } from './dtos/set-primary-did.dto'; -import { TrimStringParamPipe } from '@credebl/common/cast.helper'; + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import type { user } from '@prisma/client' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { validate as isValidUUID } from 'uuid' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { UserAccessGuard } from '../authz/guards/user-access-guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { IUserRequestInterface } from '../interfaces/IUserRequestInterface' +import type { ClientCredentialsDto } from './dtos/client-credentials.dto' +import type { CreateOrganizationDto } from './dtos/create-organization-dto' +import type { GetAllOrganizationsDto } from './dtos/get-organizations.dto' +import type { BulkSendInvitationDto } from './dtos/send-invitation.dto' +import type { PrimaryDid } from './dtos/set-primary-did.dto' +import type { UpdateOrganizationDto } from './dtos/update-organization-dto' +import type { UpdateUserRolesDto } from './dtos/update-user-roles.dto' +import type { OrganizationService } from './organization.service' @UseFilters(CustomExceptionFilter) @Controller('orgs') @@ -80,19 +80,19 @@ export class OrganizationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @Res() res: Response ): Promise { - const orgProfile = await this.organizationService.getOrgPofile(orgId); + const orgProfile = await this.organizationService.getOrgPofile(orgId) - const base64Data = orgProfile['logoUrl']; - const getImageBuffer = await this.organizationService.getBase64Image(base64Data); - res.setHeader('Content-Type', 'image/png'); - return res.send(getImageBuffer); + const base64Data = orgProfile.logoUrl + const getImageBuffer = await this.organizationService.getBase64Image(base64Data) + res.setHeader('Content-Type', 'image/png') + return res.send(getImageBuffer) } /** @@ -103,32 +103,32 @@ export class OrganizationController { @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiOperation({ summary: 'Get all public profile organizations', - description: 'Retrieve a list of all public profile organizations. Supports pagination and search.' + description: 'Retrieve a list of all public profile organizations. Supports pagination and search.', }) @ApiQuery({ name: 'pageNumber', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'pageSize', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'search', type: String, - required: false + required: false, }) async get(@Query() paginationDto: PaginationDto, @Res() res: Response): Promise { - const users = await this.organizationService.getPublicOrganizations(paginationDto); + const users = await this.organizationService.getPublicOrganizations(paginationDto) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrganizations, - data: users - }; + data: users, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -139,22 +139,22 @@ export class OrganizationController { @Get('/:orgId/roles') @ApiOperation({ summary: 'Fetch org-roles details', - description: 'Retrieve the roles details for a specific organization.' + description: 'Retrieve the roles details for a specific organization.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @ApiBearerAuth() async getOrgRoles(@Param('orgId') orgId: string, @User() user: user, @Res() res: Response): Promise { - const orgRoles = await this.organizationService.getOrgRoles(orgId.trim(), user); + const orgRoles = await this.organizationService.getOrgRoles(orgId.trim(), user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.fetchOrgRoles, - data: orgRoles - }; + data: orgRoles, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** * Fetch organization details @@ -164,29 +164,29 @@ export class OrganizationController { @Get('public-profiles/:orgSlug') @ApiOperation({ summary: 'Fetch organization details', - description: 'Retrieve the details of a specific organization using its slug.' + description: 'Retrieve the details of a specific organization using its slug.', }) @ApiParam({ name: 'orgSlug', type: String, - required: true + required: true, }) - async getPublicProfile(@Param('orgSlug') orgSlug: string, @Res() res: Response): Promise { - // eslint-disable-next-line no-param-reassign - orgSlug = orgSlug.trim(); - + async getPublicProfile( + @Param('orgSlug', TrimStringParamPipe) orgSlug: string, + @Res() res: Response + ): Promise { if (!orgSlug.length) { - throw new BadRequestException(ResponseMessages.organisation.error.orgSlugIsRequired); + throw new BadRequestException(ResponseMessages.organisation.error.orgSlugIsRequired) } - const userData = await this.organizationService.getPublicProfile(orgSlug); + const userData = await this.organizationService.getPublicProfile(orgSlug) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.fetchProfile, - data: userData - }; + data: userData, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -205,14 +205,14 @@ export class OrganizationController { @Res() res: Response, @User() reqUser: user ): Promise { - const getOrganization = await this.organizationService.getOrganizationDashboard(orgId, reqUser.id); + const getOrganization = await this.organizationService.getOrganizationDashboard(orgId, reqUser.id) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrgDashboard, - data: getOrganization - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getOrganization, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** * Get organization references count @@ -222,7 +222,7 @@ export class OrganizationController { @Get('/activity-count/:orgId') @ApiOperation({ summary: 'Get organization references count', - description: 'Retrieve the count of references for a specific organization.' + description: 'Retrieve the count of references for a specific organization.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -233,22 +233,22 @@ export class OrganizationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @Res() res: Response, @User() reqUser: user ): Promise { - const getOrganization = await this.organizationService.getOrganizationActivityCount(orgId, reqUser.id); + const getOrganization = await this.organizationService.getOrganizationActivityCount(orgId, reqUser.id) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrganizationActivity, - data: getOrganization - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getOrganization, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** * Get all invitations @@ -258,7 +258,7 @@ export class OrganizationController { @Get('/:orgId/invitations') @ApiOperation({ summary: 'Get all invitations', - description: 'Retrieve a list of all invitations for a specific organization. Supports pagination and search.' + description: 'Retrieve a list of all invitations for a specific organization. Supports pagination and search.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -266,17 +266,17 @@ export class OrganizationController { @ApiQuery({ name: 'pageNumber', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'pageSize', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'search', type: String, - required: false + required: false, }) @Roles(OrgRoles.OWNER, OrgRoles.SUPER_ADMIN, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) async getInvitationsByOrgId( @@ -284,14 +284,14 @@ export class OrganizationController { @Query() paginationDto: PaginationDto, @Res() res: Response ): Promise { - const getInvitationById = await this.organizationService.getInvitationsByOrgId(orgId, paginationDto); + const getInvitationById = await this.organizationService.getInvitationsByOrgId(orgId, paginationDto) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getInvitation, - data: getInvitationById - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getInvitationById, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** * Get all organizations @@ -307,14 +307,14 @@ export class OrganizationController { @Res() res: Response, @User() reqUser: user ): Promise { - const getOrganizations = await this.organizationService.getOrganizations(organizationDto, reqUser.id); + const getOrganizations = await this.organizationService.getOrganizations(organizationDto, reqUser.id) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrganizations, - data: getOrganizations - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getOrganizations, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -325,21 +325,21 @@ export class OrganizationController { @Get('/:orgId') @ApiOperation({ summary: 'Get an organization', - description: 'Retrieve the details of a specific organization by its ID.' + description: 'Retrieve the details of a specific organization by its ID.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @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 { - const getOrganization = await this.organizationService.getOrganization(orgId, reqUser.id); + const getOrganization = await this.organizationService.getOrganization(orgId, reqUser.id) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.getOrganization, - data: getOrganization - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getOrganization, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** * Fetch client credentials for an organization @@ -350,7 +350,7 @@ export class OrganizationController { @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @ApiOperation({ summary: 'Fetch client credentials for an organization', - description: 'Fetch client id and secret for an organization' + description: 'Fetch client id and secret for an organization', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -360,13 +360,13 @@ export class OrganizationController { @Res() res: Response, @User() reqUser: user ): Promise { - const orgCredentials = await this.organizationService.fetchOrgCredentials(orgId, reqUser.id); + const orgCredentials = await this.organizationService.fetchOrgCredentials(orgId, reqUser.id) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.fetchedOrgCredentials, - data: orgCredentials - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: orgCredentials, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -382,37 +382,37 @@ export class OrganizationController { @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiOperation({ summary: 'Get organization users list', - description: 'Retrieve a list of users in a specific organization. Supports pagination and search.' + description: 'Retrieve a list of users in a specific organization. Supports pagination and search.', }) @ApiQuery({ name: 'pageNumber', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'pageSize', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'search', type: String, - required: false + required: false, }) async getOrganizationUsers( - @User() user: IUserRequestInterface, + @User() _user: IUserRequestInterface, @Query() paginationDto: PaginationDto, @Param('orgId') orgId: string, @Res() res: Response ): Promise { - const users = await this.organizationService.getOrgUsers(orgId, paginationDto); + const users = await this.organizationService.getOrgUsers(orgId, paginationDto) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchUsers, - data: users - }; + data: users, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -427,17 +427,17 @@ export class OrganizationController { @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiOperation({ summary: 'Fetch organization DIDs', - description: 'Retrieve a list of all DIDs in a specific organization.' + description: 'Retrieve a list of all DIDs in a specific organization.', }) async getAllDidByOrgId(@Param('orgId') orgId: string, @Res() res: Response): Promise { - const users = await this.organizationService.getDidList(orgId); + const users = await this.organizationService.getDidList(orgId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.orgDids, - data: users - }; + data: users, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -448,7 +448,7 @@ export class OrganizationController { @Post('/') @ApiOperation({ summary: 'Create a new Organization', - description: 'Create a new organization with the provided details.' + description: 'Create a new organization with the provided details.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), UserAccessGuard) @@ -459,15 +459,15 @@ export class OrganizationController { @User() reqUser: user ): Promise { // eslint-disable-next-line prefer-destructuring - const keycloakUserId = reqUser.keycloakUserId; + const keycloakUserId = reqUser.keycloakUserId - const orgData = await this.organizationService.createOrganization(createOrgDto, reqUser.id, keycloakUserId); + const orgData = await this.organizationService.createOrganization(createOrgDto, reqUser.id, keycloakUserId) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.organisation.success.create, - data: orgData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: orgData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -487,12 +487,12 @@ export class OrganizationController { @Body() primaryDidPayload: PrimaryDid, @Res() res: Response ): Promise { - await this.organizationService.setPrimaryDid(primaryDidPayload, orgId); + await this.organizationService.setPrimaryDid(primaryDidPayload, orgId) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: ResponseMessages.organisation.success.primaryDid - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + message: ResponseMessages.organisation.success.primaryDid, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** * @@ -505,7 +505,7 @@ export class OrganizationController { @Roles(OrgRoles.OWNER) @ApiOperation({ summary: 'Create credentials for an organization', - description: 'Create client ID and secret for a specific organization.' + description: 'Create client ID and secret for a specific organization.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard, UserAccessGuard) @@ -516,15 +516,15 @@ export class OrganizationController { @User() reqUser: user ): Promise { // eslint-disable-next-line prefer-destructuring - const keycloakUserId = reqUser.keycloakUserId; + const keycloakUserId = reqUser.keycloakUserId - const orgCredentials = await this.organizationService.createOrgCredentials(orgId, reqUser.id, keycloakUserId); + const orgCredentials = await this.organizationService.createOrgCredentials(orgId, reqUser.id, keycloakUserId) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.organisation.success.orgCredentials, - data: orgCredentials - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: orgCredentials, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** * Authenticate client for credentials @@ -535,7 +535,7 @@ export class OrganizationController { @Post('/:clientId/token') @ApiOperation({ summary: 'Authenticate client for credentials', - description: 'Authenticate client using the provided credentials.' + description: 'Authenticate client using the provided credentials.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async clientLoginCredentials( @@ -543,19 +543,19 @@ export class OrganizationController { @Body() clientCredentialsDto: ClientCredentialsDto, @Res() res: Response ): Promise { - clientCredentialsDto.clientId = clientId.trim(); + clientCredentialsDto.clientId = clientId.trim() if (!clientCredentialsDto.clientId) { - throw new BadRequestException(ResponseMessages.organisation.error.clientIdRequired); + throw new BadRequestException(ResponseMessages.organisation.error.clientIdRequired) } - const orgCredentials = await this.organizationService.clientLoginCredentials(clientCredentialsDto); + const orgCredentials = await this.organizationService.clientLoginCredentials(clientCredentialsDto) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.organisation.success.clientCredentials, - data: orgCredentials - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: orgCredentials, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** * Register client and map users @@ -564,21 +564,21 @@ export class OrganizationController { @Post('/register-org-map-users') @ApiOperation({ summary: 'Register client and map users', - description: 'Register a new client and map users to the client.' + description: 'Register a new client and map users to the client.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.PLATFORM_ADMIN) @ApiBearerAuth() @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async registerOrgsMapUsers(@Res() res: Response): Promise { - await this.organizationService.registerOrgsMapUsers(); + await this.organizationService.registerOrgsMapUsers() const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: 'Organization client created and users mapped to client' - }; + message: 'Organization client created and users mapped to client', + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** * Create organization invitation @@ -589,7 +589,7 @@ export class OrganizationController { @Post('/:orgId/invitations') @ApiOperation({ summary: 'Create organization invitation', - description: 'Create an invitation for a specific organization.' + description: 'Create an invitation for a specific organization.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @Roles(OrgRoles.OWNER, OrgRoles.SUPER_ADMIN, OrgRoles.ADMIN) @@ -601,15 +601,15 @@ export class OrganizationController { @User() user: user, @Res() res: Response ): Promise { - bulkInvitationDto.orgId = orgId; - await this.organizationService.createInvitation(bulkInvitationDto, user.id, user.email); + bulkInvitationDto.orgId = orgId + await this.organizationService.createInvitation(bulkInvitationDto, user.id, user.email) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: ResponseMessages.organisation.success.createInvitation - }; + message: ResponseMessages.organisation.success.createInvitation, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** * Update user roles @@ -630,24 +630,24 @@ export class OrganizationController { @Param('userId') userId: string, @Res() res: Response ): Promise { - updateUserDto.orgId = orgId; - updateUserDto.userId = userId.trim(); + updateUserDto.orgId = orgId + updateUserDto.userId = userId.trim() if (!updateUserDto.userId.length) { - throw new BadRequestException(ResponseMessages.organisation.error.userIdIsRequired); + throw new BadRequestException(ResponseMessages.organisation.error.userIdIsRequired) } if (!isValidUUID(updateUserDto.userId)) { - throw new BadRequestException(ResponseMessages.organisation.error.invalidUserId); + throw new BadRequestException(ResponseMessages.organisation.error.invalidUserId) } - await this.organizationService.updateUserRoles(updateUserDto, updateUserDto.userId); + await this.organizationService.updateUserRoles(updateUserDto, updateUserDto.userId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.organisation.success.updateUserRoles - }; + message: ResponseMessages.organisation.success.updateUserRoles, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** * Update an organization @@ -661,7 +661,7 @@ export class OrganizationController { @ApiBearerAuth() @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @ApiParam({ - name: 'orgId' + name: 'orgId', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard, UserAccessGuard) @UsePipes(new ValidationPipe()) @@ -671,22 +671,22 @@ export class OrganizationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(`Invalid format for orgId`); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @Res() res: Response, @User() reqUser: user ): Promise { - updateOrgDto.orgId = orgId; - await this.organizationService.updateOrganization(updateOrgDto, reqUser.id, orgId); + updateOrgDto.orgId = orgId + await this.organizationService.updateOrganization(updateOrgDto, reqUser.id, orgId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.organisation.success.update - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.organisation.success.update, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -706,21 +706,21 @@ export class OrganizationController { TrimStringParamPipe, new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @User() user: user, @Res() res: Response ): Promise { - await this.organizationService.deleteOrganization(orgId, user); + await this.organizationService.deleteOrganization(orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.organisation.success.delete - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.organisation.success.delete, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -739,13 +739,13 @@ export class OrganizationController { @Res() res: Response, @User() user: user ): Promise { - const deleteResponse = await this.organizationService.deleteOrgClientCredentials(orgId, user); + const deleteResponse = await this.organizationService.deleteOrgClientCredentials(orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.ACCEPTED, - message: deleteResponse - }; - return res.status(HttpStatus.ACCEPTED).json(finalResponse); + message: deleteResponse, + } + return res.status(HttpStatus.ACCEPTED).json(finalResponse) } /** @@ -762,24 +762,22 @@ export class OrganizationController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) async deleteOrganizationInvitation( @Param('orgId') orgId: string, - @Param('invitationId') invitationId: string, + @Param('invitationId', TrimStringParamPipe) invitationId: string, @Res() res: Response ): Promise { - // eslint-disable-next-line no-param-reassign - invitationId = invitationId.trim(); if (!invitationId.length) { - throw new BadRequestException(ResponseMessages.organisation.error.invitationIdIsRequired); + throw new BadRequestException(ResponseMessages.organisation.error.invitationIdIsRequired) } if (!isValidUUID(invitationId)) { - throw new BadRequestException(ResponseMessages.organisation.error.invalidInvitationId); + throw new BadRequestException(ResponseMessages.organisation.error.invalidInvitationId) } - await this.organizationService.deleteOrganizationInvitation(orgId, invitationId); + await this.organizationService.deleteOrganizationInvitation(orgId, invitationId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.organisation.success.orgInvitationDeleted - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.organisation.success.orgInvitationDeleted, + } + return res.status(HttpStatus.OK).json(finalResponse) } } diff --git a/apps/api-gateway/src/organization/organization.module.ts b/apps/api-gateway/src/organization/organization.module.ts index bc8da3334..830314abe 100644 --- a/apps/api-gateway/src/organization/organization.module.ts +++ b/apps/api-gateway/src/organization/organization.module.ts @@ -1,15 +1,15 @@ -import { CommonModule, CommonService } from '@credebl/common'; +import { CommonModule, CommonService } from '@credebl/common' -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { ConfigModule } from '@nestjs/config'; -import { HttpModule } from '@nestjs/axios'; -import { Module } from '@nestjs/common'; -import { OrganizationController } from './organization.controller'; -import { OrganizationService } from './organization.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { AwsService } from '@credebl/aws'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { OrganizationController } from './organization.controller' +import { OrganizationService } from './organization.service' @Module({ imports: [ HttpModule, @@ -18,12 +18,12 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.ORGANIZATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED) + options: getNatsOptions(CommonConstants.ORGANIZATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED), }, - CommonModule - ]) + CommonModule, + ]), ], controllers: [OrganizationController], - providers: [OrganizationService, CommonService, AwsService, NATSClient] + providers: [OrganizationService, CommonService, AwsService, NATSClient], }) export class OrganizationModule {} diff --git a/apps/api-gateway/src/organization/organization.service.ts b/apps/api-gateway/src/organization/organization.service.ts index c407385e0..e4aa4d1d6 100644 --- a/apps/api-gateway/src/organization/organization.service.ts +++ b/apps/api-gateway/src/organization/organization.service.ts @@ -1,29 +1,29 @@ -import { Inject } from '@nestjs/common'; -import { Injectable } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { CreateOrganizationDto } from './dtos/create-organization-dto'; -import { BulkSendInvitationDto } from './dtos/send-invitation.dto'; -import { UpdateUserRolesDto } from './dtos/update-user-roles.dto'; -import { UpdateOrganizationDto } from './dtos/update-organization-dto'; -import { organisation, user } from '@prisma/client'; -import { IDidList, IGetOrgById, IGetOrganization } from 'apps/organization/interfaces/organization.interface'; -import { IOrgUsers } from 'apps/user/interfaces/user.interface'; -import { +import type { IClientRoles } from '@credebl/client-registration/interfaces/client.interface' +import type { NATSClient } from '@credebl/common/NATSClient' +import type { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import type { IAccessTokenData } from '@credebl/common/interfaces/interface' +import type { + IDeleteOrganization, + IOrgActivityCount, IOrgCredentials, IOrganization, - IOrganizationInvitations, IOrganizationDashboard, - IDeleteOrganization, - IOrgActivityCount -} from '@credebl/common/interfaces/organization.interface'; -import { ClientCredentialsDto } from './dtos/client-credentials.dto'; -import { IAccessTokenData } from '@credebl/common/interfaces/interface'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; -import { IClientRoles } from '@credebl/client-registration/interfaces/client.interface'; -import { GetAllOrganizationsDto } from './dtos/get-organizations.dto'; -import { PrimaryDid } from './dtos/set-primary-did.dto'; -import { NATSClient } from '@credebl/common/NATSClient'; + IOrganizationInvitations, +} from '@credebl/common/interfaces/organization.interface' +import { Inject } from '@nestjs/common' +import { Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { organisation, user } from '@prisma/client' +import type { IDidList, IGetOrgById, IGetOrganization } from 'apps/organization/interfaces/organization.interface' +import type { IOrgUsers } from 'apps/user/interfaces/user.interface' +import { BaseService } from 'libs/service/base.service' +import type { ClientCredentialsDto } from './dtos/client-credentials.dto' +import type { CreateOrganizationDto } from './dtos/create-organization-dto' +import type { GetAllOrganizationsDto } from './dtos/get-organizations.dto' +import type { BulkSendInvitationDto } from './dtos/send-invitation.dto' +import type { PrimaryDid } from './dtos/set-primary-did.dto' +import type { UpdateOrganizationDto } from './dtos/update-organization-dto' +import type { UpdateUserRolesDto } from './dtos/update-user-roles.dto' @Injectable() export class OrganizationService extends BaseService { @@ -31,7 +31,7 @@ export class OrganizationService extends BaseService { @Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, private readonly natsClient: NATSClient ) { - super('OrganizationService'); + super('OrganizationService') } /** @@ -44,8 +44,8 @@ export class OrganizationService extends BaseService { userId: string, keycloakUserId: string ): Promise { - const payload = { createOrgDto, userId, keycloakUserId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'create-organization', payload); + const payload = { createOrgDto, userId, keycloakUserId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'create-organization', payload) } /** @@ -54,9 +54,9 @@ export class OrganizationService extends BaseService { * @returns Set Primary Did for organization */ async setPrimaryDid(primaryDidPayload: PrimaryDid, orgId: string): Promise { - const { did, id } = primaryDidPayload; - const payload = { did, orgId, id }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'set-primary-did', payload); + const { did, id } = primaryDidPayload + const payload = { did, orgId, id } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'set-primary-did', payload) } /** @@ -66,8 +66,8 @@ export class OrganizationService extends BaseService { * @returns Orgnization client credentials */ async createOrgCredentials(orgId: string, userId: string, keycloakUserId: string): Promise { - const payload = { orgId, userId, keycloakUserId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'create-org-credentials', payload); + const payload = { orgId, userId, keycloakUserId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'create-org-credentials', payload) } /** @@ -76,8 +76,8 @@ export class OrganizationService extends BaseService { * @returns Organization update Success */ async updateOrganization(updateOrgDto: UpdateOrganizationDto, userId: string, orgId: string): Promise { - const payload = { updateOrgDto, userId, orgId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-organization', payload); + const payload = { updateOrgDto, userId, orgId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-organization', payload) } /** @@ -86,7 +86,7 @@ export class OrganizationService extends BaseService { * @returns Organization details with owner */ async findOrganizationOwner(orgId: string): Promise { - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-owner', orgId); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-owner', orgId) } /** @@ -96,9 +96,9 @@ export class OrganizationService extends BaseService { */ async getOrganizations(organizationDto: GetAllOrganizationsDto, userId: string): Promise { - const payload = { userId, ...organizationDto }; - const fetchOrgs = await this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organizations', payload); - return fetchOrgs; + const payload = { userId, ...organizationDto } + const fetchOrgs = await this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organizations', payload) + return fetchOrgs } /** @@ -107,17 +107,17 @@ export class OrganizationService extends BaseService { * @returns Public organizations list */ async getPublicOrganizations(paginationDto: PaginationDto): Promise { - const payload = { ...paginationDto }; - const PublicOrg = this.natsClient.sendNatsMessage(this.serviceProxy, 'get-public-organizations', payload); - return PublicOrg; + const payload = { ...paginationDto } + const PublicOrg = this.natsClient.sendNatsMessage(this.serviceProxy, 'get-public-organizations', payload) + return PublicOrg } async getPublicProfile(orgSlug: string): Promise { - const payload = { orgSlug }; + const payload = { orgSlug } try { - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-public-profile', payload); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-public-profile', payload) } catch (error) { - this.logger.error(`Error in get user:${JSON.stringify(error)}`); + this.logger.error(`Error in get user:${JSON.stringify(error)}`) } } @@ -127,13 +127,13 @@ export class OrganizationService extends BaseService { * @returns Organization get Success */ async getOrganization(orgId: string, userId: string): Promise { - const payload = { orgId, userId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-by-id', payload); + const payload = { orgId, userId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-by-id', payload) } async fetchOrgCredentials(orgId: string, userId: string): Promise { - const payload = { orgId, userId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-org-client-credentials', payload); + const payload = { orgId, userId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-org-client-credentials', payload) } /** @@ -142,19 +142,19 @@ export class OrganizationService extends BaseService { * @returns Invitations details */ async getInvitationsByOrgId(orgId: string, pagination: PaginationDto): Promise { - const { pageNumber, pageSize, search } = pagination; - const payload = { orgId, pageNumber, pageSize, search }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-invitations-by-orgId', payload); + const { pageNumber, pageSize, search } = pagination + const payload = { orgId, pageNumber, pageSize, search } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-invitations-by-orgId', payload) } async getOrganizationDashboard(orgId: string, userId: string): Promise { - const payload = { orgId, userId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-dashboard', payload); + const payload = { orgId, userId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-dashboard', payload) } async getOrganizationActivityCount(orgId: string, userId: string): Promise { - const payload = { orgId, userId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-activity-count', payload); + const payload = { orgId, userId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-organization-activity-count', payload) } /** @@ -164,8 +164,8 @@ export class OrganizationService extends BaseService { */ async getOrgRoles(orgId: string, user: user): Promise { - const payload = { orgId, user }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-org-roles', payload); + const payload = { orgId, user } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-org-roles', payload) } /** @@ -174,13 +174,13 @@ export class OrganizationService extends BaseService { * @returns Organization invitation creation Success */ async createInvitation(bulkInvitationDto: BulkSendInvitationDto, userId: string, userEmail: string): Promise { - const payload = { bulkInvitationDto, userId, userEmail }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'send-invitation', payload); + const payload = { bulkInvitationDto, userId, userEmail } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'send-invitation', payload) } async registerOrgsMapUsers(): Promise { - const payload = {}; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'register-orgs-users-map', payload); + const payload = {} + return this.natsClient.sendNatsMessage(this.serviceProxy, 'register-orgs-users-map', payload) } /** @@ -190,52 +190,52 @@ export class OrganizationService extends BaseService { * @returns User roles update response */ async updateUserRoles(updateUserDto: UpdateUserRolesDto, userId: string): Promise { - const payload = { orgId: updateUserDto.orgId, roleIds: updateUserDto.orgRoleId, userId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-user-roles', payload); + const payload = { orgId: updateUserDto.orgId, roleIds: updateUserDto.orgRoleId, userId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-user-roles', payload) } async getOrgUsers(orgId: string, paginationDto: PaginationDto): Promise { - const { pageNumber, pageSize, search } = paginationDto; - const payload = { orgId, pageNumber, pageSize, search }; + const { pageNumber, pageSize, search } = paginationDto + const payload = { orgId, pageNumber, pageSize, search } - return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-organization-user', payload); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-organization-user', payload) } async getDidList(orgId: string): Promise { - const payload = { orgId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-organization-dids', payload); + const payload = { orgId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-organization-dids', payload) } async getOrgPofile(orgId: string): Promise { - const payload = { orgId }; + const payload = { orgId } - return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-organization-profile', payload); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-organization-profile', payload) } async deleteOrganization(orgId: string, user: user): Promise { - const payload = { orgId, user }; + const payload = { orgId, user } - return this.natsClient.sendNatsMessage(this.serviceProxy, 'delete-organization', payload); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'delete-organization', payload) } async deleteOrgClientCredentials(orgId: string, user: user): Promise { - const payload = { orgId, user }; + const payload = { orgId, user } - return this.natsClient.sendNatsMessage(this.serviceProxy, 'delete-org-client-credentials', payload); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'delete-org-client-credentials', payload) } async deleteOrganizationInvitation(orgId: string, invitationId: string): Promise { - const payload = { orgId, invitationId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'delete-organization-invitation', payload); + const payload = { orgId, invitationId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'delete-organization-invitation', payload) } async clientLoginCredentials(clientCredentialsDto: ClientCredentialsDto): Promise { - return this.natsClient.sendNatsMessage(this.serviceProxy, 'authenticate-client-credentials', clientCredentialsDto); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'authenticate-client-credentials', clientCredentialsDto) } getBase64Image(base64Image: string): Buffer { - const base64Data = base64Image.replace(/^data:image\/\w+;base64,/, ''); - const imageBuffer = Buffer.from(base64Data, 'base64'); - return imageBuffer; + const base64Data = base64Image.replace(/^data:image\/\w+;base64,/, '') + const imageBuffer = Buffer.from(base64Data, 'base64') + return imageBuffer } } diff --git a/apps/api-gateway/src/platform/platform.controller.spec.ts b/apps/api-gateway/src/platform/platform.controller.spec.ts index 8cb1a53a9..5bebc5122 100644 --- a/apps/api-gateway/src/platform/platform.controller.spec.ts +++ b/apps/api-gateway/src/platform/platform.controller.spec.ts @@ -1,74 +1,69 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { plainToClass } from 'class-transformer'; -import { validate } from 'class-validator'; -import { PlatformController } from './platform.controller'; -import { PlatformService } from './platform.service'; -import { SortValue } from './platform.model'; +import { Test, TestingModule } from '@nestjs/testing' +import { PlatformController } from './platform.controller' +import { SortValue } from './platform.model' +import { PlatformService } from './platform.service' describe('Credentia lDefinitionController Test Cases', () => { - let controller: PlatformController; - const mockCredentialDefinitionService = { - connectedHolderList: jest.fn(() => ({})), - getCredentialListByConnectionId: jest.fn(() => ({})), - pingServicePlatform: jest.fn(() => ({})) - }; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [PlatformController], - providers: [PlatformService] - }) - .overrideProvider(PlatformService) - .useValue(mockCredentialDefinitionService) - .compile(); - controller = module.get( - PlatformController - ); - }); - - describe('connected holder list', () => { - const itemsPerPage: any = 1; - const page: any = 1; - const searchText: any = 'abc'; - const orgId: any = 13; - const connectionSortBy: any = 'xyz'; - const sortValue: any = 'asdd'; - it('should return an expected connected holder list', async () => { - const result = await controller.connectedHolderList( - itemsPerPage, - page, - searchText, - orgId, - connectionSortBy, - sortValue - ); - expect(result).toEqual({}); - }); - }); - describe('get credential list by connection id', () => { - const connectionId = 'jhkh'; - const itemsPerPage = 10; - const page = 1; - const searchText = 'abc'; - const sortValue:any = SortValue; - const credentialSortBy = 'ddcc'; - it('should return an expected credential list by connection id', async () => { - const result = await controller.getCredentialListByConnectionId( - connectionId, - itemsPerPage, - page, - searchText, - sortValue, - credentialSortBy - ); - expect(result).toEqual({}); - }); - }); - describe('get the platform service status', () => { - it('should return an expected platform service status', async () => { - const result = await controller.pingServicePlatform(); - expect(result).toEqual({}); - }); - }); - }); - \ No newline at end of file + let controller: PlatformController + const mockCredentialDefinitionService = { + connectedHolderList: jest.fn(() => ({})), + getCredentialListByConnectionId: jest.fn(() => ({})), + pingServicePlatform: jest.fn(() => ({})), + } + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [PlatformController], + providers: [PlatformService], + }) + .overrideProvider(PlatformService) + .useValue(mockCredentialDefinitionService) + .compile() + controller = module.get(PlatformController) + }) + + describe('connected holder list', () => { + const itemsPerPage: any = 1 + const page: any = 1 + const searchText: any = 'abc' + const orgId: any = 13 + const connectionSortBy: any = 'xyz' + const sortValue: any = 'asdd' + it('should return an expected connected holder list', async () => { + const result = await controller.connectedHolderList( + itemsPerPage, + page, + searchText, + orgId, + connectionSortBy, + sortValue + ) + expect(result).toEqual({}) + }) + }) + describe('get credential list by connection id', () => { + const connectionId = 'jhkh' + const itemsPerPage = 10 + const page = 1 + const searchText = 'abc' + const sortValue: any = SortValue + const credentialSortBy = 'ddcc' + it('should return an expected credential list by connection id', async () => { + const result = await controller.getCredentialListByConnectionId( + connectionId, + itemsPerPage, + page, + searchText, + sortValue, + credentialSortBy + ) + expect(result).toEqual({}) + }) + }) + describe('get the platform service status', () => { + it('should return an expected platform service status', async () => { + const result = await controller.pingServicePlatform() + expect(result).toEqual({}) + }) + }) +}) diff --git a/apps/api-gateway/src/platform/platform.controller.ts b/apps/api-gateway/src/platform/platform.controller.ts index 3f1c2b35f..382ca42ca 100644 --- a/apps/api-gateway/src/platform/platform.controller.ts +++ b/apps/api-gateway/src/platform/platform.controller.ts @@ -1,210 +1,213 @@ -import { BadRequestException, Controller, Get, HttpStatus, Logger, Param, Query, Res, UseFilters, UseGuards } from '@nestjs/common'; -import { PlatformService } from './platform.service'; -import { ApiBearerAuth, ApiExcludeEndpoint, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -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 { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; -import { IResponse } from '@credebl/common/interfaces/response.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { AuthGuard } from '@nestjs/passport'; -import * as QRCode from 'qrcode'; -import { CredDefSortFields, SchemaType, SortFields } from '@credebl/enum/enum'; -import { GetAllPlatformCredDefsDto } from '../credential-definition/dto/get-all-platform-cred-defs.dto'; -import { TrimStringParamPipe } from '@credebl/common/cast.helper'; +import { TrimStringParamPipe } from '@credebl/common/cast.helper' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { CredDefSortFields, SchemaType, SortFields } from '@credebl/enum/enum' +import { + BadRequestException, + Controller, + Get, + HttpStatus, + Logger, + Param, + Query, + Res, + UseFilters, + UseGuards, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' +import { ApiBearerAuth, ApiExcludeEndpoint, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import * as QRCode from 'qrcode' +import { User } from '../authz/decorators/user.decorator' +import type { GetAllPlatformCredDefsDto } from '../credential-definition/dto/get-all-platform-cred-defs.dto' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import type { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface' +import type { IUserRequestInterface } from '../interfaces/IUserRequestInterface' +import type { GetAllSchemaByPlatformDto } from '../schema/dtos/get-all-schema.dto' +import type { PlatformService } from './platform.service' @Controller('') @UseFilters(CustomExceptionFilter) export class PlatformController { - constructor(private readonly platformService: PlatformService) { } + constructor(private readonly platformService: PlatformService) {} - private readonly logger = new Logger('PlatformController'); + private readonly logger = new Logger('PlatformController') - /** - * Retrieves all schemas available on the platform with optional filters and sorting. - * - * @param ledgerId The ID of the ledger. - * @param schemaType Type of schema to filter results. - * - * @returns A paginated list of schemas based on the provided criteria. - */ - @Get('/platform/schemas') - @ApiTags('schemas') - @ApiOperation({ - summary: 'Get all schemas from platform.', - description: 'Retrieves all schemas available on the platform' - }) - @ApiQuery({ - name: 'sortField', - enum: SortFields, - required: false - }) - @ApiQuery({ - name: 'schemaType', - enum: SchemaType, - required: false - }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt')) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getAllSchema( - @Query() getAllSchemaDto: GetAllSchemaByPlatformDto, - @Res() res: Response, - @User() user: IUserRequestInterface - ): Promise { - const { ledgerId, pageSize, searchByText, pageNumber, sorting, sortByValue, schemaType } = getAllSchemaDto; - const schemaSearchCriteria: ISchemaSearchPayload = { - ledgerId, - pageNumber, - searchByText, - pageSize, - sortField: sorting, - sortBy: sortByValue, - schemaType - }; - const schemasResponse = await this.platformService.getAllSchema(schemaSearchCriteria, user); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.schema.success.fetch, - data: schemasResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Retrieves all schemas available on the platform with optional filters and sorting. + * + * @param ledgerId The ID of the ledger. + * @param schemaType Type of schema to filter results. + * + * @returns A paginated list of schemas based on the provided criteria. + */ + @Get('/platform/schemas') + @ApiTags('schemas') + @ApiOperation({ + summary: 'Get all schemas from platform.', + description: 'Retrieves all schemas available on the platform', + }) + @ApiQuery({ + name: 'sortField', + enum: SortFields, + required: false, + }) + @ApiQuery({ + name: 'schemaType', + enum: SchemaType, + required: false, + }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt')) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getAllSchema( + @Query() getAllSchemaDto: GetAllSchemaByPlatformDto, + @Res() res: Response, + @User() user: IUserRequestInterface + ): Promise { + const { ledgerId, pageSize, searchByText, pageNumber, sorting, sortByValue, schemaType } = getAllSchemaDto + const schemaSearchCriteria: ISchemaSearchPayload = { + ledgerId, + pageNumber, + searchByText, + pageSize, + sortField: sorting, + sortBy: sortByValue, + schemaType, } + const schemasResponse = await this.platformService.getAllSchema(schemaSearchCriteria, user) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.schema.success.fetch, + data: schemasResponse, + } + return res.status(HttpStatus.OK).json(finalResponse) + } -/** - * Retrieves all credential definitions available on the platform. - * - * @returns A list of credential definitions and their details. - */ - @Get('/platform/cred-defs') - @ApiTags('credential-definitions') - @ApiOperation({ - summary: 'Get all credential-definitions from platform.', - description: 'Retrieves all credential definitions available on the platform' - }) - @ApiQuery({ - name: 'sortField', - enum: CredDefSortFields, - required: false - }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt')) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getAllCredDefs( - @Query() getAllPlatformCredDefs: GetAllPlatformCredDefsDto, - @Res() res: Response, - @User() user: IUserRequestInterface - ): Promise { - const schemasResponse = await this.platformService.getAllPlatformCredDefs(getAllPlatformCredDefs, user); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.credentialDefinition.success.fetch, - data: schemasResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + /** + * Retrieves all credential definitions available on the platform. + * + * @returns A list of credential definitions and their details. + */ + @Get('/platform/cred-defs') + @ApiTags('credential-definitions') + @ApiOperation({ + summary: 'Get all credential-definitions from platform.', + description: 'Retrieves all credential definitions available on the platform', + }) + @ApiQuery({ + name: 'sortField', + enum: CredDefSortFields, + required: false, + }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt')) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getAllCredDefs( + @Query() getAllPlatformCredDefs: GetAllPlatformCredDefsDto, + @Res() res: Response, + @User() user: IUserRequestInterface + ): Promise { + const schemasResponse = await this.platformService.getAllPlatformCredDefs(getAllPlatformCredDefs, user) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.credentialDefinition.success.fetch, + data: schemasResponse, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Retrieves all available ledgers from the platform. - * - * @returns A list of ledgers and their details. - */ - @Get('/platform/ledgers') - @ApiTags('ledgers') - @ApiOperation({ - summary: 'Get all ledgers from platform.', - description: 'Retrieves a list of all available ledgers on platform.' - }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt')) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getAllLedgers( - @Res() res: Response - ): Promise { - const networksResponse = await this.platformService.getAllLedgers(); + /** + * Retrieves all available ledgers from the platform. + * + * @returns A list of ledgers and their details. + */ + @Get('/platform/ledgers') + @ApiTags('ledgers') + @ApiOperation({ + summary: 'Get all ledgers from platform.', + description: 'Retrieves a list of all available ledgers on platform.', + }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt')) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getAllLedgers(@Res() res: Response): Promise { + const networksResponse = await this.platformService.getAllLedgers() - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.ledger.success.fetch, - data: networksResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.ledger.success.fetch, + data: networksResponse, } + return res.status(HttpStatus.OK).json(finalResponse) + } - /** - * Retrieves the network URL associated with a specific ledger namespace. - * - * @param indyNamespace The namespace of the ledger. - * @returns The network URL for the specified ledger. - */ - @Get('/platform/network/url/:indyNamespace') - @ApiTags('ledgers') - @ApiOperation({ - summary: 'Get network url from platform.', - description: 'Retrieves the network URL for a specified ledger namespace.' - }) - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt')) - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getNetwrkUrl( - @Param('indyNamespace', TrimStringParamPipe) indyNamespace: string, - @Res() res: Response - ): Promise { - if (!indyNamespace) { - throw new BadRequestException(ResponseMessages.ledger.error.indyNamespaceisRequired); - } - const networksResponse = await this.platformService.getNetworkUrl(indyNamespace); + /** + * Retrieves the network URL associated with a specific ledger namespace. + * + * @param indyNamespace The namespace of the ledger. + * @returns The network URL for the specified ledger. + */ + @Get('/platform/network/url/:indyNamespace') + @ApiTags('ledgers') + @ApiOperation({ + summary: 'Get network url from platform.', + description: 'Retrieves the network URL for a specified ledger namespace.', + }) + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt')) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getNetwrkUrl( + @Param('indyNamespace', TrimStringParamPipe) indyNamespace: string, + @Res() res: Response + ): Promise { + if (!indyNamespace) { + throw new BadRequestException(ResponseMessages.ledger.error.indyNamespaceisRequired) + } + const networksResponse = await this.platformService.getNetworkUrl(indyNamespace) - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.ledger.success.fetchNetworkUrl, - data: networksResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.ledger.success.fetchNetworkUrl, + data: networksResponse, } + return res.status(HttpStatus.OK).json(finalResponse) + } - @Get('/invitation/:referenceId') - @ApiOperation({ - summary: `Get shortening url by referenceId`, - description: `Get shortening url by referenceId` - }) - @ApiExcludeEndpoint() - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getShorteningUrlById( - @Param('referenceId') referenceId: string, - @Res() res: Response - ): Promise { - const shorteningUrlDetails = await this.platformService.getShorteningUrlById(referenceId); - const finalResponse: IResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.shorteningUrl.success.getshorteningUrl, - data: shorteningUrlDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + @Get('/invitation/:referenceId') + @ApiOperation({ + summary: 'Get shortening url by referenceId', + description: 'Get shortening url by referenceId', + }) + @ApiExcludeEndpoint() + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getShorteningUrlById(@Param('referenceId') referenceId: string, @Res() res: Response): Promise { + const shorteningUrlDetails = await this.platformService.getShorteningUrlById(referenceId) + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.shorteningUrl.success.getshorteningUrl, + data: shorteningUrlDetails, } + return res.status(HttpStatus.OK).json(finalResponse) + } - @Get('/invitation/qr-code/:referenceId') - @ApiOperation({ - summary: `Get QR by referenceId`, - description: `Get QR by referenceId` - }) - @ApiExcludeEndpoint() - @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) - async getQrCode( - @Param('referenceId') referenceId: string, - @Res() res: Response - ): Promise { - const url = `${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}/invitation/${referenceId}`; - // Generate QR code as a buffer - const qrCodeBuffer = await QRCode.toBuffer(url); + @Get('/invitation/qr-code/:referenceId') + @ApiOperation({ + summary: 'Get QR by referenceId', + description: 'Get QR by referenceId', + }) + @ApiExcludeEndpoint() + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getQrCode(@Param('referenceId') referenceId: string, @Res() res: Response): Promise { + const url = `${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}/invitation/${referenceId}` + // Generate QR code as a buffer + const qrCodeBuffer = await QRCode.toBuffer(url) - // Set response type to image/png - res.type('image/png'); + // Set response type to image/png + res.type('image/png') - // Send the QR code buffer as the response - res.send(qrCodeBuffer); - } + // Send the QR code buffer as the response + res.send(qrCodeBuffer) + } } diff --git a/apps/api-gateway/src/platform/platform.interface.ts b/apps/api-gateway/src/platform/platform.interface.ts index 7679b3ad0..e42c9cdd1 100644 --- a/apps/api-gateway/src/platform/platform.interface.ts +++ b/apps/api-gateway/src/platform/platform.interface.ts @@ -1,33 +1,32 @@ -import { credentialSortBy } from '../enum'; +import type { credentialSortBy } from '../enum' export enum SortValue { - ASC = 'ASC', - DESC = 'DESC' + ASC = 'ASC', + DESC = 'DESC', } export interface IConnectedHolderList { - orgId: string; - itemsPerPage?: number; - page?: number; - searchText?: string; - connectionSortBy?: string; - sortValue?: string; + orgId: string + itemsPerPage?: number + page?: number + searchText?: string + connectionSortBy?: string + sortValue?: string } - export interface CredentialListPayload { - connectionId: string; - itemsPerPage: number; - page: number; - searchText: string; - sortValue: SortValue; - credentialSortBy: string; + connectionId: string + itemsPerPage: number + page: number + searchText: string + sortValue: SortValue + credentialSortBy: string } export interface GetCredentialListByConnectionId { - connectionId: string, - items_per_page: number, - page: number, - search_text: string, - sortValue: SortValue, - sortBy: credentialSortBy -} \ No newline at end of file + connectionId: string + items_per_page: number + page: number + search_text: string + sortValue: SortValue + sortBy: credentialSortBy +} diff --git a/apps/api-gateway/src/platform/platform.module.ts b/apps/api-gateway/src/platform/platform.module.ts index d169ee4cf..0039ba327 100644 --- a/apps/api-gateway/src/platform/platform.module.ts +++ b/apps/api-gateway/src/platform/platform.module.ts @@ -1,11 +1,11 @@ -import { Module } from '@nestjs/common'; -import { PlatformController } from './platform.controller'; -import { PlatformService } from './platform.service'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { ConfigModule } from '@nestjs/config'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { PlatformController } from './platform.controller' +import { PlatformService } from './platform.service' @Module({ imports: [ ConfigModule.forRoot(), @@ -13,11 +13,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.PLATFORM_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } - ]) + options: getNatsOptions(CommonConstants.PLATFORM_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [PlatformController], - providers: [PlatformService, NATSClient] + providers: [PlatformService, NATSClient], }) export class PlatformModule {} diff --git a/apps/api-gateway/src/platform/platform.service.ts b/apps/api-gateway/src/platform/platform.service.ts index 36838b02d..60fec7987 100644 --- a/apps/api-gateway/src/platform/platform.service.ts +++ b/apps/api-gateway/src/platform/platform.service.ts @@ -1,45 +1,46 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from '../../../../libs/service/base.service'; -import { ILedgers, ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; -import { IUserRequestInterface } from '../interfaces/IUserRequestInterface'; -import { INetworkUrl, ISchemaDetails } from '@credebl/common/interfaces/schema.interface'; -import { GetAllPlatformCredDefsDto } from '../credential-definition/dto/get-all-platform-cred-defs.dto'; -import { IPlatformCredDefsData } from '@credebl/common/interfaces/cred-def.interface'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { IPlatformCredDefsData } from '@credebl/common/interfaces/cred-def.interface' +import type { INetworkUrl, ISchemaDetails } from '@credebl/common/interfaces/schema.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from '../../../../libs/service/base.service' +import type { GetAllPlatformCredDefsDto } from '../credential-definition/dto/get-all-platform-cred-defs.dto' +import type { ILedgers, ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface' +import type { IUserRequestInterface } from '../interfaces/IUserRequestInterface' @Injectable() export class PlatformService extends BaseService { - constructor( - @Inject('NATS_CLIENT') private readonly platformServiceProxy: ClientProxy, - private readonly natsClient : NATSClient - ) { - super('PlatformService'); - } + constructor( + @Inject('NATS_CLIENT') private readonly platformServiceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('PlatformService') + } - async getAllSchema(schemaSearchCriteria: ISchemaSearchPayload, user: IUserRequestInterface): Promise { - const schemaSearch = { schemaSearchCriteria, user }; - return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-all-schemas', schemaSearch); + async getAllSchema(schemaSearchCriteria: ISchemaSearchPayload, user: IUserRequestInterface): Promise { + const schemaSearch = { schemaSearchCriteria, user } + return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-all-schemas', schemaSearch) + } - } + async getAllPlatformCredDefs( + getAllPlatformCredDefs: GetAllPlatformCredDefsDto, + user: IUserRequestInterface + ): Promise { + const credDefs = { ...getAllPlatformCredDefs, user } + return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-all-platform-cred-defs', credDefs) + } - async getAllPlatformCredDefs(getAllPlatformCredDefs: GetAllPlatformCredDefsDto, user: IUserRequestInterface): Promise { - const credDefs = { ...getAllPlatformCredDefs, user }; - return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-all-platform-cred-defs', credDefs); - } + async getAllLedgers(): Promise { + const payload = {} + return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-all-ledgers', payload) + } - async getAllLedgers(): Promise { - const payload = {}; - return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-all-ledgers', payload); - } + async getNetworkUrl(indyNamespace: string): Promise { + return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-network-url', indyNamespace) + } - async getNetworkUrl(indyNamespace: string): Promise { - return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-network-url', indyNamespace); - } - - async getShorteningUrlById(referenceId: string): Promise { - - // NATS call - return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-shortening-url', referenceId); - } -} \ No newline at end of file + async getShorteningUrlById(referenceId: string): Promise { + // NATS call + return this.natsClient.sendNatsMessage(this.platformServiceProxy, 'get-shortening-url', referenceId) + } +} diff --git a/apps/api-gateway/src/revocation/revocation.controller.ts b/apps/api-gateway/src/revocation/revocation.controller.ts index 6a3969404..239d6af18 100644 --- a/apps/api-gateway/src/revocation/revocation.controller.ts +++ b/apps/api-gateway/src/revocation/revocation.controller.ts @@ -1,75 +1,74 @@ -import { Controller, Logger } from '@nestjs/common'; -import { ApiBearerAuth } from '@nestjs/swagger'; -import { RevocationService } from './revocation.service'; +import { Controller, Logger } from '@nestjs/common' +import { ApiBearerAuth } from '@nestjs/swagger' +import type { RevocationService } from './revocation.service' @ApiBearerAuth() @Controller() export class RevocationController { + private readonly logger = new Logger('RevocationController') - private readonly logger = new Logger('RevocationController'); + constructor(private readonly revocationService: RevocationService) {} - constructor(private readonly revocationService: RevocationService) { } + // @UseGuards(AuthGuard('jwt')) + // @Post('/revocation/create-registry') + // @ApiTags('revocation-registry') + // @ApiOperation({ summary: 'Creates a new revocation registry' }) + // @ApiResponse({ status: HttpStatus.CREATED, description: 'Create Revocation Registry' }) + // createRevocationRegistry( + // @Body() createRevocationRegistryDto: CreateRevocationRegistryDto, + // @GetUser() user: any + // ) { + // return this.revocationService.createRevocationRegistry(createRevocationRegistryDto, user); + // } - // @UseGuards(AuthGuard('jwt')) - // @Post('/revocation/create-registry') - // @ApiTags('revocation-registry') - // @ApiOperation({ summary: 'Creates a new revocation registry' }) - // @ApiResponse({ status: HttpStatus.CREATED, description: 'Create Revocation Registry' }) - // createRevocationRegistry( - // @Body() createRevocationRegistryDto: CreateRevocationRegistryDto, - // @GetUser() user: any - // ) { - // return this.revocationService.createRevocationRegistry(createRevocationRegistryDto, user); - // } + // @UseGuards(AuthGuard('jwt')) + // @Post('/revocation/registry/update-uri') + // @ApiTags('revocation-registry') + // @ApiOperation({ summary: 'Update revocation registry with new public URI to the tails file.' }) + // @ApiResponse({ status: HttpStatus.CREATED, description: 'Update revocation registry with new public URI to the tails file.' }) + // updateRevocationRegistryUri( + // @Body() updateRevocationRegistryUriDto: UpdateRevocationRegistryUriDto, + // @GetUser() user: any + // ) { + // return this.revocationService.updateRevocationRegistryUri(updateRevocationRegistryUriDto, user); + // } - // @UseGuards(AuthGuard('jwt')) - // @Post('/revocation/registry/update-uri') - // @ApiTags('revocation-registry') - // @ApiOperation({ summary: 'Update revocation registry with new public URI to the tails file.' }) - // @ApiResponse({ status: HttpStatus.CREATED, description: 'Update revocation registry with new public URI to the tails file.' }) - // updateRevocationRegistryUri( - // @Body() updateRevocationRegistryUriDto: UpdateRevocationRegistryUriDto, - // @GetUser() user: any - // ) { - // return this.revocationService.updateRevocationRegistryUri(updateRevocationRegistryUriDto, user); - // } + // @UseGuards(AuthGuard('jwt')) + // @Get('/revocation/active-registry') + // @ApiTags('revocation-registry') + // @ApiQuery({ name: 'cred_def_id', required: true }) + // @ApiOperation({ summary: 'Get an active revocation registry by credential definition id' }) + // @ApiResponse({ status: HttpStatus.OK, description: 'Get an active revocation registry by credential definition id' }) + // activeRevocationRegistry( + // @Query('cred_def_id') cred_def_id: string, + // @GetUser() user: any + // ) { + // return this.revocationService.activeRevocationRegistry(cred_def_id, user); + // } - // @UseGuards(AuthGuard('jwt')) - // @Get('/revocation/active-registry') - // @ApiTags('revocation-registry') - // @ApiQuery({ name: 'cred_def_id', required: true }) - // @ApiOperation({ summary: 'Get an active revocation registry by credential definition id' }) - // @ApiResponse({ status: HttpStatus.OK, description: 'Get an active revocation registry by credential definition id' }) - // activeRevocationRegistry( - // @Query('cred_def_id') cred_def_id: string, - // @GetUser() user: any - // ) { - // return this.revocationService.activeRevocationRegistry(cred_def_id, user); - // } + // @UseGuards(AuthGuard('jwt')) + // @Post('/revocation/registry/publish') + // @ApiQuery({ name: 'rev_reg_id', required: true }) + // @ApiTags('revocation-registry') + // @ApiOperation({ summary: 'Publish a given revocation registry' }) + // @ApiResponse({ status: HttpStatus.CREATED, description: 'Publish a given revocation registry' }) + // publishRevocationRegistry( + // @Query('rev_reg_id') revocationId: string, + // @GetUser() user: any + // ) { + // return this.revocationService.publishRevocationRegistry(revocationId, user); + // } - // @UseGuards(AuthGuard('jwt')) - // @Post('/revocation/registry/publish') - // @ApiQuery({ name: 'rev_reg_id', required: true }) - // @ApiTags('revocation-registry') - // @ApiOperation({ summary: 'Publish a given revocation registry' }) - // @ApiResponse({ status: HttpStatus.CREATED, description: 'Publish a given revocation registry' }) - // publishRevocationRegistry( - // @Query('rev_reg_id') revocationId: string, - // @GetUser() user: any - // ) { - // return this.revocationService.publishRevocationRegistry(revocationId, user); - // } - - // @UseGuards(AuthGuard('jwt')) - // @Get('/revocation/registry') - // @ApiTags('revocation-registry') - // @ApiQuery({ name: 'rev_reg_id', required: true }) - // @ApiOperation({ summary: 'Get revocation registry by revocation registry id' }) - // @ApiResponse({ status: HttpStatus.OK, description: 'Get revocation registry by revocation registry id' }) - // getRevocationRegistry( - // @Query() rev_reg_id: string, - // @GetUser() user: any - // ) { - // return this.revocationService.getRevocationRegistry(rev_reg_id, user); - // } -} \ No newline at end of file + // @UseGuards(AuthGuard('jwt')) + // @Get('/revocation/registry') + // @ApiTags('revocation-registry') + // @ApiQuery({ name: 'rev_reg_id', required: true }) + // @ApiOperation({ summary: 'Get revocation registry by revocation registry id' }) + // @ApiResponse({ status: HttpStatus.OK, description: 'Get revocation registry by revocation registry id' }) + // getRevocationRegistry( + // @Query() rev_reg_id: string, + // @GetUser() user: any + // ) { + // return this.revocationService.getRevocationRegistry(rev_reg_id, user); + // } +} diff --git a/apps/api-gateway/src/revocation/revocation.module.ts b/apps/api-gateway/src/revocation/revocation.module.ts index 77558663b..c09e7871a 100644 --- a/apps/api-gateway/src/revocation/revocation.module.ts +++ b/apps/api-gateway/src/revocation/revocation.module.ts @@ -1,10 +1,10 @@ -import { Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { ClientsModule } from '@nestjs/microservices'; -import { RevocationService } from './revocation.service'; -import { RevocationController } from './revocation.controller'; -import { commonNatsOptions } from 'libs/service/nats.options'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule } from '@nestjs/microservices' +import { commonNatsOptions } from 'libs/service/nats.options' +import { RevocationController } from './revocation.controller' +import { RevocationService } from './revocation.service' @Module({ imports: [ @@ -12,11 +12,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; ClientsModule.register([ { name: 'NATS_CLIENT', - ...commonNatsOptions('REVOCATION_SERVICE:REQUESTER') - } - ]) + ...commonNatsOptions('REVOCATION_SERVICE:REQUESTER'), + }, + ]), ], controllers: [RevocationController], - providers: [RevocationService, NATSClient] + providers: [RevocationService, NATSClient], }) export class RevocationModule {} diff --git a/apps/api-gateway/src/revocation/revocation.service.ts b/apps/api-gateway/src/revocation/revocation.service.ts index 706f2408a..448dd27d3 100644 --- a/apps/api-gateway/src/revocation/revocation.service.ts +++ b/apps/api-gateway/src/revocation/revocation.service.ts @@ -1,12 +1,10 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable camelcase */ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { CreateRevocationRegistryDto } from '../dtos/create-revocation-registry.dto'; -import { UpdateRevocationRegistryUriDto } from '../dtos/update-revocation-registry.dto'; -import { BaseService } from 'libs/service/base.service'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { user } from '@prisma/client' +import { BaseService } from 'libs/service/base.service' +import type { CreateRevocationRegistryDto } from '../dtos/create-revocation-registry.dto' +import type { UpdateRevocationRegistryUriDto } from '../dtos/update-revocation-registry.dto' @Injectable() export class RevocationService extends BaseService { @@ -14,36 +12,35 @@ export class RevocationService extends BaseService { @Inject('NATS_CLIENT') private readonly revocationServiceProxy: ClientProxy, private readonly natsClient: NATSClient ) { - super('RevocationService'); + super('RevocationService') } - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - createRevocationRegistry(createRevocationRegistryDto: CreateRevocationRegistryDto, user: any) { - this.logger.log('**** createRevocationRegistry called'); - const payload = { createRevocationRegistryDto, user }; - return this.natsClient.sendNats(this.revocationServiceProxy, 'create-revocation-registry', payload); + createRevocationRegistry(createRevocationRegistryDto: CreateRevocationRegistryDto, user: user) { + this.logger.log('**** createRevocationRegistry called') + const payload = { createRevocationRegistryDto, user } + return this.natsClient.sendNats(this.revocationServiceProxy, 'create-revocation-registry', payload) } // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - updateRevocationRegistryUri(updateRevocationRegistryUriDto: UpdateRevocationRegistryUriDto, user: any) { - this.logger.log('**** updateRevocationRegistryUri called'); - const payload = { updateRevocationRegistryUriDto, user }; - return this.natsClient.sendNats(this.revocationServiceProxy, 'update-revocation-registry-uri', payload); + updateRevocationRegistryUri(updateRevocationRegistryUriDto: UpdateRevocationRegistryUriDto, user: user) { + this.logger.log('**** updateRevocationRegistryUri called') + const payload = { updateRevocationRegistryUriDto, user } + return this.natsClient.sendNats(this.revocationServiceProxy, 'update-revocation-registry-uri', payload) } // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - activeRevocationRegistry(cred_def_id: string, user: any) { - this.logger.log('**** activeRevocationRegistry called'); - const payload = { cred_def_id, user }; - return this.natsClient.sendNats(this.revocationServiceProxy, 'active-revocation-registry', payload); + activeRevocationRegistry(cred_def_id: string, user: user) { + this.logger.log('**** activeRevocationRegistry called') + const payload = { cred_def_id, user } + return this.natsClient.sendNats(this.revocationServiceProxy, 'active-revocation-registry', payload) } // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - publishRevocationRegistry(revocationId: string, user: any) { - this.logger.log('**** publishRevocationRegistry called'); - const payload = { revocationId, user }; - return this.natsClient.sendNats(this.revocationServiceProxy, 'publish-revocation-registry', payload); + publishRevocationRegistry(revocationId: string, user: user) { + this.logger.log('**** publishRevocationRegistry called') + const payload = { revocationId, user } + return this.natsClient.sendNats(this.revocationServiceProxy, 'publish-revocation-registry', payload) } - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - getRevocationRegistry(rev_reg_id: string, user: any) { - this.logger.log('**** getRevocationRegistry called'); - const payload = { rev_reg_id, user }; - return this.natsClient.sendNats(this.revocationServiceProxy, 'get-revocation-registry', payload); + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + getRevocationRegistry(rev_reg_id: string, user: user) { + this.logger.log('**** getRevocationRegistry called') + const payload = { rev_reg_id, user } + return this.natsClient.sendNats(this.revocationServiceProxy, 'get-revocation-registry', payload) } } diff --git a/apps/api-gateway/src/schema/dtos/create-schema.dto.ts b/apps/api-gateway/src/schema/dtos/create-schema.dto.ts index 881678faa..1ad280555 100644 --- a/apps/api-gateway/src/schema/dtos/create-schema.dto.ts +++ b/apps/api-gateway/src/schema/dtos/create-schema.dto.ts @@ -1,28 +1,31 @@ -import { IsArray, IsNotEmpty, IsString } from 'class-validator'; +import { IsArray, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class CreateSchemaDto { - @ApiProperty() - @IsString({ message: 'schema version must be a string' }) @IsNotEmpty({ message: 'please provide valid schema version' }) - schemaVersion: string; + @ApiProperty() + @IsString({ message: 'schema version must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema version' }) + schemaVersion: string - @ApiProperty() - @IsString({ message: 'schema name must be a string' }) @IsNotEmpty({ message: 'please provide valid schema name' }) - schemaName: string; + @ApiProperty() + @IsString({ message: 'schema name must be a string' }) + @IsNotEmpty({ message: 'please provide valid schema name' }) + schemaName: string - @ApiProperty() - @IsArray({ message: 'attributes must be an array' }) - @IsString({ each: true }) - @IsNotEmpty({ message: 'please provide valid attributes' }) - attributes: string[]; + @ApiProperty() + @IsArray({ message: 'attributes must be an array' }) + @IsString({ each: true }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + attributes: string[] - @ApiProperty() - - @IsNotEmpty({ message: 'please provide orgId' }) - orgId: string; + @ApiProperty() - @ApiProperty() - @IsString({ message: 'orgDid must be a string' }) @IsNotEmpty({ message: 'please provide valid orgDid' }) - orgDid: string; + @IsNotEmpty({ message: 'please provide orgId' }) + orgId: string + + @ApiProperty() + @IsString({ message: 'orgDid must be a string' }) + @IsNotEmpty({ message: 'please provide valid orgDid' }) + orgDid: string } 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 0e77da8cd..57e2187a6 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 @@ -1,135 +1,131 @@ +import { toNumber, trim } from '@credebl/common/cast.helper' +import { CredDefSortFields, SchemaType, SortFields, SortValue } from '@credebl/enum/enum' /* eslint-disable @typescript-eslint/no-inferrable-types */ /* eslint-disable camelcase */ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform, Type } from 'class-transformer'; -import { IsEnum, IsOptional, IsUUID, Min } from 'class-validator'; -import { toNumber, trim } from '@credebl/common/cast.helper'; -import { CredDefSortFields, SchemaType, SortFields, SortValue } from '@credebl/enum/enum'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform, Type } from 'class-transformer' +import { IsEnum, IsOptional, IsUUID, Min } from 'class-validator' export class GetAllSchemaDto { - @ApiProperty({ required: false }) - @IsOptional() - @Transform(({ value }) => trim(value)) - @Type(() => String) - searchByText: string = ''; - - @ApiProperty({ required: false, default: 1 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - @Min(1, { message: 'Page number must be greater than 0' }) - pageNumber: number = 1; - - @ApiProperty({ required: false, default: 10 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - @Min(1, { message: 'Page size must be greater than 0' }) - pageSize: number = 10; - - @ApiProperty({ - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(SortFields) - sortField: string = SortFields.CREATED_DATE_TIME; - - @ApiProperty({ - enum: [SortValue.DESC, SortValue.ASC], - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(SortValue) - sortBy: string = SortValue.DESC; + @ApiProperty({ required: false }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @Type(() => String) + searchByText = '' + + @ApiProperty({ required: false, default: 1 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + @Min(1, { message: 'Page number must be greater than 0' }) + pageNumber = 1 + + @ApiProperty({ required: false, default: 10 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + @Min(1, { message: 'Page size must be greater than 0' }) + pageSize = 10 + + @ApiProperty({ + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SortFields) + sortField: string = SortFields.CREATED_DATE_TIME + + @ApiProperty({ + enum: [SortValue.DESC, SortValue.ASC], + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SortValue) + sortBy: string = SortValue.DESC } export class GetCredentialDefinitionBySchemaIdDto { - - @ApiProperty({ required: false, default: 1 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - @Min(1, { message: 'Page number must be greater than 0' }) - pageNumber: number = 1; - - @ApiProperty({ required: false, default: 10 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - @Min(1, { message: 'Page size must be greater than 0' }) - pageSize: number = 10; - - @ApiProperty({ required: false }) - @IsOptional() - @Type(() => String) - searchByText: string = ''; - - @ApiProperty({ - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(CredDefSortFields) - sortField: string = SortFields.CREATED_DATE_TIME; - - @ApiProperty({ - enum: [SortValue.DESC, SortValue.ASC], - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(SortValue) - sortBy: string = SortValue.DESC; - - schemaId: string; - - orgId: string; + @ApiProperty({ required: false, default: 1 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + @Min(1, { message: 'Page number must be greater than 0' }) + pageNumber = 1 + + @ApiProperty({ required: false, default: 10 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + @Min(1, { message: 'Page size must be greater than 0' }) + pageSize = 10 + + @ApiProperty({ required: false }) + @IsOptional() + @Type(() => String) + searchByText = '' + + @ApiProperty({ + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(CredDefSortFields) + sortField: string = SortFields.CREATED_DATE_TIME + + @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 { - - @ApiProperty({ example: '1a7eac11-ff05-40d7-8351-4d7467687cad'}) - @ApiPropertyOptional() - @Transform(({ value }) => ('string' === typeof value && '' === value.trim() ? undefined : value.trim())) - @IsOptional() - @IsUUID('4', { message: 'Invalid format of ledgerId' }) - ledgerId?: string; - - @ApiProperty({ required: false, default: 1 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - @Min(1, { message: 'Page number must be greater than 0' }) - pageNumber: number = 1; - - @ApiProperty({ required: false }) - @IsOptional() - @Type(() => String) - searchByText: string = ''; - - @ApiProperty({ required: false, default: 10 }) - @IsOptional() - @Transform(({ value }) => toNumber(value)) - @Min(1, { message: 'Page size must be greater than 0' }) - pageSize: number = 10; - - @ApiProperty({ - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(SortFields) - sorting: string = SortFields.CREATED_DATE_TIME; - - @ApiProperty({ required: false }) - @IsOptional() - sortByValue: string = SortValue.DESC; - - @ApiProperty({ - type: SchemaType, - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(SchemaType) - schemaType: SchemaType; - -} \ No newline at end of file + @ApiProperty({ example: '1a7eac11-ff05-40d7-8351-4d7467687cad' }) + @ApiPropertyOptional() + @Transform(({ value }) => (typeof value === 'string' && value.trim() === '' ? undefined : value.trim())) + @IsOptional() + @IsUUID('4', { message: 'Invalid format of ledgerId' }) + ledgerId?: string + + @ApiProperty({ required: false, default: 1 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + @Min(1, { message: 'Page number must be greater than 0' }) + pageNumber = 1 + + @ApiProperty({ required: false }) + @IsOptional() + @Type(() => String) + searchByText = '' + + @ApiProperty({ required: false, default: 10 }) + @IsOptional() + @Transform(({ value }) => toNumber(value)) + @Min(1, { message: 'Page size must be greater than 0' }) + pageSize = 10 + + @ApiProperty({ + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SortFields) + sorting: string = SortFields.CREATED_DATE_TIME + + @ApiProperty({ required: false }) + @IsOptional() + sortByValue: string = SortValue.DESC + + @ApiProperty({ + type: SchemaType, + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SchemaType) + schemaType: SchemaType +} diff --git a/apps/api-gateway/src/schema/dtos/update-schema-dto.ts b/apps/api-gateway/src/schema/dtos/update-schema-dto.ts index 80fe4f876..106aaf215 100644 --- a/apps/api-gateway/src/schema/dtos/update-schema-dto.ts +++ b/apps/api-gateway/src/schema/dtos/update-schema-dto.ts @@ -1,23 +1,23 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator' export class UpdateSchemaDto { @ApiProperty() @Transform(({ value }) => value?.trim()) @IsNotEmpty({ message: 'Alias is required.' }) @IsString({ message: 'Alias must be in string format.' }) - alias: string; + alias: string @ApiProperty() @Transform(({ value }) => value?.trim()) @IsNotEmpty({ message: 'schemaLedgerId is required.' }) @IsString({ message: 'schemaLedgerId must be in string format.' }) - schemaLedgerId: string; + schemaLedgerId: string @ApiPropertyOptional() @IsOptional() @Transform(({ value }) => value?.trim()) @IsUUID('4') - orgId?: string; + orgId?: string } diff --git a/apps/api-gateway/src/schema/interfaces/index.ts b/apps/api-gateway/src/schema/interfaces/index.ts index a0dfce8c2..cbf7cced2 100644 --- a/apps/api-gateway/src/schema/interfaces/index.ts +++ b/apps/api-gateway/src/schema/interfaces/index.ts @@ -1,59 +1,58 @@ -import { UserRoleOrgPermsDto } from '../../dtos/user-role-org-perms.dto'; +import type { UserRoleOrgPermsDto } from '../../dtos/user-role-org-perms.dto' export interface IUserRequestInterface { - id: string; - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?: string; - selectedOrg: ISelectedOrgInterface; + id: string + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string + selectedOrg: ISelectedOrgInterface } export interface ISelectedOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: object; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: object } export interface IOrganizationInterface { - name: string; - description: string; + name: string + description: string org_agents: IOrgAgentInterface[] - } export interface IOrgAgentInterface { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } export interface ISchemaInfo { - schema: Ischema; - schemaId: string; - schemaMetadata: ISchemaMetadata; + schema: Ischema + schemaId: string + schemaMetadata: ISchemaMetadata } interface Ischema { - attrNames: string[]; - name: string; - version: string; - issuerId: string; + attrNames: string[] + name: string + version: string + issuerId: string } interface ISchemaMetadata { - didIndyNamespace: string; - indyLedgerSeqNo: number; + didIndyNamespace: string + indyLedgerSeqNo: number } diff --git a/apps/api-gateway/src/schema/schema.controller.spec.ts b/apps/api-gateway/src/schema/schema.controller.spec.ts index 6e0d602bc..23cbe17cf 100644 --- a/apps/api-gateway/src/schema/schema.controller.spec.ts +++ b/apps/api-gateway/src/schema/schema.controller.spec.ts @@ -1,222 +1,183 @@ -import { Test, TestingModule } from '@nestjs/testing'; +import { Test, TestingModule } from '@nestjs/testing' -import { Any } from 'typeorm'; -import { CreateSchemaDto } from '../dtos/create-schema.dto'; -import { SchemaController } from './schema.controller'; -import { SchemaService } from './schema.service'; -import { plainToClassFromExist } from 'class-transformer'; -import { validate } from 'class-validator'; -import { CredDefSortBy, SortValue } from '../enum'; +import { plainToClassFromExist } from 'class-transformer' +import { validate } from 'class-validator' +import { CreateSchemaDto } from '../dtos/create-schema.dto' +import { CredDefSortBy, SortValue } from '../enum' +import { SchemaController } from './schema.controller' +import { SchemaService } from './schema.service' describe('schemaController Test Cases', () => { - let controller: SchemaController; - const mockSchemaService = { - createSchema: jest.fn(() => ({})), - getSchemas: jest.fn(() => ({})), - getSchemaByOrg: jest.fn(() => ({})), - getSchemaBySchemaId:jest.fn(() => ({})), - getCredDefBySchemaId: jest.fn(() => ({})) - }; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [SchemaController], - providers: [SchemaService] - }) - .overrideProvider(SchemaService) - .useValue(mockSchemaService) - .compile(); - controller = module.get( - SchemaController - ); - }); - /////////////////////--------Create Schema -------------------////////////////////// - describe('createSchema', () => { - const user: any = {}; - - it('should return an expected schema', async () => { - const createSchemaDto: CreateSchemaDto = new CreateSchemaDto; - const result = await controller.createSchema( - createSchemaDto, - user - ); - expect(result).toEqual({}); - }); - /////////////// - - it('should check returned credentialdefinition is not to be null', async () => { - const createSchemaDto: CreateSchemaDto = new CreateSchemaDto; - const result = await controller.createSchema( - createSchemaDto, - user - ); - expect(result).not.toBeNull(); - }); - - //////////// - it('Should throw error when schema version is not string', async () => { - const schema_version_dto = { schema_version: 1 }; - const schemaVersionResult = plainToClassFromExist( - CreateSchemaDto, - schema_version_dto - ); - const errors = await validate(schemaVersionResult); - const result = await errors[0].constraints.isString; - expect(result).toEqual('schema version must be a string'); - }); - - - it('Should throw error when schema name is not a string', async () => { - const schemaName = { schema_name: 234 }; - const schemaNameResult = plainToClassFromExist( - CreateSchemaDto, - schemaName - ); - const errors = await validate(schemaNameResult); - const result = await errors[1].constraints.isString; - expect(result).toEqual('schema name must be a string'); - }); - - ////////////////////// - - it('should throw error when schema version is null', async () => { - const schema_version_dto = { schema_version: '' }; - const schemaNameResult = plainToClassFromExist( - CreateSchemaDto, - schema_version_dto - ); - const errors = await validate(schemaNameResult); - const result = await errors[0].constraints.isNotEmpty; - expect(result).toEqual('please provide valid schema version'); - }); - - it('should throw error when schema name is null', async () => { - const schema_name_dto = { schema_name: '' }; - const schemaNameResult = plainToClassFromExist( - CreateSchemaDto, - schema_name_dto - ); - const errors = await validate(schemaNameResult); - const result = await errors[1].constraints.isNotEmpty; - expect(result).toEqual('please provide valid schema name'); - }); - - ////////////////////// - - it('should throw error when attributes are not in array', async () => { - const attribute_dto = {attributes:'testAcb'}; - const schemaattributeResult = plainToClassFromExist( - CreateSchemaDto, - attribute_dto - ); - const errors = await validate(schemaattributeResult); - const result = await errors[2].constraints.isArray; - expect(result).toEqual('attributes must be an array'); - }); - - it('should throw error when elements of attributes are not a string', async () => { - const attribute_dto = {attributes: true}; - const schemaattributeResult = plainToClassFromExist( - CreateSchemaDto, - attribute_dto - ); - const errors = await validate(schemaattributeResult); - const result = await errors[2].constraints.isString; - expect(result).toEqual('each value in attributes must be a string'); - }); - - it('should throw error when attributes are null', async () => { - const attribute_dto = {attributes:''}; - const schemaattributeResult = plainToClassFromExist( - CreateSchemaDto, - attribute_dto - ); - const errors = await validate(schemaattributeResult); - const result = await errors[2].constraints.isNotEmpty; - expect(result).toEqual('please provide valid attributes'); - }); - - }); - -///////////////////// --- get schema by ledger Id ------------/////////// - - - describe('getSchemas', () => { - const user: any = {}; - const page = 1; - const search_text = 'test search'; - const items_per_page = 1; - const schemaSortBy = 'id'; - const sortValue = 'DESC'; - it('should return an expected schemas by ledger Id', async () => { - const result = await controller.getSchemaWithFilters( - page, - search_text, - items_per_page, - schemaSortBy, - sortValue, - user - ); - expect(result).toEqual({}); - }); - - }); - -/////////////////////////----- get schemas with organization id ---------- - describe('getSchemasByOrgId', () => { - const user: any = {}; - const page = 1; - const search_text = 'test search'; - const items_per_page = 1; - const sortValue = 1; - const id = 1; - const schemaSortBy = 'DESC'; - it('should return an expected schemas by org Id', async () => { - const result = await controller.getSchemasByOrgId( - page, - search_text, - items_per_page, - sortValue, - schemaSortBy, - id - ); - expect(result).toEqual({}); - }); - }); - -/////////////////////------- get schemas with schema ledger Id --------------- - - describe('getSchemaBySchemaId', () => { - const user: any = {}; - const id = '1'; - it('should return an expected schemas by org Id', async () => { - const result = await controller.getSchemaById( - user, - id - ); - expect(result).toEqual({}); - }); - }); - -/////////--------- get cred defs with schema Id ---/// - describe('getCredDefBySchemaId', () => { - const user: any = {}; - const id = 1; - const page = 1; - const search_text = 'test'; - const items_per_page = 1; - const orgId = 2; - const credDefSortBy = CredDefSortBy.id; - const sortValue = SortValue.DESC; - const supportRevocation = 'all'; - it('should return expected cred defs by schemaId', async () => { - const result = await controller.getCredDefBySchemaId( - page, search_text, items_per_page, orgId, credDefSortBy, sortValue, supportRevocation, id, user - ); - expect(result).toEqual({}); - }); - - }); - - -}); \ No newline at end of file + let controller: SchemaController + const mockSchemaService = { + createSchema: jest.fn(() => ({})), + getSchemas: jest.fn(() => ({})), + getSchemaByOrg: jest.fn(() => ({})), + getSchemaBySchemaId: jest.fn(() => ({})), + getCredDefBySchemaId: jest.fn(() => ({})), + } + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [SchemaController], + providers: [SchemaService], + }) + .overrideProvider(SchemaService) + .useValue(mockSchemaService) + .compile() + controller = module.get(SchemaController) + }) + /////////////////////--------Create Schema -------------------////////////////////// + describe('createSchema', () => { + const user: any = {} + + it('should return an expected schema', async () => { + const createSchemaDto: CreateSchemaDto = new CreateSchemaDto() + const result = await controller.createSchema(createSchemaDto, user) + expect(result).toEqual({}) + }) + /////////////// + + it('should check returned credentialdefinition is not to be null', async () => { + const createSchemaDto: CreateSchemaDto = new CreateSchemaDto() + const result = await controller.createSchema(createSchemaDto, user) + expect(result).not.toBeNull() + }) + + //////////// + it('Should throw error when schema version is not string', async () => { + const schema_version_dto = { schema_version: 1 } + const schemaVersionResult = plainToClassFromExist(CreateSchemaDto, schema_version_dto) + const errors = await validate(schemaVersionResult) + const result = await errors[0].constraints.isString + expect(result).toEqual('schema version must be a string') + }) + + it('Should throw error when schema name is not a string', async () => { + const schemaName = { schema_name: 234 } + const schemaNameResult = plainToClassFromExist(CreateSchemaDto, schemaName) + const errors = await validate(schemaNameResult) + const result = await errors[1].constraints.isString + expect(result).toEqual('schema name must be a string') + }) + + ////////////////////// + + it('should throw error when schema version is null', async () => { + const schema_version_dto = { schema_version: '' } + const schemaNameResult = plainToClassFromExist(CreateSchemaDto, schema_version_dto) + const errors = await validate(schemaNameResult) + const result = await errors[0].constraints.isNotEmpty + expect(result).toEqual('please provide valid schema version') + }) + + it('should throw error when schema name is null', async () => { + const schema_name_dto = { schema_name: '' } + const schemaNameResult = plainToClassFromExist(CreateSchemaDto, schema_name_dto) + const errors = await validate(schemaNameResult) + const result = await errors[1].constraints.isNotEmpty + expect(result).toEqual('please provide valid schema name') + }) + + ////////////////////// + + it('should throw error when attributes are not in array', async () => { + const attribute_dto = { attributes: 'testAcb' } + const schemaattributeResult = plainToClassFromExist(CreateSchemaDto, attribute_dto) + const errors = await validate(schemaattributeResult) + const result = await errors[2].constraints.isArray + expect(result).toEqual('attributes must be an array') + }) + + it('should throw error when elements of attributes are not a string', async () => { + const attribute_dto = { attributes: true } + const schemaattributeResult = plainToClassFromExist(CreateSchemaDto, attribute_dto) + const errors = await validate(schemaattributeResult) + const result = await errors[2].constraints.isString + expect(result).toEqual('each value in attributes must be a string') + }) + + it('should throw error when attributes are null', async () => { + const attribute_dto = { attributes: '' } + const schemaattributeResult = plainToClassFromExist(CreateSchemaDto, attribute_dto) + const errors = await validate(schemaattributeResult) + const result = await errors[2].constraints.isNotEmpty + expect(result).toEqual('please provide valid attributes') + }) + }) + + ///////////////////// --- get schema by ledger Id ------------/////////// + + describe('getSchemas', () => { + const user: any = {} + const page = 1 + const search_text = 'test search' + const items_per_page = 1 + const schemaSortBy = 'id' + const sortValue = 'DESC' + it('should return an expected schemas by ledger Id', async () => { + const result = await controller.getSchemaWithFilters( + page, + search_text, + items_per_page, + schemaSortBy, + sortValue, + user + ) + expect(result).toEqual({}) + }) + }) + + /////////////////////////----- get schemas with organization id ---------- + describe('getSchemasByOrgId', () => { + const _user: any = {} + const page = 1 + const search_text = 'test search' + const items_per_page = 1 + const sortValue = 1 + const id = 1 + const schemaSortBy = 'DESC' + it('should return an expected schemas by org Id', async () => { + const result = await controller.getSchemasByOrgId(page, search_text, items_per_page, sortValue, schemaSortBy, id) + expect(result).toEqual({}) + }) + }) + + /////////////////////------- get schemas with schema ledger Id --------------- + + describe('getSchemaBySchemaId', () => { + const user: any = {} + const id = '1' + it('should return an expected schemas by org Id', async () => { + const result = await controller.getSchemaById(user, id) + expect(result).toEqual({}) + }) + }) + + /////////--------- get cred defs with schema Id ---/// + describe('getCredDefBySchemaId', () => { + const user: any = {} + const id = 1 + const page = 1 + const search_text = 'test' + const items_per_page = 1 + const orgId = 2 + const credDefSortBy = CredDefSortBy.id + const sortValue = SortValue.DESC + const supportRevocation = 'all' + it('should return expected cred defs by schemaId', async () => { + const result = await controller.getCredDefBySchemaId( + page, + search_text, + items_per_page, + orgId, + credDefSortBy, + sortValue, + supportRevocation, + id, + user + ) + expect(result).toEqual({}) + }) + }) +}) diff --git a/apps/api-gateway/src/schema/schema.controller.ts b/apps/api-gateway/src/schema/schema.controller.ts index 93682107f..da09d6a60 100644 --- a/apps/api-gateway/src/schema/schema.controller.ts +++ b/apps/api-gateway/src/schema/schema.controller.ts @@ -1,27 +1,51 @@ -import { Controller, Logger, Post, Body, HttpStatus, UseGuards, Get, Query, BadRequestException, Res, UseFilters, Param, ParseUUIDPipe, Put } from '@nestjs/common'; +import { TrimStringParamPipe } from '@credebl/common/cast.helper' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { CredDefSortFields, SortFields } from '@credebl/enum/enum' +import { + BadRequestException, + Body, + Controller, + Get, + HttpStatus, + Logger, + Param, + ParseUUIDPipe, + Post, + Put, + Query, + Res, + UseFilters, + UseGuards, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable camelcase */ -import { ApiOperation, ApiResponse, ApiTags, ApiBearerAuth, ApiForbiddenResponse, ApiUnauthorizedResponse, ApiQuery, ApiExcludeEndpoint } from '@nestjs/swagger'; -import { SchemaService } from './schema.service'; -import { AuthGuard } from '@nestjs/passport'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { IResponse } from '@credebl/common/interfaces/response.interface'; -import { Response } from 'express'; -import { User } from '../authz/decorators/user.decorator'; -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'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { IUserRequestInterface } from './interfaces'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { GenericSchemaDTO } from '../dtos/create-schema.dto'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { CredDefSortFields, SortFields } from '@credebl/enum/enum'; -import { TrimStringParamPipe } from '@credebl/common/cast.helper'; -import { UpdateSchemaDto } from './dtos/update-schema-dto'; +import { + ApiBearerAuth, + ApiExcludeEndpoint, + ApiForbiddenResponse, + ApiOperation, + ApiQuery, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import type { GenericSchemaDTO } from '../dtos/create-schema.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface' +import type { GetAllSchemaDto, GetCredentialDefinitionBySchemaIdDto } from './dtos/get-all-schema.dto' +import type { UpdateSchemaDto } from './dtos/update-schema-dto' +import type { IUserRequestInterface } from './interfaces' +import type { SchemaService } from './schema.service' @UseFilters(CustomExceptionFilter) @Controller('orgs') @@ -30,10 +54,8 @@ import { UpdateSchemaDto } from './dtos/update-schema-dto'; @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) export class SchemaController { - constructor(private readonly appService: SchemaService - ) { } - private readonly logger = new Logger('SchemaController'); - + constructor(private readonly appService: SchemaService) {} + private readonly logger = new Logger('SchemaController') /** * Retrieves schema information from the ledger using its schema ID. @@ -47,152 +69,180 @@ export class SchemaController { @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @ApiOperation({ summary: 'Get schema information from the ledger using its schema ID.', - description: 'Retrives schema information from the ledger using its schema ID.' + description: 'Retrives schema information from the ledger using its schema ID.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getSchemaById( @Res() res: Response, - @Param('orgId') orgId: string, + @Param('orgId') orgId: string, @Param('schemaId', TrimStringParamPipe) schemaId: string ): Promise { - if (!schemaId) { - throw new BadRequestException(ResponseMessages.schema.error.invalidSchemaId); + throw new BadRequestException(ResponseMessages.schema.error.invalidSchemaId) } - - const schemaDetails = await this.appService.getSchemaById(schemaId, orgId); + + const schemaDetails = await this.appService.getSchemaById(schemaId, orgId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.schema.success.fetch, - data: schemaDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: schemaDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } - /** * Retrieves a list of credential definitions associated with a given schema ID. - * + * * @param orgId The organization ID. * @param schemaId The unique schema ID. * @param sortField The field by which to sort the results (optional). - * + * * @returns A list of credential definitions filtered by schema ID. */ @Get('/:orgId/schemas/:schemaId/cred-defs') @ApiOperation({ summary: 'Credential definitions by schema Id', - description: 'Retrives credential definition list by schema Id available on platform.' + description: 'Retrives credential definition list by schema Id available on platform.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiQuery({ name: 'sortField', enum: CredDefSortFields, - required: false + required: false, }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) async getcredDeffListBySchemaId( - @Param('orgId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); }})) orgId: string, + @Param( + 'orgId', + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, @Param('schemaId', TrimStringParamPipe) schemaId: string, @Query() getCredentialDefinitionBySchemaIdDto: GetCredentialDefinitionBySchemaIdDto, @Res() res: Response, - @User() user: IUserRequestInterface): Promise { - + @User() user: IUserRequestInterface + ): Promise { if (!schemaId) { - throw new BadRequestException(ResponseMessages.schema.error.invalidSchemaId); + throw new BadRequestException(ResponseMessages.schema.error.invalidSchemaId) } - getCredentialDefinitionBySchemaIdDto.schemaId = schemaId; - getCredentialDefinitionBySchemaIdDto.orgId = orgId; + getCredentialDefinitionBySchemaIdDto.schemaId = schemaId + getCredentialDefinitionBySchemaIdDto.orgId = orgId - const credentialDefinitionList = await this.appService.getcredDefListBySchemaId(getCredentialDefinitionBySchemaIdDto, user); + const credentialDefinitionList = await this.appService.getcredDefListBySchemaId( + getCredentialDefinitionBySchemaIdDto, + user + ) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.schema.success.fetch, - data: credentialDefinitionList - }; - - return res.status(HttpStatus.OK).json(finalResponse); + data: credentialDefinitionList, + } + + return res.status(HttpStatus.OK).json(finalResponse) } /** * Retrieves a list of schemas associated with a given organization ID. - * + * * @param orgId The organization ID. - * + * * @returns A list of schemas filtered by organization ID. */ @Get('/:orgId/schemas') @ApiOperation({ summary: 'Schemas by org id.', - description: 'Retrieves all schemas belonging to a specific organization available on platform.' + description: 'Retrieves all schemas belonging to a specific organization available on platform.', }) @ApiQuery({ name: 'sortField', enum: SortFields, - required: false + required: false, }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) async getSchemas( @Query() getAllSchemaDto: GetAllSchemaDto, - @Param('orgId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); }})) orgId: string, + @Param( + 'orgId', + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, @Res() res: Response, @User() user: IUserRequestInterface ): Promise { - - const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllSchemaDto; + const { pageSize, searchByText, pageNumber, sortField, sortBy } = getAllSchemaDto const schemaSearchCriteria: ISchemaSearchPayload = { pageNumber, searchByText, pageSize, sortField, - sortBy - }; - const schemasResponse = await this.appService.getSchemas(schemaSearchCriteria, user, orgId); + sortBy, + } + const schemasResponse = await this.appService.getSchemas(schemaSearchCriteria, user, orgId) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.schema.success.fetch, - data: schemasResponse - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: schemasResponse, + } + return res.status(HttpStatus.OK).json(finalResponse) } - -/** - * Create and register various types of schemas. - * - * @param orgId The organization ID. - * @param schemaDetails The schema details. - * @returns The created schema details. - */ + /** + * Create and register various types of schemas. + * + * @param orgId The organization ID. + * @param schemaDetails The schema details. + * @returns The created schema details. + */ @Post('/:orgId/schemas') @ApiOperation({ summary: 'Create and register various types of schemas.', - description: 'Create and register a schema for an organization. Supports multiple systems like Indy, Polygon, and W3C standards.' - } - ) + description: + 'Create and register a schema for an organization. Supports multiple systems like Indy, Polygon, and W3C standards.', + }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) - async createSchema(@Res() res: Response, @Body() schemaDetails: GenericSchemaDTO, @Param('orgId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); }})) orgId: string, @User() user: IUserRequestInterface): Promise { - const schemaResponse = await this.appService.createSchema(schemaDetails, user, orgId); + async createSchema( + @Res() res: Response, + @Body() schemaDetails: GenericSchemaDTO, + @Param( + 'orgId', + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, + @User() user: IUserRequestInterface + ): Promise { + const schemaResponse = await this.appService.createSchema(schemaDetails, user, orgId) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.schema.success.create, - data: schemaResponse - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: schemaResponse, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** - * Update an schema alias - * @param updateSchemaDto The details of the schema to be updated - * @returns Success message - */ + * Update an schema alias + * @param updateSchemaDto The details of the schema to be updated + * @returns Success message + */ @Put('/schema') @ApiOperation({ summary: 'Update schema', description: 'Update the details of the schema' }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @@ -200,15 +250,13 @@ export class SchemaController { @ApiBearerAuth() @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @UseGuards(AuthGuard('jwt')) - async updateSchema(@Body() updateSchemaDto: UpdateSchemaDto, @Res() res: Response): Promise { - - await this.appService.updateSchema(updateSchemaDto); + async updateSchema(@Body() updateSchemaDto: UpdateSchemaDto, @Res() res: Response): Promise { + await this.appService.updateSchema(updateSchemaDto) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.schema.success.update - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.schema.success.update, + } + return res.status(HttpStatus.OK).json(finalResponse) } - } diff --git a/apps/api-gateway/src/schema/schema.module.ts b/apps/api-gateway/src/schema/schema.module.ts index a27ec6d48..525749805 100644 --- a/apps/api-gateway/src/schema/schema.module.ts +++ b/apps/api-gateway/src/schema/schema.module.ts @@ -1,12 +1,12 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; +import { ClientsModule, Transport } from '@nestjs/microservices' -import { ConfigModule } from '@nestjs/config'; -import { Module } from '@nestjs/common'; -import { SchemaController } from './schema.controller'; -import { SchemaService } from './schema.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { SchemaController } from './schema.controller' +import { SchemaService } from './schema.service' @Module({ imports: [ @@ -15,12 +15,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.SCHEMA_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - - } - ]) + options: getNatsOptions(CommonConstants.SCHEMA_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [SchemaController], - providers: [SchemaService, NATSClient] + providers: [SchemaService, NATSClient], }) -export class SchemaModule { } +export class SchemaModule {} diff --git a/apps/api-gateway/src/schema/schema.service.ts b/apps/api-gateway/src/schema/schema.service.ts index bb328e5dc..9ef4d0503 100644 --- a/apps/api-gateway/src/schema/schema.service.ts +++ b/apps/api-gateway/src/schema/schema.service.ts @@ -1,47 +1,58 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from '../../../../libs/service/base.service'; -import { GenericSchemaDTO } from '../dtos/create-schema.dto'; -import { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface'; -import { ISchemaInfo, IUserRequestInterface } from './interfaces'; -import { ICredDefWithPagination, ISchemaData, ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; -import { GetCredentialDefinitionBySchemaIdDto } from './dtos/get-all-schema.dto'; -import { NATSClient } from '@credebl/common/NATSClient'; - -import { UpdateSchemaResponse } from 'apps/ledger/src/schema/interfaces/schema.interface'; -import { UpdateSchemaDto } from './dtos/update-schema-dto'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { + ICredDefWithPagination, + ISchemaData, + ISchemasWithPagination, +} from '@credebl/common/interfaces/schema.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from '../../../../libs/service/base.service' +import type { GenericSchemaDTO } from '../dtos/create-schema.dto' +import type { ISchemaSearchPayload } from '../interfaces/ISchemaSearch.interface' +import type { GetCredentialDefinitionBySchemaIdDto } from './dtos/get-all-schema.dto' +import type { ISchemaInfo, IUserRequestInterface } from './interfaces' + +import type { UpdateSchemaResponse } from 'apps/ledger/src/schema/interfaces/schema.interface' +import type { UpdateSchemaDto } from './dtos/update-schema-dto' @Injectable() export class SchemaService extends BaseService { - constructor( @Inject('NATS_CLIENT') private readonly schemaServiceProxy: ClientProxy, - private readonly natsClient : NATSClient - ) { super(`Schema Service`); } + private readonly natsClient: NATSClient + ) { + super('Schema Service') + } createSchema(schemaDetails: GenericSchemaDTO, user: IUserRequestInterface, orgId: string): Promise { - const payload = { schemaDetails, user, orgId }; - return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'create-schema', payload); + const payload = { schemaDetails, user, orgId } + return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'create-schema', payload) } - getSchemaById(schemaId: string, orgId: string): Promise { - const payload = { schemaId, orgId }; - return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-schema-by-id', payload); + const payload = { schemaId, orgId } + return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-schema-by-id', payload) } - getSchemas(schemaSearchCriteria: ISchemaSearchPayload, user: IUserRequestInterface, orgId: string): Promise { - const schemaSearch = { schemaSearchCriteria, user, orgId }; - return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-schemas', schemaSearch); + getSchemas( + schemaSearchCriteria: ISchemaSearchPayload, + user: IUserRequestInterface, + orgId: string + ): Promise { + const schemaSearch = { schemaSearchCriteria, user, orgId } + return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-schemas', schemaSearch) } - getcredDefListBySchemaId(schemaSearchCriteria: GetCredentialDefinitionBySchemaIdDto, user: IUserRequestInterface): Promise { - const payload = { schemaSearchCriteria, user }; - return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-cred-def-list-by-schemas-id', payload); + getcredDefListBySchemaId( + schemaSearchCriteria: GetCredentialDefinitionBySchemaIdDto, + user: IUserRequestInterface + ): Promise { + const payload = { schemaSearchCriteria, user } + return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-cred-def-list-by-schemas-id', payload) } updateSchema(schemaDetails: UpdateSchemaDto): Promise { - const payload = { schemaDetails }; - return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'update-schema', payload); + const payload = { schemaDetails } + return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'update-schema', payload) } -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/user/dto/accept-reject-invitation.dto.ts b/apps/api-gateway/src/user/dto/accept-reject-invitation.dto.ts index ab04eb078..5e989a291 100644 --- a/apps/api-gateway/src/user/dto/accept-reject-invitation.dto.ts +++ b/apps/api-gateway/src/user/dto/accept-reject-invitation.dto.ts @@ -1,24 +1,23 @@ -import { IsEnum, IsNotEmpty, IsString } from 'class-validator'; +import { IsEnum, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Invitation } from '@credebl/enum/enum'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { Invitation } from '@credebl/enum/enum' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class AcceptRejectInvitationDto { - invitationId: string; + invitationId: string - @ApiProperty({ example: 1 }) - @IsNotEmpty({ message: 'Please provide valid orgId' }) - @IsString() - orgId: string; + @ApiProperty({ example: 1 }) + @IsNotEmpty({ message: 'Please provide valid orgId' }) + @IsString() + orgId: string - @ApiProperty({ - enum: [Invitation.ACCEPTED, Invitation.REJECTED] - }) - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Please provide valid status' }) - @IsEnum(Invitation) - status: Invitation.ACCEPTED | Invitation.REJECTED; - -} \ No newline at end of file + @ApiProperty({ + enum: [Invitation.ACCEPTED, Invitation.REJECTED], + }) + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Please provide valid status' }) + @IsEnum(Invitation) + status: Invitation.ACCEPTED | Invitation.REJECTED +} 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 2101d8a48..3d50c3f14 100644 --- a/apps/api-gateway/src/user/dto/add-user.dto.ts +++ b/apps/api-gateway/src/user/dto/add-user.dto.ts @@ -1,51 +1,49 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString, MaxLength, MinLength } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString, MaxLength, MinLength } from 'class-validator' export class AddUserDetailsDto { - - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; - - @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; - - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Password is required' }) - password: string; - - @ApiProperty({ example: 'false' }) - @IsOptional() - @IsBoolean({ message: 'isPasskey should be boolean' }) - isPasskey?: boolean; - - @ApiPropertyOptional({ example: false }) - @IsOptional() - @IsBoolean({ message: 'isHolder should be boolean' }) - isHolder?: boolean; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string + + @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 + + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Password is required' }) + password: string + + @ApiProperty({ example: 'false' }) + @IsOptional() + @IsBoolean({ message: 'isPasskey should be boolean' }) + isPasskey?: boolean + + @ApiPropertyOptional({ example: false }) + @IsOptional() + @IsBoolean({ message: 'isHolder should be boolean' }) + isHolder?: boolean } export class AddPasskeyDetailsDto { - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Password is required' }) - password: string; - + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Password is required' }) + password: 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 d3bf0855e..225842361 100644 --- a/apps/api-gateway/src/user/dto/create-user.dto.ts +++ b/apps/api-gateway/src/user/dto/create-user.dto.ts @@ -1,41 +1,43 @@ -import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUrl, MaxLength } from 'class-validator'; -import { toLowerCase, trim } from '@credebl/common/cast.helper'; +import { toLowerCase, trim } from '@credebl/common/cast.helper' +import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUrl, MaxLength } from 'class-validator' -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class UserEmailVerificationDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @Transform(({ value }) => trim(value)) - @Transform(({ value }) => toLowerCase(value)) - @IsNotEmpty({ message: 'Email is required.' }) - @MaxLength(256, { message: 'Email must be at most 256 character.' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @Transform(({ value }) => trim(value)) + @Transform(({ value }) => toLowerCase(value)) + @IsNotEmpty({ message: 'Email is required.' }) + @MaxLength(256, { message: 'Email must be at most 256 character.' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + email: string - @ApiProperty({ example: 'xxxx-xxxx-xxxx' }) - @IsString({ message: 'clientId should be string' }) - clientId: string; + @ApiProperty({ example: 'xxxx-xxxx-xxxx' }) + @IsString({ message: 'clientId should be string' }) + clientId: string - @ApiProperty({ example: 'xxxx-xxxxx-xxxxx' }) - @IsString({ message: 'clientSecret should be string' }) - clientSecret: string; + @ApiProperty({ example: 'xxxx-xxxxx-xxxxx' }) + @IsString({ message: 'clientSecret should be string' }) + clientSecret: string - @ApiPropertyOptional({ example: 'https://example.com/logo.png' }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsUrl({ - // eslint-disable-next-line camelcase - require_protocol: true, - // eslint-disable-next-line camelcase - require_tld: true + @ApiPropertyOptional({ example: 'https://example.com/logo.png' }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsUrl( + { + // eslint-disable-next-line camelcase + require_protocol: true, + // eslint-disable-next-line camelcase + require_tld: true, }, - { message: 'brandLogoUrl should be a valid URL' }) - brandLogoUrl?: string; + { message: 'brandLogoUrl should be a valid URL' } + ) + brandLogoUrl?: string @ApiPropertyOptional({ example: 'MyPlatform' }) @Transform(({ value }) => trim(value)) @IsOptional() @IsString({ message: 'platformName should be string' }) - platformName?: string; + platformName?: 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 0df0ae7a2..4e21f736a 100644 --- a/apps/api-gateway/src/user/dto/email-verify.dto.ts +++ b/apps/api-gateway/src/user/dto/email-verify.dto.ts @@ -1,23 +1,22 @@ -import { IsEmail, IsNotEmpty, IsString, MaxLength } from 'class-validator'; -import { toLowerCase, trim } from '@credebl/common/cast.helper'; - -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; +import { toLowerCase, trim } from '@credebl/common/cast.helper' +import { IsEmail, IsNotEmpty, IsString, MaxLength } from 'class-validator' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class EmailVerificationDto { - @ApiProperty() - @Transform(({ value }) => trim(value)) - @Transform(({ value }) => toLowerCase(value)) - @IsNotEmpty({ message: 'Email is required.' }) - @MaxLength(256, { message: 'Email must be at most 256 character.' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @MaxLength(256, { message: 'Email must be at most 256 character' }) - email: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @Transform(({ value }) => toLowerCase(value)) + @IsNotEmpty({ message: 'Email is required.' }) + @MaxLength(256, { message: 'Email must be at most 256 character.' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @MaxLength(256, { message: 'Email must be at most 256 character' }) + email: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Verification code is required.' }) - @IsString({ message: 'Verification code should be string' }) - verificationCode: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Verification code is required.' }) + @IsString({ message: 'Verification code should be string' }) + verificationCode: string } diff --git a/apps/api-gateway/src/user/dto/get-all-invitations.dto.ts b/apps/api-gateway/src/user/dto/get-all-invitations.dto.ts index 0e8133523..a72eb6801 100644 --- a/apps/api-gateway/src/user/dto/get-all-invitations.dto.ts +++ b/apps/api-gateway/src/user/dto/get-all-invitations.dto.ts @@ -1,14 +1,12 @@ -import { IsOptional, IsString} from 'class-validator'; +import { IsOptional, IsString } from 'class-validator' - -import { ApiProperty } from '@nestjs/swagger'; -import { Invitation } from '@credebl/enum/enum'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; +import { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import { Invitation } from '@credebl/enum/enum' +import { ApiProperty } from '@nestjs/swagger' export class GetAllInvitationsDto extends PaginationDto { - @ApiProperty({ required: false }) - @IsOptional() - @IsString() - status = Invitation.PENDING; - + @ApiProperty({ required: false }) + @IsOptional() + @IsString() + status = Invitation.PENDING } 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 bd362ca27..b2489bc95 100644 --- a/apps/api-gateway/src/user/dto/login-user.dto.ts +++ b/apps/api-gateway/src/user/dto/login-user.dto.ts @@ -1,20 +1,19 @@ -import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString } from 'class-validator' -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' export class LoginUserDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiProperty() - @Transform(({ value }) => trim(value)) - @IsNotEmpty({ message: 'Password is required.' }) - password: string; - -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'Password is required.' }) + password: string +} diff --git a/apps/api-gateway/src/user/dto/update-platform-settings.dto.ts b/apps/api-gateway/src/user/dto/update-platform-settings.dto.ts index 5a13db9f9..ae0102ffb 100644 --- a/apps/api-gateway/src/user/dto/update-platform-settings.dto.ts +++ b/apps/api-gateway/src/user/dto/update-platform-settings.dto.ts @@ -1,29 +1,29 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsOptional, IsString } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsOptional, IsString } from 'class-validator' export class UpdatePlatformSettingsDto { - @ApiProperty({ example: '127.0.0.1' }) - @IsOptional() - @IsString({ message: 'external Ip should be string' }) - externalIp: string; + @ApiProperty({ example: '127.0.0.1' }) + @IsOptional() + @IsString({ message: 'external Ip should be string' }) + externalIp: string - @ApiProperty({ example: '127.0.0.1' }) - @IsOptional() - @IsString({ message: 'inbound endpoint should be string' }) - inboundEndpoint: string; + @ApiProperty({ example: '127.0.0.1' }) + @IsOptional() + @IsString({ message: 'inbound endpoint should be string' }) + inboundEndpoint: string - @ApiProperty() - @IsOptional() - @IsString({ message: 'sgApiKey should be string' }) - sgApiKey: string; + @ApiProperty() + @IsOptional() + @IsString({ message: 'sgApiKey should be string' }) + sgApiKey: string - @ApiProperty({ example: 'abc13@yopmail.com' }) - @IsOptional() - @IsString({ message: 'emailFrom should be string' }) - emailFrom: string; + @ApiProperty({ example: 'abc13@yopmail.com' }) + @IsOptional() + @IsString({ message: 'emailFrom should be string' }) + emailFrom: string - @ApiProperty({ example: `${process.env.UPLOAD_LOGO_HOST}` }) - @IsOptional() - @IsString({ message: 'API endpoint should be string' }) - apiEndPoint: string; -} \ No newline at end of file + @ApiProperty({ example: `${process.env.UPLOAD_LOGO_HOST}` }) + @IsOptional() + @IsString({ message: 'API endpoint should be string' }) + apiEndPoint: string +} diff --git a/apps/api-gateway/src/user/dto/update-user-profile.dto.ts b/apps/api-gateway/src/user/dto/update-user-profile.dto.ts index fb11882f7..1c5277c45 100644 --- a/apps/api-gateway/src/user/dto/update-user-profile.dto.ts +++ b/apps/api-gateway/src/user/dto/update-user-profile.dto.ts @@ -1,27 +1,26 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsOptional, IsString, IsBoolean } from 'class-validator'; - +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { IsBoolean, IsOptional, IsString } from 'class-validator' export class UpdateUserProfileDto { - id: string; + id: string - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'ProfileLogoUrl should be string' }) - profileImg?: string; + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'ProfileLogoUrl should be string' }) + profileImg?: string - @ApiProperty({ example: 'Alen' }) - @IsString({ message: 'firstName should be string' }) - @IsOptional() - firstName?: string; + @ApiProperty({ example: 'Alen' }) + @IsString({ message: 'firstName should be string' }) + @IsOptional() + firstName?: string - @ApiProperty({ example: 'Harvey' }) - @IsString({ message: 'lastName should be string' }) - @IsOptional() - lastName?: string; + @ApiProperty({ example: 'Harvey' }) + @IsString({ message: 'lastName should be string' }) + @IsOptional() + lastName?: string - @ApiPropertyOptional({ example: true }) - @IsBoolean({ message: 'isPublic should be boolean' }) - @IsOptional() - isPublic?: boolean = false; -} \ No newline at end of file + @ApiPropertyOptional({ example: true }) + @IsBoolean({ message: 'isPublic should be boolean' }) + @IsOptional() + isPublic?: boolean = false +} diff --git a/apps/api-gateway/src/user/interfaces/index.ts b/apps/api-gateway/src/user/interfaces/index.ts index 10d95bbfb..7cad07713 100644 --- a/apps/api-gateway/src/user/interfaces/index.ts +++ b/apps/api-gateway/src/user/interfaces/index.ts @@ -1,23 +1,23 @@ export interface IUserRequestInterface { - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - orgName?: string; - selectedOrg: ISelectedOrgInterface; + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + orgName?: string + selectedOrg: ISelectedOrgInterface } export interface ISelectedOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: IOrganizationInterface; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: IOrganizationInterface } export interface IOrganizationInterface { - name: string; - description: string; + name: string + description: string } diff --git a/apps/api-gateway/src/user/user.controller.ts b/apps/api-gateway/src/user/user.controller.ts index c9f138a52..37ee6b120 100644 --- a/apps/api-gateway/src/user/user.controller.ts +++ b/apps/api-gateway/src/user/user.controller.ts @@ -1,19 +1,26 @@ +import type { AwsService } from '@credebl/aws/aws.service' +import type { CommonService } from '@credebl/common' +import { TrimStringParamPipe } from '@credebl/common/cast.helper' +import type { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import type IResponse from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Invitation } from '@credebl/enum/enum' import { + BadRequestException, + Body, Controller, + Get, + HttpStatus, + Param, + ParseUUIDPipe, Post, Put, - Body, - Param, - UseFilters, - Res, - HttpStatus, - BadRequestException, - Get, Query, + Res, + UseFilters, UseGuards, - ParseUUIDPipe -} from '@nestjs/common'; -import { UserService } from './user.service'; +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' import { ApiBearerAuth, ApiExcludeEndpoint, @@ -23,34 +30,27 @@ import { ApiQuery, ApiResponse, ApiTags, - ApiUnauthorizedResponse -} from '@nestjs/swagger'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { Response } from 'express'; -import { CommonService } from '@credebl/common'; -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'; -import { User } from '../authz/decorators/user.decorator'; -import { AcceptRejectInvitationDto } from './dto/accept-reject-invitation.dto'; -import { Invitation } from '@credebl/enum/enum'; -import { IUserRequestInterface } from './interfaces'; -import { GetAllInvitationsDto } from './dto/get-all-invitations.dto'; -import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -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'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { AwsService } from '@credebl/aws/aws.service'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; -import { UserAccessGuard } from '../authz/guards/user-access-guard'; -import { TrimStringParamPipe } from '@credebl/common/cast.helper'; + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import type { user } from '@prisma/client' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { UserAccessGuard } from '../authz/guards/user-access-guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import type { EmailValidator } from '../dtos/email-validator.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { AcceptRejectInvitationDto } from './dto/accept-reject-invitation.dto' +import type { AddPasskeyDetailsDto } from './dto/add-user.dto' +import type { GetAllInvitationsDto } from './dto/get-all-invitations.dto' +import type { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto' +import type { UpdateUserProfileDto } from './dto/update-user-profile.dto' +import type { IUserRequestInterface } from './interfaces' +import type { UserService } from './user.service' @UseFilters(CustomExceptionFilter) @Controller('users') @@ -62,7 +62,7 @@ export class UserController { private readonly userService: UserService, private readonly commonService: CommonService, private readonly awsService: AwsService - ) { } + ) {} /** * @@ -78,36 +78,36 @@ export class UserController { @ApiQuery({ name: 'pageNumber', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'pageSize', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'search', type: String, - required: false + required: false, }) async get( - @User() user: IUserRequestInterface, + @User() _user: IUserRequestInterface, @Query() paginationDto: PaginationDto, @Res() res: Response ): Promise { - const users = await this.userService.get(paginationDto); + const users = await this.userService.get(paginationDto) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchUsers, - data: users - }; + data: users, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } - /** + /** * Get public profile details of a user by username. - * + * * @param username The username of the user. * @returns Public profile information. */ @@ -115,26 +115,25 @@ export class UserController { @ApiExcludeEndpoint() @ApiOperation({ summary: 'Fetch user details', - description: 'Retrieve publicly available details of a user using their username.' + description: 'Retrieve publicly available details of a user using their username.', }) @ApiParam({ name: 'username', type: String, - required: false + required: false, }) async getPublicProfile(@Param('username') username: string, @Res() res: Response): Promise { - const userData = await this.userService.getPublicProfile(username); + const userData = await this.userService.getPublicProfile(username) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchProfile, - data: userData - }; + data: userData, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } - /** * Retrieves the profile details of the currently logged-in user. * @@ -143,57 +142,57 @@ export class UserController { @Get('/profile') @ApiOperation({ summary: 'Fetch login user details', - description: 'Retrieves the profile details of the currently logged-in user.' + description: 'Retrieves the profile details of the currently logged-in user.', }) @UseGuards(AuthGuard('jwt'), UserAccessGuard) @ApiBearerAuth() async getProfile(@User() reqUser: user, @Res() res: Response): Promise { - const userData = await this.userService.getProfile(reqUser.id); - + const userData = await this.userService.getProfile(reqUser.id) + const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchProfile, - data: userData - }; + data: userData, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } - /** + /** * Retrieves all platform settings. - * + * * @returns The platform settings. */ @Get('/platform-settings') @ApiOperation({ summary: 'Get all platform settings', - description: 'Retrieves all platform settings.' + description: 'Retrieves all platform settings.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard, UserAccessGuard) @Roles(OrgRoles.PLATFORM_ADMIN) @ApiBearerAuth() async getPlatformSettings(@Res() res: Response): Promise { - const settings = await this.userService.getPlatformSettings(); + const settings = await this.userService.getPlatformSettings() const finalResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchPlatformSettings, - data: settings - }; + data: settings, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** - * Fetch user activities. - * - * @param limit - Number of activities to fetch. - * @returns A response containing user activity data. - */ + * Fetch user activities. + * + * @param limit - Number of activities to fetch. + * @returns A response containing user activity data. + */ @Get('/activity') @ApiOperation({ summary: 'Fetch users activity', - description: 'Fetch a list of recent activities performed by the user.' + description: 'Fetch a list of recent activities performed by the user.', }) @UseGuards(AuthGuard('jwt'), UserAccessGuard) @ApiBearerAuth() @@ -203,134 +202,145 @@ export class UserController { @Res() res: Response, @User() reqUser: user ): Promise { - const userDetails = await this.userService.getUserActivities(reqUser.id, limit); + const userDetails = await this.userService.getUserActivities(reqUser.id, limit) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.userActivity, - data: userDetails - }; + data: userDetails, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } - - /** - * Fetch organization invitations. - * - * @returns A paginated list of organization invitations. - */ + /** + * Fetch organization invitations. + * + * @returns A paginated list of organization invitations. + */ @Get('/org-invitations') @ApiOperation({ summary: 'organization invitations', - description: 'Retrieve a list of invitations received to the user to join organizations.' + description: 'Retrieve a list of invitations received to the user to join organizations.', }) @UseGuards(AuthGuard('jwt'), UserAccessGuard) @ApiBearerAuth() @ApiQuery({ name: 'pageNumber', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'pageSize', type: Number, - required: false + required: false, }) @ApiQuery({ name: 'search', type: String, - required: false + required: false, }) @ApiQuery({ name: 'status', type: String, - required: false + required: false, }) async invitations( - @Query() getAllInvitationsDto: GetAllInvitationsDto, + @Query() getAllInvitationsDto: GetAllInvitationsDto, @User() reqUser: user, @Res() res: Response ): Promise { if (!Object.values(Invitation).includes(getAllInvitationsDto.status)) { - throw new BadRequestException(ResponseMessages.user.error.invalidInvitationStatus); + throw new BadRequestException(ResponseMessages.user.error.invalidInvitationStatus) } const invitations = await this.userService.invitations( reqUser.id, getAllInvitationsDto.status, getAllInvitationsDto - ); + ) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.fetchInvitations, - data: invitations - }; + data: invitations, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } - /** - * Checks if a user is registered and verifies email existence. - * - * @param email The email address to check. - * @returns Returns user registration and email verification status. - */ + /** + * Checks if a user is registered and verifies email existence. + * + * @param email The email address to check. + * @returns Returns user registration and email verification status. + */ @Get('/:email') - @ApiOperation({ summary: 'Check user registration and email verification status', description: 'Check if a user is already registered and if their email already exists.' }) + @ApiOperation({ + summary: 'Check user registration and email verification status', + description: 'Check if a user is already registered and if their email already exists.', + }) async checkUserExist(@Param() emailParam: EmailValidator, @Res() res: Response): Promise { - const userDetails = await this.userService.checkUserExist(emailParam.email); + const userDetails = await this.userService.checkUserExist(emailParam.email) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.user.success.checkEmail, - data: userDetails - }; + data: userDetails, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } /** - * Accept or reject an organization invitation. - * - * @param invitationId The ID of the organization invitation. - * @body AcceptRejectInvitationDto - * @returns The status of the organization invitation response. - */ + * Accept or reject an organization invitation. + * + * @param invitationId The ID of the organization invitation. + * @body AcceptRejectInvitationDto + * @returns The status of the organization invitation response. + */ @Post('/org-invitations/:invitationId') @ApiOperation({ summary: 'accept/reject organization invitation', - description: 'Accept or reject an invitation to join an organization.' + description: 'Accept or reject an invitation to join an organization.', }) @UseGuards(AuthGuard('jwt'), UserAccessGuard) @ApiBearerAuth() async acceptRejectInvitaion( - @Body() acceptRejectInvitation: AcceptRejectInvitationDto, - @Param('invitationId', TrimStringParamPipe, new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(`Invalid format for InvitationId`); }})) invitationId: string, + @Body() acceptRejectInvitation: AcceptRejectInvitationDto, + @Param( + 'invitationId', + TrimStringParamPipe, + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException('Invalid format for InvitationId') + }, + }) + ) + invitationId: string, @User() reqUser: user, @Res() res: Response ): Promise { - acceptRejectInvitation.invitationId = invitationId; - const invitationRes = await this.userService.acceptRejectInvitaion(acceptRejectInvitation, reqUser.id); + acceptRejectInvitation.invitationId = invitationId + const invitationRes = await this.userService.acceptRejectInvitaion(acceptRejectInvitation, reqUser.id) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, - message: invitationRes - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + message: invitationRes, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } - + /** - * Updates the user profile. - * - * @body UpdateUserProfileDto - * @returns A response indicating the success of the update operation. - */ + * Updates the user profile. + * + * @body UpdateUserProfileDto + * @returns A response indicating the success of the update operation. + */ @Put('/') @ApiOperation({ summary: 'Update user profile', - description: 'Modify the user profile details such as name, email, or other information.' + description: 'Modify the user profile details such as name, email, or other information.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiBearerAuth() @@ -340,55 +350,55 @@ export class UserController { @User() reqUser: user, @Res() res: Response ): Promise { - const userId = reqUser.id; - updateUserProfileDto.id = userId; - await this.userService.updateUserProfile(updateUserProfileDto); - + const userId = reqUser.id + updateUserProfileDto.id = userId + await this.userService.updateUserProfile(updateUserProfileDto) + const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.update - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.user.success.update, + } + return res.status(HttpStatus.OK).json(finalResponse) } - /** + /** * @body AddPasskeyDetailsDto * @returns User's profile update status */ - - - @Put('/password/:email') - @ApiOperation({ summary: 'Store user password details', description: 'Securely store and update the user’s password details.' }) - @ApiExcludeEndpoint() - @ApiBearerAuth() - @UseGuards(AuthGuard('jwt'), UserAccessGuard) - - async addPasskey( - @Body() userInfo: AddPasskeyDetailsDto, - @User() reqUser: user, - @Res() res: Response - ): Promise { - - const userDetails = await this.userService.addPasskey(reqUser.email, userInfo); - const finalResponse = { - statusCode: HttpStatus.OK, - message: ResponseMessages.user.success.update, - data: userDetails - }; - - return res.status(HttpStatus.OK).json(finalResponse); - } + + @Put('/password/:email') + @ApiOperation({ + summary: 'Store user password details', + description: 'Securely store and update the user’s password details.', + }) + @ApiExcludeEndpoint() + @ApiBearerAuth() + @UseGuards(AuthGuard('jwt'), UserAccessGuard) + async addPasskey( + @Body() userInfo: AddPasskeyDetailsDto, + @User() reqUser: user, + @Res() res: Response + ): Promise { + const userDetails = await this.userService.addPasskey(reqUser.email, userInfo) + const finalResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.user.success.update, + data: userDetails, + } + + return res.status(HttpStatus.OK).json(finalResponse) + } /** - * Updates platform settings. - * @body UpdatePlatformSettingsDto - * - * @returns Status of the update operation. - */ + * Updates platform settings. + * @body UpdatePlatformSettingsDto + * + * @returns Status of the update operation. + */ @Put('/platform-settings') @ApiOperation({ summary: 'Update platform settings', - description: 'Modify platform settings. Only accessible by platform admins.' + description: 'Modify platform settings. Only accessible by platform admins.', }) @UseGuards(AuthGuard('jwt'), OrgRolesGuard, UserAccessGuard) @Roles(OrgRoles.PLATFORM_ADMIN) @@ -397,13 +407,13 @@ export class UserController { @Body() platformSettings: UpdatePlatformSettingsDto, @Res() res: Response ): Promise { - const result = await this.userService.updatePlatformSettings(platformSettings); + const result = await this.userService.updatePlatformSettings(platformSettings) const finalResponse = { statusCode: HttpStatus.OK, - message: result - }; + message: result, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } -} \ No newline at end of file +} diff --git a/apps/api-gateway/src/user/user.module.ts b/apps/api-gateway/src/user/user.module.ts index 02a920ffa..4a8c7dd92 100644 --- a/apps/api-gateway/src/user/user.module.ts +++ b/apps/api-gateway/src/user/user.module.ts @@ -1,14 +1,14 @@ -import { CommonService } from '@credebl/common'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { ConfigModule } from '@nestjs/config'; -import { HttpModule } from '@nestjs/axios'; -import { Module } from '@nestjs/common'; -import { UserController } from './user.controller'; -import { UserService } from './user.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { AwsService } from '@credebl/aws'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { CommonService } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { UserController } from './user.controller' +import { UserService } from './user.service' @Module({ imports: [ @@ -18,12 +18,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.USER_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - - } - ]) + options: getNatsOptions(CommonConstants.USER_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [UserController], - providers: [UserService, CommonService, AwsService, NATSClient] + providers: [UserService, CommonService, AwsService, NATSClient], }) export class UserModule {} diff --git a/apps/api-gateway/src/user/user.service.ts b/apps/api-gateway/src/user/user.service.ts index c3988d810..93a45c681 100644 --- a/apps/api-gateway/src/user/user.service.ts +++ b/apps/api-gateway/src/user/user.service.ts @@ -1,97 +1,95 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { AcceptRejectInvitationDto } from './dto/accept-reject-invitation.dto'; -import { GetAllInvitationsDto } from './dto/get-all-invitations.dto'; -import { UpdateUserProfileDto } from './dto/update-user-profile.dto'; -import { AddPasskeyDetailsDto } from './dto/add-user.dto'; -import { UpdatePlatformSettingsDto } from './dto/update-platform-settings.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'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import type { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import type { IUserInvitations } from '@credebl/common/interfaces/user.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { user } from '@prisma/client' +import type { ICheckUserDetails, IUsersProfile } from 'apps/user/interfaces/user.interface' +import { BaseService } from 'libs/service/base.service' +import type { IUsersActivity } from 'libs/user-activity/interface' +import type { AcceptRejectInvitationDto } from './dto/accept-reject-invitation.dto' +import type { AddPasskeyDetailsDto } from './dto/add-user.dto' +import type { GetAllInvitationsDto } from './dto/get-all-invitations.dto' +import type { UpdatePlatformSettingsDto } from './dto/update-platform-settings.dto' +import type { UpdateUserProfileDto } from './dto/update-user-profile.dto' @Injectable() export class UserService extends BaseService { - constructor(@Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, private readonly natsClient : NATSClient) { - super('User Service'); + constructor( + @Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('User Service') } async getProfile(id: string): Promise { - const payload = { id }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-profile', payload); + const payload = { id } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-profile', payload) } async getPublicProfile(username: string): Promise { - const payload = { username }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-public-profile', payload); + const payload = { username } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-public-profile', payload) } async updateUserProfile(updateUserProfileDto: UpdateUserProfileDto): Promise { - const payload = { updateUserProfileDto }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-user-profile', payload); + const payload = { updateUserProfileDto } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-user-profile', payload) } async findUserinSupabase(id: string): Promise { - const payload = { id }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-by-supabase', payload); + const payload = { id } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-by-supabase', payload) } async findUserinKeycloak(id: string): Promise { - const payload = { id }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-by-keycloak', payload); + const payload = { id } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-by-keycloak', payload) } - + async invitations(id: string, status: string, getAllInvitationsDto: GetAllInvitationsDto): Promise { - const { pageNumber, pageSize, search } = getAllInvitationsDto; - const payload = { id, status, pageNumber, pageSize, search }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-org-invitations', payload); + const { pageNumber, pageSize, search } = getAllInvitationsDto + const payload = { id, status, pageNumber, pageSize, search } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-org-invitations', payload) } - async acceptRejectInvitaion( - acceptRejectInvitation: AcceptRejectInvitationDto, - userId: string - ): Promise { - const payload = { acceptRejectInvitation, userId }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'accept-reject-invitations', payload); + async acceptRejectInvitaion(acceptRejectInvitation: AcceptRejectInvitationDto, userId: string): Promise { + const payload = { acceptRejectInvitation, userId } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'accept-reject-invitations', payload) } - async get( - paginationDto:PaginationDto - ): Promise { - const { pageNumber, pageSize, search } = paginationDto; - const payload = { pageNumber, pageSize, search }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-users', payload); + async get(paginationDto: PaginationDto): Promise { + const { pageNumber, pageSize, search } = paginationDto + const payload = { pageNumber, pageSize, search } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-users', payload) } async checkUserExist(userEmail: string): Promise { - const payload = { userEmail }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'check-user-exist', payload); + const payload = { userEmail } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'check-user-exist', payload) } async getUserActivities(userId: string, limit: number): Promise { - const payload = { userId, limit }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-activity', payload); + const payload = { userId, limit } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-activity', payload) } async addPasskey(userEmail: string, userInfo: AddPasskeyDetailsDto): Promise { - const payload = { userEmail, userInfo }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'add-passkey', payload); + const payload = { userEmail, userInfo } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'add-passkey', payload) } async updatePlatformSettings(platformSettings: UpdatePlatformSettingsDto): Promise { - const payload = { platformSettings }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-platform-settings', payload); + const payload = { platformSettings } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'update-platform-settings', payload) } async getPlatformSettings(): Promise { - return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-platform-settings', ''); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'fetch-platform-settings', '') } async getUserByUserIdInKeycloak(email: string): Promise { - const payload = { email }; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-info-by-user-email-keycloak', payload); + const payload = { email } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'get-user-info-by-user-email-keycloak', payload) } } diff --git a/apps/api-gateway/src/utilities/dtos/shortening-url.dto.ts b/apps/api-gateway/src/utilities/dtos/shortening-url.dto.ts index c49e5a788..6a93503f2 100644 --- a/apps/api-gateway/src/utilities/dtos/shortening-url.dto.ts +++ b/apps/api-gateway/src/utilities/dtos/shortening-url.dto.ts @@ -1,47 +1,44 @@ - -import { ApiExtraModels, ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsNotEmpty } from 'class-validator'; +import { ApiExtraModels, ApiProperty } from '@nestjs/swagger' +import { IsArray, IsNotEmpty } from 'class-validator' @ApiExtraModels() - export class UtilitiesDto { + @ApiProperty() + @IsNotEmpty() + credentialId: string - @ApiProperty() - @IsNotEmpty() - credentialId: string; - - @ApiProperty() - @IsNotEmpty() - schemaId: string; - - @ApiProperty() - @IsNotEmpty() - credDefId: string; + @ApiProperty() + @IsNotEmpty() + schemaId: string - @ApiProperty() - @IsNotEmpty() - invitationUrl: string; + @ApiProperty() + @IsNotEmpty() + credDefId: string - @ApiProperty({ - example: [ - { - name: 'name', - value: 'value' - } - ] - }) - @IsArray({ message: 'attributes must be a valid array' }) - @IsNotEmpty({ message: 'please provide valid attributes' }) - attributes: Attribute[]; + @ApiProperty() + @IsNotEmpty() + invitationUrl: string + + @ApiProperty({ + example: [ + { + name: 'name', + value: 'value', + }, + ], + }) + @IsArray({ message: 'attributes must be a valid array' }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + attributes: Attribute[] } interface Attribute { - name: string; - value: string; - } + name: string + value: string +} - export class StoreObjectDto { +export class StoreObjectDto { @ApiProperty() @IsNotEmpty() - data: string | object; -} \ No newline at end of file + data: string | object +} diff --git a/apps/api-gateway/src/utilities/utilities.controller.ts b/apps/api-gateway/src/utilities/utilities.controller.ts index a1cba29aa..70939bc7b 100644 --- a/apps/api-gateway/src/utilities/utilities.controller.ts +++ b/apps/api-gateway/src/utilities/utilities.controller.ts @@ -1,15 +1,22 @@ -import { ApiBearerAuth, ApiForbiddenResponse, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; -import { Controller, UseFilters, Post, Body, Res, HttpStatus, Param, UseGuards } from '@nestjs/common'; -import IResponse from '@credebl/common/interfaces/response.interface'; -import { Response } from 'express'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { StoreObjectDto, UtilitiesDto } from './dtos/shortening-url.dto'; -import { UtilitiesService } from './utilities.service'; -import { AuthGuard } from '@nestjs/passport'; +import type IResponse from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Body, Controller, HttpStatus, Param, Post, Res, UseFilters, UseGuards } from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' +import { + ApiBearerAuth, + ApiForbiddenResponse, + ApiOperation, + ApiResponse, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { StoreObjectDto, UtilitiesDto } from './dtos/shortening-url.dto' +import type { UtilitiesService } from './utilities.service' @UseFilters(CustomExceptionFilter) @Controller('utilities') @@ -17,10 +24,7 @@ import { AuthGuard } from '@nestjs/passport'; @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) export class UtilitiesController { - - constructor( - private readonly utilitiesService: UtilitiesService - ) { } + constructor(private readonly utilitiesService: UtilitiesService) {} /** * Create a shortening URL @@ -32,13 +36,13 @@ export class UtilitiesController { @ApiOperation({ summary: 'Create Shortening URL', description: 'Create a shortening URL for the provided details.' }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Shortening URL created successfully', type: ApiResponseDto }) async createShorteningUrl(@Body() shorteningUrlDto: UtilitiesDto, @Res() res: Response): Promise { - const shorteningUrl = await this.utilitiesService.createShorteningUrl(shorteningUrlDto); + const shorteningUrl = await this.utilitiesService.createShorteningUrl(shorteningUrlDto) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.shorteningUrl.success.createShorteningUrl, - data: shorteningUrl - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: shorteningUrl, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -51,16 +55,26 @@ export class UtilitiesController { @Post('/store-object/:persist') @ApiBearerAuth() @UseGuards(AuthGuard('jwt')) - @ApiOperation({ summary: 'Store Object and Create Short URL', description: 'Store an object and create a short URL representing the object.' }) - @ApiResponse({ status: HttpStatus.CREATED, description: 'Object stored and short URL created successfully', type: ApiResponseDto }) - async storeObject(@Body() storeObjectDto: StoreObjectDto, @Param('persist') persist: boolean, @Res() res: Response): Promise { - const shorteningUrl = await this.utilitiesService.storeObject(persist.valueOf(), storeObjectDto); + @ApiOperation({ + summary: 'Store Object and Create Short URL', + description: 'Store an object and create a short URL representing the object.', + }) + @ApiResponse({ + status: HttpStatus.CREATED, + description: 'Object stored and short URL created successfully', + type: ApiResponseDto, + }) + async storeObject( + @Body() storeObjectDto: StoreObjectDto, + @Param('persist') persist: boolean, + @Res() res: Response + ): Promise { + const shorteningUrl = await this.utilitiesService.storeObject(persist.valueOf(), storeObjectDto) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.storeObject.success.storeObject, - data: shorteningUrl - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: shorteningUrl, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } } - diff --git a/apps/api-gateway/src/utilities/utilities.module.ts b/apps/api-gateway/src/utilities/utilities.module.ts index 3fc905a4f..60f274fc6 100644 --- a/apps/api-gateway/src/utilities/utilities.module.ts +++ b/apps/api-gateway/src/utilities/utilities.module.ts @@ -1,14 +1,14 @@ -import { CommonModule, CommonService } from '@credebl/common'; +import { CommonModule, CommonService } from '@credebl/common' -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { ConfigModule } from '@nestjs/config'; -import { HttpModule } from '@nestjs/axios'; -import { Module } from '@nestjs/common'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { UtilitiesController } from './utilities.controller'; -import { UtilitiesService } from './utilities.service'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { UtilitiesController } from './utilities.controller' +import { UtilitiesService } from './utilities.service' @Module({ imports: [ @@ -18,12 +18,12 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.UTILITY_SERVICE, process.env.API_GATEWAY_NKEY_SEED) + options: getNatsOptions(CommonConstants.UTILITY_SERVICE, process.env.API_GATEWAY_NKEY_SEED), }, - CommonModule - ]) + CommonModule, + ]), ], controllers: [UtilitiesController], - providers: [UtilitiesService, CommonService, NATSClient] + providers: [UtilitiesService, CommonService, NATSClient], }) export class UtilitiesModule {} diff --git a/apps/api-gateway/src/utilities/utilities.service.ts b/apps/api-gateway/src/utilities/utilities.service.ts index c90142ee4..cad6e30d3 100644 --- a/apps/api-gateway/src/utilities/utilities.service.ts +++ b/apps/api-gateway/src/utilities/utilities.service.ts @@ -1,22 +1,25 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { StoreObjectDto, UtilitiesDto } from './dtos/shortening-url.dto'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { NATSClient } from '@credebl/common/NATSClient' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import { BaseService } from 'libs/service/base.service' +import type { StoreObjectDto, UtilitiesDto } from './dtos/shortening-url.dto' @Injectable() export class UtilitiesService extends BaseService { - constructor(@Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, private readonly natsClient : NATSClient) { - super('OrganizationService'); + constructor( + @Inject('NATS_CLIENT') private readonly serviceProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('OrganizationService') } async createShorteningUrl(shorteningUrlDto: UtilitiesDto): Promise { - return this.natsClient.sendNatsMessage(this.serviceProxy, 'create-shortening-url', shorteningUrlDto); + return this.natsClient.sendNatsMessage(this.serviceProxy, 'create-shortening-url', shorteningUrlDto) } async storeObject(persistent: boolean, storeObjectDto: StoreObjectDto): Promise { - const storeObj = storeObjectDto.data; - const payload = {persistent, storeObj}; - return this.natsClient.sendNatsMessage(this.serviceProxy, 'store-object-return-url', payload); + const storeObj = storeObjectDto.data + const payload = { persistent, storeObj } + return this.natsClient.sendNatsMessage(this.serviceProxy, 'store-object-return-url', payload) } } 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 d414112fb..d5178b7c1 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,29 +1,26 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } 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'; -import { PaginationDto } from '@credebl/common/dtos/pagination.dto'; +import { trim } from '@credebl/common/cast.helper' +import { PaginationDto } from '@credebl/common/dtos/pagination.dto' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsEnum, IsOptional } from 'class-validator' +import { SortValue } from '../../enum' +import { SortFields } from '../enum/verification.enum' export class GetAllProofRequestsDto extends PaginationDto { - - @ApiProperty({ - enum: [SortValue.DESC, SortValue.ASC], - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(SortValue) - sortBy: string = SortValue.DESC; - - @ApiProperty({ - required: false - }) - @Transform(({ value }) => trim(value)) - @IsOptional() - @IsEnum(SortFields) - sortField: string = SortFields.CREATED_DATE_TIME; - -} + @ApiProperty({ + enum: [SortValue.DESC, SortValue.ASC], + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SortValue) + sortBy: string = SortValue.DESC + @ApiProperty({ + required: false, + }) + @Transform(({ value }) => trim(value)) + @IsOptional() + @IsEnum(SortFields) + sortField: string = SortFields.CREATED_DATE_TIME +} diff --git a/apps/api-gateway/src/verification/dto/request-proof.dto.ts b/apps/api-gateway/src/verification/dto/request-proof.dto.ts index 6f1b41072..02b11f967 100644 --- a/apps/api-gateway/src/verification/dto/request-proof.dto.ts +++ b/apps/api-gateway/src/verification/dto/request-proof.dto.ts @@ -1,473 +1,478 @@ -import { ArrayNotEmpty, IsArray, IsBoolean, IsEmail, IsEnum, IsNotEmpty, IsNumberString, IsObject, IsOptional, IsString, ValidateIf, ValidateNested, IsUUID, ArrayUnique, ArrayMaxSize, ArrayMinSize } from 'class-validator'; -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { Transform, Type } from 'class-transformer'; -import { AutoAccept } from '@credebl/enum/enum'; -import { IProofFormats } from '../interfaces/verification.interface'; -import { ProofRequestType } from '../enum/verification.enum'; +import { trim } from '@credebl/common/cast.helper' +import { AutoAccept } from '@credebl/enum/enum' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform, Type } from 'class-transformer' +import { + ArrayMaxSize, + ArrayMinSize, + ArrayNotEmpty, + ArrayUnique, + IsArray, + IsBoolean, + IsEmail, + IsEnum, + IsNotEmpty, + IsNumberString, + IsObject, + IsOptional, + IsString, + IsUUID, + ValidateIf, + ValidateNested, +} from 'class-validator' +import type { ProofRequestType } from '../enum/verification.enum' +import type { IProofFormats } from '../interfaces/verification.interface' export class ProofRequestAttribute { + @ValidateIf((obj) => obj.attributeNames === undefined) + @IsNotEmpty() + @IsString() + attributeName?: string + + @ValidateIf((obj) => obj.attributeName === undefined) + @IsArray({ message: 'attributeNames must be an array' }) + @ArrayNotEmpty({ message: 'array can not be empty' }) + @IsString({ each: true }) + @IsNotEmpty({ each: true, message: 'each element cannot be empty' }) + attributeNames?: string[] - @ValidateIf((obj) => obj.attributeNames === undefined) - @IsNotEmpty() - @IsString() - attributeName?: string; - - @ValidateIf((obj) => obj.attributeName === undefined) - @IsArray({ message: 'attributeNames must be an array' }) - @ArrayNotEmpty({ message: 'array can not be empty' }) - @IsString({ each: true }) - @IsNotEmpty({ each: true, message: 'each element cannot be empty' }) - attributeNames?: string[]; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'schemaId is required' }) - schemaId?: string; - - @ApiPropertyOptional() - @ValidateIf((obj) => obj.value !== undefined || obj.condition !== undefined) - @IsNotEmpty({ message: 'condition is required' }) - @IsString({ message: 'condition must be a string' }) - condition?: string; - - @ApiPropertyOptional() - @ValidateIf((obj) => obj.condition !== undefined || obj.value !== undefined) - @IsNotEmpty({ message: 'value is required' }) - @IsNumberString({}, { message: 'value must be a number' }) - value?: string; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty({ message: 'credDefId is required' }) - credDefId?: string; + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'schemaId is required' }) + schemaId?: string + + @ApiPropertyOptional() + @ValidateIf((obj) => obj.value !== undefined || obj.condition !== undefined) + @IsNotEmpty({ message: 'condition is required' }) + @IsString({ message: 'condition must be a string' }) + condition?: string + + @ApiPropertyOptional() + @ValidateIf((obj) => obj.condition !== undefined || obj.value !== undefined) + @IsNotEmpty({ message: 'value is required' }) + @IsNumberString({}, { message: 'value must be a number' }) + value?: string + + @ApiPropertyOptional() + @IsString() + @IsOptional() + @IsNotEmpty({ message: 'credDefId is required' }) + credDefId?: string } class ProofPayload { - @ApiPropertyOptional() - @IsString({ message: 'goalCode must be in string' }) - @IsNotEmpty({ message: 'please provide valid goalCode' }) - @IsOptional() - goalCode: string; - - @ApiPropertyOptional() - @IsString({ message: 'parentThreadId must be in string' }) - @IsNotEmpty({ message: 'please provide valid parentThreadId' }) - @IsOptional() - parentThreadId?: string; - - @ApiPropertyOptional() - @IsBoolean({ message: 'willConfirm must be in boolean' }) - @IsNotEmpty({ message: 'please provide valid willConfirm' }) - @IsOptional() - willConfirm: boolean; - - @ApiPropertyOptional() - @IsString({ message: 'protocolVersion must be in string' }) - @IsNotEmpty({ message: 'please provide valid protocol version' }) - @IsOptional() - protocolVersion: string; + @ApiPropertyOptional() + @IsString({ message: 'goalCode must be in string' }) + @IsNotEmpty({ message: 'please provide valid goalCode' }) + @IsOptional() + goalCode: string + + @ApiPropertyOptional() + @IsString({ message: 'parentThreadId must be in string' }) + @IsNotEmpty({ message: 'please provide valid parentThreadId' }) + @IsOptional() + parentThreadId?: string + + @ApiPropertyOptional() + @IsBoolean({ message: 'willConfirm must be in boolean' }) + @IsNotEmpty({ message: 'please provide valid willConfirm' }) + @IsOptional() + willConfirm: boolean + + @ApiPropertyOptional() + @IsString({ message: 'protocolVersion must be in string' }) + @IsNotEmpty({ message: 'please provide valid protocol version' }) + @IsOptional() + protocolVersion: string } export class Fields { @ApiProperty() @IsArray() @IsNotEmpty({ message: 'path is required' }) - path: string[]; + path: string[] } export class Constraints { - @ApiProperty({type: () => [Fields]}) + @ApiProperty({ type: () => [Fields] }) @IsOptional() @IsNotEmpty({ message: 'Fields are required' }) @ValidateNested() @Type(() => Fields) - fields: Fields[]; + fields: Fields[] } - export class Schema { @ApiProperty() @IsNotEmpty({ message: 'uri is required' }) @IsString() - uri:string; - + uri: string } export class InputDescriptors { @ApiProperty() @IsNotEmpty({ message: 'id is required' }) @IsString() - id:string; + id: string @ApiProperty() @IsString() @IsOptional() @IsNotEmpty({ message: 'name is required' }) - name:string; + name: string @ApiProperty() @IsString() @IsOptional() @IsNotEmpty({ message: 'purpose is required' }) - purpose:string; - - @ApiProperty({type: () => [Schema]}) + purpose: string + + @ApiProperty({ type: () => [Schema] }) @IsNotEmpty({ message: 'schema is required' }) @ValidateNested() @Type(() => Schema) - schema:Schema[]; + schema: Schema[] - - @ApiProperty({type: () => Constraints}) + @ApiProperty({ type: () => Constraints }) @IsOptional() @IsNotEmpty({ message: 'Constraints are required' }) @ValidateNested() @Type(() => Constraints) - constraints:Constraints; - + constraints: Constraints } export class ProofRequestPresentationDefinition { - @ApiProperty() @IsString() @IsNotEmpty({ message: 'id is required' }) - id: string; + id: string @IsString() @IsOptional() - name: string; + name: string @ApiPropertyOptional() @IsString() @IsOptional() - purpose?: string; + purpose?: string - @ApiProperty({type: () => [InputDescriptors]}) + @ApiProperty({ type: () => [InputDescriptors] }) @IsArray({ message: 'inputDescriptors must be an array' }) @IsNotEmpty({ message: 'inputDescriptors is required' }) @ArrayMinSize(1) - @ValidateNested({each:true}) + @ValidateNested({ each: true }) @Type(() => InputDescriptors) // eslint-disable-next-line camelcase - input_descriptors:InputDescriptors[]; + input_descriptors: InputDescriptors[] } export class ProofRequestAttributeDto { @ApiProperty({ - 'example': [ - { - attributeName: 'attributeName', - condition: '>=', - value: 'predicates', - credDefId: 'string', - schemaId: 'string' - } + example: [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: 'string', + schemaId: 'string', + }, ], - type: () => [ProofRequestAttribute] -}) -@IsArray({ message: 'attributes must be in array' }) -@ValidateNested({ each: true }) -@IsObject({ each: true }) -@IsNotEmpty({ message: 'please provide valid attributes' }) -@Type(() => ProofRequestAttribute) -attributes?: ProofRequestAttribute[]; + type: () => [ProofRequestAttribute], + }) + @IsArray({ message: 'attributes must be in array' }) + @ValidateNested({ each: true }) + @IsObject({ each: true }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + @Type(() => ProofRequestAttribute) + attributes?: ProofRequestAttribute[] } export class IndyDto { @ApiProperty({ - 'example': { - 'attributes': [ - { - attributeName: 'attributeName', - condition: '>=', - value: 'predicates', - credDefId: 'string', - schemaId: 'string' - } - ] - }, - type: () => [ProofRequestAttributeDto] - }) + example: { + attributes: [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: 'string', + schemaId: 'string', + }, + ], + }, + type: () => [ProofRequestAttributeDto], + }) @ValidateNested() @IsObject({ each: true }) @IsNotEmpty({ message: 'please provide valid attributes' }) @Type(() => ProofRequestAttributeDto) - indy: ProofRequestAttributeDto; + indy: ProofRequestAttributeDto } export class RequestProofDtoBase extends ProofPayload { - - @ApiProperty({ - 'example': - { - 'indy': { - 'attributes': [ - { - attributeName: 'attributeName', - condition: '>=', - value: 'predicates', - credDefId: 'string', - schemaId: 'string' - } - ] - } + @ApiProperty({ + example: { + indy: { + attributes: [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: 'string', + schemaId: 'string', + }, + ], }, - type: () => [IndyDto] + }, + type: () => [IndyDto], }) @IsOptional() @ValidateNested() @IsObject({ message: 'ProofFormatDto must be an object' }) @IsNotEmpty({ message: 'ProofFormatDto must not be empty' }) @Type(() => IndyDto) - proofFormats?: IndyDto; - - @ApiProperty({ - 'example': + proofFormats?: IndyDto + + @ApiProperty({ + example: { + id: '32f54163-7166-48f1-93d8-ff217bdb0653', + purpose: 'Used for KYC verification.', + // eslint-disable-next-line camelcase + input_descriptors: [ + { + id: 'healthcare_input_1', + name: 'Medical History', + schema: [ { - id: '32f54163-7166-48f1-93d8-ff217bdb0653', - purpose: 'Used for KYC verification.', - // eslint-disable-next-line camelcase - input_descriptors: [ - { - 'id': 'healthcare_input_1', - 'name': 'Medical History', - 'schema': [ - { - 'uri': 'https://health-schemas.org/1.0.1/medical_history.json' - } - - ], - 'constraints': { - 'fields': [ - { - 'path': ['$.credentialSubject.PatientID'] - } - ] - } - } - ] + uri: 'https://health-schemas.org/1.0.1/medical_history.json', }, - type: () => [ProofRequestPresentationDefinition] - }) - @IsOptional() - @ValidateNested() - @IsObject({ message: 'presentationDefinition must be an object' }) - @IsNotEmpty({ message: 'presentationDefinition must not be empty' }) - @Type(() => ProofRequestPresentationDefinition) - presentationDefinition?:ProofRequestPresentationDefinition; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'comment must be in string' }) - comment: string; - - type:ProofRequestType; - - orgId: string; - - @ApiPropertyOptional({enum:AutoAccept}) - @IsString({ message: 'auto accept proof must be in string' }) - @IsNotEmpty({ message: 'please provide valid auto accept proof' }) - @IsOptional() - @IsEnum(AutoAccept, { - message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}` - }) - autoAcceptProof: AutoAccept; - version: string; + ], + constraints: { + fields: [ + { + path: ['$.credentialSubject.PatientID'], + }, + ], + }, + }, + ], + }, + type: () => [ProofRequestPresentationDefinition], + }) + @IsOptional() + @ValidateNested() + @IsObject({ message: 'presentationDefinition must be an object' }) + @IsNotEmpty({ message: 'presentationDefinition must not be empty' }) + @Type(() => ProofRequestPresentationDefinition) + presentationDefinition?: ProofRequestPresentationDefinition + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'comment must be in string' }) + comment: string + + type: ProofRequestType + + orgId: string + + @ApiPropertyOptional({ enum: AutoAccept }) + @IsString({ message: 'auto accept proof must be in string' }) + @IsNotEmpty({ message: 'please provide valid auto accept proof' }) + @IsOptional() + @IsEnum(AutoAccept, { + message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}`, + }) + autoAcceptProof: AutoAccept + version: string } export class RequestProofDtoV1 extends RequestProofDtoBase { @ApiProperty({ - example: '32f54163-7166-48f1-93d8-ff217bdb0653' - }) - @IsNotEmpty({ message: 'connectionId is required' }) - @IsString({ message: 'connectionId must be a string' }) - @IsUUID() - connectionId:string; + example: '32f54163-7166-48f1-93d8-ff217bdb0653', + }) + @IsNotEmpty({ message: 'connectionId is required' }) + @IsString({ message: 'connectionId must be a string' }) + @IsUUID() + connectionId: string } - export class RequestProofDtoV2 extends RequestProofDtoBase { @ApiProperty({ - example: ['32f54163-7166-48f1-93d8-ff217bdb0653'] - }) + example: ['32f54163-7166-48f1-93d8-ff217bdb0653'], + }) @IsNotEmpty({ each: true, message: 'connectionId array elements must not be empty' }) @IsArray({ message: 'connectionId must be an array' }) @ArrayMinSize(1, { message: 'connectionId must contain at least 1 element' }) - @ArrayMaxSize(Number(process.env.PROOF_REQ_CONN_LIMIT), { message: `Limit reached (${process.env.PROOF_REQ_CONN_LIMIT} connections max).` }) + @ArrayMaxSize(Number(process.env.PROOF_REQ_CONN_LIMIT), { + message: `Limit reached (${process.env.PROOF_REQ_CONN_LIMIT} connections max).`, + }) @IsUUID('all', { each: true, message: 'Each connectionId must be a valid UUID' }) - connectionId: string[]; + connectionId: string[] } - export class OutOfBandRequestProof extends ProofPayload { - @ApiProperty({ - 'example': [ - { - attributeName: 'attributeName', - condition: '>=', - value: 'predicates', - credDefId: '', - schemaId: '' - } - ], - type: () => [ProofRequestAttribute] - }) - @IsArray({ message: 'attributes must be in array' }) - @ValidateNested({ each: true }) - @IsObject({ each: true }) - @IsNotEmpty({ message: 'please provide valid attributes' }) - @Type(() => ProofRequestAttribute) - attributes: ProofRequestAttribute[]; - - @ApiProperty() - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @Transform(({ value }) => trim(value)) - @IsString({ each: true, message: 'Each emailId in the array should be a string' }) - @IsOptional() - emailId?: string | string[]; - - @ApiProperty() - @IsOptional() - comment: string; - orgId: string; - - @ApiPropertyOptional() - @IsString({ message: 'auto accept proof must be in string' }) - @IsNotEmpty({ message: 'please provide valid auto accept proof' }) - @IsOptional() - @IsEnum(AutoAccept, { - message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}` - }) - autoAcceptProof: string; + @ApiProperty({ + example: [ + { + attributeName: 'attributeName', + condition: '>=', + value: 'predicates', + credDefId: '', + schemaId: '', + }, + ], + type: () => [ProofRequestAttribute], + }) + @IsArray({ message: 'attributes must be in array' }) + @ValidateNested({ each: true }) + @IsObject({ each: true }) + @IsNotEmpty({ message: 'please provide valid attributes' }) + @Type(() => ProofRequestAttribute) + attributes: ProofRequestAttribute[] + + @ApiProperty() + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @Transform(({ value }) => trim(value)) + @IsString({ each: true, message: 'Each emailId in the array should be a string' }) + @IsOptional() + emailId?: string | string[] + + @ApiProperty() + @IsOptional() + comment: string + orgId: string + + @ApiPropertyOptional() + @IsString({ message: 'auto accept proof must be in string' }) + @IsNotEmpty({ message: 'please provide valid auto accept proof' }) + @IsOptional() + @IsEnum(AutoAccept, { + message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}`, + }) + autoAcceptProof: string } export class SendProofRequestPayload { + @ApiPropertyOptional() + @IsOptional() + @IsNotEmpty({ message: 'Please provide valid goal code' }) + @IsString({ message: 'goal code should be string' }) + goalCode?: string - @ApiPropertyOptional() - @IsOptional() - @IsNotEmpty({ message: 'Please provide valid goal code' }) - @IsString({ message: 'goal code should be string' }) - goalCode?: string; - - @ApiPropertyOptional() - @IsString({ message: 'protocolVersion must be in string' }) - @IsNotEmpty({ message: 'please provide valid protocol version' }) - @IsOptional() - protocolVersion: string; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'comment must be in string' }) - comment: string; - - @ApiProperty({ - 'example': { - indy: { - name: 'Verify national identity', - version: '1.0', - // eslint-disable-next-line camelcase - requested_attributes: { - verifynameAddress: { - names: ['name', 'address'], - restrictions: [{ 'schema_id': 'KU583UbI4yAKfaBTSz1rqG:2:National ID:1.0.0' }] - }, - verifyBirthPlace: { - name: 'Place', - restrictions: [{ 'schema_id': 'KU583UbI4yAKfaBTSz1rqG:2:Birth Certificate:1.0.0' }] - } - }, - // eslint-disable-next-line camelcase - requested_predicates: {} - } - } - }) - @IsObject({ each: true }) - @IsNotEmpty({ message: 'please provide valid proofFormat' }) - @IsOptional() - proofFormats?: IProofFormats; - - @ApiProperty({ - 'example': + @ApiPropertyOptional() + @IsString({ message: 'protocolVersion must be in string' }) + @IsNotEmpty({ message: 'please provide valid protocol version' }) + @IsOptional() + protocolVersion: string + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'comment must be in string' }) + comment: string + + @ApiProperty({ + example: { + indy: { + name: 'Verify national identity', + version: '1.0', + // eslint-disable-next-line camelcase + requested_attributes: { + verifynameAddress: { + names: ['name', 'address'], + restrictions: [{ schema_id: 'KU583UbI4yAKfaBTSz1rqG:2:National ID:1.0.0' }], + }, + verifyBirthPlace: { + name: 'Place', + restrictions: [{ schema_id: 'KU583UbI4yAKfaBTSz1rqG:2:Birth Certificate:1.0.0' }], + }, + }, + // eslint-disable-next-line camelcase + requested_predicates: {}, + }, + }, + }) + @IsObject({ each: true }) + @IsNotEmpty({ message: 'please provide valid proofFormat' }) + @IsOptional() + proofFormats?: IProofFormats + + @ApiProperty({ + example: { + id: '32f54163-7166-48f1-93d8-ff217bdb0653', + purpose: 'Used for KYC verification.', + inputDescriptors: [ + { + id: 'banking_input_1', + name: 'Bank Account Information', + schema: [ { - id: '32f54163-7166-48f1-93d8-ff217bdb0653', - purpose: 'Used for KYC verification.', - inputDescriptors: [ - { - 'id': 'banking_input_1', - 'name': 'Bank Account Information', - 'schema': [ - { - 'uri': 'https://bank-schemas.org/1.0.0/accounts.json' - } - - ], - 'constraints': { - 'fields': [ - { - 'path': ['$.issuer'] - } - ] - } - } - ] + uri: 'https://bank-schemas.org/1.0.0/accounts.json', }, - type: () => [ProofRequestPresentationDefinition] - }) - @IsOptional() - @ValidateNested() - @IsObject({ message: 'presentationDefinition must be an object' }) - @IsNotEmpty({ message: 'presentationDefinition must not be empty' }) - @Type(() => ProofRequestPresentationDefinition) - presentationDefinition?:ProofRequestPresentationDefinition; - - type:string; - - @ApiPropertyOptional() - @IsString({ message: 'auto accept proof must be in string' }) - @IsNotEmpty({ message: 'please provide from valid auto accept proof options' }) - @IsOptional() - @IsEnum(AutoAccept, { - message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}` - }) - autoAcceptProof: AutoAccept; - - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'label must be in string' }) - label: string; - - // TODO: [Credo-ts] Issue with parentThreadId in creating an OOB proof request. - // This causes failures in OOB connection establishment. - // @ApiPropertyOptional() - // @IsOptional() - // @IsUUID() - // @IsNotEmpty({ message: 'please provide valid parentThreadId' }) - // parentThreadId: string; - - @ApiProperty({ example: true }) - @IsBoolean() - @IsOptional() - @IsNotEmpty({message:'Please provide the flag for shorten url'}) - isShortenUrl?: boolean; - - @ApiPropertyOptional() - @IsEmail({}, { each: true, message: 'Please provide a valid email' }) - @ArrayNotEmpty({ message: 'Email array must not be empty' }) - @ArrayUnique({ message: 'Duplicate emails are not allowed' }) - @ArrayMaxSize(Number(process.env.OOB_BATCH_SIZE), { message: `Limit reached (${process.env.OOB_BATCH_SIZE} proof request max).` }) - @IsArray() - @IsString({ each: true, message: 'Each emailId in the array should be a string' }) - @IsOptional() - emailId: string[]; - - @ApiPropertyOptional({ default: true }) - @IsOptional() - @IsNotEmpty({ message: 'please provide valid value for reuseConnection' }) - @IsBoolean({ message: 'reuseConnection must be a boolean' }) - reuseConnection?: boolean; + ], + constraints: { + fields: [ + { + path: ['$.issuer'], + }, + ], + }, + }, + ], + }, + type: () => [ProofRequestPresentationDefinition], + }) + @IsOptional() + @ValidateNested() + @IsObject({ message: 'presentationDefinition must be an object' }) + @IsNotEmpty({ message: 'presentationDefinition must not be empty' }) + @Type(() => ProofRequestPresentationDefinition) + presentationDefinition?: ProofRequestPresentationDefinition + + type: string + + @ApiPropertyOptional() + @IsString({ message: 'auto accept proof must be in string' }) + @IsNotEmpty({ message: 'please provide from valid auto accept proof options' }) + @IsOptional() + @IsEnum(AutoAccept, { + message: `Invalid auto accept proof. It should be one of: ${Object.values(AutoAccept).join(', ')}`, + }) + autoAcceptProof: AutoAccept + + @ApiPropertyOptional() + @IsOptional() + @IsString({ message: 'label must be in string' }) + label: string + + // TODO: [Credo-ts] Issue with parentThreadId in creating an OOB proof request. + // This causes failures in OOB connection establishment. + // @ApiPropertyOptional() + // @IsOptional() + // @IsUUID() + // @IsNotEmpty({ message: 'please provide valid parentThreadId' }) + // parentThreadId: string; + + @ApiProperty({ example: true }) + @IsBoolean() + @IsOptional() + @IsNotEmpty({ message: 'Please provide the flag for shorten url' }) + isShortenUrl?: boolean + + @ApiPropertyOptional() + @IsEmail({}, { each: true, message: 'Please provide a valid email' }) + @ArrayNotEmpty({ message: 'Email array must not be empty' }) + @ArrayUnique({ message: 'Duplicate emails are not allowed' }) + @ArrayMaxSize(Number(process.env.OOB_BATCH_SIZE), { + message: `Limit reached (${process.env.OOB_BATCH_SIZE} proof request max).`, + }) + @IsArray() + @IsString({ each: true, message: 'Each emailId in the array should be a string' }) + @IsOptional() + emailId: string[] + @ApiPropertyOptional({ default: true }) + @IsOptional() + @IsNotEmpty({ message: 'please provide valid value for reuseConnection' }) + @IsBoolean({ message: 'reuseConnection must be a boolean' }) + reuseConnection?: boolean } 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 d4f150c48..a49c309f8 100644 --- a/apps/api-gateway/src/verification/dto/webhook-proof.dto.ts +++ b/apps/api-gateway/src/verification/dto/webhook-proof.dto.ts @@ -1,83 +1,82 @@ -import { ApiPropertyOptional } from "@nestjs/swagger"; -import { IsOptional } from "class-validator"; +import { ApiPropertyOptional } from '@nestjs/swagger' +import { IsOptional } from 'class-validator' interface IWebhookPresentationProof { - threadId: string; - state: string; - connectionId + threadId: string + state: string + connectionId } export class WebhookPresentationProofDto { + @ApiPropertyOptional() + @IsOptional() + metadata: object - @ApiPropertyOptional() - @IsOptional() - metadata: object; - - @ApiPropertyOptional() - @IsOptional() - _tags: IWebhookPresentationProof; - - @ApiPropertyOptional() - @IsOptional() - id: string; - - @ApiPropertyOptional() - @IsOptional() - createdAt: string; - - @ApiPropertyOptional() - @IsOptional() - protocolVersion: string; - - @ApiPropertyOptional() - @IsOptional() - state: string; - - @ApiPropertyOptional() - @IsOptional() - connectionId: string; - - @ApiPropertyOptional() - @IsOptional() - threadId: string; - - @ApiPropertyOptional() - @IsOptional() - parentThreadId?: string; - - @ApiPropertyOptional() - @IsOptional() - presentationId: string; - - @ApiPropertyOptional() - @IsOptional() - autoAcceptProof: string; - - @ApiPropertyOptional() - @IsOptional() - updatedAt: string; - - @ApiPropertyOptional() - @IsOptional() - isVerified: boolean; - - @ApiPropertyOptional() - @IsOptional() - contextCorrelationId: string; - - @ApiPropertyOptional() - @IsOptional() - type: string; - - @ApiPropertyOptional() - @IsOptional() - proofData: object; - - @ApiPropertyOptional() - @IsOptional() - orgId: string; - - @ApiPropertyOptional() - @IsOptional() - errorMessage: string; -} \ No newline at end of file + @ApiPropertyOptional() + @IsOptional() + _tags: IWebhookPresentationProof + + @ApiPropertyOptional() + @IsOptional() + id: string + + @ApiPropertyOptional() + @IsOptional() + createdAt: string + + @ApiPropertyOptional() + @IsOptional() + protocolVersion: string + + @ApiPropertyOptional() + @IsOptional() + state: string + + @ApiPropertyOptional() + @IsOptional() + connectionId: string + + @ApiPropertyOptional() + @IsOptional() + threadId: string + + @ApiPropertyOptional() + @IsOptional() + parentThreadId?: string + + @ApiPropertyOptional() + @IsOptional() + presentationId: string + + @ApiPropertyOptional() + @IsOptional() + autoAcceptProof: string + + @ApiPropertyOptional() + @IsOptional() + updatedAt: string + + @ApiPropertyOptional() + @IsOptional() + isVerified: boolean + + @ApiPropertyOptional() + @IsOptional() + contextCorrelationId: string + + @ApiPropertyOptional() + @IsOptional() + type: string + + @ApiPropertyOptional() + @IsOptional() + proofData: object + + @ApiPropertyOptional() + @IsOptional() + orgId: string + + @ApiPropertyOptional() + @IsOptional() + errorMessage: string +} diff --git a/apps/api-gateway/src/verification/enum/verification.enum.ts b/apps/api-gateway/src/verification/enum/verification.enum.ts index 144f94948..b07ba096c 100644 --- a/apps/api-gateway/src/verification/enum/verification.enum.ts +++ b/apps/api-gateway/src/verification/enum/verification.enum.ts @@ -1,34 +1,33 @@ export enum SortFields { - CREATED_DATE_TIME = 'createDateTime', - STATUS = 'state', - CONNECTION_ID = 'connectionId', - PRESENTATION_ID = 'presentationId' + CREATED_DATE_TIME = 'createDateTime', + STATUS = 'state', + CONNECTION_ID = 'connectionId', + PRESENTATION_ID = 'presentationId', } export enum ProofRequestType { - INDY = 'indy', - PRESENTATIONEXCHANGE = 'presentationExchange' + INDY = 'indy', + PRESENTATIONEXCHANGE = 'presentationExchange', } export enum VerificationMethodLabel { - REQUEST_PROOF = 'request-proof' + REQUEST_PROOF = 'request-proof', } export enum ProtocolVersionType { - PROTOCOL_VERSION_1 = 'v1', - PROTOCOL_VERSION_2 = 'v2' - + PROTOCOL_VERSION_1 = 'v1', + PROTOCOL_VERSION_2 = 'v2', } export enum ProofRequestLabel { - PROOF_REQUEST = 'Proof Request' + PROOF_REQUEST = 'Proof Request', } export enum ProofVersion { - PROOF_VERSION = '1.0' + PROOF_VERSION = '1.0', } export enum API_Version { - VERSION_1 = 'v1', - version_neutral = 'version_neutral' -} \ No newline at end of file + VERSION_1 = 'v1', + version_neutral = 'version_neutral', +} diff --git a/apps/api-gateway/src/verification/interfaces/verification.interface.ts b/apps/api-gateway/src/verification/interfaces/verification.interface.ts index cac18fa67..669ccbfcd 100644 --- a/apps/api-gateway/src/verification/interfaces/verification.interface.ts +++ b/apps/api-gateway/src/verification/interfaces/verification.interface.ts @@ -1,92 +1,92 @@ -import { IUserRequestInterface } from "../../interfaces/IUserRequestInterface"; +import type { IUserRequestInterface } from '../../interfaces/IUserRequestInterface' export interface IProofRequestAttribute { - attributeName: string; - condition?: string; - value?: string; - credDefId: string; - credentialName: string; + attributeName: string + condition?: string + value?: string + credDefId: string + credentialName: string } export interface IProofRequestSearchCriteria { - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - search: string; - user?: IUserRequestInterface + pageNumber: number + pageSize: number + sortField: string + sortBy: string + search: string + user?: IUserRequestInterface } export interface IProofRequest { - metadata: object; - id: string; -} + metadata: object + id: string +} export interface IProofPresentation { - createdAt: string; - protocolVersion: string; - state: string; - connectionId: string; - threadId: string; - autoAcceptProof: string; - updatedAt: string; - isVerified: boolean; - } + createdAt: string + protocolVersion: string + state: string + connectionId: string + threadId: string + autoAcceptProof: string + updatedAt: string + isVerified: boolean +} export interface IPresentation { - _tags: ITags; - metadata: object; - id: string; - createdAt: string; - protocolVersion: string; - state: string; - connectionId: string; - threadId: string; - autoAcceptProof: string; - updatedAt: string; - isVerified: boolean; - } + _tags: ITags + metadata: object + id: string + createdAt: string + protocolVersion: string + state: string + connectionId: string + threadId: string + autoAcceptProof: string + updatedAt: string + isVerified: boolean +} interface ITags { - connectionId: string; - state: string; - threadId: string; -} + connectionId: string + state: string + threadId: string +} export interface IProofFormats { - indy: IndyProof + indy: IndyProof } interface IndyProof { - name: string; - version: string; - requested_attributes: IRequestedAttributes; - requested_predicates: IRequestedPredicates; + name: string + version: string + requested_attributes: IRequestedAttributes + requested_predicates: IRequestedPredicates } interface IRequestedAttributes { - [key: string]: IRequestedAttributesName; + [key: string]: IRequestedAttributesName } interface IRequestedAttributesName { - name?: string; - names?: string; - restrictions: IRequestedRestriction[] + name?: string + names?: string + restrictions: IRequestedRestriction[] } interface IRequestedPredicates { - [key: string]: IRequestedPredicatesName; + [key: string]: IRequestedPredicatesName } interface IRequestedPredicatesName { - name: string; - restrictions: IRequestedRestriction[] + name: string + restrictions: IRequestedRestriction[] } interface IRequestedRestriction { - cred_def_id?: string; - schema_id?: string; - schema_issuer_did?: string; - schema_name?: string; - issuer_did?: string; - schema_version?: string; -} \ No newline at end of file + cred_def_id?: string + schema_id?: string + schema_issuer_did?: string + schema_name?: string + issuer_did?: string + schema_version?: string +} diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index 9a0258946..7dbb75736 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -1,57 +1,58 @@ +import { TrimStringParamPipe } from '@credebl/common/cast.helper' +import type IResponseType from '@credebl/common/interfaces/response.interface' +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Validator } from '@credebl/common/validator' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { + BadRequestException, + Body, + Controller, + Delete, + Get, + HttpStatus, + Logger, + Param, + ParseUUIDPipe, + Post, + Query, + Res, + UseFilters, + UseGuards, + Version, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable no-param-reassign */ /* eslint-disable camelcase */ import { ApiBearerAuth, - ApiTags, + ApiBody, + ApiExcludeEndpoint, + ApiForbiddenResponse, ApiOperation, + ApiQuery, ApiResponse, + ApiTags, ApiUnauthorizedResponse, - ApiForbiddenResponse, - ApiBody, - ApiQuery, - ApiExcludeEndpoint -} from '@nestjs/swagger'; -import { - Controller, - Logger, - Post, - Body, - Get, - Query, - HttpStatus, - Res, - UseGuards, - Param, - UseFilters, - BadRequestException, - ParseUUIDPipe, - Delete, - Version -} from '@nestjs/common'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { SendProofRequestPayload, RequestProofDtoV1, RequestProofDtoV2 } from './dto/request-proof.dto'; -import { VerificationService } from './verification.service'; -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'; -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 { WebhookPresentationProofDto } from './dto/webhook-proof.dto'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { User } from '../authz/decorators/user.decorator'; -import { GetAllProofRequestsDto } from './dto/get-all-proof-requests.dto'; -import { IProofRequestSearchCriteria } from './interfaces/verification.interface'; -import { API_Version, ProofRequestType, SortFields } from './enum/verification.enum'; +} from '@nestjs/swagger' // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { user } from '@prisma/client'; -import { TrimStringParamPipe } from '@credebl/common/cast.helper'; -import { Validator } from '@credebl/common/validator'; +import type { user } from '@prisma/client' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { User } from '../authz/decorators/user.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { GetAllProofRequestsDto } from './dto/get-all-proof-requests.dto' +import { RequestProofDtoV1, RequestProofDtoV2, SendProofRequestPayload } from './dto/request-proof.dto' +import type { WebhookPresentationProofDto } from './dto/webhook-proof.dto' +import { API_Version, ProofRequestType, SortFields } from './enum/verification.enum' +import type { IProofRequestSearchCriteria } from './interfaces/verification.interface' +import type { VerificationService } from './verification.service' @UseFilters(CustomExceptionFilter) @Controller() @@ -59,7 +60,7 @@ import { Validator } from '@credebl/common/validator'; export class VerificationController { constructor(private readonly verificationService: VerificationService) {} - private readonly logger = new Logger('VerificationController'); + private readonly logger = new Logger('VerificationController') /** * Get verified proof details @@ -70,7 +71,7 @@ export class VerificationController { @Get('/orgs/:orgId/verified-proofs/:proofId') @ApiOperation({ summary: 'Get verified proof details', - description: 'Retrieve the details of a verified proof for a specific organization.' + description: 'Retrieve the details of a verified proof for a specific organization.', }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER, OrgRoles.HOLDER) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -84,13 +85,13 @@ export class VerificationController { @Param('proofId') proofId: string, @Param('orgId') orgId: string ): Promise { - const sendProofRequest = await this.verificationService.getVerifiedProofDetails(proofId, orgId, user); + const sendProofRequest = await this.verificationService.getVerifiedProofDetails(proofId, orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.verification.success.verifiedProofDetails, - data: sendProofRequest - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: sendProofRequest, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -102,7 +103,7 @@ export class VerificationController { @Get('/orgs/:orgId/proofs/:proofId') @ApiOperation({ summary: 'Get proof presentation by proof Id', - description: 'Retrieve the details of a proof presentation by its proof ID for a specific organization.' + description: 'Retrieve the details of a proof presentation by its proof ID for a specific organization.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -118,8 +119,8 @@ export class VerificationController { TrimStringParamPipe, new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.verification.error.invalidProofId); - } + throw new BadRequestException(ResponseMessages.verification.error.invalidProofId) + }, }) ) proofId: string, @@ -127,19 +128,19 @@ export class VerificationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string ): Promise { - const getProofPresentationById = await this.verificationService.getProofPresentationById(proofId, orgId, user); + const getProofPresentationById = await this.verificationService.getProofPresentationById(proofId, orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.verification.success.fetch, - data: getProofPresentationById - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: getProofPresentationById, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -151,7 +152,7 @@ export class VerificationController { @Get('/orgs/proofs') @ApiOperation({ summary: 'Get verified proof presentation details by issuer Id', - description: 'Retrieve the details of a proof presentation by its issuer Id' + description: 'Retrieve the details of a proof presentation by its issuer Id', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -163,14 +164,14 @@ export class VerificationController { @User() user: IUserRequest, @Query('issuerId') issuerId: string ): Promise { - const verifiedProofDetails = await this.verificationService.getPresentationDetailsByIssuerId(issuerId, user); + const verifiedProofDetails = await this.verificationService.getPresentationDetailsByIssuerId(issuerId, user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.verification.success.fetch, - data: verifiedProofDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: verifiedProofDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -182,12 +183,12 @@ export class VerificationController { @Get('/orgs/:orgId/proofs') @ApiOperation({ summary: 'Get all proof presentations by orgId', - description: 'Retrieve all proof presentations for a the organization. Supports pagination and sorting.' + description: 'Retrieve all proof presentations for a the organization. Supports pagination and sorting.', }) @ApiQuery({ name: 'sortField', enum: SortFields, - required: false + required: false, }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -203,32 +204,32 @@ export class VerificationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(`Invalid format for orgId`); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string ): Promise { - const { pageSize, search, pageNumber, sortField, sortBy } = getAllProofRequests; + const { pageSize, search, pageNumber, sortField, sortBy } = getAllProofRequests const proofRequestsSearchCriteria: IProofRequestSearchCriteria = { pageNumber, search, pageSize, sortField, - sortBy - }; + sortBy, + } const proofPresentationDetails = await this.verificationService.getProofPresentations( proofRequestsSearchCriteria, user, orgId - ); + ) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.verification.success.fetch, - data: proofPresentationDetails - }; - return res.status(HttpStatus.OK).json(finalResponse); + data: proofPresentationDetails, + } + return res.status(HttpStatus.OK).json(finalResponse) } /** @@ -239,7 +240,7 @@ export class VerificationController { @Post('/orgs/:orgId/proofs') @ApiOperation({ summary: 'Sends a proof request', - description: 'Send a proof request to a specific organization.' + description: 'Send a proof request to a specific organization.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -247,7 +248,7 @@ export class VerificationController { @ApiBody({ type: RequestProofDtoV1 }) @ApiQuery({ name: 'requestType', - enum: ProofRequestType + enum: ProofRequestType, }) @ApiBearerAuth() @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -259,8 +260,8 @@ export class VerificationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(`Invalid format for orgId`); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @@ -268,27 +269,27 @@ export class VerificationController { @Query('requestType') requestType: ProofRequestType = ProofRequestType.INDY ): Promise { if (requestType === ProofRequestType.INDY && !requestProof.proofFormats) { - throw new BadRequestException(`type: ${requestType} requires proofFormats`); + throw new BadRequestException(`type: ${requestType} requires proofFormats`) } if (requestType === ProofRequestType.PRESENTATIONEXCHANGE && !requestProof.presentationDefinition) { - throw new BadRequestException(`type: ${requestType} requires presentationDefinition`); + throw new BadRequestException(`type: ${requestType} requires presentationDefinition`) } if (requestType === ProofRequestType.INDY) { - Validator.validateIndyProofAttributes(requestProof.proofFormats.indy.attributes); + Validator.validateIndyProofAttributes(requestProof.proofFormats.indy.attributes) } - const version = API_Version.version_neutral; - requestProof.version = version; - requestProof.orgId = orgId; - requestProof.type = requestType; - const proofData = await this.verificationService.sendProofRequest(requestProof, user); + const version = API_Version.version_neutral + requestProof.version = version + requestProof.orgId = orgId + requestProof.type = requestType + const proofData = await this.verificationService.sendProofRequest(requestProof, user) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.verification.success.send, - data: proofData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: proofData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -300,7 +301,7 @@ export class VerificationController { @Post('/orgs/:orgId/proofs') @ApiOperation({ summary: 'Sends a proof request', - description: 'Send a proof request on multiple connections for a the organization.' + description: 'Send a proof request on multiple connections for a the organization.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -308,7 +309,7 @@ export class VerificationController { @ApiBody({ type: RequestProofDtoV2 }) @ApiQuery({ name: 'requestType', - enum: ProofRequestType + enum: ProofRequestType, }) @ApiBearerAuth() @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @@ -320,8 +321,8 @@ export class VerificationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(`Invalid format for orgId`); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @@ -329,28 +330,28 @@ export class VerificationController { @Query('requestType') requestTypeV1: ProofRequestType = ProofRequestType.INDY ): Promise { if (requestTypeV1 === ProofRequestType.INDY && !requestProof.proofFormats) { - throw new BadRequestException(`type: ${requestTypeV1} requires proofFormats`); + throw new BadRequestException(`type: ${requestTypeV1} requires proofFormats`) } if (requestTypeV1 === ProofRequestType.PRESENTATIONEXCHANGE && !requestProof.presentationDefinition) { - throw new BadRequestException(`type: ${requestTypeV1} requires presentationDefinition`); + throw new BadRequestException(`type: ${requestTypeV1} requires presentationDefinition`) } if (requestTypeV1 === ProofRequestType.INDY) { - Validator.validateIndyProofAttributes(requestProof.proofFormats.indy.attributes); + Validator.validateIndyProofAttributes(requestProof.proofFormats.indy.attributes) } - const version = API_Version.VERSION_1; - requestProof.version = version; - requestProof.orgId = orgId; - requestProof.type = requestTypeV1; - const proofData = await this.verificationService.sendProofRequest(requestProof, user); + const version = API_Version.VERSION_1 + requestProof.version = version + requestProof.orgId = orgId + requestProof.type = requestTypeV1 + const proofData = await this.verificationService.sendProofRequest(requestProof, user) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.verification.success.send, - data: proofData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: proofData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -362,7 +363,7 @@ export class VerificationController { @Post('/orgs/:orgId/proofs/:proofId/verify') @ApiOperation({ summary: 'Verify presentation', - description: 'Verify the proof presentation for a the organization.' + description: 'Verify the proof presentation for a the organization.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -376,13 +377,13 @@ export class VerificationController { @Param('proofId') proofId: string, @Param('orgId') orgId: string ): Promise { - const verifyData = await this.verificationService.verifyPresentation(proofId, orgId, user); + const verifyData = await this.verificationService.verifyPresentation(proofId, orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.verification.success.verified, - data: verifyData - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: verifyData, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -393,7 +394,7 @@ export class VerificationController { @Post('/orgs/:orgId/proofs/oob') @ApiOperation({ summary: 'Sends a out-of-band proof request', - description: 'Send an out-of-band proof request for a specific organization.' + description: 'Send an out-of-band proof request for a specific organization.', }) @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @@ -401,7 +402,7 @@ export class VerificationController { @ApiBody({ type: SendProofRequestPayload }) @ApiQuery({ name: 'requestType', - enum: ProofRequestType + enum: ProofRequestType, }) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.VERIFIER) @ApiBearerAuth() @@ -413,15 +414,15 @@ export class VerificationController { @Param('orgId') orgId: string, @Query('requestType') requestType: ProofRequestType = ProofRequestType.INDY ): Promise { - user.orgId = orgId; - outOfBandRequestProof.type = requestType; - const result = await this.verificationService.sendOutOfBandPresentationRequest(outOfBandRequestProof, user); + user.orgId = orgId + outOfBandRequestProof.type = requestType + const result = await this.verificationService.sendOutOfBandPresentationRequest(outOfBandRequestProof, user) const finalResponse: IResponseType = { statusCode: HttpStatus.CREATED, message: ResponseMessages.verification.success.send, - data: result - }; - return res.status(HttpStatus.CREATED).json(finalResponse); + data: result, + } + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -432,7 +433,7 @@ export class VerificationController { @Post('wh/:orgId/proofs') @ApiOperation({ summary: 'Receive webhook proof presentation', - description: 'Handle proof presentations for a specified organization via a webhook.' + description: 'Handle proof presentations for a specified organization via a webhook.', }) @ApiExcludeEndpoint() @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) @@ -443,37 +444,37 @@ export class VerificationController { @Body() proofPresentationPayload: WebhookPresentationProofDto, @Res() res: Response ): Promise { - proofPresentationPayload.type = 'Verification'; + proofPresentationPayload.type = 'Verification' - if (orgId && 'default' === proofPresentationPayload.contextCorrelationId) { - proofPresentationPayload.orgId = orgId; + if (orgId && proofPresentationPayload.contextCorrelationId === 'default') { + proofPresentationPayload.orgId = orgId } const webhookProofPresentation = await this.verificationService .webhookProofPresentation(orgId, proofPresentationPayload) .catch((error) => { - this.logger.debug(`error in saving verification webhook ::: ${JSON.stringify(error)}`); - }); + this.logger.debug(`error in saving verification webhook ::: ${JSON.stringify(error)}`) + }) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.verification.success.create, - data: webhookProofPresentation - }; + data: webhookProofPresentation, + } const webhookUrl = await this.verificationService ._getWebhookUrl(proofPresentationPayload?.contextCorrelationId, orgId) .catch((error) => { - this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`); - }); + this.logger.debug(`error in getting webhook url ::: ${JSON.stringify(error)}`) + }) if (webhookUrl) { await this.verificationService ._postWebhookResponse(webhookUrl, { data: proofPresentationPayload }) .catch((error) => { - this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`); - }); + this.logger.debug(`error in posting webhook response to webhook url ::: ${JSON.stringify(error)}`) + }) } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -487,7 +488,7 @@ export class VerificationController { @ApiOperation({ summary: 'Delete verification record', description: - 'Delete all verification records associated with a specific organization by its orgId. This operation is restricted to users with the OWNER role.' + 'Delete all verification records associated with a specific organization by its orgId. This operation is restricted to users with the OWNER role.', }) @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) @ApiBearerAuth() @@ -498,19 +499,19 @@ export class VerificationController { 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); - } + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, }) ) orgId: string, @User() user: user, @Res() res: Response ): Promise { - await this.verificationService.deleteVerificationRecords(orgId, user); + await this.verificationService.deleteVerificationRecords(orgId, user) const finalResponse: IResponse = { statusCode: HttpStatus.OK, - message: ResponseMessages.verification.success.deleteVerificationRecord - }; - return res.status(HttpStatus.OK).json(finalResponse); + message: ResponseMessages.verification.success.deleteVerificationRecord, + } + return res.status(HttpStatus.OK).json(finalResponse) } } diff --git a/apps/api-gateway/src/verification/verification.module.ts b/apps/api-gateway/src/verification/verification.module.ts index 3f8c473af..aa13b693f 100644 --- a/apps/api-gateway/src/verification/verification.module.ts +++ b/apps/api-gateway/src/verification/verification.module.ts @@ -1,12 +1,12 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; +import { ClientsModule, Transport } from '@nestjs/microservices' -import { ConfigModule } from '@nestjs/config'; -import { Module } from '@nestjs/common'; -import { VerificationController } from './verification.controller'; -import { VerificationService } from './verification.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { VerificationController } from './verification.controller' +import { VerificationService } from './verification.service' @Module({ imports: [ @@ -15,11 +15,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.VERIFICATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } - ]) + options: getNatsOptions(CommonConstants.VERIFICATION_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [VerificationController], - providers: [VerificationService, NATSClient] + providers: [VerificationService, NATSClient], }) export class VerificationModule {} diff --git a/apps/api-gateway/src/verification/verification.service.ts b/apps/api-gateway/src/verification/verification.service.ts index d312967ce..6921768b2 100644 --- a/apps/api-gateway/src/verification/verification.service.ts +++ b/apps/api-gateway/src/verification/verification.service.ts @@ -1,19 +1,19 @@ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { SendProofRequestPayload, RequestProofDtoV1, RequestProofDtoV2 } from './dto/request-proof.dto'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { WebhookPresentationProofDto } from './dto/webhook-proof.dto'; -import { +import type { NATSClient } from '@credebl/common/NATSClient' +import type { IProofPresentationDetails, IProofPresentationList, - IVerificationRecords -} from '@credebl/common/interfaces/verification.interface'; -import { IPresentation, IProofRequest, IProofRequestSearchCriteria } from './interfaces/verification.interface'; -import { IProofPresentation } from './interfaces/verification.interface'; + IVerificationRecords, +} from '@credebl/common/interfaces/verification.interface' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' // To do make a similar interface in API-gateway -import { user } from '@prisma/client'; -import { NATSClient } from '@credebl/common/NATSClient'; +import type { user } from '@prisma/client' +import { BaseService } from 'libs/service/base.service' +import type { RequestProofDtoV1, RequestProofDtoV2, SendProofRequestPayload } from './dto/request-proof.dto' +import type { WebhookPresentationProofDto } from './dto/webhook-proof.dto' +import type { IPresentation, IProofRequest, IProofRequestSearchCriteria } from './interfaces/verification.interface' +import type { IProofPresentation } from './interfaces/verification.interface' @Injectable() export class VerificationService extends BaseService { @@ -21,7 +21,7 @@ export class VerificationService extends BaseService { @Inject('NATS_CLIENT') private readonly verificationServiceProxy: ClientProxy, private readonly natsClient: NATSClient ) { - super('VerificationService'); + super('VerificationService') } /** @@ -34,8 +34,8 @@ export class VerificationService extends BaseService { user: IUserRequest, orgId: string ): Promise { - const payload = { proofRequestsSearchCriteria, user, orgId }; - return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'get-all-proof-presentations', payload); + const payload = { proofRequestsSearchCriteria, user, orgId } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'get-all-proof-presentations', payload) } /** @@ -45,12 +45,8 @@ export class VerificationService extends BaseService { * @returns Proof presentation details by proofId */ getProofPresentationById(proofId: string, orgId: string, user: IUserRequest): Promise { - const payload = { proofId, orgId, user }; - return this.natsClient.sendNatsMessage( - this.verificationServiceProxy, - 'get-proof-presentations-by-proofId', - payload - ); + const payload = { proofId, orgId, user } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'get-proof-presentations-by-proofId', payload) } /** @@ -59,12 +55,12 @@ export class VerificationService extends BaseService { * @returns Proof presentation details by issuerId */ getPresentationDetailsByIssuerId(issuerId: string, user: IUserRequest): Promise { - const payload = { issuerId, user }; + const payload = { issuerId, user } return this.natsClient.sendNatsMessage( this.verificationServiceProxy, 'get-proof-presentation-details-by-issuerId', payload - ); + ) } /** @@ -73,8 +69,8 @@ export class VerificationService extends BaseService { * @returns Requested proof presentation details */ sendProofRequest(requestProofDto: RequestProofDtoV1 | RequestProofDtoV2, user: IUserRequest): Promise { - const payload = { requestProofDto, user }; - return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'send-proof-request', payload); + const payload = { requestProofDto, user } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'send-proof-request', payload) } /** @@ -84,13 +80,13 @@ export class VerificationService extends BaseService { * @returns Verified proof presentation details */ verifyPresentation(proofId: string, orgId: string, user: IUserRequest): Promise { - const payload = { proofId, orgId, user }; - return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'verify-presentation', payload); + const payload = { proofId, orgId, user } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'verify-presentation', payload) } webhookProofPresentation(orgId: string, proofPresentationPayload: WebhookPresentationProofDto): Promise { - const payload = { orgId, proofPresentationPayload }; - return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'webhook-proof-presentation', payload); + const payload = { orgId, proofPresentationPayload } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'webhook-proof-presentation', payload) } /** @@ -103,45 +99,45 @@ export class VerificationService extends BaseService { outOfBandRequestProof: SendProofRequestPayload, user: IUserRequest ): Promise { - const payload = { outOfBandRequestProof, user }; - return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'send-out-of-band-proof-request', payload); + const payload = { outOfBandRequestProof, user } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'send-out-of-band-proof-request', payload) } getVerifiedProofDetails(proofId: string, orgId: string, user: IUserRequest): Promise { - const payload = { proofId, orgId, user }; - return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'get-verified-proof-details', payload); + const payload = { proofId, orgId, user } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'get-verified-proof-details', payload) } async _getWebhookUrl(tenantId?: string, orgId?: string): Promise { - const pattern = { cmd: 'get-webhookurl' }; - const payload = { tenantId, orgId }; + const pattern = { cmd: 'get-webhookurl' } + const payload = { tenantId, orgId } try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const message = await this.verificationServiceProxy.send(pattern, payload).toPromise(); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.verificationServiceProxy.send(pattern, payload).toPromise() + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw error } } async _postWebhookResponse(webhookUrl: string, data: object): Promise { - const pattern = { cmd: 'post-webhook-response-to-webhook-url' }; - const payload = { webhookUrl, data }; + const pattern = { cmd: 'post-webhook-response-to-webhook-url' } + const payload = { webhookUrl, data } try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const message = await this.verificationServiceProxy.send(pattern, payload).toPromise(); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.verificationServiceProxy.send(pattern, payload).toPromise() + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw error } } async deleteVerificationRecords(orgId: string, userDetails: user): Promise { - const payload = { orgId, userDetails }; - return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'delete-verification-records', payload); + const payload = { orgId, userDetails } + return this.natsClient.sendNatsMessage(this.verificationServiceProxy, 'delete-verification-records', payload) } } diff --git a/apps/api-gateway/src/webhook/dtos/get-webhoook-dto.ts b/apps/api-gateway/src/webhook/dtos/get-webhoook-dto.ts index 846225df0..3cf200e63 100644 --- a/apps/api-gateway/src/webhook/dtos/get-webhoook-dto.ts +++ b/apps/api-gateway/src/webhook/dtos/get-webhoook-dto.ts @@ -1,21 +1,20 @@ -import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsOptional, IsString, IsUUID } from 'class-validator'; -import { Transform } from 'class-transformer'; -import { trim } from '@credebl/common/cast.helper'; +import { trim } from '@credebl/common/cast.helper' +import { ApiExtraModels, ApiPropertyOptional } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsOptional, IsString, IsUUID } from 'class-validator' @ApiExtraModels() export class GetWebhookDto { + @ApiPropertyOptional({ example: '2a041d6e-d24c-4ed9-b011-1cfc371a8b8e' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsString({ message: 'Organization id must be in string format.' }) + orgId?: string - @ApiPropertyOptional({example: '2a041d6e-d24c-4ed9-b011-1cfc371a8b8e'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'Organization id must be in string format.' }) - orgId?: string; - - @ApiPropertyOptional({example: '3a041d6e-d24c-4ed9-b011-1cfc371a8b8e'}) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsUUID('4', { message: 'Please provide valid tenantId' }) - @IsString({ message: 'Tenant id must be in string format.' }) - tenantId?: string; -} \ No newline at end of file + @ApiPropertyOptional({ example: '3a041d6e-d24c-4ed9-b011-1cfc371a8b8e' }) + @IsOptional() + @Transform(({ value }) => trim(value)) + @IsUUID('4', { message: 'Please provide valid tenantId' }) + @IsString({ message: 'Tenant id must be in string format.' }) + tenantId?: string +} diff --git a/apps/api-gateway/src/webhook/dtos/register-webhook-dto.ts b/apps/api-gateway/src/webhook/dtos/register-webhook-dto.ts index 4bde261c1..02beb7854 100644 --- a/apps/api-gateway/src/webhook/dtos/register-webhook-dto.ts +++ b/apps/api-gateway/src/webhook/dtos/register-webhook-dto.ts @@ -1,16 +1,15 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsNotEmpty, IsString, IsUrl} from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsNotEmpty, IsString, IsUrl } from 'class-validator' export class RegisterWebhookDto { + orgId: string -orgId: string; - -@ApiProperty() -@Transform(({ value }) => trim(value)) -@IsNotEmpty({ message: 'webhookUrl is required.' }) -@IsString({ message: 'webhookUrl must be in string format.' }) -@IsUrl(undefined, {message:'webhookUrl is not valid'}) -webhookUrl: string; -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'webhookUrl is required.' }) + @IsString({ message: 'webhookUrl must be in string format.' }) + @IsUrl(undefined, { message: 'webhookUrl is not valid' }) + webhookUrl: string +} diff --git a/apps/api-gateway/src/webhook/dtos/webhook-response-dto.ts b/apps/api-gateway/src/webhook/dtos/webhook-response-dto.ts index 70552b4ca..abb2d6c53 100644 --- a/apps/api-gateway/src/webhook/dtos/webhook-response-dto.ts +++ b/apps/api-gateway/src/webhook/dtos/webhook-response-dto.ts @@ -1,19 +1,18 @@ -import { trim } from '@credebl/common/cast.helper'; -import { ApiProperty } from '@nestjs/swagger'; -import { Transform } from 'class-transformer'; -import { IsNotEmpty, IsObject, IsString } from 'class-validator'; +import { trim } from '@credebl/common/cast.helper' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { IsNotEmpty, IsObject, IsString } from 'class-validator' export class WebhookResponseDto { - -@ApiProperty() -@Transform(({ value }) => trim(value)) -@IsNotEmpty({ message: 'webhookUrl is required' }) -@IsString({ message: 'webhookUrl must be in string format' }) -webhookUrl: string; + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'webhookUrl is required' }) + @IsString({ message: 'webhookUrl must be in string format' }) + webhookUrl: string -@ApiProperty() -@Transform(({ value }) => trim(value)) -@IsNotEmpty({ message: 'data is required' }) -@IsObject({ message: 'data must be an object' }) -data:object; -} \ No newline at end of file + @ApiProperty() + @Transform(({ value }) => trim(value)) + @IsNotEmpty({ message: 'data is required' }) + @IsObject({ message: 'data must be an object' }) + data: object +} diff --git a/apps/api-gateway/src/webhook/webhook.controller.ts b/apps/api-gateway/src/webhook/webhook.controller.ts index 9481263bb..2da6a3832 100644 --- a/apps/api-gateway/src/webhook/webhook.controller.ts +++ b/apps/api-gateway/src/webhook/webhook.controller.ts @@ -1,44 +1,44 @@ +import type { IResponse } from '@credebl/common/interfaces/response.interface' +import { ResponseMessages } from '@credebl/common/response-messages' /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable no-param-reassign */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable camelcase */ import { - Controller, - Post, - Body, - Logger, - UseGuards, BadRequestException, - HttpStatus, - Res, + Body, + Controller, Get, + HttpStatus, + Logger, Param, - UseFilters, ParseUUIDPipe, - Query -} from '@nestjs/common'; + Post, + Query, + Res, + UseFilters, + UseGuards, +} from '@nestjs/common' +import { AuthGuard } from '@nestjs/passport' import { - ApiTags, + ApiBearerAuth, + ApiForbiddenResponse, ApiOperation, ApiResponse, - ApiForbiddenResponse, + ApiTags, ApiUnauthorizedResponse, - ApiBearerAuth -} from '@nestjs/swagger'; -import { AuthGuard } from '@nestjs/passport'; -import { ApiResponseDto } from '../dtos/apiResponse.dto'; -import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto'; -import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto'; -import { Response } from 'express'; -import { IResponse } from '@credebl/common/interfaces/response.interface'; -import { WebhookService } from './webhook.service'; -import { RegisterWebhookDto } from './dtos/register-webhook-dto'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; -import { OrgRolesGuard } from '../authz/guards/org-roles.guard'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { Roles } from '../authz/decorators/roles.decorator'; -import { GetWebhookDto } from './dtos/get-webhoook-dto'; +} from '@nestjs/swagger' +import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler' +import type { Response } from 'express' +import { OrgRoles } from 'libs/org-roles/enums' +import { Roles } from '../authz/decorators/roles.decorator' +import { OrgRolesGuard } from '../authz/guards/org-roles.guard' +import { ApiResponseDto } from '../dtos/apiResponse.dto' +import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' +import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' +import type { GetWebhookDto } from './dtos/get-webhoook-dto' +import type { RegisterWebhookDto } from './dtos/register-webhook-dto' +import type { WebhookService } from './webhook.service' @UseFilters(CustomExceptionFilter) @Controller('webhooks') @@ -46,11 +46,9 @@ import { GetWebhookDto } from './dtos/get-webhoook-dto'; @ApiUnauthorizedResponse({ status: 401, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: 403, description: 'Forbidden', type: ForbiddenErrorDto }) export class WebhookController { - constructor( - private readonly webhookService: WebhookService - ) {} - private readonly logger = new Logger('WebhookController'); - private readonly PAGE: number = 1; + constructor(private readonly webhookService: WebhookService) {} + private readonly logger = new Logger('WebhookController') + private readonly PAGE: number = 1 /** * Register a webhook URL for an organization @@ -62,28 +60,36 @@ export class WebhookController { @Post('/orgs/:orgId/register') @ApiOperation({ summary: 'Register Webhook', - description: 'Register a webhook URL for an organization.' + description: 'Register a webhook URL for an organization.', }) @ApiBearerAuth() @UseGuards(AuthGuard('jwt'), OrgRolesGuard) @Roles(OrgRoles.OWNER, OrgRoles.ADMIN) @ApiResponse({ status: HttpStatus.CREATED, description: 'Webhook URL registered successfully', type: ApiResponseDto }) async registerWebhook( - @Param('orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); }})) orgId: string, + @Param( + 'orgId', + new ParseUUIDPipe({ + exceptionFactory: (): Error => { + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId) + }, + }) + ) + orgId: string, @Body() registerWebhookDto: RegisterWebhookDto, @Res() res: Response ): Promise { - registerWebhookDto.orgId = orgId; + registerWebhookDto.orgId = orgId - const webhookRegisterDetails = await this.webhookService.registerWebhook(registerWebhookDto); + const webhookRegisterDetails = await this.webhookService.registerWebhook(registerWebhookDto) const finalResponse: IResponse = { statusCode: HttpStatus.CREATED, message: ResponseMessages.agent.success.webhookUrlRegister, - data: webhookRegisterDetails - }; + data: webhookRegisterDetails, + } - return res.status(HttpStatus.CREATED).json(finalResponse); + return res.status(HttpStatus.CREATED).json(finalResponse) } /** @@ -95,24 +101,25 @@ export class WebhookController { @Get('/orgs/webhookurl') @ApiOperation({ summary: 'Get Webhook URL Details', - description: 'Retrieve the details of the webhook URL for an organization.' + description: 'Retrieve the details of the webhook URL for an organization.', }) @ApiBearerAuth() @UseGuards(AuthGuard('jwt')) @Roles(OrgRoles.OWNER, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.ADMIN) - @ApiResponse({ status: HttpStatus.OK, description: 'Webhook URL details retrieved successfully', type: ApiResponseDto }) - async getWebhookUrl( - @Query() getWebhook: GetWebhookDto, - @Res() res: Response - ): Promise { - const webhookUrlData = await this.webhookService.getWebhookUrl(getWebhook); + @ApiResponse({ + status: HttpStatus.OK, + description: 'Webhook URL details retrieved successfully', + type: ApiResponseDto, + }) + async getWebhookUrl(@Query() getWebhook: GetWebhookDto, @Res() res: Response): Promise { + const webhookUrlData = await this.webhookService.getWebhookUrl(getWebhook) const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.agent.success.getWebhookUrl, - data: webhookUrlData - }; + data: webhookUrlData, + } - return res.status(HttpStatus.OK).json(finalResponse); + return res.status(HttpStatus.OK).json(finalResponse) } } diff --git a/apps/api-gateway/src/webhook/webhook.module.ts b/apps/api-gateway/src/webhook/webhook.module.ts index 08433c3f9..11e72dbb7 100644 --- a/apps/api-gateway/src/webhook/webhook.module.ts +++ b/apps/api-gateway/src/webhook/webhook.module.ts @@ -1,13 +1,13 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Module } from '@nestjs/common'; -import { WebhookController } from './webhook.controller'; -import { WebhookService } from './webhook.service'; -import { CommonService } from '@credebl/common'; -import { HttpModule } from '@nestjs/axios'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { AwsService } from '@credebl/aws'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { CommonService } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { WebhookController } from './webhook.controller' +import { WebhookService } from './webhook.service' @Module({ imports: [ @@ -16,11 +16,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.WEBHOOK_SERVICE, process.env.API_GATEWAY_NKEY_SEED) - } - ]) + options: getNatsOptions(CommonConstants.WEBHOOK_SERVICE, process.env.API_GATEWAY_NKEY_SEED), + }, + ]), ], controllers: [WebhookController], - providers: [WebhookService, CommonService, AwsService, NATSClient] + providers: [WebhookService, CommonService, AwsService, NATSClient], }) -export class WebhookModule { } +export class WebhookModule {} diff --git a/apps/api-gateway/src/webhook/webhook.service.ts b/apps/api-gateway/src/webhook/webhook.service.ts index aed49bdbd..8e12df710 100644 --- a/apps/api-gateway/src/webhook/webhook.service.ts +++ b/apps/api-gateway/src/webhook/webhook.service.ts @@ -1,29 +1,30 @@ +import type { NATSClient } from '@credebl/common/NATSClient' /* eslint-disable camelcase */ -import { Injectable, Inject } from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { RegisterWebhookDto } from './dtos/register-webhook-dto'; -import { ICreateWebhookUrl, IGetWebhookUrl } from 'apps/webhook/interfaces/webhook.interfaces'; -import { GetWebhookDto } from './dtos/get-webhoook-dto'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { Inject, Injectable } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { ICreateWebhookUrl, IGetWebhookUrl } from 'apps/webhook/interfaces/webhook.interfaces' +import { BaseService } from 'libs/service/base.service' +import type { GetWebhookDto } from './dtos/get-webhoook-dto' +import type { RegisterWebhookDto } from './dtos/register-webhook-dto' @Injectable() export class WebhookService extends BaseService { - constructor(@Inject('NATS_CLIENT') private readonly webhookProxy: ClientProxy, private readonly natsClient : NATSClient) { - super('WebhookService'); + constructor( + @Inject('NATS_CLIENT') private readonly webhookProxy: ClientProxy, + private readonly natsClient: NATSClient + ) { + super('WebhookService') } - async getWebhookUrl(getWebhook: GetWebhookDto): Promise { + async getWebhookUrl(getWebhook: GetWebhookDto): Promise { // NATS call - return this.natsClient.sendNatsMessage(this.webhookProxy, 'get-webhookurl', getWebhook); + return this.natsClient.sendNatsMessage(this.webhookProxy, 'get-webhookurl', getWebhook) } async registerWebhook(registerWebhookDto: RegisterWebhookDto): Promise { - const payload = { registerWebhookDto}; + const payload = { registerWebhookDto } // NATS call - return this.natsClient.sendNatsMessage(this.webhookProxy, 'register-webhook', payload); + return this.natsClient.sendNatsMessage(this.webhookProxy, 'register-webhook', payload) } - - } diff --git a/apps/api-gateway/test/app.e2e-spec.ts b/apps/api-gateway/test/app.e2e-spec.ts index 3430c90ea..0f324f10e 100644 --- a/apps/api-gateway/test/app.e2e-spec.ts +++ b/apps/api-gateway/test/app.e2e-spec.ts @@ -1,22 +1,19 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { AppModule } from './../src/app.module'; +import type { INestApplication } from '@nestjs/common' +import { Test, type TestingModule } from '@nestjs/testing' +import * as request from 'supertest' +import { AppModule } from './../src/app.module' describe('AppController (e2e)', () => { - let app: INestApplication; + let app: INestApplication beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule] - }).compile(); + imports: [AppModule], + }).compile() - app = moduleFixture.createNestApplication(); - await app.init(); - }); + app = moduleFixture.createNestApplication() + await app.init() + }) - it('/ (GET)', () => request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!')); -}); + it('/ (GET)', () => request(app.getHttpServer()).get('/').expect(200).expect('Hello World!')) +}) diff --git a/apps/cloud-wallet/src/cloud-wallet.controller.ts b/apps/cloud-wallet/src/cloud-wallet.controller.ts index 842f422d4..b274a9067 100644 --- a/apps/cloud-wallet/src/cloud-wallet.controller.ts +++ b/apps/cloud-wallet/src/cloud-wallet.controller.ts @@ -1,8 +1,29 @@ +import type { + GetAllCloudWalletConnections, + IAcceptOffer, + IAcceptProofRequest, + IBasicMessage, + IBasicMessageDetails, + ICloudBaseWalletConfigure, + IConnectionDetailsById, + IConnectionInvitationResponse, + ICreateCloudWallet, + ICreateCloudWalletDid, + ICreateConnection, + ICredentialDetails, + IGetProofPresentation, + IGetProofPresentationById, + IGetStoredWalletInfo, + IProofRequestRes, + IReceiveInvitation, + IStoredWalletDetails, + ITenantDetail, + IWalletDetailsForDidList, +} from '@credebl/common/interfaces/cloud-wallet.interface' /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Controller } from '@nestjs/common'; // Import the common service in the library -import { CloudWalletService } from './cloud-wallet.service'; // Import the common service in connection module -import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package -import { IAcceptOffer, ICreateCloudWalletDid, IReceiveInvitation, IAcceptProofRequest, IProofRequestRes, ICloudBaseWalletConfigure, ICreateCloudWallet, IGetProofPresentation, IGetProofPresentationById, IGetStoredWalletInfo, IStoredWalletDetails, ICreateConnection, IConnectionInvitationResponse, IWalletDetailsForDidList, IConnectionDetailsById, ITenantDetail, ICredentialDetails, GetAllCloudWalletConnections, IBasicMessage, IBasicMessageDetails } from '@credebl/common/interfaces/cloud-wallet.interface'; +import { Controller } from '@nestjs/common' // Import the common service in the library +import { MessagePattern } from '@nestjs/microservices' // Import the nestjs microservices package +import type { CloudWalletService } from './cloud-wallet.service' // Import the common service in connection module @Controller() export class CloudWalletController { @@ -10,83 +31,81 @@ export class CloudWalletController { @MessagePattern({ cmd: 'configure-cloud-base-wallet' }) async configureBaseWallet(configureBaseWalletPayload: ICloudBaseWalletConfigure): Promise { - return this.cloudWalletService.configureBaseWallet(configureBaseWalletPayload); + return this.cloudWalletService.configureBaseWallet(configureBaseWalletPayload) } @MessagePattern({ cmd: 'create-connection-by-holder' }) async createConnection(createConnection: ICreateConnection): Promise { - return this.cloudWalletService.createConnection(createConnection); + return this.cloudWalletService.createConnection(createConnection) } @MessagePattern({ cmd: 'accept-proof-request-by-holder' }) async acceptProofRequest(acceptProofRequestPayload: IAcceptProofRequest): Promise { - return this.cloudWalletService.acceptProofRequest(acceptProofRequestPayload); + return this.cloudWalletService.acceptProofRequest(acceptProofRequestPayload) } @MessagePattern({ cmd: 'get-proof-by-proof-id-holder' }) async getProofById(proofPrsentationByIdPayload: IGetProofPresentationById): Promise { - return this.cloudWalletService.getProofById(proofPrsentationByIdPayload); + return this.cloudWalletService.getProofById(proofPrsentationByIdPayload) } @MessagePattern({ cmd: 'get-proof-presentation-holder' }) async getProofPresentation(proofPresentationPayload: IGetProofPresentation): Promise { - return this.cloudWalletService.getProofPresentation(proofPresentationPayload); + return this.cloudWalletService.getProofPresentation(proofPresentationPayload) } @MessagePattern({ cmd: 'create-cloud-wallet' }) async createConnectionInvitation(cloudWalletDetails: ICreateCloudWallet): Promise { - return this.cloudWalletService.createCloudWallet(cloudWalletDetails); + return this.cloudWalletService.createCloudWallet(cloudWalletDetails) } @MessagePattern({ cmd: 'receive-invitation-by-url' }) async receiveInvitationByUrl(ReceiveInvitationDetails: IReceiveInvitation): Promise { - return this.cloudWalletService.receiveInvitationByUrl(ReceiveInvitationDetails); + return this.cloudWalletService.receiveInvitationByUrl(ReceiveInvitationDetails) } @MessagePattern({ cmd: 'accept-credential-offer' }) async acceptOffer(acceptOfferDetails: IAcceptOffer): Promise { - return this.cloudWalletService.acceptOffer(acceptOfferDetails); + return this.cloudWalletService.acceptOffer(acceptOfferDetails) } @MessagePattern({ cmd: 'create-cloud-wallet-did' }) async createDid(createDidDetails: ICreateCloudWalletDid): Promise { - return this.cloudWalletService.createDid(createDidDetails); + return this.cloudWalletService.createDid(createDidDetails) } @MessagePattern({ cmd: 'cloud-wallet-did-list' }) async getDidList(walletDetails: IWalletDetailsForDidList): Promise { - return this.cloudWalletService.getDidList(walletDetails); + return this.cloudWalletService.getDidList(walletDetails) } @MessagePattern({ cmd: 'get-cloud-wallet-connection-by-id' }) async getconnectionById(connectionDetails: IConnectionDetailsById): Promise { - return this.cloudWalletService.getconnectionById(connectionDetails); + return this.cloudWalletService.getconnectionById(connectionDetails) } - @MessagePattern({ cmd: 'get-all-cloud-wallet-connections-list-by-id' }) async getAllconnectionById(connectionDetails: GetAllCloudWalletConnections): Promise { - return this.cloudWalletService.getAllconnectionById(connectionDetails); + return this.cloudWalletService.getAllconnectionById(connectionDetails) } @MessagePattern({ cmd: 'wallet-credential-by-id' }) async getCredentialList(tenantDetails: ITenantDetail): Promise { - return this.cloudWalletService.getCredentialListById(tenantDetails); + return this.cloudWalletService.getCredentialListById(tenantDetails) } - + @MessagePattern({ cmd: 'wallet-credential-by-record-id' }) async getCredentialByCredentialRecordId(credentialDetails: ICredentialDetails): Promise { - return this.cloudWalletService.getCredentialByRecord(credentialDetails); + return this.cloudWalletService.getCredentialByRecord(credentialDetails) } @MessagePattern({ cmd: 'basic-message-list-by-connection-id' }) async getBasicMessageByConnectionId(connectionDetails: IBasicMessage): Promise { - return this.cloudWalletService.getBasicMessageByConnectionId(connectionDetails); + return this.cloudWalletService.getBasicMessageByConnectionId(connectionDetails) } @MessagePattern({ cmd: 'send-basic-message' }) async sendBasicMessage(messageDetails: IBasicMessageDetails): Promise { - return this.cloudWalletService.sendBasicMessage(messageDetails); + return this.cloudWalletService.sendBasicMessage(messageDetails) } - -} \ No newline at end of file +} diff --git a/apps/cloud-wallet/src/cloud-wallet.module.ts b/apps/cloud-wallet/src/cloud-wallet.module.ts index 32f733734..96660ca27 100644 --- a/apps/cloud-wallet/src/cloud-wallet.module.ts +++ b/apps/cloud-wallet/src/cloud-wallet.module.ts @@ -1,17 +1,17 @@ -import { Logger, Module } from '@nestjs/common'; -import { CloudWalletController } from './cloud-wallet.controller'; -import { CloudWalletService } from './cloud-wallet.service'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { CommonModule } from '@credebl/common'; -import { CacheModule } from '@nestjs/cache-manager'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { PrismaService } from '@credebl/prisma-service'; -import { CloudWalletRepository } from './cloud-wallet.repository'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; +import { CommonModule } from '@credebl/common' +import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { CacheModule } from '@nestjs/cache-manager' +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { CloudWalletController } from './cloud-wallet.controller' +import { CloudWalletRepository } from './cloud-wallet.repository' +import { CloudWalletService } from './cloud-wallet.service' @Module({ imports: [ @@ -19,8 +19,8 @@ import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(process.env.CLOUD_WALLET_NKEY_SEED) - } + options: getNatsOptions(process.env.CLOUD_WALLET_NKEY_SEED), + }, ]), CommonModule, @@ -28,7 +28,7 @@ import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; LoggerModule, PlatformConfig, ContextInterceptorModule, - CacheModule.register() + CacheModule.register(), ], controllers: [CloudWalletController], providers: [ @@ -38,8 +38,8 @@ import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; Logger, { provide: MICRO_SERVICE_NAME, - useValue: 'cloud-wallet' - } - ] + useValue: 'cloud-wallet', + }, + ], }) export class CloudWalletModule {} diff --git a/apps/cloud-wallet/src/cloud-wallet.repository.ts b/apps/cloud-wallet/src/cloud-wallet.repository.ts index cbf63f788..23d8178b0 100644 --- a/apps/cloud-wallet/src/cloud-wallet.repository.ts +++ b/apps/cloud-wallet/src/cloud-wallet.repository.ts @@ -1,10 +1,14 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { CloudWalletType } from '@credebl/enum/enum'; +import type { + ICloudWalletDetails, + IGetStoredWalletInfo, + IStoreWalletInfo, + IStoredWalletDetails, +} from '@credebl/common/interfaces/cloud-wallet.interface' +import type { CloudWalletType } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, type Logger } from '@nestjs/common' // eslint-disable-next-line camelcase -import { cloud_wallet_user_info, user } from '@prisma/client'; -import { ICloudWalletDetails, IGetStoredWalletInfo, IStoredWalletDetails, IStoreWalletInfo } from '@credebl/common/interfaces/cloud-wallet.interface'; - +import type { cloud_wallet_user_info, user } from '@prisma/client' @Injectable() export class CloudWalletRepository { @@ -13,19 +17,18 @@ export class CloudWalletRepository { private readonly logger: Logger ) {} - // eslint-disable-next-line camelcase async getCloudWalletDetails(type: CloudWalletType): Promise { try { const agentDetails = await this.prisma.cloud_wallet_user_info.findFirstOrThrow({ where: { - type - } - }); - return agentDetails; + type, + }, + }) + return agentDetails } catch (error) { - this.logger.error(`Error in getCloudWalletBaseAgentDetails: ${error.message}`); - throw error; + this.logger.error(`Error in getCloudWalletBaseAgentDetails: ${error.message}`) + throw error } } @@ -34,19 +37,30 @@ export class CloudWalletRepository { try { const agentDetails = await this.prisma.cloud_wallet_user_info.findUnique({ where: { - email - } - }); - return agentDetails; + email, + }, + }) + return agentDetails } catch (error) { - this.logger.error(`Error in getCloudWalletBaseAgentDetails: ${error.message}`); - throw error; + this.logger.error(`Error in getCloudWalletBaseAgentDetails: ${error.message}`) + throw error } } // eslint-disable-next-line camelcase async storeCloudWalletDetails(cloudWalletDetails: ICloudWalletDetails): Promise { try { - const {label, lastChangedBy, tenantId, type, userId, agentApiKey, agentEndpoint, email, key, connectionImageUrl} = cloudWalletDetails; + const { + label, + lastChangedBy, + tenantId, + type, + userId, + agentApiKey, + agentEndpoint, + email, + key, + connectionImageUrl, + } = cloudWalletDetails return await this.prisma.cloud_wallet_user_info.create({ data: { @@ -60,7 +74,7 @@ export class CloudWalletRepository { agentEndpoint, agentApiKey, key, - connectionImageUrl + connectionImageUrl, }, select: { email: true, @@ -69,13 +83,12 @@ export class CloudWalletRepository { id: true, tenantId: true, label: true, - lastChangedDateTime: true - - } - }); + lastChangedDateTime: true, + }, + }) } catch (error) { - this.logger.error(`Error in storeCloudWalletDetails: ${error.message}`); - throw error; + this.logger.error(`Error in storeCloudWalletDetails: ${error.message}`) + throw error } } @@ -84,19 +97,19 @@ export class CloudWalletRepository { try { const walletInfoData = await this.prisma.cloud_wallet_user_info.findUnique({ where: { - email - } - }); - return walletInfoData; + email, + }, + }) + return walletInfoData } catch (error) { - this.logger.error(`Error in getCloudWalletInfo: ${error}`); - throw error; + this.logger.error(`Error in getCloudWalletInfo: ${error}`) + throw error } } async storeCloudWalletInfo(cloudWalletInfoPayload: IStoreWalletInfo): Promise { try { - const { agentEndpoint, agentApiKey, email, type, userId, key, createdBy, lastChangedBy } = cloudWalletInfoPayload; + const { agentEndpoint, agentApiKey, email, type, userId, key, createdBy, lastChangedBy } = cloudWalletInfoPayload const walletInfoData = await this.prisma.cloud_wallet_user_info.create({ data: { type, @@ -106,20 +119,20 @@ export class CloudWalletRepository { userId, key, createdBy, - lastChangedBy + lastChangedBy, }, select: { id: true, - email: true, + email: true, type: true, userId: true, - agentEndpoint: true - } - }); - return walletInfoData; + agentEndpoint: true, + }, + }) + return walletInfoData } catch (error) { - this.logger.error(`Error in storeCloudWalletInfo: ${error}`); - throw error; + this.logger.error(`Error in storeCloudWalletInfo: ${error}`) + throw error } } @@ -128,13 +141,13 @@ export class CloudWalletRepository { try { const cloudSubWalletDetails = await this.prisma.cloud_wallet_user_info.findFirstOrThrow({ where: { - userId - } - }); - return cloudSubWalletDetails; + userId, + }, + }) + return cloudSubWalletDetails } catch (error) { - this.logger.error(`Error in getCloudSubWallet: ${error}`); - throw error; + this.logger.error(`Error in getCloudSubWallet: ${error}`) + throw error } } @@ -142,13 +155,13 @@ export class CloudWalletRepository { try { const userDetails = await this.prisma.user.findUnique({ where: { - email - } - }); - return userDetails; + email, + }, + }) + return userDetails } catch (error) { - this.logger.error(`Error in getUserInfo: ${error}`); - throw error; + this.logger.error(`Error in getUserInfo: ${error}`) + throw error } } } diff --git a/apps/cloud-wallet/src/cloud-wallet.service.ts b/apps/cloud-wallet/src/cloud-wallet.service.ts index 5dcd378c1..ee44d321a 100644 --- a/apps/cloud-wallet/src/cloud-wallet.service.ts +++ b/apps/cloud-wallet/src/cloud-wallet.service.ts @@ -1,46 +1,46 @@ /* eslint-disable camelcase */ -import { CommonService } from '@credebl/common'; -import { - BadRequestException, - ConflictException, - Inject, - Injectable, - InternalServerErrorException, - Logger, - NotFoundException -} from '@nestjs/common'; -import { ClientProxy } from '@nestjs/microservices'; -import { Cache } from 'cache-manager'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { +import type { CommonService } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' +import type { + CloudWallet, + GetAllCloudWalletConnections, IAcceptOffer, - ICreateCloudWalletDid, - IReceiveInvitation, IAcceptProofRequest, - IProofRequestRes, + IBasicMessage, + IBasicMessageDetails, ICloudBaseWalletConfigure, ICloudWalletDetails, + IConnectionDetailsById, + IConnectionInvitationResponse, ICreateCloudWallet, + ICreateCloudWalletDid, + ICreateConnection, + ICredentialDetails, IGetProofPresentation, IGetProofPresentationById, IGetStoredWalletInfo, - IStoredWalletDetails, - CloudWallet, + IProofRequestRes, + IReceiveInvitation, IStoreWalletInfo, - IWalletDetailsForDidList, - IConnectionDetailsById, + IStoredWalletDetails, ITenantDetail, - ICredentialDetails, - ICreateConnection, - IConnectionInvitationResponse, - GetAllCloudWalletConnections, - IBasicMessage, - IBasicMessageDetails -} from '@credebl/common/interfaces/cloud-wallet.interface'; -import { CloudWalletRepository } from './cloud-wallet.repository'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { CloudWalletType } from '@credebl/enum/enum'; -import { CommonConstants } from '@credebl/common/common.constant'; + IWalletDetailsForDidList, +} from '@credebl/common/interfaces/cloud-wallet.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { CloudWalletType } from '@credebl/enum/enum' +import { CACHE_MANAGER } from '@nestjs/cache-manager' +import { + BadRequestException, + ConflictException, + Inject, + Injectable, + InternalServerErrorException, + type Logger, + NotFoundException, +} from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { Cache } from 'cache-manager' +import type { CloudWalletRepository } from './cloud-wallet.repository' @Injectable() export class CloudWalletService { @@ -58,25 +58,23 @@ export class CloudWalletService { * @returns cloud base wallet */ async configureBaseWallet(configureBaseWalletPayload: ICloudBaseWalletConfigure): Promise { - const { agentEndpoint, apiKey, email, walletKey, userId } = configureBaseWalletPayload; + const { agentEndpoint, apiKey, email, walletKey, userId } = configureBaseWalletPayload try { - const getAgentInfo = await this.commonService.httpGet( - `${agentEndpoint}${CommonConstants.URL_AGENT_GET_ENDPOINT}` - ); + const getAgentInfo = await this.commonService.httpGet(`${agentEndpoint}${CommonConstants.URL_AGENT_GET_ENDPOINT}`) if (!getAgentInfo?.isInitialized) { - throw new BadRequestException(ResponseMessages.cloudWallet.error.notReachable); + throw new BadRequestException(ResponseMessages.cloudWallet.error.notReachable) } - const existingWalletInfo = await this.cloudWalletRepository.getCloudWalletInfo(email); + const existingWalletInfo = await this.cloudWalletRepository.getCloudWalletInfo(email) if (existingWalletInfo) { - throw new ConflictException(ResponseMessages.cloudWallet.error.agentAlreadyExist); + throw new ConflictException(ResponseMessages.cloudWallet.error.agentAlreadyExist) } const [encryptionWalletKey, encryptionApiKey] = await Promise.all([ this.commonService.dataEncryption(walletKey), - this.commonService.dataEncryption(apiKey) - ]); + this.commonService.dataEncryption(apiKey), + ]) const walletInfoToStore: IStoreWalletInfo = { agentEndpoint, @@ -86,40 +84,41 @@ export class CloudWalletService { userId, key: encryptionWalletKey, createdBy: userId, - lastChangedBy: userId - }; + lastChangedBy: userId, + } - const storedWalletInfo = await this.cloudWalletRepository.storeCloudWalletInfo(walletInfoToStore); - return storedWalletInfo; + const storedWalletInfo = await this.cloudWalletRepository.storeCloudWalletInfo(walletInfoToStore) + return storedWalletInfo } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } /** * Create connection - * @param createConnection + * @param createConnection * @returns connection details */ async createConnection(createConnection: ICreateConnection): Promise { try { + const { userId, ...connectionPayload } = createConnection + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { userId, ...connectionPayload } = createConnection; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + connectionPayload.email = undefined - delete connectionPayload.email; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CREATE_CONNECTION_INVITATION}/${tenantId}` - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CREATE_CONNECTION_INVITATION}/${tenantId}`; - - const createConnectionDetails = await this.commonService.httpPost(url, connectionPayload, { headers: { authorization: decryptedApiKey } }); - return createConnectionDetails; + const createConnectionDetails = await this.commonService.httpPost(url, connectionPayload, { + headers: { authorization: decryptedApiKey }, + }) + return createConnectionDetails } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } @@ -130,27 +129,27 @@ export class CloudWalletService { */ async acceptProofRequest(acceptProofRequest: IAcceptProofRequest): Promise { const { proofRecordId, comment, filterByNonRevocationRequirements, filterByPresentationPreview, userId } = - acceptProofRequest; + acceptProofRequest try { - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${proofRecordId}${CommonConstants.CLOUD_WALLET_ACCEPT_PROOF_REQUEST}${tenantId}`; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${proofRecordId}${CommonConstants.CLOUD_WALLET_ACCEPT_PROOF_REQUEST}${tenantId}` const proofAcceptRequestPayload = { comment, filterByNonRevocationRequirements, - filterByPresentationPreview - }; + filterByPresentationPreview, + } const acceptProofRequest = await this.commonService.httpPost(url, proofAcceptRequestPayload, { - headers: { authorization: decryptedApiKey } - }); - return acceptProofRequest; + headers: { authorization: decryptedApiKey }, + }) + return acceptProofRequest } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } @@ -161,19 +160,19 @@ export class CloudWalletService { */ async getProofById(proofPrsentationByIdPayload: IGetProofPresentationById): Promise { try { - const { proofRecordId, userId } = proofPrsentationByIdPayload; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const { proofRecordId, userId } = proofPrsentationByIdPayload + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${proofRecordId}/${tenantId}`; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${proofRecordId}/${tenantId}` - const getProofById = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return getProofById; + const getProofById = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }) + return getProofById } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } @@ -184,22 +183,22 @@ export class CloudWalletService { */ async getProofPresentation(proofPresentationPayload: IGetProofPresentation): Promise { try { - const { threadId, userId } = proofPresentationPayload; + const { threadId, userId } = proofPresentationPayload - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_GET_PROOF_REQUEST}/${tenantId}${ threadId ? `?threadId=${threadId}` : '' - }`; + }` - const getProofById = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return getProofById; + const getProofById = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }) + return getProofById } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } @@ -209,28 +208,28 @@ export class CloudWalletService { * @returns cloud wallet info */ async _commonCloudWalletInfo(userId: string): Promise<[CloudWallet, CloudWallet, string]> { - const baseWalletDetails = await this.cloudWalletRepository.getCloudWalletDetails(CloudWalletType.BASE_WALLET); + const baseWalletDetails = await this.cloudWalletRepository.getCloudWalletDetails(CloudWalletType.BASE_WALLET) if (!baseWalletDetails) { - throw new NotFoundException(ResponseMessages.cloudWallet.error.notFoundBaseWallet); + throw new NotFoundException(ResponseMessages.cloudWallet.error.notFoundBaseWallet) } const getAgentDetails = await this.commonService.httpGet( `${baseWalletDetails?.agentEndpoint}${CommonConstants.URL_AGENT_GET_ENDPOINT}` - ); + ) if (!getAgentDetails?.isInitialized) { - throw new BadRequestException(ResponseMessages.cloudWallet.error.notReachable); + throw new BadRequestException(ResponseMessages.cloudWallet.error.notReachable) } - const getTenant = await this.cloudWalletRepository.getCloudSubWallet(userId); - + const getTenant = await this.cloudWalletRepository.getCloudSubWallet(userId) + if (!getTenant || !getTenant?.tenantId) { - throw new NotFoundException(ResponseMessages.cloudWallet.error.walletRecordNotFound); + throw new NotFoundException(ResponseMessages.cloudWallet.error.walletRecordNotFound) } - const decryptedApiKey = await this.commonService.decryptPassword(getTenant?.agentApiKey); + const decryptedApiKey = await this.commonService.decryptPassword(getTenant?.agentApiKey) - return [baseWalletDetails, getTenant, decryptedApiKey]; + return [baseWalletDetails, getTenant, decryptedApiKey] } /** @@ -240,49 +239,49 @@ export class CloudWalletService { */ async createCloudWallet(cloudWalletDetails: ICreateCloudWallet): Promise { try { - const { label, connectionImageUrl, email, userId } = cloudWalletDetails; + const { label, connectionImageUrl, email, userId } = cloudWalletDetails const agentPayload = { config: { label, - connectionImageUrl - } - }; + connectionImageUrl, + }, + } - const checkUserExist = await this.cloudWalletRepository.checkUserExist(email); + const checkUserExist = await this.cloudWalletRepository.checkUserExist(email) if (checkUserExist) { - throw new ConflictException(ResponseMessages.cloudWallet.error.userExist); + throw new ConflictException(ResponseMessages.cloudWallet.error.userExist) } - - const baseWalletDetails = await this.cloudWalletRepository.getCloudWalletDetails(CloudWalletType.BASE_WALLET); - const { agentEndpoint, agentApiKey } = baseWalletDetails; - const url = `${agentEndpoint}${CommonConstants.URL_SHAGENT_CREATE_TENANT}`; - const decryptedApiKey = await this.commonService.decryptPassword(agentApiKey); + const baseWalletDetails = await this.cloudWalletRepository.getCloudWalletDetails(CloudWalletType.BASE_WALLET) + + const { agentEndpoint, agentApiKey } = baseWalletDetails + const url = `${agentEndpoint}${CommonConstants.URL_SHAGENT_CREATE_TENANT}` + const decryptedApiKey = await this.commonService.decryptPassword(agentApiKey) - const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey); + const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey) if (!checkCloudWalletAgentHealth) { - throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning); + throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning) } const createCloudWalletResponse = await this.commonService.httpPost(url, agentPayload, { - headers: { authorization: decryptedApiKey } - }); + headers: { authorization: decryptedApiKey }, + }) if (!createCloudWalletResponse && !createCloudWalletResponse.id) { throw new InternalServerErrorException(ResponseMessages.cloudWallet.error.createCloudWallet, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } - const walletKey = await this.commonService.dataEncryption(createCloudWalletResponse.config.walletConfig.key); + const walletKey = await this.commonService.dataEncryption(createCloudWalletResponse.config.walletConfig.key) if (!walletKey) { throw new BadRequestException(ResponseMessages.cloudWallet.error.encryptCloudWalletKey, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } const cloudWalletResponse: ICloudWalletDetails = { @@ -296,13 +295,13 @@ export class CloudWalletService { agentEndpoint, email, key: walletKey, - connectionImageUrl - }; - const storeCloudWalletDetails = await this.cloudWalletRepository.storeCloudWalletDetails(cloudWalletResponse); - return storeCloudWalletDetails; + connectionImageUrl, + } + const storeCloudWalletDetails = await this.cloudWalletRepository.storeCloudWalletDetails(cloudWalletResponse) + return storeCloudWalletDetails } catch (error) { - this.logger.error(`[createCloudWallet] - error in create cloud wallet: ${error}`); - await this.commonService.handleError(error); + this.logger.error(`[createCloudWallet] - error in create cloud wallet: ${error}`) + await this.commonService.handleError(error) } } @@ -314,40 +313,40 @@ export class CloudWalletService { async receiveInvitationByUrl(ReceiveInvitationDetails: IReceiveInvitation): Promise { try { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { email, userId, ...invitationDetails } = ReceiveInvitationDetails; + const { email, userId, ...invitationDetails } = ReceiveInvitationDetails - const checkUserExist = await this.cloudWalletRepository.checkUserExist(email); + const checkUserExist = await this.cloudWalletRepository.checkUserExist(email) if (!checkUserExist) { - throw new ConflictException(ResponseMessages.cloudWallet.error.walletNotExist); + throw new ConflictException(ResponseMessages.cloudWallet.error.walletNotExist) } - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; - const url = `${agentEndpoint}${CommonConstants.RECEIVE_INVITATION_BY_URL}${tenantId}`; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails + const url = `${agentEndpoint}${CommonConstants.RECEIVE_INVITATION_BY_URL}${tenantId}` - const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey); + const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey) if (!checkCloudWalletAgentHealth) { - throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning); + throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning) } const receiveInvitationResponse = await this.commonService.httpPost(url, invitationDetails, { - headers: { authorization: decryptedApiKey } - }); + headers: { authorization: decryptedApiKey }, + }) if (!receiveInvitationResponse) { throw new InternalServerErrorException(ResponseMessages.cloudWallet.error.receiveInvitation, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } - return receiveInvitationResponse; + return receiveInvitationResponse } catch (error) { - this.logger.error(`[createCloudWallet] - error in receive invitation: ${error}`); - await this.commonService.handleError(error); + this.logger.error(`[createCloudWallet] - error in receive invitation: ${error}`) + await this.commonService.handleError(error) } } @@ -359,40 +358,40 @@ export class CloudWalletService { async acceptOffer(acceptOfferDetails: IAcceptOffer): Promise { try { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { email, userId, ...offerDetails } = acceptOfferDetails; + const { email, userId, ...offerDetails } = acceptOfferDetails - const checkUserExist = await this.cloudWalletRepository.checkUserExist(email); + const checkUserExist = await this.cloudWalletRepository.checkUserExist(email) if (!checkUserExist) { - throw new ConflictException(ResponseMessages.cloudWallet.error.walletNotExist); + throw new ConflictException(ResponseMessages.cloudWallet.error.walletNotExist) } - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const url = `${agentEndpoint}${CommonConstants.ACCEPT_OFFER}${tenantId}`; + const url = `${agentEndpoint}${CommonConstants.ACCEPT_OFFER}${tenantId}` - const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey); + const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey) if (!checkCloudWalletAgentHealth) { - throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning); + throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning) } const acceptOfferResponse = await this.commonService.httpPost(url, offerDetails, { - headers: { authorization: decryptedApiKey } - }); + headers: { authorization: decryptedApiKey }, + }) if (!acceptOfferResponse) { throw new InternalServerErrorException(ResponseMessages.cloudWallet.error.receiveInvitation, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } - return acceptOfferResponse; + return acceptOfferResponse } catch (error) { - this.logger.error(`[receiveInvitationByUrl] - error in accept offer: ${error}`); - await this.commonService.handleError(error); + this.logger.error(`[receiveInvitationByUrl] - error in accept offer: ${error}`) + await this.commonService.handleError(error) } } @@ -404,40 +403,40 @@ export class CloudWalletService { async createDid(createDidDetails: ICreateCloudWalletDid): Promise { try { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { email, userId, ...didDetails } = createDidDetails; + const { email, userId, ...didDetails } = createDidDetails - const checkUserExist = await this.cloudWalletRepository.checkUserExist(email); + const checkUserExist = await this.cloudWalletRepository.checkUserExist(email) if (!checkUserExist) { - throw new ConflictException(ResponseMessages.cloudWallet.error.walletNotExist); + throw new ConflictException(ResponseMessages.cloudWallet.error.walletNotExist) } - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const url = `${agentEndpoint}${CommonConstants.URL_SHAGENT_CREATE_DID}${tenantId}`; + const url = `${agentEndpoint}${CommonConstants.URL_SHAGENT_CREATE_DID}${tenantId}` - const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey); + const checkCloudWalletAgentHealth = await this.commonService.checkAgentHealth(agentEndpoint, decryptedApiKey) if (!checkCloudWalletAgentHealth) { - throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning); + throw new NotFoundException(ResponseMessages.cloudWallet.error.agentNotRunning) } const didDetailsResponse = await this.commonService.httpPost(url, didDetails, { - headers: { authorization: decryptedApiKey } - }); + headers: { authorization: decryptedApiKey }, + }) if (!didDetailsResponse) { throw new InternalServerErrorException(ResponseMessages.cloudWallet.error.receiveInvitation, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } - return didDetailsResponse; + return didDetailsResponse } catch (error) { - this.logger.error(`[createDid] - error in create DID: ${error}`); - await this.commonService.handleError(error); + this.logger.error(`[createDid] - error in create DID: ${error}`) + await this.commonService.handleError(error) } } @@ -448,19 +447,19 @@ export class CloudWalletService { */ async getDidList(walletDetails: IWalletDetailsForDidList): Promise { try { - const { userId } = walletDetails; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const { userId } = walletDetails + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_DID_LIST}${tenantId}`; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_DID_LIST}${tenantId}` - const didList = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return didList; + const didList = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }) + return didList } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } @@ -471,51 +470,55 @@ export class CloudWalletService { */ async getconnectionById(connectionDetails: IConnectionDetailsById): Promise { try { - const { userId, connectionId } = connectionDetails; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const { userId, connectionId } = connectionDetails + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CONNECTION_BY_ID}${connectionId}/${tenantId}`; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CONNECTION_BY_ID}${connectionId}/${tenantId}` - const connectionDetailResponse = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return connectionDetailResponse; + const connectionDetailResponse = await this.commonService.httpGet(url, { + headers: { authorization: decryptedApiKey }, + }) + return connectionDetailResponse } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } - /** + /** * Get connection list by tenant id * @param connectionDetails * @returns Connection Details */ - async getAllconnectionById(connectionDetails: GetAllCloudWalletConnections): Promise { - try { - const { userId, alias, myDid, outOfBandId, theirDid, theirLabel } = connectionDetails; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); - const urlOptions = { - alias, - myDid, - outOfBandId, - theirDid, - theirLabel - }; - const optionalParameter = await this.commonService.createDynamicUrl(urlOptions); - const { tenantId } = getTenant; - const { agentEndpoint } = baseWalletDetails; - - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CONNECTION_BY_ID}${tenantId}${optionalParameter}`; - - const connectionDetailList = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return connectionDetailList; - } catch (error) { - await this.commonService.handleError(error); - throw error; + async getAllconnectionById(connectionDetails: GetAllCloudWalletConnections): Promise { + try { + const { userId, alias, myDid, outOfBandId, theirDid, theirLabel } = connectionDetails + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) + const urlOptions = { + alias, + myDid, + outOfBandId, + theirDid, + theirLabel, } + const optionalParameter = await this.commonService.createDynamicUrl(urlOptions) + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails + + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CONNECTION_BY_ID}${tenantId}${optionalParameter}` + + const connectionDetailList = await this.commonService.httpGet(url, { + headers: { authorization: decryptedApiKey }, + }) + return connectionDetailList + } catch (error) { + await this.commonService.handleError(error) + throw error } + } /** * Get credential list by tenant id @@ -524,25 +527,27 @@ export class CloudWalletService { */ async getCredentialListById(tenantDetails: ITenantDetail): Promise { try { - const { userId, connectionId, state, threadId } = tenantDetails; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); + const { userId, connectionId, state, threadId } = tenantDetails + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) const urlOptions = { connectionId, state, - threadId - }; - const {tenantId} = getTenant; - const optionalParameter = await this.commonService.createDynamicUrl(urlOptions); - - const { agentEndpoint } = baseWalletDetails; + threadId, + } + const { tenantId } = getTenant + const optionalParameter = await this.commonService.createDynamicUrl(urlOptions) - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CREDENTIAL}/${tenantId}${optionalParameter}`; + const { agentEndpoint } = baseWalletDetails - const credentialDetailResponse = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return credentialDetailResponse; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CREDENTIAL}/${tenantId}${optionalParameter}` + + const credentialDetailResponse = await this.commonService.httpGet(url, { + headers: { authorization: decryptedApiKey }, + }) + return credentialDetailResponse } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } @@ -553,19 +558,21 @@ export class CloudWalletService { */ async getCredentialByRecord(credentialDetails: ICredentialDetails): Promise { try { - const { userId, credentialRecordId } = credentialDetails; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); - - const {tenantId} = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { userId, credentialRecordId } = credentialDetails + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) + + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CREDENTIAL}/${credentialRecordId}${tenantId}`; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_CREDENTIAL}/${credentialRecordId}${tenantId}` - const credentialDetailResponse = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return credentialDetailResponse; + const credentialDetailResponse = await this.commonService.httpGet(url, { + headers: { authorization: decryptedApiKey }, + }) + return credentialDetailResponse } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } @@ -576,43 +583,49 @@ export class CloudWalletService { */ async getBasicMessageByConnectionId(connectionDetails: IBasicMessage): Promise { try { - const { userId, connectionId } = connectionDetails; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); - - const {tenantId} = getTenant; - const { agentEndpoint } = baseWalletDetails; + const { userId, connectionId } = connectionDetails + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_BASIC_MESSAGE}${connectionId}/${tenantId}`; + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails - const basicMessageResponse = await this.commonService.httpGet(url, { headers: { authorization: decryptedApiKey } }); - return basicMessageResponse; + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_BASIC_MESSAGE}${connectionId}/${tenantId}` + + const basicMessageResponse = await this.commonService.httpGet(url, { + headers: { authorization: decryptedApiKey }, + }) + return basicMessageResponse } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } - /** + /** * Send basic-message by connection id * @param messageDetails * @returns Basic message Details */ - async sendBasicMessage(messageDetails: IBasicMessageDetails): Promise { + async sendBasicMessage(messageDetails: IBasicMessageDetails): Promise { try { - const { userId, connectionId, content } = messageDetails; - const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId); - - const {tenantId} = getTenant; - const { agentEndpoint } = baseWalletDetails; - - const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_BASIC_MESSAGE}${connectionId}/${tenantId}`; - const basicMessageResponse = await this.commonService.httpPost(url, {content}, { - headers: { authorization: decryptedApiKey } - }); - return basicMessageResponse; + const { userId, connectionId, content } = messageDetails + const [baseWalletDetails, getTenant, decryptedApiKey] = await this._commonCloudWalletInfo(userId) + + const { tenantId } = getTenant + const { agentEndpoint } = baseWalletDetails + + const url = `${agentEndpoint}${CommonConstants.CLOUD_WALLET_BASIC_MESSAGE}${connectionId}/${tenantId}` + const basicMessageResponse = await this.commonService.httpPost( + url, + { content }, + { + headers: { authorization: decryptedApiKey }, + } + ) + return basicMessageResponse } catch (error) { - await this.commonService.handleError(error); - throw error; + await this.commonService.handleError(error) + throw error } } } diff --git a/apps/cloud-wallet/src/main.ts b/apps/cloud-wallet/src/main.ts index c6abbdb1c..57f32950f 100644 --- a/apps/cloud-wallet/src/main.ts +++ b/apps/cloud-wallet/src/main.ts @@ -1,24 +1,23 @@ -import { NestFactory } from '@nestjs/core'; -import { CloudWalletModule } from './cloud-wallet.module'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { CloudWalletModule } from './cloud-wallet.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(CloudWalletModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.CLOUD_WALLET_SERVICE, process.env.CLOUD_WALLET_NKEY_SEED) - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.CLOUD_WALLET_SERVICE, process.env.CLOUD_WALLET_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Cloud-wallet Microservice is listening to NATS '); + await app.listen() + logger.log('Cloud-wallet Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/connection/src/connection.controller.ts b/apps/connection/src/connection.controller.ts index 0cc2e63d7..737609ad3 100644 --- a/apps/connection/src/connection.controller.ts +++ b/apps/connection/src/connection.controller.ts @@ -1,7 +1,10 @@ -import { Controller } from '@nestjs/common'; // Import the common service in the library -import { ConnectionService } from './connection.service'; // Import the common service in connection module -import { MessagePattern } from '@nestjs/microservices'; // Import the nestjs microservices package -import { +import type { IConnectionList, IDeletedConnectionsRecord } from '@credebl/common/interfaces/connection.interface' +import { Controller } from '@nestjs/common' // Import the common service in the library +import { MessagePattern } from '@nestjs/microservices' // Import the nestjs microservices package +import type { user } from '@prisma/client' +import type { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface' +import type { ConnectionService } from './connection.service' // Import the common service in connection module +import type { GetAllConnections, ICreateConnection, ICreateOutOfbandConnectionInvitation, @@ -9,12 +12,9 @@ import { IFetchConnections, IReceiveInvitationByOrg, IReceiveInvitationByUrlOrg, - IReceiveInvitationResponse -} from './interfaces/connection.interfaces'; -import { IConnectionList, IDeletedConnectionsRecord } from '@credebl/common/interfaces/connection.interface'; -import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; -import { IQuestionPayload } from './interfaces/messaging.interfaces'; -import { user } from '@prisma/client'; + IReceiveInvitationResponse, +} from './interfaces/connection.interfaces' +import type { IQuestionPayload } from './interfaces/messaging.interfaces' @Controller() export class ConnectionController { constructor(private readonly connectionService: ConnectionService) {} @@ -26,7 +26,7 @@ export class ConnectionController { */ @MessagePattern({ cmd: 'webhook-get-connection' }) async getConnectionWebhook(payload: ICreateConnection): Promise { - return this.connectionService.getConnectionWebhook(payload); + return this.connectionService.getConnectionWebhook(payload) } /** @@ -36,74 +36,74 @@ export class ConnectionController { */ @MessagePattern({ cmd: 'get-connection-url' }) async getUrl(payload: { referenceId }): Promise { - return this.connectionService.getUrl(payload.referenceId); + return this.connectionService.getUrl(payload.referenceId) } @MessagePattern({ cmd: 'get-all-connections' }) async getConnections(payload: IFetchConnections): Promise { - const { user, orgId, connectionSearchCriteria } = payload; - return this.connectionService.getConnections(user, orgId, connectionSearchCriteria); + const { user, orgId, connectionSearchCriteria } = payload + return this.connectionService.getConnections(user, orgId, connectionSearchCriteria) } @MessagePattern({ cmd: 'get-all-agent-connection-list' }) async getConnectionListFromAgent(payload: GetAllConnections): Promise { - const {orgId, connectionSearchCriteria } = payload; - return this.connectionService.getAllConnectionListFromAgent(orgId, connectionSearchCriteria); + const { orgId, connectionSearchCriteria } = payload + return this.connectionService.getAllConnectionListFromAgent(orgId, connectionSearchCriteria) } /** - * + * * @param connectionId - * @param orgId + * @param orgId * @returns connection details by connection Id */ @MessagePattern({ cmd: 'get-connection-details-by-connectionId' }) async getConnectionsById(payload: IFetchConnectionById): Promise { - const { user, connectionId, orgId } = payload; - return this.connectionService.getConnectionsById(user, connectionId, orgId); + const { user, connectionId, orgId } = payload + return this.connectionService.getConnectionsById(user, connectionId, orgId) } @MessagePattern({ cmd: 'get-connection-records' }) - async getConnectionRecordsByOrgId(payload: { orgId: string, userId: string }): Promise { - const { orgId } = payload; - return this.connectionService.getConnectionRecords(orgId); + async getConnectionRecordsByOrgId(payload: { orgId: string; userId: string }): Promise { + const { orgId } = payload + return this.connectionService.getConnectionRecords(orgId) } @MessagePattern({ cmd: 'receive-invitation-url' }) async receiveInvitationUrl(payload: IReceiveInvitationByUrlOrg): Promise { - const { user, receiveInvitationUrl, orgId } = payload; - return this.connectionService.receiveInvitationUrl(user, receiveInvitationUrl, orgId); + const { user, receiveInvitationUrl, orgId } = payload + return this.connectionService.receiveInvitationUrl(user, receiveInvitationUrl, orgId) } @MessagePattern({ cmd: 'receive-invitation' }) async receiveInvitation(payload: IReceiveInvitationByOrg): Promise { - const { user, receiveInvitation, orgId } = payload; - return this.connectionService.receiveInvitation(user, receiveInvitation, orgId); + const { user, receiveInvitation, orgId } = payload + return this.connectionService.receiveInvitation(user, receiveInvitation, orgId) } - + @MessagePattern({ cmd: 'send-question' }) async sendQuestion(payload: IQuestionPayload): Promise { - return this.connectionService.sendQuestion(payload); + return this.connectionService.sendQuestion(payload) } @MessagePattern({ cmd: 'get-question-answer-record' }) async getQuestionAnswersRecord(orgId: string): Promise { - return this.connectionService.getQuestionAnswersRecord(orgId); + return this.connectionService.getQuestionAnswersRecord(orgId) } @MessagePattern({ cmd: 'create-connection-invitation' }) async createConnectionInvitation(payload: ICreateOutOfbandConnectionInvitation): Promise { - return this.connectionService.createConnectionInvitation(payload); + return this.connectionService.createConnectionInvitation(payload) } @MessagePattern({ cmd: 'delete-connection-records' }) - async deleteConnectionRecords(payload: {orgId: string, userDetails: user}): Promise { - const { orgId, userDetails } = payload; - return this.connectionService.deleteConnectionRecords(orgId, userDetails); + async deleteConnectionRecords(payload: { orgId: string; userDetails: user }): Promise { + const { orgId, userDetails } = payload + return this.connectionService.deleteConnectionRecords(orgId, userDetails) } @MessagePattern({ cmd: 'send-basic-message-on-connection' }) - async sendBasicMessage(payload: {content: string, orgId: string, connectionId: string}): Promise { - return this.connectionService.sendBasicMesage(payload); + async sendBasicMessage(payload: { content: string; orgId: string; connectionId: string }): Promise { + return this.connectionService.sendBasicMesage(payload) } } diff --git a/apps/connection/src/connection.module.ts b/apps/connection/src/connection.module.ts index 4823f6dfd..4aefc4129 100644 --- a/apps/connection/src/connection.module.ts +++ b/apps/connection/src/connection.module.ts @@ -1,21 +1,21 @@ -/* eslint-disable array-bracket-spacing */ -import { Logger, Module } from '@nestjs/common'; -import { ConnectionController } from './connection.controller'; -import { ConnectionService } from './connection.service'; -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'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { CommonConstants } from '@credebl/common/common.constant'; +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' // import { nkeyAuthenticator } from 'nats'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { CacheModule } from '@nestjs/cache-manager' +/* eslint-disable array-bracket-spacing */ +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { UserActivityRepository } from 'libs/user-activity/repositories' +import { ConnectionController } from './connection.controller' +import { ConnectionRepository } from './connection.repository' +import { ConnectionService } from './connection.service' @Module({ imports: [ @@ -23,16 +23,18 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.CONNECTION_SERVICE, process.env.CONNECTION_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.CONNECTION_SERVICE, process.env.CONNECTION_NKEY_SEED), + }, ]), - CommonModule, - GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, - CacheModule.register() + CommonModule, + GlobalConfigModule, + LoggerModule, + PlatformConfig, + ContextInterceptorModule, + CacheModule.register(), ], controllers: [ConnectionController], - providers: [ConnectionService, ConnectionRepository, UserActivityRepository, PrismaService, Logger, NATSClient] + providers: [ConnectionService, ConnectionRepository, UserActivityRepository, PrismaService, Logger, NATSClient], }) -export class ConnectionModule { } +export class ConnectionModule {} diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index ec43c8385..63931c2bc 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -1,12 +1,12 @@ -import { Injectable, Logger, ConflictException } from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; +import type { IConnectionsListCount, IDeletedConnectionsRecord } from '@credebl/common/interfaces/connection.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { PrismaTables, SortValue } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { ConflictException, Injectable, type Logger } from '@nestjs/common' // eslint-disable-next-line camelcase -import { agent_invitations, org_agents, platform_config, shortening_url } from '@prisma/client'; -import { IConnectionSearchCriteria, ICreateConnection, OrgAgent } from './interfaces/connection.interfaces'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { IConnectionsListCount, IDeletedConnectionsRecord } from '@credebl/common/interfaces/connection.interface'; -import { PrismaTables, SortValue } from '@credebl/enum/enum'; -import { ResponseMessages } from '@credebl/common/response-messages'; +import type { agent_invitations, org_agents, platform_config, shortening_url } from '@prisma/client' +import type { IConnectionSearchCriteria, ICreateConnection, OrgAgent } from './interfaces/connection.interfaces' // import { OrgAgent } from './interfaces/connection.interfaces'; @Injectable() export class ConnectionRepository { @@ -25,16 +25,16 @@ export class ConnectionRepository { try { const agentDetails = await this.prisma.org_agents.findFirst({ where: { - orgId + orgId, }, include: { - organisation: true - } - }); - return agentDetails; + organisation: true, + }, + }) + return agentDetails } catch (error) { - this.logger.error(`Error in get getAgentEndPoint: ${error.message} `); - throw error; + this.logger.error(`Error in get getAgentEndPoint: ${error.message} `) + throw error } } @@ -60,13 +60,13 @@ export class ConnectionRepository { agentId, connectionInvitation, multiUse: true, - invitationDid - } - }); - return agentDetails; + invitationDid, + }, + }) + return agentDetails } catch (error) { - this.logger.error(`Error in saveAgentConnectionInvitations: ${error.message} `); - throw error; + this.logger.error(`Error in saveAgentConnectionInvitations: ${error.message} `) + throw error } } @@ -80,32 +80,30 @@ export class ConnectionRepository { try { const agentInvitationDetails = await this.prisma.agent_invitations.findFirst({ where: { - orgId - } - }); - return agentInvitationDetails; + orgId, + }, + }) + return agentInvitationDetails } catch (error) { - this.logger.error(`Error in saveAgentConnectionInvitations: ${error.message} `); - throw error; + this.logger.error(`Error in saveAgentConnectionInvitations: ${error.message} `) + throw error } } - async getConnectionRecordsCount(orgId: string): Promise { try { const connectionRecordsCount = await this.prisma.connections.count({ where: { - orgId - } - }); - return connectionRecordsCount; + orgId, + }, + }) + return connectionRecordsCount } catch (error) { - this.logger.error(`[get connection records by org Id] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[get connection records by org Id] - error: ${JSON.stringify(error)}`) + throw error } } - /** * Description: Save connection details * @param connectionInvitation @@ -116,63 +114,63 @@ export class ConnectionRepository { // eslint-disable-next-line camelcase async saveConnectionWebhook(payload: ICreateConnection): Promise { try { - let organisationId; - const { connectionDto, orgId } = payload; + let organisationId: string + const { connectionDto, orgId } = payload - if ('default' !== connectionDto?.contextCorrelationId) { - const getOrganizationId = await this.getOrganization(connectionDto?.contextCorrelationId); - organisationId = getOrganizationId?.orgId; + if (connectionDto?.contextCorrelationId !== 'default') { + const getOrganizationId = await this.getOrganization(connectionDto?.contextCorrelationId) + organisationId = getOrganizationId?.orgId } else { - organisationId = orgId; + organisationId = orgId } - const walletLabelName = connectionDto?.theirLabel; - let maskedTheirLabel: string; - let firstLetters: string; - let maskedMiddleLetters: string; - let lastLetters: string; + const walletLabelName = connectionDto?.theirLabel + let maskedTheirLabel: string + let firstLetters: string + let maskedMiddleLetters: string + let lastLetters: string switch (true) { - case 3 >= walletLabelName.length: - firstLetters = walletLabelName.slice(0, 1); - maskedMiddleLetters = walletLabelName.slice(1).replace(/./g, '*'); - maskedTheirLabel = firstLetters + maskedMiddleLetters; - break; + case walletLabelName.length <= 3: + firstLetters = walletLabelName.slice(0, 1) + maskedMiddleLetters = walletLabelName.slice(1).replace(/./g, '*') + maskedTheirLabel = firstLetters + maskedMiddleLetters + break - case 3 < walletLabelName.length && 6 > walletLabelName.length: - firstLetters = walletLabelName.slice(0, 1); - lastLetters = walletLabelName.slice(-1); - maskedMiddleLetters = walletLabelName.slice(1, -1).replace(/./g, '*'); - maskedTheirLabel = firstLetters + maskedMiddleLetters + lastLetters; - break; + case walletLabelName.length > 3 && walletLabelName.length < 6: + firstLetters = walletLabelName.slice(0, 1) + lastLetters = walletLabelName.slice(-1) + maskedMiddleLetters = walletLabelName.slice(1, -1).replace(/./g, '*') + maskedTheirLabel = firstLetters + maskedMiddleLetters + lastLetters + break - case 6 <= walletLabelName.length && 8 >= walletLabelName.length: - firstLetters = walletLabelName.slice(0, 2); - lastLetters = walletLabelName.slice(-2); - maskedMiddleLetters = walletLabelName.slice(2, -2).replace(/./g, '*'); - maskedTheirLabel = firstLetters + maskedMiddleLetters + lastLetters; - break; + case walletLabelName.length >= 6 && walletLabelName.length <= 8: + firstLetters = walletLabelName.slice(0, 2) + lastLetters = walletLabelName.slice(-2) + maskedMiddleLetters = walletLabelName.slice(2, -2).replace(/./g, '*') + maskedTheirLabel = firstLetters + maskedMiddleLetters + lastLetters + break - case 8 < walletLabelName.length: - firstLetters = walletLabelName.slice(0, 3); - lastLetters = walletLabelName.slice(-3); - maskedMiddleLetters = walletLabelName.slice(3, -3).replace(/./g, '*'); - maskedTheirLabel = firstLetters + maskedMiddleLetters + lastLetters; - break; + case walletLabelName.length > 8: + firstLetters = walletLabelName.slice(0, 3) + lastLetters = walletLabelName.slice(-3) + maskedMiddleLetters = walletLabelName.slice(3, -3).replace(/./g, '*') + maskedTheirLabel = firstLetters + maskedMiddleLetters + lastLetters + break default: - maskedTheirLabel = walletLabelName; - break; + maskedTheirLabel = walletLabelName + break } return this.prisma.connections.upsert({ where: { - connectionId: connectionDto?.id + connectionId: connectionDto?.id, }, update: { lastChangedDateTime: connectionDto?.lastChangedDateTime, lastChangedBy: organisationId, - state: connectionDto?.state + state: connectionDto?.state, }, create: { createDateTime: connectionDto?.createDateTime, @@ -182,12 +180,12 @@ export class ConnectionRepository { connectionId: connectionDto?.id, state: connectionDto?.state, theirLabel: maskedTheirLabel, - orgId: organisationId - } - }); + orgId: organisationId, + }, + }) } catch (error) { - this.logger.error(`Error in saveConnectionWebhook: ${error.message} `); - throw error; + this.logger.error(`Error in saveConnectionWebhook: ${error.message} `) + throw error } } @@ -203,12 +201,12 @@ export class ConnectionRepository { return this.prisma.shortening_url.create({ data: { referenceId, - type: null - } - }); + type: null, + }, + }) } catch (error) { - this.logger.error(`Error in saveAgentConnectionInvitations: ${error.message} `); - throw error; + this.logger.error(`Error in saveAgentConnectionInvitations: ${error.message} `) + throw error } } @@ -217,12 +215,12 @@ export class ConnectionRepository { try { return this.prisma.org_agents.findFirst({ where: { - tenantId - } - }); + tenantId, + }, + }) } catch (error) { - this.logger.error(`Error in getOrganization in connection repository: ${error.message} `); - throw error; + this.logger.error(`Error in getOrganization in connection repository: ${error.message} `) + throw error } } @@ -236,12 +234,12 @@ export class ConnectionRepository { try { return this.prisma.shortening_url.findFirst({ where: { - referenceId - } - }); + referenceId, + }, + }) } catch (error) { - this.logger.error(`Error in getShorteningUrl in connection repository: ${error.message} `); - throw error; + this.logger.error(`Error in getShorteningUrl in connection repository: ${error.message} `) + throw error } } @@ -252,15 +250,15 @@ export class ConnectionRepository { // 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; + this.logger.error(`[getPlatformConfigDetails] - error: ${JSON.stringify(error)}`) + throw error } } async getAllConnections( - user: IUserRequest, + _user: IUserRequest, orgId: string, connectionSearchCriteria: IConnectionSearchCriteria ): Promise { @@ -270,8 +268,8 @@ export class ConnectionRepository { orgId, OR: [ { theirLabel: { contains: connectionSearchCriteria.searchByText, mode: 'insensitive' } }, - { connectionId: { contains: connectionSearchCriteria.searchByText, mode: 'insensitive' } } - ] + { connectionId: { contains: connectionSearchCriteria.searchByText, mode: 'insensitive' } }, + ], }, select: { createDateTime: true, @@ -279,119 +277,116 @@ export class ConnectionRepository { orgId: true, state: true, theirLabel: true, - connectionId: true + connectionId: true, }, orderBy: { - [connectionSearchCriteria.sortField]: SortValue.ASC === connectionSearchCriteria.sortBy ? 'asc' : 'desc' + [connectionSearchCriteria.sortField]: SortValue.ASC === connectionSearchCriteria.sortBy ? 'asc' : 'desc', }, take: Number(connectionSearchCriteria.pageSize), - skip: (connectionSearchCriteria.pageNumber - 1) * connectionSearchCriteria.pageSize - }); + skip: (connectionSearchCriteria.pageNumber - 1) * connectionSearchCriteria.pageSize, + }) const connectionCount = await this.prisma.connections.count({ where: { orgId, OR: [ { theirLabel: { contains: connectionSearchCriteria.searchByText, mode: 'insensitive' } }, - { connectionId: { contains: connectionSearchCriteria.searchByText, mode: 'insensitive' } } - ] - } - }); + { connectionId: { contains: connectionSearchCriteria.searchByText, mode: 'insensitive' } }, + ], + }, + }) - return { connectionCount, connectionsList }; + return { connectionCount, connectionsList } } catch (error) { - this.logger.error(`[getAllConnections] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getAllConnections] - error: ${JSON.stringify(error)}`) + throw error } } async getOrgAgentType(orgAgentId: string): Promise { try { const { agent } = await this.prisma.org_agents_type.findFirst({ where: { - id: orgAgentId - } - }); + id: orgAgentId, + }, + }) - return agent; + return agent } catch (error) { - this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`) + throw error } } async deleteConnectionRecordsByOrgId(orgId: string): Promise { - const tablesToCheck = [`${PrismaTables.CREDENTIALS}`, `${PrismaTables.PRESENTATIONS}`]; + const tablesToCheck = [`${PrismaTables.CREDENTIALS}`, `${PrismaTables.PRESENTATIONS}`] try { return await this.prisma.$transaction(async (prisma) => { const referenceCounts = await Promise.all( tablesToCheck.map((table) => prisma[table].count({ where: { orgId } })) - ); + ) const referencedTables = referenceCounts - .map((count, index) => (0 < count ? tablesToCheck[index] : null)) - .filter(Boolean); + .map((count, index) => (count > 0 ? tablesToCheck[index] : null)) + .filter(Boolean) + + if (referencedTables.length > 0) { + let errorMessage = `Organization ID ${orgId} is referenced in the following table(s): ${referencedTables.join(', ')}` - if (0 < referencedTables.length) { - let errorMessage = `Organization ID ${orgId} is referenced in the following table(s): ${referencedTables.join(', ')}`; - - if (1 === referencedTables.length) { + if (referencedTables.length === 1) { if (referencedTables.includes(`${PrismaTables.PRESENTATIONS}`)) { - errorMessage += `, ${ResponseMessages.verification.error.removeVerificationData}`; + errorMessage += `, ${ResponseMessages.verification.error.removeVerificationData}` } else if (referencedTables.includes(`${PrismaTables.CREDENTIALS}`)) { - errorMessage += `, ${ResponseMessages.issuance.error.removeIssuanceData}`; + errorMessage += `, ${ResponseMessages.issuance.error.removeIssuanceData}` } - } else if (2 === referencedTables.length) { - errorMessage += `, ${ResponseMessages.connection.error.removeConnectionReferences}`; + } else if (referencedTables.length === 2) { + errorMessage += `, ${ResponseMessages.connection.error.removeConnectionReferences}` } - - throw new ConflictException(errorMessage); + + throw new ConflictException(errorMessage) } - - const getConnectionRecords = await prisma.connections.findMany( - { - where: { - orgId - }, - select: { - createDateTime: true, - createdBy: true, - connectionId: true, - theirLabel: true, - state: true, - orgId: true - } - }); + const getConnectionRecords = await prisma.connections.findMany({ + where: { + orgId, + }, + select: { + createDateTime: true, + createdBy: true, + connectionId: true, + theirLabel: true, + state: true, + orgId: true, + }, + }) - const deleteConnectionRecords = await prisma.connections.deleteMany( - { - where: { - orgId - } - }); + const deleteConnectionRecords = await prisma.connections.deleteMany({ + where: { + orgId, + }, + }) - return {getConnectionRecords, deleteConnectionRecords }; - }); + return { getConnectionRecords, deleteConnectionRecords } + }) } catch (error) { - this.logger.error(`Error in deleting connection records: ${error.message}`); - throw error; + this.logger.error(`Error in deleting connection records: ${error.message}`) + throw error } } - // eslint-disable-next-line camelcase - async getInvitationDidByOrgId(orgId: string): Promise { + // eslint-disable-next-line camelcase + async getInvitationDidByOrgId(orgId: string): Promise { try { return this.prisma.agent_invitations.findMany({ where: { - orgId + orgId, }, orderBy: { - createDateTime: 'asc' - } - }); + createDateTime: 'asc', + }, + }) } catch (error) { - this.logger.error(`Error in getInvitationDid in connection repository: ${error.message}`); - throw error; + this.logger.error(`Error in getInvitationDid in connection repository: ${error.message}`) + throw error } } } diff --git a/apps/connection/src/connection.service.ts b/apps/connection/src/connection.service.ts index 0efa7a8bf..727ac3cea 100644 --- a/apps/connection/src/connection.service.ts +++ b/apps/connection/src/connection.service.ts @@ -1,33 +1,37 @@ /* eslint-disable camelcase */ -import { CommonService } from '@credebl/common'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { HttpException, HttpStatus, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { from, map } from 'rxjs'; -import { - ConnectionResponseDetail, +import type { CommonService } from '@credebl/common' +import type { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import type { + IConnectionList, + ICreateConnectionUrl, + IDeletedConnectionsRecord, +} from '@credebl/common/interfaces/connection.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { ConnectionProcessState, OrgAgentType } from '@credebl/enum/enum' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { CACHE_MANAGER } from '@nestjs/cache-manager' +import { HttpException, HttpStatus, Inject, Injectable, type Logger, NotFoundException } from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +import { RecordType, type user } from '@prisma/client' +import type { agent_invitations } from '@prisma/client' +import type { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface' +import type { Cache } from 'cache-manager' +import type { UserActivityRepository } from 'libs/user-activity/repositories' +import { from, map } from 'rxjs' +import type { ConnectionRepository } from './connection.repository' +import type { AgentConnectionSearchCriteria, + ConnectionResponseDetail, IConnectionSearchCriteria, ICreateConnection, + ICreateConnectionInvitation, + ICreateOutOfbandConnectionInvitation, IReceiveInvitation, IReceiveInvitationResponse, IReceiveInvitationUrl, - ICreateOutOfbandConnectionInvitation, - ICreateConnectionInvitation -} 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, ConnectionProcessState } from '@credebl/enum/enum'; -import { Cache } from 'cache-manager'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { IConnectionList, ICreateConnectionUrl, IDeletedConnectionsRecord } from '@credebl/common/interfaces/connection.interface'; -import { IConnectionDetailsById } from 'apps/api-gateway/src/interfaces/IConnectionSearch.interface'; -import { IBasicMessage, IQuestionPayload } from './interfaces/messaging.interfaces'; -import { RecordType, user } from '@prisma/client'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { agent_invitations } from '@prisma/client'; -import { NATSClient } from '@credebl/common/NATSClient'; +} from './interfaces/connection.interfaces' +import type { IBasicMessage, IQuestionPayload } from './interfaces/messaging.interfaces' @Injectable() export class ConnectionService { constructor( @@ -37,7 +41,7 @@ export class ConnectionService { private readonly userActivityRepository: UserActivityRepository, private readonly logger: Logger, @Inject(CACHE_MANAGER) private readonly cacheService: Cache, - private readonly natsClient : NATSClient + private readonly natsClient: NATSClient ) {} /** @@ -47,11 +51,11 @@ export class ConnectionService { */ async getConnectionWebhook(payload: ICreateConnection): Promise { try { - const saveConnectionDetails = await this.connectionRepository.saveConnectionWebhook(payload); - return saveConnectionDetails; + const saveConnectionDetails = await this.connectionRepository.saveConnectionWebhook(payload) + return saveConnectionDetails } catch (error) { - this.logger.error(`[getConnectionWebhook] - error in fetch connection webhook: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[getConnectionWebhook] - error in fetch connection webhook: ${error}`) + throw new RpcException(error.response ? error.response : error) } } @@ -65,44 +69,43 @@ export class ConnectionService { url: string, orgId: string ): Promise<{ - response; + response }> { //nats call in agent-service to create an invitation url - const pattern = { cmd: 'agent-create-connection-legacy-invitation' }; - const payload = { connectionPayload, url, orgId }; + const pattern = { cmd: 'agent-create-connection-legacy-invitation' } + const payload = { connectionPayload, url, orgId } try { - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } async storeShorteningUrl(referenceId: string): Promise { try { - return this.connectionRepository.storeShorteningUrl(referenceId); + return this.connectionRepository.storeShorteningUrl(referenceId) } catch (error) { - this.logger.error(`Error in store agent details : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in store agent details : ${JSON.stringify(error)}`) + throw error } } async getConnectionRecords(orgId: string): Promise { try { - return await this.connectionRepository.getConnectionRecordsCount(orgId); + return await this.connectionRepository.getConnectionRecordsCount(orgId) } catch (error) { - this.logger.error( `[getConnectionRecords ] [NATS call]- error in get connection records count : ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } @@ -113,11 +116,11 @@ export class ConnectionService { */ async getUrl(referenceId: string): Promise { try { - const urlDetails = await this.connectionRepository.getShorteningUrl(referenceId); - return urlDetails.referenceId; + const urlDetails = await this.connectionRepository.getShorteningUrl(referenceId) + return urlDetails.referenceId } catch (error) { - this.logger.error(`Error in get url in connection service: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in get url in connection service: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -134,46 +137,42 @@ export class ConnectionService { connectionSearchCriteria: IConnectionSearchCriteria ): Promise { try { - const getConnectionList = await this.connectionRepository.getAllConnections( - user, - orgId, - connectionSearchCriteria - ); + const getConnectionList = await this.connectionRepository.getAllConnections(user, orgId, connectionSearchCriteria) - if (0 === getConnectionList.connectionCount) { - throw new NotFoundException(ResponseMessages.connection.error.connectionNotFound); + if (getConnectionList.connectionCount === 0) { + throw new NotFoundException(ResponseMessages.connection.error.connectionNotFound) } const connectionResponse: { - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; + 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; - }[]; + createDateTime: Date + createdBy: string + connectionId: string + theirLabel: string + state: string + orgId: string + }[] } = { totalItems: getConnectionList.connectionCount, hasNextPage: connectionSearchCriteria.pageSize * connectionSearchCriteria.pageNumber < getConnectionList.connectionCount, - hasPreviousPage: 1 < connectionSearchCriteria.pageNumber, + hasPreviousPage: connectionSearchCriteria.pageNumber > 1, nextPage: Number(connectionSearchCriteria.pageNumber) + 1, previousPage: connectionSearchCriteria.pageNumber - 1, lastPage: Math.ceil(getConnectionList.connectionCount / connectionSearchCriteria.pageSize), - data: getConnectionList.connectionsList - }; - return connectionResponse; + data: getConnectionList.connectionsList, + } + return connectionResponse } catch (error) { - this.logger.error(`[getConnections] [NATS call]- error in fetch connections details : ${JSON.stringify(error)}`); + this.logger.error(`[getConnections] [NATS call]- error in fetch connections details : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } @@ -182,59 +181,59 @@ export class ConnectionService { connectionSearchCriteria: AgentConnectionSearchCriteria ): Promise { try { - const { alias, myDid, outOfBandId, state, theirDid, theirLabel } = connectionSearchCriteria; - const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); - const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); - const { agentEndPoint } = agentDetails; + const { alias, myDid, outOfBandId, state, theirDid, theirLabel } = connectionSearchCriteria + const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId) + const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - let url: string; + let url: string if (orgAgentType === OrgAgentType.DEDICATED) { - url = `${agentEndPoint}${CommonConstants.URL_CONN_GET_CONNECTIONS}`; + url = `${agentEndPoint}${CommonConstants.URL_CONN_GET_CONNECTIONS}` } else if (orgAgentType === OrgAgentType.SHARED) { url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_GET_CREATEED_INVITATIONS}`.replace( '#', agentDetails.tenantId - ); + ) } else { - throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound) } //Create the dynamic URL for Search Criteria - const criteriaParams = []; + const criteriaParams = [] if (alias) { - criteriaParams.push(`alias=${alias}`); + criteriaParams.push(`alias=${alias}`) } if (myDid) { - criteriaParams.push(`myDid=${myDid}`); + criteriaParams.push(`myDid=${myDid}`) } if (outOfBandId) { - criteriaParams.push(`outOfBandId=${outOfBandId}`); + criteriaParams.push(`outOfBandId=${outOfBandId}`) } if (state) { - criteriaParams.push(`state=${state}`); + criteriaParams.push(`state=${state}`) } if (theirDid) { - criteriaParams.push(`theirDid=${theirDid}`); + criteriaParams.push(`theirDid=${theirDid}`) } if (theirLabel) { - criteriaParams.push(`theirLabel=${theirLabel}`); + criteriaParams.push(`theirLabel=${theirLabel}`) } - if (0 < criteriaParams.length) { - url += `?${criteriaParams.join('&')}`; + if (criteriaParams.length > 0) { + url += `?${criteriaParams.join('&')}` } - const connectionResponse = await this._getAllConnections(url, orgId); - return connectionResponse.response; + const connectionResponse = await this._getAllConnections(url, orgId) + return connectionResponse.response } catch (error) { this.logger.error( `[getConnectionsFromAgent] [NATS call]- error in fetch connections details : ${JSON.stringify(error)}` - ); + ) - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } @@ -242,75 +241,74 @@ export class ConnectionService { url: string, orgId: string ): Promise<{ - response: string; + response: string }> { try { - const pattern = { cmd: 'agent-get-all-connections' }; - const payload = { url, orgId }; - return await this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-get-all-connections' } + const payload = { url, orgId } + return await this.natsCall(pattern, payload) } catch (error) { this.logger.error( `[_getAllConnections] [NATS call]- error in fetch connections details : ${JSON.stringify(error)}` - ); - throw error; + ) + throw error } } - 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); + const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId) + const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - let url; + let url: string if (orgAgentType === OrgAgentType.DEDICATED) { - url = `${agentEndPoint}${CommonConstants.URL_CONN_GET_CONNECTION_BY_ID}`.replace('#', connectionId); + url = `${agentEndPoint}${CommonConstants.URL_CONN_GET_CONNECTION_BY_ID}`.replace('#', connectionId) } else if (orgAgentType === OrgAgentType.SHARED) { url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_GET_CREATEED_INVITATION_BY_CONNECTIONID}` .replace('#', connectionId) - .replace('@', agentDetails.tenantId); + .replace('@', agentDetails.tenantId) } else { - throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound) } - const createConnectionInvitation = await this._getConnectionsByConnectionId(url, orgId); - return createConnectionInvitation?.response; + const createConnectionInvitation = await this._getConnectionsByConnectionId(url, orgId) + return createConnectionInvitation?.response } catch (error) { - this.logger.error(`[getConnectionsById] - error in get connections : ${JSON.stringify(error)}`); + this.logger.error(`[getConnectionsById] - error in get connections : ${JSON.stringify(error)}`) if (error?.response?.error?.reason) { throw new RpcException({ message: ResponseMessages.connection.error.connectionNotFound, statusCode: error?.response?.status, - error: error?.response?.error?.reason - }); - } else { - throw new RpcException(error.response ? error.response : error); + error: error?.response?.error?.reason, + }) } + throw new RpcException(error.response ? error.response : error) } } async getQuestionAnswersRecord(orgId: string): Promise { try { - const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); - const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); - const { agentEndPoint } = agentDetails; + const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId) + const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - const label = 'get-question-answer-record'; - const url = await this.getQuestionAnswerAgentUrl(label, orgAgentType, agentEndPoint, agentDetails?.tenantId); + const label = 'get-question-answer-record' + const url = await this.getQuestionAnswerAgentUrl(label, orgAgentType, agentEndPoint, agentDetails?.tenantId) - const record = await this._getQuestionAnswersRecord(url, orgId); - return record; + const record = await this._getQuestionAnswersRecord(url, orgId) + return record } catch (error) { - this.logger.error(`[sendQuestion] - error in get question answer record: ${error}`); - this.handleError(error); + this.logger.error(`[sendQuestion] - error in get question answer record: ${error}`) + this.handleError(error) } } @@ -318,18 +316,18 @@ export class ConnectionService { url: string, orgId: string ): Promise<{ - response; + response }> { //nats call in agent service for fetch connection details - const pattern = { cmd: 'agent-get-connection-details-by-connectionId' }; - const payload = { url, orgId }; - return this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-get-connection-details-by-connectionId' } + const payload = { url, orgId } + return this.natsCall(pattern, payload) } async _getQuestionAnswersRecord(url: string, orgId: string): Promise { - const pattern = { cmd: 'agent-get-question-answer-record' }; - const payload = { url, orgId }; - return this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-get-question-answer-record' } + const payload = { url, orgId } + return this.natsCall(pattern, payload) } /** @@ -344,28 +342,28 @@ export class ConnectionService { connectionInvitationFlag?: string ): Promise { try { - let url; - if ('connection-invitation' === connectionInvitationFlag) { + let url: string + if (connectionInvitationFlag === 'connection-invitation') { if (orgAgentType === OrgAgentType.DEDICATED) { - url = `${agentEndPoint}${CommonConstants.URL_CONN_INVITE}`; + url = `${agentEndPoint}${CommonConstants.URL_CONN_INVITE}` } else if (orgAgentType === OrgAgentType.SHARED) { - url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_CONNECTION_INVITATION}`.replace('#', tenantId); + url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_CONNECTION_INVITATION}`.replace('#', tenantId) } else { - throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound) } } else { if (orgAgentType === OrgAgentType.DEDICATED) { - url = `${agentEndPoint}${CommonConstants.URL_CONN_LEGACY_INVITE}`; + url = `${agentEndPoint}${CommonConstants.URL_CONN_LEGACY_INVITE}` } else if (orgAgentType === OrgAgentType.SHARED) { - url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_INVITATION}`.replace('#', tenantId); + url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_INVITATION}`.replace('#', tenantId) } else { - throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound) } } - return url; + return url } catch (error) { - this.logger.error(`Error in get agent url: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in get agent url: ${JSON.stringify(error)}`) + throw error } } @@ -377,18 +375,18 @@ export class ConnectionService { connectionId?: string ): Promise { try { - let url; + let url: string switch (label) { case 'send-question': { url = orgAgentType === OrgAgentType.DEDICATED ? `${agentEndPoint}${CommonConstants.URL_SEND_QUESTION}`.replace('#', connectionId) : orgAgentType === OrgAgentType.SHARED - ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_SEND_QUESTION}` - .replace('#', connectionId) - .replace('@', tenantId) - : null; - break; + ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_SEND_QUESTION}` + .replace('#', connectionId) + .replace('@', tenantId) + : null + break } case 'get-question-answer-record': { @@ -396,95 +394,94 @@ export class ConnectionService { orgAgentType === OrgAgentType.DEDICATED ? `${agentEndPoint}${CommonConstants.URL_QUESTION_ANSWER_RECORD}` : orgAgentType === OrgAgentType.SHARED - ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_QUESTION_ANSWER_RECORD}`.replace('#', tenantId) - : null; - break; + ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_QUESTION_ANSWER_RECORD}`.replace('#', tenantId) + : null + break } default: { - break; + break } } if (!url) { - throw new NotFoundException(ResponseMessages.issuance.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentUrlNotFound) } - return url; + return url } catch (error) { - this.logger.error(`Error get question answer agent Url: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error get question answer agent Url: ${JSON.stringify(error)}`) + throw error } } async _getOrgAgentApiKey(orgId: string): Promise<{ - response: string; + response: string }> { - const pattern = { cmd: 'get-org-agent-api-key' }; - const payload = { orgId }; + const pattern = { cmd: 'get-org-agent-api-key' } + const payload = { orgId } try { - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } async receiveInvitationUrl( - user: IUserRequest, + _user: IUserRequest, receiveInvitationUrl: IReceiveInvitationUrl, orgId: string ): Promise { try { - const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); - const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); + const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId) + const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - let url; + let url: string if (orgAgentType === OrgAgentType.DEDICATED) { - url = `${agentEndPoint}${CommonConstants.URL_RECEIVE_INVITATION_URL}`; + url = `${agentEndPoint}${CommonConstants.URL_RECEIVE_INVITATION_URL}` } else if (orgAgentType === OrgAgentType.SHARED) { url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_RECEIVE_INVITATION_URL}`.replace( '#', agentDetails.tenantId - ); + ) } else { - throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound) } - const createConnectionInvitation = await this._receiveInvitationUrl(url, orgId, receiveInvitationUrl); - return createConnectionInvitation.response; + const createConnectionInvitation = await this._receiveInvitationUrl(url, orgId, receiveInvitationUrl) + return createConnectionInvitation.response } catch (error) { - this.logger.error(`[receiveInvitationUrl] - error in receive invitation url : ${JSON.stringify(error, null, 2)}`); + this.logger.error(`[receiveInvitationUrl] - error in receive invitation url : ${JSON.stringify(error, null, 2)}`) - const customErrorMessage = error?.status?.message?.error?.message; + const customErrorMessage = error?.status?.message?.error?.message if (customErrorMessage) { throw new RpcException({ statusCode: HttpStatus.CONFLICT, message: customErrorMessage, - error: ResponseMessages.errorMessages.conflict - }); - } else + error: ResponseMessages.errorMessages.conflict, + }) + } if (error?.response?.error?.reason) { throw new RpcException({ message: ResponseMessages.connection.error.connectionNotFound, statusCode: error?.response?.status, - error: error?.response?.error?.reason - }); - } else { - throw new RpcException(error.response ? error.response : error); + error: error?.response?.error?.reason, + }) } + throw new RpcException(error.response ? error.response : error) } } @@ -493,63 +490,61 @@ export class ConnectionService { orgId: string, receiveInvitationUrl: IReceiveInvitationUrl ): Promise<{ - response; + response }> { - - const pattern = { cmd: 'agent-receive-invitation-url' }; - const payload = { url, orgId, receiveInvitationUrl }; + const pattern = { cmd: 'agent-receive-invitation-url' } + const payload = { url, orgId, receiveInvitationUrl } try { - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } async receiveInvitation( - user: IUserRequest, + _user: IUserRequest, receiveInvitation: IReceiveInvitation, orgId: string ): Promise { try { - const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); - const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); + const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId) + const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - let url; + let url: string if (orgAgentType === OrgAgentType.DEDICATED) { - url = `${agentEndPoint}${CommonConstants.URL_RECEIVE_INVITATION}`; + url = `${agentEndPoint}${CommonConstants.URL_RECEIVE_INVITATION}` } else if (orgAgentType === OrgAgentType.SHARED) { - url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_RECEIVE_INVITATION}`.replace('#', agentDetails.tenantId); + url = `${agentEndPoint}${CommonConstants.URL_SHAGENT_RECEIVE_INVITATION}`.replace('#', agentDetails.tenantId) } else { - throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentUrlNotFound) } - const createConnectionInvitation = await this._receiveInvitation(url, orgId, receiveInvitation); - return createConnectionInvitation?.response; + const createConnectionInvitation = await this._receiveInvitation(url, orgId, receiveInvitation) + return createConnectionInvitation?.response } catch (error) { - this.logger.error(`[receiveInvitation] - error in receive invitation : ${JSON.stringify(error)}`); + this.logger.error(`[receiveInvitation] - error in receive invitation : ${JSON.stringify(error)}`) if (error?.response?.error?.reason) { throw new RpcException({ message: ResponseMessages.connection.error.connectionNotFound, statusCode: error?.response?.status, - error: error?.response?.error?.reason - }); - } else { - throw new RpcException(error.response ? error.response : error); + error: error?.response?.error?.reason, + }) } + throw new RpcException(error.response ? error.response : error) } } @@ -558,81 +553,80 @@ export class ConnectionService { orgId: string, receiveInvitation: IReceiveInvitation ): Promise<{ - response; + response }> { - const pattern = { cmd: 'agent-receive-invitation' }; - const payload = { url, orgId, receiveInvitation }; - return this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-receive-invitation' } + const payload = { url, orgId, receiveInvitation } + return this.natsCall(pattern, payload) } async _sendQuestion(questionPayload: IQuestionPayload, url: string, orgId: string): Promise { - const pattern = { cmd: 'agent-send-question' }; - const payload = { questionPayload, url, orgId }; - return this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-send-question' } + const payload = { questionPayload, url, orgId } + return this.natsCall(pattern, payload) } async sendQuestion(payload: IQuestionPayload): Promise { - const { detail, validResponses, question, orgId, connectionId } = payload; + const { detail, validResponses, question, orgId, connectionId } = payload try { - const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); + const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId) - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.connection.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentEndPointNotFound) } const questionPayload = { detail, validResponses, - question - }; + question, + } - const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); - const label = 'send-question'; + const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) + const label = 'send-question' const url = await this.getQuestionAnswerAgentUrl( label, orgAgentType, agentEndPoint, agentDetails?.tenantId, connectionId - ); + ) - const createQuestion = await this._sendQuestion(questionPayload, url, orgId); - return createQuestion; + const createQuestion = await this._sendQuestion(questionPayload, url, orgId) + return createQuestion } catch (error) { - this.logger.error(`[sendQuestion] - error in sending question: ${error}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + this.logger.error(`[sendQuestion] - error in sending question: ${error}`) + if (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); + statusCode: error?.status?.code, + }) } + throw new RpcException(error.response ? error.response : error) } } async storeConnectionObjectAndReturnUrl(connectionInvitationUrl: string, persistent: boolean): Promise { - const storeObj = connectionInvitationUrl; + const storeObj = connectionInvitationUrl //nats call in agent-service to create an invitation url - const pattern = { cmd: 'store-object-return-url' }; - const payload = { persistent, storeObj }; + const pattern = { cmd: 'store-object-return-url' } + const payload = { persistent, storeObj } try { - const message = await this.natsCall(pattern, payload); - return message.response; + const message = await this.natsCall(pattern, payload) + return message.response } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } @@ -644,7 +638,6 @@ export class ConnectionService { */ async createConnectionInvitation(payload: ICreateOutOfbandConnectionInvitation): Promise { try { - const { alias, appendedAttachments, @@ -660,35 +653,35 @@ export class ConnectionService { routing, recipientKey, invitationDid, - IsReuseConnection - } = payload?.createOutOfBandConnectionInvitation; + IsReuseConnection, + // biome-ignore lint/correctness/noUnsafeOptionalChaining: + } = payload?.createOutOfBandConnectionInvitation const agentDetails = await this.connectionRepository.getAgentEndPoint( payload?.createOutOfBandConnectionInvitation?.orgId - ); + ) - const { agentEndPoint, id, organisation } = agentDetails; - const agentId = id; + const { agentEndPoint, id, organisation } = agentDetails + const agentId = id if (!agentDetails) { - throw new NotFoundException(ResponseMessages.connection.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentEndPointNotFound) } - let legacyinvitationDid; + let legacyinvitationDid: string if (IsReuseConnection) { - const data: agent_invitations[] = await this.connectionRepository.getInvitationDidByOrgId(orgId); - if (data && 0 < data.length) { - const [firstElement] = data; - legacyinvitationDid = firstElement?.invitationDid ?? undefined; - - this.logger.log('legacyinvitationDid:', legacyinvitationDid); + const data: agent_invitations[] = await this.connectionRepository.getInvitationDidByOrgId(orgId) + if (data && data.length > 0) { + const [firstElement] = data + legacyinvitationDid = firstElement?.invitationDid ?? undefined + + this.logger.log('legacyinvitationDid:', legacyinvitationDid) } } - const connectionInvitationDid = invitationDid ? invitationDid : legacyinvitationDid; + const connectionInvitationDid = invitationDid ? invitationDid : legacyinvitationDid - this.logger.log('connectionInvitationDid:', connectionInvitationDid); + this.logger.log('connectionInvitationDid:', connectionInvitationDid) - - this.logger.log(`logoUrl:::, ${organisation.logoUrl}`); + this.logger.log(`logoUrl:::, ${organisation.logoUrl}`) const connectionPayload = { multiUseInvitation: multiUseInvitation ?? true, autoAcceptConnection: autoAcceptConnection ?? true, @@ -703,31 +696,31 @@ export class ConnectionService { routing: routing || undefined, messages: messages || undefined, recipientKey: recipientKey || undefined, - invitationDid: connectionInvitationDid || undefined - }; + invitationDid: connectionInvitationDid || undefined, + } - const createConnectionInvitationFlag = 'connection-invitation'; - const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); + const createConnectionInvitationFlag = 'connection-invitation' + const orgAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) const url = await this.getAgentUrl( orgAgentType, agentEndPoint, agentDetails?.tenantId, createConnectionInvitationFlag - ); - const createConnectionInvitation = await this._createOutOfBandConnectionInvitation(connectionPayload, url, orgId); - const connectionInvitationUrl = createConnectionInvitation?.response?.invitationUrl; + ) + const createConnectionInvitation = await this._createOutOfBandConnectionInvitation(connectionPayload, url, orgId) + const connectionInvitationUrl = createConnectionInvitation?.response?.invitationUrl const shortenedUrl = await this.storeConnectionObjectAndReturnUrl( connectionInvitationUrl, connectionPayload.multiUseInvitation - ); + ) - const invitationsDid = createConnectionInvitation?.response?.invitationDid || invitationDid; + const invitationsDid = createConnectionInvitation?.response?.invitationDid || invitationDid const saveConnectionDetails = await this.connectionRepository.saveAgentConnectionInvitations( shortenedUrl, agentId, orgId, - invitationsDid - ); + invitationsDid + ) const connectionStorePayload: ConnectionResponseDetail = { id: saveConnectionDetails.id, orgId: saveConnectionDetails.orgId, @@ -739,12 +732,12 @@ export class ConnectionService { lastChangedDateTime: saveConnectionDetails.lastChangedDateTime, lastChangedBy: saveConnectionDetails.lastChangedBy, recordId: createConnectionInvitation.response.outOfBandRecord.id, - invitationDid: saveConnectionDetails.invitationDid - }; - return connectionStorePayload; + invitationDid: saveConnectionDetails.invitationDid, + } + return connectionStorePayload } catch (error) { - this.logger.error(`[createConnectionInvitation] - error in connection oob invitation: ${error}`); - this.handleError(error); + this.logger.error(`[createConnectionInvitation] - error in connection oob invitation: ${error}`) + this.handleError(error) } } @@ -758,23 +751,23 @@ export class ConnectionService { url: string, orgId: string ): Promise<{ - response; + response }> { //nats call in agent-service to create an invitation url - const pattern = { cmd: 'agent-create-connection-invitation' }; - const payload = { connectionPayload, url, orgId }; + const pattern = { cmd: 'agent-create-connection-invitation' } + const payload = { connectionPayload, url, orgId } try { - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } @@ -782,138 +775,132 @@ export class ConnectionService { pattern: object, payload: object ): Promise<{ - response: string; + response: string }> { try { - return from(this.natsClient - .send(this.connectionServiceProxy, pattern, payload)) + return from(this.natsClient.send(this.connectionServiceProxy, pattern, payload)) .pipe( map((response) => ({ - response + response, })) ) .toPromise() .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.statusCode, - error: error.message + error: error.message, }, error.error - ); - }); + ) + }) } catch (error) { - this.logger.error(`[ConnectionService natsCall] - error in nats call : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[ConnectionService natsCall] - error in nats call : ${JSON.stringify(error)}`) + throw error } } handleError(error): Promise { - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + if (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); + statusCode: error?.status?.code, + }) } + throw new RpcException(error.response ? error.response : error) } async deleteConnectionRecords(orgId: string, user: user): Promise { try { - const deleteConnections = await this.connectionRepository.deleteConnectionRecordsByOrgId(orgId); - - if (0 === deleteConnections?.deleteConnectionRecords?.count) { - throw new NotFoundException(ResponseMessages.connection.error.connectionRecordNotFound); - } + const deleteConnections = await this.connectionRepository.deleteConnectionRecordsByOrgId(orgId) - const statusCounts = { - [ConnectionProcessState.START]: 0, - [ConnectionProcessState.COMPLETE]: 0, - [ConnectionProcessState.ABANDONED]: 0, - [ConnectionProcessState.INVITATION_SENT]: 0, - [ConnectionProcessState.INVITATION_RECEIVED]: 0, - [ConnectionProcessState.REQUEST_SENT]: 0, - [ConnectionProcessState.DECLIEND]: 0, - [ConnectionProcessState.REQUEST_RECEIVED]: 0, - [ConnectionProcessState.RESPONSE_SENT]: 0, - [ConnectionProcessState.RESPONSE_RECEIVED]: 0 - }; + if (deleteConnections?.deleteConnectionRecords?.count === 0) { + throw new NotFoundException(ResponseMessages.connection.error.connectionRecordNotFound) + } - await Promise.all(deleteConnections.getConnectionRecords.map(async (record) => { - statusCounts[record.state]++; - })); + const statusCounts = { + [ConnectionProcessState.START]: 0, + [ConnectionProcessState.COMPLETE]: 0, + [ConnectionProcessState.ABANDONED]: 0, + [ConnectionProcessState.INVITATION_SENT]: 0, + [ConnectionProcessState.INVITATION_RECEIVED]: 0, + [ConnectionProcessState.REQUEST_SENT]: 0, + [ConnectionProcessState.DECLIEND]: 0, + [ConnectionProcessState.REQUEST_RECEIVED]: 0, + [ConnectionProcessState.RESPONSE_SENT]: 0, + [ConnectionProcessState.RESPONSE_RECEIVED]: 0, + } - const filteredStatusCounts = Object.fromEntries( - Object.entries(statusCounts).filter(entry => 0 < entry[1]) - ); + await Promise.all( + deleteConnections.getConnectionRecords.map(async (record) => { + statusCounts[record.state]++ + }) + ) - const deletedConnectionData = { - deletedConnectionsRecordsCount: deleteConnections?.deleteConnectionRecords?.count, - deletedRecordsStatusCount: filteredStatusCounts - }; + const filteredStatusCounts = Object.fromEntries(Object.entries(statusCounts).filter((entry) => entry[1] > 0)) - await this.userActivityRepository._orgDeletedActivity(orgId, user, deletedConnectionData, RecordType.CONNECTION); + const deletedConnectionData = { + deletedConnectionsRecordsCount: deleteConnections?.deleteConnectionRecords?.count, + deletedRecordsStatusCount: filteredStatusCounts, + } - return deleteConnections; + await this.userActivityRepository._orgDeletedActivity(orgId, user, deletedConnectionData, RecordType.CONNECTION) + return deleteConnections } catch (error) { - this.logger.error(`[deleteConnectionRecords] - error in deleting connection records: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[deleteConnectionRecords] - error in deleting connection records: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - async sendBasicMesage(payload: IBasicMessage): Promise { - const { content, orgId, connectionId } = payload; + const { content, orgId, connectionId } = payload try { - const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId); + const agentDetails = await this.connectionRepository.getAgentEndPoint(orgId) - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.connection.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.connection.error.agentEndPointNotFound) } const questionPayload = { - content - }; + content, + } - const organizationAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); - const label = 'send-basic-message'; + const organizationAgentType = await this.connectionRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) + const label = 'send-basic-message' const agentUrl = await this.commonService.sendBasicMessageAgentUrl( label, organizationAgentType, agentEndPoint, agentDetails?.tenantId, connectionId - ); + ) - const sendBasicMessage = await this._sendBasicMessageToAgent(questionPayload, agentUrl, orgId); - return sendBasicMessage; + const sendBasicMessage = await this._sendBasicMessageToAgent(questionPayload, agentUrl, orgId) + return sendBasicMessage } catch (error) { - this.logger.error(`[sendBasicMesage] - error in send basic message: ${error}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + this.logger.error(`[sendBasicMesage] - error in send basic message: ${error}`) + if (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); + statusCode: error?.status?.code, + }) } + throw new RpcException(error.response ? error.response : error) } } async _sendBasicMessageToAgent(content: IBasicMessage, url: string, orgId: string): Promise { - const pattern = { cmd: 'agent-send-basic-message' }; - const payload = { content, url, orgId }; + const pattern = { cmd: 'agent-send-basic-message' } + const payload = { content, url, orgId } // eslint-disable-next-line no-return-await - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } - } diff --git a/apps/connection/src/enum.ts b/apps/connection/src/enum.ts index 0376d7b99..13b6798d6 100644 --- a/apps/connection/src/enum.ts +++ b/apps/connection/src/enum.ts @@ -1,4 +1,4 @@ export enum CredentialSortBy { - id = 'id', - createDateTime = 'createDateTime' -} \ No newline at end of file + id = 'id', + createDateTime = 'createDateTime', +} diff --git a/apps/connection/src/enum/connection.enum.ts b/apps/connection/src/enum/connection.enum.ts index 6e42e5d6d..4d9ec4af7 100644 --- a/apps/connection/src/enum/connection.enum.ts +++ b/apps/connection/src/enum/connection.enum.ts @@ -1,5 +1,5 @@ export enum SortFields { - CREATED_DATE_TIME = 'createDateTime', - USER_LABEL = 'theirLabel', - CONNECTION_ID = 'connectionId' -} \ No newline at end of file + CREATED_DATE_TIME = 'createDateTime', + USER_LABEL = 'theirLabel', + CONNECTION_ID = 'connectionId', +} diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index 020e4821d..d6d2d0d8f 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -1,294 +1,294 @@ // eslint-disable-next-line camelcase -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { organisation } from '@prisma/client'; -import { UserRoleOrgPermsDto } from 'apps/api-gateway/src/dtos/user-role-org-perms.dto'; +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import type { organisation } from '@prisma/client' +import type { UserRoleOrgPermsDto } from 'apps/api-gateway/src/dtos/user-role-org-perms.dto' export interface IConnection { - user: IUserRequestInterface; - alias: string; - label: string; - imageUrl: string; - multiUseInvitation: boolean; - autoAcceptConnection: boolean; - goalCode: string; - goal: string; - handshake: string; - handshakeProtocols: string[]; - orgId: string; - recipientKey?: string; + user: IUserRequestInterface + alias: string + label: string + imageUrl: string + multiUseInvitation: boolean + autoAcceptConnection: boolean + goalCode: string + goal: string + handshake: string + handshakeProtocols: string[] + orgId: string + recipientKey?: string invitationDid?: string } export interface IUserRequestInterface { - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?: string; - selectedOrg: ISelectedOrgInterface; + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string + selectedOrg: ISelectedOrgInterface } export interface ISelectedOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: object; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: object } export interface IOrganizationInterface { - name: string; - description: string; - org_agents: IOrgAgentInterface[]; + name: string + description: string + org_agents: IOrgAgentInterface[] } export interface IOrgAgentInterface { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } export interface ICreateConnection { - connectionDto: ICreateConnectionPayload; - orgId: string; + connectionDto: ICreateConnectionPayload + orgId: string } export interface ICreateConnectionPayload { - createDateTime: string; - lastChangedDateTime: string; - id: string; - state: string; - imageUrl: string; - orgDid?: string; - theirLabel: string; - autoAcceptConnection: boolean; - outOfBandId: string; - orgId: string; - contextCorrelationId: string; + createDateTime: string + lastChangedDateTime: string + id: string + state: string + imageUrl: string + orgDid?: string + theirLabel: string + autoAcceptConnection: boolean + outOfBandId: string + orgId: string + contextCorrelationId: string } export interface IFetchConnections { - connectionSearchCriteria: IConnectionSearchCriteria; - user: IUserRequest; - orgId: string; + connectionSearchCriteria: IConnectionSearchCriteria + user: IUserRequest + orgId: string } export interface GetAllConnections { - connectionSearchCriteria: AgentConnectionSearchCriteria; - user: IUserRequest; - orgId: string; + connectionSearchCriteria: AgentConnectionSearchCriteria + user: IUserRequest + orgId: string } export interface IFetchConnectionById { - user: IUserRequest; - connectionId: string; - orgId: string; + user: IUserRequest + connectionId: string + orgId: string } export interface IFetchConnectionUrlById { - user: IUserRequest; - invitationId: string; - orgId: string; + user: IUserRequest + invitationId: string + orgId: string } export interface IConnectionInvitation { - message: IInvitation; + message: IInvitation } interface IInvitation { - invitation: string; - invitationUrl: string; + invitation: string + invitationUrl: string } export interface OrgAgent { - organisation: organisation; - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - orgDid: string; - verkey: string; - agentEndPoint: string; - agentId: string; - isDidPublic: boolean; - ledgerId: string; - orgAgentTypeId: string; - tenantId: string; + organisation: organisation + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + orgDid: string + verkey: string + agentEndPoint: string + agentId: string + isDidPublic: boolean + ledgerId: string + orgAgentTypeId: string + tenantId: string } export interface IConnectionSearchCriteria { - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - searchByText: string; + pageNumber: number + pageSize: number + sortField: string + sortBy: string + searchByText: string user: IUserRequestInterface } export interface AgentConnectionSearchCriteria { - outOfBandId: string; - alias: string; - state: string; - myDid: string; - theirDid: string; - theirLabel: string; + outOfBandId: string + alias: string + state: string + myDid: string + theirDid: string + theirLabel: string } export interface IReceiveInvitationByUrlOrg { - user: IUserRequestInterface, - receiveInvitationUrl: IReceiveInvitationUrl, + user: IUserRequestInterface + receiveInvitationUrl: IReceiveInvitationUrl orgId: string } export interface IReceiveInvitationUrl extends IReceiveInvite { - invitationUrl: string; + invitationUrl: string } export interface IReceiveInvitationByOrg { - user: IUserRequestInterface, - receiveInvitation: IReceiveInvitation, + user: IUserRequestInterface + receiveInvitation: IReceiveInvitation orgId: string } interface Service { - id: string; - serviceEndpoint: string; - type: string; - recipientKeys: string[]; - routingKeys: string[]; - accept: string[]; + id: string + serviceEndpoint: string + type: string + recipientKeys: string[] + routingKeys: string[] + accept: string[] } interface Invitation { - '@id': string; - '@type': string; - label: string; - goalCode: string; - goal: string; - accept: string[]; - handshake_protocols: string[]; - services: (Service | string)[]; - imageUrl?: string; + '@id': string + '@type': string + label: string + goalCode: string + goal: string + accept: string[] + handshake_protocols: string[] + services: (Service | string)[] + imageUrl?: string } export interface IReceiveInvite { - alias?: string; - label?: string; - imageUrl?: string; - autoAcceptConnection?: boolean; - autoAcceptInvitation?: boolean; - reuseConnection?: boolean; - acceptInvitationTimeoutMs?: number; + alias?: string + label?: string + imageUrl?: string + autoAcceptConnection?: boolean + autoAcceptInvitation?: boolean + reuseConnection?: boolean + acceptInvitationTimeoutMs?: number } export interface IReceiveInvitation extends IReceiveInvite { - invitation: Invitation; + invitation: Invitation } interface Tags { - invitationId: string; - recipientKeyFingerprints: string[]; - role: string; - state: string; - threadId: string; + invitationId: string + recipientKeyFingerprints: string[] + role: string + state: string + threadId: string } interface OutOfBandInvitationService { - id: string; - serviceEndpoint: string; - type: string; - recipientKeys: string[]; - routingKeys: string[]; + id: string + serviceEndpoint: string + type: string + recipientKeys: string[] + routingKeys: string[] } interface OutOfBandInvitation { - "@type": string; - "@id": string; - label: string; - accept: string[]; - handshake_protocols: string[]; - services: OutOfBandInvitationService[]; + '@type': string + '@id': string + label: string + accept: string[] + handshake_protocols: string[] + services: OutOfBandInvitationService[] } interface OutOfBandRecord { - _tags: Tags; - metadata?: { [key: string]: string }; - id: string; - createdAt: string; - outOfBandInvitation: OutOfBandInvitation; - role: string; - state: string; - autoAcceptConnection: boolean; - reusable: boolean; - updatedAt: string; + _tags: Tags + metadata?: { [key: string]: string } + id: string + createdAt: string + outOfBandInvitation: OutOfBandInvitation + role: string + state: string + autoAcceptConnection: boolean + reusable: boolean + updatedAt: string } interface ConnectionRecord { - _tags: { [key: string]: string }; - metadata: { [key: string]: string }; - connectionTypes: string[]; - id: string; - createdAt: string; - did: string; - invitationDid: string; - theirLabel: string; - state: string; - role: string; - alias: string; - autoAcceptConnection: boolean; - threadId: string; - protocol: string; - outOfBandId: string; - updatedAt: string; + _tags: { [key: string]: string } + metadata: { [key: string]: string } + connectionTypes: string[] + id: string + createdAt: string + did: string + invitationDid: string + theirLabel: string + state: string + role: string + alias: string + autoAcceptConnection: boolean + threadId: string + protocol: string + outOfBandId: string + updatedAt: string } export interface IReceiveInvitationResponse { - outOfBandRecord: OutOfBandRecord; - connectionRecord: ConnectionRecord; + outOfBandRecord: OutOfBandRecord + connectionRecord: ConnectionRecord } export interface ConnectionResponseDetail { - id: string; - orgId: string; - agentId: string; - connectionInvitation: string; - multiUse: boolean; - createDateTime: Date; - createdBy: number; - lastChangedDateTime: Date; - lastChangedBy: number; - recordId: string; + id: string + orgId: string + agentId: string + connectionInvitation: string + multiUse: boolean + createDateTime: Date + createdBy: number + lastChangedDateTime: Date + lastChangedBy: number + recordId: string invitationDid?: string } export interface ICreateConnectionInvitation { - label?: string; - alias?: string; - imageUrl?: string; - goalCode?: string; - goal?: string; - handshake?: boolean; - handshakeProtocols?: object[]; - messages?: object[]; - multiUseInvitation?: boolean; - autoAcceptConnection?: boolean; - IsReuseConnection?: boolean; - routing?: object; - appendedAttachments?: object[]; - orgId?: string; - recipientKey?: string; - invitationDid?: string; + label?: string + alias?: string + imageUrl?: string + goalCode?: string + goal?: string + handshake?: boolean + handshakeProtocols?: object[] + messages?: object[] + multiUseInvitation?: boolean + autoAcceptConnection?: boolean + IsReuseConnection?: boolean + routing?: object + appendedAttachments?: object[] + orgId?: string + recipientKey?: string + invitationDid?: string } export interface ICreateOutOfbandConnectionInvitation { - user: IUserRequestInterface, - createOutOfBandConnectionInvitation: ICreateConnectionInvitation, -} \ No newline at end of file + user: IUserRequestInterface + createOutOfBandConnectionInvitation: ICreateConnectionInvitation +} diff --git a/apps/connection/src/interfaces/messaging.interfaces.ts b/apps/connection/src/interfaces/messaging.interfaces.ts index e5cbbacd2..ed6f2ffbb 100644 --- a/apps/connection/src/interfaces/messaging.interfaces.ts +++ b/apps/connection/src/interfaces/messaging.interfaces.ts @@ -1,19 +1,19 @@ export interface IValidResponses { - text: string; + text: string } export interface IQuestionPayload { - detail: string; - validResponses: IValidResponses[]; - question: string; - orgId?: string; - connectionId?: string; - tenantId?: string; + detail: string + validResponses: IValidResponses[] + question: string + orgId?: string + connectionId?: string + tenantId?: string } export interface IBasicMessage { - content: string; - orgId?: string; - connectionId?: string; - tenantId?: string; + content: string + orgId?: string + connectionId?: string + tenantId?: string } diff --git a/apps/connection/src/main.ts b/apps/connection/src/main.ts index 752b048f6..22e416bc8 100644 --- a/apps/connection/src/main.ts +++ b/apps/connection/src/main.ts @@ -1,25 +1,24 @@ -import { NestFactory } from '@nestjs/core'; -import { ConnectionModule } from './connection.module'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { ConnectionModule } from './connection.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(ConnectionModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.CONNECTION_SERVICE, process.env.CONNECTION_NKEY_SEED) - }); - - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.CONNECTION_SERVICE, process.env.CONNECTION_NKEY_SEED), + }) + + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Connection-Service Microservice is listening to NATS '); + await app.listen() + logger.log('Connection-Service Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/connection/test/app.e2e-spec.ts b/apps/connection/test/app.e2e-spec.ts index bae2e58fd..d066c353f 100644 --- a/apps/connection/test/app.e2e-spec.ts +++ b/apps/connection/test/app.e2e-spec.ts @@ -1,22 +1,19 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { ConnectionModule } from '../src/connection.module'; +import type { INestApplication } from '@nestjs/common' +import { Test, type TestingModule } from '@nestjs/testing' +import * as request from 'supertest' +import { ConnectionModule } from '../src/connection.module' describe('ConnectionServiceController (e2e)', () => { - let app: INestApplication; + let app: INestApplication beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [ConnectionModule] - }).compile(); + imports: [ConnectionModule], + }).compile() - app = moduleFixture.createNestApplication(); - await app.init(); - }); + app = moduleFixture.createNestApplication() + await app.init() + }) - it('/ (GET)', () => request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!')); -}); + it('/ (GET)', () => request(app.getHttpServer()).get('/').expect(200).expect('Hello World!')) +}) diff --git a/apps/geo-location/src/geo-location.controller.ts b/apps/geo-location/src/geo-location.controller.ts index acbee33c8..a0d5d993b 100644 --- a/apps/geo-location/src/geo-location.controller.ts +++ b/apps/geo-location/src/geo-location.controller.ts @@ -1,7 +1,7 @@ -import { Controller } from '@nestjs/common'; -import { GeoLocationService } from './geo-location.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { CountryInterface, StateInterface, CityInterface } from '@credebl/common/interfaces/geolocation.interface'; +import type { CityInterface, CountryInterface, StateInterface } from '@credebl/common/interfaces/geolocation.interface' +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { GeoLocationService } from './geo-location.service' @Controller() export class GeoLocationController { @@ -9,16 +9,16 @@ export class GeoLocationController { @MessagePattern({ cmd: 'get-all-countries' }) async getAllCountries(): Promise { - return this.geoLocationService.getAllCountries(); + return this.geoLocationService.getAllCountries() } @MessagePattern({ cmd: 'get-all-states' }) async getStatesByCountryId(payload: { countryId: number }): Promise { - return this.geoLocationService.getStatesByCountryId(payload.countryId); + return this.geoLocationService.getStatesByCountryId(payload.countryId) } @MessagePattern({ cmd: 'get-all-cities' }) async getCitiesByStateAndCountry(payload: { countryId: number; stateId: number }): Promise { - return this.geoLocationService.getCitiesByStateAndCountry(payload.countryId, payload.stateId); + return this.geoLocationService.getCitiesByStateAndCountry(payload.countryId, payload.stateId) } } diff --git a/apps/geo-location/src/geo-location.module.ts b/apps/geo-location/src/geo-location.module.ts index f664a861f..8839dc013 100644 --- a/apps/geo-location/src/geo-location.module.ts +++ b/apps/geo-location/src/geo-location.module.ts @@ -1,17 +1,17 @@ -import { Logger, Module } from '@nestjs/common'; -import { GeoLocationController } from './geo-location.controller'; -import { GeoLocationService } from './geo-location.service'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { CommonModule } from '@credebl/common'; -import { CacheModule } from '@nestjs/cache-manager'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { PrismaService } from '@credebl/prisma-service'; -import { GeoLocationRepository } from './geo-location.repository'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; +import { CommonModule } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { CacheModule } from '@nestjs/cache-manager' +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { GeoLocationController } from './geo-location.controller' +import { GeoLocationRepository } from './geo-location.repository' +import { GeoLocationService } from './geo-location.service' @Module({ imports: [ @@ -19,15 +19,17 @@ import { ContextInterceptorModule } from '@credebl/context/contextInterceptorMod { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.GEO_LOCATION_SERVICE, process.env.GEOLOCATION_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.GEO_LOCATION_SERVICE, process.env.GEOLOCATION_NKEY_SEED), + }, ]), CommonModule, GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, - CacheModule.register() + LoggerModule, + PlatformConfig, + ContextInterceptorModule, + CacheModule.register(), ], controllers: [GeoLocationController], - providers: [GeoLocationService, Logger, PrismaService, GeoLocationRepository] + providers: [GeoLocationService, Logger, PrismaService, GeoLocationRepository], }) export class GeoLocationModule {} diff --git a/apps/geo-location/src/geo-location.repository.ts b/apps/geo-location/src/geo-location.repository.ts index 404fd8a9b..2b3911007 100644 --- a/apps/geo-location/src/geo-location.repository.ts +++ b/apps/geo-location/src/geo-location.repository.ts @@ -1,6 +1,6 @@ -import { CountryInterface, StateInterface, CityInterface } from '@credebl/common/interfaces/geolocation.interface'; -import { PrismaService } from '@credebl/prisma-service'; -import { Injectable, Logger } from '@nestjs/common'; +import type { CityInterface, CountryInterface, StateInterface } from '@credebl/common/interfaces/geolocation.interface' +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, type Logger } from '@nestjs/common' @Injectable() export class GeoLocationRepository { @@ -14,12 +14,12 @@ export class GeoLocationRepository { return await this.prisma.countries.findMany({ select: { id: true, - name: true - } - }); + name: true, + }, + }) } catch (error) { - this.logger.error(`Error in GeoLocationRepository::[findAllCountries]: ${error}`); - throw error; + this.logger.error(`Error in GeoLocationRepository::[findAllCountries]: ${error}`) + throw error } } async findStatesByCountryId(countryId: number): Promise { @@ -30,12 +30,12 @@ export class GeoLocationRepository { id: true, name: true, countryId: true, - countryCode: true - } - }); + countryCode: true, + }, + }) } catch (error) { - this.logger.error(`Error in GeoLocationRepository::[findStatesByCountryId]: ${error} `); - throw error; + this.logger.error(`Error in GeoLocationRepository::[findStatesByCountryId]: ${error} `) + throw error } } @@ -44,7 +44,7 @@ export class GeoLocationRepository { return await this.prisma.cities.findMany({ where: { stateId: Number(stateId), - countryId: Number(countryId) + countryId: Number(countryId), }, select: { id: true, @@ -52,12 +52,12 @@ export class GeoLocationRepository { stateId: true, stateCode: true, countryId: true, - countryCode: true - } - }); + countryCode: true, + }, + }) } catch (error) { - this.logger.error(`Error finding cities for stateId ${stateId} and countryId ${countryId}: ${error}`); - throw error; + this.logger.error(`Error finding cities for stateId ${stateId} and countryId ${countryId}: ${error}`) + throw error } } } diff --git a/apps/geo-location/src/geo-location.service.ts b/apps/geo-location/src/geo-location.service.ts index b3a40c8fe..cfd77865d 100644 --- a/apps/geo-location/src/geo-location.service.ts +++ b/apps/geo-location/src/geo-location.service.ts @@ -1,8 +1,8 @@ -import { Injectable, Logger, NotFoundException } from '@nestjs/common'; -import { RpcException } from '@nestjs/microservices'; -import { CountryInterface, StateInterface, CityInterface } from '@credebl/common/interfaces/geolocation.interface'; -import { GeoLocationRepository } from './geo-location.repository'; -import { ResponseMessages } from '@credebl/common/response-messages'; +import type { CityInterface, CountryInterface, StateInterface } from '@credebl/common/interfaces/geolocation.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Injectable, type Logger, NotFoundException } from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' +import type { GeoLocationRepository } from './geo-location.repository' @Injectable() export class GeoLocationService { @@ -13,11 +13,11 @@ export class GeoLocationService { async getAllCountries(): Promise { try { - this.logger.log(`Inside Service: finding all countries,GeoLocationService::getAllCountries`); - return this.geoLocationRepository.findAllCountries(); + this.logger.log('Inside Service: finding all countries,GeoLocationService::getAllCountries') + return this.geoLocationRepository.findAllCountries() } catch (error) { - this.logger.error(`[getAllCountries] - error in get all countries:: ${JSON.stringify(error)}`); - throw new RpcException(error); + this.logger.error(`[getAllCountries] - error in get all countries:: ${JSON.stringify(error)}`) + throw new RpcException(error) } } @@ -25,16 +25,16 @@ export class GeoLocationService { try { this.logger.log( `Inside Service: finding all states for countryId= ${countryId},GeoLocationService::getStatesByCountryId` - ); - const states = await this.geoLocationRepository.findStatesByCountryId(countryId); + ) + const states = await this.geoLocationRepository.findStatesByCountryId(countryId) if (!states.length) { - throw new NotFoundException(ResponseMessages.geolocation.error.stateNotFound); + throw new NotFoundException(ResponseMessages.geolocation.error.stateNotFound) } - return states; + return states } catch (error) { - this.logger.error(`[getStatesByCountryId] - error in get states by countryId:: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[getStatesByCountryId] - error in get states by countryId:: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -42,17 +42,17 @@ export class GeoLocationService { try { this.logger.log( `Inside Service: finding all cities for stateId= ${stateId} and countryId= ${countryId},GeoLocationService::getCitiesByStateAndCountry` - ); - const cities = await this.geoLocationRepository.findCitiesByStateAndCountry(countryId, stateId); + ) + const cities = await this.geoLocationRepository.findCitiesByStateAndCountry(countryId, stateId) if (!cities.length) { - throw new NotFoundException(ResponseMessages.geolocation.error.citiesNotFound); + throw new NotFoundException(ResponseMessages.geolocation.error.citiesNotFound) } - return cities; + return cities } catch (error) { this.logger.error( `[getCitiesByStateAndCountry] - error in get cities by using countryId and stateId:: ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } } diff --git a/apps/geo-location/src/main.ts b/apps/geo-location/src/main.ts index 0e01892c0..9e108ce9f 100644 --- a/apps/geo-location/src/main.ts +++ b/apps/geo-location/src/main.ts @@ -1,23 +1,23 @@ -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { NestFactory } from '@nestjs/core'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { GeoLocationModule } from './geo-location.module'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { GeoLocationModule } from './geo-location.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { const app = await NestFactory.createMicroservice(GeoLocationModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.GEO_LOCATION_SERVICE, process.env.GEOLOCATION_NKEY_SEED) - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.GEO_LOCATION_SERVICE, process.env.GEOLOCATION_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Geolocation Microservice is listening to NATS '); + await app.listen() + logger.log('Geolocation Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/issuance/enum/issuance.enum.ts b/apps/issuance/enum/issuance.enum.ts index aa09cabc9..34a072c3a 100644 --- a/apps/issuance/enum/issuance.enum.ts +++ b/apps/issuance/enum/issuance.enum.ts @@ -1,6 +1,6 @@ export enum SortFields { - CREATED_DATE_TIME = 'createDateTime', - SCHEMA_ID = 'schemaId', - CONNECTION_ID = 'connectionId', - STATE = 'state' -} \ No newline at end of file + CREATED_DATE_TIME = 'createDateTime', + SCHEMA_ID = 'schemaId', + CONNECTION_ID = 'connectionId', + STATE = 'state', +} diff --git a/apps/issuance/interfaces/issuance.interfaces.ts b/apps/issuance/interfaces/issuance.interfaces.ts index 6fb847924..3e4d22a7c 100644 --- a/apps/issuance/interfaces/issuance.interfaces.ts +++ b/apps/issuance/interfaces/issuance.interfaces.ts @@ -1,405 +1,405 @@ // eslint-disable-next-line camelcase -import { AutoAccept, SchemaType } from '@credebl/enum/enum'; -import { Prisma, organisation } from '@prisma/client'; +import type { AutoAccept, SchemaType } from '@credebl/enum/enum' +import type { Prisma, organisation } from '@prisma/client' -import { IPrettyVc } from '@credebl/common/interfaces/issuance.interface'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { IUserRequestInterface } from 'apps/agent-service/src/interface/agent-service.interface'; -import { IssueCredentialType } from 'apps/api-gateway/src/issuance/interfaces'; +import type { IPrettyVc } from '@credebl/common/interfaces/issuance.interface' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import type { IUserRequestInterface } from 'apps/agent-service/src/interface/agent-service.interface' +import type { IssueCredentialType } from 'apps/api-gateway/src/issuance/interfaces' export interface IAttributes { - attributeName: string; - name: string; - value: string; - isRequired?: boolean; + attributeName: string + name: string + value: string + isRequired?: boolean } interface ICredentialsAttributes { - connectionId: string; - attributes: IAttributes[]; - credential?: ICredential; - options?: IOptions; + connectionId: string + attributes: IAttributes[] + credential?: ICredential + options?: IOptions } export interface IIssuance { - user?: IUserRequest; - credentialDefinitionId: string; - comment?: string; - credentialData: ICredentialsAttributes[]; - orgId: string; - autoAcceptCredential?: AutoAccept; - protocolVersion?: string; - goalCode?: string; - parentThreadId?: string; - willConfirm?: boolean; - label?: string; - credentialType: string; - isValidateSchema?: string; + user?: IUserRequest + credentialDefinitionId: string + comment?: string + credentialData: ICredentialsAttributes[] + orgId: string + autoAcceptCredential?: AutoAccept + protocolVersion?: string + goalCode?: string + parentThreadId?: string + willConfirm?: boolean + label?: string + credentialType: string + isValidateSchema?: string } interface IIndy { - attributes: IAttributes[]; - credentialDefinitionId: string; + attributes: IAttributes[] + credentialDefinitionId: string } export interface IIssueData { - protocolVersion?: string; - connectionId: string; + protocolVersion?: string + connectionId: string credentialFormats: { - indy: IIndy; - }; - autoAcceptCredential: string; - comment?: string; + indy: IIndy + } + autoAcceptCredential: string + comment?: string } interface ICredentialAttribute { - 'mime-type': string; - name: string; - value: string; + 'mime-type': string + name: string + value: string } export interface ICreateOfferResponse { _tags?: { - connectionId: string; - state: string; - threadId: string; - }; + connectionId: string + state: string + threadId: string + } metadata?: { '_anoncreds/credential'?: { - schemaId: string; - credentialDefinitionId: string; - }; - }; - credentials?: unknown[]; - id: string; - createdAt: string; - state: string; - connectionId: string; - threadId: string; - protocolVersion: string; - credentialAttributes?: ICredentialAttribute[]; - autoAcceptCredential?: string; - contextCorrelationId?: string; + schemaId: string + credentialDefinitionId: string + } + } + credentials?: unknown[] + id: string + createdAt: string + state: string + connectionId: string + threadId: string + protocolVersion: string + credentialAttributes?: ICredentialAttribute[] + autoAcceptCredential?: string + contextCorrelationId?: string } export interface IIssueCredentials { - issuedCredentialsSearchCriteria: IIssuedCredentialsSearchCriteria; - user: IUserRequest; - orgId: string; + issuedCredentialsSearchCriteria: IIssuedCredentialsSearchCriteria + user: IUserRequest + orgId: string } export interface IPattern { - cmd: string; + cmd: string } export interface ISendOfferNatsPayload { - issueData: IIssueData; - url: string; - apiKey?: string; - orgId?: string; + issueData: IIssueData + url: string + apiKey?: string + orgId?: string } export interface IIssueCredentialsDefinitions { - user: IUserRequest; - credentialRecordId: string; - orgId: string; + user: IUserRequest + credentialRecordId: string + orgId: string } export interface IIssuanceWebhookInterface { - createDateTime: string; - connectionId: string; - threadId: string; - protocolVersion: string; - credentialAttributes: ICredentialAttributesInterface[]; - orgId: string; - schemaId: string; - credDefId: string; - id: string; - state: string; - contextCorrelationId: string; - metadata: Metadata; + createDateTime: string + connectionId: string + threadId: string + protocolVersion: string + credentialAttributes: ICredentialAttributesInterface[] + orgId: string + schemaId: string + credDefId: string + id: string + state: string + contextCorrelationId: string + metadata: Metadata } interface Metadata { - '_anoncreds/credential': AnoncredsMetadata; + '_anoncreds/credential': AnoncredsMetadata } interface AnoncredsMetadata { - schemaId?: string; - credentialDefinitionId?: string; + schemaId?: string + credentialDefinitionId?: string } export interface IssueCredentialWebhookPayload { - issueCredentialDto: IIssuanceWebhookInterface; - id: string; + issueCredentialDto: IIssuanceWebhookInterface + id: string } export interface ICredentialAttributesInterface { - 'mime-type': string; - name: string; - value: string; + 'mime-type': string + name: string + value: string } export interface ICredential { - '@context': []; - type: string[]; - prettyVc?: IPrettyVc; + '@context': [] + type: string[] + prettyVc?: IPrettyVc issuer?: { - id: string; - }; - issuanceDate?: string; - credentialSubject?: ICredentialSubject; + id: string + } + issuanceDate?: string + credentialSubject?: ICredentialSubject } interface ICredentialSubject { - [key: string]: string; + [key: string]: string } export interface IOptions { - proofType: string; - proofPurpose: string; + proofType: string + proofPurpose: string } export interface CredentialOffer { - emailId: string; - attributes: IAttributes[]; - credential?: ICredential; - options?: IOptions; + emailId: string + attributes: IAttributes[] + credential?: ICredential + options?: IOptions } export interface OutOfBandCredentialOfferPayload { - credentialDefinitionId?: string; - orgId: string; - comment?: string; - credentialOffer?: CredentialOffer[]; - emailId?: string; - attributes?: IAttributes[]; - protocolVersion?: string; - isReuseConnection?: boolean; - goalCode?: string; - parentThreadId?: string; - willConfirm?: boolean; - label?: string; - imageUrl?: string; - autoAcceptCredential?: string; - credentialType?: IssueCredentialType; - isValidateSchema?: boolean; + credentialDefinitionId?: string + orgId: string + comment?: string + credentialOffer?: CredentialOffer[] + emailId?: string + attributes?: IAttributes[] + protocolVersion?: string + isReuseConnection?: boolean + goalCode?: string + parentThreadId?: string + willConfirm?: boolean + label?: string + imageUrl?: string + autoAcceptCredential?: string + credentialType?: IssueCredentialType + isValidateSchema?: boolean } export interface OutOfBandCredentialOffer { - user: IUserRequest; - outOfBandCredentialDto: OutOfBandCredentialOfferPayload; + user: IUserRequest + outOfBandCredentialDto: OutOfBandCredentialOfferPayload } export interface SchemaDetails { - credentialDefinitionId?: string; - tag?: string; - schemaLedgerId: string; - attributes: string; - name?: string; + credentialDefinitionId?: string + tag?: string + schemaLedgerId: string + attributes: string + name?: string } export interface ImportFileDetails { - templateId: string; - fileKey: string; - fileName: string; - type: string; - isValidateSchema?: boolean; + templateId: string + fileKey: string + fileName: string + type: string + isValidateSchema?: boolean } export interface ICredentialPayload { - schemaLedgerId: string; - credentialDefinitionId: string; - fileData: object; - fileName: string; - credentialType: string; - schemaName?: string; + schemaLedgerId: string + credentialDefinitionId: string + fileData: object + fileName: string + credentialType: string + schemaName?: string } export interface PreviewRequest { - pageNumber: number; - pageSize: number; - searchByText: string; - sortField?: string; - sortBy?: string; + pageNumber: number + pageSize: number + searchByText: string + sortField?: string + sortBy?: string } export interface FileUpload { - name?: string; - upload_type?: string; - status?: string; - orgId?: string; - createDateTime?: Date | null; - lastChangedDateTime?: Date | null; - credentialType?: string; - templateId?: string; + name?: string + upload_type?: string + status?: string + orgId?: string + createDateTime?: Date | null + lastChangedDateTime?: Date | null + credentialType?: string + templateId?: string } export interface FileUploadData { - fileUpload: string; - fileRow: string; - isError: boolean; - referenceId: string; - createDateTime: Date; - error?: string; - detailError?: string; - jobId: string; + fileUpload: string + fileRow: string + isError: boolean + referenceId: string + createDateTime: Date + error?: string + detailError?: string + jobId: string } export interface IClientDetails { - clientId: string; - userId?: string; - isSelectiveIssuance?: boolean; - fileName?: string; - organizationLogoUrl?: string; - platformName?: string; - certificate?: string; - size?: string; - orientation?: string; - height?: string; - width?: string; + clientId: string + userId?: string + isSelectiveIssuance?: boolean + fileName?: string + organizationLogoUrl?: string + platformName?: string + certificate?: string + size?: string + orientation?: string + height?: string + width?: string } export interface IIssuedCredentialsSearchInterface { - issuedCredentialsSearchCriteria: IIssuedCredentialsSearchCriteria; - user: IUserRequestInterface; - orgId: string; + issuedCredentialsSearchCriteria: IIssuedCredentialsSearchCriteria + user: IUserRequestInterface + orgId: string } export interface IIssuedCredentialsSearchCriteria { - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - search: string; - user?: IUserRequestInterface; + pageNumber: number + pageSize: number + sortField: string + sortBy: string + search: string + user?: IUserRequestInterface } export interface OrgAgent { - organisation: organisation; - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - orgDid: string; - verkey: string; - agentEndPoint: string; - agentId: string; - isDidPublic: boolean; - ledgerId: string; - orgAgentTypeId: string; - tenantId: string; + organisation: organisation + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + orgDid: string + verkey: string + agentEndPoint: string + agentId: string + isDidPublic: boolean + ledgerId: string + orgAgentTypeId: string + tenantId: string } export interface SendEmailCredentialOffer { - iterator: CredentialOffer; - emailId: string; - index: number; - credentialType: IssueCredentialType; - protocolVersion: string; - isReuseConnection?: boolean; - attributes: IAttributes[]; - credentialDefinitionId: string; - outOfBandCredential: OutOfBandCredentialOfferPayload; - comment: string; - organisation: organisation; - errors; - url: string; - orgId: string; - organizationDetails: organisation; - platformName?: string; - organizationLogoUrl?: string; - prettyVc?: IPrettyVc; - isValidateSchema?: boolean; + iterator: CredentialOffer + emailId: string + index: number + credentialType: IssueCredentialType + protocolVersion: string + isReuseConnection?: boolean + attributes: IAttributes[] + credentialDefinitionId: string + outOfBandCredential: OutOfBandCredentialOfferPayload + comment: string + organisation: organisation + errors + url: string + orgId: string + organizationDetails: organisation + platformName?: string + organizationLogoUrl?: string + prettyVc?: IPrettyVc + isValidateSchema?: boolean } export interface TemplateDetailsInterface { - templateId?: string; - schemaType?: SchemaType; + templateId?: string + schemaType?: SchemaType } interface CredentialData { - email_identifier: string; - [key: string]: string; + email_identifier: string + [key: string]: string } export interface IJobDetails { - id: string; - schemaName: string; - cacheId?: string; - clientId?: string; - referenceId: string | null; - fileUploadId: string; - schemaLedgerId: string; - credentialDefinitionId?: string; - status?: boolean; - credential_data: CredentialData; - orgId: string; - credentialType: string; + id: string + schemaName: string + cacheId?: string + clientId?: string + referenceId: string | null + fileUploadId: string + schemaLedgerId: string + credentialDefinitionId?: string + status?: boolean + credential_data: CredentialData + orgId: string + credentialType: string } export interface IQueuePayload { - id: string; - jobId: string; - cacheId?: string; - isValidateSchema?: boolean; - clientId: string; - referenceId: string; - fileUploadId: string; - schemaLedgerId: string; - credentialDefinitionId: string; - status: string; - credential_data: CredentialData; - orgId: string; - credentialType: string; - totalJobs: number; - isRetry: boolean; - isLastData: boolean; - organizationLogoUrl?: string; - platformName?: string; - certificate?: string; - size?: string; - orientation?: string; - height?: string; - width?: string; - isReuseConnection?: boolean; + id: string + jobId: string + cacheId?: string + isValidateSchema?: boolean + clientId: string + referenceId: string + fileUploadId: string + schemaLedgerId: string + credentialDefinitionId: string + status: string + credential_data: CredentialData + orgId: string + credentialType: string + totalJobs: number + isRetry: boolean + isLastData: boolean + organizationLogoUrl?: string + platformName?: string + certificate?: string + size?: string + orientation?: string + height?: string + width?: string + isReuseConnection?: boolean } interface FileDetails { - schemaLedgerId: string; - credentialDefinitionId: string; - fileData: object; - fileName: string; - credentialType: string; - schemaName: string; + schemaLedgerId: string + credentialDefinitionId: string + fileData: object + fileName: string + credentialType: string + schemaName: string } export interface IBulkPayloadObject { - parsedData?: unknown[]; - parsedFileDetails?: FileDetails; - userId: string; - fileUploadId: string; + parsedData?: unknown[] + parsedFileDetails?: FileDetails + userId: string + fileUploadId: string } export interface ISchemaAttributes { - attributeName: string; - schemaDataType: string; - displayName: string; - isRequired: boolean; + attributeName: string + schemaDataType: string + displayName: string + isRequired: boolean } export interface IIssuanceAttributes { - [key: string]: string; + [key: string]: string } export interface IDeletedFileUploadRecords { - deleteFileDetails: Prisma.BatchPayload; - deleteFileUploadDetails: Prisma.BatchPayload; + deleteFileDetails: Prisma.BatchPayload + deleteFileUploadDetails: Prisma.BatchPayload } export interface BulkPayloadDetails { - clientId: string; - orgId: string; - requestId?: string; - isValidateSchema?: boolean; - isRetry: boolean; - organizationLogoUrl?: string; - platformName?: string; - certificate?: string; - size?: string; - orientation?: string; - height?: string; - width?: string; + clientId: string + orgId: string + requestId?: string + isValidateSchema?: boolean + isRetry: boolean + organizationLogoUrl?: string + platformName?: string + certificate?: string + size?: string + orientation?: string + height?: string + width?: string } export interface ISchemaId { - schemaLedgerId: string; + schemaLedgerId: string } diff --git a/apps/issuance/libs/helpers/attributes.extractor.ts b/apps/issuance/libs/helpers/attributes.extractor.ts index 5c62aaa93..024521b81 100644 --- a/apps/issuance/libs/helpers/attributes.extractor.ts +++ b/apps/issuance/libs/helpers/attributes.extractor.ts @@ -1,115 +1,126 @@ -import { CommonConstants } from '@credebl/common/common.constant'; -import { TemplateIdentifier } from '@credebl/enum/enum'; +import { CommonConstants } from '@credebl/common/common.constant' +import { TemplateIdentifier } from '@credebl/enum/enum' // Function for extracting attributes from nested structure export function extractAttributeNames( attributeObj, - parentKey: string = '', + parentKey = '', result: Set = new Set(), - inNestedArray: boolean = false + inNestedArray = false ): string[] { if (Array.isArray(attributeObj)) { + // biome-ignore lint/complexity/noForEach: attributeObj.forEach((item) => { - extractAttributeNames(item, parentKey, result, inNestedArray); - }); - } else if ('object' === typeof attributeObj && null !== attributeObj) { - let newParentKey = parentKey; + extractAttributeNames(item, parentKey, result, inNestedArray) + }) + } else if (typeof attributeObj === 'object' && attributeObj !== null) { + let newParentKey = parentKey + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (attributeObj.hasOwnProperty('attributeName')) { newParentKey = parentKey ? `${parentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}${attributeObj.attributeName}` - : attributeObj.attributeName; + : attributeObj.attributeName } + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (attributeObj.hasOwnProperty('items') && Array.isArray(attributeObj.items)) { // Always use index 0 for items in an array - attributeObj.items.forEach((item) => { - extractAttributeNames(item, `${newParentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}0`, result, true); - }); + // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/complexity/noForEach: + attributeObj.items.forEach((item: any) => { + extractAttributeNames(item, `${newParentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}0`, result, true) + }) + // biome-ignore lint/suspicious/noPrototypeBuiltins: } else if (attributeObj.hasOwnProperty('properties')) { + // biome-ignore lint/complexity/noForEach: Object.entries(attributeObj.properties).forEach(([key, value]) => { - const propertyKey = `${newParentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}${key}`; - extractAttributeNames(value, propertyKey, result, inNestedArray); - }); + const propertyKey = `${newParentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}${key}` + extractAttributeNames(value, propertyKey, result, inNestedArray) + }) } else { + // biome-ignore lint/complexity/noForEach: Object.entries(attributeObj).forEach(([key, value]) => { if (!['attributeName', 'items', 'properties'].includes(key)) { - extractAttributeNames(value, newParentKey, result, inNestedArray); + extractAttributeNames(value, newParentKey, result, inNestedArray) } - }); + }) } } else { - result.add(parentKey); + result.add(parentKey) } - return Array.from(result); + return Array.from(result) } // Handles both explicitly indexed arrays and implicit arrays function mergeArrayObjects(obj): void { - if (!obj || 'object' !== typeof obj) { - return; + if (!obj || typeof obj !== 'object') { + return } // First pass: Convert objects with numeric keys to arrays for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { - const value = obj[key]; + const value = obj[key] // Skip non-objects - if (!value || 'object' !== typeof value) { - continue; + if (!value || typeof value !== 'object') { + continue } // Process arrays if (Array.isArray(value)) { + // biome-ignore lint/complexity/noForEach: value.forEach((item) => { - if (item && 'object' === typeof item) { - mergeArrayObjects(item); + if (item && typeof item === 'object') { + mergeArrayObjects(item) } - }); + }) } else { // Process objects // Check if this object has numeric keys - const keys = Object.keys(value); - const numericKeys = keys.filter((k) => /^\d+$/.test(k)); + const keys = Object.keys(value) + const numericKeys = keys.filter((k) => /^\d+$/.test(k)) - if (0 < numericKeys.length) { + if (numericKeys.length > 0) { // Has numeric keys - convert to array - const tempArray = []; + const tempArray = [] // First, add all numeric keys to the array + // biome-ignore lint/complexity/noForEach: numericKeys - .sort((a, b) => parseInt(a) - parseInt(b)) + .sort((a, b) => Number.parseInt(a) - Number.parseInt(b)) .forEach((k) => { - const index = parseInt(k); - tempArray[index] = value[k]; + const index = Number.parseInt(k) + tempArray[index] = value[k] // Process recursively - if (value[k] && 'object' === typeof value[k]) { - mergeArrayObjects(value[k]); + if (value[k] && typeof value[k] === 'object') { + mergeArrayObjects(value[k]) } - }); + }) // Then add all non-numeric keys to every array element - const nonNumericKeys = keys.filter((k) => !/^\d+$/.test(k)); - if (0 < nonNumericKeys.length) { + const nonNumericKeys = keys.filter((k) => !/^\d+$/.test(k)) + if (nonNumericKeys.length > 0) { tempArray.forEach((item, index) => { - if (!item || 'object' !== typeof item) { - tempArray[index] = {}; + if (!item || typeof item !== 'object') { + tempArray[index] = {} } + // biome-ignore lint/complexity/noForEach: nonNumericKeys.forEach((k) => { - tempArray[index][k] = value[k]; - }); - }); + tempArray[index][k] = value[k] + }) + }) } // Replace the object with our array - obj[key] = tempArray; + obj[key] = tempArray } else { // No numeric keys - process recursively - mergeArrayObjects(value); + mergeArrayObjects(value) } } } @@ -120,47 +131,50 @@ function mergeArrayObjects(obj): void { if (Object.prototype.hasOwnProperty.call(obj, key)) { if (Array.isArray(obj[key])) { // Look for patterns like "field1", "field2" in each array element + // biome-ignore lint/complexity/noForEach: obj[key].forEach((item) => { - if (item && 'object' === typeof item) { - const keys = Object.keys(item); - const prefixMap = new Map(); + if (item && typeof item === 'object') { + const keys = Object.keys(item) + const prefixMap = new Map() // Group keys by prefix + // biome-ignore lint/complexity/noForEach: keys.forEach((k) => { - const match = k.match(/^([^0-9]+)(\d{1,10})$/); + const match = k.match(/^([^0-9]+)(\d{1,10})$/) if (match) { // eslint-disable-next-line prefer-destructuring - const prefix = match[1]; - const index = parseInt(match[2]); + const prefix = match[1] + const index = Number.parseInt(match[2]) if (!prefixMap.has(prefix)) { - prefixMap.set(prefix, []); + prefixMap.set(prefix, []) } - prefixMap.get(prefix).push({ key: k, index }); + prefixMap.get(prefix).push({ key: k, index }) } - }); + }) // Convert grouped prefixes to arrays for (const [prefix, matches] of prefixMap.entries()) { - if (0 < matches.length) { - const tempArray = []; + if (matches.length > 0) { + const tempArray = [] // Sort by index and populate array + // biome-ignore lint/complexity/noForEach: matches .sort((a, b) => a.index - b.index) .forEach((match) => { - tempArray[match.index] = item[match.key]; - delete item[match.key]; - }); + tempArray[match.index] = item[match.key] + delete item[match.key] + }) // Set the array on the item - item[prefix] = tempArray; + item[prefix] = tempArray } } // Process recursively - mergeArrayObjects(item); + mergeArrayObjects(item) } - }); + }) } } } @@ -168,102 +182,100 @@ function mergeArrayObjects(obj): void { // Helper function to process remaining parts of a key path function processRemainingParts(obj, parts: string[], value): void { - let current = obj; + let current = obj for (let i = 0; i < parts.length; i++) { - const part = parts[i]; + const part = parts[i] // If this is the last part, set the value if (i === parts.length - 1) { - current[part] = value; - return; + current[part] = value + return } // Check if next part is a number (array index) - const isNextPartNumeric = i < parts.length - 1 && !isNaN(Number(parts[i + 1])); + const isNextPartNumeric = i < parts.length - 1 && !Number.isNaN(Number(parts[i + 1])) if (isNextPartNumeric) { // This is an array index, create array if needed if (!current[part]) { - current[part] = []; + current[part] = [] } - const index = parseInt(parts[i + 1]); + const index = Number.parseInt(parts[i + 1]) while (current[part].length <= index) { - current[part].push({}); + current[part].push({}) } // Update the local variable instead of the parameter - current = current[part][index]; - i++; // Skip the index part + current = current[part][index] + i++ // Skip the index part } else { // This is a regular object property if (!current[part]) { - current[part] = {}; + current[part] = {} } - current = current[part]; + current = current[part] } } } // Function to convert a flattened CSV row into a nested object export function unflattenCsvRow(row: object): object { - const result: object = {}; - const groupedKeys: Record = {}; + const result: object = {} + const groupedKeys: Record = {} // First pass: handle simple keys and identify complex keys for (const key in row) { if (Object.prototype.hasOwnProperty.call(row, key)) { // Skip empty values - if ('' === row[key]) { - continue; + if (row[key] === '') { + continue } // Handle email identifier specially if (TemplateIdentifier.EMAIL_COLUMN === key) { - result[key] = row[key]; - continue; + result[key] = row[key] + continue } - const keyParts = key.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR); + const keyParts = key.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR) // Handle array notation: key~index~otherParts - if (1 < keyParts.length && !isNaN(Number(keyParts[1]))) { - // eslint-disable-next-line prefer-destructuring - const arrayName = keyParts[0]; - // eslint-disable-next-line prefer-destructuring - const arrayIndex = keyParts[1]; - const groupKey = `${arrayName}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}${arrayIndex}`; + if (keyParts.length > 1 && !Number.isNaN(Number(keyParts[1]))) { + const arrayName = keyParts[0] + const arrayIndex = keyParts[1] + const groupKey = `${arrayName}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}${arrayIndex}` if (!groupedKeys[groupKey]) { - groupedKeys[groupKey] = []; + groupedKeys[groupKey] = [] } - groupedKeys[groupKey].push(key); + groupedKeys[groupKey].push(key) } else { // Handle implicit array notation or simple nested keys // Check if this key has any numeric part that might indicate an array - const hasArrayPart = keyParts.some((part, index) => 0 < index && !isNaN(Number(part)) && '' !== part); + const hasArrayPart = keyParts.some((part, index) => index > 0 && !Number.isNaN(Number(part)) && part !== '') if (hasArrayPart) { // Handle as potential array, but we'll process it in the second pass if (!groupedKeys[keyParts[0]]) { - groupedKeys[keyParts[0]] = []; + groupedKeys[keyParts[0]] = [] } - groupedKeys[keyParts[0]].push(key); + groupedKeys[keyParts[0]].push(key) } else { // Handle as simple nested key (no arrays) - let currentLevel = result; + let currentLevel = result for (let i = 0; i < keyParts.length; i++) { - const part = keyParts[i]; + const part = keyParts[i] if (i === keyParts.length - 1) { - currentLevel[part] = row[key]; + currentLevel[part] = row[key] } else { if (!currentLevel[part]) { - currentLevel[part] = {}; + currentLevel[part] = {} } - currentLevel = currentLevel[part]; + currentLevel = currentLevel[part] } } } @@ -274,47 +286,47 @@ export function unflattenCsvRow(row: object): object { // Second pass: process explicitly indexed arrays for (const grpKey in groupedKeys) { if (Object.prototype.hasOwnProperty.call(groupedKeys, grpKey)) { - const keys = groupedKeys[grpKey]; + const keys = groupedKeys[grpKey] // For explicit indexed arrays (format: arrayName~index~...) if (grpKey.includes(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR)) { - const [arrayName, arrayIndex] = grpKey.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR); + const [arrayName, arrayIndex] = grpKey.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR) if (!result[arrayName]) { - result[arrayName] = []; + result[arrayName] = [] } - const index = parseInt(arrayIndex); + const index = Number.parseInt(arrayIndex) while (result[arrayName].length <= index) { - result[arrayName].push({}); + result[arrayName].push({}) } for (const key of keys) { - const keyParts = key.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR); - const remainingParts = keyParts.slice(2); - const currentLevel = result[arrayName][index]; + const keyParts = key.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR) + const remainingParts = keyParts.slice(2) + const currentLevel = result[arrayName][index] - processRemainingParts(currentLevel, remainingParts, row[key]); + processRemainingParts(currentLevel, remainingParts, row[key]) } } else { // For implicit arrays (format: arrayName~field~0~...) - const arrayName = grpKey; + const arrayName = grpKey if (!result[arrayName]) { - result[arrayName] = {}; + result[arrayName] = {} } for (const key of keys) { - const keyParts = key.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR); - const remainingParts = keyParts.slice(1); - const currentLevel = result[arrayName]; + const keyParts = key.split(CommonConstants.NESTED_ATTRIBUTE_SEPARATOR) + const remainingParts = keyParts.slice(1) + const currentLevel = result[arrayName] - processRemainingParts(currentLevel, remainingParts, row[key]); + processRemainingParts(currentLevel, remainingParts, row[key]) } } } } - mergeArrayObjects(result); - return result; + mergeArrayObjects(result) + return result } diff --git a/apps/issuance/libs/helpers/attributes.validator.ts b/apps/issuance/libs/helpers/attributes.validator.ts index 78df951e9..08a5a020a 100644 --- a/apps/issuance/libs/helpers/attributes.validator.ts +++ b/apps/issuance/libs/helpers/attributes.validator.ts @@ -1,60 +1,61 @@ -import { W3CSchemaDataType } from '@credebl/enum/enum'; -import { BadRequestException } from '@nestjs/common'; -import { IIssuanceAttributes, ISchemaAttributes } from 'apps/issuance/interfaces/issuance.interfaces'; +import { W3CSchemaDataType } from '@credebl/enum/enum' +import { BadRequestException } from '@nestjs/common' +import type { IIssuanceAttributes, ISchemaAttributes } from 'apps/issuance/interfaces/issuance.interfaces' export function validateW3CSchemaAttributes( filteredIssuanceAttributes: IIssuanceAttributes, schemaUrlAttributes: ISchemaAttributes[] ): void { - const mismatchedAttributes: string[] = []; - const missingAttributes: string[] = []; - const extraAttributes: string[] = []; + const mismatchedAttributes: string[] = [] + const missingAttributes: string[] = [] + const extraAttributes: string[] = [] - const schemaAttributesSet = new Set(schemaUrlAttributes.map((attr) => attr.attributeName)); + const schemaAttributesSet = new Set(schemaUrlAttributes.map((attr) => attr.attributeName)) for (const schemaAttribute of schemaUrlAttributes) { - const { attributeName, schemaDataType, isRequired } = schemaAttribute; - const attributeValue = filteredIssuanceAttributes[attributeName]; + const { attributeName, schemaDataType, isRequired } = schemaAttribute + const attributeValue = filteredIssuanceAttributes[attributeName] if (isRequired && attributeValue === undefined) { - missingAttributes.push(`Attribute ${attributeName} is missing`); - continue; + missingAttributes.push(`Attribute ${attributeName} is missing`) + continue } if (isRequired && !attributeValue) { - mismatchedAttributes.push(`Attribute ${attributeName} must have a non-empty value`); - continue; + mismatchedAttributes.push(`Attribute ${attributeName} must have a non-empty value`) + continue } if (attributeValue !== undefined) { - const actualType = typeof attributeValue; + const actualType = typeof attributeValue // Check if the schemaDataType is 'datetime-local' and treat it as a string - if ((W3CSchemaDataType.DATE_TIME === schemaDataType && W3CSchemaDataType.STRING !== actualType) || - (W3CSchemaDataType.DATE_TIME !== schemaDataType && actualType !== schemaDataType)) { - + if ( + (W3CSchemaDataType.DATE_TIME === schemaDataType && W3CSchemaDataType.STRING !== actualType) || + (W3CSchemaDataType.DATE_TIME !== schemaDataType && actualType !== schemaDataType) + ) { mismatchedAttributes.push( `Attribute ${attributeName} has type ${actualType} but expected type ${schemaDataType}` - ); + ) } } } for (const attributeName in filteredIssuanceAttributes) { if (!schemaAttributesSet.has(attributeName)) { - extraAttributes.push(`Attribute ${attributeName} is not defined in the schema`); + extraAttributes.push(`Attribute ${attributeName} is not defined in the schema`) } } - if (0 < missingAttributes.length) { - throw new BadRequestException(`Validation failed: ${missingAttributes.join(', ')}`); + if (missingAttributes.length > 0) { + throw new BadRequestException(`Validation failed: ${missingAttributes.join(', ')}`) } - if (0 < mismatchedAttributes.length) { - throw new BadRequestException(`Validation failed: ${mismatchedAttributes.join(', ')}`); + if (mismatchedAttributes.length > 0) { + throw new BadRequestException(`Validation failed: ${mismatchedAttributes.join(', ')}`) } - if (0 < extraAttributes.length) { - throw new BadRequestException(`Validation failed: ${extraAttributes.join(', ')}`); + if (extraAttributes.length > 0) { + throw new BadRequestException(`Validation failed: ${extraAttributes.join(', ')}`) } } diff --git a/apps/issuance/src/issuance.controller.ts b/apps/issuance/src/issuance.controller.ts index a1c0ade71..a4630106d 100644 --- a/apps/issuance/src/issuance.controller.ts +++ b/apps/issuance/src/issuance.controller.ts @@ -1,4 +1,9 @@ -import { +import type { + ICredentialOfferResponse, + IDeletedIssuanceRecords, + IIssuedCredential, +} from '@credebl/common/interfaces/issuance.interface' +import type { IClientDetails, IIssuance, IIssueCredentials, @@ -7,19 +12,14 @@ import { IssueCredentialWebhookPayload, OutOfBandCredentialOffer, PreviewRequest, - TemplateDetailsInterface -} from '../interfaces/issuance.interfaces'; -import { - ICredentialOfferResponse, - IDeletedIssuanceRecords, - IIssuedCredential -} from '@credebl/common/interfaces/issuance.interface'; + TemplateDetailsInterface, +} from '../interfaces/issuance.interfaces' -import { Controller } from '@nestjs/common'; -import { IssuanceService } from './issuance.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { OOBIssueCredentialDto } from 'apps/api-gateway/src/issuance/dtos/issuance.dto'; -import { user } from '@prisma/client'; +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { user } from '@prisma/client' +import type { OOBIssueCredentialDto } from 'apps/api-gateway/src/issuance/dtos/issuance.dto' +import type { IssuanceService } from './issuance.service' @Controller() export class IssuanceController { @@ -27,78 +27,78 @@ export class IssuanceController { @MessagePattern({ cmd: 'get-issuance-records' }) async getIssuanceRecordsByOrgId(payload: { orgId: string; userId: string }): Promise { - const { orgId } = payload; - return this.issuanceService.getIssuanceRecords(orgId); + const { orgId } = payload + return this.issuanceService.getIssuanceRecords(orgId) } @MessagePattern({ cmd: 'send-credential-create-offer' }) async sendCredentialCreateOffer(payload: IIssuance): Promise { - return this.issuanceService.sendCredentialCreateOffer(payload); + return this.issuanceService.sendCredentialCreateOffer(payload) } @MessagePattern({ cmd: 'send-credential-create-offer-oob' }) async sendCredentialOutOfBand(payload: OOBIssueCredentialDto): Promise<{ response: object }> { - return this.issuanceService.sendCredentialOutOfBand(payload); + return this.issuanceService.sendCredentialOutOfBand(payload) } @MessagePattern({ cmd: 'get-all-issued-credentials' }) async getIssueCredentials(payload: IIssueCredentials): Promise { - const { user, orgId, issuedCredentialsSearchCriteria } = payload; - return this.issuanceService.getIssueCredentials(user, orgId, issuedCredentialsSearchCriteria); + const { user, orgId, issuedCredentialsSearchCriteria } = payload + return this.issuanceService.getIssueCredentials(user, orgId, issuedCredentialsSearchCriteria) } @MessagePattern({ cmd: 'get-issued-credentials-by-credentialDefinitionId' }) async getIssueCredentialsbyCredentialRecordId(payload: IIssueCredentialsDefinitions): Promise { - const { user, credentialRecordId, orgId } = payload; - return this.issuanceService.getIssueCredentialsbyCredentialRecordId(user, credentialRecordId, orgId); + const { user, credentialRecordId, orgId } = payload + return this.issuanceService.getIssueCredentialsbyCredentialRecordId(user, credentialRecordId, orgId) } @MessagePattern({ cmd: 'webhook-get-issue-credential' }) async getIssueCredentialWebhook(payload: IssueCredentialWebhookPayload): Promise { - return this.issuanceService.getIssueCredentialWebhook(payload); + return this.issuanceService.getIssueCredentialWebhook(payload) } @MessagePattern({ cmd: 'out-of-band-credential-offer' }) async outOfBandCredentialOffer(payload: OutOfBandCredentialOffer): Promise { - const { outOfBandCredentialDto } = payload; - return this.issuanceService.outOfBandCredentialOffer(outOfBandCredentialDto); + const { outOfBandCredentialDto } = payload + return this.issuanceService.outOfBandCredentialOffer(outOfBandCredentialDto) } @MessagePattern({ cmd: 'download-csv-template-for-bulk-operation' }) async downloadBulkIssuanceCSVTemplate(payload: { - orgId: string; - templateDetails: TemplateDetailsInterface; + orgId: string + templateDetails: TemplateDetailsInterface }): Promise { - const { orgId, templateDetails } = payload; - return this.issuanceService.downloadBulkIssuanceCSVTemplate(orgId, templateDetails); + const { orgId, templateDetails } = payload + return this.issuanceService.downloadBulkIssuanceCSVTemplate(orgId, templateDetails) } @MessagePattern({ cmd: 'upload-csv-template' }) async uploadCSVTemplate(payload: { importFileDetails: ImportFileDetails; orgId: string }): Promise { - return this.issuanceService.uploadCSVTemplate(payload.importFileDetails, payload.orgId); + return this.issuanceService.uploadCSVTemplate(payload.importFileDetails, payload.orgId) } @MessagePattern({ cmd: 'preview-csv-details' }) async previewCSVDetails(payload: { requestId: string; previewFileDetails: PreviewRequest }): Promise { - return this.issuanceService.previewFileDataForIssuance(payload.requestId, payload.previewFileDetails); + return this.issuanceService.previewFileDataForIssuance(payload.requestId, payload.previewFileDetails) } @MessagePattern({ cmd: 'issued-file-details' }) async issuedFiles(payload: { orgId: string; fileParameter: PreviewRequest }): Promise { - return this.issuanceService.issuedFileDetails(payload.orgId, payload.fileParameter); + return this.issuanceService.issuedFileDetails(payload.orgId, payload.fileParameter) } @MessagePattern({ cmd: 'issued-file-data' }) async getFileDetailsByFileId(payload: { fileId: string; fileParameter: PreviewRequest }): Promise { - return this.issuanceService.getFileDetailsByFileId(payload.fileId, payload.fileParameter); + return this.issuanceService.getFileDetailsByFileId(payload.fileId, payload.fileParameter) } @MessagePattern({ cmd: 'issue-bulk-credentials' }) async issueBulkCredentials(payload: { - requestId: string; - orgId: string; - clientDetails: IClientDetails; - reqPayload: ImportFileDetails; - isValidateSchema: boolean; + requestId: string + orgId: string + clientDetails: IClientDetails + reqPayload: ImportFileDetails + isValidateSchema: boolean }): Promise { return this.issuanceService.issueBulkCredential( payload.requestId, @@ -106,31 +106,31 @@ export class IssuanceController { payload.clientDetails, payload.reqPayload, payload.isValidateSchema - ); + ) } @MessagePattern({ cmd: 'retry-bulk-credentials' }) async retryeBulkCredentials(payload: { - fileId: string; - orgId: string; - clientDetails: IClientDetails; - isValidateSchema?: boolean; + fileId: string + orgId: string + clientDetails: IClientDetails + isValidateSchema?: boolean }): Promise { return this.issuanceService.retryBulkCredential( payload.fileId, payload.orgId, payload.clientDetails, payload.isValidateSchema - ); + ) } @MessagePattern({ cmd: 'delete-issuance-records' }) async deleteIssuanceRecords(payload: { orgId: string; userDetails: user }): Promise { - const { orgId, userDetails } = payload; - return this.issuanceService.deleteIssuanceRecords(orgId, userDetails); + const { orgId, userDetails } = payload + return this.issuanceService.deleteIssuanceRecords(orgId, userDetails) } @MessagePattern({ cmd: 'issued-file-data-and-file-details' }) async getFileDetailsAndFileDataByFileId(payload: { fileId: string; orgId: string }): Promise { - return this.issuanceService.getFileDetailsAndFileDataByFileId(payload.fileId, payload.orgId); + return this.issuanceService.getFileDetailsAndFileDataByFileId(payload.fileId, payload.orgId) } } diff --git a/apps/issuance/src/issuance.module.ts b/apps/issuance/src/issuance.module.ts index 84886a913..e46cc0497 100644 --- a/apps/issuance/src/issuance.module.ts +++ b/apps/issuance/src/issuance.module.ts @@ -1,26 +1,26 @@ -import { CommonModule } from '@credebl/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { Logger, Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { IssuanceController } from './issuance.controller'; -import { IssuanceRepository } from './issuance.repository'; -import { IssuanceService } from './issuance.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { OutOfBandIssuance } from '../templates/out-of-band-issuance.template'; -import { EmailDto } from '@credebl/common/dtos/email.dto'; -import { BullModule } from '@nestjs/bull'; -import { CacheModule } from '@nestjs/cache-manager'; -import * as redisStore from 'cache-manager-redis-store'; -import { BulkIssuanceProcessor } from './issuance.processor'; -import { AwsService } from '@credebl/aws'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import { EmailDto } from '@credebl/common/dtos/email.dto' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { BullModule } from '@nestjs/bull' +import { CacheModule } from '@nestjs/cache-manager' +import { Logger, Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import * as redisStore from 'cache-manager-redis-store' +import { UserActivityRepository } from 'libs/user-activity/repositories' +import { OutOfBandIssuance } from '../templates/out-of-band-issuance.template' +import { IssuanceController } from './issuance.controller' +import { BulkIssuanceProcessor } from './issuance.processor' +import { IssuanceRepository } from './issuance.repository' +import { IssuanceService } from './issuance.service' @Module({ imports: [ @@ -29,8 +29,8 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.ISSUANCE_SERVICE, process.env.ISSUANCE_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.ISSUANCE_SERVICE, process.env.ISSUANCE_NKEY_SEED), + }, ]), CommonModule, GlobalConfigModule, @@ -41,12 +41,12 @@ import { NATSClient } from '@credebl/common/NATSClient'; BullModule.forRoot({ redis: { host: process.env.REDIS_HOST, - port: parseInt(process.env.REDIS_PORT) - } + port: Number.parseInt(process.env.REDIS_PORT), + }, }), BullModule.registerQueue({ - name: 'bulk-issuance' - }) + name: 'bulk-issuance', + }), ], controllers: [IssuanceController], providers: [ @@ -62,8 +62,8 @@ import { NATSClient } from '@credebl/common/NATSClient'; NATSClient, { provide: MICRO_SERVICE_NAME, - useValue: 'IssuanceService' - } - ] + useValue: 'IssuanceService', + }, + ], }) export class IssuanceModule {} diff --git a/apps/issuance/src/issuance.processor.ts b/apps/issuance/src/issuance.processor.ts index be45d2a36..c7ff9609e 100644 --- a/apps/issuance/src/issuance.processor.ts +++ b/apps/issuance/src/issuance.processor.ts @@ -1,27 +1,23 @@ -import { OnQueueActive, Process, Processor } from '@nestjs/bull'; -import { Job } from 'bull'; -import { IssuanceService } from './issuance.service'; -import { Logger } from '@nestjs/common'; -import { IQueuePayload } from '../interfaces/issuance.interfaces'; +import { OnQueueActive, Process, Processor } from '@nestjs/bull' +import { Logger } from '@nestjs/common' +import type { Job } from 'bull' +import type { IQueuePayload } from '../interfaces/issuance.interfaces' +import type { IssuanceService } from './issuance.service' @Processor('bulk-issuance') export class BulkIssuanceProcessor { - private readonly logger = new Logger('IssueCredentialService'); + private readonly logger = new Logger('IssueCredentialService') constructor(private readonly issuanceService: IssuanceService) {} @OnQueueActive() onActive(job: Job): void { - this.logger.log( - `Emitting job status${job.id} of type ${job.name} with data ${JSON.stringify(job.data)}...` - ); + this.logger.log(`Emitting job status${job.id} of type ${job.name} with data ${JSON.stringify(job.data)}...`) } @Process() - async issueCredential(job: Job):Promise { - this.logger.log( - `Processing job ${job.id} of type ${job.name} with data ${JSON.stringify(job.data)}...` - ); + async issueCredential(job: Job): Promise { + this.logger.log(`Processing job ${job.id} of type ${job.name} with data ${JSON.stringify(job.data)}...`) - this.issuanceService.processIssuanceData(job.data); + this.issuanceService.processIssuanceData(job.data) } } diff --git a/apps/issuance/src/issuance.repository.ts b/apps/issuance/src/issuance.repository.ts index c825cb96a..e94e287c6 100644 --- a/apps/issuance/src/issuance.repository.ts +++ b/apps/issuance/src/issuance.repository.ts @@ -1,17 +1,14 @@ +import { PrismaTables, SortValue } from '@credebl/enum/enum' /* eslint-disable camelcase */ -import { ConflictException, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; import { - FileUpload, - FileUploadData, - IDeletedFileUploadRecords, - IssueCredentialWebhookPayload, - OrgAgent, - PreviewRequest, - SchemaDetails -} from '../interfaces/issuance.interfaces'; -import { PrismaTables, SortValue } from '@credebl/enum/enum'; + ConflictException, + Injectable, + InternalServerErrorException, + type Logger, + NotFoundException, +} from '@nestjs/common' // eslint-disable-next-line camelcase -import { +import type { agent_invitations, credentials, file_data, @@ -19,15 +16,24 @@ import { org_agents, organisation, platform_config, - schema -} from '@prisma/client'; + schema, +} from '@prisma/client' +import type { + FileUpload, + FileUploadData, + IDeletedFileUploadRecords, + IssueCredentialWebhookPayload, + OrgAgent, + PreviewRequest, + SchemaDetails, +} from '../interfaces/issuance.interfaces' -import { FileUploadStatus } from 'apps/api-gateway/src/enum'; -import { IDeletedIssuanceRecords } from '@credebl/common/interfaces/issuance.interface'; -import { IIssuedCredentialSearchParams } from 'apps/api-gateway/src/issuance/interfaces'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { PrismaService } from '@credebl/prisma-service'; -import { ResponseMessages } from '@credebl/common/response-messages'; +import type { IDeletedIssuanceRecords } from '@credebl/common/interfaces/issuance.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import type { PrismaService } from '@credebl/prisma-service' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { FileUploadStatus } from 'apps/api-gateway/src/enum' +import type { IIssuedCredentialSearchParams } from 'apps/api-gateway/src/issuance/interfaces' @Injectable() export class IssuanceRepository { @@ -46,21 +52,21 @@ export class IssuanceRepository { try { const agentDetails = await this.prisma.org_agents.findFirst({ where: { - orgId + orgId, }, include: { - organisation: true - } - }); + organisation: true, + }, + }) if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - return agentDetails; + return agentDetails } catch (error) { - this.logger.error(`Error in get getAgentEndPoint: ${error.message} `); - throw error; + this.logger.error(`Error in get getAgentEndPoint: ${error.message} `) + throw error } } @@ -68,13 +74,13 @@ export class IssuanceRepository { try { const issuanceRecordsCount = await this.prisma.credentials.count({ where: { - orgId - } - }); - return issuanceRecordsCount; + orgId, + }, + }) + return issuanceRecordsCount } catch (error) { - this.logger.error(`[get issuance records by org Id] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[get issuance records by org Id] - error: ${JSON.stringify(error)}`) + throw error } } @@ -82,12 +88,12 @@ export class IssuanceRepository { try { return this.prisma.org_agents.findFirst({ where: { - tenantId - } - }); + tenantId, + }, + }) } catch (error) { - this.logger.error(`Error in getOrganization in issuance repository: ${error.message} `); - throw error; + this.logger.error(`Error in getOrganization in issuance repository: ${error.message} `) + throw error } } @@ -95,33 +101,33 @@ export class IssuanceRepository { try { return this.prisma.agent_invitations.findMany({ where: { - orgId + orgId, }, orderBy: { - createDateTime: 'asc' - } - }); + createDateTime: 'asc', + }, + }) } catch (error) { - this.logger.error(`Error in getInvitationDid in issuance repository: ${error.message}`); - throw error; + this.logger.error(`Error in getInvitationDid in issuance repository: ${error.message}`) + throw error } } async getAllIssuedCredentials( - user: IUserRequest, + _user: IUserRequest, orgId: string, issuedCredentialsSearchCriteria: IIssuedCredentialSearchParams, schemaIds?: string[] ): Promise<{ - issuedCredentialsCount: number; + issuedCredentialsCount: number issuedCredentialsList: { - createDateTime: Date; - createdBy: string; - connectionId: string; - schemaId: string; - state: string; - orgId: string; - }[]; + createDateTime: Date + createdBy: string + connectionId: string + schemaId: string + state: string + orgId: string + }[] }> { try { const issuedCredentialsList = await this.prisma.credentials.findMany({ @@ -132,10 +138,10 @@ export class IssuanceRepository { ? { OR: [ { connectionId: { contains: issuedCredentialsSearchCriteria.search, mode: 'insensitive' } }, - { schemaId: { contains: issuedCredentialsSearchCriteria.search, mode: 'insensitive' } } - ] + { schemaId: { contains: issuedCredentialsSearchCriteria.search, mode: 'insensitive' } }, + ], } - : {}) + : {}), }, select: { credentialExchangeId: true, @@ -144,15 +150,15 @@ export class IssuanceRepository { orgId: true, state: true, schemaId: true, - connectionId: true + connectionId: true, }, orderBy: { [issuedCredentialsSearchCriteria?.sortField]: - SortValue.DESC === issuedCredentialsSearchCriteria?.sortBy ? 'desc' : 'asc' + SortValue.DESC === issuedCredentialsSearchCriteria?.sortBy ? 'desc' : 'asc', }, take: Number(issuedCredentialsSearchCriteria.pageSize), - skip: (issuedCredentialsSearchCriteria.pageNumber - 1) * issuedCredentialsSearchCriteria.pageSize - }); + skip: (issuedCredentialsSearchCriteria.pageNumber - 1) * issuedCredentialsSearchCriteria.pageSize, + }) const issuedCredentialsCount = await this.prisma.credentials.count({ where: { orgId, @@ -161,17 +167,17 @@ export class IssuanceRepository { ? { OR: [ { connectionId: { contains: issuedCredentialsSearchCriteria.search, mode: 'insensitive' } }, - { schemaId: { contains: issuedCredentialsSearchCriteria.search, mode: 'insensitive' } } - ] + { schemaId: { contains: issuedCredentialsSearchCriteria.search, mode: 'insensitive' } }, + ], } - : {}) - } - }); + : {}), + }, + }) - return { issuedCredentialsCount, issuedCredentialsList }; + return { issuedCredentialsCount, issuedCredentialsList } } catch (error) { - this.logger.error(`[getAllredentials] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getAllredentials] - error: ${JSON.stringify(error)}`) + throw error } } @@ -183,38 +189,37 @@ export class IssuanceRepository { // eslint-disable-next-line camelcase async saveIssuedCredentialDetails(payload: IssueCredentialWebhookPayload): Promise { try { - let organisationId: string; - const { issueCredentialDto, id } = payload; + let organisationId: string + const { issueCredentialDto, id } = payload - if ('default' !== issueCredentialDto?.contextCorrelationId) { - const getOrganizationId = await this.getOrganizationByTenantId(issueCredentialDto?.contextCorrelationId); - organisationId = getOrganizationId?.orgId; + if (issueCredentialDto?.contextCorrelationId !== 'default') { + const getOrganizationId = await this.getOrganizationByTenantId(issueCredentialDto?.contextCorrelationId) + organisationId = getOrganizationId?.orgId } else { - organisationId = id; + organisationId = id } - let schemaId = ''; + let schemaId = '' if ( issueCredentialDto?.metadata?.['_anoncreds/credential']?.schemaId || - issueCredentialDto?.['credentialData']?.offer?.jsonld?.credential?.['@context'][1] || - (issueCredentialDto?.state && - issueCredentialDto?.['credentialData']?.proposal?.jsonld?.credential?.['@context'][1]) + issueCredentialDto?.credentialData?.offer?.jsonld?.credential?.['@context'][1] || + (issueCredentialDto?.state && issueCredentialDto?.credentialData?.proposal?.jsonld?.credential?.['@context'][1]) ) { schemaId = issueCredentialDto?.metadata?.['_anoncreds/credential']?.schemaId || - issueCredentialDto?.['credentialData']?.offer?.jsonld?.credential?.['@context'][1] || - issueCredentialDto?.['credentialData']?.proposal?.jsonld?.credential?.['@context'][1]; + issueCredentialDto?.credentialData?.offer?.jsonld?.credential?.['@context'][1] || + issueCredentialDto?.credentialData?.proposal?.jsonld?.credential?.['@context'][1] } - let credDefId = ''; + let credDefId = '' if (issueCredentialDto?.metadata?.['_anoncreds/credential']?.credentialDefinitionId) { - credDefId = issueCredentialDto?.metadata?.['_anoncreds/credential']?.credentialDefinitionId; + credDefId = issueCredentialDto?.metadata?.['_anoncreds/credential']?.credentialDefinitionId } const credentialDetails = await this.prisma.credentials.upsert({ where: { - threadId: issueCredentialDto?.threadId + threadId: issueCredentialDto?.threadId, }, update: { lastChangedBy: organisationId, @@ -223,7 +228,7 @@ export class IssuanceRepository { connectionId: issueCredentialDto?.connectionId, state: issueCredentialDto?.state, schemaId, - credDefId + credDefId, }, create: { createDateTime: issueCredentialDto?.createDateTime, @@ -235,14 +240,14 @@ export class IssuanceRepository { schemaId, credDefId, credentialExchangeId: issueCredentialDto?.id, - orgId: organisationId - } - }); + orgId: organisationId, + }, + }) - return credentialDetails; + return credentialDetails } catch (error) { - this.logger.error(`Error in get saveIssuedCredentialDetails: ${error.message} `); - throw error; + this.logger.error(`Error in get saveIssuedCredentialDetails: ${error.message} `) + throw error } } @@ -253,10 +258,10 @@ export class IssuanceRepository { // 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 new InternalServerErrorException(error); + this.logger.error(`[getPlatformConfigDetails] - error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -266,11 +271,11 @@ export class IssuanceRepository { */ async getOrganization(orgId: string): Promise { try { - const organizationDetails = await this.prisma.organisation.findUnique({ where: { id: orgId } }); - return organizationDetails; + const organizationDetails = await this.prisma.organisation.findUnique({ where: { id: orgId } }) + return organizationDetails } catch (error) { - this.logger.error(`[getOrganization] - error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`[getOrganization] - error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -279,14 +284,14 @@ export class IssuanceRepository { //Todo: Enhance this query by using FindFirstOrThrow const schemaDetails = await this.prisma.schema.findFirst({ where: { - schemaLedgerId: schemaId - } - }); + schemaLedgerId: schemaId, + }, + }) - return schemaDetails; + return schemaDetails } catch (error) { - this.logger.error(`Error in get schema details: ${error.message}`); - throw new InternalServerErrorException(error.message); + this.logger.error(`Error in get schema details: ${error.message}`) + throw new InternalServerErrorException(error.message) } } @@ -294,18 +299,18 @@ export class IssuanceRepository { try { const credentialDefinitionDetails = await this.prisma.credential_definition.findFirst({ where: { - credentialDefinitionId - } - }); + credentialDefinitionId, + }, + }) if (!credentialDefinitionDetails) { - throw new NotFoundException(`Credential definition not found for ID: ${credentialDefinitionId}`); + throw new NotFoundException(`Credential definition not found for ID: ${credentialDefinitionId}`) } - const schemaDetails = await this.getSchemaDetailsBySchemaIdentifier(credentialDefinitionDetails.schemaLedgerId); + const schemaDetails = await this.getSchemaDetailsBySchemaIdentifier(credentialDefinitionDetails.schemaLedgerId) if (!schemaDetails) { - throw new NotFoundException(`Schema not found for credential definition ID: ${credentialDefinitionId}`); + throw new NotFoundException(`Schema not found for credential definition ID: ${credentialDefinitionId}`) } const credentialDefRes = { @@ -313,28 +318,28 @@ export class IssuanceRepository { tag: credentialDefinitionDetails.tag, schemaLedgerId: schemaDetails.schemaLedgerId, attributes: schemaDetails.attributes, - schemaName: schemaDetails.name - }; + schemaName: schemaDetails.name, + } - return credentialDefRes; + return credentialDefRes } catch (error) { - this.logger.error(`Error in getCredentialDefinitionDetails: ${error.message}`); - throw error; + this.logger.error(`Error in getCredentialDefinitionDetails: ${error.message}`) + throw error } } async getSchemaDetailsBySchemaIdentifier(schemaIdentifier: string): Promise { const schemaDetails = await this.prisma.schema.findFirst({ where: { - schemaLedgerId: schemaIdentifier - } - }); - return schemaDetails; + schemaLedgerId: schemaIdentifier, + }, + }) + return schemaDetails } async saveFileUploadDetails(fileUploadPayload: FileUpload, userId: string): Promise { try { - const { name, status, upload_type, orgId, credentialType, templateId } = fileUploadPayload; + const { name, status, upload_type, orgId, credentialType, templateId } = fileUploadPayload return this.prisma.file_upload.create({ data: { name: String(name), @@ -344,29 +349,29 @@ export class IssuanceRepository { createdBy: userId, lastChangedBy: userId, credential_type: credentialType, - templateId - } - }); + templateId, + }, + }) } catch (error) { - this.logger.error(`[saveFileUploadDetails] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[saveFileUploadDetails] - error: ${JSON.stringify(error)}`) + throw error } } async updateFileUploadDetails(fileId: string, fileUploadPayload): Promise { try { - const { status } = fileUploadPayload; + const { status } = fileUploadPayload return this.prisma.file_upload.update({ where: { - id: fileId + id: fileId, }, data: { - status - } - }); + status, + }, + }) } catch (error) { - this.logger.error(`[updateFileUploadDetails] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[updateFileUploadDetails] - error: ${JSON.stringify(error)}`) + throw error } } @@ -375,36 +380,36 @@ export class IssuanceRepository { const errorCount = await this.prisma.file_data.count({ where: { fileUploadId, - OR: [{ isError: true }, { status: false }] - } - }); + OR: [{ isError: true }, { status: false }], + }, + }) - return errorCount; + return errorCount } catch (error) { - this.logger.error(`[countErrorsForFile] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[countErrorsForFile] - error: ${JSON.stringify(error)}`) + throw error } } async getAllFileDetails( orgId: string, getAllfileDetails: PreviewRequest ): Promise<{ - fileCount: number; + fileCount: number fileList: { - id: string; - name: string; - status: string; - upload_type: string; - orgId: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - deletedAt: Date; - failedRecords: number; - totalRecords: number; - templateId: string; - }[]; + id: string + name: string + status: string + upload_type: string + orgId: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + deletedAt: Date + failedRecords: number + totalRecords: number + templateId: string + }[] }> { try { const fileList = await this.prisma.file_upload.findMany({ @@ -413,39 +418,39 @@ export class IssuanceRepository { OR: [ { name: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } }, { status: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } }, - { upload_type: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } } - ] + { upload_type: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } }, + ], }, take: Number(getAllfileDetails?.pageSize), skip: (getAllfileDetails?.pageNumber - 1) * getAllfileDetails?.pageSize, orderBy: { - createDateTime: 'desc' === getAllfileDetails.sortBy ? 'desc' : 'asc' - } - }); + createDateTime: getAllfileDetails.sortBy === 'desc' ? 'desc' : 'asc', + }, + }) const fileListWithDetails = await Promise.all( fileList.map(async (file) => { - const failedRecords = await this.countErrorsForFile(file.id); + const failedRecords = await this.countErrorsForFile(file.id) const totalRecords = await this.prisma.file_data.count({ where: { - fileUploadId: file.id - } - }); - const successfulRecords = totalRecords - failedRecords; - return { ...file, failedRecords, totalRecords, successfulRecords }; + fileUploadId: file.id, + }, + }) + const successfulRecords = totalRecords - failedRecords + return { ...file, failedRecords, totalRecords, successfulRecords } }) - ); + ) const fileCount = await this.prisma.file_upload.count({ where: { - orgId - } - }); + orgId, + }, + }) - return { fileCount, fileList: fileListWithDetails }; + return { fileCount, fileList: fileListWithDetails } } catch (error) { - this.logger.error(`[getFileUploadDetails] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getFileUploadDetails] - error: ${JSON.stringify(error)}`) + throw error } } @@ -453,20 +458,20 @@ export class IssuanceRepository { fileId: unknown, getAllfileDetails: PreviewRequest ): Promise<{ - fileCount: number; + fileCount: number fileDataList: { - id: string; - referenceId: string; - isError: boolean; - error: string; - detailError: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - deletedAt: Date; - fileUploadId: string; - }[]; + id: string + referenceId: string + isError: boolean + error: string + detailError: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + deletedAt: Date + fileUploadId: string + }[] }> { try { const fileDataList = await this.prisma.file_data.findMany({ @@ -475,30 +480,30 @@ export class IssuanceRepository { OR: [ { error: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } }, { referenceId: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } }, - { detailError: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } } - ] + { detailError: { contains: getAllfileDetails?.searchByText, mode: 'insensitive' } }, + ], }, take: Number(getAllfileDetails?.pageSize), skip: (getAllfileDetails?.pageNumber - 1) * getAllfileDetails?.pageSize, orderBy: { - createDateTime: 'desc' === getAllfileDetails.sortBy ? 'desc' : 'asc' - } - }); + createDateTime: getAllfileDetails.sortBy === 'desc' ? 'desc' : 'asc', + }, + }) const fileCount = await this.prisma.file_data.count({ where: { - fileUploadId: fileId - } - }); - return { fileCount, fileDataList }; + fileUploadId: fileId, + }, + }) + return { fileCount, fileDataList } } catch (error) { - this.logger.error(`[getFileDetailsByFileId] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getFileDetailsByFileId] - error: ${JSON.stringify(error)}`) + throw error } } async updateFileUploadData(fileUploadData: FileUploadData): Promise { try { - const { jobId, fileUpload, isError, referenceId, error, detailError } = fileUploadData; + const { jobId, fileUpload, isError, referenceId, error, detailError } = fileUploadData if (jobId) { return this.prisma.file_data.update({ where: { id: jobId }, @@ -507,15 +512,15 @@ export class IssuanceRepository { error, isError, referenceId, - fileUploadId: fileUpload - } - }); + fileUploadId: fileUpload, + }, + }) } else { - throw error; + throw error } } catch (error) { - this.logger.error(`[saveFileUploadData] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[saveFileUploadData] - error: ${JSON.stringify(error)}`) + throw error } } async deleteFileDataByJobId(jobId: string): Promise { @@ -525,20 +530,20 @@ export class IssuanceRepository { where: { id: jobId }, data: { credential_data: null, - status: true - } - }); + status: true, + }, + }) } } catch (error) { - this.logger.error(`[saveFileUploadData] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[saveFileUploadData] - error: ${JSON.stringify(error)}`) + throw error } } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-unused-vars async saveFileDetails(fileData, userId: string) { try { - const { credential_data, schemaId, credDefId, status, isError, fileUploadId, credentialType } = fileData; + const { credential_data, schemaId, credDefId, status, isError, fileUploadId, credentialType } = fileData return this.prisma.file_data.create({ data: { credential_data, @@ -549,12 +554,12 @@ export class IssuanceRepository { isError, createdBy: userId, lastChangedBy: userId, - credential_type: credentialType - } - }); + credential_type: credentialType, + }, + }) } catch (error) { - this.logger.error(`[saveFileUploadData] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[saveFileUploadData] - error: ${JSON.stringify(error)}`) + throw error } } @@ -562,14 +567,14 @@ export class IssuanceRepository { try { const { agent } = await this.prisma.org_agents_type.findFirst({ where: { - id: orgAgentId - } - }); + id: orgAgentId, + }, + }) - return agent; + return agent } catch (error) { - this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`) + throw error } } @@ -577,12 +582,12 @@ export class IssuanceRepository { try { return this.prisma.file_data.findMany({ where: { - fileUploadId: fileId - } - }); + fileUploadId: fileId, + }, + }) } catch (error) { - this.logger.error(`[getFileDetails] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getFileDetails] - error: ${JSON.stringify(error)}`) + throw error } } @@ -591,12 +596,12 @@ export class IssuanceRepository { return this.prisma.file_data.findMany({ where: { fileUploadId: fileId, - OR: [{ isError: true }, { status: false }] - } - }); + OR: [{ isError: true }, { status: false }], + }, + }) } catch (error) { - this.logger.error(`[getFileDetails] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getFileDetails] - error: ${JSON.stringify(error)}`) + throw error } } @@ -604,15 +609,15 @@ export class IssuanceRepository { try { return this.prisma.file_upload.update({ where: { - id: fileId + id: fileId, }, data: { - status: FileUploadStatus.retry - } - }); + status: FileUploadStatus.retry, + }, + }) } catch (error) { - this.logger.error(`[updateFileUploadStatus] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[updateFileUploadStatus] - error: ${JSON.stringify(error)}`) + throw error } } @@ -620,12 +625,12 @@ export class IssuanceRepository { try { return this.prisma.file_upload.findUnique({ where: { - id: fileId - } - }); + id: fileId, + }, + }) } catch (error) { - this.logger.error(`[updateFileUploadStatus] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[updateFileUploadStatus] - error: ${JSON.stringify(error)}`) + throw error } } @@ -633,13 +638,13 @@ export class IssuanceRepository { try { const fileDetails = await this.prisma.file_upload.findMany({ where: { - orgId - } - }); - return fileDetails; + orgId, + }, + }) + return fileDetails } catch (error) { - this.logger.error(`[getting file upload details] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getting file upload details] - error: ${JSON.stringify(error)}`) + throw error } } @@ -649,47 +654,47 @@ export class IssuanceRepository { const deleteFileDetails = await prisma.file_data.deleteMany({ where: { fileUploadId: { - in: fileUploadIds - } - } - }); + in: fileUploadIds, + }, + }, + }) const deleteFileUploadDetails = await prisma.file_upload.deleteMany({ where: { - orgId - } - }); + orgId, + }, + }) - return { deleteFileDetails, deleteFileUploadDetails }; - }); + return { deleteFileDetails, deleteFileUploadDetails } + }) } catch (error) { - this.logger.error(`[Error in deleting file data] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[Error in deleting file data] - error: ${JSON.stringify(error)}`) + throw error } } async deleteIssuanceRecordsByOrgId(orgId: string): Promise { try { - const tablesToCheck = [`${PrismaTables.PRESENTATIONS}`]; + const tablesToCheck = [`${PrismaTables.PRESENTATIONS}`] const referenceCounts = await Promise.all( tablesToCheck.map((table) => this.prisma[table].count({ where: { orgId } })) - ); + ) const referencedTables = referenceCounts - .map((count, index) => (0 < count ? tablesToCheck[index] : null)) - .filter(Boolean); + .map((count, index) => (count > 0 ? tablesToCheck[index] : null)) + .filter(Boolean) - if (0 < referencedTables.length) { - let errorMessage = `Organization ID ${orgId} is referenced in the following table(s): ${referencedTables.join(', ')}`; + if (referencedTables.length > 0) { + let errorMessage = `Organization ID ${orgId} is referenced in the following table(s): ${referencedTables.join(', ')}` - if (1 === referencedTables.length) { + if (referencedTables.length === 1) { if (referencedTables.includes(`${PrismaTables.PRESENTATIONS}`)) { - errorMessage += `, ${ResponseMessages.verification.error.removeVerificationData}`; + errorMessage += `, ${ResponseMessages.verification.error.removeVerificationData}` } } - throw new ConflictException(errorMessage); + throw new ConflictException(errorMessage) } return await this.prisma.$transaction(async (prisma) => { @@ -701,19 +706,19 @@ export class IssuanceRepository { connectionId: true, schemaId: true, state: true, - orgId: true - } - }); + orgId: true, + }, + }) const deleteResult = await prisma.credentials.deleteMany({ - where: { orgId } - }); + where: { orgId }, + }) - return { deleteResult, recordsToDelete }; - }); + return { deleteResult, recordsToDelete } + }) } catch (error) { - this.logger.error(`Error in deleting issuance records: ${error.message}`); - throw error; + this.logger.error(`Error in deleting issuance records: ${error.message}`) + throw error } } async getFileDetailsAndFileDataByFileId(fileId: string, orgId: string): Promise { @@ -721,16 +726,16 @@ export class IssuanceRepository { const fileDetails = await this.prisma.file_upload.findUnique({ where: { id: fileId, - orgId + orgId, }, include: { - file_data: true - } - }); - return fileDetails; + file_data: true, + }, + }) + return fileDetails } catch (error) { - this.logger.error(`[getFileDetailsAndFileDataByFileId] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getFileDetailsAndFileDataByFileId] - error: ${JSON.stringify(error)}`) + throw error } } } diff --git a/apps/issuance/src/issuance.service.ts b/apps/issuance/src/issuance.service.ts index 7030d2b0c..93f2890f5 100644 --- a/apps/issuance/src/issuance.service.ts +++ b/apps/issuance/src/issuance.service.ts @@ -1,7 +1,43 @@ +import { join } from 'path' +import type { AwsService } from '@credebl/aws' /* eslint-disable quotes */ /* eslint-disable no-useless-catch */ /* eslint-disable camelcase */ -import { CommonService } from '@credebl/common'; +import type { CommonService } from '@credebl/common' +import type { NATSClient } from '@credebl/common/NATSClient' +import { + createOobJsonldIssuancePayload, + validateAndUpdateIssuanceDates, + validateEmail, +} from '@credebl/common/cast.helper' +import { CommonConstants } from '@credebl/common/common.constant' +import { convertUrlToDeepLinkUrl, paginator } from '@credebl/common/common.utils' +import type { EmailDto } from '@credebl/common/dtos/email.dto' +import type { + ICredentialOfferResponse, + IDeletedIssuanceRecords, + IIssuedCredential, + IJsonldCredential, + IPrettyVc, + ISchemaObject, +} from '@credebl/common/interfaces/issuance.interface' +import type { ISchemaDetail } from '@credebl/common/interfaces/schema.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { sendEmail } from '@credebl/common/send-grid-helper-file' +import type ContextStorageService from '@credebl/context/contextStorageService.interface' +import { ContextStorageServiceKey } from '@credebl/context/contextStorageService.interface' +import { + AutoAccept, + IssuanceProcessState, + OrgAgentType, + PromiseResult, + SchemaType, + TemplateIdentifier, + W3CSchemaDataType, +} from '@credebl/enum/enum' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { InjectQueue } from '@nestjs/bull' +import { CACHE_MANAGER } from '@nestjs/cache-manager' import { BadRequestException, ConflictException, @@ -11,15 +47,32 @@ import { Injectable, InternalServerErrorException, Logger, - NotFoundException -} from '@nestjs/common'; -import { IssuanceRepository } from './issuance.repository'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { map } from 'rxjs'; + NotFoundException, +} from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' import { + RecordType, + type agent_invitations, + file_data, + file_upload, + type organisation, + type user, +} from '@prisma/client' +import { FileUploadStatus, FileUploadType } from 'apps/api-gateway/src/enum' +import type { OOBIssueCredentialDto } from 'apps/api-gateway/src/issuance/dtos/issuance.dto' +import { type IIssuedCredentialSearchParams, IssueCredentialType } from 'apps/api-gateway/src/issuance/interfaces' +import type { Queue } from 'bull' +import type { Cache } from 'cache-manager' +import { parse } from 'json2csv' +import type { UserActivityRepository } from 'libs/user-activity/repositories' +import * as pLimit from 'p-limit' +import { parse as paParse } from 'papaparse' +import * as QRCode from 'qrcode' +import { map } from 'rxjs' +import { io } from 'socket.io-client' +import { v4 as uuidv4 } from 'uuid' +import { checkIfFileOrDirectoryExists, createFile } from '../../api-gateway/src/helper-files/file-operation.helper' +import type { BulkPayloadDetails, CredentialOffer, FileUpload, @@ -42,62 +95,17 @@ import { PreviewRequest, SchemaDetails, SendEmailCredentialOffer, - TemplateDetailsInterface -} from '../interfaces/issuance.interfaces'; -import { - AutoAccept, - IssuanceProcessState, - OrgAgentType, - PromiseResult, - SchemaType, - TemplateIdentifier, - W3CSchemaDataType -} from '@credebl/enum/enum'; -import * as QRCode from 'qrcode'; -import { OutOfBandIssuance } from '../templates/out-of-band-issuance.template'; -import { EmailDto } from '@credebl/common/dtos/email.dto'; -import { join } from 'path'; -import { parse } from 'json2csv'; -import { checkIfFileOrDirectoryExists, createFile } from '../../api-gateway/src/helper-files/file-operation.helper'; -import { parse as paParse } from 'papaparse'; -import { v4 as uuidv4 } from 'uuid'; -import { Cache } from 'cache-manager'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { convertUrlToDeepLinkUrl, paginator } from '@credebl/common/common.utils'; -import { InjectQueue } from '@nestjs/bull'; -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 { IIssuedCredentialSearchParams, IssueCredentialType } from 'apps/api-gateway/src/issuance/interfaces'; -import { - ICredentialOfferResponse, - IDeletedIssuanceRecords, - IIssuedCredential, - IJsonldCredential, - IPrettyVc, - ISchemaObject -} from '@credebl/common/interfaces/issuance.interface'; -import { OOBIssueCredentialDto } from 'apps/api-gateway/src/issuance/dtos/issuance.dto'; -import { RecordType, agent_invitations, organisation, user } from '@prisma/client'; -import { - createOobJsonldIssuancePayload, - validateAndUpdateIssuanceDates, - validateEmail -} from '@credebl/common/cast.helper'; -import { sendEmail } from '@credebl/common/send-grid-helper-file'; -import * as pLimit from 'p-limit'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { validateW3CSchemaAttributes } from '../libs/helpers/attributes.validator'; -import { ISchemaDetail } from '@credebl/common/interfaces/schema.interface'; -import ContextStorageService, { ContextStorageServiceKey } from '@credebl/context/contextStorageService.interface'; -import { NATSClient } from '@credebl/common/NATSClient'; -import { extractAttributeNames, unflattenCsvRow } from '../libs/helpers/attributes.extractor'; + TemplateDetailsInterface, +} from '../interfaces/issuance.interfaces' +import { extractAttributeNames, unflattenCsvRow } from '../libs/helpers/attributes.extractor' +import { validateW3CSchemaAttributes } from '../libs/helpers/attributes.validator' +import type { OutOfBandIssuance } from '../templates/out-of-band-issuance.template' +import type { IssuanceRepository } from './issuance.repository' @Injectable() export class IssuanceService { - private readonly logger = new Logger('IssueCredentialService'); - private counter = 0; - private processedJobsCounters: Record = {}; + private readonly logger = new Logger('IssueCredentialService') + private counter = 0 + private processedJobsCounters: Record = {} constructor( @Inject('NATS_CLIENT') private readonly issuanceServiceProxy: ClientProxy, private readonly commonService: CommonService, @@ -116,85 +124,88 @@ export class IssuanceService { async getIssuanceRecords(orgId: string): Promise { try { - return await this.issuanceRepository.getIssuanceRecordsCount(orgId); + return await this.issuanceRepository.getIssuanceRecordsCount(orgId) } catch (error) { this.logger.error( `[getIssuanceRecords ] [NATS call]- error in get issuance records count : ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } async getW3CSchemaAttributes(schemaUrl: string): Promise { - const schemaRequest = await this.commonService.httpGet(schemaUrl).then(async (response) => response); + const schemaRequest = await this.commonService.httpGet(schemaUrl).then(async (response) => response) if (!schemaRequest) { throw new NotFoundException(ResponseMessages.schema.error.W3CSchemaNotFOund, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - const getSchemaDetails = await this.issuanceRepository.getSchemaDetails(schemaUrl); + const getSchemaDetails = await this.issuanceRepository.getSchemaDetails(schemaUrl) if (!getSchemaDetails) { - throw new NotFoundException(ResponseMessages.schema.error.notFound); + throw new NotFoundException(ResponseMessages.schema.error.notFound) } - const schemaAttributes = JSON.parse(getSchemaDetails?.attributes); + const schemaAttributes = JSON.parse(getSchemaDetails?.attributes) - return schemaAttributes; + return schemaAttributes } async sendCredentialCreateOffer(payload: IIssuance): Promise { try { - const { orgId, credentialDefinitionId, comment, credentialData, isValidateSchema } = payload || {}; + const { orgId, credentialDefinitionId, comment, credentialData, isValidateSchema } = payload || {} if (payload.credentialType === IssueCredentialType.INDY) { const schemaResponse: SchemaDetails = - await this.issuanceRepository.getCredentialDefinitionDetails(credentialDefinitionId); + await this.issuanceRepository.getCredentialDefinitionDetails(credentialDefinitionId) if (schemaResponse?.attributes) { - const schemaResponseError = []; - const attributesArray: IAttributes[] = JSON.parse(schemaResponse.attributes); + const schemaResponseError = [] + const attributesArray: IAttributes[] = JSON.parse(schemaResponse.attributes) + // biome-ignore lint/complexity/noForEach: attributesArray.forEach((attribute) => { if (attribute.attributeName && attribute.isRequired) { credentialData.forEach((credential, i) => { + // biome-ignore lint/complexity/noForEach: credential.attributes.forEach((attr) => { if (attr.name === attribute.attributeName && attribute.isRequired && !attr.value) { - schemaResponseError.push(`Attribute ${attribute.attributeName} is required at position ${i + 1}`); + schemaResponseError.push(`Attribute ${attribute.attributeName} is required at position ${i + 1}`) } - }); - }); + }) + }) } - }); + }) - if (0 < schemaResponseError.length) { - throw new BadRequestException(schemaResponseError); + if (schemaResponseError.length > 0) { + throw new BadRequestException(schemaResponseError) } } } - const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); + const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId) if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails - const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); + const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) if (!orgAgentType) { - throw new NotFoundException(ResponseMessages.issuance.error.orgAgentTypeNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.orgAgentTypeNotFound) } - const issuanceMethodLabel = 'create-offer'; - const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId); + const issuanceMethodLabel = 'create-offer' + const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId) if (payload.credentialType === IssueCredentialType.JSONLD) { - await validateAndUpdateIssuanceDates(credentialData); + await validateAndUpdateIssuanceDates(credentialData) } const issuancePromises = credentialData.map(async (credentials) => { - const { connectionId, attributes, credential, options } = credentials; - let issueData; + const { connectionId, attributes, credential, options } = credentials + // biome-ignore lint/suspicious/noImplicitAnyLet: + let issueData if (payload.credentialType === IssueCredentialType.INDY) { issueData = { @@ -204,25 +215,25 @@ export class IssuanceService { indy: { // eslint-disable-next-line @typescript-eslint/no-unused-vars attributes: attributes.map(({ isRequired, ...rest }) => rest), - credentialDefinitionId - } + credentialDefinitionId, + }, }, autoAcceptCredential: payload.autoAcceptCredential || 'always', - comment - }; + comment, + } } else if (payload.credentialType === IssueCredentialType.JSONLD) { const schemaIds = credentialData?.map((item) => { - const context: string[] = item?.credential?.['@context']; - return Array.isArray(context) && 1 < context.length ? context[1] : undefined; - }); + const context: string[] = item?.credential?.['@context'] + return Array.isArray(context) && context.length > 1 ? context[1] : undefined + }) - const schemaDetails = await this._getSchemaDetails(schemaIds); + const schemaDetails = await this._getSchemaDetails(schemaIds) - const ledgerIds = schemaDetails?.map((item) => item?.ledgerId); + const ledgerIds = schemaDetails?.map((item) => item?.ledgerId) for (const ledgerId of ledgerIds) { if (agentDetails?.ledgerId !== ledgerId) { - throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched); + throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched) } } @@ -232,86 +243,86 @@ export class IssuanceService { credentialFormats: { jsonld: { credential, - options - } + options, + }, }, autoAcceptCredential: payload.autoAcceptCredential || 'always', - comment: comment || '' - }; - const payloadAttributes = issueData?.credentialFormats?.jsonld?.credential?.credentialSubject; + comment: comment || '', + } + const payloadAttributes = issueData?.credentialFormats?.jsonld?.credential?.credentialSubject // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { id, ...filteredIssuanceAttributes } = payloadAttributes; + const { id, ...filteredIssuanceAttributes } = payloadAttributes - const schemaServerUrl = issueData?.credentialFormats?.jsonld?.credential?.['@context']?.[1]; + const schemaServerUrl = issueData?.credentialFormats?.jsonld?.credential?.['@context']?.[1] - const schemaUrlAttributes = await this.getW3CSchemaAttributes(schemaServerUrl); + const schemaUrlAttributes = await this.getW3CSchemaAttributes(schemaServerUrl) if (isValidateSchema) { - validateW3CSchemaAttributes(filteredIssuanceAttributes, schemaUrlAttributes); + validateW3CSchemaAttributes(filteredIssuanceAttributes, schemaUrlAttributes) } } - await this.delay(500); - return this._sendCredentialCreateOffer(issueData, url, orgId); - }); + await this.delay(500) + return this._sendCredentialCreateOffer(issueData, url, orgId) + }) - const results = await Promise.allSettled(issuancePromises); + const results = await Promise.allSettled(issuancePromises) const processedResults = results.map((result) => { if (PromiseResult.REJECTED === result.status) { return { statusCode: result?.reason?.status?.message?.statusCode || result?.reason?.response?.statusCode, message: result?.reason?.status?.message?.error?.message || result?.reason?.response?.message, - error: result?.reason?.response?.error || ResponseMessages.errorMessages.serverError - }; - } else if (PromiseResult.FULFILLED === result.status) { + error: result?.reason?.response?.error || ResponseMessages.errorMessages.serverError, + } + } + if (PromiseResult.FULFILLED === result.status) { return { statusCode: HttpStatus.CREATED, message: ResponseMessages.issuance.success.create, - data: result.value - }; + data: result.value, + } } - return null; - }); + return null + }) - const allSuccessful = processedResults.every((result) => result?.statusCode === HttpStatus.CREATED); - const allFailed = processedResults.every((result) => result?.statusCode !== HttpStatus.CREATED); + const allSuccessful = processedResults.every((result) => result?.statusCode === HttpStatus.CREATED) + const allFailed = processedResults.every((result) => result?.statusCode !== HttpStatus.CREATED) - let finalStatusCode: HttpStatus; - let finalMessage: string; + let finalStatusCode: HttpStatus + let finalMessage: string if (allSuccessful) { - finalStatusCode = HttpStatus.CREATED; - finalMessage = ResponseMessages.issuance.success.create; + finalStatusCode = HttpStatus.CREATED + finalMessage = ResponseMessages.issuance.success.create } else if (allFailed) { - finalStatusCode = HttpStatus.BAD_REQUEST; - finalMessage = ResponseMessages.issuance.error.unableToCreateOffer; + finalStatusCode = HttpStatus.BAD_REQUEST + finalMessage = ResponseMessages.issuance.error.unableToCreateOffer } else { - finalStatusCode = HttpStatus.PARTIAL_CONTENT; - finalMessage = ResponseMessages.issuance.success.partiallyOfferCreated; + finalStatusCode = HttpStatus.PARTIAL_CONTENT + finalMessage = ResponseMessages.issuance.success.partiallyOfferCreated } const finalResult = { statusCode: finalStatusCode, message: finalMessage, - data: processedResults - }; + data: processedResults, + } - return finalResult; + return finalResult } catch (error) { - this.logger.error(`[sendCredentialCreateOffer] - error in create credentials : ${JSON.stringify(error)}`); - const errorStack = error?.status?.message?.error?.reason || error?.status?.message?.error; + this.logger.error(`[sendCredentialCreateOffer] - error in create credentials : ${JSON.stringify(error)}`) + const errorStack = error?.status?.message?.error?.reason || error?.status?.message?.error if (errorStack) { throw new RpcException({ error: errorStack?.message ? errorStack?.message : errorStack, statusCode: error?.status?.code, - message: ResponseMessages.issuance.error.unableToCreateOffer - }); - } else { - throw new RpcException(error.response ? error.response : error); + message: ResponseMessages.issuance.error.unableToCreateOffer, + }) } + throw new RpcException(error.response ? error.response : error) } } @@ -328,55 +339,58 @@ export class IssuanceService { credentialType, isShortenUrl, reuseConnection, - isValidateSchema - } = payload; + isValidateSchema, + } = payload if (credentialType === IssueCredentialType.INDY) { const schemadetailsResponse: SchemaDetails = - await this.issuanceRepository.getCredentialDefinitionDetails(credentialDefinitionId); + await this.issuanceRepository.getCredentialDefinitionDetails(credentialDefinitionId) if (schemadetailsResponse?.attributes) { - const schemadetailsResponseError = []; - const attributesArray: IAttributes[] = JSON.parse(schemadetailsResponse.attributes); + const schemadetailsResponseError = [] + const attributesArray: IAttributes[] = JSON.parse(schemadetailsResponse.attributes) + // biome-ignore lint/complexity/noForEach: attributesArray.forEach((attribute) => { if (attribute.attributeName && attribute.isRequired) { + // biome-ignore lint/complexity/noForEach: payload.attributes.forEach((attr) => { if (attr.name === attribute.attributeName && attribute.isRequired && !attr.value) { schemadetailsResponseError.push( `Attribute '${attribute.attributeName}' is required but has an empty value.` - ); + ) } - return true; - }); + return true + }) } - }); - if (0 < schemadetailsResponseError.length) { - throw new BadRequestException(schemadetailsResponseError); + }) + if (schemadetailsResponseError.length > 0) { + throw new BadRequestException(schemadetailsResponseError) } } } - const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); - let invitationDid: string | undefined; - if (true === reuseConnection) { - const data: agent_invitations[] = await this.issuanceRepository.getInvitationDidByOrgId(orgId); - if (data && 0 < data.length) { - const [firstElement] = data; - invitationDid = firstElement?.invitationDid ?? undefined; + const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId) + let invitationDid: string | undefined + if (reuseConnection === true) { + const data: agent_invitations[] = await this.issuanceRepository.getInvitationDidByOrgId(orgId) + if (data && data.length > 0) { + const [firstElement] = data + invitationDid = firstElement?.invitationDid ?? undefined } } - const { agentEndPoint, organisation } = agentDetails; + const { agentEndPoint, organisation } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); + const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) - const issuanceMethodLabel = 'create-offer-oob'; - const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId); + const issuanceMethodLabel = 'create-offer-oob' + const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId) - let issueData; + // biome-ignore lint/suspicious/noImplicitAnyLet: + let issueData if (credentialType === IssueCredentialType.INDY) { issueData = { protocolVersion: protocolVersion || 'v1', @@ -384,8 +398,8 @@ export class IssuanceService { indy: { // eslint-disable-next-line @typescript-eslint/no-unused-vars attributes: attributes.map(({ isRequired, ...rest }) => rest), - credentialDefinitionId - } + credentialDefinitionId, + }, }, autoAcceptCredential: payload.autoAcceptCredential || 'always', goalCode: payload.goalCode || undefined, @@ -394,23 +408,23 @@ export class IssuanceService { imageUrl: organisation?.logoUrl || payload?.imageUrl || undefined, label: organisation?.name, comment: comment || '', - invitationDid: invitationDid || undefined - }; + invitationDid: invitationDid || undefined, + } } if (credentialType === IssueCredentialType.JSONLD) { - const context = credential?.['@context'][1]; + const context = credential?.['@context'][1] - const schemaDetails = await this.issuanceRepository.getSchemaDetails(String(context)); + const schemaDetails = await this.issuanceRepository.getSchemaDetails(String(context)) if (!schemaDetails) { - throw new NotFoundException(ResponseMessages.schema.error.notFound); + throw new NotFoundException(ResponseMessages.schema.error.notFound) } - const ledgerId = schemaDetails?.ledgerId; + const ledgerId = schemaDetails?.ledgerId if (agentDetails?.ledgerId !== ledgerId) { - throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched); + throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched) } issueData = { @@ -418,8 +432,8 @@ export class IssuanceService { credentialFormats: { jsonld: { credential, - options - } + options, + }, }, autoAcceptCredential: payload.autoAcceptCredential || 'always', goalCode: payload.goalCode || undefined, @@ -428,60 +442,59 @@ export class IssuanceService { imageUrl: organisation?.logoUrl || payload?.imageUrl || undefined, label: organisation?.name, comment: comment || '', - invitationDid: invitationDid || undefined - }; - const payloadAttributes = issueData?.credentialFormats?.jsonld?.credential?.credentialSubject; + invitationDid: invitationDid || undefined, + } + const payloadAttributes = issueData?.credentialFormats?.jsonld?.credential?.credentialSubject // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { id, ...filteredIssuanceAttributes } = payloadAttributes; + const { id, ...filteredIssuanceAttributes } = payloadAttributes - const schemaServerUrl = issueData?.credentialFormats?.jsonld?.credential?.['@context']?.[1]; + const schemaServerUrl = issueData?.credentialFormats?.jsonld?.credential?.['@context']?.[1] - const schemaUrlAttributes = await this.getW3CSchemaAttributes(schemaServerUrl); + const schemaUrlAttributes = await this.getW3CSchemaAttributes(schemaServerUrl) if (isValidateSchema) { - validateW3CSchemaAttributes(filteredIssuanceAttributes, schemaUrlAttributes); + validateW3CSchemaAttributes(filteredIssuanceAttributes, schemaUrlAttributes) } } - const credentialCreateOfferDetails = await this._outOfBandCredentialOffer(issueData, url, orgId); + const credentialCreateOfferDetails = await this._outOfBandCredentialOffer(issueData, url, orgId) if (isShortenUrl) { - const invitationUrl: string = credentialCreateOfferDetails.response?.invitationUrl; - const url: string = await this.storeIssuanceObjectReturnUrl(invitationUrl); - credentialCreateOfferDetails.response['invitationUrl'] = url; + const invitationUrl: string = credentialCreateOfferDetails.response?.invitationUrl + const url: string = await this.storeIssuanceObjectReturnUrl(invitationUrl) + credentialCreateOfferDetails.response.invitationUrl = url // Add deepLinkURL param to response - const deepLinkURL = convertUrlToDeepLinkUrl(url); - credentialCreateOfferDetails.response['deepLinkURL'] = deepLinkURL; + const deepLinkURL = convertUrlToDeepLinkUrl(url) + credentialCreateOfferDetails.response.deepLinkURL = deepLinkURL } - return credentialCreateOfferDetails.response; + return credentialCreateOfferDetails.response } catch (error) { - this.logger.error(`[storeIssuanceObjectReturnUrl] - error in create credentials : ${JSON.stringify(error)}`); + this.logger.error(`[storeIssuanceObjectReturnUrl] - error in create credentials : ${JSON.stringify(error)}`) - const errorStack = error?.status?.message?.error; + const errorStack = error?.status?.message?.error if (errorStack) { throw new RpcException({ message: errorStack?.reason ? errorStack?.reason : errorStack?.message, - statusCode: error?.status?.code - }); - } else { - throw new RpcException(error.response ? error.response : error); + statusCode: error?.status?.code, + }) } + throw new RpcException(error.response ? error.response : error) } } async storeIssuanceObjectReturnUrl(storeObj: string): Promise { try { // Set default to false, since currently our invitation are not multi-use - const persistent: boolean = false; + const persistent: boolean = false //nats call in agent-service to create an invitation url - const pattern = { cmd: 'store-object-return-url' }; - const payload = { persistent, storeObj }; - const message = await this.natsCall(pattern, payload); - return message.response; + const pattern = { cmd: 'store-object-return-url' } + const payload = { persistent, storeObj } + const message = await this.natsCall(pattern, payload) + return message.response } catch (error) { this.logger.error( `[storeIssuanceObjectReturnUrl] [NATS call]- error in storing object and returning url : ${JSON.stringify(error)}` - ); - throw error; + ) + throw error } } @@ -493,19 +506,19 @@ export class IssuanceService { .send(this.issuanceServiceProxy, pattern, payload) .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.statusCode, - error: error.message + error: error.message, }, error.error - ); - }); - return createOffer; + ) + }) + return createOffer } catch (error) { - this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`) + throw error } } @@ -513,43 +526,43 @@ export class IssuanceService { pattern: object, payload: object ): Promise<{ - response: string; + response: string }> { try { return this.issuanceServiceProxy .send(pattern, payload) .pipe( map((response) => ({ - response + response, })) ) .toPromise() .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.statusCode, - error: error.message + error: error.message, }, error.error - ); - }); + ) + }) } catch (error) { - this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`) + throw error } } async _sendCredentialCreateOffer(issueData: IIssueData, url: string, orgId: string): Promise { try { - const pattern = { cmd: 'agent-send-credential-create-offer' }; - const payload: ISendOfferNatsPayload = { issueData, url, orgId }; - return await this.natsCallAgent(pattern, payload); + const pattern = { cmd: 'agent-send-credential-create-offer' } + const payload: ISendOfferNatsPayload = { issueData, url, orgId } + return await this.natsCallAgent(pattern, payload) } catch (error) { this.logger.error( `[_sendCredentialCreateOffer] [NATS call]- error in create credentials : ${JSON.stringify(error)}` - ); - throw error; + ) + throw error } } @@ -559,12 +572,12 @@ export class IssuanceService { issuedCredentialsSearchCriteria: IIssuedCredentialSearchParams ): Promise { try { - let schemaIds; + let schemaIds: string[] if (issuedCredentialsSearchCriteria?.search) { - const schemaDetails = await this._getSchemaDetailsByName(issuedCredentialsSearchCriteria?.search, orgId); + const schemaDetails = await this._getSchemaDetailsByName(issuedCredentialsSearchCriteria?.search, orgId) - if (schemaDetails && 0 < schemaDetails?.length) { - schemaIds = schemaDetails.map((item) => item?.schemaLedgerId); + if (schemaDetails && schemaDetails?.length > 0) { + schemaIds = schemaDetails.map((item) => item?.schemaLedgerId) } } @@ -573,159 +586,159 @@ export class IssuanceService { orgId, issuedCredentialsSearchCriteria, schemaIds - ); + ) - const getSchemaIds = getIssuedCredentialsList?.issuedCredentialsList?.map((schema) => schema?.schemaId); + const getSchemaIds = getIssuedCredentialsList?.issuedCredentialsList?.map((schema) => schema?.schemaId) - const getSchemaDetails = await this._getSchemaDetails(getSchemaIds); + const getSchemaDetails = await this._getSchemaDetails(getSchemaIds) - let responseWithSchemaName; + // biome-ignore lint/suspicious/noImplicitAnyLet: + let responseWithSchemaName if (getSchemaDetails) { responseWithSchemaName = getIssuedCredentialsList?.issuedCredentialsList.map((file) => { - const schemaDetail = getSchemaDetails?.find((schema) => schema.schemaLedgerId === file.schemaId); + const schemaDetail = getSchemaDetails?.find((schema) => schema.schemaLedgerId === file.schemaId) return { ...file, - schemaName: schemaDetail?.name - }; - }); + schemaName: schemaDetail?.name, + } + }) } else { - const getSchemaUrlDetails = await this.getSchemaUrlDetails(getSchemaIds); + const getSchemaUrlDetails = await this.getSchemaUrlDetails(getSchemaIds) responseWithSchemaName = getIssuedCredentialsList?.issuedCredentialsList.map((file) => { - const schemaDetail = getSchemaUrlDetails?.find((schema) => schema.title); + const schemaDetail = getSchemaUrlDetails?.find((schema) => schema.title) return { ...file, - schemaName: schemaDetail?.title - }; - }); + schemaName: schemaDetail?.title, + } + }) } const issuedCredentialsResponse: IIssuedCredential = { totalItems: getIssuedCredentialsList.issuedCredentialsCount, hasNextPage: issuedCredentialsSearchCriteria.pageSize * issuedCredentialsSearchCriteria.pageNumber < getIssuedCredentialsList.issuedCredentialsCount, - hasPreviousPage: 1 < issuedCredentialsSearchCriteria.pageNumber, + hasPreviousPage: issuedCredentialsSearchCriteria.pageNumber > 1, nextPage: Number(issuedCredentialsSearchCriteria.pageNumber) + 1, previousPage: issuedCredentialsSearchCriteria.pageNumber - 1, lastPage: Math.ceil(getIssuedCredentialsList.issuedCredentialsCount / issuedCredentialsSearchCriteria.pageSize), - data: responseWithSchemaName - }; + data: responseWithSchemaName, + } - if (0 === getIssuedCredentialsList?.issuedCredentialsCount) { - throw new NotFoundException(ResponseMessages.issuance.error.credentialsNotFound); + if (getIssuedCredentialsList?.issuedCredentialsCount === 0) { + throw new NotFoundException(ResponseMessages.issuance.error.credentialsNotFound) } - return issuedCredentialsResponse; + return issuedCredentialsResponse } catch (error) { - this.logger.error(`Error in fetching issued credentials by org id: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in fetching issued credentials by org id: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async _getSchemaDetailsByName(schemaName: string, orgId: string): Promise { - const pattern = { cmd: 'get-schemas-details-by-name' }; - const payload = { schemaName, orgId }; + const pattern = { cmd: 'get-schemas-details-by-name' } + const payload = { schemaName, orgId } const schemaDetails = await this.natsClient .send(this.issuanceServiceProxy, pattern, payload) .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return schemaDetails; + return schemaDetails } async getSchemaUrlDetails(schemaUrls: string[]): Promise { - const results = []; + const results = [] for (const schemaUrl of schemaUrls) { - const schemaRequest = await this.commonService.httpGet(schemaUrl); + const schemaRequest = await this.commonService.httpGet(schemaUrl) if (!schemaRequest) { throw new NotFoundException(ResponseMessages.schema.error.W3CSchemaNotFOund, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - results.push(schemaRequest); + results.push(schemaRequest) } - return results; + return results } async _getIssueCredentials( url: string, apiKey: string ): Promise<{ - response: string; + response: string }> { try { - const pattern = { cmd: 'agent-get-all-issued-credentials' }; - const payload = { url, apiKey }; - return await this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-get-all-issued-credentials' } + const payload = { url, apiKey } + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`[_getIssueCredentials] [NATS call]- error in fetch credentials : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[_getIssueCredentials] [NATS call]- error in fetch credentials : ${JSON.stringify(error)}`) + throw error } } async getIssueCredentialsbyCredentialRecordId( - user: IUserRequest, + _user: IUserRequest, credentialRecordId: string, orgId: string ): Promise { try { - const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); + const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId) // const platformConfig: platform_config = await this.issuanceRepository.getPlatformConfigDetails(); - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); - const issuanceMethodLabel = 'get-issue-credential-by-credential-id'; + const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) + const issuanceMethodLabel = 'get-issue-credential-by-credential-id' const url = await this.getAgentUrl( issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId, credentialRecordId - ); + ) - const createConnectionInvitation = await this._getIssueCredentialsbyCredentialRecordId(url, orgId); - return createConnectionInvitation?.response; + const createConnectionInvitation = await this._getIssueCredentialsbyCredentialRecordId(url, orgId) + return createConnectionInvitation?.response } catch (error) { this.logger.error( `[getIssueCredentialsbyCredentialRecordId] - error in get credentials : ${JSON.stringify(error)}` - ); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + ) + if (error?.status?.message?.error) { throw new RpcException({ message: error?.status?.message?.error?.reason || error?.status?.message?.error?.message || error?.status?.message?.error, - statusCode: error?.status?.code - }); - } else { - throw new RpcException(error.response ? error.response : error); + statusCode: error?.status?.code, + }) } + throw new RpcException(error.response ? error.response : error) } } async getIssueCredentialWebhook(payload: IssueCredentialWebhookPayload): Promise { try { - const agentDetails = await this.issuanceRepository.saveIssuedCredentialDetails(payload); - return agentDetails; + const agentDetails = await this.issuanceRepository.saveIssuedCredentialDetails(payload) + return agentDetails } catch (error) { this.logger.error( `[getIssueCredentialsbyCredentialRecordId] - error in get credentials : ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } @@ -733,17 +746,17 @@ export class IssuanceService { url: string, orgId: string ): Promise<{ - response: string; + response: string }> { try { - const pattern = { cmd: 'agent-get-issued-credentials-by-credentialDefinitionId' }; - const payload = { url, orgId }; - return await this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-get-issued-credentials-by-credentialDefinitionId' } + const payload = { url, orgId } + return await this.natsCall(pattern, payload) } catch (error) { this.logger.error( `[_getIssueCredentialsbyCredentialRecordId] [NATS call]- error in fetch credentials : ${JSON.stringify(error)}` - ); - throw error; + ) + throw error } } @@ -764,115 +777,116 @@ export class IssuanceService { emailId, credentialType, isReuseConnection, - isValidateSchema - } = outOfBandCredential; + isValidateSchema, + } = outOfBandCredential - const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); + const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId) if (IssueCredentialType.JSONLD === credentialType) { - await validateAndUpdateIssuanceDates(credentialOffer); + await validateAndUpdateIssuanceDates(credentialOffer) const schemaIds = credentialOffer?.map((item) => { - const context: string[] = item?.credential?.['@context']; - return Array.isArray(context) && 1 < context.length ? context[1] : undefined; - }); + const context: string[] = item?.credential?.['@context'] + return Array.isArray(context) && context.length > 1 ? context[1] : undefined + }) - const schemaDetails = await this._getSchemaDetails(schemaIds); + const schemaDetails = await this._getSchemaDetails(schemaIds) - const ledgerIds = schemaDetails?.map((item) => item?.ledgerId); + const ledgerIds = schemaDetails?.map((item) => item?.ledgerId) for (const ledgerId of ledgerIds) { if (agentDetails?.ledgerId !== ledgerId) { - throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched); + throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched) } } } if (IssueCredentialType.INDY === credentialType) { const schemaResponse: SchemaDetails = - await this.issuanceRepository.getCredentialDefinitionDetails(credentialDefinitionId); + await this.issuanceRepository.getCredentialDefinitionDetails(credentialDefinitionId) - let attributesArray: IAttributes[] = []; + let attributesArray: IAttributes[] = [] if (schemaResponse?.attributes) { - attributesArray = JSON.parse(schemaResponse.attributes); + attributesArray = JSON.parse(schemaResponse.attributes) } - if (0 < attributes?.length) { - const attrError = []; + if (attributes?.length > 0) { + const attrError = [] attributesArray.forEach((schemaAttribute, i) => { if (schemaAttribute.isRequired) { - const attribute = attributes.find((attribute) => attribute.name === schemaAttribute.attributeName); + const attribute = attributes.find((attribute) => attribute.name === schemaAttribute.attributeName) if (!attribute?.value) { - attrError.push(`attributes.${i}.Attribute ${schemaAttribute.attributeName} is required`); + attrError.push(`attributes.${i}.Attribute ${schemaAttribute.attributeName} is required`) } } - }); - if (0 < attrError.length) { - throw new BadRequestException(attrError); + }) + if (attrError.length > 0) { + throw new BadRequestException(attrError) } } - if (0 < credentialOffer?.length) { - const credefError = []; + if (credentialOffer?.length > 0) { + const credefError = [] credentialOffer.forEach((credentialAttribute, index) => { attributesArray.forEach((schemaAttribute, i) => { const attribute = credentialAttribute.attributes.find( (attribute) => attribute.name === schemaAttribute.attributeName - ); + ) if (schemaAttribute.isRequired && !attribute?.value) { credefError.push( `credentialOffer.${index}.attributes.${i}.Attribute ${schemaAttribute.attributeName} is required` - ); + ) } - }); - }); - if (0 < credefError.length) { - throw new BadRequestException(credefError); + }) + }) + if (credefError.length > 0) { + throw new BadRequestException(credefError) } } } - const { organisation } = agentDetails; + const { organisation } = agentDetails if (!agentDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound) } - const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId); + const orgAgentType = await this.issuanceRepository.getOrgAgentType(agentDetails?.orgAgentTypeId) - const issuanceMethodLabel = 'create-offer-oob'; + const issuanceMethodLabel = 'create-offer-oob' const url = await this.getAgentUrl( issuanceMethodLabel, orgAgentType, agentDetails.agentEndPoint, agentDetails.tenantId - ); - const organizationDetails = await this.issuanceRepository.getOrganization(orgId); + ) + const organizationDetails = await this.issuanceRepository.getOrganization(orgId) if (!organizationDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.organizationNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.organizationNotFound) } - const errors = []; - let credentialOfferResponse; - const arraycredentialOfferResponse = []; + const errors = [] + // biome-ignore lint/style/useConst: + let credentialOfferResponse: boolean + const arraycredentialOfferResponse = [] const sendEmailCredentialOffer: { - iterator: CredentialOffer; - emailId: string; - index: number; - credentialType: IssueCredentialType; - protocolVersion: string; - isReuseConnection?: boolean; - attributes: IAttributes[]; - credentialDefinitionId: string; - outOfBandCredential: OutOfBandCredentialOfferPayload; - comment: string; - organisation: organisation; - errors: string[]; - url: string; - orgId: string; - organizationDetails: organisation; - platformName?: string; - organizationLogoUrl?: string; - prettyVc?: IPrettyVc; - isValidateSchema?: boolean; + iterator: CredentialOffer + emailId: string + index: number + credentialType: IssueCredentialType + protocolVersion: string + isReuseConnection?: boolean + attributes: IAttributes[] + credentialDefinitionId: string + outOfBandCredential: OutOfBandCredentialOfferPayload + comment: string + organisation: organisation + errors: string[] + url: string + orgId: string + organizationDetails: organisation + platformName?: string + organizationLogoUrl?: string + prettyVc?: IPrettyVc + isValidateSchema?: boolean } = { credentialType, protocolVersion, @@ -897,51 +911,49 @@ export class IssuanceService { size: prettyVc?.size, orientation: prettyVc?.orientation, height: prettyVc?.height, - width: prettyVc?.width - } - }; + width: prettyVc?.width, + }, + } if (credentialOffer) { for (const [index, iterator] of credentialOffer.entries()) { - sendEmailCredentialOffer['iterator'] = iterator; - sendEmailCredentialOffer['emailId'] = iterator.emailId; - sendEmailCredentialOffer['index'] = index; + sendEmailCredentialOffer.iterator = iterator + sendEmailCredentialOffer.emailId = iterator.emailId + sendEmailCredentialOffer.index = index - await this.delay(500); // Wait for 0.5 seconds - const sendOobOffer = await this.sendEmailForCredentialOffer(sendEmailCredentialOffer); + await this.delay(500) // Wait for 0.5 seconds + const sendOobOffer = await this.sendEmailForCredentialOffer(sendEmailCredentialOffer) - arraycredentialOfferResponse.push(sendOobOffer); + arraycredentialOfferResponse.push(sendOobOffer) } - if (0 < errors.length) { - throw errors; + if (errors.length > 0) { + throw errors } - return arraycredentialOfferResponse.every((result) => true === result); - } else { - credentialOfferResponse = await this.sendEmailForCredentialOffer(sendEmailCredentialOffer); - return credentialOfferResponse; + return arraycredentialOfferResponse.every((result) => result === true) } + credentialOfferResponse = await this.sendEmailForCredentialOffer(sendEmailCredentialOffer) + return credentialOfferResponse } catch (error) { this.logger.error( `[outOfBoundCredentialOffer] - error in create out-of-band credentials: ${JSON.stringify(error)}` - ); - if (0 < error?.length) { + ) + if (error?.length > 0) { const errorStack = error?.map((item) => { - const { statusCode, message, error } = item?.error || item?.response || {}; + const { statusCode, message, error } = item?.error || item?.response || {} return { statusCode, message, - error - }; - }); + error, + } + }) throw new RpcException({ error: errorStack, statusCode: error?.status?.code, - message: ResponseMessages.issuance.error.unableToCreateOOBOffer - }); - } else { - throw new RpcException(error.response ? error.response : error); + message: ResponseMessages.issuance.error.unableToCreateOOBOffer, + }) } + throw new RpcException(error.response ? error.response : error) } } @@ -964,20 +976,21 @@ export class IssuanceService { platformName, organizationLogoUrl, isReuseConnection, - isValidateSchema - } = sendEmailCredentialOffer; - const iterationNo = index + 1; + isValidateSchema, + } = sendEmailCredentialOffer + const iterationNo = index + 1 try { - let invitationDid: string | undefined; - if (true === isReuseConnection) { - const data: agent_invitations[] = await this.issuanceRepository.getInvitationDidByOrgId(orgId); - if (data && 0 < data.length) { - const [firstElement] = data; - invitationDid = firstElement?.invitationDid ?? undefined; + let invitationDid: string | undefined + if (isReuseConnection === true) { + const data: agent_invitations[] = await this.issuanceRepository.getInvitationDidByOrgId(orgId) + if (data && data.length > 0) { + const [firstElement] = data + invitationDid = firstElement?.invitationDid ?? undefined } } - let outOfBandIssuancePayload; + // biome-ignore lint/suspicious/noImplicitAnyLet: + let outOfBandIssuancePayload if (IssueCredentialType.INDY === credentialType) { outOfBandIssuancePayload = { protocolVersion: protocolVersion || 'v1', @@ -985,8 +998,8 @@ export class IssuanceService { indy: { // eslint-disable-next-line @typescript-eslint/no-unused-vars attributes: attributes ? attributes : iterator.attributes.map(({ isRequired, ...rest }) => rest), - credentialDefinitionId - } + credentialDefinitionId, + }, }, autoAcceptCredential: outOfBandCredential.autoAcceptCredential || 'always', comment, @@ -995,8 +1008,8 @@ export class IssuanceService { willConfirm: outOfBandCredential.willConfirm || undefined, label: organisation?.name, imageUrl: organisation?.logoUrl || outOfBandCredential?.imageUrl, - invitationDid: invitationDid || undefined - }; + invitationDid: invitationDid || undefined, + } } if (IssueCredentialType.JSONLD === credentialType) { @@ -1005,8 +1018,8 @@ export class IssuanceService { credentialFormats: { jsonld: { credential: iterator.credential, - options: iterator.options - } + options: iterator.options, + }, }, // For Educreds autoAcceptCredential: AutoAccept.Always, @@ -1016,101 +1029,100 @@ export class IssuanceService { willConfirm: outOfBandCredential.willConfirm || undefined, label: organisation?.name, imageUrl: organisation?.logoUrl || outOfBandCredential?.imageUrl, - invitationDid: invitationDid || undefined - }; + invitationDid: invitationDid || undefined, + } - const payloadAttributes = outOfBandIssuancePayload?.credentialFormats?.jsonld?.credential?.credentialSubject; + const payloadAttributes = outOfBandIssuancePayload?.credentialFormats?.jsonld?.credential?.credentialSubject // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { id, ...filteredIssuanceAttributes } = payloadAttributes; + const { id, ...filteredIssuanceAttributes } = payloadAttributes - const schemaServerUrl = outOfBandIssuancePayload?.credentialFormats?.jsonld?.credential?.['@context']?.[1]; + const schemaServerUrl = outOfBandIssuancePayload?.credentialFormats?.jsonld?.credential?.['@context']?.[1] - const schemaUrlAttributes = await this.getW3CSchemaAttributes(schemaServerUrl); + const schemaUrlAttributes = await this.getW3CSchemaAttributes(schemaServerUrl) if (isValidateSchema) { - validateW3CSchemaAttributes(filteredIssuanceAttributes, schemaUrlAttributes); + validateW3CSchemaAttributes(filteredIssuanceAttributes, schemaUrlAttributes) } } - const credentialCreateOfferDetails = await this._outOfBandCredentialOffer(outOfBandIssuancePayload, url, orgId); + const credentialCreateOfferDetails = await this._outOfBandCredentialOffer(outOfBandIssuancePayload, url, orgId) if (!credentialCreateOfferDetails) { - errors.push(new NotFoundException(ResponseMessages.issuance.error.credentialOfferNotFound)); - return false; + errors.push(new NotFoundException(ResponseMessages.issuance.error.credentialOfferNotFound)) + return false } - const invitationUrl: string = credentialCreateOfferDetails.response?.invitationUrl; - const shortenUrl: string = await this.storeIssuanceObjectReturnUrl(invitationUrl); + const invitationUrl: string = credentialCreateOfferDetails.response?.invitationUrl + const shortenUrl: string = await this.storeIssuanceObjectReturnUrl(invitationUrl) - const deepLinkURL = convertUrlToDeepLinkUrl(shortenUrl); + const deepLinkURL = convertUrlToDeepLinkUrl(shortenUrl) if (!invitationUrl) { - errors.push(new NotFoundException(ResponseMessages.issuance.error.invitationNotFound)); - return false; + errors.push(new NotFoundException(ResponseMessages.issuance.error.invitationNotFound)) + return false } - const qrCodeOptions = { type: 'image/png' }; - const outOfBandIssuanceQrCode = await QRCode.toDataURL(shortenUrl, qrCodeOptions); - const platformConfigData = await this.issuanceRepository.getPlatformConfigDetails(); + const qrCodeOptions = { type: 'image/png' } + const outOfBandIssuanceQrCode = await QRCode.toDataURL(shortenUrl, qrCodeOptions) + const platformConfigData = await this.issuanceRepository.getPlatformConfigDetails() if (!platformConfigData) { - errors.push(new NotFoundException(ResponseMessages.issuance.error.platformConfigNotFound)); - return false; + errors.push(new NotFoundException(ResponseMessages.issuance.error.platformConfigNotFound)) + return false } - this.emailData.emailFrom = platformConfigData?.emailFrom; - this.emailData.emailTo = iterator?.emailId ?? emailId; - const platform = platformName || process.env.PLATFORM_NAME; - this.emailData.emailSubject = `${platform} Platform: Issuance of Your Credential`; + this.emailData.emailFrom = platformConfigData?.emailFrom + this.emailData.emailTo = iterator?.emailId ?? emailId + const platform = platformName || process.env.PLATFORM_NAME + this.emailData.emailSubject = `${platform} Platform: Issuance of Your Credential` this.emailData.emailHtml = this.outOfBandIssuance.outOfBandIssuance( emailId, organizationDetails.name, deepLinkURL, platformName, organizationLogoUrl - ); + ) this.emailData.emailAttachments = [ { filename: 'qrcode.png', content: outOfBandIssuanceQrCode.split(';base64,')[1], contentType: 'image/png', - disposition: 'attachment' - } - ]; + disposition: 'attachment', + }, + ] - const isEmailSent = await sendEmail(this.emailData); + const isEmailSent = await sendEmail(this.emailData) - this.logger.log(`isEmailSent ::: ${JSON.stringify(isEmailSent)}-${this.counter}`); - this.counter++; + this.logger.log(`isEmailSent ::: ${JSON.stringify(isEmailSent)}-${this.counter}`) + this.counter++ if (!isEmailSent) { - errors.push(new InternalServerErrorException(ResponseMessages.issuance.error.emailSend)); - return false; + errors.push(new InternalServerErrorException(ResponseMessages.issuance.error.emailSend)) + return false } - return isEmailSent; + return isEmailSent } catch (error) { - const iterationNoMessage = ` at position ${iterationNo}`; - this.logger.error('[OUT-OF-BAND CREATE OFFER - SEND EMAIL]::', JSON.stringify(error)); - const errorStack = error?.status?.message; + const iterationNoMessage = ` at position ${iterationNo}` + this.logger.error('[OUT-OF-BAND CREATE OFFER - SEND EMAIL]::', JSON.stringify(error)) + const errorStack = error?.status?.message if (errorStack) { errors.push( new RpcException({ statusCode: errorStack?.statusCode, message: `${ResponseMessages.issuance.error.walletError} at position ${iterationNo}`, - error: `${errorStack?.error?.message} at position ${iterationNo}` + error: `${errorStack?.error?.message} at position ${iterationNo}`, }) - ); + ) - error.status.message = `${error.status.message}${iterationNoMessage}`; - throw error; - } else { - errors.push( - new RpcException({ - statusCode: error?.response?.statusCode, - message: `${error?.response?.message} at position ${iterationNo}`, - error: error?.response?.error - }) - ); - error.response.message = `${error.response.message}${iterationNoMessage}`; - throw error; // Check With other issuance flow + error.status.message = `${error.status.message}${iterationNoMessage}` + throw error } + errors.push( + new RpcException({ + statusCode: error?.response?.statusCode, + message: `${error?.response?.message} at position ${iterationNo}`, + error: error?.response?.error, + }) + ) + error.response.message = `${error.response.message}${iterationNoMessage}` + throw error // Check With other issuance flow } } @@ -1119,15 +1131,15 @@ export class IssuanceService { url: string, orgId: string ): Promise<{ - response; + response }> { try { - const pattern = { cmd: 'agent-out-of-band-credential-offer' }; - const payload = { outOfBandIssuancePayload, url, orgId }; - return await this.natsCall(pattern, payload); + const pattern = { cmd: 'agent-out-of-band-credential-offer' } + const payload = { outOfBandIssuancePayload, url, orgId } + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`[_outOfBandCredentialOffer] [NATS call]- error in out of band : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[_outOfBandCredentialOffer] [NATS call]- error in out of band : ${JSON.stringify(error)}`) + throw error } } @@ -1144,7 +1156,7 @@ export class IssuanceService { credentialRecordId?: string ): Promise { try { - let url; + let url: string switch (issuanceMethodLabel) { case 'create-offer': { url = @@ -1152,8 +1164,8 @@ export class IssuanceService { ? `${agentEndPoint}${CommonConstants.URL_ISSUE_CREATE_CRED_OFFER_AFJ}` : orgAgentType === OrgAgentType.SHARED ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_OFFER}`.replace('#', tenantId) - : null; - break; + : null + break } case 'create-offer-oob': { @@ -1162,8 +1174,8 @@ export class IssuanceService { ? `${agentEndPoint}${CommonConstants.URL_OUT_OF_BAND_CREDENTIAL_OFFER}` : orgAgentType === OrgAgentType.SHARED ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_CREATE_OFFER_OUT_OF_BAND}`.replace('#', tenantId) - : null; - break; + : null + break } case 'get-issue-credentials': { @@ -1172,8 +1184,8 @@ export class IssuanceService { ? `${agentEndPoint}${CommonConstants.URL_ISSUE_GET_CREDS_AFJ}` : orgAgentType === OrgAgentType.SHARED ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_GET_CREDENTIALS}`.replace('#', tenantId) - : null; - break; + : null + break } case 'get-issue-credential-by-credential-id': { @@ -1184,366 +1196,366 @@ export class IssuanceService { ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_GET_CREDENTIALS_BY_CREDENTIAL_ID}` .replace('#', credentialRecordId) .replace('@', tenantId) - : null; - break; + : null + break } default: { - break; + break } } if (!url) { - throw new NotFoundException(ResponseMessages.issuance.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentUrlNotFound) } - return url; + return url } catch (error) { - this.logger.error(`Error in get agent url: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in get agent url: ${JSON.stringify(error)}`) + throw error } } async downloadBulkIssuanceCSVTemplate(orgId: string, templateDetails: TemplateDetailsInterface): Promise { try { - let schemaResponse: SchemaDetails; - let fileName: string; + let schemaResponse: SchemaDetails + let fileName: string - const orgDetails = await this.issuanceRepository.getAgentEndPoint(orgId); + const orgDetails = await this.issuanceRepository.getAgentEndPoint(orgId) - const { schemaType, templateId } = templateDetails; + const { schemaType, templateId } = templateDetails if (!templateId) { - throw new BadRequestException(ResponseMessages.bulkIssuance.error.invalidtemplateId); + throw new BadRequestException(ResponseMessages.bulkIssuance.error.invalidtemplateId) } - const timestamp = Math.floor(Date.now() / 1000); + const timestamp = Math.floor(Date.now() / 1000) if (schemaType === SchemaType.INDY) { - schemaResponse = await this.issuanceRepository.getCredentialDefinitionDetails(templateId); + schemaResponse = await this.issuanceRepository.getCredentialDefinitionDetails(templateId) if (!schemaResponse) { - throw new NotFoundException(ResponseMessages.bulkIssuance.error.invalidIdentifier); + throw new NotFoundException(ResponseMessages.bulkIssuance.error.invalidIdentifier) } - const schemaDetails = await this.issuanceRepository.getSchemaDetails(schemaResponse.schemaLedgerId); + const schemaDetails = await this.issuanceRepository.getSchemaDetails(schemaResponse.schemaLedgerId) if (!schemaDetails) { - throw new NotFoundException(ResponseMessages.schema.error.notFound); + throw new NotFoundException(ResponseMessages.schema.error.notFound) } if (orgDetails?.ledgerId !== schemaDetails?.ledgerId) { - throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched); + throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched) } - fileName = `${schemaResponse.tag}-${timestamp}.csv`; + fileName = `${schemaResponse.tag}-${timestamp}.csv` } else if (schemaType === SchemaType.W3C_Schema) { - const schemaDetails = await this.issuanceRepository.getSchemaDetailsBySchemaIdentifier(templateId); + const schemaDetails = await this.issuanceRepository.getSchemaDetailsBySchemaIdentifier(templateId) if (orgDetails?.ledgerId !== schemaDetails?.ledgerId) { - throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched); + throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched) } if (!schemaDetails) { - throw new NotFoundException(ResponseMessages.bulkIssuance.error.invalidIdentifier); + throw new NotFoundException(ResponseMessages.bulkIssuance.error.invalidIdentifier) } - const { attributes, schemaLedgerId, name } = schemaDetails; - schemaResponse = { attributes, schemaLedgerId, name }; - fileName = `${schemaResponse.name}-${timestamp}.csv`; + const { attributes, schemaLedgerId, name } = schemaDetails + schemaResponse = { attributes, schemaLedgerId, name } + fileName = `${schemaResponse.name}-${timestamp}.csv` } - const attributesArray = JSON.parse(schemaResponse.attributes); + const attributesArray = JSON.parse(schemaResponse.attributes) - const csvFields: string[] = [TemplateIdentifier.EMAIL_COLUMN]; + const csvFields: string[] = [TemplateIdentifier.EMAIL_COLUMN] - const flattendData = extractAttributeNames(attributesArray); - csvFields.push(...flattendData); + const flattendData = extractAttributeNames(attributesArray) + csvFields.push(...flattendData) - const jsonData = []; + const jsonData = [] if (!csvFields.length) { // eslint-disable-next-line prefer-promise-reject-errors - return Promise.reject('Unable to transform schema data for CSV.'); + return Promise.reject('Unable to transform schema data for CSV.') } - const csv = parse(jsonData, { fields: csvFields }); - const filePath = join(process.cwd(), `uploadedFiles/exports`); - await createFile(filePath, fileName, csv); - const fullFilePath = join(process.cwd(), `uploadedFiles/exports/${fileName}`); - this.logger.log('fullFilePath::::::::', fullFilePath); //remove after user + const csv = parse(jsonData, { fields: csvFields }) + const filePath = join(process.cwd(), 'uploadedFiles/exports') + await createFile(filePath, fileName, csv) + const fullFilePath = join(process.cwd(), `uploadedFiles/exports/${fileName}`) + this.logger.log('fullFilePath::::::::', fullFilePath) //remove after user if (!checkIfFileOrDirectoryExists(fullFilePath)) { - throw new NotFoundException(ResponseMessages.bulkIssuance.error.PathNotFound); + throw new NotFoundException(ResponseMessages.bulkIssuance.error.PathNotFound) } // https required to download csv from frontend side - const filePathToDownload = `${process.env.API_GATEWAY_PROTOCOL_SECURE}://${process.env.UPLOAD_LOGO_HOST}/${fileName}`; + const filePathToDownload = `${process.env.API_GATEWAY_PROTOCOL_SECURE}://${process.env.UPLOAD_LOGO_HOST}/${fileName}` return { fileContent: filePathToDownload, - fileName - }; + fileName, + } } catch (error) { - this.logger.error(`error in downloading csv : ${JSON.stringify(error.response)}`); - throw new RpcException(error?.response ? error?.response : error); + this.logger.error(`error in downloading csv : ${JSON.stringify(error.response)}`) + throw new RpcException(error?.response ? error?.response : error) } } async uploadCSVTemplate(importFileDetails: ImportFileDetails, orgId: string, requestId?: string): Promise { try { - let credentialDetails; + // biome-ignore lint/suspicious/noImplicitAnyLet: + let credentialDetails const credentialPayload: ICredentialPayload = { schemaLedgerId: '', credentialDefinitionId: '', fileData: {}, fileName: '', credentialType: '', - schemaName: '' - }; + schemaName: '', + } - const orgDetails = await this.issuanceRepository.getAgentEndPoint(orgId); + const orgDetails = await this.issuanceRepository.getAgentEndPoint(orgId) - const { fileName, templateId, type, isValidateSchema } = importFileDetails; + const { fileName, templateId, type, isValidateSchema } = importFileDetails if (type === SchemaType.W3C_Schema) { - credentialDetails = await this.issuanceRepository.getSchemaDetailsBySchemaIdentifier(templateId); + credentialDetails = await this.issuanceRepository.getSchemaDetailsBySchemaIdentifier(templateId) if (orgDetails?.ledgerId !== credentialDetails?.ledgerId) { - throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched); + throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched) } - credentialPayload.schemaLedgerId = credentialDetails.schemaLedgerId; - credentialPayload.credentialDefinitionId = SchemaType.W3C_Schema; - credentialPayload.credentialType = SchemaType.W3C_Schema; - credentialPayload.schemaName = credentialDetails.name; + credentialPayload.schemaLedgerId = credentialDetails.schemaLedgerId + credentialPayload.credentialDefinitionId = SchemaType.W3C_Schema + credentialPayload.credentialType = SchemaType.W3C_Schema + credentialPayload.schemaName = credentialDetails.name } else if (type === SchemaType.INDY) { - credentialDetails = await this.issuanceRepository.getCredentialDefinitionDetails(templateId); - const schemaDetails = await this.issuanceRepository.getSchemaDetails(credentialDetails.schemaLedgerId); + credentialDetails = await this.issuanceRepository.getCredentialDefinitionDetails(templateId) + const schemaDetails = await this.issuanceRepository.getSchemaDetails(credentialDetails.schemaLedgerId) if (!schemaDetails) { - throw new NotFoundException(ResponseMessages.schema.error.notFound); + throw new NotFoundException(ResponseMessages.schema.error.notFound) } if (orgDetails?.ledgerId !== schemaDetails?.ledgerId) { - throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched); + throw new BadRequestException(ResponseMessages.issuance.error.ledgerMismatched) } - credentialPayload.schemaLedgerId = credentialDetails.schemaLedgerId; - credentialPayload.credentialDefinitionId = credentialDetails.credentialDefinitionId; - credentialPayload.credentialType = SchemaType.INDY; - credentialPayload.schemaName = credentialDetails.schemaName; + credentialPayload.schemaLedgerId = credentialDetails.schemaLedgerId + credentialPayload.credentialDefinitionId = credentialDetails.credentialDefinitionId + credentialPayload.credentialType = SchemaType.INDY + credentialPayload.schemaName = credentialDetails.schemaName } - const getFileDetails = await this.awsService.getFile(importFileDetails.fileKey); + const getFileDetails = await this.awsService.getFile(importFileDetails.fileKey) - const csvData: string = getFileDetails.Body.toString(); + const csvData: string = getFileDetails.Body.toString() const parsedData = paParse(csvData, { header: true, skipEmptyLines: true, transformheader: (header) => header.toLowerCase().replace('#', '').trim(), - complete: (results) => results.data - }); + complete: (results) => results.data, + }) - const nestedObject = parsedData.data.map((row) => unflattenCsvRow(row)); + const nestedObject = parsedData.data.map((row) => unflattenCsvRow(row)) - if (0 >= parsedData.data.length) { - throw new BadRequestException(ResponseMessages.bulkIssuance.error.emptyFile); + if (parsedData.data.length <= 0) { + throw new BadRequestException(ResponseMessages.bulkIssuance.error.emptyFile) } - if (0 >= parsedData.meta.fields.length) { - throw new BadRequestException(ResponseMessages.bulkIssuance.error.emptyheader); + if (parsedData.meta.fields.length <= 0) { + throw new BadRequestException(ResponseMessages.bulkIssuance.error.emptyheader) } - const invalidEmails = parsedData.data.filter((entry) => !validateEmail(entry.email_identifier.trim())); + const invalidEmails = parsedData.data.filter((entry) => !validateEmail(entry.email_identifier.trim())) - if (0 < invalidEmails.length) { - throw new BadRequestException(ResponseMessages.bulkIssuance.error.invalidEmails); + if (invalidEmails.length > 0) { + throw new BadRequestException(ResponseMessages.bulkIssuance.error.invalidEmails) } - const fileData: string[][] = nestedObject.map(Object.values); - const fileHeader: string[] = parsedData.meta.fields; - const attributesArray = JSON.parse(credentialDetails.attributes); + const fileData: string[][] = nestedObject.map(Object.values) + const fileHeader: string[] = parsedData.meta.fields + const attributesArray = JSON.parse(credentialDetails.attributes) // Extract the 'attributeName' values from the objects and store them in an array - const attributeNameArray = attributesArray.map((attribute) => attribute.attributeName); - if (0 >= attributeNameArray.length) { - throw new BadRequestException(`Attributes are empty for credential definition ${templateId}`); + const attributeNameArray = attributesArray.map((attribute) => attribute.attributeName) + if (attributeNameArray.length <= 0) { + throw new BadRequestException(`Attributes are empty for credential definition ${templateId}`) } - let validatedData; + // biome-ignore lint/suspicious/noImplicitAnyLet: + let validatedData if (type === SchemaType.W3C_Schema && isValidateSchema) { validatedData = parsedData.data.map((row) => { - const { email_identifier, ...rest } = row; - const newRow = { ...rest }; + const { email_identifier, ...rest } = row + const newRow = { ...rest } + // biome-ignore lint/complexity/noForEach: attributesArray.forEach((attr) => { if (!(attr?.attributeName in newRow)) { - throw new BadRequestException(`Missing attribute ${attr?.attributeName} in CSV data`); + throw new BadRequestException(`Missing attribute ${attr?.attributeName} in CSV data`) } if (W3CSchemaDataType.NUMBER === attr.schemaDataType) { - newRow[attr?.attributeName] = Number(newRow[attr?.attributeName]); - if (isNaN(newRow[attr.attributeName])) { - throw new BadRequestException(`Invalid data type for attribute ${attr?.attributeName}`); + newRow[attr?.attributeName] = Number(newRow[attr?.attributeName]) + if (Number.isNaN(newRow[attr.attributeName])) { + throw new BadRequestException(`Invalid data type for attribute ${attr?.attributeName}`) } } else if (W3CSchemaDataType.STRING === attr?.schemaDataType) { - newRow[attr?.attributeName] = String(newRow[attr?.attributeName]); + newRow[attr?.attributeName] = String(newRow[attr?.attributeName]) } - }); + }) - return { email_identifier, ...newRow }; - }); + return { email_identifier, ...newRow } + }) } else if (type === SchemaType.W3C_Schema && !isValidateSchema) { validatedData = nestedObject.map((row) => { - const { email_identifier, ...rest } = row; - const newRow = { ...rest }; + const { email_identifier, ...rest } = row + const newRow = { ...rest } - return { email_identifier, ...newRow }; - }); + return { email_identifier, ...newRow } + }) } const finalFileData = { data: validatedData, errors: [], - meta: parsedData.meta - }; + meta: parsedData.meta, + } if (isValidateSchema) { - await this.validateFileHeaders(fileHeader, attributeNameArray); - await this.validateFileData(fileData, attributesArray, fileHeader); + await this.validateFileHeaders(fileHeader, attributeNameArray) + await this.validateFileData(fileData, attributesArray, fileHeader) } - credentialPayload.fileData = type === SchemaType.W3C_Schema ? finalFileData : parsedData; - credentialPayload.fileName = fileName; - const newCacheKey = uuidv4(); - const cacheTTL = Number(process.env.FILEUPLOAD_CACHE_TTL) || CommonConstants.DEFAULT_CACHE_TTL; - await this.cacheManager.set(requestId || newCacheKey, JSON.stringify(credentialPayload), cacheTTL); + credentialPayload.fileData = type === SchemaType.W3C_Schema ? finalFileData : parsedData + credentialPayload.fileName = fileName + const newCacheKey = uuidv4() + const cacheTTL = Number(process.env.FILEUPLOAD_CACHE_TTL) || CommonConstants.DEFAULT_CACHE_TTL + await this.cacheManager.set(requestId || newCacheKey, JSON.stringify(credentialPayload), cacheTTL) - return newCacheKey; + return newCacheKey } catch (error) { - this.logger.error(`error in validating credentials : ${error.response}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`error in validating credentials : ${error.response}`) + throw new RpcException(error.response ? error.response : error) } } async previewFileDataForIssuance(requestId: string, previewRequest: PreviewRequest): Promise { try { - if ('' !== requestId.trim()) { - const cachedData = await this.cacheManager.get(requestId); + if (requestId.trim() !== '') { + const cachedData = await this.cacheManager.get(requestId) if (!cachedData) { - throw new NotFoundException(ResponseMessages.issuance.error.emptyFileData); + throw new NotFoundException(ResponseMessages.issuance.error.emptyFileData) } if (cachedData === undefined || null) { - throw new BadRequestException(ResponseMessages.issuance.error.previewCachedData); + throw new BadRequestException(ResponseMessages.issuance.error.previewCachedData) } - const parsedData = JSON.parse(cachedData as string).fileData.data; + const parsedData = JSON.parse(cachedData as string).fileData.data // Apply search to the entire dataset if searchByText is provided - let filteredData = parsedData; + let filteredData = parsedData if (previewRequest.searchByText) { - const searchTerm = previewRequest.searchByText.toLowerCase(); + const searchTerm = previewRequest.searchByText.toLowerCase() filteredData = parsedData.filter( (item) => item.email_identifier.toLowerCase().includes(searchTerm) || item.name.toLowerCase().includes(searchTerm) - ); + ) } // Apply pagination to the filtered data - const finalData = paginator(filteredData, previewRequest.pageNumber, previewRequest.pageSize); + const finalData = paginator(filteredData, previewRequest.pageNumber, previewRequest.pageSize) - return finalData; - } else { - throw new BadRequestException(ResponseMessages.issuance.error.previewFile); + return finalData } + throw new BadRequestException(ResponseMessages.issuance.error.previewFile) } catch (error) { - this.logger.error(`error in previewFileDataForIssuance : ${error}`); - throw new RpcException(error.response); + this.logger.error(`error in previewFileDataForIssuance : ${error}`) + throw new RpcException(error.response) } } async getFileDetailsByFileId(fileId: string, getAllfileDetails: PreviewRequest): Promise { try { - const fileData = await this.issuanceRepository.getFileDetailsByFileId(fileId, getAllfileDetails); + const fileData = await this.issuanceRepository.getFileDetailsByFileId(fileId, getAllfileDetails) const fileResponse = { totalItems: fileData.fileCount, hasNextPage: getAllfileDetails.pageSize * getAllfileDetails.pageNumber < fileData.fileCount, - hasPreviousPage: 1 < getAllfileDetails.pageNumber, + hasPreviousPage: getAllfileDetails.pageNumber > 1, nextPage: Number(getAllfileDetails.pageNumber) + 1, previousPage: getAllfileDetails.pageNumber - 1, lastPage: Math.ceil(fileData.fileCount / getAllfileDetails.pageSize), - data: fileData.fileDataList - }; + data: fileData.fileDataList, + } - if (0 !== fileData.fileCount) { - return fileResponse; - } else { - throw new NotFoundException(ResponseMessages.issuance.error.fileNotFound); + if (fileData.fileCount !== 0) { + return fileResponse } + throw new NotFoundException(ResponseMessages.issuance.error.fileNotFound) } catch (error) { - this.logger.error(`error in issuedFileDetails : ${error}`); - throw new RpcException(error.response); + this.logger.error(`error in issuedFileDetails : ${error}`) + throw new RpcException(error.response) } } async issuedFileDetails(orgId: string, getAllfileDetails: PreviewRequest): Promise { try { - const fileDetails = await this.issuanceRepository.getAllFileDetails(orgId, getAllfileDetails); + const fileDetails = await this.issuanceRepository.getAllFileDetails(orgId, getAllfileDetails) - const templateIds = fileDetails?.fileList.map((file) => file.templateId); + const templateIds = fileDetails?.fileList.map((file) => file.templateId) - const getSchemaDetails = await this._getSchemaDetails(templateIds); + const getSchemaDetails = await this._getSchemaDetails(templateIds) const fileListWithSchema = fileDetails?.fileList.map((file) => { - const schemaDetail = getSchemaDetails?.find((schema) => schema.schemaLedgerId === file.templateId); + const schemaDetail = getSchemaDetails?.find((schema) => schema.schemaLedgerId === file.templateId) return { ...file, schema: schemaDetail ? { name: schemaDetail.name, version: schemaDetail.version, schemaType: schemaDetail.type } - : null - }; - }); + : null, + } + }) const fileResponse = { totalItems: fileDetails.fileCount, hasNextPage: getAllfileDetails.pageSize * getAllfileDetails.pageNumber < fileDetails.fileCount, - hasPreviousPage: 1 < getAllfileDetails.pageNumber, + hasPreviousPage: getAllfileDetails.pageNumber > 1, nextPage: Number(getAllfileDetails.pageNumber) + 1, previousPage: getAllfileDetails.pageNumber - 1, lastPage: Math.ceil(fileDetails.fileCount / getAllfileDetails.pageSize), - data: fileListWithSchema - }; + data: fileListWithSchema, + } - if (0 !== fileDetails.fileCount) { - return fileResponse; - } else { - throw new NotFoundException(ResponseMessages.issuance.error.notFound); + if (fileDetails.fileCount !== 0) { + return fileResponse } + throw new NotFoundException(ResponseMessages.issuance.error.notFound) } catch (error) { - this.logger.error(`error in issuedFileDetails : ${error}`); - throw new RpcException(error.response); + this.logger.error(`error in issuedFileDetails : ${error}`) + throw new RpcException(error.response) } } async _getSchemaDetails(templateIds: string[]): Promise { - const pattern = { cmd: 'get-schemas-details' }; + const pattern = { cmd: 'get-schemas-details' } const payload = { - templateIds - }; + templateIds, + } const schemaDetails = await this.natsClient .send(this.issuanceServiceProxy, pattern, payload) .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); - return schemaDetails; + ) + }) + return schemaDetails } async delay(ms): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); + return new Promise((resolve) => setTimeout(resolve, ms)) } /** @@ -1555,17 +1567,17 @@ export class IssuanceService { */ private async processInBatches(bulkPayload, bulkPayloadDetails: BulkPayloadDetails): Promise { - const { clientId, isRetry, orgId, requestId, isValidateSchema } = bulkPayloadDetails; - const delay = (ms: number): Promise => new Promise((resolve) => setTimeout(resolve, ms)); - const batchSize = CommonConstants.ISSUANCE_BATCH_SIZE; // initial 1000 - const uniqueJobId = uuidv4(); - const limit = pLimit(CommonConstants.ISSUANCE_MAX_CONCURRENT_OPERATIONS); + const { clientId, isRetry, orgId, requestId, isValidateSchema } = bulkPayloadDetails + const delay = (ms: number): Promise => new Promise((resolve) => setTimeout(resolve, ms)) + const batchSize = CommonConstants.ISSUANCE_BATCH_SIZE // initial 1000 + const uniqueJobId = uuidv4() + const limit = pLimit(CommonConstants.ISSUANCE_MAX_CONCURRENT_OPERATIONS) // Generator function to yield batches // eslint-disable-next-line @typescript-eslint/explicit-function-return-type function* createBatches(array, size) { for (let i = 0; i < array.length; i += size) { - yield array.slice(i, i + size); + yield array.slice(i, i + size) } } @@ -1595,30 +1607,30 @@ export class IssuanceService { size: bulkPayloadDetails?.size, orientation: bulkPayloadDetails?.orientation, height: bulkPayloadDetails?.height, - width: bulkPayloadDetails?.width - } - })); + width: bulkPayloadDetails?.width, + }, + })) - this.logger.log(`Processing batch ${batchIndex + 1} with ${batch.length} items.`); + this.logger.log(`Processing batch ${batchIndex + 1} with ${batch.length} items.`) // Execute the batched jobs with limited concurrency - await Promise.all(queueJobsArray.map((job) => limit(() => job))); - return queueJobsArray; - }; + await Promise.all(queueJobsArray.map((job) => limit(() => job))) + return queueJobsArray + } - let batchIndex = 0; + let batchIndex = 0 for (const batch of createBatches(bulkPayload, batchSize)) { - const resolvedBatchJobs = await processBatch(batch, batchIndex); + const resolvedBatchJobs = await processBatch(batch, batchIndex) - this.logger.log('Adding resolved jobs to the queue:', resolvedBatchJobs); - await this.bulkIssuanceQueue.addBulk(resolvedBatchJobs); + this.logger.log('Adding resolved jobs to the queue:', resolvedBatchJobs) + await this.bulkIssuanceQueue.addBulk(resolvedBatchJobs) - batchIndex++; + batchIndex++ // Wait for 60 seconds before processing the next batch, if more batches are remaining if (batchIndex * batchSize < bulkPayload.length) { - await delay(CommonConstants.ISSUANCE_BATCH_DELAY); + await delay(CommonConstants.ISSUANCE_BATCH_DELAY) } } } @@ -1639,7 +1651,7 @@ export class IssuanceService { isValidateSchema: boolean ): Promise { if (!requestId) { - throw new BadRequestException(ResponseMessages.issuance.error.missingRequestId); + throw new BadRequestException(ResponseMessages.issuance.error.missingRequestId) } const fileUpload: FileUpload = { lastChangedDateTime: null, @@ -1648,59 +1660,59 @@ export class IssuanceService { orgId: '', createDateTime: null, name: '', - credentialType: '' - }; + credentialType: '', + } - let csvFileDetail; + let csvFileDetail: file_upload try { - let cachedData = await this.cacheManager.get(requestId); + let cachedData = await this.cacheManager.get(requestId) if (!cachedData) { - throw new BadRequestException(ResponseMessages.issuance.error.cacheTimeOut); + throw new BadRequestException(ResponseMessages.issuance.error.cacheTimeOut) } // For demo UI if (cachedData && clientDetails?.isSelectiveIssuance) { - await this.cacheManager.del(requestId); - await this.uploadCSVTemplate(reqPayload, requestId); - cachedData = await this.cacheManager.get(requestId); + await this.cacheManager.del(requestId) + await this.uploadCSVTemplate(reqPayload, requestId) + cachedData = await this.cacheManager.get(requestId) } - const parsedData = JSON.parse(cachedData as string).fileData.data; + const parsedData = JSON.parse(cachedData as string).fileData.data if (!parsedData) { - throw new BadRequestException(ResponseMessages.issuance.error.cachedData); + throw new BadRequestException(ResponseMessages.issuance.error.cachedData) } - const parsedFileDetails = JSON.parse(cachedData as string); + const parsedFileDetails = JSON.parse(cachedData as string) if (!parsedFileDetails) { - throw new BadRequestException(ResponseMessages.issuance.error.cachedfileData); + throw new BadRequestException(ResponseMessages.issuance.error.cachedfileData) } - fileUpload.upload_type = FileUploadType.Issuance; - fileUpload.status = FileUploadStatus.started; - fileUpload.orgId = orgId; - fileUpload.createDateTime = new Date(); - fileUpload.name = parsedFileDetails.fileName; - fileUpload.credentialType = parsedFileDetails.credentialType; - fileUpload.templateId = parsedFileDetails?.schemaLedgerId; - csvFileDetail = await this.issuanceRepository.saveFileUploadDetails(fileUpload, clientDetails.userId); + fileUpload.upload_type = FileUploadType.Issuance + fileUpload.status = FileUploadStatus.started + fileUpload.orgId = orgId + fileUpload.createDateTime = new Date() + fileUpload.name = parsedFileDetails.fileName + fileUpload.credentialType = parsedFileDetails.credentialType + fileUpload.templateId = parsedFileDetails?.schemaLedgerId + csvFileDetail = await this.issuanceRepository.saveFileUploadDetails(fileUpload, clientDetails.userId) const bulkPayloadObject: IBulkPayloadObject = { parsedData, parsedFileDetails, userId: clientDetails.userId, - fileUploadId: csvFileDetail.id - }; + fileUploadId: csvFileDetail.id, + } - const storeBulkPayload = await this._storeBulkPayloadInBatch(bulkPayloadObject); + const storeBulkPayload = await this._storeBulkPayloadInBatch(bulkPayloadObject) if (!storeBulkPayload) { - throw new BadRequestException(ResponseMessages.issuance.error.storeBulkData); + throw new BadRequestException(ResponseMessages.issuance.error.storeBulkData) } // Process in batches - const bulkPayload = await this.issuanceRepository.getFileDetails(csvFileDetail.id); + const bulkPayload = await this.issuanceRepository.getFileDetails(csvFileDetail.id) if (!bulkPayload) { - throw new BadRequestException(ResponseMessages.issuance.error.fileData); + throw new BadRequestException(ResponseMessages.issuance.error.fileData) } try { @@ -1716,23 +1728,23 @@ export class IssuanceService { size: clientDetails?.size, orientation: clientDetails?.orientation, height: clientDetails?.height, - width: clientDetails?.width - }; + width: clientDetails?.width, + } - this.processInBatches(bulkPayload, bulkPayloadDetails); + this.processInBatches(bulkPayload, bulkPayloadDetails) } catch (error) { - this.logger.error(`Error processing issuance data: ${error}`); + this.logger.error(`Error processing issuance data: ${error}`) } - return ResponseMessages.issuance.success.bulkProcess; + return ResponseMessages.issuance.success.bulkProcess } catch (error) { - fileUpload.status = FileUploadStatus.interrupted; - this.logger.error(`Error in issueBulkCredential: ${error}`); - throw new RpcException(error.response); + fileUpload.status = FileUploadStatus.interrupted + this.logger.error(`Error in issueBulkCredential: ${error}`) + throw new RpcException(error.response) } finally { if (csvFileDetail !== undefined && csvFileDetail.id !== undefined) { - fileUpload.lastChangedDateTime = new Date(); - await this.issuanceRepository.updateFileUploadDetails(csvFileDetail.id, fileUpload); + fileUpload.lastChangedDateTime = new Date() + await this.issuanceRepository.updateFileUploadDetails(csvFileDetail.id, fileUpload) } } } @@ -1743,16 +1755,16 @@ export class IssuanceService { clientDetails: IClientDetails, isValidateSchema?: boolean ): Promise { - let bulkpayloadRetry; + let bulkpayloadRetry: file_data[] try { - const fileDetails = await this.issuanceRepository.getFileDetailsById(fileId); + const fileDetails = await this.issuanceRepository.getFileDetailsById(fileId) if (!fileDetails) { - throw new BadRequestException(ResponseMessages.issuance.error.retry); + throw new BadRequestException(ResponseMessages.issuance.error.retry) } - bulkpayloadRetry = await this.issuanceRepository.getFailedCredentials(fileId); - if (0 === bulkpayloadRetry.length) { - const errorMessage = ResponseMessages.bulkIssuance.error.fileDetailsNotFound; - throw new BadRequestException(`${errorMessage}`); + bulkpayloadRetry = await this.issuanceRepository.getFailedCredentials(fileId) + if (bulkpayloadRetry.length === 0) { + const errorMessage = ResponseMessages.bulkIssuance.error.fileDetailsNotFound + throw new BadRequestException(`${errorMessage}`) } try { @@ -1767,28 +1779,28 @@ export class IssuanceService { size: clientDetails?.size, orientation: clientDetails?.orientation, height: clientDetails?.height, - width: clientDetails?.width - }; - this.processInBatches(bulkpayloadRetry, bulkPayloadDetails); + width: clientDetails?.width, + } + this.processInBatches(bulkpayloadRetry, bulkPayloadDetails) } catch (error) { - this.logger.error(`Error processing issuance data: ${error}`); + this.logger.error(`Error processing issuance data: ${error}`) } - return ResponseMessages.bulkIssuance.success.reinitiated; + return ResponseMessages.bulkIssuance.success.reinitiated } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } async processIssuanceData(jobDetails: IQueuePayload): Promise { - const { jobId, totalJobs } = jobDetails; + const { jobId, totalJobs } = jobDetails if (!this.processedJobsCounters[jobId]) { - this.processedJobsCounters[jobId] = 0; + this.processedJobsCounters[jobId] = 0 } - this.processedJobsCounters[jobId] += 1; + this.processedJobsCounters[jobId] += 1 if (this.processedJobsCounters[jobId] === totalJobs) { - jobDetails.isLastData = true; - delete this.processedJobsCounters[jobId]; + jobDetails.isLastData = true + delete this.processedJobsCounters[jobId] } const fileUploadData: FileUploadData = { @@ -1799,23 +1811,24 @@ export class IssuanceService { createDateTime: undefined, error: '', detailError: '', - jobId: '' - }; - - fileUploadData.fileUpload = jobDetails.fileUploadId; - fileUploadData.fileRow = JSON.stringify(jobDetails); - fileUploadData.isError = false; - fileUploadData.createDateTime = new Date(); - fileUploadData.referenceId = jobDetails?.credential_data?.email_identifier; - fileUploadData.jobId = jobDetails.id; - const { orgId } = jobDetails; - - const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId); - const { organisation, orgDid } = agentDetails; - let prettyVc; - let isErrorOccurred = false; + jobId: '', + } + + fileUploadData.fileUpload = jobDetails.fileUploadId + fileUploadData.fileRow = JSON.stringify(jobDetails) + fileUploadData.isError = false + fileUploadData.createDateTime = new Date() + fileUploadData.referenceId = jobDetails?.credential_data?.email_identifier + fileUploadData.jobId = jobDetails.id + const { orgId } = jobDetails + + const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId) + const { organisation, orgDid } = agentDetails + let prettyVc: IPrettyVc + let isErrorOccurred = false try { - let oobIssuancepayload; + // biome-ignore lint/suspicious/noImplicitAnyLet: + let oobIssuancepayload if (jobDetails.credentialType === SchemaType.INDY) { oobIssuancepayload = { credentialDefinitionId: jobDetails.credentialDefinitionId, @@ -1824,38 +1837,39 @@ export class IssuanceService { attributes: [], emailId: jobDetails?.credential_data?.email_identifier, credentialType: IssueCredentialType.INDY, - isReuseConnection: true - }; + isReuseConnection: true, + } for (const key in jobDetails?.credential_data) { + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (jobDetails.credential_data.hasOwnProperty(key) && TemplateIdentifier.EMAIL_COLUMN !== key) { - const value = jobDetails?.credential_data[key]; - oobIssuancepayload.attributes.push({ name: key, value }); + const value = jobDetails?.credential_data[key] + oobIssuancepayload.attributes.push({ name: key, value }) } } } else if (jobDetails.credentialType === SchemaType.W3C_Schema) { const schemaDetails = await this.issuanceRepository.getSchemaDetailsBySchemaIdentifier( jobDetails.schemaLedgerId - ); - const { name, schemaLedgerId } = schemaDetails; + ) + const { name, schemaLedgerId } = schemaDetails const JsonldCredentialDetails: IJsonldCredential = { schemaName: name, schemaLedgerId, credentialData: jobDetails.credential_data, orgDid, orgId, - isReuseConnection: true - }; + isReuseConnection: true, + } prettyVc = { certificate: jobDetails?.certificate, size: jobDetails?.size, orientation: jobDetails?.orientation, height: jobDetails?.height, - width: jobDetails?.width - }; + width: jobDetails?.width, + } - oobIssuancepayload = await createOobJsonldIssuancePayload(JsonldCredentialDetails, prettyVc); - oobIssuancepayload.isValidateSchema = jobDetails?.isValidateSchema; + oobIssuancepayload = await createOobJsonldIssuancePayload(JsonldCredentialDetails, prettyVc) + oobIssuancepayload.isValidateSchema = jobDetails?.isValidateSchema } const oobCredentials = await this.outOfBandCredentialOffer( @@ -1863,101 +1877,102 @@ export class IssuanceService { jobDetails?.platformName, jobDetails?.organizationLogoUrl, prettyVc - ); + ) if (oobCredentials) { - await this.issuanceRepository.deleteFileDataByJobId(jobDetails.id); + await this.issuanceRepository.deleteFileDataByJobId(jobDetails.id) } } catch (error) { - this.logger.error(`error in issuanceBulkCredential for data : ${JSON.stringify(error)}`); - fileUploadData.isError = true; - fileUploadData.error = JSON.stringify(error.error) ? JSON.stringify(error.error) : JSON.stringify(error); - fileUploadData.detailError = `${JSON.stringify(error)}`; + this.logger.error(`error in issuanceBulkCredential for data : ${JSON.stringify(error)}`) + fileUploadData.isError = true + fileUploadData.error = JSON.stringify(error.error) ? JSON.stringify(error.error) : JSON.stringify(error) + fileUploadData.detailError = `${JSON.stringify(error)}` if (!isErrorOccurred) { - isErrorOccurred = true; + isErrorOccurred = true } } - await this.issuanceRepository.updateFileUploadData(fileUploadData); + await this.issuanceRepository.updateFileUploadData(fileUploadData) try { if (jobDetails.isLastData) { const socket = await io(`${process.env.SOCKET_HOST}`, { reconnection: true, reconnectionDelay: 5000, - reconnectionAttempts: Infinity, + reconnectionAttempts: Number.POSITIVE_INFINITY, autoConnect: true, - transports: ['websocket'] - }); - const errorCount = await this.issuanceRepository.countErrorsForFile(jobDetails.fileUploadId); - const status = 0 === errorCount ? FileUploadStatus.completed : FileUploadStatus.partially_completed; + transports: ['websocket'], + }) + const errorCount = await this.issuanceRepository.countErrorsForFile(jobDetails.fileUploadId) + const status = errorCount === 0 ? FileUploadStatus.completed : FileUploadStatus.partially_completed if (!jobDetails.isRetry) { socket.emit('bulk-issuance-process-completed', { clientId: jobDetails.clientId, - fileUploadId: jobDetails.fileUploadId - }); - this.cacheManager.del(jobDetails.cacheId); + fileUploadId: jobDetails.fileUploadId, + }) + this.cacheManager.del(jobDetails.cacheId) } else { socket.emit('bulk-issuance-process-retry-completed', { clientId: jobDetails.clientId, - fileUploadId: jobDetails.fileUploadId - }); + fileUploadId: jobDetails.fileUploadId, + }) } await this.issuanceRepository.updateFileUploadDetails(jobDetails.fileUploadId, { status, - lastChangedDateTime: new Date() - }); + lastChangedDateTime: new Date(), + }) } } catch (error) { - this.logger.error(`Error in completing bulk issuance process: ${error}`); + this.logger.error(`Error in completing bulk issuance process: ${error}`) const socket = await io(`${process.env.SOCKET_HOST}`, { reconnection: true, reconnectionDelay: 5000, - reconnectionAttempts: Infinity, + reconnectionAttempts: Number.POSITIVE_INFINITY, autoConnect: true, - transports: ['websocket'] - }); + transports: ['websocket'], + }) if (!isErrorOccurred) { - isErrorOccurred = true; + isErrorOccurred = true socket.emit('error-in-bulk-issuance-process', { clientId: jobDetails.clientId, error, - fileUploadId: jobDetails.fileUploadId - }); + fileUploadId: jobDetails.fileUploadId, + }) } - throw error; + throw error } - return true; + return true } async splitIntoBatches(array: T[], batchSize: number): Promise { - const batches = []; + const batches = [] for (let i = 0; i < array.length; i += batchSize) { - batches.push(array.slice(i, i + batchSize)); + batches.push(array.slice(i, i + batchSize)) } - return batches; + return batches } async validateFileHeaders(fileHeader: string[], schemaAttributes: string[]): Promise { try { - const fileSchemaHeader: string[] = fileHeader.slice(); + const fileSchemaHeader: string[] = fileHeader.slice() if (TemplateIdentifier.EMAIL_COLUMN === fileHeader[0]) { - fileSchemaHeader.splice(0, 1); + fileSchemaHeader.splice(0, 1) } else { - throw new BadRequestException(ResponseMessages.bulkIssuance.error.emailColumn); + throw new BadRequestException(ResponseMessages.bulkIssuance.error.emailColumn) } if (schemaAttributes.length !== fileSchemaHeader.length) { - throw new ConflictException(ResponseMessages.bulkIssuance.error.attributeNumber); + throw new ConflictException(ResponseMessages.bulkIssuance.error.attributeNumber) } - const mismatchedAttributes = fileSchemaHeader.filter((value) => !schemaAttributes.includes(value)); + const mismatchedAttributes = fileSchemaHeader.filter((value) => !schemaAttributes.includes(value)) - if (0 < mismatchedAttributes.length) { - throw new ConflictException(ResponseMessages.bulkIssuance.error.mismatchedAttributes); + if (mismatchedAttributes.length > 0) { + throw new ConflictException(ResponseMessages.bulkIssuance.error.mismatchedAttributes) } } catch (error) { - throw error; + // biome-ignore lint/complexity/noUselessCatch: + throw error } } @@ -1970,66 +1985,69 @@ export class IssuanceService { const filedata = fileData.map((item: string[]) => { const fileHeaderData = item?.map((element, j) => ({ value: element, - header: fileHeader[j] - })); - return fileHeaderData; - }); + header: fileHeader[j], + })) + return fileHeaderData + }) - const errorFileData = []; + const errorFileData = [] filedata.forEach((attr, i) => { + // biome-ignore lint/complexity/noForEach: attr.forEach((eachElement) => { + // biome-ignore lint/complexity/noForEach: attributesArray.forEach((eachItem) => { if (eachItem.attributeName === eachElement.header) { if (eachItem.isRequired && !eachElement.value) { - errorFileData.push(`Attribute ${eachItem.attributeName} is required at row ${i + 1}`); + errorFileData.push(`Attribute ${eachItem.attributeName} is required at row ${i + 1}`) } } - }); - return eachElement; - }); - return attr; - }); + }) + return eachElement + }) + return attr + }) - if (0 < errorFileData.length) { - throw new BadRequestException(errorFileData); + if (errorFileData.length > 0) { + throw new BadRequestException(errorFileData) } } catch (error) { - throw error; + // biome-ignore lint/complexity/noUselessCatch: + throw error } } async _getOrgAgentApiKey(orgId: string): Promise { - const pattern = { cmd: 'get-org-agent-api-key' }; - const payload = { orgId }; + 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.natsClient.send(this.issuanceServiceProxy, pattern, payload); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.natsClient.send(this.issuanceServiceProxy, pattern, payload) + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } async _storeBulkPayloadInBatch(bulkPayloadObject: IBulkPayloadObject): Promise { try { - const { parsedFileDetails, parsedData, fileUploadId, userId } = bulkPayloadObject; + const { parsedFileDetails, parsedData, fileUploadId, userId } = bulkPayloadObject - const limit = pLimit(CommonConstants.MAX_CONCURRENT_OPERATIONS); - const startTime = Date.now(); - const batches = await this.splitIntoBatches(parsedData, CommonConstants.BATCH_SIZE); - this.logger.log('Total number of batches:', batches.length); + const limit = pLimit(CommonConstants.MAX_CONCURRENT_OPERATIONS) + const startTime = Date.now() + const batches = await this.splitIntoBatches(parsedData, CommonConstants.BATCH_SIZE) + this.logger.log('Total number of batches:', batches.length) for (const [index, batch] of batches.entries()) { - const batchStartTime = Date.now(); + const batchStartTime = Date.now() // Create an array of limited promises for the current batch const saveFileDetailsPromises = batch.map((element) => @@ -2042,48 +2060,48 @@ export class IssuanceService { state: false, isError: false, fileUploadId, - credentialType: parsedFileDetails.credentialType - }; - return this.issuanceRepository.saveFileDetails(credentialPayload, userId); + credentialType: parsedFileDetails.credentialType, + } + return this.issuanceRepository.saveFileDetails(credentialPayload, userId) }) - ); + ) - this.logger.log(`Processing batch ${index + 1} with ${batch.length} elements...`); + this.logger.log(`Processing batch ${index + 1} with ${batch.length} elements...`) // Wait for all operations in the current batch to complete before moving to the next batch - await Promise.all(saveFileDetailsPromises); + await Promise.all(saveFileDetailsPromises) - const batchEndTime = Date.now(); // End timing the current batch - this.logger.log(`Batch ${index + 1} processed in ${batchEndTime - batchStartTime} milliseconds.`); + const batchEndTime = Date.now() // End timing the current batch + this.logger.log(`Batch ${index + 1} processed in ${batchEndTime - batchStartTime} milliseconds.`) } - const endTime = Date.now(); - this.logger.log(`Total processing time: ${endTime - startTime} milliseconds.`); - return true; + const endTime = Date.now() + this.logger.log(`Total processing time: ${endTime - startTime} milliseconds.`) + return true } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } async deleteIssuanceRecords(orgId: string, userDetails: user): Promise { try { - const getFileUploadData = await this.issuanceRepository.getFileUploadDataByOrgId(orgId); + const getFileUploadData = await this.issuanceRepository.getFileUploadDataByOrgId(orgId) - const getFileUploadIds = getFileUploadData.map((fileData) => fileData.id); + const getFileUploadIds = getFileUploadData.map((fileData) => fileData.id) - await this.issuanceRepository.deleteFileUploadData(getFileUploadIds, orgId); + await this.issuanceRepository.deleteFileUploadData(getFileUploadIds, orgId) - const deletedCredentialsRecords = await this.issuanceRepository.deleteIssuanceRecordsByOrgId(orgId); + const deletedCredentialsRecords = await this.issuanceRepository.deleteIssuanceRecordsByOrgId(orgId) - if (0 === deletedCredentialsRecords?.deleteResult?.count) { - throw new NotFoundException(ResponseMessages.issuance.error.issuanceRecordsNotFound); + if (deletedCredentialsRecords?.deleteResult?.count === 0) { + throw new NotFoundException(ResponseMessages.issuance.error.issuanceRecordsNotFound) } const statusCounts = { @@ -2097,46 +2115,46 @@ export class IssuanceService { [IssuanceProcessState.DECLIEND]: 0, [IssuanceProcessState.CREDENTIAL_RECEIVED]: 0, [IssuanceProcessState.CREDENTIAL_ISSUED]: 0, - [IssuanceProcessState.ABANDONED]: 0 - }; + [IssuanceProcessState.ABANDONED]: 0, + } await Promise.all( deletedCredentialsRecords?.recordsToDelete?.map(async (record) => { - statusCounts[record.state]++; + statusCounts[record.state]++ }) - ); + ) - const filteredStatusCounts = Object.fromEntries(Object.entries(statusCounts).filter((entry) => 0 < entry[1])); + const filteredStatusCounts = Object.fromEntries(Object.entries(statusCounts).filter((entry) => entry[1] > 0)) const deletedIssuanceData = { deletedCredentialsRecordsCount: deletedCredentialsRecords?.deleteResult?.count, - deletedRecordsStatusCount: filteredStatusCounts - }; + deletedRecordsStatusCount: filteredStatusCounts, + } await this.userActivityRepository._orgDeletedActivity( orgId, userDetails, deletedIssuanceData, RecordType.ISSUANCE_RECORD - ); + ) - return deletedCredentialsRecords; + return deletedCredentialsRecords } catch (error) { - this.logger.error(`[deleteIssuanceRecords] - error in deleting issuance records: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[deleteIssuanceRecords] - error in deleting issuance records: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getFileDetailsAndFileDataByFileId(fileId: string, orgId: string): Promise { try { - const fileDetails = await this.issuanceRepository.getFileDetailsAndFileDataByFileId(fileId, orgId); + const fileDetails = await this.issuanceRepository.getFileDetailsAndFileDataByFileId(fileId, orgId) if (!fileDetails) { - throw new NotFoundException(ResponseMessages.issuance.error.fileNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.fileNotFound) } - return fileDetails; + return fileDetails } catch (error) { - this.logger.error(`error in getFileDetailsAndFileDataByFileId : ${error}`); - throw new RpcException(error.response); + this.logger.error(`error in getFileDetailsAndFileDataByFileId : ${error}`) + throw new RpcException(error.response) } } } diff --git a/apps/issuance/src/main.ts b/apps/issuance/src/main.ts index 5f435d931..3ae02ea5d 100644 --- a/apps/issuance/src/main.ts +++ b/apps/issuance/src/main.ts @@ -1,25 +1,23 @@ -import { NestFactory } from '@nestjs/core'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { IssuanceModule } from '../src/issuance.module'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { IssuanceModule } from '../src/issuance.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(IssuanceModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.ISSUANCE_SERVICE, process.env.ISSUANCE_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.ISSUANCE_SERVICE, process.env.ISSUANCE_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Issuance-Service Microservice is listening to NATS '); + await app.listen() + logger.log('Issuance-Service Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/issuance/templates/out-of-band-issuance.template.ts b/apps/issuance/templates/out-of-band-issuance.template.ts index 9723ba305..ac2a63336 100644 --- a/apps/issuance/templates/out-of-band-issuance.template.ts +++ b/apps/issuance/templates/out-of-band-issuance.template.ts @@ -6,10 +6,9 @@ export class OutOfBandIssuance { platformName?: string, organizationLogoUrl?: string ): string { - - const logoUrl = organizationLogoUrl || process.env.BRAND_LOGO; - const platform = platformName || process.env.PLATFORM_NAME; - const poweredBy = platformName || process.env.POWERED_BY; + const logoUrl = organizationLogoUrl || process.env.BRAND_LOGO + const platform = platformName || process.env.PLATFORM_NAME + const poweredBy = platformName || process.env.POWERED_BY try { return ` @@ -94,7 +93,7 @@ export class OutOfBandIssuance { - `; - } catch (error) {} + ` + } catch (_error) {} } } diff --git a/apps/ledger/libs/helpers/w3c.schema.builder.ts b/apps/ledger/libs/helpers/w3c.schema.builder.ts index da967ff39..941c4ad07 100644 --- a/apps/ledger/libs/helpers/w3c.schema.builder.ts +++ b/apps/ledger/libs/helpers/w3c.schema.builder.ts @@ -1,136 +1,136 @@ -import { IW3CAttributeValue } from '@credebl/common/interfaces/interface'; -import { ISchemaAttributesFormat } from 'apps/ledger/src/schema/interfaces/schema-payload.interface'; -import { IProductSchema } from 'apps/ledger/src/schema/interfaces/schema.interface'; -import ExclusiveMinimum from 'libs/validations/exclusiveMinimum'; -import MaxItems from 'libs/validations/maxItems'; -import MaxLength from 'libs/validations/maxLength'; -import Minimum from 'libs/validations/minimum'; -import MinItems from 'libs/validations/minItems'; -import MinLength from 'libs/validations/minLength'; -import MultipleOf from 'libs/validations/multipleOf'; -import Pattern from 'libs/validations/pattern'; -import UniqueItems from 'libs/validations/uniqueItems'; +import type { IW3CAttributeValue } from '@credebl/common/interfaces/interface' +import type { ISchemaAttributesFormat } from 'apps/ledger/src/schema/interfaces/schema-payload.interface' +import type { IProductSchema } from 'apps/ledger/src/schema/interfaces/schema.interface' +import ExclusiveMinimum from 'libs/validations/exclusiveMinimum' +import MaxItems from 'libs/validations/maxItems' +import MaxLength from 'libs/validations/maxLength' +import MinItems from 'libs/validations/minItems' +import MinLength from 'libs/validations/minLength' +import Minimum from 'libs/validations/minimum' +import MultipleOf from 'libs/validations/multipleOf' +import Pattern from 'libs/validations/pattern' +import UniqueItems from 'libs/validations/uniqueItems' export function w3cSchemaBuilder(attributes: IW3CAttributeValue[], schemaName: string, description: string): object { // Function to apply validations based on attribute properties const applyValidations = (attribute, propertyObj): ISchemaAttributesFormat => { - const context = { ...propertyObj }; + const context = { ...propertyObj } // Apply string validations - if ('string' === attribute.schemaDataType.toLowerCase()) { + if (attribute.schemaDataType.toLowerCase() === 'string') { if (attribute.minLength !== undefined) { - const validation = new MinLength(attribute.minLength); - validation.json(context); + const validation = new MinLength(attribute.minLength) + validation.json(context) } if (attribute.maxLength !== undefined) { - const validation = new MaxLength(attribute.maxLength); - validation.json(context); + const validation = new MaxLength(attribute.maxLength) + validation.json(context) } if (attribute.pattern !== undefined) { - const validation = new Pattern(attribute.pattern); - validation.json(context); + const validation = new Pattern(attribute.pattern) + validation.json(context) } } // Apply number validations if (['number', 'integer'].includes(attribute.schemaDataType.toLowerCase())) { if (attribute.minimum !== undefined) { - const validation = new Minimum(attribute.minimum); - validation.json(context); + const validation = new Minimum(attribute.minimum) + validation.json(context) } if (attribute.exclusiveMinimum !== undefined) { - const validation = new ExclusiveMinimum(attribute.exclusiveMinimum); - validation.json(context); + const validation = new ExclusiveMinimum(attribute.exclusiveMinimum) + validation.json(context) } if (attribute.multipleOf !== undefined) { - const validation = new MultipleOf(attribute.multipleOf); - validation.json(context); + const validation = new MultipleOf(attribute.multipleOf) + validation.json(context) } } // Apply array validations - if ('array' === attribute.schemaDataType.toLowerCase()) { + if (attribute.schemaDataType.toLowerCase() === 'array') { if (attribute.minItems !== undefined) { - const validation = new MinItems(attribute.minItems); - validation.json(context); + const validation = new MinItems(attribute.minItems) + validation.json(context) } if (attribute.maxItems !== undefined) { - const validation = new MaxItems(attribute.maxItems); - validation.json(context); + const validation = new MaxItems(attribute.maxItems) + validation.json(context) } if (attribute.uniqueItems !== undefined) { - const validation = new UniqueItems(attribute.uniqueItems); - validation.json(context); + const validation = new UniqueItems(attribute.uniqueItems) + validation.json(context) } } - return context; - }; + return context + } // Function to recursively process attributes const processAttributes = (attrs: IW3CAttributeValue[]): IProductSchema => { if (!Array.isArray(attrs)) { - return { properties: {}, required: [] }; + return { properties: {}, required: [] } } - const properties = {}; - const required = []; + const properties = {} + const required = [] attrs.forEach((attribute) => { - const { attributeName, schemaDataType, isRequired, displayName, description } = attribute; + const { attributeName, schemaDataType, isRequired, displayName, description } = attribute // Add to required array if isRequired is true if (isRequired) { - required.push(attributeName); + required.push(attributeName) } // Create base property object with common fields const baseProperty = { type: schemaDataType.toLowerCase(), title: displayName || attributeName, - description: description ? description : `${attributeName} field` - }; + description: description ? description : `${attributeName} field`, + } // Handle different attribute types if (['string', 'number', 'boolean', 'integer'].includes(schemaDataType.toLowerCase())) { // Apply validations to the base property - properties[attributeName] = applyValidations(attribute, baseProperty); - } else if ('datetime-local' === schemaDataType.toLowerCase()) { + properties[attributeName] = applyValidations(attribute, baseProperty) + } else if (schemaDataType.toLowerCase() === 'datetime-local') { properties[attributeName] = { ...baseProperty, type: 'string', - format: 'date-time' - }; - } else if ('array' === schemaDataType.toLowerCase() && attribute.items) { + format: 'date-time', + } + } else if (schemaDataType.toLowerCase() === 'array' && attribute.items) { // Process array items - const arrayItemProperties = {}; - const arrayItemRequired = []; + const arrayItemProperties = {} + const arrayItemRequired = [] if (Array.isArray(attribute.items)) { // If items is an array, process each item attribute.items.forEach((item) => { - if ('object' === item.schemaDataType.toLowerCase() && item.properties) { + if (item.schemaDataType.toLowerCase() === 'object' && item.properties) { // Process object properties - const nestedObjProperties = {}; - const nestedObjRequired = []; + const nestedObjProperties = {} + const nestedObjRequired = [] // Process properties object Object.keys(item.properties).forEach((propKey) => { - const prop = item.properties[propKey]; + const prop = item.properties[propKey] if (prop.isRequired) { - nestedObjRequired.push(prop.attributeName); + nestedObjRequired.push(prop.attributeName) } - if ('array' === prop.schemaDataType.toLowerCase() && prop.items) { + if (prop.schemaDataType.toLowerCase() === 'array' && prop.items) { // Handle nested array - const nestedArrayResult = processAttributes(prop.items); + const nestedArrayResult = processAttributes(prop.items) nestedObjProperties[prop.attributeName] = { type: prop.schemaDataType.toLowerCase(), @@ -138,151 +138,151 @@ export function w3cSchemaBuilder(attributes: IW3CAttributeValue[], schemaName: s description: `${prop.attributeName} field`, items: { type: 'object', - properties: nestedArrayResult.properties - } - }; + properties: nestedArrayResult.properties, + }, + } - if (0 < nestedArrayResult.required.length) { - nestedObjProperties[prop.attributeName].items.required = nestedArrayResult.required; + if (nestedArrayResult.required.length > 0) { + nestedObjProperties[prop.attributeName].items.required = nestedArrayResult.required } } else { // Handle basic property nestedObjProperties[prop.attributeName] = { type: prop.schemaDataType.toLowerCase(), title: prop.displayName || prop.attributeName, - description: `${prop.attributeName} field` - }; + description: `${prop.attributeName} field`, + } // Apply validations nestedObjProperties[prop.attributeName] = applyValidations( prop, nestedObjProperties[prop.attributeName] - ); + ) } - }); + }) // Add object to array item properties arrayItemProperties[item.attributeName] = { type: 'object', title: item.displayName || item.attributeName, description: `${item.attributeName} field`, - properties: nestedObjProperties - }; + properties: nestedObjProperties, + } - if (0 < nestedObjRequired.length) { - arrayItemProperties[item.attributeName].required = nestedObjRequired; + if (nestedObjRequired.length > 0) { + arrayItemProperties[item.attributeName].required = nestedObjRequired } if (item.isRequired) { - arrayItemRequired.push(item.attributeName); + arrayItemRequired.push(item.attributeName) } } else { // Handle basic array item arrayItemProperties[item.attributeName] = { type: item.schemaDataType.toLowerCase(), title: item.displayName || item.attributeName, - description: `${item.attributeName} field` - }; + description: `${item.attributeName} field`, + } // Apply validations - arrayItemProperties[item.attributeName] = applyValidations(item, arrayItemProperties[item.attributeName]); + arrayItemProperties[item.attributeName] = applyValidations(item, arrayItemProperties[item.attributeName]) if (item.isRequired) { - arrayItemRequired.push(item.attributeName); + arrayItemRequired.push(item.attributeName) } } - }); + }) } properties[attributeName] = { ...baseProperty, items: { type: 'object', - properties: arrayItemProperties - } - }; + properties: arrayItemProperties, + }, + } // Apply array-specific validations - properties[attributeName] = applyValidations(attribute, properties[attributeName]); + properties[attributeName] = applyValidations(attribute, properties[attributeName]) // Add required properties to the items schema if any - if (0 < arrayItemRequired.length) { - properties[attributeName].items.required = arrayItemRequired; + if (arrayItemRequired.length > 0) { + properties[attributeName].items.required = arrayItemRequired } - } else if ('object' === schemaDataType.toLowerCase() && attribute.properties) { - const nestedProperties = {}; - const nestedRequired = []; + } else if (schemaDataType.toLowerCase() === 'object' && attribute.properties) { + const nestedProperties = {} + const nestedRequired = [] // Process each property in the object Object.keys(attribute.properties).forEach((propKey) => { - const prop = attribute.properties[propKey]; + const prop = attribute.properties[propKey] // Add to nested required array if isRequired is true if (prop.isRequired) { - nestedRequired.push(propKey); + nestedRequired.push(propKey) } // Create base property for nested object const nestedBaseProperty = { type: prop.schemaDataType.toLowerCase(), title: prop.displayName || prop.attributeName, - description: `${prop.attributeName} field` - }; + description: `${prop.attributeName} field`, + } - if ('array' === prop.schemaDataType.toLowerCase() && prop.items) { + if (prop.schemaDataType.toLowerCase() === 'array' && prop.items) { // Handle nested arrays - const result = processAttributes(prop.items); + const result = processAttributes(prop.items) nestedProperties[prop.attributeName] = { ...nestedBaseProperty, type: 'array', items: { type: 'object', - properties: result.properties - } - }; + properties: result.properties, + }, + } // Apply array-specific validations - nestedProperties[prop.attributeName] = applyValidations(prop, nestedProperties[prop.attributeName]); + nestedProperties[prop.attributeName] = applyValidations(prop, nestedProperties[prop.attributeName]) // Add required properties to the items schema if any - if (0 < result.required.length) { - nestedProperties[prop.attributeName].items.required = result.required; + if (result.required.length > 0) { + nestedProperties[prop.attributeName].items.required = result.required } } else { // Handle basic properties with validations - nestedProperties[prop.attributeName] = applyValidations(prop, nestedBaseProperty); + nestedProperties[prop.attributeName] = applyValidations(prop, nestedBaseProperty) } - }); + }) properties[attributeName] = { ...baseProperty, type: 'object', - properties: nestedProperties - }; + properties: nestedProperties, + } // Add required properties to the object schema if any - if (0 < nestedRequired.length) { - properties[attributeName].required = nestedRequired; + if (nestedRequired.length > 0) { + properties[attributeName].required = nestedRequired } } - }); + }) - return { properties, required }; - }; + return { properties, required } + } // Process all attributes - const result = processAttributes(attributes); - const { properties } = result; + const result = processAttributes(attributes) + const { properties } = result // Add id property to required fields along with other required fields // eslint-disable-next-line @typescript-eslint/no-unused-vars - const required = ['id', ...result.required]; + const _required = ['id', ...result.required] // Add id property - properties['id'] = { + properties.id = { type: 'string', - format: 'uri' - }; + format: 'uri', + } // Create the final W3C Schema const W3CSchema = { @@ -294,107 +294,107 @@ export function w3cSchemaBuilder(attributes: IW3CAttributeValue[], schemaName: s required: ['@context', 'issuer', 'issuanceDate', 'type', 'credentialSubject'], properties: { '@context': { - $ref: '#/$defs/context' + $ref: '#/$defs/context', }, type: { type: 'array', items: { anyOf: [ { - const: 'VerifiableCredential' + const: 'VerifiableCredential', }, { - const: schemaName - } - ] - } + const: schemaName, + }, + ], + }, }, credentialSubject: { - $ref: '#/$defs/credentialSubject' + $ref: '#/$defs/credentialSubject', }, id: { type: 'string', - format: 'uri' + format: 'uri', }, issuer: { - $ref: '#/$defs/uriOrId' + $ref: '#/$defs/uriOrId', }, issuanceDate: { type: 'string', - format: 'date-time' + format: 'date-time', }, expirationDate: { type: 'string', - format: 'date-time' + format: 'date-time', }, credentialStatus: { - $ref: '#/$defs/credentialStatus' + $ref: '#/$defs/credentialStatus', }, credentialSchema: { - $ref: '#/$defs/credentialSchema' - } + $ref: '#/$defs/credentialSchema', + }, }, $defs: { context: { type: 'array', prefixItems: [ { - const: 'https://www.w3.org/2018/credentials/v1' - } + const: 'https://www.w3.org/2018/credentials/v1', + }, ], items: { oneOf: [ { type: 'string', - format: 'uri' + format: 'uri', }, { - type: 'object' + type: 'object', }, { type: 'array', - items: false - } - ] + items: false, + }, + ], }, minItems: 1, - uniqueItems: true + uniqueItems: true, }, credentialSubject: { type: 'object', required: ['id', ...result.required], additionalProperties: false, - properties + properties, }, credentialSchema: { oneOf: [ { - $ref: '#/$defs/idAndType' + $ref: '#/$defs/idAndType', }, { type: 'array', items: { - $ref: '#/$defs/idAndType' + $ref: '#/$defs/idAndType', }, minItems: 1, - uniqueItems: true - } - ] + uniqueItems: true, + }, + ], }, credentialStatus: { oneOf: [ { - $ref: '#/$defs/idAndType' + $ref: '#/$defs/idAndType', }, { type: 'array', items: { - $ref: '#/$defs/idAndType' + $ref: '#/$defs/idAndType', }, minItems: 1, - uniqueItems: true - } - ] + uniqueItems: true, + }, + ], }, idAndType: { type: 'object', @@ -402,18 +402,18 @@ export function w3cSchemaBuilder(attributes: IW3CAttributeValue[], schemaName: s properties: { id: { type: 'string', - format: 'uri' + format: 'uri', }, type: { - type: 'string' - } - } + type: 'string', + }, + }, }, uriOrId: { oneOf: [ { type: 'string', - format: 'uri' + format: 'uri', }, { type: 'object', @@ -421,14 +421,14 @@ export function w3cSchemaBuilder(attributes: IW3CAttributeValue[], schemaName: s properties: { id: { type: 'string', - format: 'uri' - } - } - } - ] - } - } - }; + format: 'uri', + }, + }, + }, + ], + }, + }, + } - return W3CSchema; + return W3CSchema } diff --git a/apps/ledger/src/credential-definition/credential-definition.controller.ts b/apps/ledger/src/credential-definition/credential-definition.controller.ts index 138929978..98ad08de9 100644 --- a/apps/ledger/src/credential-definition/credential-definition.controller.ts +++ b/apps/ledger/src/credential-definition/credential-definition.controller.ts @@ -1,53 +1,58 @@ /* eslint-disable camelcase */ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { Controller, Logger } from '@nestjs/common'; - -import { CredentialDefinitionService } from './credential-definition.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { GetAllCredDefsPayload, GetCredDefBySchemaId, IPlatformCredDefs, SaveCredDefPayload } from './interfaces/create-credential-definition.interface'; -import { CreateCredDefPayload, GetCredDefPayload } from './interfaces/create-credential-definition.interface'; -import { credential_definition } from '@prisma/client'; -import { CredDefSchema } from './interfaces/credential-definition.interface'; -import { ICredDefDetails, IPlatformCredDefsData } from '@credebl/common/interfaces/cred-def.interface'; +import { Controller, Logger } from '@nestjs/common' + +import type { ICredDefDetails, IPlatformCredDefsData } from '@credebl/common/interfaces/cred-def.interface' +import { MessagePattern } from '@nestjs/microservices' +import type { credential_definition } from '@prisma/client' +import type { CredentialDefinitionService } from './credential-definition.service' +import type { + GetAllCredDefsPayload, + GetCredDefBySchemaId, + IPlatformCredDefs, + SaveCredDefPayload, +} from './interfaces/create-credential-definition.interface' +import type { CreateCredDefPayload, GetCredDefPayload } from './interfaces/create-credential-definition.interface' +import type { CredDefSchema } from './interfaces/credential-definition.interface' @Controller('credential-definitions') export class CredentialDefinitionController { - private logger = new Logger(); - - constructor(private readonly credDefService: CredentialDefinitionService) { } - - @MessagePattern({ cmd: 'create-credential-definition' }) - async createCredentialDefinition(payload: CreateCredDefPayload): Promise { - return this.credDefService.createCredentialDefinition(payload); - } - - @MessagePattern({ cmd: 'get-credential-definition-by-id' }) - async getCredentialDefinitionById(payload: GetCredDefPayload): Promise { - return this.credDefService.getCredentialDefinitionById(payload); - } - - @MessagePattern({ cmd: 'get-all-platform-cred-defs' }) - async getAllSchema(credDefPayload: IPlatformCredDefs): Promise { - return this.credDefService.getAllPlatformCredDefs(credDefPayload); - } - - @MessagePattern({ cmd: 'get-all-credential-definitions' }) - async getAllCredDefs(payload: GetAllCredDefsPayload): Promise { - return this.credDefService.getAllCredDefs(payload); - } - - @MessagePattern({ cmd: 'get-all-credential-definitions-by-schema-id' }) - async getCredentialDefinitionBySchemaId(payload: GetCredDefBySchemaId): Promise { - return this.credDefService.getCredentialDefinitionBySchemaId(payload); - } - - @MessagePattern({ cmd: 'get-all-credential-template-for-bulk-operation' }) - async getAllCredentialTemplates (payload: {orgId : string, schemaType: string }): Promise { - const {orgId, schemaType} = payload; - return this.credDefService.getAllCredentialTemplates(orgId, schemaType); - } - - @MessagePattern({ cmd: 'store-cred-def-record' }) - async getSchemaRecordBySchemaId(payload: SaveCredDefPayload): Promise { - return this.credDefService.storeCredDefRecord(payload.credDefDetails); - } -} \ No newline at end of file + private logger = new Logger() + + constructor(private readonly credDefService: CredentialDefinitionService) {} + + @MessagePattern({ cmd: 'create-credential-definition' }) + async createCredentialDefinition(payload: CreateCredDefPayload): Promise { + return this.credDefService.createCredentialDefinition(payload) + } + + @MessagePattern({ cmd: 'get-credential-definition-by-id' }) + async getCredentialDefinitionById(payload: GetCredDefPayload): Promise { + return this.credDefService.getCredentialDefinitionById(payload) + } + + @MessagePattern({ cmd: 'get-all-platform-cred-defs' }) + async getAllSchema(credDefPayload: IPlatformCredDefs): Promise { + return this.credDefService.getAllPlatformCredDefs(credDefPayload) + } + + @MessagePattern({ cmd: 'get-all-credential-definitions' }) + async getAllCredDefs(payload: GetAllCredDefsPayload): Promise { + return this.credDefService.getAllCredDefs(payload) + } + + @MessagePattern({ cmd: 'get-all-credential-definitions-by-schema-id' }) + async getCredentialDefinitionBySchemaId(payload: GetCredDefBySchemaId): Promise { + return this.credDefService.getCredentialDefinitionBySchemaId(payload) + } + + @MessagePattern({ cmd: 'get-all-credential-template-for-bulk-operation' }) + async getAllCredentialTemplates(payload: { orgId: string; schemaType: string }): Promise { + const { orgId, schemaType } = payload + return this.credDefService.getAllCredentialTemplates(orgId, schemaType) + } + + @MessagePattern({ cmd: 'store-cred-def-record' }) + async getSchemaRecordBySchemaId(payload: SaveCredDefPayload): Promise { + return this.credDefService.storeCredDefRecord(payload.credDefDetails) + } +} diff --git a/apps/ledger/src/credential-definition/credential-definition.module.ts b/apps/ledger/src/credential-definition/credential-definition.module.ts index a51ae4109..098ba3752 100644 --- a/apps/ledger/src/credential-definition/credential-definition.module.ts +++ b/apps/ledger/src/credential-definition/credential-definition.module.ts @@ -1,36 +1,33 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Logger, Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' -import { CommonModule } from '@credebl/common'; -import { CredentialDefinitionController } from './credential-definition.controller'; -import { CredentialDefinitionRepository } from './repositories/credential-definition.repository'; -import { CredentialDefinitionService } from './credential-definition.service'; -import { HttpModule } from '@nestjs/axios'; -import { PrismaService } from '@credebl/prisma-service'; -import { CacheModule } from '@nestjs/cache-manager'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { PrismaService } from '@credebl/prisma-service' +import { HttpModule } from '@nestjs/axios' +import { CacheModule } from '@nestjs/cache-manager' +import { CredentialDefinitionController } from './credential-definition.controller' +import { CredentialDefinitionService } from './credential-definition.service' +import { CredentialDefinitionRepository } from './repositories/credential-definition.repository' @Module({ imports: [ ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.CREDENTIAL_DEFINITION_SERVICE, process.env.CREDENTAILDEFINITION_NKEY_SEED) - } + options: getNatsOptions( + CommonConstants.CREDENTIAL_DEFINITION_SERVICE, + process.env.CREDENTAILDEFINITION_NKEY_SEED + ), + }, ]), HttpModule, CommonModule, - CacheModule.register() + CacheModule.register(), ], - providers: [ - CredentialDefinitionService, - CredentialDefinitionRepository, - Logger, - PrismaService, - NATSClient - ], - controllers: [CredentialDefinitionController] + providers: [CredentialDefinitionService, CredentialDefinitionRepository, Logger, PrismaService, NATSClient], + controllers: [CredentialDefinitionController], }) -export class CredentialDefinitionModule { } +export class CredentialDefinitionModule {} diff --git a/apps/ledger/src/credential-definition/credential-definition.service.ts b/apps/ledger/src/credential-definition/credential-definition.service.ts index a98d59480..d82fbd480 100644 --- a/apps/ledger/src/credential-definition/credential-definition.service.ts +++ b/apps/ledger/src/credential-definition/credential-definition.service.ts @@ -1,438 +1,441 @@ +import type { NATSClient } from '@credebl/common/NATSClient' +import type { ICredDefDetails, IPlatformCredDefsData } from '@credebl/common/interfaces/cred-def.interface' +import type { ISchemaDetail } from '@credebl/common/interfaces/schema.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { OrgAgentType, SchemaType, SortValue } from '@credebl/enum/enum' +import { CACHE_MANAGER } from '@nestjs/cache-manager' /* eslint-disable camelcase */ -import { - ConflictException, - HttpException, - Inject, - Injectable, - NotFoundException -} from '@nestjs/common'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { CredentialDefinitionRepository } from './repositories/credential-definition.repository'; -import { CreateCredDefPayload, CredDefPayload, GetAllCredDefsPayload, GetCredDefBySchemaId, GetCredDefPayload, IPlatformCredDefs, ISaveCredDef } from './interfaces/create-credential-definition.interface'; -import { credential_definition } from '@prisma/client'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { CreateCredDefAgentRedirection, CredDefSchema, GetCredDefAgentRedirection } from './interfaces/credential-definition.interface'; -import { map } from 'rxjs/operators'; -import { OrgAgentType, SchemaType, SortValue } from '@credebl/enum/enum'; -import { Cache } from 'cache-manager'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { ICredDefDetails, IPlatformCredDefsData } from '@credebl/common/interfaces/cred-def.interface'; -import { NATSClient } from '@credebl/common/NATSClient'; -import { from } from 'rxjs'; -import { ISchemaDetail } from '@credebl/common/interfaces/schema.interface'; +import { ConflictException, HttpException, Inject, Injectable, NotFoundException } from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +import type { credential_definition } from '@prisma/client' +import type { Cache } from 'cache-manager' +import { BaseService } from 'libs/service/base.service' +import { from } from 'rxjs' +import { map } from 'rxjs/operators' +import type { + CreateCredDefPayload, + CredDefPayload, + GetAllCredDefsPayload, + GetCredDefBySchemaId, + GetCredDefPayload, + IPlatformCredDefs, + ISaveCredDef, +} from './interfaces/create-credential-definition.interface' +import type { + CreateCredDefAgentRedirection, + CredDefSchema, + GetCredDefAgentRedirection, +} from './interfaces/credential-definition.interface' +import type { CredentialDefinitionRepository } from './repositories/credential-definition.repository' @Injectable() export class CredentialDefinitionService extends BaseService { - constructor( - private readonly credentialDefinitionRepository: CredentialDefinitionRepository, - @Inject('NATS_CLIENT') private readonly credDefServiceProxy: ClientProxy, - @Inject(CACHE_MANAGER) private readonly cacheService: Cache, - private readonly natsClient : NATSClient - - ) { - super('CredentialDefinitionService'); - } + constructor( + private readonly credentialDefinitionRepository: CredentialDefinitionRepository, + @Inject('NATS_CLIENT') private readonly credDefServiceProxy: ClientProxy, + @Inject(CACHE_MANAGER) private readonly cacheService: Cache, + private readonly natsClient: NATSClient + ) { + super('CredentialDefinitionService') + } + + async createCredentialDefinition(payload: CreateCredDefPayload): Promise { + try { + const { credDef, user } = payload + const { agentEndPoint, orgDid } = await this.credentialDefinitionRepository.getAgentDetailsByOrgId(credDef.orgId) + // eslint-disable-next-line yoda + const did = credDef.orgDid?.split(':').length >= 4 ? credDef.orgDid : orgDid + const getAgentDetails = await this.credentialDefinitionRepository.getAgentType(credDef.orgId) + + const userId = user.id + credDef.tag = credDef.tag.trim() + const dbResult: credential_definition = await this.credentialDefinitionRepository.getByAttribute( + credDef.schemaLedgerId, + credDef.tag + ) - async createCredentialDefinition(payload: CreateCredDefPayload): Promise { - try { - const { credDef, user } = payload; - const { agentEndPoint, orgDid } = await this.credentialDefinitionRepository.getAgentDetailsByOrgId(credDef.orgId); - // eslint-disable-next-line yoda - const did = credDef.orgDid?.split(':').length >= 4 ? credDef.orgDid : orgDid; - const getAgentDetails = await this.credentialDefinitionRepository.getAgentType(credDef.orgId); - - const userId = user.id; - credDef.tag = credDef.tag.trim(); - const dbResult: credential_definition = await this.credentialDefinitionRepository.getByAttribute( - credDef.schemaLedgerId, - credDef.tag - ); - - if (dbResult) { - throw new ConflictException(ResponseMessages.credentialDefinition.error.Conflict); - } - let credDefResponseFromAgentService; - - const orgAgentType = await this.credentialDefinitionRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId); - if (OrgAgentType.DEDICATED === orgAgentType) { - const CredDefPayload = { - tag: credDef.tag, - schemaId: credDef.schemaLedgerId, - issuerId: did, - agentEndPoint, - orgId: credDef.orgId, - agentType: OrgAgentType.DEDICATED - }; - - credDefResponseFromAgentService = await this._createCredentialDefinition(CredDefPayload); - - } else if (OrgAgentType.SHARED === orgAgentType) { - const { tenantId } = await this.credentialDefinitionRepository.getAgentDetailsByOrgId(credDef.orgId); - - const CredDefPayload = { - tenantId, - method: 'registerCredentialDefinition', - payload: { - tag: credDef.tag, - schemaId: credDef.schemaLedgerId, - issuerId: did - }, - agentEndPoint, - orgId: credDef.orgId, - agentType: OrgAgentType.SHARED - }; - credDefResponseFromAgentService = await this._createCredentialDefinition(CredDefPayload); - } - const response = JSON.parse(JSON.stringify(credDefResponseFromAgentService.response)); - const schemaDetails = await this.credentialDefinitionRepository.getSchemaById(credDef.schemaLedgerId); - if (!schemaDetails) { - throw new NotFoundException(ResponseMessages.credentialDefinition.error.schemaIdNotFound); - } - const credDefData: CredDefPayload = { - tag: '', - schemaLedgerId: '', - issuerId: '', - revocable: credDef.revocable, - createdBy: `0`, - lastChangedBy: `0`, - orgId: '0', - schemaId: '0', - credentialDefinitionId: '' - }; - - if ('finished' === response.state) { - credDefData.tag = response.credentialDefinition.tag; - credDefData.schemaLedgerId = response.credentialDefinition.schemaId; - credDefData.issuerId = response.credentialDefinition.issuerId; - credDefData.credentialDefinitionId = response.credentialDefinitionId; - credDefData.orgId = credDef.orgId; - 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; - credDefData.issuerId = response.credentialDefinition.credentialDefinition.issuerId; - credDefData.credentialDefinitionId = response.credentialDefinition.credentialDefinitionId; - credDefData.orgId = credDef.orgId; - credDefData.revocable = credDef.revocable; - credDefData.schemaId = schemaDetails.id; - credDefData.createdBy = userId; - credDefData.lastChangedBy = userId; - } - const credDefResponse = await this.credentialDefinitionRepository.saveCredentialDefinition(credDefData); - - delete credDefResponse.lastChangedBy; - delete credDefResponse.lastChangedDateTime; - - return credDefResponse; - - } catch (error) { - this.logger.error( - `Error in creating credential definition: ${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); - } + if (dbResult) { + throw new ConflictException(ResponseMessages.credentialDefinition.error.Conflict) + } + // biome-ignore lint/suspicious/noImplicitAnyLet: + let credDefResponseFromAgentService + + const orgAgentType = await this.credentialDefinitionRepository.getOrgAgentType( + getAgentDetails.org_agents[0].orgAgentTypeId + ) + if (OrgAgentType.DEDICATED === orgAgentType) { + const CredDefPayload = { + tag: credDef.tag, + schemaId: credDef.schemaLedgerId, + issuerId: did, + agentEndPoint, + orgId: credDef.orgId, + agentType: OrgAgentType.DEDICATED, } - } - async _createCredentialDefinition(payload: CreateCredDefAgentRedirection): Promise<{ - response: string; - }> { - try { - const pattern = { - cmd: 'agent-create-credential-definition' - }; - - const credDefResponse = await from(this.natsClient - .send(this.credDefServiceProxy, 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 credDefResponse; - } catch (error) { - this.logger.error(`Error in creating credential definition : ${JSON.stringify(error)}`); - throw error; + credDefResponseFromAgentService = await this._createCredentialDefinition(CredDefPayload) + } else if (OrgAgentType.SHARED === orgAgentType) { + const { tenantId } = await this.credentialDefinitionRepository.getAgentDetailsByOrgId(credDef.orgId) + + const CredDefPayload = { + tenantId, + method: 'registerCredentialDefinition', + payload: { + tag: credDef.tag, + schemaId: credDef.schemaLedgerId, + issuerId: did, + }, + agentEndPoint, + orgId: credDef.orgId, + agentType: OrgAgentType.SHARED, } + credDefResponseFromAgentService = await this._createCredentialDefinition(CredDefPayload) + } + const response = JSON.parse(JSON.stringify(credDefResponseFromAgentService.response)) + const schemaDetails = await this.credentialDefinitionRepository.getSchemaById(credDef.schemaLedgerId) + if (!schemaDetails) { + throw new NotFoundException(ResponseMessages.credentialDefinition.error.schemaIdNotFound) + } + const credDefData: CredDefPayload = { + tag: '', + schemaLedgerId: '', + issuerId: '', + revocable: credDef.revocable, + createdBy: '0', + lastChangedBy: '0', + orgId: '0', + schemaId: '0', + credentialDefinitionId: '', + } + + if (response.state === 'finished') { + credDefData.tag = response.credentialDefinition.tag + credDefData.schemaLedgerId = response.credentialDefinition.schemaId + credDefData.issuerId = response.credentialDefinition.issuerId + credDefData.credentialDefinitionId = response.credentialDefinitionId + credDefData.orgId = credDef.orgId + credDefData.revocable = credDef.revocable + credDefData.schemaId = schemaDetails.id + credDefData.createdBy = userId + credDefData.lastChangedBy = userId + } else if (response.credentialDefinition.state === 'finished') { + credDefData.tag = response.credentialDefinition.credentialDefinition.tag + credDefData.schemaLedgerId = response.credentialDefinition.credentialDefinition.schemaId + credDefData.issuerId = response.credentialDefinition.credentialDefinition.issuerId + credDefData.credentialDefinitionId = response.credentialDefinition.credentialDefinitionId + credDefData.orgId = credDef.orgId + credDefData.revocable = credDef.revocable + credDefData.schemaId = schemaDetails.id + credDefData.createdBy = userId + credDefData.lastChangedBy = userId + } + const credDefResponse = await this.credentialDefinitionRepository.saveCredentialDefinition(credDefData) + + credDefResponse.lastChangedBy = undefined + credDefResponse.lastChangedDateTime = undefined + + return credDefResponse + } catch (error) { + this.logger.error(`Error in creating credential definition: ${JSON.stringify(error)}`) + if (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, + }) + } + throw new RpcException(error.response ? error.response : error) } + } - async getAllPlatformCredDefs(credDefsPayload: IPlatformCredDefs): Promise { - try { - const { pageSize, pageNumber } = credDefsPayload; - const response = await this.credentialDefinitionRepository.getAllPlatformCredDefsDetails(credDefsPayload); - - const credDefResponse: IPlatformCredDefsData = { - totalItems: response.credDefCount, - hasNextPage: pageSize * pageNumber < response.credDefCount, - hasPreviousPage: 1 < pageNumber, - nextPage: pageNumber + 1, - previousPage: pageNumber - 1, - lastPage: Math.ceil(response.credDefCount / pageSize), - data: response.credDefResult - }; - - if (0 !== response.credDefCount) { - return credDefResponse; - } else { - throw new NotFoundException(ResponseMessages.credentialDefinition.error.NotFound); - } - - - } catch (error) { - this.logger.error(`Error in retrieving all credential definitions: ${error}`); - throw new RpcException(error.response ? error.response : error); - } + async _createCredentialDefinition(payload: CreateCredDefAgentRedirection): Promise<{ + response: string + }> { + try { + const pattern = { + cmd: 'agent-create-credential-definition', } - - async getCredentialDefinitionById(payload: GetCredDefPayload): Promise { - try { - const { credentialDefinitionId, orgId } = payload; - 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); - - let credDefResponse; - if (OrgAgentType.DEDICATED === orgAgentType) { - const getSchemaPayload = { - credentialDefinitionId, - orgId, - agentEndPoint, - agentType: OrgAgentType.DEDICATED - }; - credDefResponse = await this._getCredentialDefinitionById(getSchemaPayload); - } else if (OrgAgentType.SHARED === orgAgentType) { - const { tenantId } = await this.credentialDefinitionRepository.getAgentDetailsByOrgId(String(orgId)); - const getSchemaPayload = { - orgId, - tenantId, - method: 'getCredentialDefinitionById', - payload: { credentialDefinitionId }, - agentType: OrgAgentType.SHARED, - agentEndPoint - }; - credDefResponse = await this._getCredentialDefinitionById(getSchemaPayload); - } - if (credDefResponse.response.resolutionMetadata.error) { - throw new NotFoundException(ResponseMessages.credentialDefinition.error.credDefIdNotFound); - } - - return credDefResponse; - } catch (error) { - this.logger.error(`Error retrieving credential definition with id ${payload.credentialDefinitionId}`); - 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); - } - } + + const credDefResponse = await from(this.natsClient.send(this.credDefServiceProxy, 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 credDefResponse + } catch (error) { + this.logger.error(`Error in creating credential definition : ${JSON.stringify(error)}`) + throw error } + } - async _getCredentialDefinitionById(payload: GetCredDefAgentRedirection): Promise<{ - response: string; - }> { - - try { - const pattern = { - cmd: 'agent-get-credential-definition' - }; - const credDefResponse = await from(this.natsClient - .send(this.credDefServiceProxy, 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 credDefResponse; - } catch (error) { - this.logger.error(`Error in creating credential definition : ${JSON.stringify(error)}`); - throw error; - } + async getAllPlatformCredDefs(credDefsPayload: IPlatformCredDefs): Promise { + try { + const { pageSize, pageNumber } = credDefsPayload + const response = await this.credentialDefinitionRepository.getAllPlatformCredDefsDetails(credDefsPayload) + + const credDefResponse: IPlatformCredDefsData = { + totalItems: response.credDefCount, + hasNextPage: pageSize * pageNumber < response.credDefCount, + hasPreviousPage: pageNumber > 1, + nextPage: pageNumber + 1, + previousPage: pageNumber - 1, + lastPage: Math.ceil(response.credDefCount / pageSize), + data: response.credDefResult, + } + + if (response.credDefCount !== 0) { + return credDefResponse + } + throw new NotFoundException(ResponseMessages.credentialDefinition.error.NotFound) + } catch (error) { + this.logger.error(`Error in retrieving all credential definitions: ${error}`) + throw new RpcException(error.response ? error.response : error) } + } - async getAllCredDefs(payload: GetAllCredDefsPayload): Promise { - try { - const { credDefSearchCriteria, orgId } = payload; - const response = await this.credentialDefinitionRepository.getAllCredDefs(credDefSearchCriteria, orgId); - - const schemaIds = response?.map((item) => item?.schemaLedgerId); - - const schemaDetails = await this._getSchemaDetails(schemaIds); - - const archivedSchemaIds = schemaDetails - .filter((schema) => schema.isSchemaArchived) - .map((schema) => schema.schemaLedgerId); - - const filteredResponse = response.filter( - (credDef) => !archivedSchemaIds.includes(credDef.schemaLedgerId) - ); - - const credDefResponse = { - totalItems: filteredResponse.length, - hasNextPage: credDefSearchCriteria.pageSize * credDefSearchCriteria.pageNumber < response.length, - hasPreviousPage: 1 < credDefSearchCriteria.pageNumber, - nextPage: credDefSearchCriteria.pageNumber + 1, - previousPage: credDefSearchCriteria.pageNumber - 1, - lastPage: Math.ceil(response.length / credDefSearchCriteria.pageSize), - data: filteredResponse - }; - - if (0 === filteredResponse.length) { - throw new NotFoundException(ResponseMessages.credentialDefinition.error.NotFound); - } - - return credDefResponse; - } catch (error) { - this.logger.error(`Error in retrieving credential definitions: ${error}`); - throw new RpcException(error.response ? error.response : error); + async getCredentialDefinitionById(payload: GetCredDefPayload): Promise { + try { + const { credentialDefinitionId, orgId } = payload + 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 + ) + + // biome-ignore lint/suspicious/noImplicitAnyLet: + let credDefResponse + if (OrgAgentType.DEDICATED === orgAgentType) { + const getSchemaPayload = { + credentialDefinitionId, + orgId, + agentEndPoint, + agentType: OrgAgentType.DEDICATED, + } + credDefResponse = await this._getCredentialDefinitionById(getSchemaPayload) + } else if (OrgAgentType.SHARED === orgAgentType) { + const { tenantId } = await this.credentialDefinitionRepository.getAgentDetailsByOrgId(String(orgId)) + const getSchemaPayload = { + orgId, + tenantId, + method: 'getCredentialDefinitionById', + payload: { credentialDefinitionId }, + agentType: OrgAgentType.SHARED, + agentEndPoint, } + credDefResponse = await this._getCredentialDefinitionById(getSchemaPayload) + } + if (credDefResponse.response.resolutionMetadata.error) { + throw new NotFoundException(ResponseMessages.credentialDefinition.error.credDefIdNotFound) + } + + return credDefResponse + } catch (error) { + this.logger.error(`Error retrieving credential definition with id ${payload.credentialDefinitionId}`) + if (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, + }) + } + throw new RpcException(error.response ? error.response : error) } - - async _getSchemaDetails(schemaIds: string[]): Promise { - const pattern = { cmd: 'get-schemas-details' }; - - const payload = { - templateIds: schemaIds - }; - - const getSchemaDetails = await this.credDefServiceProxy - .send(pattern, payload) - .toPromise() - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.status, - error: error.message - }, - error.status - ); - }); - return getSchemaDetails; + } + + async _getCredentialDefinitionById(payload: GetCredDefAgentRedirection): Promise<{ + response: string + }> { + try { + const pattern = { + cmd: 'agent-get-credential-definition', } + const credDefResponse = await from(this.natsClient.send(this.credDefServiceProxy, 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 credDefResponse + } catch (error) { + this.logger.error(`Error in creating credential definition : ${JSON.stringify(error)}`) + throw error + } + } - async getCredentialDefinitionBySchemaId(payload: GetCredDefBySchemaId): Promise { - try { - const { schemaId } = payload; - const credDefListBySchemaId = await this.credentialDefinitionRepository.getCredentialDefinitionBySchemaId(schemaId); - return credDefListBySchemaId; - } catch (error) { - this.logger.error(`Error in retrieving credential definitions: ${error}`); - throw new RpcException(error.response ? error.response : error); - } + async getAllCredDefs(payload: GetAllCredDefsPayload): Promise { + try { + const { credDefSearchCriteria, orgId } = payload + const response = await this.credentialDefinitionRepository.getAllCredDefs(credDefSearchCriteria, orgId) + + const schemaIds = response?.map((item) => item?.schemaLedgerId) + + const schemaDetails = await this._getSchemaDetails(schemaIds) + + const archivedSchemaIds = schemaDetails + .filter((schema) => schema.isSchemaArchived) + .map((schema) => schema.schemaLedgerId) + + const filteredResponse = response.filter((credDef) => !archivedSchemaIds.includes(credDef.schemaLedgerId)) + + const credDefResponse = { + totalItems: filteredResponse.length, + hasNextPage: credDefSearchCriteria.pageSize * credDefSearchCriteria.pageNumber < response.length, + hasPreviousPage: credDefSearchCriteria.pageNumber > 1, + nextPage: credDefSearchCriteria.pageNumber + 1, + previousPage: credDefSearchCriteria.pageNumber - 1, + lastPage: Math.ceil(response.length / credDefSearchCriteria.pageSize), + data: filteredResponse, + } + + if (filteredResponse.length === 0) { + throw new NotFoundException(ResponseMessages.credentialDefinition.error.NotFound) + } + + return credDefResponse + } catch (error) { + this.logger.error(`Error in retrieving credential definitions: ${error}`) + throw new RpcException(error.response ? error.response : error) } + } - async getAllCredentialTemplates(orgId: string, schemaType: string): Promise { - const schemaTypeEnum = schemaType as SchemaType; - if (!Object.values(SchemaType).includes(schemaTypeEnum)) { - throw new NotFoundException(ResponseMessages.credentialDefinition.error.InvalidSchemaType); - } - try { - const payload = { - orgId, - sortValue: SortValue.ASC, - credDefSortBy: 'id' - }; - - if (schemaType === SchemaType.W3C_Schema) { - const schemaDetailList = await this.credentialDefinitionRepository.getAllSchemaByOrgIdAndType(orgId, schemaType); - const schemaResponse = await Promise.all(schemaDetailList.map(async (schemaDetails) => ({ - schemaCredDefName: `${schemaDetails.name}-${schemaDetails.version}`, - schemaName: schemaDetails.name, - schemaVersion: schemaDetails.version, - schemaAttributes: schemaDetails.attributes, - type: SchemaType.W3C_Schema, - schemaIdentifier: schemaDetails.schemaLedgerId, - createDateTime: schemaDetails.createDateTime, - organizationName: schemaDetails?.organisation?.name, - userName: schemaDetails?.organisation?.userOrgRoles[0]?.user?.firstName - }))); - - return schemaResponse; - } - const credDefSchemaList = - await this.credentialDefinitionRepository.getAllCredDefsByOrgIdForBulk( - payload - ); - - if (!credDefSchemaList) { - throw new NotFoundException(ResponseMessages.credentialDefinition.error.NotFound); - } - - const activeCredDefSchemaList = credDefSchemaList.filter((item) => !item?.['isSchemaArchived']); - - return activeCredDefSchemaList; - } catch (error) { - this.logger.error( - `get Cred-Defs and schema List By OrgId for bulk operations: ${JSON.stringify(error)}` - ); - if (error?.status?.message?.error) { - const reason = error?.status?.message?.error?.reason ?? error?.status?.message?.error; - throw new RpcException({ - message: reason, - statusCode: error?.status?.code - }); - } else { - throw new RpcException(error.response ?? error); - } - } + async _getSchemaDetails(schemaIds: string[]): Promise { + const pattern = { cmd: 'get-schemas-details' } + + const payload = { + templateIds: schemaIds, + } + + const getSchemaDetails = await this.credDefServiceProxy + .send(pattern, payload) + .toPromise() + .catch((error) => { + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw new HttpException( + { + status: error.status, + error: error.message, + }, + error.status + ) + }) + return getSchemaDetails + } + + async getCredentialDefinitionBySchemaId(payload: GetCredDefBySchemaId): Promise { + try { + const { schemaId } = payload + const credDefListBySchemaId = + await this.credentialDefinitionRepository.getCredentialDefinitionBySchemaId(schemaId) + return credDefListBySchemaId + } catch (error) { + this.logger.error(`Error in retrieving credential definitions: ${error}`) + throw new RpcException(error.response ? error.response : error) } + } + + async getAllCredentialTemplates(orgId: string, schemaType: string): Promise { + const schemaTypeEnum = schemaType as SchemaType + if (!Object.values(SchemaType).includes(schemaTypeEnum)) { + throw new NotFoundException(ResponseMessages.credentialDefinition.error.InvalidSchemaType) + } + try { + const payload = { + orgId, + sortValue: SortValue.ASC, + credDefSortBy: 'id', + } + + if (schemaType === SchemaType.W3C_Schema) { + const schemaDetailList = await this.credentialDefinitionRepository.getAllSchemaByOrgIdAndType(orgId, schemaType) + const schemaResponse = await Promise.all( + schemaDetailList.map(async (schemaDetails) => ({ + schemaCredDefName: `${schemaDetails.name}-${schemaDetails.version}`, + schemaName: schemaDetails.name, + schemaVersion: schemaDetails.version, + schemaAttributes: schemaDetails.attributes, + type: SchemaType.W3C_Schema, + schemaIdentifier: schemaDetails.schemaLedgerId, + createDateTime: schemaDetails.createDateTime, + organizationName: schemaDetails?.organisation?.name, + userName: schemaDetails?.organisation?.userOrgRoles[0]?.user?.firstName, + })) + ) + + return schemaResponse + } + const credDefSchemaList = await this.credentialDefinitionRepository.getAllCredDefsByOrgIdForBulk(payload) + + if (!credDefSchemaList) { + throw new NotFoundException(ResponseMessages.credentialDefinition.error.NotFound) + } + + const activeCredDefSchemaList = credDefSchemaList.filter((item) => !item?.isSchemaArchived) + + return activeCredDefSchemaList + } catch (error) { + this.logger.error(`get Cred-Defs and schema List By OrgId for bulk operations: ${JSON.stringify(error)}`) + if (error?.status?.message?.error) { + const reason = error?.status?.message?.error?.reason ?? error?.status?.message?.error + throw new RpcException({ + message: reason, + statusCode: error?.status?.code, + }) + } + throw new RpcException(error.response ?? error) + } + } async _getOrgAgentApiKey(orgId: string): Promise { - const pattern = { cmd: 'get-org-agent-api-key' }; - const payload = { orgId }; + 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.natsClient.send(this.credDefServiceProxy, pattern, payload); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.natsClient.send(this.credDefServiceProxy, pattern, payload) + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException({ - status: error.status, - error: error.message - }, error.status); + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw new HttpException( + { + status: error.status, + error: error.message, + }, + error.status + ) } } async storeCredDefRecord(credDefDetails: ISaveCredDef): Promise { try { - const schemaSearchResult = await this.credentialDefinitionRepository.storeCredDefRecord(credDefDetails); - return schemaSearchResult; + const schemaSearchResult = await this.credentialDefinitionRepository.storeCredDefRecord(credDefDetails) + return schemaSearchResult } catch (error) { - this.logger.error(`Error in getSchemaBySchemaId: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in getSchemaBySchemaId: ${error}`) + throw new RpcException(error.response ? error.response : error) } } -} \ 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 dbbd2c876..64ab3e451 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 @@ -1,64 +1,63 @@ -import { SortValue } from '@credebl/enum/enum'; -import { CreateCredentialDefinitionDto } from 'apps/api-gateway/src/credential-definition/dto/create-cred-defs.dto'; -import { IUserRequestInterface } from '.'; - +import type { SortValue } from '@credebl/enum/enum' +import type { CreateCredentialDefinitionDto } from 'apps/api-gateway/src/credential-definition/dto/create-cred-defs.dto' +import type { IUserRequestInterface } from '.' export interface GetCredDefPayload { - page?: number; - searchText?: string; - itemsPerPage?: number; - user?: IUserRequestInterface; - orgId?: string; - sortValue?: SortValue; - credDefSortBy?: string; - supportRevocation?: string; - credentialDefinitionId?: string; - orgDid: string; + page?: number + searchText?: string + itemsPerPage?: number + user?: IUserRequestInterface + orgId?: string + sortValue?: SortValue + credDefSortBy?: string + supportRevocation?: string + credentialDefinitionId?: string + orgDid: string } export interface CreateCredDefPayload { - credDef: CreateCredentialDefinitionDto; - user: IUserRequestInterface; - orgId?: string; + credDef: CreateCredentialDefinitionDto + user: IUserRequestInterface + orgId?: string } export interface IPlatformCredDefs { - ledgerId?: string; - pageNumber?: number; - pageSize?: number; - sortField?: string; - sortBy?: string; - search?: string; + ledgerId?: string + pageNumber?: number + pageSize?: number + sortField?: string + sortBy?: string + search?: string user: IUserRequestInterface } export interface CredDefPayload { - userId?: string, - schemaId?: string; - tag?: string; - issuerId?: string; - credentialDefinitionId?: string; - issuerDid?: string; - schemaLedgerId?: string; - orgId?: string; - createdBy?: string; - lastChangedBy?: string; - autoIssue?: boolean; - revocable?: boolean; - orgDid?: string; + userId?: string + schemaId?: string + tag?: string + issuerId?: string + credentialDefinitionId?: string + issuerDid?: string + schemaLedgerId?: string + orgId?: string + createdBy?: string + lastChangedBy?: string + autoIssue?: boolean + revocable?: boolean + orgDid?: string } export class GetAllCredDefsDto { - pageSize?: number; - pageNumber?: number; - searchByText?: string; - sorting?: string; - revocable?: boolean; - sortByValue?: string; + pageSize?: number + pageNumber?: number + searchByText?: string + sorting?: string + revocable?: boolean + sortByValue?: string } export interface GetAllCredDefsPayload { - credDefSearchCriteria: GetAllCredDefsDto, - user: IUserRequestInterface, + credDefSearchCriteria: GetAllCredDefsDto + user: IUserRequestInterface orgId: string } @@ -67,16 +66,16 @@ export interface GetCredDefBySchemaId { } export interface ISaveCredDef { - schemaLedgerId: string; - tag: string; - credentialDefinitionId: string; - revocable: boolean; - createdBy: string; - lastChangedBy: string; - orgId: string; - schemaId: string; + schemaLedgerId: string + tag: string + credentialDefinitionId: string + revocable: boolean + createdBy: string + lastChangedBy: string + orgId: string + schemaId: string } export interface SaveCredDefPayload { credDefDetails: ISaveCredDef -} \ No newline at end of file +} diff --git a/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts b/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts index 69e2f4096..0d75d966d 100644 --- a/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts +++ b/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts @@ -1,44 +1,45 @@ export interface CreateCredDefAgentRedirection { - tenantId?: string; - tag?: string; - schemaId?: string; - issuerId?: string; - payload?: ITenantCredDef; - method?: string; - agentType?: string; - apiKey?: string; - agentEndPoint?: string; - orgId?: string; + tenantId?: string + tag?: string + schemaId?: string + issuerId?: string + payload?: ITenantCredDef + method?: string + agentType?: string + apiKey?: string + agentEndPoint?: string + orgId?: string } export interface ITenantCredDef { - tag: string; - schemaId: string; - issuerId: string; + tag: string + schemaId: string + issuerId: string } export interface GetCredDefAgentRedirection { - credentialDefinitionId?: string; - tenantId?: string; - payload?: GetCredDefFromTenantPayload; - apiKey?: string; - agentEndPoint?: string; - agentType?: string; - method?: string; - orgId?: string; + credentialDefinitionId?: string + tenantId?: string + payload?: GetCredDefFromTenantPayload + apiKey?: string + agentEndPoint?: string + agentType?: string + method?: string + orgId?: string } export interface GetCredDefFromTenantPayload { - credentialDefinitionId: string; + credentialDefinitionId: string } export interface CredDefSchema { - credentialDefinitionId?: string; - schemaCredDefName: string; + [x: string]: any + credentialDefinitionId?: string + schemaCredDefName: string } export interface BulkCredDefSchema { - orgId: string - sortValue: string, - credDefSortBy: string + orgId: string + sortValue: string + credDefSortBy: string } diff --git a/apps/ledger/src/credential-definition/interfaces/index.ts b/apps/ledger/src/credential-definition/interfaces/index.ts index bb5099072..d356fca31 100644 --- a/apps/ledger/src/credential-definition/interfaces/index.ts +++ b/apps/ledger/src/credential-definition/interfaces/index.ts @@ -1,66 +1,65 @@ -import { UserRoleOrgPermsDto } from '../../schema/dtos/user-role-org-perms.dto'; +import type { UserRoleOrgPermsDto } from '../../schema/dtos/user-role-org-perms.dto' export interface IUserRequestInterface { - id: string; - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?: string; - selectedOrg: ISelectedOrgInterface; + id: string + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string + selectedOrg: ISelectedOrgInterface } export interface ISelectedOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: IOrganizationInterface; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: IOrganizationInterface } export interface IOrganizationInterface { - name: string; - description: string; + name: string + description: string org_agents: IOrgAgentInterface[] - } export interface IOrgAgentInterface { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } -export interface ISchemaResponse{ - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - orgId: string; - createDateTime?: Date; - createdBy?: string; - organisation?: Organisation; +export interface ISchemaResponse { + name: string + version: string + attributes: string + schemaLedgerId: string + orgId: string + createDateTime?: Date + createdBy?: string + organisation?: Organisation } interface UserDetails { - firstName: string; + firstName: string } interface UserOrgRole { - user: UserDetails; + user: UserDetails } interface Organisation { - name: string; - userOrgRoles: UserOrgRole[]; -} \ No newline at end of file + name: string + userOrgRoles: UserOrgRole[] +} 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 6923b49ea..27bee48ac 100644 --- a/apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts +++ b/apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts @@ -1,356 +1,349 @@ +import type { ICredDefData, IPlatformCredDefDetails } from '@credebl/common/interfaces/cred-def.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { SchemaType, SortValue } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, Logger } from '@nestjs/common' +import type { credential_definition, org_agents, org_agents_type, organisation, schema } from '@prisma/client' +import type { ISchemaResponse } from '../interfaces' /* eslint-disable camelcase */ -import { CredDefPayload, GetAllCredDefsDto, IPlatformCredDefs, ISaveCredDef } from '../interfaces/create-credential-definition.interface'; -import { PrismaService } from '@credebl/prisma-service'; -import { credential_definition, org_agents, org_agents_type, organisation, schema } from '@prisma/client'; -import { Injectable, Logger } from '@nestjs/common'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { BulkCredDefSchema, CredDefSchema } from '../interfaces/credential-definition.interface'; -import { ICredDefData, IPlatformCredDefDetails } from '@credebl/common/interfaces/cred-def.interface'; -import { SchemaType, SortValue } from '@credebl/enum/enum'; -import { ISchemaResponse } from '../interfaces'; +import type { + CredDefPayload, + GetAllCredDefsDto, + IPlatformCredDefs, + ISaveCredDef, +} from '../interfaces/create-credential-definition.interface' +import type { BulkCredDefSchema, CredDefSchema } from '../interfaces/credential-definition.interface' @Injectable() export class CredentialDefinitionRepository { - private readonly logger = new Logger('CredentialDefinitionRepository'); + private readonly logger = new Logger('CredentialDefinitionRepository') - constructor( - private prisma: PrismaService - ) { } + constructor(private prisma: PrismaService) {} - async saveCredentialDefinition(credDef: CredDefPayload): Promise { - try { - const dbResult: credential_definition = await this.getByAttribute( - credDef.schemaLedgerId, - credDef.tag - ); - if (!dbResult) { - const saveResult = await this.prisma.credential_definition.create({ - data: { - schemaLedgerId: credDef.schemaLedgerId, - tag: credDef.tag, - credentialDefinitionId: credDef.credentialDefinitionId, - revocable: credDef.revocable, - createdBy: credDef.createdBy, - lastChangedBy: credDef.lastChangedBy, - orgId: credDef.orgId, - schemaId: credDef.schemaId - } - }); - return saveResult; - } - } catch (error) { - this.logger.error( - `${ResponseMessages.credentialDefinition.error.NotSaved}: ${error.message} ` - ); - throw error; - } + async saveCredentialDefinition(credDef: CredDefPayload): Promise { + try { + const dbResult: credential_definition = await this.getByAttribute(credDef.schemaLedgerId, credDef.tag) + if (!dbResult) { + const saveResult = await this.prisma.credential_definition.create({ + data: { + schemaLedgerId: credDef.schemaLedgerId, + tag: credDef.tag, + credentialDefinitionId: credDef.credentialDefinitionId, + revocable: credDef.revocable, + createdBy: credDef.createdBy, + lastChangedBy: credDef.lastChangedBy, + orgId: credDef.orgId, + schemaId: credDef.schemaId, + }, + }) + return saveResult + } + } catch (error) { + this.logger.error(`${ResponseMessages.credentialDefinition.error.NotSaved}: ${error.message} `) + throw error } + } - async getSchemaById(schemaLedgerId: string): Promise { - try { - const response = await this.prisma.schema.findFirst({ where: { schemaLedgerId } }); - return response; - } catch (error) { - this.logger.error( - `${ResponseMessages.credentialDefinition.error.NotSaved}: ${error.message} ` - ); - throw error; - } + async getSchemaById(schemaLedgerId: string): Promise { + try { + const response = await this.prisma.schema.findFirst({ where: { schemaLedgerId } }) + return response + } catch (error) { + this.logger.error(`${ResponseMessages.credentialDefinition.error.NotSaved}: ${error.message} `) + throw error } + } - async getAllPlatformCredDefsDetails(credDefsPayload: IPlatformCredDefs): Promise { - try { - const { ledgerId, search, sortBy, sortField, pageNumber, pageSize } = credDefsPayload || {}; - const credDefResult = await this.prisma.credential_definition.findMany({ - where: { - schema: { - ledgerId - }, - OR: [ - { tag: { contains: search, mode: 'insensitive' } }, - { credentialDefinitionId: { contains: search, mode: 'insensitive' } }, - { schemaLedgerId: { contains: search, mode: 'insensitive' } } - ] - }, - select: { - createDateTime: true, - tag: true, - schemaId: true, - orgId: true, - schemaLedgerId: true, - createdBy: true, - credentialDefinitionId: true, - revocable: true + async getAllPlatformCredDefsDetails(credDefsPayload: IPlatformCredDefs): Promise { + try { + const { ledgerId, search, sortBy, sortField, pageNumber, pageSize } = credDefsPayload || {} + const credDefResult = await this.prisma.credential_definition.findMany({ + where: { + schema: { + ledgerId, + }, + OR: [ + { tag: { contains: search, mode: 'insensitive' } }, + { credentialDefinitionId: { contains: search, mode: 'insensitive' } }, + { schemaLedgerId: { contains: search, mode: 'insensitive' } }, + ], }, - orderBy: { - [sortField]: SortValue.DESC === sortBy ? SortValue.DESC : SortValue.ASC - }, - take: Number(pageSize), - skip: (pageNumber - 1) * pageSize - }); - - const credDefCount = await this.prisma.credential_definition.count({ - where: { - schema: { - ledgerId - } - } - }); - return { credDefCount, credDefResult }; - } catch (error) { - this.logger.error(`Error in getting credential definitions: ${error}`); - throw error; - } - } - - async getByAttribute(schema: string, tag: string): Promise { - try { - const response = await this.prisma.credential_definition.findFirst({ where: { schemaLedgerId: schema, tag: { contains: tag, mode: 'insensitive' } } }); - return response; - } catch (error) { - this.logger.error(`${ResponseMessages.credentialDefinition.error.NotFound}: ${error}`); - } - } + select: { + createDateTime: true, + tag: true, + schemaId: true, + orgId: true, + schemaLedgerId: true, + createdBy: true, + credentialDefinitionId: true, + revocable: true, + }, + orderBy: { + [sortField]: SortValue.DESC === sortBy ? SortValue.DESC : SortValue.ASC, + }, + take: Number(pageSize), + skip: (pageNumber - 1) * pageSize, + }) - async getAllCredDefs(credDefSearchCriteria: GetAllCredDefsDto, orgId: string): Promise { - try { - const credDefResult = await this.prisma.credential_definition.findMany({ - where: { - orgId, - OR: [ - { tag: { contains: credDefSearchCriteria.searchByText, mode: 'insensitive' } }, - { credentialDefinitionId: { contains: credDefSearchCriteria.searchByText, mode: 'insensitive' } }, - { schemaLedgerId: { contains: credDefSearchCriteria.searchByText, mode: 'insensitive' } } - ] - }, - select: { - createDateTime: true, - tag: true, - schemaId: true, - orgId: true, - schemaLedgerId: true, - createdBy: true, - credentialDefinitionId: true, - revocable: true - }, - orderBy: { - [credDefSearchCriteria.sorting]: SortValue.DESC === credDefSearchCriteria.sortByValue ? SortValue.DESC : SortValue.ASC - }, - take: credDefSearchCriteria.pageSize, - skip: (credDefSearchCriteria.pageNumber - 1) * credDefSearchCriteria.pageSize - }); - return credDefResult; - } catch (error) { - this.logger.error(`Error in getting credential definitions: ${error}`); - throw error; - } + const credDefCount = await this.prisma.credential_definition.count({ + where: { + schema: { + ledgerId, + }, + }, + }) + return { credDefCount, credDefResult } + } catch (error) { + this.logger.error(`Error in getting credential definitions: ${error}`) + throw error } + } - async getAgentDetailsByOrgId(orgId: string): Promise<{ - orgDid: string; - agentEndPoint: string; - tenantId: string - }> { - try { - const schemasResult = await this.prisma.org_agents.findFirst({ - where: { - orgId - }, - select: { - orgDid: true, - agentEndPoint: true, - tenantId: true - } - }); - return schemasResult; - } catch (error) { - this.logger.error(`Error in getting agent DID: ${error}`); - throw error; - } + async getByAttribute(schema: string, tag: string): Promise { + try { + const response = await this.prisma.credential_definition.findFirst({ + where: { schemaLedgerId: schema, tag: { contains: tag, mode: 'insensitive' } }, + }) + return response + } catch (error) { + this.logger.error(`${ResponseMessages.credentialDefinition.error.NotFound}: ${error}`) } + } - async getAgentType(orgId: string): Promise { - try { - const agentDetails = await this.prisma.organisation.findUnique({ - where: { - id: orgId - }, - include: { - org_agents: { - include: { - org_agent_type: true - } - } - } - }); - return agentDetails; - } catch (error) { - this.logger.error(`Error in getting agent type: ${error}`); - throw error; - } + async getAllCredDefs(credDefSearchCriteria: GetAllCredDefsDto, orgId: string): Promise { + try { + const credDefResult = await this.prisma.credential_definition.findMany({ + where: { + orgId, + OR: [ + { tag: { contains: credDefSearchCriteria.searchByText, mode: 'insensitive' } }, + { credentialDefinitionId: { contains: credDefSearchCriteria.searchByText, mode: 'insensitive' } }, + { schemaLedgerId: { contains: credDefSearchCriteria.searchByText, mode: 'insensitive' } }, + ], + }, + select: { + createDateTime: true, + tag: true, + schemaId: true, + orgId: true, + schemaLedgerId: true, + createdBy: true, + credentialDefinitionId: true, + revocable: true, + }, + orderBy: { + [credDefSearchCriteria.sorting]: + SortValue.DESC === credDefSearchCriteria.sortByValue ? SortValue.DESC : SortValue.ASC, + }, + take: credDefSearchCriteria.pageSize, + skip: (credDefSearchCriteria.pageNumber - 1) * credDefSearchCriteria.pageSize, + }) + return credDefResult + } catch (error) { + this.logger.error(`Error in getting credential definitions: ${error}`) + throw error } + } - async getCredentialDefinitionBySchemaId(schemaId: string): Promise { - try { - return this.prisma.credential_definition.findMany({ - where: { - schemaLedgerId: schemaId - } - - }); - } catch (error) { - this.logger.error(`Error in getting credential definitions: ${error}`); - throw error; - } + async getAgentDetailsByOrgId(orgId: string): Promise<{ + orgDid: string + agentEndPoint: string + tenantId: string + }> { + try { + const schemasResult = await this.prisma.org_agents.findFirst({ + where: { + orgId, + }, + select: { + orgDid: true, + agentEndPoint: true, + tenantId: true, + }, + }) + return schemasResult + } catch (error) { + this.logger.error(`Error in getting agent DID: ${error}`) + throw error } + } + async getAgentType(orgId: string): Promise< + organisation & { + org_agents: (org_agents & { + org_agent_type: org_agents_type + })[] + } + > { + try { + const agentDetails = await this.prisma.organisation.findUnique({ + where: { + id: orgId, + }, + include: { + org_agents: { + include: { + org_agent_type: true, + }, + }, + }, + }) + return agentDetails + } catch (error) { + this.logger.error(`Error in getting agent type: ${error}`) + throw error + } + } - async getAllCredDefsByOrgIdForBulk(payload: BulkCredDefSchema): Promise { - try { - const { credDefSortBy, sortValue, orgId } = payload; - - const credentialDefinitions = await this.prisma.credential_definition.findMany({ - where: { - orgId - }, - select: { - id: true, - credentialDefinitionId: true, - tag: true, - createDateTime: true, - schemaLedgerId: true - }, - orderBy: { - [credDefSortBy]: SortValue.DESC === sortValue ? SortValue.DESC : SortValue.ASC - } - }); + async getCredentialDefinitionBySchemaId(schemaId: string): Promise { + try { + return this.prisma.credential_definition.findMany({ + where: { + schemaLedgerId: schemaId, + }, + }) + } catch (error) { + this.logger.error(`Error in getting credential definitions: ${error}`) + throw error + } + } - const schemaLedgerIdArray = credentialDefinitions.map((credDef) => credDef.schemaLedgerId); + async getAllCredDefsByOrgIdForBulk(payload: BulkCredDefSchema): Promise { + try { + const { credDefSortBy, sortValue, orgId } = payload - const schemas = await this.prisma.schema.findMany({ - where: { - schemaLedgerId: { - in: schemaLedgerIdArray - }, - type: SchemaType.INDY - }, - select: { - name: true, - version: true, - schemaLedgerId: true, - orgId: true, - attributes: true, - isSchemaArchived: true - } - }); + const credentialDefinitions = await this.prisma.credential_definition.findMany({ + where: { + orgId, + }, + select: { + id: true, + credentialDefinitionId: true, + tag: true, + createDateTime: true, + schemaLedgerId: true, + }, + orderBy: { + [credDefSortBy]: SortValue.DESC === sortValue ? SortValue.DESC : SortValue.ASC, + }, + }) - // Match Credential Definitions with Schemas and map to CredDefSchema - const matchingSchemas = credentialDefinitions.map((credDef) => { + const schemaLedgerIdArray = credentialDefinitions.map((credDef) => credDef.schemaLedgerId) - const matchingSchema = schemas.find((schema) => schema.schemaLedgerId === credDef.schemaLedgerId); - if (matchingSchema) { - return { - credentialDefinitionId: credDef.credentialDefinitionId, - credentialDefinition: credDef.tag, - schemaCredDefName: `${matchingSchema.name}:${matchingSchema.version}-${credDef.tag}`, - schemaName: matchingSchema.name, - schemaVersion: matchingSchema.version, - schemaAttributes: matchingSchema.attributes, - schemaLedgerId: matchingSchema.schemaLedgerId, - isSchemaArchived: matchingSchema.isSchemaArchived - }; - } - return null; - }); + const schemas = await this.prisma.schema.findMany({ + where: { + schemaLedgerId: { + in: schemaLedgerIdArray, + }, + type: SchemaType.INDY, + }, + select: { + name: true, + version: true, + schemaLedgerId: true, + orgId: true, + attributes: true, + isSchemaArchived: true, + }, + }) - // Filter out null values (missing schemas) and return the result - return matchingSchemas.filter((schema) => null !== schema) as CredDefSchema[]; - } catch (error) { - this.logger.error(`Error in listing all credential definitions with schema details: ${error}`); - throw error; + // Match Credential Definitions with Schemas and map to CredDefSchema + const matchingSchemas = credentialDefinitions.map((credDef) => { + const matchingSchema = schemas.find((schema) => schema.schemaLedgerId === credDef.schemaLedgerId) + if (matchingSchema) { + return { + credentialDefinitionId: credDef.credentialDefinitionId, + credentialDefinition: credDef.tag, + schemaCredDefName: `${matchingSchema.name}:${matchingSchema.version}-${credDef.tag}`, + schemaName: matchingSchema.name, + schemaVersion: matchingSchema.version, + schemaAttributes: matchingSchema.attributes, + schemaLedgerId: matchingSchema.schemaLedgerId, + isSchemaArchived: matchingSchema.isSchemaArchived, + } } + return null + }) + + // Filter out null values (missing schemas) and return the result + return matchingSchemas.filter((schema) => schema !== null) as CredDefSchema[] + } catch (error) { + this.logger.error(`Error in listing all credential definitions with schema details: ${error}`) + throw error } + } - async getAllSchemaByOrgIdAndType(orgId: string, schemaType: string): Promise { - try { - return await this.prisma.schema.findMany({ - where: { - orgId, - isSchemaArchived: false, - type: schemaType - }, + async getAllSchemaByOrgIdAndType(orgId: string, schemaType: string): Promise { + try { + return await this.prisma.schema.findMany({ + where: { + orgId, + isSchemaArchived: false, + type: schemaType, + }, + select: { + name: true, + version: true, + schemaLedgerId: true, + orgId: true, + attributes: true, + createDateTime: true, + createdBy: true, + organisation: { + select: { + name: true, + userOrgRoles: { select: { - name: true, - version: true, - schemaLedgerId: true, - orgId: true, - attributes: true, - createDateTime: true, - createdBy: true, - organisation: { - select:{ - name: true, - userOrgRoles: { - select: { - user: { - select: { - firstName: true - } - } - } - } - } - } - } - }); - } catch (error) { - this.logger.error(`[getAllSchemaByOrgIdAndType] - error: ${JSON.stringify(error)}`); - throw error; - } + user: { + select: { + firstName: true, + }, + }, + }, + }, + }, + }, + }, + }) + } catch (error) { + this.logger.error(`[getAllSchemaByOrgIdAndType] - error: ${JSON.stringify(error)}`) + throw error } - - - async getOrgAgentType(orgAgentId: string): Promise { - try { - - const { agent } = await this.prisma.org_agents_type.findFirst({ - where: { - id: orgAgentId - } - }); - - return agent; - } catch (error) { - this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`); - throw error; - } - } + } - async storeCredDefRecord(credDefDetails: ISaveCredDef): Promise { - try { - const saveResult = await this.prisma.credential_definition.create({ - data: { - schemaLedgerId: credDefDetails.schemaLedgerId, - tag: credDefDetails.tag, - credentialDefinitionId: credDefDetails.credentialDefinitionId, - revocable: credDefDetails.revocable, - createdBy: credDefDetails.createdBy, - lastChangedBy: credDefDetails.lastChangedBy, - orgId: credDefDetails.orgId, - schemaId: credDefDetails.schemaId - } - }); - return saveResult; - } catch (error) { - this.logger.error( - `Error in saving credential-definition: ${error.message} ` - ); - throw error; - } + async getOrgAgentType(orgAgentId: string): Promise { + try { + const { agent } = await this.prisma.org_agents_type.findFirst({ + where: { + id: orgAgentId, + }, + }) + + return agent + } catch (error) { + this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`) + throw error } + } -} \ No newline at end of file + async storeCredDefRecord(credDefDetails: ISaveCredDef): Promise { + try { + const saveResult = await this.prisma.credential_definition.create({ + data: { + schemaLedgerId: credDefDetails.schemaLedgerId, + tag: credDefDetails.tag, + credentialDefinitionId: credDefDetails.credentialDefinitionId, + revocable: credDefDetails.revocable, + createdBy: credDefDetails.createdBy, + lastChangedBy: credDefDetails.lastChangedBy, + orgId: credDefDetails.orgId, + schemaId: credDefDetails.schemaId, + }, + }) + return saveResult + } catch (error) { + this.logger.error(`Error in saving credential-definition: ${error.message} `) + throw error + } + } +} diff --git a/apps/ledger/src/interfaces/ledgers.interface.ts b/apps/ledger/src/interfaces/ledgers.interface.ts index e8ca2d5f3..ba73b7656 100644 --- a/apps/ledger/src/interfaces/ledgers.interface.ts +++ b/apps/ledger/src/interfaces/ledgers.interface.ts @@ -1,6 +1,6 @@ export interface LedgerDetails { - id: string, - name: string, - indyNamespace: string, - networkUrl: string -} \ No newline at end of file + id: string + name: string + indyNamespace: string + networkUrl: string +} diff --git a/apps/ledger/src/ledger.controller.spec.ts b/apps/ledger/src/ledger.controller.spec.ts index a40191922..5a3df825d 100644 --- a/apps/ledger/src/ledger.controller.spec.ts +++ b/apps/ledger/src/ledger.controller.spec.ts @@ -1,22 +1,22 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { LedgerServiceController } from './ledger.controller'; -import { LedgerServiceService } from './ledger.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { LedgerServiceController } from './ledger.controller' +import { LedgerServiceService } from './ledger.service' describe('LedgerServiceController', () => { - let ledgerServiceController: LedgerServiceController; + let ledgerServiceController: LedgerServiceController beforeEach(async () => { const app: TestingModule = await Test.createTestingModule({ controllers: [LedgerServiceController], - providers: [LedgerServiceService] - }).compile(); + providers: [LedgerServiceService], + }).compile() - ledgerServiceController = app.get(LedgerServiceController); - }); + ledgerServiceController = app.get(LedgerServiceController) + }) describe('root', () => { it('should return "Hello World!"', () => { - expect(ledgerServiceController.getHello()).toBe('Hello World!'); - }); - }); -}); + expect(ledgerServiceController.getHello()).toBe('Hello World!') + }) + }) +}) diff --git a/apps/ledger/src/ledger.controller.ts b/apps/ledger/src/ledger.controller.ts index 250203dfb..7682183bc 100644 --- a/apps/ledger/src/ledger.controller.ts +++ b/apps/ledger/src/ledger.controller.ts @@ -1,32 +1,37 @@ -import { Controller } from '@nestjs/common'; -import { LedgerService } from './ledger.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { ledgers } from '@prisma/client'; -import { LedgerDetails } from './interfaces/ledgers.interface'; -import { INetworkUrl } from '@credebl/common/interfaces/schema.interface'; -import { ISchemasList } from './schema/interfaces/schema.interface'; +import type { INetworkUrl } from '@credebl/common/interfaces/schema.interface' +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { ledgers } from '@prisma/client' +import type { LedgerDetails } from './interfaces/ledgers.interface' +import type { LedgerService } from './ledger.service' +import type { ISchemasList } from './schema/interfaces/schema.interface' @Controller() export class LedgerController { - constructor(private readonly ledgerService: LedgerService) { } + constructor(private readonly ledgerService: LedgerService) {} @MessagePattern({ cmd: 'get-all-ledgers' }) async getAllLedgers(): Promise { - return this.ledgerService.getAllLedgers(); + return this.ledgerService.getAllLedgers() } @MessagePattern({ cmd: 'get-network-url' }) async getNetworkUrl(indyNamespace: string): Promise { - return this.ledgerService.getNetworkUrl(indyNamespace); + return this.ledgerService.getNetworkUrl(indyNamespace) } @MessagePattern({ cmd: 'get-network-details-by-id' }) - async getNetworkDetailsById(payload: {id: string}): Promise { - return this.ledgerService.getLedgerDetailsById(payload.id); + async getNetworkDetailsById(payload: { id: string }): Promise { + return this.ledgerService.getLedgerDetailsById(payload.id) } @MessagePattern({ cmd: 'get-schema-details-for-ecosystem' }) - async schemaDetailsForEcosystem(payload: {schemaArray: string[], search: string, pageSize: number, pageNumber: number}): Promise { - return this.ledgerService.schemaDetailsForEcosystem(payload); + async schemaDetailsForEcosystem(payload: { + schemaArray: string[] + search: string + pageSize: number + pageNumber: number + }): Promise { + return this.ledgerService.schemaDetailsForEcosystem(payload) } -} \ No newline at end of file +} diff --git a/apps/ledger/src/ledger.module.ts b/apps/ledger/src/ledger.module.ts index ed5daa043..4f625bcd0 100644 --- a/apps/ledger/src/ledger.module.ts +++ b/apps/ledger/src/ledger.module.ts @@ -1,38 +1,35 @@ -import { Logger, Module } from '@nestjs/common'; -import { LedgerController } from './ledger.controller'; -import { LedgerService } from './ledger.service'; -import { SchemaModule } from './schema/schema.module'; -import { PrismaService } from '@credebl/prisma-service'; -import { CredentialDefinitionModule } from './credential-definition/credential-definition.module'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { LedgerRepository } from './repositories/ledger.repository'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { CredentialDefinitionModule } from './credential-definition/credential-definition.module' +import { LedgerController } from './ledger.controller' +import { LedgerService } from './ledger.service' +import { LedgerRepository } from './repositories/ledger.repository' +import { SchemaModule } from './schema/schema.module' @Module({ imports: [ GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, + LoggerModule, + PlatformConfig, + ContextInterceptorModule, ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.LEDGER_SERVICE, process.env.LEDGER_NKEY_SEED) - - } + options: getNatsOptions(CommonConstants.LEDGER_SERVICE, process.env.LEDGER_NKEY_SEED), + }, ]), - SchemaModule, CredentialDefinitionModule + SchemaModule, + CredentialDefinitionModule, ], controllers: [LedgerController], - providers: [ - LedgerService, - PrismaService, - LedgerRepository, - Logger - ] + providers: [LedgerService, PrismaService, LedgerRepository, Logger], }) -export class LedgerModule { } +export class LedgerModule {} diff --git a/apps/ledger/src/ledger.service.ts b/apps/ledger/src/ledger.service.ts index 170f6c3ac..58faab9e3 100644 --- a/apps/ledger/src/ledger.service.ts +++ b/apps/ledger/src/ledger.service.ts @@ -1,83 +1,82 @@ -import { Injectable, NotFoundException } from '@nestjs/common'; -import { BaseService } from 'libs/service/base.service'; -import { LedgerRepository } from './repositories/ledger.repository'; -import { RpcException } from '@nestjs/microservices'; +import type { INetworkUrl } from '@credebl/common/interfaces/schema.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Injectable, NotFoundException } from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' // eslint-disable-next-line camelcase -import { ledgers } from '@prisma/client'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { LedgerDetails } from './interfaces/ledgers.interface'; -import { INetworkUrl } from '@credebl/common/interfaces/schema.interface'; -import { ISchemasList } from './schema/interfaces/schema.interface'; +import type { ledgers } from '@prisma/client' +import { BaseService } from 'libs/service/base.service' +import type { LedgerDetails } from './interfaces/ledgers.interface' +import type { LedgerRepository } from './repositories/ledger.repository' +import type { ISchemasList } from './schema/interfaces/schema.interface' @Injectable() export class LedgerService extends BaseService { - - constructor( - private readonly ledgerRepository: LedgerRepository - ) { - super('LedgerService'); + constructor(private readonly ledgerRepository: LedgerRepository) { + super('LedgerService') + } + + async getAllLedgers(): Promise { + try { + const getAllLedgerDetails = await this.ledgerRepository.getAllLedgers() + + if (!getAllLedgerDetails) { + throw new NotFoundException(ResponseMessages.ledger.error.NotFound) + } + + return getAllLedgerDetails + } catch (error) { + this.logger.error(`Error in retrieving all ledgers: ${error}`) + throw new RpcException(error.response ? error.response : error) } + } - async getAllLedgers(): Promise { - try { - const getAllLedgerDetails = await this.ledgerRepository.getAllLedgers(); + async getNetworkUrl(indyNamespace: string): Promise { + try { + const getNetworkUrl = await this.ledgerRepository.getNetworkUrl(indyNamespace) - if (!getAllLedgerDetails) { - throw new NotFoundException(ResponseMessages.ledger.error.NotFound); - } + if (!getNetworkUrl) { + throw new NotFoundException(ResponseMessages.ledger.error.NotFound) + } - return getAllLedgerDetails; - } catch (error) { - this.logger.error(`Error in retrieving all ledgers: ${error}`); - throw new RpcException(error.response ? error.response : error); - } + return getNetworkUrl + } catch (error) { + this.logger.error(`Error in retrieving network url: ${error}`) + throw new RpcException(error.response ? error.response : error) } + } - async getNetworkUrl(indyNamespace: string): Promise { - try { - const getNetworkUrl = await this.ledgerRepository.getNetworkUrl(indyNamespace); + async getLedgerDetailsById(id: string): Promise { + try { + const getAllLedgerDetails = await this.ledgerRepository.getNetworkById(id) - if (!getNetworkUrl) { - throw new NotFoundException(ResponseMessages.ledger.error.NotFound); - } + if (!getAllLedgerDetails) { + throw new NotFoundException(ResponseMessages.ledger.error.NotFound) + } - return getNetworkUrl; - } catch (error) { - this.logger.error(`Error in retrieving network url: ${error}`); - throw new RpcException(error.response ? error.response : error); - } + return getAllLedgerDetails + } catch (error) { + this.logger.error(`Error in getLedgerDetailsById: ${error}`) + throw new RpcException(error.response ? error.response : error) } - - async getLedgerDetailsById(id: string): Promise { - try { - const getAllLedgerDetails = await this.ledgerRepository.getNetworkById(id); - - if (!getAllLedgerDetails) { - throw new NotFoundException(ResponseMessages.ledger.error.NotFound); - } - - return getAllLedgerDetails; - } catch (error) { - this.logger.error(`Error in getLedgerDetailsById: ${error}`); - throw new RpcException(error.response ? error.response : error); - } + } + + async schemaDetailsForEcosystem(data: { + schemaArray: string[] + search: string + pageSize: number + pageNumber: number + }): Promise { + try { + const getSchemaDetails = await this.ledgerRepository.handleGetSchemas(data) + + if (!getSchemaDetails) { + throw new NotFoundException(ResponseMessages.ledger.error.NotFound) + } + + return getSchemaDetails + } catch (error) { + this.logger.error(`Error in getLedgerDetailsById: ${error}`) + throw new RpcException(error.response ? error.response : error) } - - - async schemaDetailsForEcosystem(data: {schemaArray: string[], search: string, pageSize: number, pageNumber: number}): Promise { - - try { - const getSchemaDetails = await this.ledgerRepository.handleGetSchemas(data); - - if (!getSchemaDetails) { - throw new NotFoundException(ResponseMessages.ledger.error.NotFound); - } - - return getSchemaDetails; - } catch (error) { - this.logger.error(`Error in getLedgerDetailsById: ${error}`); - throw new RpcException(error.response ? error.response : error); - } - } - -} \ No newline at end of file + } +} diff --git a/apps/ledger/src/main.ts b/apps/ledger/src/main.ts index fe38aaa35..a24e4d0a9 100644 --- a/apps/ledger/src/main.ts +++ b/apps/ledger/src/main.ts @@ -1,23 +1,21 @@ -import { NestFactory } from '@nestjs/core'; -import { LedgerModule } from './ledger.module'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; - +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { LedgerModule } from './ledger.module' async function bootstrap(): Promise { const app = await NestFactory.createMicroservice(LedgerModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.LEDGER_SERVICE, process.env.LEDGER_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.LEDGER_SERVICE, process.env.LEDGER_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - Logger.log('Ledger-Service Microservice is listening to NATS '); + await app.listen() + Logger.log('Ledger-Service Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/ledger/src/repositories/ledger.repository.ts b/apps/ledger/src/repositories/ledger.repository.ts index 176d365f5..c5b957f26 100644 --- a/apps/ledger/src/repositories/ledger.repository.ts +++ b/apps/ledger/src/repositories/ledger.repository.ts @@ -1,113 +1,110 @@ -import { PrismaService } from '@credebl/prisma-service'; -import { Injectable, Logger } from '@nestjs/common'; +import type { INetworkUrl } from '@credebl/common/interfaces/schema.interface' +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, Logger } from '@nestjs/common' // eslint-disable-next-line camelcase -import { ledgers } from '@prisma/client'; -import { LedgerDetails } from '../interfaces/ledgers.interface'; -import { INetworkUrl } from '@credebl/common/interfaces/schema.interface'; -import { ISchemasList, ISchemasResult } from '../schema/interfaces/schema.interface'; - +import type { ledgers } from '@prisma/client' +import type { LedgerDetails } from '../interfaces/ledgers.interface' +import type { ISchemasList, ISchemasResult } from '../schema/interfaces/schema.interface' @Injectable() export class LedgerRepository { - private readonly logger = new Logger('LedgerRepository'); + private readonly logger = new Logger('LedgerRepository') - constructor( - private prisma: PrismaService - ) { } + constructor(private prisma: PrismaService) {} - async getAllLedgers(): Promise { - try { - return this.prisma.ledgers.findMany(); - } catch (error) { - this.logger.error(`Error in getAllLedgers: ${error}`); - throw error; - } + async getAllLedgers(): Promise { + try { + return this.prisma.ledgers.findMany() + } catch (error) { + this.logger.error(`Error in getAllLedgers: ${error}`) + throw error } + } - async getNetworkUrl(indyNamespace: string): Promise { + async getNetworkUrl(indyNamespace: string): Promise { + try { + return this.prisma.ledgers.findFirstOrThrow({ + where: { + indyNamespace, + }, + select: { + networkUrl: true, + }, + }) + } catch (error) { + this.logger.error(`Error in getNetworkUrl: ${error}`) + throw error + } + } - try { - return this.prisma.ledgers.findFirstOrThrow({ - where: { - indyNamespace - }, - select: { - networkUrl: true - } - }); - } catch (error) { - this.logger.error(`Error in getNetworkUrl: ${error}`); - throw error; - } + async getNetworkById(ledgerId: string): Promise { + try { + return this.prisma.ledgers.findFirst({ + where: { + id: ledgerId, + }, + select: { + id: true, + name: true, + indyNamespace: true, + networkUrl: true, + }, + }) + } catch (error) { + this.logger.error(`Error in getNetworkById: ${error}`) + throw error } + } - async getNetworkById(ledgerId: string): Promise { + async handleGetSchemas(data: { + schemaArray: string[] + search: string + pageSize: number + pageNumber: number + }): Promise { + try { + const { schemaArray, search, pageSize, pageNumber } = data - try { - return this.prisma.ledgers.findFirst({ - where: { - id: ledgerId - }, - select: { - id: true, - name: true, - indyNamespace: true, - networkUrl: true - } - }); - } catch (error) { - this.logger.error(`Error in getNetworkById: ${error}`); - throw error; - } - } + const schemasResult: ISchemasResult[] = await this.prisma.schema.findMany({ + where: { + schemaLedgerId: { + in: schemaArray, + }, + OR: [ + { version: { contains: search, mode: 'insensitive' } }, + { name: { contains: search, mode: 'insensitive' } }, + { schemaLedgerId: { contains: search, mode: 'insensitive' } }, + ], + }, + take: pageSize, + skip: (pageNumber - 1) * pageSize, + orderBy: { + createDateTime: 'desc', + }, + }) - async handleGetSchemas(data: {schemaArray: string[], search: string, pageSize: number, pageNumber: number}): Promise { - try { - const { schemaArray, search, pageSize, pageNumber } = data; - - const schemasResult: ISchemasResult[] = await this.prisma.schema.findMany({ - where: { - schemaLedgerId: { - in: schemaArray - }, - OR: [ - { version: { contains: search, mode: 'insensitive' } }, - { name: { contains: search, mode: 'insensitive' } }, - { schemaLedgerId: { contains: search, mode: 'insensitive' } } - ] - }, - take: pageSize, - skip: (pageNumber - 1) * pageSize, - orderBy: { - createDateTime: 'desc' - } - }); - - // Get the total count of schemas that match the query - const schemasCount = await this.prisma.schema.count({ - where: { - schemaLedgerId: { - in: schemaArray - }, - OR: [ - { version: { contains: search, mode: 'insensitive' } }, - { name: { contains: search, mode: 'insensitive' } }, - { schemaLedgerId: { contains: search, mode: 'insensitive' } } - ] - } - }); - - // Return the schemas and the total count - return { - schemasCount, - schemasResult - }; - - } catch (error) { - this.logger.error(`Error handling 'get-schemas' request: ${JSON.stringify(error)}`); - throw error; - } - } + // Get the total count of schemas that match the query + const schemasCount = await this.prisma.schema.count({ + where: { + schemaLedgerId: { + in: schemaArray, + }, + OR: [ + { version: { contains: search, mode: 'insensitive' } }, + { name: { contains: search, mode: 'insensitive' } }, + { schemaLedgerId: { contains: search, mode: 'insensitive' } }, + ], + }, + }) - -} \ No newline at end of file + // Return the schemas and the total count + return { + schemasCount, + schemasResult, + } + } catch (error) { + this.logger.error(`Error handling 'get-schemas' request: ${JSON.stringify(error)}`) + throw error + } + } +} diff --git a/apps/ledger/src/schema/dtos/user-role-org-perms.dto.ts b/apps/ledger/src/schema/dtos/user-role-org-perms.dto.ts index 2f4069f23..baf7b97ae 100644 --- a/apps/ledger/src/schema/dtos/user-role-org-perms.dto.ts +++ b/apps/ledger/src/schema/dtos/user-role-org-perms.dto.ts @@ -1,27 +1,24 @@ - export class UserRoleOrgPermsDto { - id?: string; - role?: userRoleDto; - organization?: userOrgDto; - userRoleOrgPermissions?: unknown; - } - - export class userRoleDto { - id: string; - name: string; - permissions: string[]; - - } - - export class OrgRole { - id: string; - } - - export class userOrgDto { - id?: string; - orgName?: string; - orgRole?: OrgRole; - agentEndPoint?: string; - apiKey?: string; - } - \ No newline at end of file + id?: string + role?: userRoleDto + organization?: userOrgDto + userRoleOrgPermissions?: unknown +} + +export class userRoleDto { + id: string + name: string + permissions: string[] +} + +export class OrgRole { + id: string +} + +export class userOrgDto { + id?: string + orgName?: string + orgRole?: OrgRole + agentEndPoint?: string + apiKey?: string +} diff --git a/apps/ledger/src/schema/enum/schema.enum.ts b/apps/ledger/src/schema/enum/schema.enum.ts index 1a307a646..6f36f3aec 100644 --- a/apps/ledger/src/schema/enum/schema.enum.ts +++ b/apps/ledger/src/schema/enum/schema.enum.ts @@ -1,15 +1,13 @@ - - export enum SortFields { - ID = 'id', - CREATED_DATE_TIME = 'createDateTime', - NAME = 'name', - VERSION = 'version', - LEDGER_ID = 'schemaLedgerId', - PUBLISHER_DID = 'publisherDid', - ISSUER_ID = 'issuerId' + ID = 'id', + CREATED_DATE_TIME = 'createDateTime', + NAME = 'name', + VERSION = 'version', + LEDGER_ID = 'schemaLedgerId', + PUBLISHER_DID = 'publisherDid', + ISSUER_ID = 'issuerId', } export enum W3CSchemaVersion { - W3C_SCHEMA_VERSION = 'draft/2020-12' + W3C_SCHEMA_VERSION = 'draft/2020-12', } diff --git a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts index db8d09192..386de9625 100644 --- a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts @@ -1,140 +1,138 @@ -import { SchemaType, SortValue } from '@credebl/enum/enum'; -import { IUserRequestInterface } from './schema.interface'; +import type { SchemaType, SortValue } from '@credebl/enum/enum' +import type { IUserRequestInterface } from './schema.interface' export interface ISchema { - schema?: ISchemaPayload; - user?: IUserRequestInterface; - createdBy?: string; - issuerId?: string; - changedBy?: string; - ledgerId?: string; - orgId?: string; - onLedgerStatus?: string; - credDefSortBy?: string; - supportRevocation?: string; - schemaId?: string; - createTransactionForEndorser?: boolean; - transactionId?: string; - endorserWriteTxn?: string; - orgDid?: string; - type?: string; - alias?: string; + schema?: ISchemaPayload + user?: IUserRequestInterface + createdBy?: string + issuerId?: string + changedBy?: string + ledgerId?: string + orgId?: string + onLedgerStatus?: string + credDefSortBy?: string + supportRevocation?: string + schemaId?: string + createTransactionForEndorser?: boolean + transactionId?: string + endorserWriteTxn?: string + orgDid?: string + type?: string + alias?: string } export interface IAttributeValue { - isRequired: boolean; - attributeName: string; - schemaDataType: string; - displayName: string; - + isRequired: boolean + attributeName: string + schemaDataType: string + displayName: string } export interface ISchemaPayload { - schemaVersion: string; - schemaName: string; - orgDid?: string; - attributes: IAttributeValue[]; - issuerId?: string; - onLedgerStatus?: string; - id?: string; - user?: IUserRequestInterface; - page?: number; - searchText?: string - itemsPerPage?: number; - sortValue?: SortValue; - schemaSortBy?: string; + schemaVersion: string + schemaName: string + orgDid?: string + attributes: IAttributeValue[] + issuerId?: string + onLedgerStatus?: string + id?: string + user?: IUserRequestInterface + page?: number + searchText?: string + itemsPerPage?: number + sortValue?: SortValue + schemaSortBy?: string } export interface ISchemaSearchPayload { - schemaSearchCriteria: ISchemaSearchCriteria, - user: IUserRequestInterface, - orgId: string + schemaSearchCriteria: ISchemaSearchCriteria + user: IUserRequestInterface + orgId: string } export interface ISchemaSearchCriteria { - ledgerId?: string; - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - searchByText?: string; - schemaType?: SchemaType; - user?: IUserRequestInterface - schemaId?: string; - orgId?: string; + ledgerId?: string + pageNumber: number + pageSize: number + sortField: string + sortBy: string + searchByText?: string + schemaType?: SchemaType + user?: IUserRequestInterface + schemaId?: string + orgId?: string } export interface ISchemaCredDeffSearchInterface { - schemaId: string; - schemaSearchCriteria?: ISchemaSearchCriteria, - user: IUserRequestInterface, + schemaId: string + schemaSearchCriteria?: ISchemaSearchCriteria + user: IUserRequestInterface } export interface ISchemaExist { - schemaName: string; - version: string; + schemaName: string + version: string } export interface SchemaPayload { - schemaAttributes: W3CSchemaAttributes [], - schemaName: string, - did: string, - description: string - jsonSchemaType?: string - } + schemaAttributes: W3CSchemaAttributes[] + schemaName: string + did: string + description: string + jsonSchemaType?: string +} - export interface W3CSchemaAttributes { - type: string, - title: string, - } - - export interface ISchemaAttributesFormat extends W3CSchemaAttributes{ - order: number, - description: string; - exclusiveMinimum?: number; - multipleOf?: number; - pattern?: string; - minLength?: number; - maxLength?: number; - items?: object[] | string [] | number []; - properties?: object; - format?: string; - minItems?: number; - maxItems?: number; - uniqueItems?: boolean; - } +export interface W3CSchemaAttributes { + type: string + title: string +} + +export interface ISchemaAttributesFormat extends W3CSchemaAttributes { + order: number + description: string + exclusiveMinimum?: number + multipleOf?: number + pattern?: string + minLength?: number + maxLength?: number + items?: object[] | string[] | number[] + properties?: object + format?: string + minItems?: number + maxItems?: number + uniqueItems?: boolean +} export interface W3CSchemaPayload { - schemaPayload: SchemaPayload, - orgId: string, - user: string - } + schemaPayload: SchemaPayload + orgId: string + user: string +} export interface W3CCreateSchema { - url: string, - orgId: string, - schemaRequestPayload: object -} + url: string + orgId: string + schemaRequestPayload: object +} export interface IdAttribute extends W3CSchemaAttributes { - format: string; - order?: string -} - + format: string + order?: string +} export interface ISaveSchema { - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - issuerId: string; - createdBy: string; - lastChangedBy: string; - publisherDid: string; - orgId: string; - ledgerId: string; - type?: string; + name: string + version: string + attributes: string + schemaLedgerId: string + issuerId: string + createdBy: string + lastChangedBy: string + publisherDid: string + orgId: string + ledgerId: string + type?: string } export interface SaveSchemaPayload { - schemaDetails: ISaveSchema -} \ No newline at end of file + schemaDetails: ISaveSchema +} diff --git a/apps/ledger/src/schema/interfaces/schema.interface.ts b/apps/ledger/src/schema/interfaces/schema.interface.ts index 7791d5e2d..bce972b84 100644 --- a/apps/ledger/src/schema/interfaces/schema.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema.interface.ts @@ -1,137 +1,156 @@ -import { JSONSchemaType, SchemaTypeEnum } from '@credebl/enum/enum'; -import { UserRoleOrgPermsDto } from '../dtos/user-role-org-perms.dto'; -import { IW3CAttributeValue } from '@credebl/common/interfaces/interface'; +import type { IW3CAttributeValue } from '@credebl/common/interfaces/interface' +import type { JSONSchemaType, SchemaTypeEnum } from '@credebl/enum/enum' +import type { UserRoleOrgPermsDto } from '../dtos/user-role-org-perms.dto' export interface IUserRequestInterface { - id: string; - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: UserRoleOrgPermsDto[]; - orgName?: string; - selectedOrg: ISelectedOrgInterface; + id: string + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: UserRoleOrgPermsDto[] + orgName?: string + selectedOrg: ISelectedOrgInterface } export interface ISelectedOrgInterface { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: IOrganizationInterface; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: IOrganizationInterface } export interface IOrganizationInterface { - name: string; - description: string; - org_agents: IOrgAgentInterface[]; + name: string + description: string + org_agents: IOrgAgentInterface[] } export interface IOrgAgentInterface { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } export interface AgentDetails { - orgDid: string; - agentEndPoint: string; - tenantId: string; + orgDid: string + agentEndPoint: string + tenantId: string +} +export interface SchemaWithOrgAndUser { + attributes: string + name: string + alias: string + createDateTime: Date + createdBy: string + orgId: string + version: string + schemaLedgerId: string + publisherDid: string + issuerId: string + organisation: { + name: string + userOrgRoles: { + user: { + firstName: string + } + }[] + } } - export interface ISchemaData { - createDateTime: Date; - createdBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - ledgerId?: string; - id?: string; + createDateTime: Date + createdBy: string + name: string + version: string + attributes: string + schemaLedgerId: string + publisherDid: string + issuerId: string + orgId: string + ledgerId?: string + id?: string } export interface ISchemasWithCount { - schemasCount: number; - schemasResult: ISchemaData[]; + schemasCount: number + schemasResult: SchemaWithOrgAndUser[] } export interface IProductSchema { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - properties: Record; - required: string[]; + // biome-ignore lint/suspicious/noExplicitAny: + properties: Record + required: string[] } interface IAttributeValue { - attributeName: string; - schemaDataType: string; - displayName: string; - isRequired: boolean; + attributeName: string + schemaDataType: string + displayName: string + isRequired: boolean } export interface ICreateSchema { - schemaVersion?: string; - schemaName: string; - attributes: IAttributeValue[]; - orgId?: string; - orgDid?: string; + schemaVersion?: string + schemaName: string + attributes: IAttributeValue[] + orgId?: string + orgDid?: string } export interface ICreateW3CSchema { - attributes: IW3CAttributeValue[]; - schemaName: string; - description: string; - schemaType: JSONSchemaType; + attributes: IW3CAttributeValue[] + schemaName: string + description: string + schemaType: JSONSchemaType } export interface IGenericSchema { - alias: string; - type: SchemaTypeEnum; - schemaPayload: ICreateSchema | ICreateW3CSchema; + alias: string + type: SchemaTypeEnum + schemaPayload: ICreateSchema | ICreateW3CSchema } export interface IschemaPayload { - schemaDetails: IGenericSchema; - user: IUserRequestInterface; - orgId: string; + schemaDetails: IGenericSchema + user: IUserRequestInterface + orgId: string } export interface ISchemasResult { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - ledgerId: string; - type: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + name: string + version: string + attributes: string + schemaLedgerId: string + publisherDid: string + issuerId: string + orgId: string + ledgerId: string + type: string } export interface ISchemasList { - schemasCount: number; - schemasResult: ISchemasResult[]; + schemasCount: number + schemasResult: ISchemasResult[] } export interface IUpdateSchema { - alias: string; - schemaLedgerId: string; - orgId?: string; + alias: string + schemaLedgerId: string + orgId?: string } export interface UpdateSchemaResponse { - count: number; + count: number } diff --git a/apps/ledger/src/schema/repositories/schema.repository.ts b/apps/ledger/src/schema/repositories/schema.repository.ts index 381eef7bd..e5597f930 100644 --- a/apps/ledger/src/schema/repositories/schema.repository.ts +++ b/apps/ledger/src/schema/repositories/schema.repository.ts @@ -1,29 +1,34 @@ +import type { ICredDefWithCount, IPlatformSchemas } from '@credebl/common/interfaces/schema.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { SchemaType, SortValue } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' /* eslint-disable camelcase */ -import { ConflictException, Injectable, InternalServerErrorException, Logger } from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { ledgers, org_agents, org_agents_type, organisation, Prisma, schema } from '@prisma/client'; -import { ISchema, ISchemaExist, ISchemaSearchCriteria, ISaveSchema } from '../interfaces/schema-payload.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { AgentDetails, ISchemasWithCount, IUpdateSchema, UpdateSchemaResponse } from '../interfaces/schema.interface'; -import { SchemaType, SortValue } from '@credebl/enum/enum'; -import { ICredDefWithCount, IPlatformSchemas } from '@credebl/common/interfaces/schema.interface'; -import { ISchemaId } from '../schema.interface'; +import { ConflictException, Injectable, InternalServerErrorException, Logger } from '@nestjs/common' +import type { Prisma, ledgers, org_agents, org_agents_type, organisation, schema } from '@prisma/client' +import type { ISaveSchema, ISchema, ISchemaExist, ISchemaSearchCriteria } from '../interfaces/schema-payload.interface' +import type { + AgentDetails, + ISchemasWithCount, + IUpdateSchema, + UpdateSchemaResponse, +} from '../interfaces/schema.interface' +import type { ISchemaId } from '../schema.interface' @Injectable() export class SchemaRepository { - private readonly logger = new Logger('SchemaRepository'); + private readonly logger = new Logger('SchemaRepository') constructor(private prisma: PrismaService) {} async saveSchema(schemaResult: ISchema): Promise { try { if (schemaResult.schema.schemaName) { - const schema = await this.schemaExists(schemaResult.schema.schemaName, schemaResult.schema.schemaVersion); - const schemaLength = 0; + const schema = await this.schemaExists(schemaResult.schema.schemaName, schemaResult.schema.schemaVersion) + const schemaLength = 0 if (schema.length !== schemaLength) { throw new ConflictException(ResponseMessages.schema.error.exists, { cause: new Error(), - description: ResponseMessages.errorMessages.conflict - }); + description: ResponseMessages.errorMessages.conflict, + }) } const saveResult = await this.prisma.schema.create({ data: { @@ -39,14 +44,14 @@ export class SchemaRepository { ledgerId: schemaResult.ledgerId, type: schemaResult.type, isSchemaArchived: false, - alias: schemaResult.alias - } - }); - return saveResult; + alias: schemaResult.alias, + }, + }) + return saveResult } } catch (error) { - this.logger.error(`Error in saving schema repository: ${error.message} `); - throw error; + this.logger.error(`Error in saving schema repository: ${error.message} `) + throw error } } @@ -65,13 +70,13 @@ export class SchemaRepository { publisherDid: schemaDetails.publisherDid, orgId: String(schemaDetails.orgId), ledgerId: schemaDetails.ledgerId, - type: schemaDetails.type - } - }); - return saveResult; + type: schemaDetails.type, + }, + }) + return saveResult } catch (error) { - this.logger.error(`Error in saveSchemaRecord: ${error}`); - throw error; + this.logger.error(`Error in saveSchemaRecord: ${error}`) + throw error } } @@ -83,17 +88,17 @@ export class SchemaRepository { isSchemaArchived: false, name: { contains: schemaName, - mode: 'insensitive' + mode: 'insensitive', }, version: { contains: schemaVersion, - mode: 'insensitive' - } - } - }); + mode: 'insensitive', + }, + }, + }) } catch (error) { - this.logger.error(`Error in schemaExists: ${error}`); - throw error; + this.logger.error(`Error in schemaExists: ${error}`) + throw error } } @@ -107,8 +112,8 @@ export class SchemaRepository { { name: { contains: payload.searchByText, mode: 'insensitive' } }, { version: { contains: payload.searchByText, mode: 'insensitive' } }, { schemaLedgerId: { contains: payload.searchByText, mode: 'insensitive' } }, - { issuerId: { contains: payload.searchByText, mode: 'insensitive' } } - ] + { issuerId: { contains: payload.searchByText, mode: 'insensitive' } }, + ], }, select: { createDateTime: true, @@ -128,34 +133,34 @@ export class SchemaRepository { select: { user: { select: { - firstName: true - } - } - } - } - } - } + firstName: true, + }, + }, + }, + }, + }, + }, }, orderBy: { - [payload.sortField]: SortValue.ASC === payload.sortBy ? SortValue.ASC : SortValue.DESC + [payload.sortField]: SortValue.ASC === payload.sortBy ? SortValue.ASC : SortValue.DESC, }, take: Number(payload.pageSize), - skip: (payload.pageNumber - 1) * payload.pageSize - }); + skip: (payload.pageNumber - 1) * payload.pageSize, + }) const schemasCount = await this.prisma.schema.count({ where: { organisation: { - id: orgId - } - } - }); - return { schemasCount, schemasResult }; + id: orgId, + }, + }, + }) + return { schemasCount, schemasResult } } catch (error) { - this.logger.error(`Error in getting schemas: ${error}`); + this.logger.error(`Error in getting schemas: ${error}`) throw new InternalServerErrorException(ResponseMessages.schema.error.failedFetchSchema, { cause: new Error(), - description: error.message - }); + description: error.message, + }) } } @@ -163,13 +168,13 @@ export class SchemaRepository { const schemaDetails = await this.prisma.schema.findMany({ where: { orgId, - name: { contains: schemaName, mode: 'insensitive' } + name: { contains: schemaName, mode: 'insensitive' }, }, - select: { schemaLedgerId: true } - }); + select: { schemaLedgerId: true }, + }) - return schemaDetails; + return schemaDetails } async getSchemasDetailsBySchemaIds(templateIds: string[]): Promise { @@ -177,21 +182,21 @@ export class SchemaRepository { const schemasResult = await this.prisma.schema.findMany({ where: { schemaLedgerId: { - in: templateIds - } + in: templateIds, + }, }, include: { organisation: { select: { - name: true - } - } - } - }); - return schemasResult; + name: true, + }, + }, + }, + }) + return schemasResult } catch (error) { - this.logger.error(`Error in getting agent DID: ${error}`); - throw error; + this.logger.error(`Error in getting agent DID: ${error}`) + throw error } } @@ -199,17 +204,17 @@ export class SchemaRepository { try { const schemasResult = await this.prisma.schema.updateMany({ where: { - issuerId: did + issuerId: did, }, data: { - isSchemaArchived: true - } - }); + isSchemaArchived: true, + }, + }) - return schemasResult; + return schemasResult } catch (error) { - this.logger.error(`Error in archive schemas: ${error}`); - throw error; + this.logger.error(`Error in archive schemas: ${error}`) + throw error } } @@ -217,50 +222,50 @@ export class SchemaRepository { try { const schemasResult = await this.prisma.org_agents.findFirst({ where: { - orgId + orgId, }, select: { orgDid: true, agentEndPoint: true, - tenantId: true - } - }); - return schemasResult; + tenantId: true, + }, + }) + return schemasResult } catch (error) { - this.logger.error(`Error in getting agent DID: ${error}`); - throw error; + this.logger.error(`Error in getting agent DID: ${error}`) + throw error } } async getAgentType(orgId: string): Promise< organisation & { org_agents: (org_agents & { - org_agent_type: org_agents_type; - })[]; + org_agent_type: org_agents_type + })[] } > { try { const agentDetails = await this.prisma.organisation.findUnique({ where: { - id: orgId + id: orgId, }, include: { org_agents: { include: { - org_agent_type: true - } - } - } - }); - return agentDetails; + org_agent_type: true, + }, + }, + }, + }) + return agentDetails } catch (error) { - this.logger.error(`Error in getting agent type: ${error}`); - throw error; + this.logger.error(`Error in getting agent type: ${error}`) + throw error } } async getSchemasCredDeffList(payload: ISchemaSearchCriteria): Promise { - const { orgId, schemaId, searchByText, sortField, sortBy, pageNumber, pageSize } = payload; + const { orgId, schemaId, searchByText, sortField, sortBy, pageNumber, pageSize } = payload try { const credDefResult = await this.prisma.credential_definition.findMany({ @@ -269,38 +274,39 @@ export class SchemaRepository { OR: [ { tag: { contains: searchByText, mode: 'insensitive' } }, { credentialDefinitionId: { contains: searchByText, mode: 'insensitive' } }, - { schemaLedgerId: { contains: searchByText, mode: 'insensitive' } } - ] + { schemaLedgerId: { contains: searchByText, mode: 'insensitive' } }, + ], }, select: { tag: true, credentialDefinitionId: true, schemaLedgerId: true, revocable: true, - createDateTime: true + createDateTime: true, }, orderBy: { - [sortField]: SortValue.ASC === sortBy ? SortValue.ASC : SortValue.DESC + [sortField]: SortValue.ASC === sortBy ? SortValue.ASC : SortValue.DESC, }, take: Number(pageSize), - skip: (pageNumber - 1) * pageSize - }); + skip: (pageNumber - 1) * pageSize, + }) const credDefCount = await this.prisma.credential_definition.count({ where: { - AND: [{ orgId }, { schemaLedgerId: schemaId }] - } - }); - return { credDefResult, credDefCount }; + AND: [{ orgId }, { schemaLedgerId: schemaId }], + }, + }) + return { credDefResult, credDefCount } } catch (error) { - this.logger.error(`Error in getting cred def list by schema id: ${error}`); - throw error; + this.logger.error(`Error in getting cred def list by schema id: ${error}`) + throw error } } async getAllSchemaDetails(payload: ISchemaSearchCriteria): Promise { try { - const { ledgerId, schemaType, searchByText, sortField, sortBy, pageSize, pageNumber } = payload; - let schemaResult; + const { ledgerId, schemaType, searchByText, sortField, sortBy, pageSize, pageNumber } = payload + // biome-ignore lint/suspicious/noImplicitAnyLet: + let schemaResult /** * This is made so because the default pageNumber is set to 1 in DTO, * If there is any 'searchByText' field, we ignore the pageNumbers and search @@ -319,8 +325,8 @@ export class SchemaRepository { { version: { contains: searchByText, mode: 'insensitive' } }, { schemaLedgerId: { contains: searchByText, mode: 'insensitive' } }, { issuerId: { contains: searchByText, mode: 'insensitive' } }, - { alias: { contains: searchByText, mode: 'insensitive' } } - ] + { alias: { contains: searchByText, mode: 'insensitive' } }, + ], }, select: { createDateTime: true, @@ -334,13 +340,13 @@ export class SchemaRepository { orgId: true, // This field can be null issuerId: true, type: true, - alias: true + alias: true, }, orderBy: { - [sortField]: SortValue.DESC === sortBy ? SortValue.DESC : SortValue.ASC + [sortField]: SortValue.DESC === sortBy ? SortValue.DESC : SortValue.ASC, }, - take: Number(pageSize) - }); + take: Number(pageSize), + }) } else { /** * Queries apart from the one containing searchText would go here @@ -349,7 +355,7 @@ export class SchemaRepository { where: { ledgerId, isSchemaArchived: false, - type: schemaType + type: schemaType, }, select: { createDateTime: true, @@ -363,33 +369,33 @@ export class SchemaRepository { orgId: true, // This field can be null issuerId: true, type: true, - alias: true + alias: true, }, orderBy: { - [sortField]: SortValue.DESC === sortBy ? SortValue.DESC : SortValue.ASC + [sortField]: SortValue.DESC === sortBy ? SortValue.DESC : SortValue.ASC, }, take: Number(pageSize), - skip: (pageNumber - 1) * pageSize - }); + skip: (pageNumber - 1) * pageSize, + }) } const schemasCount = await this.prisma.schema.count({ where: { ledgerId, - type: schemaType - } - }); + type: schemaType, + }, + }) // Handle null orgId in the response const schemasWithDefaultOrgId = schemaResult.map((schema) => ({ ...schema, - orgId: schema.orgId || null // Replace null orgId with 'N/A' or any default value - })); + orgId: schema.orgId || null, // Replace null orgId with 'N/A' or any default value + })) - return { schemasCount, schemasResult: schemasWithDefaultOrgId }; + return { schemasCount, schemasResult: schemasWithDefaultOrgId } } catch (error) { - this.logger.error(`Error in getting schemas: ${error}`); - throw error; + this.logger.error(`Error in getting schemas: ${error}`) + throw error } } @@ -397,12 +403,12 @@ export class SchemaRepository { try { return this.prisma.schema.findFirst({ where: { - schemaLedgerId: schemaId - } - }); + schemaLedgerId: schemaId, + }, + }) } catch (error) { - this.logger.error(`Error in getting get schema by schema ledger id: ${error}`); - throw error; + this.logger.error(`Error in getting get schema by schema ledger id: ${error}`) + throw error } } @@ -410,14 +416,14 @@ export class SchemaRepository { try { const { agent } = await this.prisma.org_agents_type.findFirst({ where: { - id: orgAgentId - } - }); + id: orgAgentId, + }, + }) - return agent; + return agent } catch (error) { - this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`) + throw error } } @@ -425,56 +431,56 @@ export class SchemaRepository { try { return this.prisma.ledgers.findFirst({ where: { - indyNamespace: LedgerName - } - }); + indyNamespace: LedgerName, + }, + }) } catch (error) { - this.logger.error(`Error in getting get schema by schema ledger id: ${error}`); - throw error; + this.logger.error(`Error in getting get schema by schema ledger id: ${error}`) + throw error } } async schemaExist(payload: ISchemaExist): Promise< { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - ledgerId: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + name: string + version: string + attributes: string + schemaLedgerId: string + publisherDid: string + issuerId: string + orgId: string + ledgerId: string }[] > { try { return this.prisma.schema.findMany({ where: { name: payload.schemaName, - version: payload.version - } - }); + version: payload.version, + }, + }) } catch (error) { - this.logger.error(`Error in getting get schema by name and version: ${error}`); - throw error; + this.logger.error(`Error in getting get schema by name and version: ${error}`) + throw error } } async updateSchema(schemaDetails: IUpdateSchema): Promise { - const { alias, schemaLedgerId, orgId } = schemaDetails; + const { alias, schemaLedgerId, orgId } = schemaDetails try { - return await this.prisma.schema.updateMany({ - where: orgId ? { schemaLedgerId, orgId } : { schemaLedgerId }, - data: { alias } - }); + return await this.prisma.schema.updateMany({ + where: orgId ? { schemaLedgerId, orgId } : { schemaLedgerId }, + data: { alias }, + }) } catch (error) { - this.logger.error(`Error in updating schema details: ${error}`); - throw error; + this.logger.error(`Error in updating schema details: ${error}`) + throw error } } -} \ No newline at end of file +} diff --git a/apps/ledger/src/schema/schema.controller.ts b/apps/ledger/src/schema/schema.controller.ts index 45d36462c..e159f6729 100644 --- a/apps/ledger/src/schema/schema.controller.ts +++ b/apps/ledger/src/schema/schema.controller.ts @@ -1,24 +1,23 @@ -import { Controller } from '@nestjs/common'; -import { SchemaService } from './schema.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { +import type { + ICredDefWithPagination, + ISchemaData, + ISchemaDetails, + ISchemasWithPagination, +} from '@credebl/common/interfaces/schema.interface' +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { Prisma, schema } from '@prisma/client' +import type { UpdateSchemaDto } from 'apps/api-gateway/src/schema/dtos/update-schema-dto' +import type { ISchema, ISchemaCredDeffSearchInterface, ISchemaExist, ISchemaSearchPayload, - SaveSchemaPayload -} from './interfaces/schema-payload.interface'; -import { Prisma, schema } from '@prisma/client'; -import { - ICredDefWithPagination, - ISchemaData, - ISchemaDetails, - ISchemasWithPagination -} from '@credebl/common/interfaces/schema.interface'; -import { IschemaPayload } from './interfaces/schema.interface'; -import { ISchemaId } from './schema.interface'; -import { UpdateSchemaDto } from 'apps/api-gateway/src/schema/dtos/update-schema-dto'; - + SaveSchemaPayload, +} from './interfaces/schema-payload.interface' +import type { IschemaPayload } from './interfaces/schema.interface' +import type { ISchemaId } from './schema.interface' +import type { SchemaService } from './schema.service' @Controller('schema') export class SchemaController { @@ -26,81 +25,83 @@ export class SchemaController { @MessagePattern({ cmd: 'create-schema' }) async createSchema(payload: IschemaPayload): Promise { - const { schemaDetails, user, orgId } = payload; - return this.schemaService.createSchema(schemaDetails, user, orgId); + const { schemaDetails, user, orgId } = payload + return this.schemaService.createSchema(schemaDetails, user, orgId) } @MessagePattern({ cmd: 'get-schemas-details' }) - async getSchemasDetails(payload: {templateIds: string[]}): Promise { - const { templateIds } = payload; - return this.schemaService.getSchemaDetails(templateIds); + async getSchemasDetails(payload: { templateIds: string[] }): Promise { + const { templateIds } = payload + return this.schemaService.getSchemaDetails(templateIds) } @MessagePattern({ cmd: 'get-schemas-details-by-name' }) - async getSchemasDetailsBySchemaName(payload:{schemaName:string, orgId:string}): Promise { - const {orgId, schemaName} = payload; - return this.schemaService.getSchemaDetailsBySchemaName(schemaName, orgId); + async getSchemasDetailsBySchemaName(payload: { schemaName: string; orgId: string }): Promise { + const { orgId, schemaName } = payload + return this.schemaService.getSchemaDetailsBySchemaName(schemaName, orgId) } @MessagePattern({ cmd: 'get-schema-by-id' }) async getSchemaById(payload: ISchema): Promise { - const { schemaId, orgId } = payload; - return this.schemaService.getSchemaById(schemaId, orgId); + const { schemaId, orgId } = payload + return this.schemaService.getSchemaById(schemaId, orgId) } @MessagePattern({ cmd: 'get-schemas' }) async getSchemas(schemaSearch: ISchemaSearchPayload): Promise { - const { schemaSearchCriteria, orgId } = schemaSearch; - return this.schemaService.getSchemas(schemaSearchCriteria, orgId); + const { schemaSearchCriteria, orgId } = schemaSearch + return this.schemaService.getSchemas(schemaSearchCriteria, orgId) } @MessagePattern({ cmd: 'get-cred-def-list-by-schemas-id' }) async getcredDefListBySchemaId(payload: ISchemaCredDeffSearchInterface): Promise { - return this.schemaService.getcredDefListBySchemaId(payload); + return this.schemaService.getcredDefListBySchemaId(payload) } @MessagePattern({ cmd: 'get-all-schemas' }) async getAllSchema(schemaSearch: ISchemaSearchPayload): Promise { - const { schemaSearchCriteria } = schemaSearch; - return this.schemaService.getAllSchema(schemaSearchCriteria); + const { schemaSearchCriteria } = schemaSearch + return this.schemaService.getAllSchema(schemaSearchCriteria) } @MessagePattern({ cmd: 'schema-exist' }) - async schemaExist(payload: ISchemaExist): Promise<{ - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - ledgerId: string; - }[]> { - return this.schemaService.schemaExist(payload); + async schemaExist(payload: ISchemaExist): Promise< + { + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + name: string + version: string + attributes: string + schemaLedgerId: string + publisherDid: string + issuerId: string + orgId: string + ledgerId: string + }[] + > { + return this.schemaService.schemaExist(payload) } @MessagePattern({ cmd: 'archive-schemas' }) - async archiveSchemas(payload: {did: string}): Promise { - return this.schemaService.archiveSchemas(payload.did); + async archiveSchemas(payload: { did: string }): Promise { + return this.schemaService.archiveSchemas(payload.did) } @MessagePattern({ cmd: 'store-schema-record' }) async saveSchemaRecord(payload: SaveSchemaPayload): Promise { - return this.schemaService.storeSchemaDetails(payload.schemaDetails); + return this.schemaService.storeSchemaDetails(payload.schemaDetails) } @MessagePattern({ cmd: 'get-schema-record-by-schema-id' }) - async getSchemaRecordBySchemaId(payload: {schemaId: string}): Promise { - return this.schemaService.getSchemaBySchemaId(payload.schemaId); + async getSchemaRecordBySchemaId(payload: { schemaId: string }): Promise { + return this.schemaService.getSchemaBySchemaId(payload.schemaId) } -@MessagePattern({ cmd: 'update-schema' }) - updateSchema(payload:{schemaDetails:UpdateSchemaDto}): Promise { - return this.schemaService.updateSchema(payload.schemaDetails); + @MessagePattern({ cmd: 'update-schema' }) + updateSchema(payload: { schemaDetails: UpdateSchemaDto }): Promise { + return this.schemaService.updateSchema(payload.schemaDetails) } -} \ No newline at end of file +} diff --git a/apps/ledger/src/schema/schema.interface.ts b/apps/ledger/src/schema/schema.interface.ts index 92d0e55d6..a09cf0748 100644 --- a/apps/ledger/src/schema/schema.interface.ts +++ b/apps/ledger/src/schema/schema.interface.ts @@ -1,59 +1,59 @@ -import { IUserRequestInterface } from './interfaces/schema.interface'; +import type { IUserRequestInterface } from './interfaces/schema.interface' export interface ISchemaId { - schemaLedgerId: string; + schemaLedgerId: string } export interface SchemaSearchCriteria { - schemaLedgerId: string; - credentialDefinitionId: string; - user : IUserRequestInterface + schemaLedgerId: string + credentialDefinitionId: string + user: IUserRequestInterface } export interface IAttributeValue { - attributeName: string; - schemaDataType: string; - displayName: string + attributeName: string + schemaDataType: string + displayName: string } export interface CreateSchemaAgentRedirection { - tenantId?: string; - attributes?: string[]; - version?: string; - name?: string; - issuerId?: string; - payload?: ITenantSchemaDto; - method?: string; - agentType?: string; - apiKey?: string; - agentEndPoint?: string; - orgId?: string; + tenantId?: string + attributes?: string[] + version?: string + name?: string + issuerId?: string + payload?: ITenantSchemaDto + method?: string + agentType?: string + apiKey?: string + agentEndPoint?: string + orgId?: string } export interface ITenantSchemaDto { - attributes: string[]; - version: string; - name: string; - issuerId: string; + attributes: string[] + version: string + name: string + issuerId: string } export interface GetSchemaAgentRedirection { - schemaId?: string; - tenantId?: string; - payload?: GetSchemaFromTenantPayload; - apiKey?: string; - agentEndPoint?: string; - agentType?: string; - method?: string; - orgId?: string; + schemaId?: string + tenantId?: string + payload?: GetSchemaFromTenantPayload + apiKey?: string + agentEndPoint?: string + agentType?: string + method?: string + orgId?: string } export interface GetSchemaFromTenantPayload { - schemaId: string; + schemaId: string } export interface ISchemaInfo { - schemaUrl: string; - did: string; - schemaId: string; - schemaTxnHash: string; - } + schemaUrl: string + did: string + schemaId: string + schemaTxnHash: string +} diff --git a/apps/ledger/src/schema/schema.module.ts b/apps/ledger/src/schema/schema.module.ts index a8c8609d3..2a6c1dc16 100644 --- a/apps/ledger/src/schema/schema.module.ts +++ b/apps/ledger/src/schema/schema.module.ts @@ -1,37 +1,31 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Logger, Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' -import { CommonModule } from '@credebl/common'; -import { SchemaController } from './schema.controller'; -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'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { PrismaService } from '@credebl/prisma-service' +import { HttpModule } from '@nestjs/axios' +import { CacheModule } from '@nestjs/cache-manager' +import { SchemaRepository } from './repositories/schema.repository' +import { SchemaController } from './schema.controller' +import { SchemaService } from './schema.service' @Module({ imports: [ ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.SCHEMA_SERVICE, process.env.SCHEMA_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.SCHEMA_SERVICE, process.env.SCHEMA_NKEY_SEED), + }, ]), HttpModule, CommonModule, - CacheModule.register() + CacheModule.register(), ], - providers: [ - SchemaService, - SchemaRepository, - Logger, - PrismaService, - NATSClient - ], - controllers: [SchemaController] + providers: [SchemaService, SchemaRepository, Logger, PrismaService, NATSClient], + controllers: [SchemaController], }) -export class SchemaModule { } +export class SchemaModule {} diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index 198678295..c505366d9 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -1,61 +1,62 @@ +import type { CommonService } from '@credebl/common' +import type { NATSClient } from '@credebl/common/NATSClient' +import { checkDidLedgerAndNetwork } from '@credebl/common/cast.helper' +import { CommonConstants } from '@credebl/common/common.constant' +import { networkNamespace } from '@credebl/common/common.utils' +import { IW3CAttributeValue } from '@credebl/common/interfaces/interface' +import type { + ICredDefWithPagination, + ISchemaData, + ISchemaDetails, + ISchemasWithPagination, +} from '@credebl/common/interfaces/schema.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { + JSONSchemaType, + LedgerLessConstant, + LedgerLessMethods, + OrgAgentType, + SchemaType, + SchemaTypeEnum, +} from '@credebl/enum/enum' +import { CACHE_MANAGER } from '@nestjs/cache-manager' /* eslint-disable camelcase */ import { BadRequestException, + ConflictException, HttpException, Inject, - ConflictException, Injectable, NotAcceptableException, - NotFoundException -} from '@nestjs/common'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; -import { SchemaRepository } from './repositories/schema.repository'; -import { Prisma, schema } from '@prisma/client'; -import { + NotFoundException, +} from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +import type { Prisma, schema } from '@prisma/client' +import { w3cSchemaBuilder } from 'apps/ledger/libs/helpers/w3c.schema.builder' +import type { Cache } from 'cache-manager' +import { BaseService } from 'libs/service/base.service' +import { from } from 'rxjs' +import { map } from 'rxjs/operators' +import { v4 as uuidv4 } from 'uuid' +import { W3CSchemaVersion } from './enum/schema.enum' +import type { ISaveSchema, ISchema, ISchemaCredDeffSearchInterface, ISchemaExist, ISchemaSearchCriteria, - W3CCreateSchema -} from './interfaces/schema-payload.interface'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { + W3CCreateSchema, +} from './interfaces/schema-payload.interface' +import type { ICreateSchema, ICreateW3CSchema, IGenericSchema, IUpdateSchema, IUserRequestInterface, - UpdateSchemaResponse -} from './interfaces/schema.interface'; -import { CreateSchemaAgentRedirection, GetSchemaAgentRedirection, ISchemaId } from './schema.interface'; -import { map } from 'rxjs/operators'; -import { - JSONSchemaType, - LedgerLessConstant, - LedgerLessMethods, - OrgAgentType, - SchemaType, - SchemaTypeEnum -} from '@credebl/enum/enum'; -import { - ICredDefWithPagination, - ISchemaData, - ISchemaDetails, - ISchemasWithPagination -} from '@credebl/common/interfaces/schema.interface'; -import { Cache } from 'cache-manager'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { CommonService } from '@credebl/common'; -import { W3CSchemaVersion } from './enum/schema.enum'; -import { v4 as uuidv4 } from 'uuid'; -import { networkNamespace } from '@credebl/common/common.utils'; -import { checkDidLedgerAndNetwork } from '@credebl/common/cast.helper'; -import { NATSClient } from '@credebl/common/NATSClient'; -import { from } from 'rxjs'; -import { w3cSchemaBuilder } from 'apps/ledger/libs/helpers/w3c.schema.builder'; + UpdateSchemaResponse, +} from './interfaces/schema.interface' +import type { SchemaRepository } from './repositories/schema.repository' +import type { CreateSchemaAgentRedirection, GetSchemaAgentRedirection, ISchemaId } from './schema.interface' @Injectable() export class SchemaService extends BaseService { @@ -66,105 +67,107 @@ export class SchemaService extends BaseService { @Inject(CACHE_MANAGER) private readonly cacheService: Cache, private readonly natsClient: NATSClient ) { - super('SchemaService'); + super('SchemaService') } async createSchema(schemaDetails: IGenericSchema, user: IUserRequestInterface, orgId: string): Promise { - const userId = user.id; + const userId = user.id try { - const { schemaPayload, type, alias } = schemaDetails; + const { schemaPayload, type, alias } = schemaDetails if (type === SchemaTypeEnum.INDY) { - const schema = schemaPayload as ICreateSchema; - const schemaExists = await this.schemaRepository.schemaExists(schema.schemaName, schema.schemaVersion); + const schema = schemaPayload as ICreateSchema + const schemaExists = await this.schemaRepository.schemaExists(schema.schemaName, schema.schemaVersion) - if (0 !== schemaExists.length) { - this.logger.error(ResponseMessages.schema.error.exists); + if (schemaExists.length !== 0) { + this.logger.error(ResponseMessages.schema.error.exists) throw new ConflictException(ResponseMessages.schema.error.exists, { cause: new Error(), - description: ResponseMessages.errorMessages.conflict - }); + description: ResponseMessages.errorMessages.conflict, + }) } - if (null !== schema || schema !== undefined) { - const schemaVersionIndexOf = -1; + if (schema !== null || schema !== undefined) { + const schemaVersionIndexOf = -1 if ( - isNaN(parseFloat(schema.schemaVersion)) || + Number.isNaN(Number.parseFloat(schema.schemaVersion)) || schema.schemaVersion.toString().indexOf('.') === schemaVersionIndexOf ) { throw new NotAcceptableException(ResponseMessages.schema.error.invalidVersion, { cause: new Error(), - description: ResponseMessages.errorMessages.notAcceptable - }); + description: ResponseMessages.errorMessages.notAcceptable, + }) } - const schemaAttributeLength = 0; + const schemaAttributeLength = 0 if (schema.attributes.length === schemaAttributeLength) { throw new NotAcceptableException(ResponseMessages.schema.error.insufficientAttributes, { cause: new Error(), - description: ResponseMessages.errorMessages.notAcceptable - }); - } else if (schema.attributes.length > schemaAttributeLength) { + description: ResponseMessages.errorMessages.notAcceptable, + }) + } + if (schema.attributes.length > schemaAttributeLength) { const trimmedAttributes = schema.attributes.map((attribute) => ({ attributeName: attribute.attributeName.trim(), schemaDataType: attribute.schemaDataType, displayName: attribute.displayName.trim(), - isRequired: attribute.isRequired - })); + isRequired: attribute.isRequired, + })) - const attributeNamesLowerCase = trimmedAttributes.map((attribute) => attribute.attributeName.toLowerCase()); + const attributeNamesLowerCase = trimmedAttributes.map((attribute) => attribute.attributeName.toLowerCase()) const duplicateAttributeNames = attributeNamesLowerCase.filter( (value, index, element) => element.indexOf(value) !== index - ); + ) - if (0 < duplicateAttributeNames.length) { + if (duplicateAttributeNames.length > 0) { throw new ConflictException(ResponseMessages.schema.error.uniqueAttributesnames, { cause: new Error(), - description: ResponseMessages.errorMessages.conflict - }); + description: ResponseMessages.errorMessages.conflict, + }) } const attributeDisplayNamesLowerCase = trimmedAttributes.map((attribute) => attribute.displayName.toLocaleLowerCase() - ); + ) const duplicateAttributeDisplayNames = attributeDisplayNamesLowerCase.filter( (value, index, element) => element.indexOf(value) !== index - ); + ) - if (0 < duplicateAttributeDisplayNames.length) { + if (duplicateAttributeDisplayNames.length > 0) { throw new ConflictException(ResponseMessages.schema.error.uniqueAttributesDisplaynames, { cause: new Error(), - description: ResponseMessages.errorMessages.conflict - }); + description: ResponseMessages.errorMessages.conflict, + }) } - schema.schemaName = schema.schemaName.trim(); - const agentDetails = await this.schemaRepository.getAgentDetailsByOrgId(orgId); + schema.schemaName = schema.schemaName.trim() + const agentDetails = await this.schemaRepository.getAgentDetailsByOrgId(orgId) if (!agentDetails) { throw new NotFoundException(ResponseMessages.schema.error.agentDetailsNotFound, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - const { agentEndPoint, orgDid } = agentDetails; - const getAgentDetails = await this.schemaRepository.getAgentType(orgId); + 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; + const did = schema.orgDid?.split(':').length >= 4 ? schema.orgDid : orgDid const orgAgentType = await this.schemaRepository.getOrgAgentType( getAgentDetails.org_agents[0].orgAgentTypeId - ); + ) - const attributeArray = trimmedAttributes.map((item) => item.attributeName); + const attributeArray = trimmedAttributes.map((item) => item.attributeName) - const isRequiredAttributeExists = trimmedAttributes.some((attribute) => attribute.isRequired); + const isRequiredAttributeExists = trimmedAttributes.some((attribute) => attribute.isRequired) if (!isRequiredAttributeExists) { - throw new BadRequestException(ResponseMessages.schema.error.atLeastOneRequired); + throw new BadRequestException(ResponseMessages.schema.error.atLeastOneRequired) } - let schemaResponseFromAgentService; + // biome-ignore lint/suspicious/noExplicitAny: + let schemaResponseFromAgentService: { response: any } if (OrgAgentType.DEDICATED === orgAgentType) { - const issuerId = did; + const issuerId = did const schemaPayload = { attributes: attributeArray, @@ -173,11 +176,11 @@ export class SchemaService extends BaseService { issuerId, agentEndPoint, orgId, - agentType: OrgAgentType.DEDICATED - }; - schemaResponseFromAgentService = await this._createSchema(schemaPayload); + agentType: OrgAgentType.DEDICATED, + } + schemaResponseFromAgentService = await this._createSchema(schemaPayload) } else if (OrgAgentType.SHARED === orgAgentType) { - const { tenantId } = await this.schemaRepository.getAgentDetailsByOrgId(orgId); + const { tenantId } = await this.schemaRepository.getAgentDetailsByOrgId(orgId) const schemaPayload = { tenantId, @@ -186,88 +189,87 @@ export class SchemaService extends BaseService { attributes: attributeArray, version: schema.schemaVersion, name: schema.schemaName, - issuerId: did + issuerId: did, }, agentEndPoint, orgId, - agentType: OrgAgentType.SHARED - }; - schemaResponseFromAgentService = await this._createSchema(schemaPayload); + agentType: OrgAgentType.SHARED, + } + schemaResponseFromAgentService = await this._createSchema(schemaPayload) } - const responseObj = JSON.parse(JSON.stringify(schemaResponseFromAgentService.response)); + const responseObj = JSON.parse(JSON.stringify(schemaResponseFromAgentService.response)) - const indyNamespace = `${did.split(':')[2]}:${did.split(':')[3]}`; - const getLedgerId = await this.schemaRepository.getLedgerByNamespace(indyNamespace); + const indyNamespace = `${did.split(':')[2]}:${did.split(':')[3]}` + const getLedgerId = await this.schemaRepository.getLedgerByNamespace(indyNamespace) const schemaDetails: ISchema = { schema: { schemaName: '', attributes: [], schemaVersion: '', id: '' }, - createdBy: `0`, + createdBy: '0', issuerId: '', onLedgerStatus: 'Submitted on ledger', orgId, ledgerId: getLedgerId.id, - type: SchemaType.INDY - }; - - if ('finished' === responseObj.schema.state) { - schemaDetails.schema.schemaName = responseObj.schema.schema.name; - schemaDetails.schema.attributes = trimmedAttributes; - schemaDetails.schema.schemaVersion = responseObj.schema.schema.version; - schemaDetails.createdBy = userId; - schemaDetails.schema.id = responseObj.schema.schemaId; - schemaDetails.changedBy = userId; - schemaDetails.orgId = orgId; - schemaDetails.issuerId = responseObj.schema.schema.issuerId; - const saveResponse = this.schemaRepository.saveSchema(schemaDetails); - - const attributesArray = JSON.parse((await saveResponse).attributes); - (await saveResponse).attributes = attributesArray; - delete (await saveResponse).lastChangedBy; - delete (await saveResponse).lastChangedDateTime; - return saveResponse; - } else if ('finished' === responseObj.state) { - schemaDetails.schema.schemaName = responseObj.schema.name; - schemaDetails.schema.attributes = trimmedAttributes; - schemaDetails.schema.schemaVersion = responseObj.schema.version; - schemaDetails.createdBy = userId; - schemaDetails.schema.id = responseObj.schemaId; - schemaDetails.changedBy = userId; - schemaDetails.orgId = orgId; - schemaDetails.issuerId = responseObj.schema.issuerId; - const saveResponse = this.schemaRepository.saveSchema(schemaDetails); - - const attributesArray = JSON.parse((await saveResponse).attributes); - (await saveResponse).attributes = attributesArray; - delete (await saveResponse).lastChangedBy; - delete (await saveResponse).lastChangedDateTime; - return saveResponse; - } else { - throw new NotFoundException(ResponseMessages.schema.error.notCreated, { - cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + type: SchemaType.INDY, } - } else { - throw new BadRequestException(ResponseMessages.schema.error.emptyData, { + + if (responseObj.schema.state === 'finished') { + schemaDetails.schema.schemaName = responseObj.schema.schema.name + schemaDetails.schema.attributes = trimmedAttributes + schemaDetails.schema.schemaVersion = responseObj.schema.schema.version + schemaDetails.createdBy = userId + schemaDetails.schema.id = responseObj.schema.schemaId + schemaDetails.changedBy = userId + schemaDetails.orgId = orgId + schemaDetails.issuerId = responseObj.schema.schema.issuerId + const saveResponse = await this.schemaRepository.saveSchema(schemaDetails) + + const attributesArray = JSON.parse(saveResponse.attributes) + saveResponse.attributes = attributesArray + saveResponse.lastChangedBy = undefined + saveResponse.lastChangedDateTime = undefined + return saveResponse + } + if (responseObj.state === 'finished') { + schemaDetails.schema.schemaName = responseObj.schema.name + schemaDetails.schema.attributes = trimmedAttributes + schemaDetails.schema.schemaVersion = responseObj.schema.version + schemaDetails.createdBy = userId + schemaDetails.schema.id = responseObj.schemaId + schemaDetails.changedBy = userId + schemaDetails.orgId = orgId + schemaDetails.issuerId = responseObj.schema.issuerId + const saveResponse = await this.schemaRepository.saveSchema(schemaDetails) + + const attributesArray = JSON.parse(saveResponse.attributes) + saveResponse.attributes = attributesArray + saveResponse.lastChangedBy = undefined + saveResponse.lastChangedDateTime = undefined + return saveResponse + } + throw new NotFoundException(ResponseMessages.schema.error.notCreated, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.notFound, + }) } - } else { throw new BadRequestException(ResponseMessages.schema.error.emptyData, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } - } else if (type === SchemaTypeEnum.JSON) { - const josnSchemaDetails = schemaPayload as unknown as ICreateW3CSchema; - const createW3CSchema = await this.createW3CSchema(orgId, josnSchemaDetails, user.id, alias); - return createW3CSchema; + throw new BadRequestException(ResponseMessages.schema.error.emptyData, { + cause: new Error(), + description: ResponseMessages.errorMessages.badRequest, + }) + } + if (type === SchemaTypeEnum.JSON) { + const josnSchemaDetails = schemaPayload as unknown as ICreateW3CSchema + const createW3CSchema = await this.createW3CSchema(orgId, josnSchemaDetails, user.id, alias) + return createW3CSchema } } catch (error) { - this.logger.error(`[createSchema] - outer Error: ${JSON.stringify(error)}`); + this.logger.error(`[createSchema] - outer Error: ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } @@ -278,116 +280,137 @@ export class SchemaService extends BaseService { alias: string ): Promise { try { - let createSchema; + // biome-ignore lint/suspicious/noExplicitAny: + let createSchema: any - const { description, attributes, schemaName } = schemaPayload; - const agentDetails = await this.schemaRepository.getAgentDetailsByOrgId(orgId); + const { description, attributes, schemaName } = schemaPayload + const agentDetails = await this.schemaRepository.getAgentDetailsByOrgId(orgId) if (!agentDetails) { throw new NotFoundException(ResponseMessages.schema.error.agentDetailsNotFound, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - const { agentEndPoint } = agentDetails; + const { agentEndPoint } = agentDetails - const ledgerAndNetworkDetails = await checkDidLedgerAndNetwork(schemaPayload.schemaType, agentDetails.orgDid); + const ledgerAndNetworkDetails = await checkDidLedgerAndNetwork(schemaPayload.schemaType, agentDetails.orgDid) if (!ledgerAndNetworkDetails) { throw new BadRequestException(ResponseMessages.schema.error.orgDidAndSchemaType, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } - const getAgentDetails = await this.schemaRepository.getAgentType(orgId); - const orgAgentType = await this.schemaRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId); - let url; + const getAgentDetails = await this.schemaRepository.getAgentType(orgId) + const orgAgentType = await this.schemaRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId) + let url: string if (OrgAgentType.DEDICATED === orgAgentType) { - url = `${agentEndPoint}${CommonConstants.DEDICATED_CREATE_POLYGON_W3C_SCHEMA}`; + url = `${agentEndPoint}${CommonConstants.DEDICATED_CREATE_POLYGON_W3C_SCHEMA}` } else if (OrgAgentType.SHARED === orgAgentType) { - const { tenantId } = await this.schemaRepository.getAgentDetailsByOrgId(orgId); - url = `${agentEndPoint}${CommonConstants.SHARED_CREATE_POLYGON_W3C_SCHEMA}${tenantId}`; + const { tenantId } = await this.schemaRepository.getAgentDetailsByOrgId(orgId) + url = `${agentEndPoint}${CommonConstants.SHARED_CREATE_POLYGON_W3C_SCHEMA}${tenantId}` } - const schemaObject = await w3cSchemaBuilder(attributes, schemaName, description); + const schemaObject = await w3cSchemaBuilder(attributes, schemaName, description) if (!schemaObject) { throw new BadRequestException(ResponseMessages.schema.error.schemaBuilder, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } const agentSchemaPayload = { schema: schemaObject, did: agentDetails.orgDid, - schemaName - }; + schemaName, + } const W3cSchemaPayload = { url, orgId, - schemaRequestPayload: agentSchemaPayload - }; + schemaRequestPayload: agentSchemaPayload, + } if (schemaPayload.schemaType === JSONSchemaType.POLYGON_W3C) { - const createSchemaPayload = await this._createW3CSchema(W3cSchemaPayload); - createSchema = createSchemaPayload.response; - createSchema.type = JSONSchemaType.POLYGON_W3C; + const createSchemaPayload = await this._createW3CSchema(W3cSchemaPayload) + createSchema = createSchemaPayload.response + createSchema.type = JSONSchemaType.POLYGON_W3C } else { - const createSchemaPayload = await this._createW3CledgerAgnostic(schemaObject); + const createSchemaPayload = await this._createW3CledgerAgnostic(schemaObject) if (!createSchemaPayload) { throw new BadRequestException(ResponseMessages.schema.error.schemaUploading, { cause: new Error(), - description: ResponseMessages.errorMessages.badRequest - }); + description: ResponseMessages.errorMessages.badRequest, + }) } - createSchema = createSchemaPayload.data; - createSchema.did = agentDetails.orgDid; - createSchema.type = JSONSchemaType.LEDGER_LESS; - createSchema.schemaUrl = `${process.env.SCHEMA_FILE_SERVER_URL}${createSchemaPayload.data.schemaId}`; + createSchema = createSchemaPayload.data + createSchema.did = agentDetails.orgDid + createSchema.type = JSONSchemaType.LEDGER_LESS + createSchema.schemaUrl = `${process.env.SCHEMA_FILE_SERVER_URL}${createSchemaPayload.data.schemaId}` } - const storeW3CSchema = await this.storeW3CSchemas(createSchema, user, orgId, attributes, alias); + const storeW3CSchema = await this.storeW3CSchemas(createSchema, user, orgId, attributes, alias) if (!storeW3CSchema) { throw new BadRequestException(ResponseMessages.schema.error.storeW3CSchema, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - return storeW3CSchema; + return storeW3CSchema } catch (error) { - this.logger.error(`[createSchema] - outer Error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[createSchema] - outer Error: ${JSON.stringify(error)}`) + throw error } } - private async storeW3CSchemas(schemaDetails, user, orgId, attributes, alias): Promise { - let ledgerDetails; - const schemaServerUrl = `${process.env.SCHEMA_FILE_SERVER_URL}${schemaDetails.schemaId}`; - const schemaRequest = await this.commonService.httpGet(schemaServerUrl).then(async (response) => response); + private async storeW3CSchemas( + // biome-ignore lint/suspicious/noExplicitAny: + schemaDetails: { schemaId: any; did: string; schemaUrl: any }, + user: string, + orgId: string, + attributes: IW3CAttributeValue[], + alias: string + ): Promise { + let ledgerDetails: { + // biome-ignore lint/suspicious/noExplicitAny: + id: any + createDateTime?: Date + lastChangedDateTime?: Date + name?: string + networkType?: string + poolConfig?: string + isActive?: boolean + networkString?: string + nymTxnEndpoint?: string + indyNamespace?: string + networkUrl?: string + } + const schemaServerUrl = `${process.env.SCHEMA_FILE_SERVER_URL}${schemaDetails.schemaId}` + const schemaRequest = await this.commonService.httpGet(schemaServerUrl).then(async (response) => response) if (!schemaRequest) { throw new NotFoundException(ResponseMessages.schema.error.W3CSchemaNotFOund, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - const indyNamespace = await networkNamespace(schemaDetails?.did); + const indyNamespace = await networkNamespace(schemaDetails?.did) if (indyNamespace === LedgerLessMethods.WEB || indyNamespace === LedgerLessMethods.KEY) { - ledgerDetails = await this.schemaRepository.getLedgerByNamespace(LedgerLessConstant.NO_LEDGER); + ledgerDetails = await this.schemaRepository.getLedgerByNamespace(LedgerLessConstant.NO_LEDGER) } else { - ledgerDetails = await this.schemaRepository.getLedgerByNamespace(indyNamespace); + ledgerDetails = await this.schemaRepository.getLedgerByNamespace(indyNamespace) } if (!ledgerDetails) { throw new NotFoundException(ResponseMessages.schema.error.networkNotFound, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } const storeSchemaDetails = { schema: { schemaName: schemaRequest.title, schemaVersion: W3CSchemaVersion.W3C_SCHEMA_VERSION, attributes, - id: schemaDetails.schemaUrl + id: schemaDetails.schemaUrl, }, issuerId: schemaDetails.did, createdBy: user, @@ -396,74 +419,74 @@ export class SchemaService extends BaseService { orgId, ledgerId: ledgerDetails.id, type: SchemaType.W3C_Schema, - alias - }; - const saveResponse = await this.schemaRepository.saveSchema(storeSchemaDetails); - return saveResponse; + alias, + } + const saveResponse = await this.schemaRepository.saveSchema(storeSchemaDetails) + return saveResponse } async _createSchema(payload: CreateSchemaAgentRedirection): Promise<{ - response: string; + response: string }> { const pattern = { - cmd: 'agent-create-schema' - }; + cmd: 'agent-create-schema', + } const schemaResponse = await from(this.natsClient.send(this.schemaServiceProxy, pattern, payload)) .pipe( map((response) => ({ - response + response, })) ) .toPromise() .catch((error) => { - this.logger.error(`Error in creating schema : ${JSON.stringify(error)}`); + this.logger.error(`Error in creating schema : ${JSON.stringify(error)}`) throw new HttpException( { status: error.statusCode, error: error.error, - message: error.message + message: error.message, }, error.error - ); - }); - return schemaResponse; + ) + }) + return schemaResponse } async _createW3CSchema(payload: W3CCreateSchema): Promise<{ - response: string; + response: string }> { const natsPattern = { - cmd: 'agent-create-w3c-schema' - }; + cmd: 'agent-create-w3c-schema', + } const W3CSchemaResponse = await from(this.natsClient.send(this.schemaServiceProxy, natsPattern, payload)) .pipe( map((response) => ({ - response + response, })) ) .toPromise() .catch((error) => { - this.logger.error(`Error in creating W3C schema : ${JSON.stringify(error)}`); + this.logger.error(`Error in creating W3C schema : ${JSON.stringify(error)}`) throw new HttpException( { status: error.error.code, error: error.message, - message: error.error.message.error.message + message: error.error.message.error.message, }, error.error - ); - }); - return W3CSchemaResponse; + ) + }) + return W3CSchemaResponse } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type - async _createW3CledgerAgnostic(payload) { - const schemaResourceId = uuidv4(); + async _createW3CledgerAgnostic(payload: object) { + const schemaResourceId = uuidv4() const schemaPayload = JSON.stringify({ schemaId: `${schemaResourceId}`, - schema: payload - }); + schema: payload, + }) try { const jsonldSchemaResponse = await this.commonService.httpPost( @@ -472,15 +495,15 @@ export class SchemaService extends BaseService { { headers: { authorization: `Bearer ${process.env.SCHEMA_FILE_SERVER_TOKEN}`, - 'Content-Type': 'application/json' - } + 'Content-Type': 'application/json', + }, } - ); + ) - return jsonldSchemaResponse; + return jsonldSchemaResponse } catch (error) { - this.logger.error('Error creating W3C ledger agnostic schema:', error); - throw new Error(`Failed to create W3C ledger agnostic schema: ${error.message}`); + this.logger.error('Error creating W3C ledger agnostic schema:', error) + throw new Error(`Failed to create W3C ledger agnostic schema: ${error.message}`) } } @@ -489,289 +512,291 @@ export class SchemaService extends BaseService { const [{ agentEndPoint }, getAgentDetails, getSchemaDetails] = await Promise.all([ this.schemaRepository.getAgentDetailsByOrgId(orgId), this.schemaRepository.getAgentType(orgId), - this.schemaRepository.getSchemaBySchemaId(schemaId) - ]); + this.schemaRepository.getSchemaBySchemaId(schemaId), + ]) if (!getSchemaDetails) { - throw new NotFoundException(ResponseMessages.schema.error.notFound); + throw new NotFoundException(ResponseMessages.schema.error.notFound) } - const orgAgentType = await this.schemaRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId); + const orgAgentType = await this.schemaRepository.getOrgAgentType(getAgentDetails.org_agents[0].orgAgentTypeId) - let schemaResponse; + // biome-ignore lint/suspicious/noExplicitAny: + let schemaResponse: { response: any } if (getSchemaDetails?.type === SchemaType.INDY) { if (OrgAgentType.DEDICATED === orgAgentType) { const getSchemaPayload = { schemaId, orgId, agentEndPoint, - agentType: OrgAgentType.DEDICATED - }; - schemaResponse = await this._getSchemaById(getSchemaPayload); + agentType: OrgAgentType.DEDICATED, + } + schemaResponse = await this._getSchemaById(getSchemaPayload) } else if (OrgAgentType.SHARED === orgAgentType) { - const { tenantId } = await this.schemaRepository.getAgentDetailsByOrgId(orgId); + const { tenantId } = await this.schemaRepository.getAgentDetailsByOrgId(orgId) const getSchemaPayload = { tenantId, method: 'getSchemaById', payload: { schemaId }, agentType: OrgAgentType.SHARED, agentEndPoint, - orgId - }; - schemaResponse = await this._getSchemaById(getSchemaPayload); + orgId, + } + schemaResponse = await this._getSchemaById(getSchemaPayload) } - return schemaResponse.response; - } else if (getSchemaDetails?.type === SchemaType.W3C_Schema) { - return getSchemaDetails; + return schemaResponse.response + } + if (getSchemaDetails?.type === SchemaType.W3C_Schema) { + return getSchemaDetails } } catch (error) { - this.logger.error(`Error in getting schema by id: ${error}`); - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + this.logger.error(`Error in getting schema by id: ${error}`) + if (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); + statusCode: error?.status?.code, + }) } + throw new RpcException(error.response ? error.response : error) } } async getSchemaDetails(templateIds: string[]): Promise { try { - const getSchemaData = await this.schemaRepository.getSchemasDetailsBySchemaIds(templateIds); - return getSchemaData; + const getSchemaData = await this.schemaRepository.getSchemasDetailsBySchemaIds(templateIds) + return getSchemaData } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } async getSchemaDetailsBySchemaName(schemaName: string, orgId: string): Promise { try { - const getSchemaDetails = await this.schemaRepository.getSchemasDetailsBySchemaName(schemaName, orgId); - return getSchemaDetails; + const getSchemaDetails = await this.schemaRepository.getSchemasDetailsBySchemaName(schemaName, orgId) + return getSchemaDetails } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } async _getSchemaById(payload: GetSchemaAgentRedirection): Promise<{ response: string }> { try { const pattern = { - cmd: 'agent-get-schema' - }; + cmd: 'agent-get-schema', + } const schemaResponse = await from(this.natsClient.send(this.schemaServiceProxy, pattern, payload)) .pipe( map((response) => ({ - response + response, })) ) .toPromise() .catch((error) => { - this.logger.error(`Catch : ${JSON.stringify(error)}`); + this.logger.error(`Catch : ${JSON.stringify(error)}`) throw new HttpException( { status: error.statusCode, - error: error.message + error: error.message, }, error.error - ); - }); - return schemaResponse; + ) + }) + return schemaResponse } catch (error) { - this.logger.error(`Error in getting schema : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in getting schema : ${JSON.stringify(error)}`) + throw error } } async getSchemas(schemaSearchCriteria: ISchemaSearchCriteria, orgId: string): Promise { try { - const response = await this.schemaRepository.getSchemas(schemaSearchCriteria, orgId); + const response = await this.schemaRepository.getSchemas(schemaSearchCriteria, orgId) - if (0 === response.schemasCount) { - throw new NotFoundException(ResponseMessages.schema.error.notFound); + if (response.schemasCount === 0) { + throw new NotFoundException(ResponseMessages.schema.error.notFound) } const schemasDetails = response?.schemasResult.map((schemaAttributeItem) => { - const attributes = JSON.parse(schemaAttributeItem.attributes); - const firstName = schemaAttributeItem?.['organisation']?.userOrgRoles[0]?.user?.firstName; - const orgName = schemaAttributeItem?.['organisation'].name; - delete schemaAttributeItem?.['organisation']; + const attributes = JSON.parse(schemaAttributeItem.attributes) + const firstName = schemaAttributeItem?.organisation?.userOrgRoles[0]?.user?.firstName + const orgName = schemaAttributeItem?.organisation.name + if (schemaAttributeItem?.organisation) { + schemaAttributeItem.organisation = undefined + } return { ...schemaAttributeItem, attributes, organizationName: orgName, - userName: firstName - }; - }); + userName: firstName, + } + }) - const nextPage: number = Number(schemaSearchCriteria.pageNumber) + 1; + const nextPage: number = Number(schemaSearchCriteria.pageNumber) + 1 const schemasResponse: ISchemasWithPagination = { totalItems: response.schemasCount, hasNextPage: schemaSearchCriteria.pageSize * schemaSearchCriteria.pageNumber < response.schemasCount, - hasPreviousPage: 1 < schemaSearchCriteria.pageNumber, + hasPreviousPage: schemaSearchCriteria.pageNumber > 1, nextPage, previousPage: schemaSearchCriteria.pageNumber - 1, lastPage: Math.ceil(response.schemasCount / schemaSearchCriteria.pageSize), - data: schemasDetails - }; + data: schemasDetails, + } - return schemasResponse; + return schemasResponse } catch (error) { - this.logger.error(`Error in retrieving schemas by org id: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in retrieving schemas by org id: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async getcredDefListBySchemaId(payload: ISchemaCredDeffSearchInterface): Promise { - const { schemaSearchCriteria } = payload; + const { schemaSearchCriteria } = payload try { - const response = await this.schemaRepository.getSchemasCredDeffList(schemaSearchCriteria); + const response = await this.schemaRepository.getSchemasCredDeffList(schemaSearchCriteria) - if (0 === response.credDefCount) { - throw new NotFoundException(ResponseMessages.schema.error.credentialDefinitionNotFound); + if (response.credDefCount === 0) { + throw new NotFoundException(ResponseMessages.schema.error.credentialDefinitionNotFound) } const schemasResponse = { totalItems: response.credDefCount, hasNextPage: schemaSearchCriteria.pageSize * schemaSearchCriteria.pageNumber < response.credDefCount, - hasPreviousPage: 1 < schemaSearchCriteria.pageNumber, + hasPreviousPage: schemaSearchCriteria.pageNumber > 1, nextPage: schemaSearchCriteria.pageNumber + 1, previousPage: schemaSearchCriteria.pageNumber - 1, lastPage: Math.ceil(response.credDefCount / schemaSearchCriteria.pageSize), - data: response.credDefResult - }; + data: response.credDefResult, + } - return schemasResponse; + return schemasResponse } catch (error) { - this.logger.error(`Error in retrieving credential definition: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in retrieving credential definition: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async getAllSchema(schemaSearchCriteria: ISchemaSearchCriteria): Promise { try { - const response = await this.schemaRepository.getAllSchemaDetails(schemaSearchCriteria); + const response = await this.schemaRepository.getAllSchemaDetails(schemaSearchCriteria) const schemasDetails = response?.schemasResult.map((schemaAttributeItem) => { - const attributes = JSON.parse(schemaAttributeItem.attributes); - return { ...schemaAttributeItem, attributes }; - }); + const attributes = JSON.parse(schemaAttributeItem.attributes) + return { ...schemaAttributeItem, attributes } + }) const schemasResponse = { totalItems: response.schemasCount, hasNextPage: schemaSearchCriteria.pageSize * schemaSearchCriteria.pageNumber < response.schemasCount, - hasPreviousPage: 1 < schemaSearchCriteria.pageNumber, + hasPreviousPage: schemaSearchCriteria.pageNumber > 1, nextPage: schemaSearchCriteria.pageNumber + 1, previousPage: schemaSearchCriteria.pageNumber - 1, lastPage: Math.ceil(response.schemasCount / schemaSearchCriteria.pageSize), - data: schemasDetails - }; + data: schemasDetails, + } - if (0 !== response.schemasCount) { - return schemasResponse; - } else { - throw new NotFoundException(ResponseMessages.schema.error.notFound); + if (response.schemasCount !== 0) { + return schemasResponse } + throw new NotFoundException(ResponseMessages.schema.error.notFound) } catch (error) { - this.logger.error(`Error in retrieving all schemas: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in retrieving all schemas: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async _getOrgAgentApiKey(orgId: string): Promise { - const pattern = { cmd: 'get-org-agent-api-key' }; - const payload = { orgId }; + 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.natsClient.send(this.schemaServiceProxy, pattern, payload); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.natsClient.send(this.schemaServiceProxy, pattern, payload) + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } async schemaExist(payload: ISchemaExist): Promise< { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - name: string; - version: string; - attributes: string; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - ledgerId: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + name: string + version: string + attributes: string + schemaLedgerId: string + publisherDid: string + issuerId: string + orgId: string + ledgerId: string }[] > { try { - const schemaExist = await this.schemaRepository.schemaExist(payload); - return schemaExist; + const schemaExist = await this.schemaRepository.schemaExist(payload) + return schemaExist } catch (error) { - this.logger.error(`Error in schema exist: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in schema exist: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async archiveSchemas(did: string): Promise { try { - const schemaDetails = await this.schemaRepository.archiveSchemasByDid(did); - return schemaDetails; + const schemaDetails = await this.schemaRepository.archiveSchemasByDid(did) + return schemaDetails } catch (error) { - this.logger.error(`Error in archive schemas: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in archive schemas: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async storeSchemaDetails(schemaDetails: ISaveSchema): Promise { try { - const schemaStoreResult = await this.schemaRepository.saveSchemaRecord(schemaDetails); - return schemaStoreResult; + const schemaStoreResult = await this.schemaRepository.saveSchemaRecord(schemaDetails) + return schemaStoreResult } catch (error) { - this.logger.error(`Error in storeSchemaDetails: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in storeSchemaDetails: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async getSchemaBySchemaId(schemaId: string): Promise { try { - const schemaSearchResult = await this.schemaRepository.getSchemaBySchemaId(schemaId); - return schemaSearchResult; + const schemaSearchResult = await this.schemaRepository.getSchemaBySchemaId(schemaId) + return schemaSearchResult } catch (error) { - this.logger.error(`Error in getSchemaBySchemaId: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in getSchemaBySchemaId: ${error}`) + throw new RpcException(error.response ? error.response : error) } } async updateSchema(schemaDetails: IUpdateSchema): Promise { try { - const schemaSearchResult = await this.schemaRepository.updateSchema(schemaDetails); + const schemaSearchResult = await this.schemaRepository.updateSchema(schemaDetails) - if (0 === schemaSearchResult?.count) { - throw new NotFoundException('Records with given condition not found'); + if (schemaSearchResult?.count === 0) { + throw new NotFoundException('Records with given condition not found') } - return schemaSearchResult; + return schemaSearchResult } catch (error) { - this.logger.error(`Error in updateSchema: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in updateSchema: ${error}`) + throw new RpcException(error.response ? error.response : error) } } } diff --git a/apps/notification/interfaces/notification.interfaces.ts b/apps/notification/interfaces/notification.interfaces.ts index 57edecd46..78d85b4fa 100644 --- a/apps/notification/interfaces/notification.interfaces.ts +++ b/apps/notification/interfaces/notification.interfaces.ts @@ -1,23 +1,21 @@ - - export interface INotification { - id: string; - orgId: string; - notificationWebhook: string; + id: string + orgId: string + notificationWebhook: string } export interface IWebhookEndpoint { - orgId: string; - notificationWebhook: string; + orgId: string + notificationWebhook: string } export interface ISendNotification { - fcmToken: string; - messageType: string; - clientCode: string; + fcmToken: string + messageType: string + clientCode: string } export interface IGetNotification { - fcmToken: string; - messageType: string; -} \ No newline at end of file + fcmToken: string + messageType: string +} diff --git a/apps/notification/src/main.ts b/apps/notification/src/main.ts index 3ca6db826..cd2b59013 100644 --- a/apps/notification/src/main.ts +++ b/apps/notification/src/main.ts @@ -1,26 +1,23 @@ -import { NestFactory } from '@nestjs/core'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { NotificationModule } from '../src/notification.module'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { NotificationModule } from '../src/notification.module' - -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(NotificationModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.NOTIFICATION_SERVICE, process.env.NOTIFICATION_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.NOTIFICATION_SERVICE, process.env.NOTIFICATION_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Notification-Service Microservice is listening to NATS '); + await app.listen() + logger.log('Notification-Service Microservice is listening to NATS ') } -bootstrap(); \ No newline at end of file +bootstrap() diff --git a/apps/notification/src/notification.controller.ts b/apps/notification/src/notification.controller.ts index 40c9d33e8..a8145c7e3 100644 --- a/apps/notification/src/notification.controller.ts +++ b/apps/notification/src/notification.controller.ts @@ -1,7 +1,7 @@ -import { Controller } from '@nestjs/common'; -import { NotificationService } from './notification.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { INotification, IWebhookEndpoint, ISendNotification } from '../interfaces/notification.interfaces'; +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { INotification, ISendNotification, IWebhookEndpoint } from '../interfaces/notification.interfaces' +import type { NotificationService } from './notification.service' @Controller() export class NotificationController { @@ -9,21 +9,21 @@ export class NotificationController { /** * Register organization webhook endpoint - * @param payload + * @param payload * @returns Stored notification data */ @MessagePattern({ cmd: 'register-org-webhook-endpoint-for-notification' }) async registerOrgWebhookEndpoint(payload: IWebhookEndpoint): Promise { - return this.notificationService.registerOrgWebhookEndpoint(payload); + return this.notificationService.registerOrgWebhookEndpoint(payload) } /** * Send notification for holder - * @param payload + * @param payload * @returns Get notification details */ @MessagePattern({ cmd: 'send-notification' }) async sendNotification(payload: ISendNotification): Promise { - return this.notificationService.sendNotification(payload); + return this.notificationService.sendNotification(payload) } -} \ No newline at end of file +} diff --git a/apps/notification/src/notification.module.ts b/apps/notification/src/notification.module.ts index a29ff124e..29ac714fc 100644 --- a/apps/notification/src/notification.module.ts +++ b/apps/notification/src/notification.module.ts @@ -1,18 +1,18 @@ -import { CommonModule } from '@credebl/common'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CacheModule } from '@nestjs/cache-manager'; -import { Logger, Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { NotificationController } from './notification.controller'; -import { NotificationService } from './notification.service'; -import { PrismaService } from '@credebl/prisma-service'; -import { NotificationRepository } from './notification.repository'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; +import { CommonModule } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { CacheModule } from '@nestjs/cache-manager' +import { Logger, Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { NotificationController } from './notification.controller' +import { NotificationRepository } from './notification.repository' +import { NotificationService } from './notification.service' @Module({ imports: [ @@ -21,15 +21,17 @@ import { ContextInterceptorModule } from '@credebl/context/contextInterceptorMod { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.NOTIFICATION_SERVICE, process.env.NOTIFICATION_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.NOTIFICATION_SERVICE, process.env.NOTIFICATION_NKEY_SEED), + }, ]), CommonModule, GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, - CacheModule.register({ host: process.env.REDIS_HOST, port: process.env.REDIS_PORT }) + LoggerModule, + PlatformConfig, + ContextInterceptorModule, + CacheModule.register({ host: process.env.REDIS_HOST, port: process.env.REDIS_PORT }), ], controllers: [NotificationController], - providers: [NotificationService, NotificationRepository, PrismaService, Logger] + providers: [NotificationService, NotificationRepository, PrismaService, Logger], }) -export class NotificationModule { } \ No newline at end of file +export class NotificationModule {} diff --git a/apps/notification/src/notification.repository.ts b/apps/notification/src/notification.repository.ts index e543899b7..280283d68 100644 --- a/apps/notification/src/notification.repository.ts +++ b/apps/notification/src/notification.repository.ts @@ -1,65 +1,62 @@ -import { ResponseMessages } from '@credebl/common/response-messages'; -import { PrismaService } from '@credebl/prisma-service'; -import { Injectable, Logger, NotFoundException } from '@nestjs/common'; -import { INotification, IWebhookEndpoint } from '../interfaces/notification.interfaces'; +import { ResponseMessages } from '@credebl/common/response-messages' +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, type Logger, NotFoundException } from '@nestjs/common' +import type { INotification, IWebhookEndpoint } from '../interfaces/notification.interfaces' @Injectable() export class NotificationRepository { - constructor( - private readonly prisma: PrismaService, - private readonly logger: Logger - ) { } - - - /** - * Register organization webhook endpoint - * @param payload - * @returns Stored notification data - */ - async storeOrgWebhookEndpoint(payload: IWebhookEndpoint): Promise { - try { - - const { orgId, notificationWebhook } = payload; - const updateNotification = await this.prisma.notification.create({ - data: { - orgId, - notificationWebhook - } - }); - - if (!updateNotification) { - throw new NotFoundException(ResponseMessages.notification.error.notFound); - } - - return updateNotification; - } catch (error) { - this.logger.error(`Error in storeOrgWebhookEndpoint: ${error.message} `); - throw error; - } + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger + ) {} + + /** + * Register organization webhook endpoint + * @param payload + * @returns Stored notification data + */ + async storeOrgWebhookEndpoint(payload: IWebhookEndpoint): Promise { + try { + const { orgId, notificationWebhook } = payload + const updateNotification = await this.prisma.notification.create({ + data: { + orgId, + notificationWebhook, + }, + }) + + if (!updateNotification) { + throw new NotFoundException(ResponseMessages.notification.error.notFound) + } + + return updateNotification + } catch (error) { + this.logger.error(`Error in storeOrgWebhookEndpoint: ${error.message} `) + throw error } - - /** - * Get webhook endpoint - * @param orgId - * @returns Get notification details - */ - async getOrgWebhookEndpoint(orgId: string): Promise { - try { - - const updateNotification = await this.prisma.notification.findUnique({ - where: { - orgId - } - }); - - if (!updateNotification) { - throw new NotFoundException(ResponseMessages.notification.error.notFound); - } - - return updateNotification; - } catch (error) { - this.logger.error(`Error in getOrgWebhookEndpoint: ${error.message} `); - throw error; - } + } + + /** + * Get webhook endpoint + * @param orgId + * @returns Get notification details + */ + async getOrgWebhookEndpoint(orgId: string): Promise { + try { + const updateNotification = await this.prisma.notification.findUnique({ + where: { + orgId, + }, + }) + + if (!updateNotification) { + throw new NotFoundException(ResponseMessages.notification.error.notFound) + } + + return updateNotification + } catch (error) { + this.logger.error(`Error in getOrgWebhookEndpoint: ${error.message} `) + throw error } -} \ No newline at end of file + } +} diff --git a/apps/notification/src/notification.service.ts b/apps/notification/src/notification.service.ts index 01bb467d2..193fbd465 100644 --- a/apps/notification/src/notification.service.ts +++ b/apps/notification/src/notification.service.ts @@ -1,17 +1,13 @@ -import { BadRequestException, Injectable, Logger } from '@nestjs/common'; -import { - INotification, - IWebhookEndpoint, - ISendNotification -} from '../interfaces/notification.interfaces'; -import { RpcException } from '@nestjs/microservices'; -import { NotificationRepository } from './notification.repository'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { CommonService } from '@credebl/common'; +import type { CommonService } from '@credebl/common' +import { ResponseMessages } from '@credebl/common/response-messages' +import { BadRequestException, Injectable, Logger } from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' +import type { INotification, ISendNotification, IWebhookEndpoint } from '../interfaces/notification.interfaces' +import type { NotificationRepository } from './notification.repository' @Injectable() export class NotificationService { - private readonly logger = new Logger('NotificationService'); + private readonly logger = new Logger('NotificationService') constructor( private readonly commonService: CommonService, private readonly notificationRepository: NotificationRepository @@ -27,11 +23,11 @@ export class NotificationService { /** * Call the function for store the org webhook endpoint on notification table */ - const storeOrgWebhookEndpoint = await this.notificationRepository.storeOrgWebhookEndpoint(payload); - return storeOrgWebhookEndpoint; + const storeOrgWebhookEndpoint = await this.notificationRepository.storeOrgWebhookEndpoint(payload) + return storeOrgWebhookEndpoint } catch (error) { - this.logger.error(`[registerEndpoint] - error in register org webhook endpoint: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[registerEndpoint] - error in register org webhook endpoint: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -42,17 +38,17 @@ export class NotificationService { */ async sendNotification(payload: ISendNotification): Promise { try { - const orgId = payload.clientCode; + const orgId = payload.clientCode /** * Fetch the webhook endpoint by orgId */ - const getWebhookUrl = await this.notificationRepository.getOrgWebhookEndpoint(orgId); + const getWebhookUrl = await this.notificationRepository.getOrgWebhookEndpoint(orgId) const webhookPayload = { fcmToken: payload.fcmToken, - messageType: payload.messageType - }; + messageType: payload.messageType, + } /** * Send notification details with webhook endpoint @@ -61,23 +57,23 @@ export class NotificationService { .httpPost(getWebhookUrl?.notificationWebhook, webhookPayload) .then(async (response) => response) .catch((error) => { - this.logger.error(`Error in sendNotification : ${JSON.stringify(error)}`); - throw error; - }); + this.logger.error(`Error in sendNotification : ${JSON.stringify(error)}`) + throw error + }) if (!this.isValidUrl(getWebhookUrl?.notificationWebhook)) { - throw new BadRequestException(ResponseMessages.notification.error.invalidUrl); + throw new BadRequestException(ResponseMessages.notification.error.invalidUrl) } - return webhookResponse; + return webhookResponse } catch (error) { - this.logger.error(`[registerEndpoint] - error in send notification: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[registerEndpoint] - error in send notification: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } private isValidUrl(url: string): boolean { - const urlRegex = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/; - return urlRegex.test(url); + const urlRegex = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/ + return urlRegex.test(url) } } diff --git a/apps/organization/dtos/create-organization.dto.ts b/apps/organization/dtos/create-organization.dto.ts index 51c0e0b38..15e19bc7a 100644 --- a/apps/organization/dtos/create-organization.dto.ts +++ b/apps/organization/dtos/create-organization.dto.ts @@ -1,24 +1,24 @@ -import { ApiExtraModels } from '@nestjs/swagger'; +import { ApiExtraModels } from '@nestjs/swagger' @ApiExtraModels() export class CreateOrganizationDto { - name?: string; - description?: string; - logo?: string; - website?: string; - orgSlug?:string; - createdBy?:string; - updatedBy?:string; - lastChangedBy?:string; - notificationWebhook?: string; - registrationNumber?:string; - countryId?: number; - cityId?: number; - stateId?: number; + name?: string + description?: string + logo?: string + website?: string + orgSlug?: string + createdBy?: string + updatedBy?: string + lastChangedBy?: string + notificationWebhook?: string + registrationNumber?: string + countryId?: number + cityId?: number + stateId?: number } export class CreateUserRoleOrgDto { - orgRoleId: string; - userId: string; - organisationId: string; -} \ No newline at end of file + orgRoleId: string + userId: string + organisationId: string +} diff --git a/apps/organization/dtos/send-invitation.dto.ts b/apps/organization/dtos/send-invitation.dto.ts index 43b64f14b..b4f8fb8c8 100644 --- a/apps/organization/dtos/send-invitation.dto.ts +++ b/apps/organization/dtos/send-invitation.dto.ts @@ -1,13 +1,13 @@ -import { ApiExtraModels } from '@nestjs/swagger'; +import { ApiExtraModels } from '@nestjs/swagger' @ApiExtraModels() export class SendInvitationDto { - email: string; - orgRoleId: string[]; + email: string + orgRoleId: string[] } @ApiExtraModels() export class BulkSendInvitationDto { - invitations: SendInvitationDto[]; - orgId: string; -} \ No newline at end of file + invitations: SendInvitationDto[] + orgId: string +} diff --git a/apps/organization/dtos/update-invitation.dt.ts b/apps/organization/dtos/update-invitation.dt.ts index 21e345858..fbfde1683 100644 --- a/apps/organization/dtos/update-invitation.dt.ts +++ b/apps/organization/dtos/update-invitation.dt.ts @@ -1,10 +1,10 @@ -import { Invitation } from '@credebl/enum/enum'; +import type { Invitation } from '@credebl/enum/enum' export class UpdateInvitationDto { - invitationId: string; - orgId: string; - status: Invitation; - userId: string; - keycloakUserId: string; - email: string; -} \ No newline at end of file + invitationId: string + orgId: string + status: Invitation + userId: string + keycloakUserId: string + email: string +} diff --git a/apps/organization/dtos/verify-email-token.dto.ts b/apps/organization/dtos/verify-email-token.dto.ts index 27ca0154f..e97f69746 100644 --- a/apps/organization/dtos/verify-email-token.dto.ts +++ b/apps/organization/dtos/verify-email-token.dto.ts @@ -1,8 +1,8 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty } from '@nestjs/swagger' export class VerifyEmailTokenDto { - @ApiProperty() - email: string; - @ApiProperty() - verificationCode: string; -} \ No newline at end of file + @ApiProperty() + email: string + @ApiProperty() + verificationCode: string +} diff --git a/apps/organization/interfaces/organization.interface.ts b/apps/organization/interfaces/organization.interface.ts index 2c58d00fe..0a391ff97 100644 --- a/apps/organization/interfaces/organization.interface.ts +++ b/apps/organization/interfaces/organization.interface.ts @@ -1,308 +1,308 @@ -import { Prisma } from '@prisma/client'; -import { JsonValue } from '@prisma/client/runtime/library'; +import type { Prisma } from '@prisma/client' +import type { JsonValue } from '@prisma/client/runtime/library' export interface IUserOrgRoles { - id: string; - userId: string; - orgRoleId: string; - orgId: string | null; - orgRole: IOrgRole; + id: string + userId: string + orgRoleId: string + orgId: string | null + orgRole: IOrgRole } export interface IClientCredentials { - clientId: string; - clientSecret: string; + clientId: string + clientSecret: string } export interface IUpdateOrganization { - name: string; - description?: string; - orgId: string; - logo?: string; - website?: string; - orgSlug?: string; - isPublic?: boolean; - userId?: string; - countryId?: number; - cityId?: number; - stateId?: number; + name: string + description?: string + orgId: string + logo?: string + website?: string + orgSlug?: string + isPublic?: boolean + userId?: string + countryId?: number + cityId?: number + stateId?: number } export interface ICreateConnectionUrl { - id: string; - orgId: string; - agentId: string; - connectionInvitation: string; - multiUse: boolean; - createDateTime: Date; - createdBy: number; - lastChangedDateTime: Date; - lastChangedBy: number; + id: string + orgId: string + agentId: string + connectionInvitation: string + multiUse: boolean + createDateTime: Date + createdBy: number + lastChangedDateTime: Date + lastChangedBy: number } export interface IOrgAgent { - url: string; - apiKey: string; + url: string + apiKey: string } export interface IGetOrgById { - id: string; - name: string; - description: string; - orgSlug: string; - logoUrl: string; - website: string; - publicProfile: boolean; - schema: ISchema[]; - org_agents: IOrgAgents[]; + id: string + name: string + description: string + orgSlug: string + logoUrl: string + website: string + publicProfile: boolean + schema: ISchema[] + org_agents: IOrgAgents[] } interface ISchema { - id: string; - name: string; + id: string + name: string } interface IOrgAgents { - agent_invitations: IAgentInvitation[]; - ledgers: ILedgers; - org_agent_type: IOrgAgentType; + agent_invitations: IAgentInvitation[] + ledgers: ILedgers + org_agent_type: IOrgAgentType } interface IAgentInvitation { - id: string; - connectionInvitation: string; - multiUse: boolean; + id: string + connectionInvitation: string + multiUse: boolean } export interface IUserOrgRole { - user: string; - orgRole: string; + user: string + orgRole: string } interface IOrgAgentType { - id: string; - createDateTime: Date; - lastChangedDateTime: Date; - agent: string; + id: string + createDateTime: Date + lastChangedDateTime: Date + agent: string } interface ILedgers { - id: string; - name: string; - networkType: string; + id: string + name: string + networkType: string } export interface IGetOrganization { - totalCount: number; - totalPages: number; - organizations: IGetAllOrganizations[]; + totalCount: number + totalPages: number + organizations: IGetAllOrganizations[] } interface IGetAllOrganizations { - id: string; - name: string; - description: string; - logoUrl: string; - orgSlug: string; - userOrgRoles: IUserOrganizationRoles[]; + id: string + name: string + description: string + logoUrl: string + orgSlug: string + userOrgRoles: IUserOrganizationRoles[] } interface IUserOrganizationRoles { - id: string; - orgRole: IOrgRole; + id: string + orgRole: IOrgRole } export interface IOrgRole { - id: string; - name: string; - description: string; + id: string + name: string + description: string } export interface IOrgInvitationsPagination { - totalPages: number; - invitations: IInvitation[]; + totalPages: number + invitations: IInvitation[] } interface IInvitation { - id: string; - orgId: string; - email: string; - userId: string; - status: string; - orgRoles: string[]; - createDateTime: Date; - createdBy: string; - organisation: IOrganizationPagination; + id: string + orgId: string + email: string + userId: string + status: string + orgRoles: string[] + createDateTime: Date + createdBy: string + organisation: IOrganizationPagination } interface IOrganizationPagination { - id: string; - name: string; - logoUrl: string; + id: string + name: string + logoUrl: string } export interface Payload { - pageNumber: number; - pageSize: number; - search: string; - role?: string; + pageNumber: number + pageSize: number + search: string + role?: string } export interface IDidList { - id: string; - createDateTime: Date; - did: string; - lastChangedDateTime: Date; - isPrimaryDid: boolean; + id: string + createDateTime: Date + did: string + lastChangedDateTime: Date + isPrimaryDid: boolean } export interface IPrimaryDid { - orgId: string; - did: string; + orgId: string + did: string } export interface IDidDetails { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - orgId: string; - isPrimaryDid: boolean; - did: string; - didDocument: Prisma.JsonValue; - orgAgentId: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + orgId: string + isPrimaryDid: boolean + did: string + didDocument: Prisma.JsonValue + orgAgentId: string } export interface IPrimaryDidDetails extends IPrimaryDid { - id: string; - networkId: string; - didDocument: Prisma.JsonValue; + id: string + networkId: string + didDocument: Prisma.JsonValue } export interface OrgInvitation { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - deletedAt: Date; - userId: string; - orgId: string; - status: string; - orgRoles: string[]; - email: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + deletedAt: Date + userId: string + orgId: string + status: string + orgRoles: string[] + email: string } export interface ILedgerNameSpace { - id: string; - createDateTime: Date; - lastChangedDateTime: Date; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - nymTxnEndpoint: string; - indyNamespace: string; - networkUrl: string; + id: string + createDateTime: Date + lastChangedDateTime: Date + name: string + networkType: string + poolConfig: string + isActive: boolean + networkString: string + nymTxnEndpoint: string + indyNamespace: string + networkUrl: string } export interface IGetDids { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - orgId: string; - isPrimaryDid: boolean; - did: string; - didDocument: Prisma.JsonValue; - orgAgentId: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + orgId: string + isPrimaryDid: boolean + did: string + didDocument: Prisma.JsonValue + orgAgentId: string } export interface ILedgerDetails { - id: string; - createDateTime: Date; - lastChangedDateTime: Date; - name: string; - networkType: string; - poolConfig: string; - isActive: boolean; - networkString: string; - nymTxnEndpoint: string; - indyNamespace: string; - networkUrl: string; + id: string + createDateTime: Date + lastChangedDateTime: Date + name: string + networkType: string + poolConfig: string + isActive: boolean + networkString: string + nymTxnEndpoint: string + indyNamespace: string + networkUrl: string } export interface IOrgRoleDetails { - id: string; - name: string; - description: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - deletedAt: Date; + id: string + name: string + description: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + deletedAt: Date } export interface IEcosystemOrgStatus { - ecosystemId: string; - orgId: string; - status: string; + ecosystemId: string + orgId: string + status: string } interface IDidDocument { - id: string; - '@context': string[]; - authentication: string[]; - verificationMethod: IVerificationMethod[]; + id: string + '@context': string[] + authentication: string[] + verificationMethod: IVerificationMethod[] } interface IVerificationMethod { - id: string; - type: string; - controller: string; - publicKeyBase58: string; + id: string + type: string + controller: string + publicKeyBase58: string } interface IOrgAgentDetails { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - orgDid: string; - verkey: string | null; - agentEndPoint: string; - agentId: string | null; - isDidPublic: boolean; - agentSpinUpStatus: number; - agentOptions: string | Buffer | null; - walletName: string; - tenantId: string; - apiKey: string | null; - agentsTypeId: string; - orgId: string; - orgAgentTypeId: string; - ledgerId: string; - didDocument: IDidDocument | JsonValue; - webhookUrl: string | null; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + orgDid: string + verkey: string | null + agentEndPoint: string + agentId: string | null + isDidPublic: boolean + agentSpinUpStatus: number + agentOptions: string | Buffer | null + walletName: string + tenantId: string + apiKey: string | null + agentsTypeId: string + orgId: string + orgAgentTypeId: string + ledgerId: string + didDocument: IDidDocument | JsonValue + webhookUrl: string | null } interface IOrganisation { - id: string; - name: string; - orgSlug: string; + id: string + name: string + orgSlug: string } interface IUserOrgRolesDetails { - id: string; - userId: string; - orgRoleId: string; - orgId: string | null; - idpRoleId: string; + id: string + userId: string + orgRoleId: string + orgId: string | null + idpRoleId: string } export interface IOrgDetails { - organisations: IOrganisation[]; - orgAgents: IOrgAgentDetails[]; - userOrgRoles: IUserOrgRolesDetails[]; + organisations: IOrganisation[] + orgAgents: IOrgAgentDetails[] + userOrgRoles: IUserOrgRolesDetails[] } diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index dfec7845b..ecfb55d3b 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -1,45 +1,51 @@ /* eslint-disable prefer-destructuring */ /* eslint-disable camelcase */ -import { ConflictException, Injectable, Logger, NotFoundException, InternalServerErrorException } from '@nestjs/common'; -// eslint-disable-next-line camelcase import { + ConflictException, + Injectable, + InternalServerErrorException, + type Logger, + NotFoundException, +} from '@nestjs/common' +// eslint-disable-next-line camelcase +import type { Prisma, agent_invitations, org_agents, org_invitations, + org_roles, + organisation, user, user_org_roles, - organisation, - org_roles -} from '@prisma/client'; +} from '@prisma/client' -import { CreateOrganizationDto } from '../dtos/create-organization.dto'; -import { - IGetDids, +import type { + IDeleteOrganization, + IOrganization, + IOrganizationDashboard, + IOrganizationInvitations, +} from '@credebl/common/interfaces/organization.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { Invitation, PrismaTables, SortValue } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import type { UserOrgRolesService } from '@credebl/user-org-roles' +import type { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface' +import type { CreateOrganizationDto } from '../dtos/create-organization.dto' +import type { IDidDetails, IDidList, + IGetDids, IGetOrgById, IGetOrganization, + ILedgerDetails, + ILedgerNameSpace, + IOrgDetails, + IOrgRoleDetails, IPrimaryDidDetails, IUpdateOrganization, - ILedgerNameSpace, OrgInvitation, - ILedgerDetails, - IOrgRoleDetails, - IOrgDetails -} from '../interfaces/organization.interface'; -import { Invitation, PrismaTables, SortValue } from '@credebl/enum/enum'; -import { PrismaService } from '@credebl/prisma-service'; -import { UserOrgRolesService } from '@credebl/user-org-roles'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { - IOrganizationInvitations, - IOrganization, - IOrganizationDashboard, - IDeleteOrganization -} from '@credebl/common/interfaces/organization.interface'; -import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; +} from '../interfaces/organization.interface' @Injectable() export class OrganizationRepository { @@ -51,11 +57,11 @@ export class OrganizationRepository { async getPlatformConfigDetails(): Promise { try { - const platformConfigdetails = await this.prisma.platform_config.findMany(); - return platformConfigdetails; + const platformConfigdetails = await this.prisma.platform_config.findMany() + return platformConfigdetails } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -69,12 +75,12 @@ export class OrganizationRepository { try { return this.prisma.organisation.findFirst({ where: { - name - } - }); + name, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -82,12 +88,12 @@ export class OrganizationRepository { try { return this.prisma.organisation.findUnique({ where: { - orgSlug - } - }); + orgSlug, + }, + }) } catch (error) { - this.logger.error(`error in checkOrganizationSlugExist: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error in checkOrganizationSlugExist: ${JSON.stringify(error)}`) + throw error } } @@ -112,13 +118,13 @@ export class OrganizationRepository { cityId: createOrgDto.cityId, stateId: createOrgDto.stateId, createdBy: createOrgDto.createdBy, - lastChangedBy: createOrgDto.lastChangedBy - } - }); - return orgData; + lastChangedBy: createOrgDto.lastChangedBy, + }, + }) + return orgData } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -132,7 +138,7 @@ export class OrganizationRepository { try { return this.prisma.organisation.update({ where: { - id: String(updateOrgDto.orgId) + id: String(updateOrgDto.orgId), }, data: { name: updateOrgDto.name, @@ -144,12 +150,12 @@ export class OrganizationRepository { lastChangedBy: updateOrgDto.userId, countryId: updateOrgDto.countryId, stateId: updateOrgDto.stateId, - cityId: updateOrgDto.cityId - } - }); + cityId: updateOrgDto.cityId, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -157,13 +163,13 @@ export class OrganizationRepository { try { const response = await this.prisma.agent_invitations.findUnique({ where: { - id: orgId - } - }); - return response; + id: orgId, + }, + }) + return response } catch (error) { - this.logger.error(`error in getting agent invitation details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error in getting agent invitation details: ${JSON.stringify(error)}`) + throw error } } @@ -172,13 +178,13 @@ export class OrganizationRepository { const temp = await this.prisma.agent_invitations.updateMany({ where: { orgId }, data: { - connectionInvitation - } - }); - return temp; + connectionInvitation, + }, + }) + return temp } catch (error) { - this.logger.error(`Error in updating connection invitation details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in updating connection invitation details: ${JSON.stringify(error)}`) + throw error } } @@ -195,12 +201,12 @@ export class OrganizationRepository { data: { userId: userOrgRoleDto.userId, orgRoleId: userOrgRoleDto.orgRoleId, - orgId: userOrgRoleDto.orgId - } - }); + orgId: userOrgRoleDto.orgId, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -225,12 +231,12 @@ export class OrganizationRepository { orgRoles: orgRoleId, status: Invitation.PENDING, createdBy: userId, - lastChangedBy: userId - } - }); + lastChangedBy: userId, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -243,18 +249,18 @@ export class OrganizationRepository { async getOrganizationDetails(orgId: string): Promise { try { if (!orgId) { - throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound) } const orgDetails = await this.prisma.organisation.findFirst({ where: { - id: orgId - } - }); + id: orgId, + }, + }) - return orgDetails; + return orgDetails } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -262,14 +268,14 @@ export class OrganizationRepository { try { return this.prisma.organisation.findFirstOrThrow({ where: { - id: orgId + id: orgId, }, include: { userOrgRoles: { where: { orgRole: { - name: role - } + name: role, + }, }, include: { user: { @@ -279,17 +285,17 @@ export class OrganizationRepository { id: true, firstName: true, lastName: true, - isEmailVerified: true - } + isEmailVerified: true, + }, }, - orgRole: true - } - } - } - }); + orgRole: true, + }, + }, + }, + }) } catch (error) { - this.logger.error(`error in getOrganizationOwnerDetails: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error in getOrganizationOwnerDetails: ${JSON.stringify(error)}`) + throw error } } @@ -300,24 +306,24 @@ export class OrganizationRepository { pageSize: number, search = '' ): Promise { - this.logger.log(search); + this.logger.log(search) const query = { email, - status - }; - return this.getOrgInvitationsPagination(query, pageNumber, pageSize); + status, + } + return this.getOrgInvitationsPagination(query, pageNumber, pageSize) } async updateOrganizationById(data: object, orgId: string): Promise { try { const orgDetails = await this.prisma.organisation.update({ where: { id: orgId }, - data - }); - return orgDetails; + data, + }) + return orgDetails } catch (error) { - this.logger.error(`Error in updateOrganizationById: ${error.message}`); - throw error; + this.logger.error(`Error in updateOrganizationById: ${error.message}`) + throw error } } @@ -325,15 +331,15 @@ export class OrganizationRepository { try { return this.prisma.org_invitations.findMany({ where: { - ...queryObject + ...queryObject, }, include: { - organisation: true - } - }); + organisation: true, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -341,12 +347,12 @@ export class OrganizationRepository { try { return this.prisma.org_invitations.count({ where: { - orgId - } - }); + orgId, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -359,7 +365,7 @@ export class OrganizationRepository { const result = await this.prisma.$transaction([ this.prisma.org_invitations.findMany({ where: { - ...queryObject + ...queryObject, }, select: { id: true, @@ -373,32 +379,32 @@ export class OrganizationRepository { select: { id: true, name: true, - logoUrl: true - } + logoUrl: true, + }, }, - orgRoles: true + orgRoles: true, }, take: pageSize, skip: (pageNumber - 1) * pageSize, orderBy: { - createDateTime: 'desc' - } + createDateTime: 'desc', + }, }), this.prisma.org_invitations.count({ where: { - ...queryObject - } - }) - ]); + ...queryObject, + }, + }), + ]) - const invitations = result[0]; - const totalCount = result[1]; - const totalPages = Math.ceil(totalCount / pageSize); + const invitations = result[0] + const totalCount = result[1] + const totalPages = Math.ceil(totalCount / pageSize) - return { totalPages, invitations }; + return { totalPages, invitations } } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -413,14 +419,14 @@ export class OrganizationRepository { orgId, OR: [ { email: { contains: search, mode: 'insensitive' } }, - { status: { contains: search, mode: 'insensitive' } } - ] - }; + { status: { contains: search, mode: 'insensitive' } }, + ], + } - return this.getOrgInvitationsPagination(query, pageNumber, pageSize); + return this.getOrgInvitationsPagination(query, pageNumber, pageSize) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -428,13 +434,13 @@ export class OrganizationRepository { try { const getUserById = await this.prisma.user.findUnique({ where: { - id - } - }); - return getUserById; + id, + }, + }) + return getUserById } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -442,7 +448,7 @@ export class OrganizationRepository { try { return this.prisma.organisation.findFirst({ where: { - ...queryObject + ...queryObject, }, select: { id: true, @@ -458,13 +464,13 @@ export class OrganizationRepository { schema: { select: { id: true, - name: true - } + name: true, + }, }, userOrgRoles: { select: { - orgRole: true - } + orgRole: true, + }, }, org_agents: { select: { @@ -482,69 +488,69 @@ export class OrganizationRepository { select: { id: true, connectionInvitation: true, - multiUse: true - } + multiUse: true, + }, }, org_agent_type: true, ledgers: { select: { id: true, name: true, - networkType: true - } - } - } - } - } - }); + networkType: true, + }, + }, + }, + }, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } async getOrgDashboard(orgId: string): Promise { const query = { where: { - orgId - } - }; + orgId, + }, + } try { const usersCount = await this.prisma.user.count({ where: { userOrgRoles: { some: { - orgId - } - } - } - }); + orgId, + }, + }, + }, + }) const schemasCount = await this.prisma.schema.count({ where: { orgId, - isSchemaArchived: false - } - }); + isSchemaArchived: false, + }, + }) const credentialsCount = await this.prisma.credentials.count({ - ...query - }); + ...query, + }) const presentationsCount = await this.prisma.presentations.count({ - ...query - }); + ...query, + }) return { usersCount, schemasCount, credentialsCount, - presentationsCount - }; + presentationsCount, + } } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -557,15 +563,15 @@ export class OrganizationRepository { try { return this.prisma.org_invitations.findUnique({ where: { - id + id, }, include: { - organisation: true - } - }); + organisation: true, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -573,7 +579,7 @@ export class OrganizationRepository { try { const recordsWithNullIdpId = await this.prisma.organisation.findMany({ where: { - idpId: null + idpId: null, }, include: { userOrgRoles: { @@ -584,19 +590,19 @@ export class OrganizationRepository { username: true, id: true, keycloakUserId: true, - isEmailVerified: true - } + isEmailVerified: true, + }, }, - orgRole: true - } - } - } - }); + orgRole: true, + }, + }, + }, + }) - return recordsWithNullIdpId; + return recordsWithNullIdpId } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -610,15 +616,15 @@ export class OrganizationRepository { try { return this.prisma.org_invitations.update({ where: { - id + id, }, data: { - ...data - } - }); + ...data, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException('Unable to update org invitation'); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException('Unable to update org invitation') } } @@ -631,7 +637,7 @@ export class OrganizationRepository { userId?: string ): Promise { try { - const sortByName = SortValue.DESC; + const sortByName = SortValue.DESC const result = await this.prisma.$transaction([ this.prisma.organisation.findMany({ where: { @@ -639,11 +645,11 @@ export class OrganizationRepository { userOrgRoles: { some: { orgRole: { - name: role + name: role, }, - userId - } - } + userId, + }, + }, }, select: { id: true, @@ -658,9 +664,9 @@ export class OrganizationRepository { userOrgRoles: { where: { orgRole: { - name: role + name: role, }, - ...filterOptions + ...filterOptions, }, select: { id: true, @@ -668,22 +674,22 @@ export class OrganizationRepository { select: { id: true, name: true, - description: true - } - } - } + description: true, + }, + }, + }, }, org_agents: { select: { - orgDid: true - } - } + orgDid: true, + }, + }, }, take: pageSize, skip: (pageNumber - 1) * pageSize, orderBy: { - createDateTime: sortByName - } + createDateTime: sortByName, + }, }), this.prisma.organisation.count({ where: { @@ -691,22 +697,22 @@ export class OrganizationRepository { userOrgRoles: { some: { orgRole: { - name: role + name: role, }, - userId - } - } - } - }) - ]); - const organizations = result[0]; - const totalCount = result[1]; - const totalPages = Math.ceil(totalCount / pageSize); + userId, + }, + }, + }, + }), + ]) + const organizations = result[0] + const totalCount = result[1] + const totalPages = Math.ceil(totalCount / pageSize) - return { totalCount, totalPages, organizations }; + return { totalCount, totalPages, organizations } } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -714,11 +720,11 @@ export class OrganizationRepository { const getOrgCount = await this.prisma.organisation.count({ where: { userOrgRoles: { - some: { userId } - } - } - }); - return getOrgCount; + some: { userId }, + }, + }, + }) + return getOrgCount } /** * @@ -731,12 +737,12 @@ export class OrganizationRepository { return this.prisma.organisation.findUnique({ where: { id: orgId, - name - } - }); + name, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } @@ -744,42 +750,42 @@ export class OrganizationRepository { try { return this.prisma.organisation.findUnique({ where: { - id - } - }); + id, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } async getCredDefByOrg(orgId: string): Promise< { - tag: string; - credentialDefinitionId: string; - schemaLedgerId: string; - revocable: boolean; + tag: string + credentialDefinitionId: string + schemaLedgerId: string + revocable: boolean }[] > { try { return this.prisma.credential_definition.findMany({ where: { - orgId + orgId, }, select: { tag: true, credentialDefinitionId: true, schemaLedgerId: true, revocable: true, - createDateTime: true + createDateTime: true, }, orderBy: { - createDateTime: 'desc' - } - }); + createDateTime: 'desc', + }, + }) } catch (error) { - this.logger.error(`Error in getting agent DID: ${error}`); - throw error; + this.logger.error(`Error in getting agent DID: ${error}`) + throw error } } @@ -787,27 +793,27 @@ export class OrganizationRepository { try { const agentDetails = await this.prisma.org_agents.findFirstOrThrow({ where: { - orgId - } - }); + orgId, + }, + }) if (!agentDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.notFound); + throw new NotFoundException(ResponseMessages.organisation.error.notFound) } - return agentDetails; + return agentDetails } catch (error) { - this.logger.error(`Error in get getAgentEndPoint: ${error.message} `); - throw error; + this.logger.error(`Error in get getAgentEndPoint: ${error.message} `) + throw error } } async deleteOrg(id: string): Promise<{ - deletedUserActivity: Prisma.BatchPayload; - deletedUserOrgRole: Prisma.BatchPayload; - deletedOrgInvitations: Prisma.BatchPayload; - deletedNotification: Prisma.BatchPayload; - deleteOrg: IDeleteOrganization; + deletedUserActivity: Prisma.BatchPayload + deletedUserOrgRole: Prisma.BatchPayload + deletedOrgInvitations: Prisma.BatchPayload + deletedNotification: Prisma.BatchPayload + deleteOrg: IDeleteOrganization }> { const tablesToCheck = [ `${PrismaTables.ORG_AGENTS}`, @@ -816,49 +822,49 @@ export class OrganizationRepository { `${PrismaTables.CONNECTIONS}`, `${PrismaTables.CREDENTIALS}`, `${PrismaTables.PRESENTATIONS}`, - `${PrismaTables.FILE_UPLOAD}` - ]; + `${PrismaTables.FILE_UPLOAD}`, + ] try { return await this.prisma.$transaction(async (prisma) => { // Check for references in all tables in parallel const referenceCounts = await Promise.all( tablesToCheck.map((table) => prisma[table].count({ where: { orgId: id } })) - ); + ) referenceCounts.forEach((count, index) => { - if (0 < count) { - throw new ConflictException(`Organization ID ${id} is referenced in the table ${tablesToCheck[index]}`); + if (count > 0) { + throw new ConflictException(`Organization ID ${id} is referenced in the table ${tablesToCheck[index]}`) } - }); + }) - const deletedNotification = await prisma.notification.deleteMany({ where: { orgId: id } }); + const deletedNotification = await prisma.notification.deleteMany({ where: { orgId: id } }) - const deletedUserActivity = await prisma.user_activity.deleteMany({ where: { orgId: id } }); + const deletedUserActivity = await prisma.user_activity.deleteMany({ where: { orgId: id } }) - const deletedUserOrgRole = await prisma.user_org_roles.deleteMany({ where: { orgId: id } }); + const deletedUserOrgRole = await prisma.user_org_roles.deleteMany({ where: { orgId: id } }) - const deletedOrgInvitations = await prisma.org_invitations.deleteMany({ where: { orgId: id } }); + const deletedOrgInvitations = await prisma.org_invitations.deleteMany({ where: { orgId: id } }) await this.prisma.schema.updateMany({ where: { orgId: id }, - data: { orgId: null } - }); + data: { orgId: null }, + }) await this.prisma.credential_definition.updateMany({ where: { orgId: id }, - data: { orgId: null } - }); + data: { orgId: null }, + }) // If no references are found, delete the organization - const deleteOrg = await prisma.organisation.delete({ where: { id } }); + const deleteOrg = await prisma.organisation.delete({ where: { id } }) - return { deletedUserActivity, deletedUserOrgRole, deletedOrgInvitations, deletedNotification, deleteOrg }; - }); + return { deletedUserActivity, deletedUserOrgRole, deletedOrgInvitations, deletedNotification, deleteOrg } + }) // return result; } catch (error) { - this.logger.error(`Error in deleteOrg: ${error}`); - throw error; + this.logger.error(`Error in deleteOrg: ${error}`) + throw error } } @@ -871,12 +877,12 @@ export class OrganizationRepository { try { return await this.prisma.org_invitations.delete({ where: { - id - } - }); + id, + }, + }) } catch (error) { - this.logger.error(`Delete Org Invitation Error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Delete Org Invitation Error: ${JSON.stringify(error)}`) + throw error } } @@ -885,49 +891,49 @@ export class OrganizationRepository { try { return this.prisma.org_dids.findMany({ where: { - orgId + orgId, }, select: { id: true, createDateTime: true, did: true, lastChangedDateTime: true, - isPrimaryDid: true - } - }); + isPrimaryDid: true, + }, + }) } catch (error) { - this.logger.error(`error in getAllOrganizationDid: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error in getAllOrganizationDid: ${JSON.stringify(error)}`) + throw error } } async setOrgsPrimaryDid(primaryDidDetails: IPrimaryDidDetails): Promise { try { - const { did, didDocument, id, orgId, networkId } = primaryDidDetails; + const { did, didDocument, id, orgId, networkId } = primaryDidDetails await this.prisma.$transaction([ this.prisma.org_dids.update({ where: { - id + id, }, data: { - isPrimaryDid: true - } + isPrimaryDid: true, + }, }), this.prisma.org_agents.update({ where: { - orgId + orgId, }, data: { orgDid: did, didDocument, - ledgerId: networkId - } - }) - ]); - return ResponseMessages.organisation.success.didDetails; + ledgerId: networkId, + }, + }), + ]) + return ResponseMessages.organisation.success.didDetails } catch (error) { - this.logger.error(`[setOrgsPrimaryDid] - Update DID details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[setOrgsPrimaryDid] - Update DID details: ${JSON.stringify(error)}`) + throw error } } @@ -935,12 +941,12 @@ export class OrganizationRepository { try { return this.prisma.org_dids.findFirstOrThrow({ where: { - did - } - }); + did, + }, + }) } catch (error) { - this.logger.error(`[getDidDetailsByDid] - get DID details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getDidDetailsByDid] - get DID details: ${JSON.stringify(error)}`) + throw error } } @@ -949,12 +955,12 @@ export class OrganizationRepository { return this.prisma.org_dids.findFirstOrThrow({ where: { orgId, - isPrimaryDid: true - } - }); + isPrimaryDid: true, + }, + }) } catch (error) { - this.logger.error(`[getPerviousPrimaryDid] - get DID details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getPerviousPrimaryDid] - get DID details: ${JSON.stringify(error)}`) + throw error } } @@ -962,12 +968,12 @@ export class OrganizationRepository { try { return this.prisma.org_dids.findMany({ where: { - orgId - } - }); + orgId, + }, + }) } catch (error) { - this.logger.error(`[getDids] - get all DIDs: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getDids] - get all DIDs: ${JSON.stringify(error)}`) + throw error } } @@ -975,15 +981,15 @@ export class OrganizationRepository { try { return this.prisma.org_dids.update({ where: { - id + id, }, data: { - isPrimaryDid: false - } - }); + isPrimaryDid: false, + }, + }) } catch (error) { - this.logger.error(`[setPreviousDidFlase] - Update DID details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[setPreviousDidFlase] - Update DID details: ${JSON.stringify(error)}`) + throw error } } @@ -991,12 +997,12 @@ export class OrganizationRepository { try { return this.prisma.org_invitations.findMany({ where: { - orgId - } - }); + orgId, + }, + }) } catch (error) { - this.logger.error(`[getOrgInvitationsByOrg] - get organization invitations: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgInvitationsByOrg] - get organization invitations: ${JSON.stringify(error)}`) + throw error } } @@ -1004,12 +1010,12 @@ export class OrganizationRepository { try { return this.prisma.ledgers.findFirstOrThrow({ where: { - indyNamespace: nameSpace - } - }); + indyNamespace: nameSpace, + }, + }) } catch (error) { - this.logger.error(`[getNetworkByIndyNameSpace] - get network by namespace: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getNetworkByIndyNameSpace] - get network by namespace: ${JSON.stringify(error)}`) + throw error } } @@ -1017,13 +1023,13 @@ export class OrganizationRepository { try { const ledgerData = await this.prisma.ledgers.findFirstOrThrow({ where: { - name - } - }); - return ledgerData; + name, + }, + }) + return ledgerData } catch (error) { - this.logger.error(`[getLedger] - get ledger details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getLedger] - get ledger details: ${JSON.stringify(error)}`) + throw error } } @@ -1032,14 +1038,14 @@ export class OrganizationRepository { const orgRoleData = await this.prisma.org_roles.findMany({ where: { id: { - in: id - } - } - }); - return orgRoleData; + in: id, + }, + }, + }) + return orgRoleData } catch (error) { - this.logger.error(`[getOrgRole] - get org role details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgRole] - get org role details: ${JSON.stringify(error)}`) + throw error } } @@ -1048,19 +1054,19 @@ export class OrganizationRepository { const userOrgRoleDetails = await this.prisma.user_org_roles.findMany({ where: { userId, - orgId + orgId, }, select: { - orgRoleId: true - } - }); + orgRoleId: true, + }, + }) // Map the result to an array of orgRoleId - const orgRoleIds = userOrgRoleDetails.map((role) => role.orgRoleId); + const orgRoleIds = userOrgRoleDetails.map((role) => role.orgRoleId) - return orgRoleIds; + return orgRoleIds } catch (error) { - this.logger.error(`[getUserOrgRole] - get user org role details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getUserOrgRole] - get user org role details: ${JSON.stringify(error)}`) + throw error } } @@ -1068,14 +1074,14 @@ export class OrganizationRepository { try { const { agent } = await this.prisma.org_agents_type.findFirst({ where: { - id: orgAgentTypeId - } - }); + id: orgAgentTypeId, + }, + }) - return agent; + return agent } catch (error) { - this.logger.error(`[getAgentTypeByAgentTypeId] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getAgentTypeByAgentTypeId] - error: ${JSON.stringify(error)}`) + throw error } } @@ -1083,24 +1089,24 @@ export class OrganizationRepository { try { const orgRoleDetails = await this.prisma.org_roles.findFirstOrThrow({ where: { - name: roleName - } - }); + name: roleName, + }, + }) - return orgRoleDetails; + return orgRoleDetails } catch (error) { - this.logger.error(`[getOrgRoles] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgRoles] - error: ${JSON.stringify(error)}`) + throw error } } async getAllOrgRolesDetails(): Promise { try { - const orgRoleDetails = await this.prisma.org_roles.findMany(); - return orgRoleDetails; + const orgRoleDetails = await this.prisma.org_roles.findMany() + return orgRoleDetails } catch (error) { - this.logger.error(`[getAllOrgRolesDetails] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getAllOrgRolesDetails] - error: ${JSON.stringify(error)}`) + throw error } } @@ -1109,18 +1115,18 @@ export class OrganizationRepository { const roleDetails = await this.prisma.org_roles.findMany({ where: { id: { - in: orgRoles - } + in: orgRoles, + }, }, select: { id: true, name: true, - description: true - } - }); - return roleDetails; + description: true, + }, + }) + return roleDetails } catch (error) { - this.logger.error(`[getOrgRolesById] - error: ${JSON.stringify(error)}`); + this.logger.error(`[getOrgRolesById] - error: ${JSON.stringify(error)}`) } } @@ -1129,26 +1135,26 @@ export class OrganizationRepository { const organisations = await this.prisma.organisation.findMany({ where: { id: { - in: organisationIds - } + in: organisationIds, + }, }, select: { id: true, name: true, - orgSlug: true - } - }); + orgSlug: true, + }, + }) - return organisations; + return organisations } catch (error) { - this.logger.error(`Error fetching organisations: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error fetching organisations: ${JSON.stringify(error)}`) + throw error } } async handleGetOrganisationData(data: { orgIds: string[]; search: string }): Promise { try { - const { orgIds, search } = data; + const { orgIds, search } = data // Fetch organisation data with optional search filtering const organisations = await this.prisma.organisation.findMany({ @@ -1157,38 +1163,38 @@ export class OrganizationRepository { OR: [ { name: { contains: search, mode: 'insensitive' } }, // eslint-disable-next-line camelcase - { org_agents: { some: { orgDid: { contains: search, mode: 'insensitive' } } } } - ] + { org_agents: { some: { orgDid: { contains: search, mode: 'insensitive' } } } }, + ], }, select: { id: true, name: true, - orgSlug: true - } - }); + orgSlug: true, + }, + }) // Fetch org_agents data const orgAgents = await this.prisma.org_agents.findMany({ where: { orgId: { in: orgIds }, - ...(search && { orgDid: { contains: search, mode: 'insensitive' } }) - } - }); + ...(search && { orgDid: { contains: search, mode: 'insensitive' } }), + }, + }) const userOrgRoles = await this.prisma.user_org_roles.findMany({ where: { - orgId: { in: orgIds } - } - }); + orgId: { in: orgIds }, + }, + }) return { organisations, orgAgents, - userOrgRoles - }; + userOrgRoles, + } } catch (error) { - this.logger.error(`Error in handleGetOrganisationData: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in handleGetOrganisationData: ${JSON.stringify(error)}`) + throw error } } } diff --git a/apps/organization/src/main.ts b/apps/organization/src/main.ts index a8d0f278e..a5f32834d 100644 --- a/apps/organization/src/main.ts +++ b/apps/organization/src/main.ts @@ -1,26 +1,24 @@ -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { NestFactory } from '@nestjs/core'; -import { OrganizationModule } from './organization.module'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; +import { CommonConstants } from '@credebl/common/common.constant' // import { nkeyAuthenticator } from 'nats'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { OrganizationModule } from './organization.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(OrganizationModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.ORGANIZATION_SERVICE, process.env.ORGANIZATION_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.ORGANIZATION_SERVICE, process.env.ORGANIZATION_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Organization Microservice is listening to NATS '); + await app.listen() + logger.log('Organization Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/organization/src/organization.controller.ts b/apps/organization/src/organization.controller.ts index ca93335e0..524972d3e 100644 --- a/apps/organization/src/organization.controller.ts +++ b/apps/organization/src/organization.controller.ts @@ -1,20 +1,34 @@ -import { Controller, Logger, Body } from '@nestjs/common'; -import { MessagePattern } from '@nestjs/microservices'; -import { OrganizationService } from './organization.service'; -import { CreateOrganizationDto } from '../dtos/create-organization.dto'; -import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; -import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; -import { IDidList, IGetOrgById, IGetOrganization, IOrgDetails, IUpdateOrganization, Payload } from '../interfaces/organization.interface'; -import { IOrgCredentials, IOrganizationInvitations, IOrganization, IOrganizationDashboard, IDeleteOrganization, IOrgActivityCount } from '@credebl/common/interfaces/organization.interface'; -import { organisation, user } from '@prisma/client'; -import { IAccessTokenData } from '@credebl/common/interfaces/interface'; -import { IClientRoles } from '@credebl/client-registration/interfaces/client.interface'; -import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; +import type { IClientRoles } from '@credebl/client-registration/interfaces/client.interface' +import type { IAccessTokenData } from '@credebl/common/interfaces/interface' +import type { + IDeleteOrganization, + IOrgActivityCount, + IOrgCredentials, + IOrganization, + IOrganizationDashboard, + IOrganizationInvitations, +} from '@credebl/common/interfaces/organization.interface' +import { Body, Controller, Logger } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { organisation, user } from '@prisma/client' +import type { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface' +import type { CreateOrganizationDto } from '../dtos/create-organization.dto' +import type { BulkSendInvitationDto } from '../dtos/send-invitation.dto' +import type { UpdateInvitationDto } from '../dtos/update-invitation.dt' +import type { + IDidList, + IGetOrgById, + IGetOrganization, + IOrgDetails, + IUpdateOrganization, + Payload, +} from '../interfaces/organization.interface' +import type { OrganizationService } from './organization.service' @Controller() export class OrganizationController { constructor(private readonly organizationService: OrganizationService) {} - private readonly logger = new Logger('OrganizationController'); + private readonly logger = new Logger('OrganizationController') /** * Description: create new organization @@ -23,8 +37,10 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'create-organization' }) - async createOrganization(@Body() payload: { createOrgDto: CreateOrganizationDto; userId: string, keycloakUserId: string }): Promise { - return this.organizationService.createOrganization(payload.createOrgDto, payload.userId, payload.keycloakUserId); + async createOrganization( + @Body() payload: { createOrgDto: CreateOrganizationDto; userId: string; keycloakUserId: string } + ): Promise { + return this.organizationService.createOrganization(payload.createOrgDto, payload.userId, payload.keycloakUserId) } /** @@ -34,18 +50,20 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'set-primary-did' }) - async setPrimaryDid(@Body() payload: { orgId:string, did:string, id:string}): Promise { - return this.organizationService.setPrimaryDid(payload.orgId, payload.did, payload.id); + async setPrimaryDid(@Body() payload: { orgId: string; did: string; id: string }): Promise { + return this.organizationService.setPrimaryDid(payload.orgId, payload.did, payload.id) } /** - * - * @param payload + * + * @param payload * @returns organization client credentials */ @MessagePattern({ cmd: 'create-org-credentials' }) - async createOrgCredentials(@Body() payload: { orgId: string; userId: string, keycloakUserId: string }): Promise { - return this.organizationService.createOrgCredentials(payload.orgId, payload.userId, payload.keycloakUserId); + async createOrgCredentials( + @Body() payload: { orgId: string; userId: string; keycloakUserId: string } + ): Promise { + return this.organizationService.createOrgCredentials(payload.orgId, payload.userId, payload.keycloakUserId) } /** @@ -55,8 +73,12 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'update-organization' }) - async updateOrganization(payload: { updateOrgDto: IUpdateOrganization; userId: string, orgId: string }): Promise { - return this.organizationService.updateOrganization(payload.updateOrgDto, payload.userId, payload.orgId); + async updateOrganization(payload: { + updateOrgDto: IUpdateOrganization + userId: string + orgId: string + }): Promise { + return this.organizationService.updateOrganization(payload.updateOrgDto, payload.userId, payload.orgId) } /** @@ -65,8 +87,8 @@ export class OrganizationController { * @returns organization's did list */ @MessagePattern({ cmd: 'fetch-organization-dids' }) - async getOrgDidList(payload: {orgId:string}): Promise { - return this.organizationService.getOrgDidList(payload.orgId); + async getOrgDidList(payload: { orgId: string }): Promise { + return this.organizationService.getOrgDidList(payload.orgId) } /** @@ -75,11 +97,9 @@ export class OrganizationController { * @returns Get created organization details */ @MessagePattern({ cmd: 'get-organizations' }) - async getOrganizations( - @Body() payload: { userId: string} & Payload - ): Promise { - const { userId, pageNumber, pageSize, search, role } = payload; - return this.organizationService.getOrganizations(userId, pageNumber, pageSize, search, role); + async getOrganizations(@Body() payload: { userId: string } & Payload): Promise { + const { userId, pageNumber, pageSize, search, role } = payload + return this.organizationService.getOrganizations(userId, pageNumber, pageSize, search, role) } /** * Description: get organization count @@ -87,24 +107,19 @@ export class OrganizationController { * @returns Get created organization details */ @MessagePattern({ cmd: 'get-organizations-count' }) - async countTotalOrgs( - @Body() payload: { userId: string} - ): Promise { - - const { userId } = payload; - - return this.organizationService.countTotalOrgs(userId); + async countTotalOrgs(@Body() payload: { userId: string }): Promise { + const { userId } = payload + + return this.organizationService.countTotalOrgs(userId) } /** * @returns Get public organization details */ @MessagePattern({ cmd: 'get-public-organizations' }) - async getPublicOrganizations( - @Body() payload: Payload - ): Promise { - const { pageNumber, pageSize, search } = payload; - return this.organizationService.getPublicOrganizations(pageNumber, pageSize, search); + async getPublicOrganizations(@Body() payload: Payload): Promise { + const { pageNumber, pageSize, search } = payload + return this.organizationService.getPublicOrganizations(pageNumber, pageSize, search) } /** @@ -113,16 +128,16 @@ export class OrganizationController { * @returns Get created organization details */ @MessagePattern({ cmd: 'get-organization-by-id' }) - async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise { - return this.organizationService.getOrganization(payload.orgId); + async getOrganization(@Body() payload: { orgId: string; userId: string }): Promise { + return this.organizationService.getOrganization(payload.orgId) } -/** - * @param orgSlug - * @returns organization details - */ + /** + * @param orgSlug + * @returns organization details + */ @MessagePattern({ cmd: 'get-organization-public-profile' }) async getPublicProfile(payload: { orgSlug }): Promise { - return this.organizationService.getPublicProfile(payload); + return this.organizationService.getPublicProfile(payload) } /** @@ -131,29 +146,27 @@ export class OrganizationController { * @returns Get created invitation details */ @MessagePattern({ cmd: 'get-invitations-by-orgId' }) - async getInvitationsByOrgId( - @Body() payload: { orgId: string } & Payload - ): Promise { + async getInvitationsByOrgId(@Body() payload: { orgId: string } & Payload): Promise { return this.organizationService.getInvitationsByOrgId( payload.orgId, payload.pageNumber, payload.pageSize, payload.search - ); + ) } /** - * @returns Get org-roles + * @returns Get org-roles */ @MessagePattern({ cmd: 'get-org-roles' }) - async getOrgRoles(payload: {orgId: string, user: user}): Promise { - return this.organizationService.getOrgRoles(payload.orgId, payload.user); + async getOrgRoles(payload: { orgId: string; user: user }): Promise { + return this.organizationService.getOrgRoles(payload.orgId, payload.user) } @MessagePattern({ cmd: 'register-orgs-users-map' }) async registerOrgsMapUsers(): Promise { - return this.organizationService.registerOrgsMapUsers(); + return this.organizationService.registerOrgsMapUsers() } /** @@ -163,9 +176,9 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'send-invitation' }) async createInvitation( - @Body() payload: { bulkInvitationDto: BulkSendInvitationDto; userId: string, userEmail: string } + @Body() payload: { bulkInvitationDto: BulkSendInvitationDto; userId: string; userEmail: string } ): Promise { - return this.organizationService.createInvitation(payload.bulkInvitationDto, payload.userId, payload.userEmail); + return this.organizationService.createInvitation(payload.bulkInvitationDto, payload.userId, payload.userEmail) } @MessagePattern({ cmd: 'fetch-user-invitations' }) @@ -178,7 +191,7 @@ export class OrganizationController { payload.pageNumber, payload.pageSize, payload.search - ); + ) } /** @@ -188,7 +201,7 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'update-invitation-status' }) async updateOrgInvitation(@Body() payload: UpdateInvitationDto): Promise { - return this.organizationService.updateOrgInvitation(payload); + return this.organizationService.updateOrgInvitation(payload) } /** @@ -198,95 +211,95 @@ export class OrganizationController { */ @MessagePattern({ cmd: 'update-user-roles' }) - async updateUserRoles(payload: { orgId: string; roleIds: string[]; userId: string}): Promise { - return this.organizationService.updateUserRoles(payload.orgId, payload.roleIds, payload.userId); + async updateUserRoles(payload: { orgId: string; roleIds: string[]; userId: string }): Promise { + return this.organizationService.updateUserRoles(payload.orgId, payload.roleIds, payload.userId) } @MessagePattern({ cmd: 'get-organization-dashboard' }) async getOrgDashboard(payload: { orgId: string; userId: string }): Promise { - return this.organizationService.getOrgDashboard(payload.orgId); + return this.organizationService.getOrgDashboard(payload.orgId) } @MessagePattern({ cmd: 'get-organization-activity-count' }) async getOrganizationActivityCount(payload: { orgId: string; userId: string }): Promise { - return this.organizationService.getOrganizationActivityCount(payload.orgId, payload.userId); + return this.organizationService.getOrganizationActivityCount(payload.orgId, payload.userId) } -/** - * @returns organization profile details - */ + /** + * @returns organization profile details + */ @MessagePattern({ cmd: 'fetch-organization-profile' }) async getOrgPofile(payload: { orgId: string }): Promise { - return this.organizationService.getOrgPofile(payload.orgId); + return this.organizationService.getOrgPofile(payload.orgId) } @MessagePattern({ cmd: 'get-organization-owner' }) async getOrgOwner(orgId: string): Promise { - return this.organizationService.getOrgOwner(orgId); + return this.organizationService.getOrgOwner(orgId) } @MessagePattern({ cmd: 'fetch-org-client-credentials' }) async fetchOrgCredentials(payload: { orgId: string }): Promise { - return this.organizationService.fetchOrgCredentials(payload.orgId); + return this.organizationService.fetchOrgCredentials(payload.orgId) } @MessagePattern({ cmd: 'get-organization-details' }) - async getOrgData(payload: { orgId: string; }): Promise { - return this.organizationService.getOrgDetails(payload.orgId); + async getOrgData(payload: { orgId: string }): Promise { + return this.organizationService.getOrgDetails(payload.orgId) } - + @MessagePattern({ cmd: 'delete-organization' }) - async deleteOrganization(payload: { orgId: string, user: user }): Promise { - return this.organizationService.deleteOrganization(payload.orgId, payload.user); + async deleteOrganization(payload: { orgId: string; user: user }): Promise { + return this.organizationService.deleteOrganization(payload.orgId, payload.user) } @MessagePattern({ cmd: 'delete-org-client-credentials' }) - async deleteOrganizationCredentials(payload: { orgId: string, user: user }): Promise { - return this.organizationService.deleteClientCredentials(payload.orgId, payload.user); + async deleteOrganizationCredentials(payload: { orgId: string; user: user }): Promise { + return this.organizationService.deleteClientCredentials(payload.orgId, payload.user) } @MessagePattern({ cmd: 'delete-organization-invitation' }) - async deleteOrganizationInvitation(payload: { orgId: string; invitationId: string; }): Promise { - return this.organizationService.deleteOrganizationInvitation(payload.orgId, payload.invitationId); + async deleteOrganizationInvitation(payload: { orgId: string; invitationId: string }): Promise { + return this.organizationService.deleteOrganizationInvitation(payload.orgId, payload.invitationId) } @MessagePattern({ cmd: 'authenticate-client-credentials' }) - async clientLoginCredentails(payload: { clientId: string; clientSecret: string;}): Promise { - return this.organizationService.clientLoginCredentails(payload); + async clientLoginCredentails(payload: { clientId: string; clientSecret: string }): Promise { + return this.organizationService.clientLoginCredentails(payload) } @MessagePattern({ cmd: 'get-platform-config-details' }) async getPlatformConfigDetails(): Promise { - return this.organizationService.getPlatformConfigDetails(); + return this.organizationService.getPlatformConfigDetails() } @MessagePattern({ cmd: 'get-agent-type-by-org-agent-type-id' }) - async getAgentTypeByAgentTypeId(payload: {orgAgentTypeId: string}): Promise { - return this.organizationService.getAgentTypeByAgentTypeId(payload.orgAgentTypeId); + async getAgentTypeByAgentTypeId(payload: { orgAgentTypeId: string }): Promise { + return this.organizationService.getAgentTypeByAgentTypeId(payload.orgAgentTypeId) } @MessagePattern({ cmd: 'get-org-roles-details' }) - async getOrgRolesDetails(payload: {roleName: string}): Promise { - return this.organizationService.getOrgRolesDetails(payload.roleName); + async getOrgRolesDetails(payload: { roleName: string }): Promise { + return this.organizationService.getOrgRolesDetails(payload.roleName) } @MessagePattern({ cmd: 'get-all-org-roles-details' }) async getAllOrgRoles(): Promise { - return this.organizationService.getAllOrgRoles(); + return this.organizationService.getAllOrgRoles() } @MessagePattern({ cmd: 'get-org-roles-by-id' }) async getOrgRolesDetailsByIds(orgRoles: string[]): Promise { - return this.organizationService.getOrgRolesDetailsByIds(orgRoles); + return this.organizationService.getOrgRolesDetailsByIds(orgRoles) } @MessagePattern({ cmd: 'get-organization-by-org-id' }) async getOrganisationsByIds(payload: { organisationIds }): Promise { - return this.organizationService.getOrganisationsByIds(payload.organisationIds); + return this.organizationService.getOrganisationsByIds(payload.organisationIds) } @MessagePattern({ cmd: 'get-org-agents-and-user-roles' }) - async getOrgAgentDetailsForEcosystem(payload: {orgIds: string[], search: string}): Promise { - return this.organizationService.getOrgAgentDetailsForEcosystem(payload); + async getOrgAgentDetailsForEcosystem(payload: { orgIds: string[]; search: string }): Promise { + return this.organizationService.getOrgAgentDetailsForEcosystem(payload) } -} \ No newline at end of file +} diff --git a/apps/organization/src/organization.module.ts b/apps/organization/src/organization.module.ts index 37ad1c270..d0a1dcda5 100644 --- a/apps/organization/src/organization.module.ts +++ b/apps/organization/src/organization.module.ts @@ -1,54 +1,64 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Logger, Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' -import { CommonModule } from '@credebl/common'; -import { OrgRolesRepository } from 'libs/org-roles/repositories'; -import { OrgRolesService } from '@credebl/org-roles'; -import { OrganizationController } from './organization.controller'; -import { OrganizationRepository } from '../repositories/organization.repository'; -import { OrganizationService } from './organization.service'; -import { PrismaService } from '@credebl/prisma-service'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -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'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { ClientRegistrationService } from '@credebl/client-registration'; -import { KeycloakUrlService } from '@credebl/keycloak-url'; +import { ClientRegistrationService } from '@credebl/client-registration' +import { CommonModule } from '@credebl/common' +import { getNatsOptions } from '@credebl/common/nats.config' +import { KeycloakUrlService } from '@credebl/keycloak-url' +import { OrgRolesService } from '@credebl/org-roles' +import { PrismaService } from '@credebl/prisma-service' +import { UserActivityService } from '@credebl/user-activity' +import { UserOrgRolesService } from '@credebl/user-org-roles' +import { CacheModule } from '@nestjs/cache-manager' +import { UserRepository } from 'apps/user/repositories/user.repository' +import { OrgRolesRepository } from 'libs/org-roles/repositories' +import { UserActivityRepository } from 'libs/user-activity/repositories' +import { UserOrgRolesRepository } from 'libs/user-org-roles/repositories' +import { OrganizationRepository } from '../repositories/organization.repository' +import { OrganizationController } from './organization.controller' +import { OrganizationService } from './organization.service' -import { AwsService } from '@credebl/aws'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' @Module({ imports: [ ClientsModule.register([ { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.ORGANIZATION_SERVICE, process.env.ORGANIZATION_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.ORGANIZATION_SERVICE, process.env.ORGANIZATION_NKEY_SEED), + }, ]), CommonModule, GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, - CacheModule.register() + LoggerModule, + PlatformConfig, + ContextInterceptorModule, + CacheModule.register(), ], controllers: [OrganizationController], providers: [ - OrganizationService, OrganizationRepository, PrismaService, - Logger, OrgRolesService, UserOrgRolesService, OrgRolesRepository, UserActivityRepository, - UserActivityRepository, UserOrgRolesRepository, UserRepository, UserActivityService, - ClientRegistrationService, - KeycloakUrlService, - AwsService, - NATSClient - ] - + OrganizationService, + OrganizationRepository, + PrismaService, + Logger, + OrgRolesService, + UserOrgRolesService, + OrgRolesRepository, + UserActivityRepository, + UserActivityRepository, + UserOrgRolesRepository, + UserRepository, + UserActivityService, + ClientRegistrationService, + KeycloakUrlService, + AwsService, + NATSClient, + ], }) export class OrganizationModule {} diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index edf05c322..01543eec9 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -1,57 +1,68 @@ -/* eslint-disable prefer-destructuring */ -// eslint-disable-next-line camelcase -import { RecordType, org_invitations, organisation, user } from '@prisma/client'; +import type { AwsService } from '@credebl/aws' +import type { ClientRegistrationService } from '@credebl/client-registration/client-registration.service' +import type { CommonService } from '@credebl/common' +import { EmailDto } from '@credebl/common/dtos/email.dto' +import type { + IDeleteOrganization, + IOrgActivityCount, + IOrgCredentials, + IOrganization, + IOrganizationDashboard, + IOrganizationInvitations, +} from '@credebl/common/interfaces/organization.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { sendEmail } from '@credebl/common/send-grid-helper-file' +import { DidMethod, Invitation, Ledgers, PrismaTables, transition } from '@credebl/enum/enum' +import type { OrgRolesService } from '@credebl/org-roles' +import type { PrismaService } from '@credebl/prisma-service' +import type { UserActivityService } from '@credebl/user-activity' +import type { UserOrgRolesService } from '@credebl/user-org-roles' +import { CACHE_MANAGER } from '@nestjs/cache-manager' import { - Injectable, - Logger, - ConflictException, - InternalServerErrorException, - HttpException, BadRequestException, + ConflictException, ForbiddenException, - UnauthorizedException, + HttpException, + Inject, + Injectable, + InternalServerErrorException, + type Logger, NotFoundException, - Inject -} from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { CommonService } from '@credebl/common'; -import { OrganizationRepository } from '../repositories/organization.repository'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { OrgRolesService } from '@credebl/org-roles'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { UserOrgRolesService } from '@credebl/user-org-roles'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { OrganizationInviteTemplate } from '../templates/organization-invitation.template'; -import { EmailDto } from '@credebl/common/dtos/email.dto'; -import { sendEmail } from '@credebl/common/send-grid-helper-file'; -import { CreateOrganizationDto } from '../dtos/create-organization.dto'; -import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; -import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; -import { DidMethod, Invitation, Ledgers, PrismaTables, transition } from '@credebl/enum/enum'; -import { IGetOrgById, IGetOrganization, IUpdateOrganization, IClientCredentials, ICreateConnectionUrl, IOrgRole, IDidList, IPrimaryDidDetails, IEcosystemOrgStatus, IOrgDetails } from '../interfaces/organization.interface'; -import { UserActivityService } from '@credebl/user-activity'; -import { ClientRegistrationService } from '@credebl/client-registration/client-registration.service'; -import { map } from 'rxjs/operators'; -import { Cache } from 'cache-manager'; -import { AwsService } from '@credebl/aws'; -import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { - IOrgCredentials, - IOrganization, - IOrganizationInvitations, - IOrganizationDashboard, - IDeleteOrganization, - IOrgActivityCount -} from '@credebl/common/interfaces/organization.interface'; - -import { ClientCredentialTokenPayloadDto } from '@credebl/client-registration/dtos/client-credential-token-payload.dto'; -import { IAccessTokenData } from '@credebl/common/interfaces/interface'; -import { IClientRoles } from '@credebl/client-registration/interfaces/client.interface'; -import { toNumber } from '@credebl/common/cast.helper'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { DeleteOrgInvitationsEmail } from '../templates/delete-organization-invitations.template'; -import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; -import { NATSClient } from '@credebl/common/NATSClient'; + UnauthorizedException, +} from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +/* eslint-disable prefer-destructuring */ +// eslint-disable-next-line camelcase +import { RecordType, type org_invitations, type organisation, type user } from '@prisma/client' +import type { Cache } from 'cache-manager' +import { OrgRoles } from 'libs/org-roles/enums' +import { map } from 'rxjs/operators' +import type { CreateOrganizationDto } from '../dtos/create-organization.dto' +import type { BulkSendInvitationDto } from '../dtos/send-invitation.dto' +import type { UpdateInvitationDto } from '../dtos/update-invitation.dt' +import type { + IClientCredentials, + ICreateConnectionUrl, + IDidList, + IEcosystemOrgStatus, + IGetOrgById, + IGetOrganization, + IOrgDetails, + IOrgRole, + IPrimaryDidDetails, + IUpdateOrganization, +} from '../interfaces/organization.interface' +import type { OrganizationRepository } from '../repositories/organization.repository' +import { OrganizationInviteTemplate } from '../templates/organization-invitation.template' + +import { ClientCredentialTokenPayloadDto } from '@credebl/client-registration/dtos/client-credential-token-payload.dto' +import type { IClientRoles } from '@credebl/client-registration/interfaces/client.interface' +import type { NATSClient } from '@credebl/common/NATSClient' +import { toNumber } from '@credebl/common/cast.helper' +import type { IAccessTokenData } from '@credebl/common/interfaces/interface' +import type { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface' +import type { UserActivityRepository } from 'libs/user-activity/repositories' +import { DeleteOrgInvitationsEmail } from '../templates/delete-organization-invitations.template' @Injectable() export class OrganizationService { constructor( @@ -67,19 +78,19 @@ export class OrganizationService { @Inject(CACHE_MANAGER) private cacheService: Cache, private readonly clientRegistrationService: ClientRegistrationService, private readonly userActivityRepository: UserActivityRepository, - private readonly natsClient : NATSClient + private readonly natsClient: NATSClient ) {} - + async getPlatformConfigDetails(): Promise { try { - const getPlatformDetails = await this.organizationRepository.getPlatformConfigDetails(); - return getPlatformDetails; + const getPlatformDetails = await this.organizationRepository.getPlatformConfigDetails() + return getPlatformDetails } catch (error) { - this.logger.error(`In fetch getPlatformConfigDetails : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In fetch getPlatformConfigDetails : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - + /** * * @param registerOrgDto @@ -93,45 +104,44 @@ export class OrganizationService { keycloakUserId: string ): Promise { try { - const userOrgCount = await this.organizationRepository.userOrganizationCount(userId); - + const userOrgCount = await this.organizationRepository.userOrganizationCount(userId) + if (userOrgCount >= toNumber(`${process.env.MAX_ORG_LIMIT}`)) { - throw new BadRequestException(ResponseMessages.organisation.error.MaximumOrgsLimit); + throw new BadRequestException(ResponseMessages.organisation.error.MaximumOrgsLimit) } - const organizationExist = await this.organizationRepository.checkOrganizationNameExist(createOrgDto.name); + const organizationExist = await this.organizationRepository.checkOrganizationNameExist(createOrgDto.name) if (organizationExist) { - throw new ConflictException(ResponseMessages.organisation.error.exists); + throw new ConflictException(ResponseMessages.organisation.error.exists) } - const orgSlug = this.createOrgSlug(createOrgDto.name); + const orgSlug = this.createOrgSlug(createOrgDto.name) - const isOrgSlugExist = await this.organizationRepository.checkOrganizationSlugExist(orgSlug); + const isOrgSlugExist = await this.organizationRepository.checkOrganizationSlugExist(orgSlug) if (isOrgSlugExist) { - throw new ConflictException(ResponseMessages.organisation.error.exists); - } + throw new ConflictException(ResponseMessages.organisation.error.exists) + } - createOrgDto.orgSlug = orgSlug; - createOrgDto.createdBy = userId; - createOrgDto.lastChangedBy = userId; + createOrgDto.orgSlug = orgSlug + createOrgDto.createdBy = userId + createOrgDto.lastChangedBy = userId if (await this.isValidBase64(createOrgDto?.logo)) { - const imageUrl = await this.uploadFileToS3(createOrgDto.logo); - createOrgDto.logo = imageUrl; + const imageUrl = await this.uploadFileToS3(createOrgDto.logo) + createOrgDto.logo = imageUrl } else { - createOrgDto.logo = ''; + createOrgDto.logo = '' } - - const organizationDetails = await this.organizationRepository.createOrganization(createOrgDto); + const organizationDetails = await this.organizationRepository.createOrganization(createOrgDto) // To return selective object data - delete organizationDetails.lastChangedBy; - delete organizationDetails.lastChangedDateTime; - delete organizationDetails.orgSlug; - delete organizationDetails.website; + organizationDetails.lastChangedBy = undefined + organizationDetails.lastChangedDateTime = undefined + organizationDetails.orgSlug = undefined + organizationDetails.website = undefined try { const orgCredentials = await this.registerToKeycloak( @@ -140,30 +150,30 @@ export class OrganizationService { keycloakUserId, userId, false - ); + ) - const { clientId, idpId } = orgCredentials; + const { clientId, idpId } = orgCredentials const updateOrgData = { clientId, - idpId - }; - + idpId, + } + const updatedOrg = await this.organizationRepository.updateOrganizationById( updateOrgData, organizationDetails.id - ); - + ) + if (!updatedOrg) { - throw new InternalServerErrorException(ResponseMessages.organisation.error.credentialsNotUpdate); + throw new InternalServerErrorException(ResponseMessages.organisation.error.credentialsNotUpdate) } } catch (error) { - this.logger.error(`Error In creating client : ${JSON.stringify(error)}`); - throw new InternalServerErrorException('Unable to create client'); + this.logger.error(`Error In creating client : ${JSON.stringify(error)}`) + throw new InternalServerErrorException('Unable to create client') } if (createOrgDto.notificationWebhook) { - await this.storeOrgWebhookEndpoint(organizationDetails.id, createOrgDto.notificationWebhook); + await this.storeOrgWebhookEndpoint(organizationDetails.id, createOrgDto.notificationWebhook) } await this.userActivityService.createActivity( @@ -171,84 +181,80 @@ export class OrganizationService { organizationDetails.id, `${organizationDetails.name} organization created`, 'Get started with inviting users to join organization' - ); + ) - return organizationDetails; + return organizationDetails } catch (error) { - this.logger.error(`In create organization : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In create organization : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - /** + /** * * @param registerOrgDto * @returns */ // eslint-disable-next-line camelcase - async setPrimaryDid( - orgId:string, - did:string, - id:string - ): Promise { + async setPrimaryDid(orgId: string, did: string, id: string): Promise { try { - const organizationExist = await this.organizationRepository.getOrgProfile(orgId); + const organizationExist = await this.organizationRepository.getOrgProfile(orgId) if (!organizationExist) { - throw new NotFoundException(ResponseMessages.organisation.error.notFound); + throw new NotFoundException(ResponseMessages.organisation.error.notFound) } - const orgAgentDetails = await this.organizationRepository.getAgentEndPoint(orgId); + const orgAgentDetails = await this.organizationRepository.getAgentEndPoint(orgId) if (orgAgentDetails.orgDid === did) { - throw new ConflictException(ResponseMessages.organisation.error.primaryDid); + throw new ConflictException(ResponseMessages.organisation.error.primaryDid) } //check user DID exist in the organization's did list - const organizationDidList = await this.organizationRepository.getAllOrganizationDid(orgId); - const isDidMatch = organizationDidList.some(item => item.did === did); + const organizationDidList = await this.organizationRepository.getAllOrganizationDid(orgId) + const isDidMatch = organizationDidList.some((item) => item.did === did) if (!isDidMatch) { - throw new NotFoundException(ResponseMessages.organisation.error.didNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.didNotFound) } - const didDetails = await this.organizationRepository.getDidDetailsByDid(did); + const didDetails = await this.organizationRepository.getDidDetailsByDid(did) if (!didDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.didNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.didNotFound) } - - const dids = await this.organizationRepository.getDids(orgId); - const noPrimaryDid = dids.every(orgDids => false === orgDids.isPrimaryDid); - let existingPrimaryDid; - let priviousDidFalse; + const dids = await this.organizationRepository.getDids(orgId) + const noPrimaryDid = dids.every((orgDids) => orgDids.isPrimaryDid === false) + + let existingPrimaryDid + let priviousDidFalse if (!noPrimaryDid) { - existingPrimaryDid = await this.organizationRepository.getPerviousPrimaryDid(orgId); - + existingPrimaryDid = await this.organizationRepository.getPerviousPrimaryDid(orgId) + if (!existingPrimaryDid) { - throw new NotFoundException(ResponseMessages.organisation.error.didNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.didNotFound) } - - priviousDidFalse = await this.organizationRepository.setPreviousDidFlase(existingPrimaryDid.id); - } - const didParts = did.split(':'); - let nameSpace: string | null = null; - + priviousDidFalse = await this.organizationRepository.setPreviousDidFlase(existingPrimaryDid.id) + } + + const didParts = did.split(':') + let nameSpace: string | null = null + // This condition will handle the multi-ledger support if (DidMethod.INDY === didParts[1]) { - nameSpace = `${didParts[2]}:${didParts[3]}`; + nameSpace = `${didParts[2]}:${didParts[3]}` } else if (DidMethod.POLYGON === didParts[1]) { - nameSpace = `${didParts[1]}:${didParts[2]}`; + nameSpace = `${didParts[1]}:${didParts[2]}` } else { - nameSpace = null; + nameSpace = null } - let network; - if (null !== nameSpace) { - network = await this.organizationRepository.getNetworkByNameSpace(nameSpace); + let network + if (nameSpace !== null) { + network = await this.organizationRepository.getNetworkByNameSpace(nameSpace) } else { - network = await this.organizationRepository.getLedger(Ledgers.Not_Applicable); + network = await this.organizationRepository.getLedger(Ledgers.Not_Applicable) if (!network) { - throw new NotFoundException(ResponseMessages.agent.error.noLedgerFound); + throw new NotFoundException(ResponseMessages.agent.error.noLedgerFound) } } @@ -257,19 +263,17 @@ export class OrganizationService { orgId, id, didDocument: didDetails.didDocument, - networkId: network?.id ?? null - }; - - const setPrimaryDid = await this.organizationRepository.setOrgsPrimaryDid(primaryDidDetails); + networkId: network?.id ?? null, + } - await Promise.all([setPrimaryDid, existingPrimaryDid, priviousDidFalse]); + const setPrimaryDid = await this.organizationRepository.setOrgsPrimaryDid(primaryDidDetails) + await Promise.all([setPrimaryDid, existingPrimaryDid, priviousDidFalse]) - return ResponseMessages.organisation.success.primaryDid; - + return ResponseMessages.organisation.success.primaryDid } catch (error) { - this.logger.error(`In setPrimaryDid method: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In setPrimaryDid method: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -280,30 +284,31 @@ export class OrganizationService { */ async createOrgCredentials(orgId: string, userId: string, keycloakUserId: string): Promise { try { - const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId); + const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId) if (!organizationDetails) { - throw new ConflictException(ResponseMessages.organisation.error.orgNotFound); + throw new ConflictException(ResponseMessages.organisation.error.orgNotFound) } - let updateOrgData = {}; - let generatedClientSecret = ''; + let updateOrgData = {} + let generatedClientSecret = '' if (organizationDetails.idpId) { - - const userDetails = await this.organizationRepository.getUser(userId); - const token = await this.clientRegistrationService.getManagementToken(userDetails.clientId, userDetails.clientSecret); + const userDetails = await this.organizationRepository.getUser(userId) + const token = await this.clientRegistrationService.getManagementToken( + userDetails.clientId, + userDetails.clientSecret + ) generatedClientSecret = await this.clientRegistrationService.generateClientSecret( organizationDetails.idpId, token - ); + ) updateOrgData = { - clientSecret: this.maskString(generatedClientSecret) - }; + clientSecret: this.maskString(generatedClientSecret), + } } else { - try { const orgCredentials = await this.registerToKeycloak( organizationDetails.name, @@ -311,37 +316,37 @@ export class OrganizationService { keycloakUserId, userId, true - ); - - const { clientId, idpId, clientSecret } = orgCredentials; - - generatedClientSecret = clientSecret; - + ) + + const { clientId, idpId, clientSecret } = orgCredentials + + generatedClientSecret = clientSecret + updateOrgData = { clientId, clientSecret: this.maskString(clientSecret), - idpId - }; + idpId, + } } catch (error) { - this.logger.error(`Error In creating client : ${JSON.stringify(error)}`); - throw new InternalServerErrorException('Unable to create client'); + this.logger.error(`Error In creating client : ${JSON.stringify(error)}`) + throw new InternalServerErrorException('Unable to create client') } } - const updatedOrg = await this.organizationRepository.updateOrganizationById(updateOrgData, orgId); + const updatedOrg = await this.organizationRepository.updateOrganizationById(updateOrgData, orgId) if (!updatedOrg) { - throw new InternalServerErrorException(ResponseMessages.organisation.error.credentialsNotUpdate); + throw new InternalServerErrorException(ResponseMessages.organisation.error.credentialsNotUpdate) } return { idpId: updatedOrg.idpId, clientId: updatedOrg.clientId, - clientSecret: generatedClientSecret - }; + clientSecret: generatedClientSecret, + } } catch (error) { - this.logger.error(`In createOrgCredentials : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In createOrgCredentials : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -358,80 +363,81 @@ export class OrganizationService { userId: string, shouldUpdateRole: boolean ): Promise { - const userDetails = await this.organizationRepository.getUser(userId); - const token = await this.clientRegistrationService.getManagementToken(userDetails.clientId, userDetails.clientSecret); - const orgDetails = await this.clientRegistrationService.createClient(orgName, orgId, token); + const userDetails = await this.organizationRepository.getUser(userId) + const token = await this.clientRegistrationService.getManagementToken( + userDetails.clientId, + userDetails.clientSecret + ) + const orgDetails = await this.clientRegistrationService.createClient(orgName, orgId, token) - const orgRolesList = [OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER]; + const orgRolesList = [OrgRoles.OWNER, OrgRoles.ADMIN, OrgRoles.ISSUER, OrgRoles.VERIFIER, OrgRoles.MEMBER] - for (const role of orgRolesList) { - await this.clientRegistrationService.createClientRole(orgDetails.idpId, token, role, role); - } + for (const role of orgRolesList) { + await this.clientRegistrationService.createClientRole(orgDetails.idpId, token, role, role) + } const ownerRoleClient = await this.clientRegistrationService.getClientSpecificRoles( orgDetails.idpId, token, OrgRoles.OWNER - ); + ) const payload = [ { id: ownerRoleClient.id, - name: ownerRoleClient.name - } - ]; + name: ownerRoleClient.name, + }, + ] - const ownerRoleData = await this.orgRoleService.getRole(OrgRoles.OWNER); + const ownerRoleData = await this.orgRoleService.getRole(OrgRoles.OWNER) if (!shouldUpdateRole) { - await Promise.all([ this.clientRegistrationService.createUserClientRole(orgDetails.idpId, token, keycloakUserId, payload), - this.userOrgRoleService.createUserOrgRole(userId, ownerRoleData.id, orgId, ownerRoleClient.id) - ]); - + this.userOrgRoleService.createUserOrgRole(userId, ownerRoleData.id, orgId, ownerRoleClient.id), + ]) } else { const roleIdList = [ { roleId: ownerRoleData.id, - idpRoleId: ownerRoleClient.id - } - ]; - + idpRoleId: ownerRoleClient.id, + }, + ] + await Promise.all([ this.clientRegistrationService.createUserClientRole(orgDetails.idpId, token, keycloakUserId, payload), this.userOrgRoleService.deleteOrgRoles(userId, orgId), - this.userOrgRoleService.updateUserOrgRole(userId, orgId, roleIdList) - ]); + this.userOrgRoleService.updateUserOrgRole(userId, orgId, roleIdList), + ]) } - return orgDetails; + return orgDetails } async deleteClientCredentials(orgId: string, user: user): Promise { - const getUser = await this.organizationRepository.getUser(user?.id); - const token = await this.clientRegistrationService.getManagementToken(getUser.clientId, getUser.clientSecret); + const getUser = await this.organizationRepository.getUser(user?.id) + const token = await this.clientRegistrationService.getManagementToken(getUser.clientId, getUser.clientSecret) - const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId); + const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId) if (!organizationDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound) } try { - await this.clientRegistrationService.deleteClient(organizationDetails.idpId, token); + await this.clientRegistrationService.deleteClient(organizationDetails.idpId, token) const updateOrgData = { clientId: null, clientSecret: null, - idpId: null - }; + idpId: null, + } - await this.organizationRepository.updateOrganizationById(updateOrgData, orgId); - } catch (error) { - throw new InternalServerErrorException('Unable to delete client credentails'); + await this.organizationRepository.updateOrganizationById(updateOrgData, orgId) + } catch (_error) { + throw new InternalServerErrorException('Unable to delete client credentails') } - return ResponseMessages.organisation.success.deleteCredentials; + return ResponseMessages.organisation.success.deleteCredentials } /** @@ -440,38 +446,38 @@ export class OrganizationService { * @returns */ maskString(inputString: string): string { - if (5 <= inputString.length) { + if (inputString.length >= 5) { // Extract the last 5 characters - const lastFiveCharacters = inputString.slice(-8); + const lastFiveCharacters = inputString.slice(-8) // Create a masked string with '*' characters - const maskedString = '*'.repeat(inputString.length - 8) + lastFiveCharacters; + const maskedString = '*'.repeat(inputString.length - 8) + lastFiveCharacters - return maskedString; + return maskedString } else { // If the inputString is less than 5 characters, return the original string - return inputString; + return inputString } } async isValidBase64(value: string): Promise { try { - if (!value || 'string' !== typeof value) { - return false; + if (!value || typeof value !== 'string') { + return false } - const base64Regex = /^data:image\/([a-zA-Z]*);base64,([^\"]*)$/; - const matches = value.match(base64Regex); - return Boolean(matches) && 3 === matches.length; - } catch (error) { - return false; + const base64Regex = /^data:image\/([a-zA-Z]*);base64,([^\"]*)$/ + const matches = value.match(base64Regex) + return Boolean(matches) && matches.length === 3 + } catch (_error) { + return false } } async uploadFileToS3(orgLogo: string): Promise { try { - const updatedOrglogo = orgLogo.split(',')[1]; - const imgData = Buffer.from(updatedOrglogo, 'base64'); + const updatedOrglogo = orgLogo.split(',')[1] + const imgData = Buffer.from(updatedOrglogo, 'base64') const logoUrl = await this.awsService.uploadFileToS3Bucket( imgData, 'png', @@ -479,11 +485,11 @@ export class OrganizationService { process.env.AWS_ORG_LOGO_BUCKET_NAME, 'base64', 'orgLogos' - ); - return logoUrl; + ) + return logoUrl } catch (error) { - this.logger.error(`In getting imageUrl : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In getting imageUrl : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -497,7 +503,7 @@ export class OrganizationService { .toLowerCase() // Convert the input to lowercase .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/[^a-z0-9-]/g, '') // Remove non-alphanumeric characters except hyphens - .replace(/--+/g, '-'); // Replace multiple consecutive hyphens with a single hyphen + .replace(/--+/g, '-') // Replace multiple consecutive hyphens with a single hyphen } /** @@ -509,91 +515,90 @@ export class OrganizationService { // eslint-disable-next-line camelcase async updateOrganization(updateOrgDto: IUpdateOrganization, userId: string, orgId: string): Promise { try { - - const organizationExist = await this.organizationRepository.checkOrganizationNameExist(updateOrgDto.name); + const organizationExist = await this.organizationRepository.checkOrganizationNameExist(updateOrgDto.name) if (organizationExist && organizationExist.id !== orgId) { - throw new ConflictException(ResponseMessages.organisation.error.exists); + throw new ConflictException(ResponseMessages.organisation.error.exists) } - const orgSlug = await this.createOrgSlug(updateOrgDto.name); - updateOrgDto.orgSlug = orgSlug; - updateOrgDto.userId = userId; + const orgSlug = await this.createOrgSlug(updateOrgDto.name) + updateOrgDto.orgSlug = orgSlug + updateOrgDto.userId = userId if (await this.isValidBase64(updateOrgDto.logo)) { - const imageUrl = await this.uploadFileToS3(updateOrgDto.logo); - updateOrgDto.logo = imageUrl; + const imageUrl = await this.uploadFileToS3(updateOrgDto.logo) + updateOrgDto.logo = imageUrl } else { - delete updateOrgDto.logo; + updateOrgDto.logo = undefined } - let organizationDetails; - const checkAgentIsExists = await this.organizationRepository.getAgentInvitationDetails(orgId); + let organizationDetails + const checkAgentIsExists = await this.organizationRepository.getAgentInvitationDetails(orgId) if (!checkAgentIsExists?.connectionInvitation && !checkAgentIsExists?.agentId) { - organizationDetails = await this.organizationRepository.updateOrganization(updateOrgDto); - } else if (organizationDetails?.logoUrl !== organizationExist?.logoUrl || organizationDetails?.name !== organizationExist?.name) { - const invitationData = await this._createConnection(updateOrgDto?.logo, updateOrgDto?.name, orgId); - await this.organizationRepository.updateConnectionInvitationDetails(orgId, invitationData?.connectionInvitation); + organizationDetails = await this.organizationRepository.updateOrganization(updateOrgDto) + } else if ( + organizationDetails?.logoUrl !== organizationExist?.logoUrl || + organizationDetails?.name !== organizationExist?.name + ) { + const invitationData = await this._createConnection(updateOrgDto?.logo, updateOrgDto?.name, orgId) + await this.organizationRepository.updateConnectionInvitationDetails(orgId, invitationData?.connectionInvitation) } - await this.userActivityService.createActivity(userId, organizationDetails.id, `${organizationDetails.name} organization updated`, 'Organization details updated successfully'); - return organizationDetails; + await this.userActivityService.createActivity( + userId, + organizationDetails.id, + `${organizationDetails.name} organization updated`, + 'Organization details updated successfully' + ) + return organizationDetails } catch (error) { - this.logger.error(`In update organization : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In update organization : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - async _createConnection( - orgName: string, - logoUrl: string, - orgId: string - ): Promise { - const pattern = { cmd: 'create-connection-invitation' }; + async _createConnection(orgName: string, logoUrl: string, orgId: string): Promise { + const pattern = { cmd: 'create-connection-invitation' } const payload = { createOutOfBandConnectionInvitation: { orgName, logoUrl, - orgId - } - }; + orgId, + }, + } const connectionInvitationData = await this.natsClient .send(this.organizationServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return connectionInvitationData; + return connectionInvitationData } - async countTotalOrgs( - userId: string - - ): Promise { + async countTotalOrgs(userId: string): Promise { try { - - const getOrgs = await this.organizationRepository.userOrganizationCount(userId); - return getOrgs; + const getOrgs = await this.organizationRepository.userOrganizationCount(userId) + return getOrgs } catch (error) { - this.logger.error(`In fetch getOrganizations : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In fetch getOrganizations : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - + /** * @returns Get created organizations details */ - + async getOrganizations( userId: string, pageNumber: number, @@ -604,18 +609,18 @@ export class OrganizationService { try { const query = { userOrgRoles: { - some: { userId } + some: { userId }, }, OR: [ { name: { contains: search, mode: 'insensitive' } }, - { description: { contains: search, mode: 'insensitive' } } - ] - }; - + { description: { contains: search, mode: 'insensitive' } }, + ], + } + const filterOptions = { - userId - }; - + userId, + } + const getOrgs = await this.organizationRepository.getOrganizations( query, filterOptions, @@ -623,93 +628,91 @@ export class OrganizationService { pageSize, role, userId - ); + ) + + const { organizations } = getOrgs - const { organizations } = getOrgs; - - if (0 === organizations?.length) { - throw new NotFoundException(ResponseMessages.organisation.error.organizationNotFound); + if (organizations?.length === 0) { + throw new NotFoundException(ResponseMessages.organisation.error.organizationNotFound) } - let orgIds; - let updatedOrgs; + let orgIds + let updatedOrgs + + if (process.env.IS_ECOSYSTEM_ENABLE === 'true') { + orgIds = organizations?.map((item) => item.id) + + const orgEcosystemDetails = await this._getOrgEcosystems(orgIds) - if ('true' === process.env.IS_ECOSYSTEM_ENABLE) { - orgIds = organizations?.map(item => item.id); - - const orgEcosystemDetails = await this._getOrgEcosystems(orgIds); - - updatedOrgs = getOrgs.organizations.map(org => { + updatedOrgs = getOrgs.organizations.map((org) => { const matchingEcosystems = orgEcosystemDetails - .filter(ecosystem => ecosystem.orgId === org.id) - .map(ecosystem => ({ ecosystemId: ecosystem.ecosystemId })); + .filter((ecosystem) => ecosystem.orgId === org.id) + .map((ecosystem) => ({ ecosystemId: ecosystem.ecosystemId })) return { ...org, - ecosystemOrgs: 0 < matchingEcosystems.length ? matchingEcosystems : [] - }; - }); + ecosystemOrgs: matchingEcosystems.length > 0 ? matchingEcosystems : [], + } + }) } else { - updatedOrgs = getOrgs?.organizations?.map(org => ({ - ...org - })); + updatedOrgs = getOrgs?.organizations?.map((org) => ({ + ...org, + })) } - + return { totalCount: getOrgs.totalCount, totalPages: getOrgs.totalPages, - organizations: updatedOrgs - }; + organizations: updatedOrgs, + } } catch (error) { - this.logger.error(`In fetch getOrganizations : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In fetch getOrganizations : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async _getOrgEcosystems(orgIds: string[]): Promise { - const pattern = { cmd: 'get-ecosystems-by-org' }; + const pattern = { cmd: 'get-ecosystems-by-org' } - const payload = { orgIds }; + const payload = { orgIds } const response = await this.organizationServiceProxy .send(pattern, payload) .toPromise() .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); - return response; + ) + }) + return response } async clientLoginCredentails(clientCredentials: IClientCredentials): Promise { - const {clientId, clientSecret} = clientCredentials; - return this.authenticateClientKeycloak(clientId, clientSecret); -} + const { clientId, clientSecret } = clientCredentials + return this.authenticateClientKeycloak(clientId, clientSecret) + } async authenticateClientKeycloak(clientId: string, clientSecret: string): Promise { - - try { - const payload = new ClientCredentialTokenPayloadDto(); - // eslint-disable-next-line camelcase - payload.client_id = clientId; - // eslint-disable-next-line camelcase - payload.client_secret = clientSecret; - try { - const mgmtTokenResponse = await this.clientRegistrationService.getToken(payload); - return mgmtTokenResponse; - } catch (error) { - throw new UnauthorizedException(ResponseMessages.organisation.error.invalidClient); - } + const payload = new ClientCredentialTokenPayloadDto() + // eslint-disable-next-line camelcase + payload.client_id = clientId + // eslint-disable-next-line camelcase + payload.client_secret = clientSecret + try { + const mgmtTokenResponse = await this.clientRegistrationService.getToken(payload) + return mgmtTokenResponse + } catch (_error) { + throw new UnauthorizedException(ResponseMessages.organisation.error.invalidClient) + } } catch (error) { - this.logger.error(`Error in authenticateClientKeycloak : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in authenticateClientKeycloak : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -725,38 +728,38 @@ export class OrganizationService { publicProfile: true, OR: [ { name: { contains: search, mode: 'insensitive' } }, - { description: { contains: search, mode: 'insensitive' } } - ] - }; + { description: { contains: search, mode: 'insensitive' } }, + ], + } - const filterOptions = {}; + const filterOptions = {} - return this.organizationRepository.getOrganizations(query, filterOptions, pageNumber, pageSize); + return this.organizationRepository.getOrganizations(query, filterOptions, pageNumber, pageSize) } catch (error) { - this.logger.error(`In fetch getPublicOrganizations : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In fetch getPublicOrganizations : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getPublicProfile(payload: { orgSlug: string }): Promise { - const { orgSlug } = payload; + const { orgSlug } = payload try { const query = { orgSlug, - publicProfile: true - }; + publicProfile: true, + } - const organizationDetails = await this.organizationRepository.getOrganization(query); + const organizationDetails = await this.organizationRepository.getOrganization(query) if (!organizationDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.orgProfileNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgProfileNotFound) } - const credDefs = await this.organizationRepository.getCredDefByOrg(organizationDetails.id); - organizationDetails['credential_definitions'] = credDefs; - return organizationDetails; + const credDefs = await this.organizationRepository.getCredDefByOrg(organizationDetails.id) + organizationDetails.credential_definitions = credDefs + return organizationDetails } catch (error) { - this.logger.error(`get user: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get user: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -769,14 +772,14 @@ export class OrganizationService { async getOrganization(orgId: string): Promise { try { const query = { - id: orgId - }; + id: orgId, + } - const organizationDetails = await this.organizationRepository.getOrganization(query); - return organizationDetails; + const organizationDetails = await this.organizationRepository.getOrganization(query) + return organizationDetails } catch (error) { - this.logger.error(`In create organization : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In create organization : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -798,15 +801,15 @@ export class OrganizationService { pageNumber, pageSize, search - ); - for await (const item of getOrganization['invitations']) { - const getOrgRoles = await this.orgRoleService.getOrgRolesByIds(item['orgRoles']); - (item['orgRoles'] as object) = getOrgRoles; + ) + for await (const item of getOrganization.invitations) { + const getOrgRoles = await this.orgRoleService.getOrgRolesByIds(item.orgRoles) + ;(item.orgRoles as object) = getOrgRoles } - return getOrganization; + return getOrganization } catch (error) { - this.logger.error(`In create organization : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In create organization : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -818,26 +821,26 @@ export class OrganizationService { async getOrgRoles(orgId: string, user: user): Promise { try { if (!orgId) { - throw new BadRequestException(ResponseMessages.organisation.error.orgIdIsRequired); + throw new BadRequestException(ResponseMessages.organisation.error.orgIdIsRequired) } - const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId); + const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId) if (!organizationDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound) } if (!organizationDetails.idpId) { - return this.orgRoleService.getOrgRoles(); + return this.orgRoleService.getOrgRoles() } - const getUser = await this.organizationRepository.getUser(user?.id); - const token = await this.clientRegistrationService.getManagementToken(getUser?.clientId, getUser?.clientSecret); + const getUser = await this.organizationRepository.getUser(user?.id) + const token = await this.clientRegistrationService.getManagementToken(getUser?.clientId, getUser?.clientSecret) - return this.clientRegistrationService.getAllClientRoles(organizationDetails.idpId, token); + return this.clientRegistrationService.getAllClientRoles(organizationDetails.idpId, token) } catch (error) { - this.logger.error(`In getOrgRoles : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In getOrgRoles : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -850,31 +853,31 @@ export class OrganizationService { try { const query = { email, - orgId - }; + orgId, + } - const invitations = await this.organizationRepository.getOrgInvitations(query); + const invitations = await this.organizationRepository.getOrgInvitations(query) - let isPendingInvitation = false; - let isAcceptedInvitation = false; + let isPendingInvitation = false + let isAcceptedInvitation = false for (const invitation of invitations) { if (invitation.status === Invitation.PENDING) { - isPendingInvitation = true; + isPendingInvitation = true } if (invitation.status === Invitation.ACCEPTED) { - isAcceptedInvitation = true; + isAcceptedInvitation = true } } if (isPendingInvitation || isAcceptedInvitation) { - return true; + return true } - return false; + return false } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -883,36 +886,35 @@ export class OrganizationService { userEmail: string, userId: string, orgName: string - ): Promise { - const { invitations, orgId } = bulkInvitationDto; + ): Promise { + const { invitations, orgId } = bulkInvitationDto - for (const invitation of invitations) { - const { orgRoleId, email } = invitation; + for (const invitation of invitations) { + const { orgRoleId, email } = invitation - const isUserExist = await this.checkUserExistInPlatform(email); + const isUserExist = await this.checkUserExistInPlatform(email) - const userData = await this.getUserFirstName(userEmail); - - const {firstName} = userData; - const orgRolesDetails = await this.orgRoleService.getOrgRolesByIds(orgRoleId); - - if (0 === orgRolesDetails.length) { - throw new NotFoundException(ResponseMessages.organisation.error.orgRoleIdNotFound); - } + const userData = await this.getUserFirstName(userEmail) - const isInvitationExist = await this.checkInvitationExist(email, orgId); + const { firstName } = userData + const orgRolesDetails = await this.orgRoleService.getOrgRolesByIds(orgRoleId) - if (!isInvitationExist && userEmail !== invitation.email) { + if (orgRolesDetails.length === 0) { + throw new NotFoundException(ResponseMessages.organisation.error.orgRoleIdNotFound) + } - await this.organizationRepository.createSendInvitation(email, String(orgId), String(userId), orgRoleId); + const isInvitationExist = await this.checkInvitationExist(email, orgId) - try { - await this.sendInviteEmailTemplate(email, orgName, orgRolesDetails, firstName, isUserExist); - } catch (error) { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); - } + if (!isInvitationExist && userEmail !== invitation.email) { + await this.organizationRepository.createSendInvitation(email, String(orgId), String(userId), orgRoleId) + + try { + await this.sendInviteEmailTemplate(email, orgName, orgRolesDetails, firstName, isUserExist) + } catch (_error) { + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } } + } } async createInvitationByClientRoles( @@ -921,54 +923,48 @@ export class OrganizationService { userId: string, orgName: string, idpId: string - ): Promise { - const { invitations, orgId } = bulkInvitationDto; + ): Promise { + const { invitations, orgId } = bulkInvitationDto - const userDetails = await this.organizationRepository.getUser(userId); - const token = await this.clientRegistrationService.getManagementToken(userDetails.clientId, userDetails.clientSecret); - const clientRolesList = await this.clientRegistrationService.getAllClientRoles(idpId, token); - const orgRoles = await this.orgRoleService.getOrgRoles(); + const userDetails = await this.organizationRepository.getUser(userId) + const token = await this.clientRegistrationService.getManagementToken( + userDetails.clientId, + userDetails.clientSecret + ) + const clientRolesList = await this.clientRegistrationService.getAllClientRoles(idpId, token) + const orgRoles = await this.orgRoleService.getOrgRoles() for (const invitation of invitations) { - const { orgRoleId, email } = invitation; + const { orgRoleId, email } = invitation - const isUserExist = await this.checkUserExistInPlatform(email); + const isUserExist = await this.checkUserExistInPlatform(email) - const userData = await this.getUserFirstName(userEmail); + const userData = await this.getUserFirstName(userEmail) - const { firstName } = userData; + const { firstName } = userData - const matchedRoles = clientRolesList - .filter((role) => orgRoleId.includes(role.id.trim())) - .map((role) => role.name); + const matchedRoles = clientRolesList.filter((role) => orgRoleId.includes(role.id.trim())).map((role) => role.name) if (orgRoleId.length !== matchedRoles.length) { - throw new NotFoundException(ResponseMessages.organisation.error.orgRoleIdNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgRoleIdNotFound) } - const filteredOrgRoles = orgRoles.filter((role) => matchedRoles.includes(role.name.trim())); + const filteredOrgRoles = orgRoles.filter((role) => matchedRoles.includes(role.name.trim())) - const isInvitationExist = await this.checkInvitationExist(email, orgId); + const isInvitationExist = await this.checkInvitationExist(email, orgId) if (!isInvitationExist && userEmail !== invitation.email) { - await this.organizationRepository.createSendInvitation( email, String(orgId), String(userId), filteredOrgRoles.map((role) => role.id) - ); + ) try { - await this.sendInviteEmailTemplate( - email, - orgName, - filteredOrgRoles, - firstName, - isUserExist - ); - } catch (error) { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); + await this.sendInviteEmailTemplate(email, orgName, filteredOrgRoles, firstName, isUserExist) + } catch (_error) { + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } } } @@ -981,22 +977,17 @@ export class OrganizationService { */ async createInvitation(bulkInvitationDto: BulkSendInvitationDto, userId: string, userEmail: string): Promise { - const { orgId } = bulkInvitationDto; + const { orgId } = bulkInvitationDto try { - const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId); + const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId) if (!organizationDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound) } if (!organizationDetails.idpId) { - await this.createInvitationByOrgRoles( - bulkInvitationDto, - userEmail, - userId, - organizationDetails.name - ); + await this.createInvitationByOrgRoles(bulkInvitationDto, userEmail, userId, organizationDetails.name) } else { await this.createInvitationByClientRoles( bulkInvitationDto, @@ -1004,7 +995,7 @@ export class OrganizationService { userId, organizationDetails.name, organizationDetails.idpId - ); + ) } await this.userActivityService.createActivity( @@ -1012,11 +1003,11 @@ export class OrganizationService { organizationDetails.id, `Invitations sent for ${organizationDetails.name}`, 'Get started with user role management once invitations accepted' - ); - return ResponseMessages.organisation.success.createInvitation; + ) + return ResponseMessages.organisation.success.createInvitation } catch (error) { - this.logger.error(`In send Invitation : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In send Invitation : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -1035,13 +1026,13 @@ export class OrganizationService { firstName: string, isUserExist: boolean ): Promise { - const platformConfigData = await this.prisma.platform_config.findMany(); + const platformConfigData = await this.prisma.platform_config.findMany() - const urlEmailTemplate = new OrganizationInviteTemplate(); - const emailData = new EmailDto(); - emailData.emailFrom = platformConfigData[0].emailFrom; - emailData.emailTo = email; - emailData.emailSubject = `Invitation to join “${orgName}” on ${process.env.PLATFORM_NAME}`; + const urlEmailTemplate = new OrganizationInviteTemplate() + const emailData = new EmailDto() + emailData.emailFrom = platformConfigData[0].emailFrom + emailData.emailTo = email + emailData.emailSubject = `Invitation to join “${orgName}” on ${process.env.PLATFORM_NAME}` emailData.emailHtml = await urlEmailTemplate.sendInviteEmailTemplate( email, @@ -1049,75 +1040,73 @@ export class OrganizationService { orgRolesDetails, firstName, isUserExist - ); + ) //Email is sent to user for the verification through emailData - const isEmailSent = await sendEmail(emailData); + const isEmailSent = await sendEmail(emailData) - return isEmailSent; + return isEmailSent } async checkUserExistInPlatform(email: string): Promise { - const pattern = { cmd: 'get-user-by-mail' }; - const payload = { email }; + const pattern = { cmd: 'get-user-by-mail' } + const payload = { email } const userData: user = await this.natsClient .send(this.organizationServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) if (userData?.isEmailVerified) { - return true; + return true } - return false; + return false } async getUserFirstName(userEmail: string): Promise { - const pattern = { cmd: 'get-user-by-mail' }; - const payload = { email: userEmail }; + const pattern = { cmd: 'get-user-by-mail' } + const payload = { email: userEmail } const userData = await this.natsClient .send(this.organizationServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); - return userData; + ) + }) + return userData } async getUserUserId(userId: string): Promise { - const pattern = { cmd: 'get-user-by-user-id' }; + const pattern = { cmd: 'get-user-by-user-id' } // const payload = { id: userId }; - const userData = await this.natsClient - .send(this.organizationServiceProxy, pattern, userId) - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.status, - error: error.error, - message: error.message - }, - error.status - ); - }); - return userData; + const userData = await this.natsClient.send(this.organizationServiceProxy, pattern, userId).catch((error) => { + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw new HttpException( + { + status: error.status, + error: error.error, + message: error.message, + }, + error.status + ) + }) + return userData } async fetchUserInvitation( @@ -1128,10 +1117,10 @@ export class OrganizationService { search = '' ): Promise { try { - return this.organizationRepository.getAllOrgInvitations(email, status, pageNumber, pageSize, search); + return this.organizationRepository.getAllOrgInvitations(email, status, pageNumber, pageSize, search) } catch (error) { - this.logger.error(`In fetchUserInvitation : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In fetchUserInvitation : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -1144,39 +1133,46 @@ export class OrganizationService { orgId: string, status: string ): Promise { - const userDetails = await this.organizationRepository.getUser(userId); - const token = await this.clientRegistrationService.getManagementToken(userDetails.clientId, userDetails.clientSecret); - const clientRolesList = await this.clientRegistrationService.getAllClientRoles(idpId, token); - - const orgRoles = await this.orgRoleService.getOrgRolesByIds(invitation.orgRoles); - - const rolesPayload: { roleId: string; name: string; idpRoleId: string }[] = orgRoles.map((orgRole: IOrgRole) => { - let roleObj: { roleId: string; name: string; idpRoleId: string} = null; - - for (let index = 0; index < clientRolesList.length; index++) { - if (clientRolesList[index].name === orgRole.name) { - roleObj = { - roleId: orgRole.id, - name: orgRole.name, - idpRoleId: clientRolesList[index].id - }; - break; + const userDetails = await this.organizationRepository.getUser(userId) + const token = await this.clientRegistrationService.getManagementToken( + userDetails.clientId, + userDetails.clientSecret + ) + const clientRolesList = await this.clientRegistrationService.getAllClientRoles(idpId, token) + + const orgRoles = await this.orgRoleService.getOrgRolesByIds(invitation.orgRoles) + + const rolesPayload: { roleId: string; name: string; idpRoleId: string }[] = orgRoles.map((orgRole: IOrgRole) => { + let roleObj: { roleId: string; name: string; idpRoleId: string } = null + + for (let index = 0; index < clientRolesList.length; index++) { + if (clientRolesList[index].name === orgRole.name) { + roleObj = { + roleId: orgRole.id, + name: orgRole.name, + idpRoleId: clientRolesList[index].id, } + break } + } - return roleObj; - }); + return roleObj + }) - const data = { - status - }; - - await Promise.all([ - this.organizationRepository.updateOrgInvitation(invitation.id, data), - this.clientRegistrationService.createUserClientRole(idpId, token, keycloakUserId, rolesPayload.map(role => ({id: role.idpRoleId, name: role.name}))), - this.userOrgRoleService.updateUserOrgRole(userId, orgId, rolesPayload) - ]); + const data = { + status, + } + await Promise.all([ + this.organizationRepository.updateOrgInvitation(invitation.id, data), + this.clientRegistrationService.createUserClientRole( + idpId, + token, + keycloakUserId, + rolesPayload.map((role) => ({ id: role.idpRoleId, name: role.name })) + ), + this.userOrgRoleService.updateUserOrgRole(userId, orgId, rolesPayload), + ]) } /** @@ -1186,60 +1182,60 @@ export class OrganizationService { */ async updateOrgInvitation(payload: UpdateInvitationDto): Promise { try { - const { orgId, status, invitationId, userId, keycloakUserId, email } = payload; - const invitation = await this.organizationRepository.getInvitationById(String(invitationId)); + const { orgId, status, invitationId, userId, keycloakUserId, email } = payload + const invitation = await this.organizationRepository.getInvitationById(String(invitationId)) if (Invitation.ACCEPTED === payload.status) { - const userOrgCount = await this.organizationRepository.userOrganizationCount(userId); + const userOrgCount = await this.organizationRepository.userOrganizationCount(userId) if (userOrgCount >= toNumber(`${process.env.MAX_ORG_LIMIT}`)) { - throw new BadRequestException(ResponseMessages.organisation.error.MaximumOrgsLimit); + throw new BadRequestException(ResponseMessages.organisation.error.MaximumOrgsLimit) } } if (!invitation || (invitation && invitation.email !== email)) { - throw new NotFoundException(ResponseMessages.user.error.invitationNotFound); + throw new NotFoundException(ResponseMessages.user.error.invitationNotFound) } if (invitation.orgId !== orgId) { - throw new NotFoundException(ResponseMessages.user.error.invalidOrgId); + throw new NotFoundException(ResponseMessages.user.error.invalidOrgId) } - const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId); + const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId) if (!organizationDetails) { - throw new ConflictException(ResponseMessages.organisation.error.orgNotFound); + throw new ConflictException(ResponseMessages.organisation.error.orgNotFound) } - const invitationStatus = invitation.status as Invitation; + const invitationStatus = invitation.status as Invitation if (!transition(invitationStatus, payload.status)) { throw new BadRequestException( `${ResponseMessages.user.error.invitationStatusUpdateInvalid} ${invitation.status}` - ); + ) } const data = { - status - }; + status, + } if (status === Invitation.REJECTED) { - await this.organizationRepository.updateOrgInvitation(invitationId, data); - return ResponseMessages.user.success.invitationReject; + await this.organizationRepository.updateOrgInvitation(invitationId, data) + return ResponseMessages.user.success.invitationReject } if (organizationDetails.idpId) { - await this.updateClientInvitation(invitation, organizationDetails.idpId, userId, keycloakUserId, orgId, status); + await this.updateClientInvitation(invitation, organizationDetails.idpId, userId, keycloakUserId, orgId, status) } else { - await this.organizationRepository.updateOrgInvitation(invitationId, data); + await this.organizationRepository.updateOrgInvitation(invitationId, data) for (const roleId of invitation.orgRoles) { - await this.userOrgRoleService.createUserOrgRole(userId, roleId, orgId); + await this.userOrgRoleService.createUserOrgRole(userId, roleId, orgId) } } - return ResponseMessages.user.success.invitationAccept; + return ResponseMessages.user.success.invitationAccept } catch (error) { - this.logger.error(`In updateOrgInvitation : ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In updateOrgInvitation : ${error}`) + throw new RpcException(error.response ? error.response : error) } } @@ -1250,52 +1246,48 @@ export class OrganizationService { userId: string, orgId: string ): Promise { - const userDetails = await this.organizationRepository.getUser(userId); - const token = await this.clientRegistrationService.getManagementToken(userDetails.clientId, userDetails.clientSecret); - const clientRolesList = await this.clientRegistrationService.getAllClientRoles( - idpId, - token - ); - const orgRoles = await this.orgRoleService.getOrgRoles(); + const userDetails = await this.organizationRepository.getUser(userId) + const token = await this.clientRegistrationService.getManagementToken( + userDetails.clientId, + userDetails.clientSecret + ) + const clientRolesList = await this.clientRegistrationService.getAllClientRoles(idpId, token) + const orgRoles = await this.orgRoleService.getOrgRoles() - const matchedClientRoles = clientRolesList.filter((role) => roleIds.includes(role.id.trim())); + const matchedClientRoles = clientRolesList.filter((role) => roleIds.includes(role.id.trim())) if (roleIds.length !== matchedClientRoles.length) { - throw new NotFoundException(ResponseMessages.organisation.error.orgRoleIdNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgRoleIdNotFound) } const rolesPayload: { roleId: string; name: string; idpRoleId: string }[] = matchedClientRoles.map( (clientRole: IClientRoles) => { - let roleObj: { roleId: string; name: string; idpRoleId: string } = null; + let roleObj: { roleId: string; name: string; idpRoleId: string } = null for (let index = 0; index < orgRoles.length; index++) { if (orgRoles[index].name === clientRole.name) { roleObj = { roleId: orgRoles[index].id, name: orgRoles[index].name, - idpRoleId: clientRole.id - }; - break; + idpRoleId: clientRole.id, + } + break } } - return roleObj; + return roleObj } - ); + ) - const userData = await this.getUserUserId(userId); + const userData = await this.getUserUserId(userId) const [, deletedUserRoleRecords] = await Promise.all([ - this.clientRegistrationService.deleteUserClientRoles( - idpId, - token, - userData.keycloakUserId - ), - this.userOrgRoleService.deleteOrgRoles(userId, orgId) - ]); + this.clientRegistrationService.deleteUserClientRoles(idpId, token, userData.keycloakUserId), + this.userOrgRoleService.deleteOrgRoles(userId, orgId), + ]) - if (0 === deletedUserRoleRecords['count']) { - throw new InternalServerErrorException(ResponseMessages.organisation.error.updateUserRoles); + if (deletedUserRoleRecords.count === 0) { + throw new InternalServerErrorException(ResponseMessages.organisation.error.updateUserRoles) } const [, isUserRoleUpdated] = await Promise.all([ @@ -1305,10 +1297,10 @@ export class OrganizationService { userData.keycloakUserId, rolesPayload.map((role) => ({ id: role.idpRoleId, name: role.name })) ), - this.userOrgRoleService.updateUserOrgRole(userId, orgId, rolesPayload) - ]); + this.userOrgRoleService.updateUserOrgRole(userId, orgId, rolesPayload), + ]) - return isUserRoleUpdated; + return isUserRoleUpdated } /** @@ -1320,439 +1312,439 @@ export class OrganizationService { */ async updateUserRoles(orgId: string, roleIds: string[], userId: string): Promise { try { - const isUserExistForOrg = await this.userOrgRoleService.checkUserOrgExist(userId, orgId); + const isUserExistForOrg = await this.userOrgRoleService.checkUserOrgExist(userId, orgId) if (!isUserExistForOrg) { - throw new NotFoundException(ResponseMessages.organisation.error.userNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.userNotFound) } - const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId); + const organizationDetails = await this.organizationRepository.getOrganizationDetails(orgId) if (!organizationDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound); + throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound) } if (!organizationDetails.idpId) { - const isRolesExist = await this.orgRoleService.getOrgRolesByIds(roleIds); + const isRolesExist = await this.orgRoleService.getOrgRolesByIds(roleIds) - if (isRolesExist && 0 === isRolesExist.length) { - throw new NotFoundException(ResponseMessages.organisation.error.rolesNotExist); + if (isRolesExist && isRolesExist.length === 0) { + throw new NotFoundException(ResponseMessages.organisation.error.rolesNotExist) } - const deleteUserRecords = await this.userOrgRoleService.deleteOrgRoles(userId, orgId); + const deleteUserRecords = await this.userOrgRoleService.deleteOrgRoles(userId, orgId) - if (0 === deleteUserRecords['count']) { - throw new InternalServerErrorException(ResponseMessages.organisation.error.updateUserRoles); + if (deleteUserRecords.count === 0) { + throw new InternalServerErrorException(ResponseMessages.organisation.error.updateUserRoles) } for (const role of roleIds) { - this.userOrgRoleService.createUserOrgRole(userId, role, orgId); + this.userOrgRoleService.createUserOrgRole(userId, role, orgId) } - return true; + return true } else { - - return this.updateUserClientRoles( - roleIds, - organizationDetails.idpId, - userId, - organizationDetails.id - ); + return this.updateUserClientRoles(roleIds, organizationDetails.idpId, userId, organizationDetails.id) } - } catch (error) { - this.logger.error(`Error in updateUserRoles: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in updateUserRoles: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getOrgDashboard(orgId: string): Promise { try { - return this.organizationRepository.getOrgDashboard(orgId); + return this.organizationRepository.getOrgDashboard(orgId) } catch (error) { - this.logger.error(`In create organization : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In create organization : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - async getOrganizationActivityCount(orgId: string, userId: string): Promise { try { - const [ + const [verificationRecordsCount, issuanceRecordsCount, connectionRecordsCount, orgInvitationsCount, orgUsers] = + await Promise.all([ + this._getVerificationRecordsCount(orgId, userId), + this._getIssuanceRecordsCount(orgId, userId), + this._getConnectionRecordsCount(orgId, userId), + this.organizationRepository.getOrgInvitationsCount(orgId), + this.organizationRepository.getOrgDashboard(orgId), + ]) + + const orgUsersCount = orgUsers?.usersCount + + return { verificationRecordsCount, issuanceRecordsCount, connectionRecordsCount, - orgInvitationsCount, - orgUsers - ] = await Promise.all([ - this._getVerificationRecordsCount(orgId, userId), - this._getIssuanceRecordsCount(orgId, userId), - this._getConnectionRecordsCount(orgId, userId), - this.organizationRepository.getOrgInvitationsCount(orgId), - this.organizationRepository.getOrgDashboard(orgId) - ]); - - const orgUsersCount = orgUsers?.['usersCount']; - - return {verificationRecordsCount, issuanceRecordsCount, connectionRecordsCount, orgUsersCount, orgInvitationsCount}; + orgUsersCount, + orgInvitationsCount, + } } catch (error) { - this.logger.error(`In fetch organization references count : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In fetch organization references count : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async _getEcosystemsCount(orgId: string, userId: string): Promise { - const pattern = { cmd: 'get-ecosystem-records' }; + const pattern = { cmd: 'get-ecosystem-records' } const payload = { orgId, - userId - }; - const ecosystemsCount = await (this.natsClient - .send(this.organizationServiceProxy, pattern, payload) as unknown as Promise) - - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.status, - error: error.message - }, - error.status - ); - }); + userId, + } + const ecosystemsCount = await ( + this.natsClient.send(this.organizationServiceProxy, pattern, payload) as unknown as Promise + ).catch((error) => { + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw new HttpException( + { + status: error.status, + error: error.message, + }, + error.status + ) + }) - return ecosystemsCount; + return ecosystemsCount } - async _getConnectionRecordsCount(orgId: string, userId: string): Promise { - const pattern = { cmd: 'get-connection-records' }; + const pattern = { cmd: 'get-connection-records' } const payload = { orgId, - userId - }; + userId, + } const connectionsCount = await this.natsClient .send(this.organizationServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return connectionsCount; + return connectionsCount } - async _getIssuanceRecordsCount(orgId: string, userId: string): Promise { - const pattern = { cmd: 'get-issuance-records' }; + const pattern = { cmd: 'get-issuance-records' } const payload = { orgId, - userId - }; + userId, + } const issuanceCount = await this.natsClient .send(this.organizationServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return issuanceCount; + return issuanceCount } async _getVerificationRecordsCount(orgId: string, userId: string): Promise { - const pattern = { cmd: 'get-verification-records' }; + const pattern = { cmd: 'get-verification-records' } const payload = { orgId, - userId - }; + userId, + } const verificationCount = await this.natsClient .send(this.organizationServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return verificationCount; + return verificationCount } async getOrgPofile(orgId: string): Promise { try { - const orgProfile = await this.organizationRepository.getOrgProfile(orgId); - if (!orgProfile.logoUrl || '' === orgProfile.logoUrl) { - throw new NotFoundException(ResponseMessages.organisation.error.orgProfile); + const orgProfile = await this.organizationRepository.getOrgProfile(orgId) + if (!orgProfile.logoUrl || orgProfile.logoUrl === '') { + throw new NotFoundException(ResponseMessages.organisation.error.orgProfile) } - return orgProfile; + return orgProfile } catch (error) { - this.logger.error(`get organization profile : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get organization profile : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async fetchOrgCredentials(orgId: string): Promise { try { - const orgCredentials = await this.organizationRepository.getOrganizationDetails(orgId); + const orgCredentials = await this.organizationRepository.getOrganizationDetails(orgId) if (!orgCredentials.clientId) { - throw new NotFoundException(ResponseMessages.organisation.error.notExistClientCred); + throw new NotFoundException(ResponseMessages.organisation.error.notExistClientCred) } return { clientId: orgCredentials.clientId, - clientSecret: orgCredentials.clientSecret - }; + clientSecret: orgCredentials.clientSecret, + } } catch (error) { - this.logger.error(`Error in fetchOrgCredentials : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in fetchOrgCredentials : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getOrgDetails(orgId: string): Promise { try { - const orgDetails = await this.organizationRepository.getOrganizationDetails(orgId); - return orgDetails; + const orgDetails = await this.organizationRepository.getOrganizationDetails(orgId) + return orgDetails } catch (error) { - this.logger.error(`in getting organization details : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`in getting organization details : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getOrgOwner(orgId: string): Promise { try { - const orgDetails = await this.organizationRepository.getOrganizationOwnerDetails(orgId, OrgRoles.OWNER); - return orgDetails; + const orgDetails = await this.organizationRepository.getOrganizationOwnerDetails(orgId, OrgRoles.OWNER) + return orgDetails } catch (error) { - this.logger.error(`get organization profile : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get organization profile : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - + async deleteOrganization(orgId: string, user: user): Promise { try { - const getUser = await this.organizationRepository.getUser(user?.id); + const getUser = await this.organizationRepository.getUser(user?.id) // Fetch token and organization details in parallel const [token, organizationDetails] = await Promise.all([ this.clientRegistrationService.getManagementToken(getUser?.clientId, getUser?.clientSecret), - this.organizationRepository.getOrganizationDetails(orgId) - ]); - + this.organizationRepository.getOrganizationDetails(orgId), + ]) + if (!organizationDetails) { - throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound); - } - - const organizationInvitationDetails = await this.organizationRepository.getOrgInvitationsByOrg(orgId); - - const arrayEmail = organizationInvitationDetails.map(userData => userData.email); - this.logger.debug(`arrayEmail ::: ${JSON.stringify(arrayEmail)}`); - + throw new NotFoundException(ResponseMessages.organisation.error.orgNotFound) + } + + const organizationInvitationDetails = await this.organizationRepository.getOrgInvitationsByOrg(orgId) + + const arrayEmail = organizationInvitationDetails.map((userData) => userData.email) + this.logger.debug(`arrayEmail ::: ${JSON.stringify(arrayEmail)}`) + // Fetch Keycloak IDs only if there are emails to process - const keycloakUserIds = 0 < arrayEmail.length - ? (await this.getUserKeycloakIdByEmail(arrayEmail)).response.map(user => user.keycloakUserId) - : []; - - this.logger.log('Keycloak User Ids'); + const keycloakUserIds = + arrayEmail.length > 0 + ? (await this.getUserKeycloakIdByEmail(arrayEmail)).response.map((user) => user.keycloakUserId) + : [] + + this.logger.log('Keycloak User Ids') // Delete user client roles in parallel - const deleteUserRolesPromises = keycloakUserIds.map(keycloakUserId => this.clientRegistrationService.deleteUserClientRoles(organizationDetails?.idpId, token, keycloakUserId) - ); + const deleteUserRolesPromises = keycloakUserIds.map((keycloakUserId) => + this.clientRegistrationService.deleteUserClientRoles(organizationDetails?.idpId, token, keycloakUserId) + ) deleteUserRolesPromises.push( this.clientRegistrationService.deleteUserClientRoles(organizationDetails?.idpId, token, getUser?.keycloakUserId) - ); - - this.logger.debug(`deleteUserRolesPromises ::: ${JSON.stringify(deleteUserRolesPromises)}`); + ) + + this.logger.debug(`deleteUserRolesPromises ::: ${JSON.stringify(deleteUserRolesPromises)}`) + + const deleteUserRolesResults = await Promise.allSettled(deleteUserRolesPromises) - const deleteUserRolesResults = await Promise.allSettled(deleteUserRolesPromises); - // Check for failures in deleting user roles - const deletionFailures = deleteUserRolesResults.filter(result => 'rejected' === result?.status); - - if (0 < deletionFailures.length) { - this.logger.error(`deletionFailures ::: ${JSON.stringify(deletionFailures)}`); - throw new NotFoundException(ResponseMessages.organisation.error.orgDataNotFoundInkeycloak); - } - - const deletedOrgInvitationInfo: { email?: string, orgName?: string, orgRoleNames?: string[] }[] = []; - const userIds = (await this.getUserKeycloakIdByEmail(arrayEmail)).response.map(user => user.id); - await Promise.all(userIds.map(async (userId) => { - const userOrgRoleIds = await this.organizationRepository.getUserOrgRole(userId, orgId); - this.logger.debug(`userOrgRoleIds ::::: ${JSON.stringify(userOrgRoleIds)}`); - - const userDetails = await this.organizationRepository.getUser(userId); - this.logger.debug(`userDetails ::::: ${JSON.stringify(userDetails)}`); - - const orgRoles = await this.organizationRepository.getOrgRole(userOrgRoleIds); - this.logger.debug(`orgRoles ::::: ${JSON.stringify(orgRoles)}`); - - const orgRoleNames = orgRoles.map(orgRoleName => orgRoleName.name); - const sendEmail = await this.sendEmailForOrgInvitationsMember(userDetails?.email, organizationDetails?.name, orgRoleNames); - const newInvitation = { - email: userDetails.email, - orgName: organizationDetails?.name, - orgRoleNames - }; - - // Step 3: Push the data into the array - deletedOrgInvitationInfo.push(newInvitation); - - this.logger.log(`email: ${userDetails.email}, orgName: ${organizationDetails?.name}, orgRoles: ${JSON.stringify(orgRoleNames)}, sendEmail: ${sendEmail}`); - })); - + const deletionFailures = deleteUserRolesResults.filter((result) => result?.status === 'rejected') + + if (deletionFailures.length > 0) { + this.logger.error(`deletionFailures ::: ${JSON.stringify(deletionFailures)}`) + throw new NotFoundException(ResponseMessages.organisation.error.orgDataNotFoundInkeycloak) + } + + const deletedOrgInvitationInfo: { email?: string; orgName?: string; orgRoleNames?: string[] }[] = [] + const userIds = (await this.getUserKeycloakIdByEmail(arrayEmail)).response.map((user) => user.id) + await Promise.all( + userIds.map(async (userId) => { + const userOrgRoleIds = await this.organizationRepository.getUserOrgRole(userId, orgId) + this.logger.debug(`userOrgRoleIds ::::: ${JSON.stringify(userOrgRoleIds)}`) + + const userDetails = await this.organizationRepository.getUser(userId) + this.logger.debug(`userDetails ::::: ${JSON.stringify(userDetails)}`) + + const orgRoles = await this.organizationRepository.getOrgRole(userOrgRoleIds) + this.logger.debug(`orgRoles ::::: ${JSON.stringify(orgRoles)}`) + + const orgRoleNames = orgRoles.map((orgRoleName) => orgRoleName.name) + const sendEmail = await this.sendEmailForOrgInvitationsMember( + userDetails?.email, + organizationDetails?.name, + orgRoleNames + ) + const newInvitation = { + email: userDetails.email, + orgName: organizationDetails?.name, + orgRoleNames, + } + + // Step 3: Push the data into the array + deletedOrgInvitationInfo.push(newInvitation) + + this.logger.log( + `email: ${userDetails.email}, orgName: ${organizationDetails?.name}, orgRoles: ${JSON.stringify(orgRoleNames)}, sendEmail: ${sendEmail}` + ) + }) + ) + // Delete organization data - const { deletedUserActivity, deletedUserOrgRole, deleteOrg, deletedOrgInvitations, deletedNotification } = await this.organizationRepository.deleteOrg(orgId); - - this.logger.debug(`deletedUserActivity ::: ${JSON.stringify(deletedUserActivity)}`); - this.logger.debug(`deletedUserOrgRole ::: ${JSON.stringify(deletedUserOrgRole)}`); - this.logger.debug(`deleteOrg ::: ${JSON.stringify(deleteOrg)}`); - this.logger.debug(`deletedOrgInvitations ::: ${JSON.stringify(deletedOrgInvitations)}`); - + const { deletedUserActivity, deletedUserOrgRole, deleteOrg, deletedOrgInvitations, deletedNotification } = + await this.organizationRepository.deleteOrg(orgId) + + this.logger.debug(`deletedUserActivity ::: ${JSON.stringify(deletedUserActivity)}`) + this.logger.debug(`deletedUserOrgRole ::: ${JSON.stringify(deletedUserOrgRole)}`) + this.logger.debug(`deleteOrg ::: ${JSON.stringify(deleteOrg)}`) + this.logger.debug(`deletedOrgInvitations ::: ${JSON.stringify(deletedOrgInvitations)}`) + const deletions = [ { records: deletedUserActivity.count, tableName: `${PrismaTables.USER_ACTIVITY}` }, { records: deletedUserOrgRole.count, tableName: `${PrismaTables.USER_ORG_ROLES}` }, - { records: deletedOrgInvitations.count, deletedOrgInvitationInfo, tableName: `${PrismaTables.ORG_INVITATIONS}` }, + { + records: deletedOrgInvitations.count, + deletedOrgInvitationInfo, + tableName: `${PrismaTables.ORG_INVITATIONS}`, + }, { records: deletedNotification.count, tableName: `${PrismaTables.NOTIFICATION}` }, - { records: deleteOrg ? 1 : 0, tableName: `${PrismaTables.ORGANIZATION}` } - ]; - + { records: deleteOrg ? 1 : 0, tableName: `${PrismaTables.ORGANIZATION}` }, + ] + // Log deletion activities in parallel - await Promise.all(deletions.map(async ({ records, tableName, deletedOrgInvitationInfo }) => { - if (records) { - const txnMetadata: { - deletedRecordsCount: number; - deletedRecordInTable: string; - deletedOrgInvitationInfo?: object[] - } = { - deletedRecordsCount: records, - deletedRecordInTable: tableName - }; - - if (deletedOrgInvitationInfo) { - txnMetadata.deletedOrgInvitationInfo = deletedOrgInvitationInfo; + await Promise.all( + deletions.map(async ({ records, tableName, deletedOrgInvitationInfo }) => { + if (records) { + const txnMetadata: { + deletedRecordsCount: number + deletedRecordInTable: string + deletedOrgInvitationInfo?: object[] + } = { + deletedRecordsCount: records, + deletedRecordInTable: tableName, + } + + if (deletedOrgInvitationInfo) { + txnMetadata.deletedOrgInvitationInfo = deletedOrgInvitationInfo + } + + const recordType = RecordType.ORGANIZATION + await this.userActivityRepository._orgDeletedActivity(orgId, user, txnMetadata, recordType) } - - const recordType = RecordType.ORGANIZATION; - await this.userActivityRepository._orgDeletedActivity(orgId, user, txnMetadata, recordType); - } - })); - - return deleteOrg; - + }) + ) + + return deleteOrg } catch (error) { - this.logger.error(`delete organization: ${JSON.stringify(error)}`); - throw new RpcException(error.response ?? error); + this.logger.error(`delete organization: ${JSON.stringify(error)}`) + throw new RpcException(error.response ?? error) } } - async sendEmailForOrgInvitationsMember(email: string, orgName: string, orgRole: string[]): Promise { - const platformConfigData = await this.prisma.platform_config.findMany(); - const urlEmailTemplate = new DeleteOrgInvitationsEmail(); - const emailData = new EmailDto(); - emailData.emailFrom = platformConfigData[0].emailFrom; - emailData.emailTo = email; - emailData.emailSubject = `Removal of participation of “${orgName}”`; - - emailData.emailHtml = await urlEmailTemplate.sendDeleteOrgMemberEmailTemplate( - email, - orgName, - orgRole - ); + const platformConfigData = await this.prisma.platform_config.findMany() + const urlEmailTemplate = new DeleteOrgInvitationsEmail() + const emailData = new EmailDto() + emailData.emailFrom = platformConfigData[0].emailFrom + emailData.emailTo = email + emailData.emailSubject = `Removal of participation of “${orgName}”` + + emailData.emailHtml = await urlEmailTemplate.sendDeleteOrgMemberEmailTemplate(email, orgName, orgRole) //Email is sent to user for the verification through emailData - const isEmailSent = await sendEmail(emailData); + const isEmailSent = await sendEmail(emailData) - return isEmailSent; + return isEmailSent } async getUserKeycloakIdByEmail(userEmails: string[]): Promise<{ - response; + response }> { try { const pattern = { - cmd: 'get-user-keycloak-id' - }; + cmd: 'get-user-keycloak-id', + } return this.organizationServiceProxy .send(pattern, userEmails) .pipe( map((response: string) => ({ - response + response, })) ) .toPromise() .catch((error) => { - this.logger.error(`getUserKeycloakIdByEmail catch: ${JSON.stringify(error)}`); + this.logger.error(`getUserKeycloakIdByEmail catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error?.statusCode, - error: error?.message + error: error?.message, }, error.error - ); - }); + ) + }) } catch (error) { - this.logger.error(`[getUserKeycloakIdByEmail] - error in get keycloak id by email : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getUserKeycloakIdByEmail] - error in get keycloak id by email : ${JSON.stringify(error)}`) + throw error } } async _getOrgAgentApiKey(orgId: string): Promise { - const pattern = { cmd: 'get-org-agent-api-key' }; - const payload = { orgId }; + 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; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.organizationServiceProxy.send(pattern, payload).toPromise() + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } async registerOrgsMapUsers(): Promise { - try { + const unregisteredOrgsList = await this.organizationRepository.getUnregisteredClientOrgs() - const unregisteredOrgsList = await this.organizationRepository.getUnregisteredClientOrgs(); - - if (!unregisteredOrgsList || 0 === unregisteredOrgsList.length) { - throw new NotFoundException('Unregistered client organizations not found'); - } + if (!unregisteredOrgsList || unregisteredOrgsList.length === 0) { + throw new NotFoundException('Unregistered client organizations not found') + } for (const org of unregisteredOrgsList) { - const userOrgRoles = 0 < org['userOrgRoles'].length && org['userOrgRoles']; + const userOrgRoles = org.userOrgRoles.length > 0 && org.userOrgRoles - const ownerUserList = 0 < org['userOrgRoles'].length - && userOrgRoles.filter(userOrgRole => userOrgRole.orgRole.name === OrgRoles.OWNER); + const ownerUserList = + org.userOrgRoles.length > 0 && + userOrgRoles.filter((userOrgRole) => userOrgRole.orgRole.name === OrgRoles.OWNER) - const ownerUser = 0 < ownerUserList.length && ownerUserList[0].user; + const ownerUser = ownerUserList.length > 0 && ownerUserList[0].user const orgObj = { id: org.id, @@ -1760,8 +1752,8 @@ export class OrganizationService { name: org.name, ownerId: ownerUser.id, ownerEmail: ownerUser.email, - ownerKeycloakId: ownerUser.keycloakUserId - }; + ownerKeycloakId: ownerUser.keycloakUserId, + } if (orgObj.ownerKeycloakId) { const orgCredentials = await this.registerToKeycloak( @@ -1770,120 +1762,121 @@ export class OrganizationService { orgObj.ownerKeycloakId, orgObj.ownerId, true - ); + ) + + const { clientId, idpId, clientSecret } = orgCredentials - const { clientId, idpId, clientSecret } = orgCredentials; - const updateOrgData = { clientId, clientSecret: this.maskString(clientSecret), - idpId - }; - - const updatedOrg = await this.organizationRepository.updateOrganizationById(updateOrgData, orgObj.id); - - this.logger.log(`updatedOrg::`, updatedOrg); - - const usersToRegisterList = userOrgRoles.filter(userOrgRole => null !== userOrgRole.user.keycloakUserId); - - const userDetails = await this.organizationRepository.getUser(orgObj.ownerId); - const token = await this.clientRegistrationService.getManagementToken(userDetails.clientId, userDetails.clientSecret); - const clientRolesList = await this.clientRegistrationService.getAllClientRoles(idpId, token); - - const deletedUserDetails: string[] = []; - for (const userRole of usersToRegisterList) { - const user = userRole.user; - - const matchedClientRoles = clientRolesList.filter((role) => userRole.orgRole.name === role.name) - .map(clientRole => ({roleId: userRole.orgRole.id, idpRoleId: clientRole.id, name: clientRole.name})); - - if (!deletedUserDetails.includes(user.id)) { - const [, deletedUserRoleRecords] = await Promise.all([ - this.clientRegistrationService.deleteUserClientRoles(idpId, token, user.keycloakUserId), - this.userOrgRoleService.deleteOrgRoles(user.id, orgObj.id) - ]); - - this.logger.log(`deletedUserRoleRecords::`, deletedUserRoleRecords); - - deletedUserDetails.push(user.id); - } - - - await Promise.all([ - this.clientRegistrationService.createUserClientRole( - idpId, - token, - user.keycloakUserId, - matchedClientRoles.map((role) => ({ id: role.idpRoleId, name: role.name })) - ), - this.userOrgRoleService.updateUserOrgRole( - user.id, - orgObj.id, - matchedClientRoles.map((role) => ({ roleId: role.roleId, idpRoleId: role.idpRoleId })) - ) - ]); - this.logger.log(`Organization client created and users mapped to roles`); - - } - } - } - - return ''; - } catch (error) { - this.logger.error(`Error in registerOrgsMapUsers: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + idpId, + } + + const updatedOrg = await this.organizationRepository.updateOrganizationById(updateOrgData, orgObj.id) + + this.logger.log('updatedOrg::', updatedOrg) + + const usersToRegisterList = userOrgRoles.filter((userOrgRole) => userOrgRole.user.keycloakUserId !== null) + + const userDetails = await this.organizationRepository.getUser(orgObj.ownerId) + const token = await this.clientRegistrationService.getManagementToken( + userDetails.clientId, + userDetails.clientSecret + ) + const clientRolesList = await this.clientRegistrationService.getAllClientRoles(idpId, token) + + const deletedUserDetails: string[] = [] + for (const userRole of usersToRegisterList) { + const user = userRole.user + + const matchedClientRoles = clientRolesList + .filter((role) => userRole.orgRole.name === role.name) + .map((clientRole) => ({ roleId: userRole.orgRole.id, idpRoleId: clientRole.id, name: clientRole.name })) + + if (!deletedUserDetails.includes(user.id)) { + const [, deletedUserRoleRecords] = await Promise.all([ + this.clientRegistrationService.deleteUserClientRoles(idpId, token, user.keycloakUserId), + this.userOrgRoleService.deleteOrgRoles(user.id, orgObj.id), + ]) + + this.logger.log(`deletedUserRoleRecords::`, deletedUserRoleRecords) + + deletedUserDetails.push(user.id) + } + + await Promise.all([ + this.clientRegistrationService.createUserClientRole( + idpId, + token, + user.keycloakUserId, + matchedClientRoles.map((role) => ({ id: role.idpRoleId, name: role.name })) + ), + this.userOrgRoleService.updateUserOrgRole( + user.id, + orgObj.id, + matchedClientRoles.map((role) => ({ roleId: role.roleId, idpRoleId: role.idpRoleId })) + ), + ]) + this.logger.log(`Organization client created and users mapped to roles`) + } + } + } + return '' + } catch (error) { + this.logger.error(`Error in registerOrgsMapUsers: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async deleteOrganizationInvitation(orgId: string, invitationId: string): Promise { try { - const invitationDetails = await this.organizationRepository.getInvitationById(invitationId); + const invitationDetails = await this.organizationRepository.getInvitationById(invitationId) // Check invitation is present if (!invitationDetails) { - throw new NotFoundException(ResponseMessages.user.error.invitationNotFound); + 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); + 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); + throw new BadRequestException(ResponseMessages.organisation.error.invitationStatusInvalid) } - await this.organizationRepository.deleteOrganizationInvitation(invitationId); + await this.organizationRepository.deleteOrganizationInvitation(invitationId) - return true; + return true } catch (error) { - this.logger.error(`delete organization invitation: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`delete organization invitation: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async storeOrgWebhookEndpoint(orgId: string, notificationWebhook: string): Promise { - const pattern = { cmd: 'register-org-webhook-endpoint-for-notification' }; + const pattern = { cmd: 'register-org-webhook-endpoint-for-notification' } const payload = { orgId, - notificationWebhook - }; + notificationWebhook, + } try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const message = await this.natsClient.send(this.organizationServiceProxy, pattern, payload); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.natsClient.send(this.organizationServiceProxy, pattern, payload) + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } @@ -1894,72 +1887,72 @@ export class OrganizationService { */ async getOrgDidList(orgId: string): Promise { try { - return await this.organizationRepository.getAllOrganizationDid(orgId); + return await this.organizationRepository.getAllOrganizationDid(orgId) } catch (error) { - this.logger.error(`get Org dids: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get Org dids: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getAgentTypeByAgentTypeId(orgAgentTypeId: string): Promise { try { - return await this.organizationRepository.getAgentTypeByAgentTypeId(orgAgentTypeId); + return await this.organizationRepository.getAgentTypeByAgentTypeId(orgAgentTypeId) } catch (error) { - this.logger.error(`get getAgentTypeByAgentTypeId error: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get getAgentTypeByAgentTypeId error: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getOrgRolesDetails(roleName: string): Promise { try { - const orgRoleDetails = await this.organizationRepository.getOrgRoles(roleName); - return orgRoleDetails; + const orgRoleDetails = await this.organizationRepository.getOrgRoles(roleName) + return orgRoleDetails } catch (error) { - this.logger.error(`in getting organization role details : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`in getting organization role details : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getAllOrgRoles(): Promise { try { - const orgRoleDetails = await this.organizationRepository.getAllOrgRolesDetails(); - return orgRoleDetails; + const orgRoleDetails = await this.organizationRepository.getAllOrgRolesDetails() + return orgRoleDetails } catch (error) { - this.logger.error(`in getting all organization roles : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`in getting all organization roles : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getOrgRolesDetailsByIds(orgRoles: string[]): Promise { try { - const orgRoleDetails = await this.organizationRepository.getOrgRolesById(orgRoles); - return orgRoleDetails; + const orgRoleDetails = await this.organizationRepository.getOrgRolesById(orgRoles) + return orgRoleDetails } catch (error) { - this.logger.error(`in getting org roles by id : ${JSON.stringify(error)}`); + this.logger.error(`in getting org roles by id : ${JSON.stringify(error)}`) } } async getOrganisationsByIds(organisationIds): Promise { try { - return await this.organizationRepository.getOrganisationsByIds(organisationIds); + return await this.organizationRepository.getOrganisationsByIds(organisationIds) } catch (error) { - this.logger.error(`get getOrganisationsByIds error: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get getOrganisationsByIds error: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - async getOrgAgentDetailsForEcosystem(data: {orgIds: string[], search: string}): Promise { + async getOrgAgentDetailsForEcosystem(data: { orgIds: string[]; search: string }): Promise { try { - const getAllOrganizationDetails = await this.organizationRepository.handleGetOrganisationData(data); + const getAllOrganizationDetails = await this.organizationRepository.handleGetOrganisationData(data) - if (!getAllOrganizationDetails) { - throw new NotFoundException(ResponseMessages.ledger.error.NotFound); - } + if (!getAllOrganizationDetails) { + throw new NotFoundException(ResponseMessages.ledger.error.NotFound) + } - return getAllOrganizationDetails; + return getAllOrganizationDetails } catch (error) { - this.logger.error(`Error in getOrgAgentDetailsForEcosystem: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in getOrgAgentDetailsForEcosystem: ${error}`) + throw new RpcException(error.response ? error.response : error) } + } } -} \ No newline at end of file diff --git a/apps/organization/templates/delete-organization-invitations.template.ts b/apps/organization/templates/delete-organization-invitations.template.ts index e083d6fdb..10ca0c867 100644 --- a/apps/organization/templates/delete-organization-invitations.template.ts +++ b/apps/organization/templates/delete-organization-invitations.template.ts @@ -1,12 +1,6 @@ export class DeleteOrgInvitationsEmail { - - public sendDeleteOrgMemberEmailTemplate( - email: string, - orgName: string, - orgRoles: string[] - ): string { - - const orgRoleNames = 0 < orgRoles.length ? orgRoles.join(', ') : ''; + public sendDeleteOrgMemberEmailTemplate(email: string, orgName: string, orgRoles: string[]): string { + const orgRoleNames = orgRoles.length > 0 ? orgRoles.join(', ') : '' return ` @@ -43,9 +37,6 @@ export class DeleteOrgInvitationsEmail { - `; - - } - - -} \ No newline at end of file + ` + } +} diff --git a/apps/organization/templates/organization-invitation.template.ts b/apps/organization/templates/organization-invitation.template.ts index e3fb38f58..ec1f91fd2 100644 --- a/apps/organization/templates/organization-invitation.template.ts +++ b/apps/organization/templates/organization-invitation.template.ts @@ -1,25 +1,25 @@ export class OrganizationInviteTemplate { + public sendInviteEmailTemplate( + email: string, + orgName: string, + _orgRolesDetails: object[], + firstName: string, + isUserExist: boolean + ): string { + const validUrl = isUserExist + ? `${process.env.FRONT_END_URL}/authentication/sign-in` + : `${process.env.FRONT_END_URL}/authentication/sign-up` - public sendInviteEmailTemplate( - email: string, - orgName: string, - orgRolesDetails: object[], - firstName: string, - isUserExist: boolean - ): string { + const message = isUserExist + ? 'Please accept the invitation using the following link:' + : `To get started, kindly register on ${process.env.PLATFORM_NAME} platform using this link:` - const validUrl = isUserExist ? `${process.env.FRONT_END_URL}/authentication/sign-in` : `${process.env.FRONT_END_URL}/authentication/sign-up`; + const secondMessage = isUserExist + ? `After successful login into ${process.env.PLATFORM_NAME} click on "Accept Organization Invitation" link on your dashboard.` + : 'After successful registration, you can log in to the platform and click on “Accept Organization Invitation” on your dashboard.' - const message = isUserExist - ? `Please accept the invitation using the following link:` - : `To get started, kindly register on ${process.env.PLATFORM_NAME} platform using this link:`; + const Button = isUserExist ? 'Accept Organization Invitation' : `Register on ${process.env.PLATFORM_NAME}` - const secondMessage = isUserExist - ? `After successful login into ${process.env.PLATFORM_NAME} click on "Accept Organization Invitation" link on your dashboard.` - : `After successful registration, you can log in to the platform and click on “Accept Organization Invitation” on your dashboard.`; - - const Button = isUserExist ? `Accept Organization Invitation` : `Register on ${process.env.PLATFORM_NAME}`; - return ` @@ -74,9 +74,6 @@ export class OrganizationInviteTemplate { - `; - - } - - -} \ No newline at end of file + ` + } +} diff --git a/apps/organization/templates/organization-onboard.template.ts b/apps/organization/templates/organization-onboard.template.ts index 7f4c8b3be..3b826251a 100644 --- a/apps/organization/templates/organization-onboard.template.ts +++ b/apps/organization/templates/organization-onboard.template.ts @@ -1,7 +1,6 @@ export class OnBoardVerificationRequest { - public getOnBoardRequest(orgName: string, email: string): string { - const year: number = new Date().getFullYear(); + const year: number = new Date().getFullYear() try { return ` @@ -83,8 +82,7 @@ export class OnBoardVerificationRequest { - `; - } catch (error) { - } + ` + } catch (_error) {} } -} \ No newline at end of file +} diff --git a/apps/organization/templates/organization-url-template.ts b/apps/organization/templates/organization-url-template.ts index 6846d6077..a7edaceb1 100644 --- a/apps/organization/templates/organization-url-template.ts +++ b/apps/organization/templates/organization-url-template.ts @@ -1,78 +1,78 @@ -import * as url from 'url'; - -export class URLOrganizationEmailTemplate { - - public getOrganizationURLTemplate(orgName: string, email: string, verificationCode: string, type: string): string { - const endpoint = `${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}`; - const year: number = new Date().getFullYear(); - let apiUrl; - - if ('ADMIN' === type) { - apiUrl = url.parse(`${endpoint}/email/tenant/verify?verificationCode=${verificationCode}&email=${encodeURIComponent(email)}`); - } else { - apiUrl = url.parse(`${endpoint}/email/non-admin-user/verify?verificationCode=${verificationCode}&email=${encodeURIComponent(email)}`); - } - - const validUrl = apiUrl.href.replace('/:', ':'); - try { - return ` - - - - - - - - - -
-
- -
-
-

- Hello ${orgName}, -

-

- Your organisation ${orgName} has been successfully created on ${process.env.PLATFORM_NAME}. In order to enable access for your account, - we need to verify your email address. Please use the link below or click on the “Verify” button to enable access to your account. -

-

Your account details as follows,

-
    -
  • Username/Email: ${email}
  • -
  • Verification Link: ${validUrl}
  • -
- -

In case you need any assistance to access your account, please contact ${process.env.POWERED_BY} -

-
-
-
- - f - t -
-

- ® ${process.env.PLATFORM_NAME} ${year}, Powered by ${process.env.POWERED_BY}. All Rights Reserved. -

-
-
-
- - `; - - } catch (error) { - } - } -} - +import * as url from 'url' + +export class URLOrganizationEmailTemplate { + public getOrganizationURLTemplate(orgName: string, email: string, verificationCode: string, type: string): string { + const endpoint = `${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}` + const year: number = new Date().getFullYear() + let apiUrl: url.UrlWithStringQuery + + if (type === 'ADMIN') { + apiUrl = url.parse( + `${endpoint}/email/tenant/verify?verificationCode=${verificationCode}&email=${encodeURIComponent(email)}` + ) + } else { + apiUrl = url.parse( + `${endpoint}/email/non-admin-user/verify?verificationCode=${verificationCode}&email=${encodeURIComponent(email)}` + ) + } + + const validUrl = apiUrl.href.replace('/:', ':') + try { + return ` + + + + + + + + + +
+
+ +
+
+

+ Hello ${orgName}, +

+

+ Your organisation ${orgName} has been successfully created on ${process.env.PLATFORM_NAME}. In order to enable access for your account, + we need to verify your email address. Please use the link below or click on the “Verify” button to enable access to your account. +

+

Your account details as follows,

+
    +
  • Username/Email: ${email}
  • +
  • Verification Link: ${validUrl}
  • +
+ +

In case you need any assistance to access your account, please contact ${process.env.POWERED_BY} +

+
+
+
+ + f + t +
+

+ ® ${process.env.PLATFORM_NAME} ${year}, Powered by ${process.env.POWERED_BY}. All Rights Reserved. +

+
+
+
+ + ` + } catch (_error) {} + } +} diff --git a/apps/user/dtos/accept-reject-invitation.dto.ts b/apps/user/dtos/accept-reject-invitation.dto.ts index 970e3bf32..173abe267 100644 --- a/apps/user/dtos/accept-reject-invitation.dto.ts +++ b/apps/user/dtos/accept-reject-invitation.dto.ts @@ -1,7 +1,7 @@ -import { Invitation } from '@credebl/enum/enum'; +import type { Invitation } from '@credebl/enum/enum' export class AcceptRejectInvitationDto { - invitationId: string; - orgId: string; - status: Invitation; + invitationId: string + orgId: string + status: Invitation } diff --git a/apps/user/dtos/create-user.dto.ts b/apps/user/dtos/create-user.dto.ts index a0372f080..3fef75413 100644 --- a/apps/user/dtos/create-user.dto.ts +++ b/apps/user/dtos/create-user.dto.ts @@ -1,6 +1,6 @@ export class CreateUserDto { - email: string; - password: string; - firstName: string; - lastName: string; -} \ No newline at end of file + email: string + password: string + firstName: string + lastName: string +} diff --git a/apps/user/dtos/keycloak-register.dto.ts b/apps/user/dtos/keycloak-register.dto.ts index bfeb2c715..dadac553b 100644 --- a/apps/user/dtos/keycloak-register.dto.ts +++ b/apps/user/dtos/keycloak-register.dto.ts @@ -1,29 +1,28 @@ export class KeycloakUserRegistrationDto { - email: string; - firstName: string; - lastName: string; - username: string; - enabled: boolean; - totp: boolean; - emailVerified: boolean; - notBefore: number; - credentials: Credentials[]; - access: Access; - realmRoles: string[]; - attributes: object; - + email: string + firstName: string + lastName: string + username: string + enabled: boolean + totp: boolean + emailVerified: boolean + notBefore: number + credentials: Credentials[] + access: Access + realmRoles: string[] + attributes: object } export class Credentials { - type: string; - value: string; - temporary: boolean; + type: string + value: string + temporary: boolean } export class Access { - manageGroupMembership: boolean; - view: boolean; - mapRoles: boolean; - impersonate: boolean; - manage: boolean; -} \ No newline at end of file + manageGroupMembership: boolean + view: boolean + mapRoles: boolean + impersonate: boolean + manage: boolean +} diff --git a/apps/user/dtos/login-user.dto.ts b/apps/user/dtos/login-user.dto.ts index 2a4aa64db..9ba1e27d3 100644 --- a/apps/user/dtos/login-user.dto.ts +++ b/apps/user/dtos/login-user.dto.ts @@ -1,23 +1,23 @@ -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 { 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' export class LoginUserDto { - @ApiProperty({ example: 'awqx@yopmail.com' }) - @IsEmail({}, { message: 'Please provide a valid email' }) - @IsNotEmpty({ message: 'Email is required' }) - @IsString({ message: 'Email should be a string' }) - @Transform(({ value }) => trim(value)) - email: string; - - @ApiProperty({ example: 'Password@1' }) - @IsOptional() - @IsString({ message: 'password should be string' }) - password?: string; + @ApiProperty({ example: 'awqx@yopmail.com' }) + @IsEmail({}, { message: 'Please provide a valid email' }) + @IsNotEmpty({ message: 'Email is required' }) + @IsString({ message: 'Email should be a string' }) + @Transform(({ value }) => trim(value)) + email: string - @ApiProperty({ example: 'false' }) - @IsOptional() - @IsBoolean({ message: 'isPasskey should be boolean' }) - isPasskey?: boolean; + @ApiProperty({ example: 'Password@1' }) + @IsOptional() + @IsString({ message: 'password should be string' }) + password?: string + + @ApiProperty({ example: 'false' }) + @IsOptional() + @IsBoolean({ message: 'isPasskey should be boolean' }) + isPasskey?: boolean } diff --git a/apps/user/dtos/verify-email.dto.ts b/apps/user/dtos/verify-email.dto.ts index 0355265de..4920e302b 100644 --- a/apps/user/dtos/verify-email.dto.ts +++ b/apps/user/dtos/verify-email.dto.ts @@ -1,4 +1,4 @@ export class VerifyEmailTokenDto { - email: string; - verificationCode: string; + email: string + verificationCode: string } diff --git a/apps/user/interfaces/user.interface.ts b/apps/user/interfaces/user.interface.ts index dd6c1d60d..80343572b 100644 --- a/apps/user/interfaces/user.interface.ts +++ b/apps/user/interfaces/user.interface.ts @@ -1,246 +1,246 @@ -import { $Enums, Prisma, RecordType } from '@prisma/client'; +import type { $Enums, Prisma, RecordType } from '@prisma/client' export interface IUsersProfile { - id: string; - username?: string; - email?: string; - firstName?: string; - lastName?: string; - supabaseUserId?: string; - keycloakUserId?: string; - userOrgRoles?: IUserOrgRole[]; + id: string + username?: string + email?: string + firstName?: string + lastName?: string + supabaseUserId?: string + keycloakUserId?: string + userOrgRoles?: IUserOrgRole[] } interface IUserOrgRole { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole :IOrgRole; - organisation:IOrganisation; -} - export interface IOrgRole{ - id: string; - name: string; - description: string; - }; - export interface IOrganisation{ - id: string; - name: string; - description: string; - orgSlug: string; - logoUrl: string; - website: string; - publicProfile: boolean; - countryId: number; - stateId: number; - cityId: number; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: IOrgRole + organisation: IOrganisation +} +export interface IOrgRole { + id: string + name: string + description: string +} +export interface IOrganisation { + id: string + name: string + description: string + orgSlug: string + logoUrl: string + website: string + publicProfile: boolean + countryId: number + stateId: number + cityId: number } export interface OrgInvitations { - id: string; - userId: string; - orgId?: string; - organisation?: object; - orgRoleId?: string; - status: string; - email?: string; - orgRoles: string[]; + id: string + userId: string + orgId?: string + organisation?: object + orgRoleId?: string + status: string + email?: string + orgRoles: string[] } export interface ISendVerificationEmail { - email: string; - username?: string; - clientId?: string; - clientSecret?: string; + email: string + username?: string + clientId?: string + clientSecret?: string } export interface IUserInformation { - email: string; - password: string; - firstName: string; - lastName: string; - isPasskey: boolean; - isHolder?: boolean; + email: string + password: string + firstName: string + lastName: string + isPasskey: boolean + isHolder?: boolean } export interface AddPasskeyDetails { - password: string; + password: string } export interface UpdateUserProfile { - id: string; - profileImg?: string; - firstName: string; - lastName: string; - isPublic: boolean; + id: string + profileImg?: string + firstName: string + lastName: string + isPublic: boolean } export interface PlatformSettings { - externalIp: string; - inboundEndpoint: string; - sgApiKey: string; - emailFrom: string; - apiEndPoint: string; + externalIp: string + inboundEndpoint: string + sgApiKey: string + emailFrom: string + apiEndPoint: string } export interface IShareUserCertificate { - schemaId: string; - credDefId: string; - credentialId: string; - attributes: Attribute[]; - invitationUrl?: string; + schemaId: string + credDefId: string + credentialId: string + attributes: Attribute[] + invitationUrl?: string } export interface IShareDegreeCertificateRes { - cretificate: string; - invitationUrl?: string; + cretificate: string + invitationUrl?: string } export interface Attribute { - [key: string]: string; - label: string; + [key: string]: string + label: string } export interface ICheckUserDetails { - isEmailVerified?: boolean; - isFidoVerified?: boolean; - isRegistrationCompleted?: boolean; - userId?: number; - message?:string; + isEmailVerified?: boolean + isFidoVerified?: boolean + isRegistrationCompleted?: boolean + userId?: number + message?: string } export interface IOrgUsers { - totalPages: number, - users: OrgUser[] + totalPages: number + users: OrgUser[] } export interface IDidList { - id: string; - createDateTime: Date; - did: string; - lastChangedDateTime: Date; - isPrimaryDid: boolean; + id: string + createDateTime: Date + did: string + lastChangedDateTime: Date + isPrimaryDid: boolean } interface OrgUser { - id: string; - username: string; - email: string; - firstName: string; - lastName: string; - isEmailVerified: boolean; - userOrgRoles: UserOrgRoles[]; + 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 + id: string + orgId: string + orgRoleId: string + orgRole: OrgRole + organisation: Organization } interface OrgRole { - id: string; - name: string; - description: string; + id: string + name: string + description: string } interface Organization { - id: string, - name: string, - description: string, - orgSlug: string, - logoUrl: string, - org_agents: OrgAgents[]; + 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 + id: string + orgDid: string + walletName: string + agentSpinUpStatus: number + agentsTypeId: string + createDateTime: Date + orgAgentTypeId: string } export interface Payload { - pageNumber: number; - pageSize: number; - search: string; + pageNumber: number + pageSize: number + search: string } -export interface IVerifyUserEmail{ - email: string; - verificationCode: string; +export interface IVerifyUserEmail { + email: string + verificationCode: string } -export interface IUserSignIn{ - email: string; - password: string; - isPasskey?: boolean; +export interface IUserSignIn { + email: string + password: string + isPasskey?: boolean } -export interface IUserResetPassword{ - email: string; - oldPassword?: string; - newPassword?: string; - token?: string; - password?: string; +export interface IUserResetPassword { + email: string + oldPassword?: string + newPassword?: string + token?: string + password?: string } -export interface IUserForgotPassword{ - email: string; - brandLogoUrl?: string, - platformName?: string, +export interface IUserForgotPassword { + email: string + brandLogoUrl?: string + platformName?: string endpoint?: string } export interface IIssueCertificate { - courseCode: string; - courseName: string; - theoryGradeCredits: string; - theoryObtainedEarned: string; - practicalGradeCredits: string; - practicalObtainedEarned: string; + courseCode: string + courseName: string + theoryGradeCredits: string + theoryObtainedEarned: string + practicalGradeCredits: string + practicalObtainedEarned: string } -export interface IPuppeteerOption{ - width: number; - height: number; +export interface IPuppeteerOption { + width: number + height: number } export interface IUserDeletedActivity { - id: string; - userId: string; - orgId: string; - recordType: RecordType; - txnMetadata: Prisma.JsonValue; - deletedBy: string; - deleteDateTime: Date; + id: string + userId: string + orgId: string + recordType: RecordType + txnMetadata: Prisma.JsonValue + deletedBy: string + deleteDateTime: Date } export interface UserKeycloakId { - id: string; - keycloakUserId: string; - email: string; + id: string + keycloakUserId: string + email: string } export interface UserRoleMapping { - id: string; - userId: string; - userRoleId: string; + id: string + userId: string + userRoleId: string } -export interface UserRoleDetails{ - id: string; - role: $Enums.UserRole; +export interface UserRoleDetails { + id: string + role: $Enums.UserRole } export interface IEcosystemConfig { - id: string; - key: string; - value: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - deletedAt: Date | null; -} \ No newline at end of file + id: string + key: string + value: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + deletedAt: Date | null +} diff --git a/apps/user/repositories/fido-user.repository.ts b/apps/user/repositories/fido-user.repository.ts index ea78d1627..0c38a54e7 100644 --- a/apps/user/repositories/fido-user.repository.ts +++ b/apps/user/repositories/fido-user.repository.ts @@ -1,30 +1,32 @@ -import { Injectable, Logger, NotFoundException } from '@nestjs/common'; -import { CreateUserDto } from '../dtos/create-user.dto'; -import { InternalServerErrorException } from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { user } from '@prisma/client'; -import { v4 as uuidv4 } from 'uuid'; +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, type Logger, NotFoundException } from '@nestjs/common' +import { InternalServerErrorException } from '@nestjs/common' +import type { user } from '@prisma/client' +import { v4 as uuidv4 } from 'uuid' +import type { CreateUserDto } from '../dtos/create-user.dto' type UserUpdateData = { - fidoUserId?: string; - isFidoVerified?: boolean; - username?: string; + fidoUserId?: string + isFidoVerified?: boolean + username?: string // Add other properties you want to update -}; +} @Injectable() export class FidoUserRepository { - constructor(private readonly prisma: PrismaService, private readonly logger: Logger) { } + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger + ) {} - /** - * - * @param createUserDto + * + * @param createUserDto * @returns user details */ async createUser(createUserDto: CreateUserDto): Promise { try { - const verifyCode = uuidv4(); + const verifyCode = uuidv4() const saveResponse = await this.prisma.user.create({ data: { @@ -32,21 +34,20 @@ export class FidoUserRepository { email: createUserDto.email, firstName: createUserDto.firstName, lastName: createUserDto.lastName, - verificationCode: verifyCode - } - }); - - return saveResponse; + verificationCode: verifyCode, + }, + }) + return saveResponse } catch (error) { - this.logger.error(`In Create User Repository: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`In Create User Repository: ${JSON.stringify(error)}`) + throw error } } /** - * - * @param email + * + * @param email * @returns User exist details */ @@ -55,75 +56,71 @@ export class FidoUserRepository { try { return this.prisma.user.findFirstOrThrow({ where: { - email - } - }); + email, + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } /** - * - * @param email - * @returns User details - */ + * + * @param email + * @returns User details + */ // eslint-disable-next-line camelcase async getUserDetails(email: string): Promise { try { return this.prisma.user.findFirst({ where: { - email - } - }); + email, + }, + }) } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } /** - * - * @param tenantDetails - * @returns Updates organization details - */ + * + * @param tenantDetails + * @returns Updates organization details + */ // eslint-disable-next-line camelcase - async updateFidoUserDetails(email:string, fidoUserId: string, username: string): Promise { + async updateFidoUserDetails(email: string, fidoUserId: string, username: string): Promise { try { const updateUserDetails = await this.prisma.user.update({ where: { - email + email, }, data: { fidoUserId, - username - } - }); - return updateUserDetails; - + username, + }, + }) + return updateUserDetails } catch (error) { - this.logger.error(`Error in update isEmailVerified: ${error.message} `); - throw error; + this.logger.error(`Error in update isEmailVerified: ${error.message} `) + throw error } } - - async updateUserDetails(email:string, additionalParams:UserUpdateData[]): Promise { + async updateUserDetails(email: string, additionalParams: UserUpdateData[]): Promise { try { const updateUserDetails = await this.prisma.user.update({ where: { - email + email, }, - data: { ...additionalParams[0]} - }); - return updateUserDetails; - + data: { ...additionalParams[0] }, + }) + return updateUserDetails } catch (error) { - this.logger.error(`Error in update isEmailVerified: ${error.message} `); - throw error; + this.logger.error(`Error in update isEmailVerified: ${error.message} `) + throw error } } } - diff --git a/apps/user/repositories/user-device.repository.ts b/apps/user/repositories/user-device.repository.ts index f9935f81b..d268b16b7 100644 --- a/apps/user/repositories/user-device.repository.ts +++ b/apps/user/repositories/user-device.repository.ts @@ -1,26 +1,29 @@ -import { Injectable, Logger, NotFoundException } from '@nestjs/common'; -import { InternalServerErrorException } from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, type Logger, NotFoundException } from '@nestjs/common' +import { InternalServerErrorException } from '@nestjs/common' // eslint-disable-next-line camelcase -import { Prisma, user_devices } from '@prisma/client'; +import type { Prisma, user_devices } from '@prisma/client' type FidoMultiDevicePayload = { - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - devices: Prisma.JsonValue; - credentialId: string; - deviceFriendlyName: string; - id: string; -}[]; + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + devices: Prisma.JsonValue + credentialId: string + deviceFriendlyName: string + id: string +}[] @Injectable() export class UserDevicesRepository { - constructor(private readonly prisma: PrismaService, private readonly logger: Logger) { } + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger + ) {} /** - * - * @param email + * + * @param email * @returns User exist details */ @@ -29,98 +32,95 @@ export class UserDevicesRepository { try { return this.prisma.user_devices.findFirst({ where: { - userId:String(userId) - } - }); + userId: String(userId), + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } /** - * - * @param createFidoMultiDevice - * @returns Device details - */ + * + * @param createFidoMultiDevice + * @returns Device details + */ // eslint-disable-next-line camelcase async createMultiDevice(newDevice: Prisma.JsonValue, userId: string): Promise { try { - const saveResponse = await this.prisma.user_devices.create({ data: { devices: newDevice, - userId:String(userId), + userId: String(userId), createdBy: userId, - lastChangedBy: userId - } - }); - - return saveResponse; + lastChangedBy: userId, + }, + }) + return saveResponse } catch (error) { - this.logger.error(`In Create User Repository: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`In Create User Repository: ${JSON.stringify(error)}`) + throw error } } /** - * - * @param userId - * @returns Device details - */ + * + * @param userId + * @returns Device details + */ // eslint-disable-next-line camelcase async fidoMultiDevice(userId: string): Promise { try { const userDetails = await this.prisma.user_devices.findMany({ where: { - userId:String(userId), - deletedAt: null + userId: String(userId), + deletedAt: null, }, orderBy: { - createDateTime: 'desc' - } - }); + createDateTime: 'desc', + }, + }) - return userDetails; + return userDetails } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } /** - * - * @param userId - * @returns Get all device details - */ + * + * @param userId + * @returns Get all device details + */ // eslint-disable-next-line camelcase, @typescript-eslint/no-explicit-any async getfidoMultiDevice(userId: string): Promise { try { - const fidoMultiDevice = await this.prisma.user_devices.findMany({ where: { - userId:String(userId) - } - }); - return fidoMultiDevice; + userId: String(userId), + }, + }) + return fidoMultiDevice } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } /** - * - * @param userId - * @returns Get all active device details - */ + * + * @param userId + * @returns Get all active device details + */ async getfidoMultiDeviceDetails(userId: string): Promise { try { const fidoMultiDevice = await this.prisma.user_devices.findMany({ where: { - userId:String(userId), - deletedAt: null + userId: String(userId), + deletedAt: null, }, select: { id: true, @@ -130,162 +130,159 @@ export class UserDevicesRepository { lastChangedBy: true, devices: true, credentialId: true, - deviceFriendlyName: true - } - }); - return fidoMultiDevice; + deviceFriendlyName: true, + }, + }) + return fidoMultiDevice } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } /** - * - * @param credentialId - * @returns Find device details from credentialID - */ + * + * @param credentialId + * @returns Find device details from credentialID + */ async getFidoUserDeviceDetails(credentialId: string): Promise { try { const getUserDevice = await this.prisma.$queryRaw` SELECT * FROM user_devices WHERE credentialId LIKE '%${credentialId}%' LIMIT 1; -`; - return getUserDevice; +` + return getUserDevice } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } /** - * - * @param credentialId - * @param loginCounter - * @returns Update Auth counter - */ + * + * @param credentialId + * @param loginCounter + * @returns Update Auth counter + */ async updateFidoAuthCounter(credentialId: string, loginCounter: number): Promise { try { return await this.prisma.user_devices.updateMany({ where: { - credentialId + credentialId, }, data: { - authCounter: loginCounter - } - }); - + authCounter: loginCounter, + }, + }) } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } /** - * - * @param credentialId - * @returns Device detail for specific credentialId - */ + * + * @param credentialId + * @returns Device detail for specific credentialId + */ // eslint-disable-next-line camelcase async checkUserDeviceByCredentialId(credentialId: string): Promise { try { return await this.prisma.user_devices.findFirst({ where: { - credentialId - } - }); + credentialId, + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } /** - * - * @param credentialId - * @returns Delete device - */ + * + * @param credentialId + * @returns Delete device + */ // eslint-disable-next-line camelcase async deleteUserDeviceByCredentialId(credentialId: string): Promise { try { return await this.prisma.user_devices.updateMany({ where: { - credentialId + credentialId, }, data: { - deletedAt: new Date() - } - }); + deletedAt: new Date(), + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } /** - * - * @param id - * @param deviceName - * @returns Update device name - */ + * + * @param id + * @param deviceName + * @returns Update device name + */ async updateUserDeviceByCredentialId(id: string, deviceName: string): Promise { try { return await this.prisma.user_devices.updateMany({ where: { - id + id, }, data: { - deviceFriendlyName: deviceName - } - }); + deviceFriendlyName: deviceName, + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } /** - * - * @param credentialId - * @param deviceFriendlyName - * @returns Get device details name for specific credentialId - */ + * + * @param credentialId + * @param deviceFriendlyName + * @returns Get device details name for specific credentialId + */ async updateDeviceByCredentialId(credentialId: string): Promise { try { return await this.prisma.$queryRaw` SELECT * FROM user_devices WHERE devices->>'credentialID' = ${credentialId} - `; + ` } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } /** - * - * @param id - * @param credentialId - * @param deviceFriendlyName - * @returns Update device name for specific credentialId - */ + * + * @param id + * @param credentialId + * @param deviceFriendlyName + * @returns Update device name for specific credentialId + */ // eslint-disable-next-line camelcase async addCredentialIdAndNameById(id: string, updateFidoUserDetails: string): Promise { - try { return await this.prisma.user_devices.update({ where: { - id + id, }, data: { credentialId: JSON.parse(updateFidoUserDetails).credentialId, - deviceFriendlyName: JSON.parse(updateFidoUserDetails).updateFidoUserDetailsDto.deviceFriendlyName - } - }); + deviceFriendlyName: JSON.parse(updateFidoUserDetails).updateFidoUserDetailsDto.deviceFriendlyName, + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } - } diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index 1cc3efad2..7f17c1e41 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -1,29 +1,29 @@ /* eslint-disable prefer-destructuring */ -import { Injectable, Logger, NotFoundException, InternalServerErrorException } from '@nestjs/common'; -import { +import type { UserRole } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, InternalServerErrorException, type Logger, NotFoundException } from '@nestjs/common' +// eslint-disable-next-line camelcase +import type { RecordType, schema, token, user, user_org_roles } from '@prisma/client' +import type { IOrgUsers, - PlatformSettings, - IShareUserCertificate, - UpdateUserProfile, ISendVerificationEmail, - IUsersProfile, + IShareUserCertificate, + IUserDeletedActivity, IUserInformation, + IUsersProfile, IVerifyUserEmail, - IUserDeletedActivity, + PlatformSettings, + UpdateUserProfile, UserKeycloakId, + UserRoleDetails, UserRoleMapping, - UserRoleDetails -} from '../interfaces/user.interface'; -import { PrismaService } from '@credebl/prisma-service'; -// eslint-disable-next-line camelcase -import { RecordType, schema, token, user, user_org_roles } from '@prisma/client'; -import { UserRole } from '@credebl/enum/enum'; +} from '../interfaces/user.interface' interface UserQueryOptions { - id?: string; // Use the appropriate type based on your data model - email?: string; // Use the appropriate type based on your data model - username?: string; + id?: string // Use the appropriate type based on your data model + email?: string // Use the appropriate type based on your data model + username?: string // Add more properties if needed for other unique identifier fields } @@ -43,7 +43,7 @@ export class UserRepository { try { const saveResponse = await this.prisma.user.upsert({ where: { - email: userEmailVerification.email + email: userEmailVerification.email, }, create: { username: userEmailVerification.username, @@ -51,17 +51,17 @@ export class UserRepository { verificationCode: verifyCode.toString(), clientId: userEmailVerification.clientId, clientSecret: userEmailVerification.clientSecret, - publicProfile: true + publicProfile: true, }, update: { - verificationCode: verifyCode.toString() - } - }); + verificationCode: verifyCode.toString(), + }, + }) - return saveResponse; + return saveResponse } catch (error) { - this.logger.error(`In Create User Repository: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`In Create User Repository: ${JSON.stringify(error)}`) + throw error } } @@ -76,12 +76,12 @@ export class UserRepository { try { return this.prisma.user.findFirst({ where: { - email - } - }); + email, + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new error(); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new error() } } @@ -94,12 +94,12 @@ export class UserRepository { try { return this.prisma.user.findFirst({ where: { - email - } - }); + email, + }, + }) } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } @@ -110,10 +110,10 @@ export class UserRepository { */ async getUserById(id: string): Promise { const queryOptions: UserQueryOptions = { - id - }; + id, + } - return this.findUser(queryOptions); + return this.findUser(queryOptions) } /** @@ -123,10 +123,10 @@ export class UserRepository { */ async getUserPublicProfile(username: string): Promise { const queryOptions: UserQueryOptions = { - username - }; + username, + } - return this.findUserForPublicProfile(queryOptions); + return this.findUserForPublicProfile(queryOptions) } /** @@ -138,19 +138,19 @@ export class UserRepository { try { const userdetails = await this.prisma.user.update({ where: { - id: String(updateUserProfile.id) + id: String(updateUserProfile.id), }, data: { profileImg: updateUserProfile.profileImg, firstName: updateUserProfile.firstName, lastName: updateUserProfile.lastName, - publicProfile: updateUserProfile?.isPublic - } - }); - return userdetails; + publicProfile: updateUserProfile?.isPublic, + }, + }) + return userdetails } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -163,7 +163,7 @@ export class UserRepository { try { return this.prisma.user.findFirst({ where: { - supabaseUserId: id + supabaseUserId: id, }, select: { id: true, @@ -181,16 +181,16 @@ export class UserRepository { organisation: { include: { // eslint-disable-next-line camelcase - org_agents: true - } - } - } - } - } - }); + org_agents: true, + }, + }, + }, + }, + }, + }) } catch (error) { - this.logger.error(`Not Found: ${JSON.stringify(error)}`); - throw new NotFoundException(error); + this.logger.error(`Not Found: ${JSON.stringify(error)}`) + throw new NotFoundException(error) } } @@ -203,7 +203,7 @@ export class UserRepository { try { return this.prisma.user.findFirstOrThrow({ where: { - keycloakUserId: id + keycloakUserId: id, }, select: { id: true, @@ -222,24 +222,24 @@ export class UserRepository { organisation: { include: { // eslint-disable-next-line camelcase - org_agents: true - } - } - } - } - } - }); + org_agents: true, + }, + }, + }, + }, + }, + }) } catch (error) { - this.logger.error(`error in getUserByKeycloakId: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error in getUserByKeycloakId: ${JSON.stringify(error)}`) + throw error } } async findUserByEmail(email: string): Promise { const queryOptions: UserQueryOptions = { - email - }; - return this.findUser(queryOptions); + email, + } + return this.findUser(queryOptions) } async findUser(queryOptions: UserQueryOptions): Promise { @@ -247,12 +247,12 @@ export class UserRepository { where: { OR: [ { - id: queryOptions.id + id: queryOptions.id, }, { - email: queryOptions.email - } - ] + email: queryOptions.email, + }, + ], }, select: { id: true, @@ -275,8 +275,8 @@ export class UserRepository { select: { id: true, name: true, - description: true - } + description: true, + }, }, organisation: { select: { @@ -289,13 +289,13 @@ export class UserRepository { publicProfile: true, countryId: true, stateId: true, - cityId: true - } - } - } - } - } - }); + cityId: true, + }, + }, + }, + }, + }, + }) } async findUserForPublicProfile(queryOptions: UserQueryOptions): Promise { @@ -304,15 +304,15 @@ export class UserRepository { publicProfile: true, OR: [ { - id: String(queryOptions.id) + id: String(queryOptions.id), }, { - email: queryOptions.email + email: queryOptions.email, }, { - username: queryOptions.username - } - ] + username: queryOptions.username, + }, + ], }, select: { id: true, @@ -332,8 +332,8 @@ export class UserRepository { select: { id: true, name: true, - description: true - } + description: true, + }, }, organisation: { select: { @@ -346,13 +346,13 @@ export class UserRepository { publicProfile: true, countryId: true, stateId: true, - cityId: true - } - } - } - } - } - }); + cityId: true, + }, + }, + }, + }, + }, + }) } /** @@ -365,17 +365,17 @@ export class UserRepository { try { const updateUserDetails = await this.prisma.user.update({ where: { - id + id, }, data: { isEmailVerified: true, - keycloakUserId: keycloakId - } - }); - return updateUserDetails; + keycloakUserId: keycloakId, + }, + }) + return updateUserDetails } catch (error) { - this.logger.error(`Error in update isEmailVerified: ${error.message} `); - throw error; + this.logger.error(`Error in update isEmailVerified: ${error.message} `) + throw error } } @@ -389,17 +389,17 @@ export class UserRepository { try { const updateUserDetails = await this.prisma.user.update({ where: { - email + email, }, data: { firstName: userInfo.firstName, - lastName: userInfo.lastName - } - }); - return updateUserDetails; + lastName: userInfo.lastName, + }, + }) + return updateUserDetails } catch (error) { - this.logger.error(`Error in update isEmailVerified: ${error.message} `); - throw error; + this.logger.error(`Error in update isEmailVerified: ${error.message} `) + throw error } } @@ -418,7 +418,7 @@ export class UserRepository { const result = await this.prisma.$transaction([ this.prisma.user.findMany({ where: { - ...queryOptions // Spread the dynamic condition object + ...queryOptions, // Spread the dynamic condition object }, select: { id: true, @@ -429,7 +429,7 @@ export class UserRepository { isEmailVerified: true, userOrgRoles: { where: { - ...filterOptions + ...filterOptions, // Additional filtering conditions if needed }, select: { @@ -440,8 +440,8 @@ export class UserRepository { select: { id: true, name: true, - description: true - } + description: true, + }, }, organisation: { select: { @@ -459,32 +459,32 @@ export class UserRepository { agentSpinUpStatus: true, agentsTypeId: true, createDateTime: true, - orgAgentTypeId: true - } - } - } - } - } - } + orgAgentTypeId: true, + }, + }, + }, + }, + }, + }, }, take: pageSize, skip: (pageNumber - 1) * pageSize, orderBy: { - createDateTime: 'desc' - } + createDateTime: 'desc', + }, }), this.prisma.user.count({ where: { - ...queryOptions - } - }) - ]); + ...queryOptions, + }, + }), + ]) - const users = result[0]; - const totalCount = result[1]; - const totalPages = Math.ceil(totalCount / pageSize); + const users = result[0] + const totalCount = result[1] + const totalPages = Math.ceil(totalCount / pageSize) - return { totalPages, users }; + return { totalPages, users } } /** @@ -498,7 +498,7 @@ export class UserRepository { this.prisma.user.findMany({ where: { ...queryOptions, // Spread the dynamic condition object - publicProfile: true + publicProfile: true, }, select: { id: true, @@ -510,39 +510,39 @@ export class UserRepository { isEmailVerified: true, clientId: false, clientSecret: false, - supabaseUserId: false + supabaseUserId: false, }, take: pageSize, skip: (pageNumber - 1) * pageSize, orderBy: { - createDateTime: 'desc' - } + createDateTime: 'desc', + }, }), this.prisma.user.count({ where: { - ...queryOptions - } - }) - ]); + ...queryOptions, + }, + }), + ]) - const users = result[0]; - const totalCount = result[1]; - const totalPages = Math.ceil(totalCount / pageSize); + const users = result[0] + const totalCount = result[1] + const totalPages = Math.ceil(totalCount / pageSize) - return { totalPages, users }; + return { totalPages, users } } async getAttributesBySchemaId(shareUserCertificate: IShareUserCertificate): Promise { try { const getAttributes = await this.prisma.schema.findFirst({ where: { - schemaLedgerId: shareUserCertificate.schemaId - } - }); - return getAttributes; + schemaLedgerId: shareUserCertificate.schemaId, + }, + }) + return getAttributes } catch (error) { - this.logger.error(`checkSchemaExist:${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkSchemaExist:${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -550,12 +550,12 @@ export class UserRepository { try { return this.prisma.user.findUnique({ where: { - email - } - }); + email, + }, + }) } catch (error) { - this.logger.error(`checkUserExist: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`checkUserExist: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -563,16 +563,16 @@ export class UserRepository { try { const updateUserDetails = await this.prisma.user.update({ where: { - email + email, }, data: { - isEmailVerified: true - } - }); - return updateUserDetails; + isEmailVerified: true, + }, + }) + return updateUserDetails } catch (error) { - this.logger.error(`Error in update isEmailVerified: ${error.message} `); - throw error; + this.logger.error(`Error in update isEmailVerified: ${error.message} `) + throw error } } @@ -586,16 +586,16 @@ export class UserRepository { try { const updateUserDetails = await this.prisma.user.update({ where: { - email + email, }, data: { - password: userInfo - } - }); - return updateUserDetails; + password: userInfo, + }, + }) + return updateUserDetails } catch (error) { - this.logger.error(`Error in update isEmailVerified: ${error.message} `); - throw error; + this.logger.error(`Error in update isEmailVerified: ${error.message} `) + throw error } } @@ -612,13 +612,13 @@ export class UserRepository { data: { token, userId, - expiresAt: expireTime - } - }); - return createResetPasswordToken; + expiresAt: expireTime, + }, + }) + return createResetPasswordToken } catch (error) { - this.logger.error(`Error in createTokenForResetPassword: ${error.message} `); - throw error; + this.logger.error(`Error in createTokenForResetPassword: ${error.message} `) + throw error } } @@ -633,13 +633,13 @@ export class UserRepository { const tokenDetails = await this.prisma.token.findUnique({ where: { userId, - token - } - }); - return tokenDetails; + token, + }, + }) + return tokenDetails } catch (error) { - this.logger.error(`Error in getResetPasswordTokenDetails: ${error.message} `); - throw error; + this.logger.error(`Error in getResetPasswordTokenDetails: ${error.message} `) + throw error } } @@ -652,13 +652,13 @@ export class UserRepository { try { const tokenDeleteDetails = await this.prisma.token.delete({ where: { - id - } - }); - return tokenDeleteDetails; + id, + }, + }) + return tokenDeleteDetails } catch (error) { - this.logger.error(`Error in deleteResetPasswordToken: ${error.message} `); - throw error; + this.logger.error(`Error in deleteResetPasswordToken: ${error.message} `) + throw error } } @@ -669,38 +669,45 @@ export class UserRepository { */ async updatePlatformSettings(updatePlatformSettings: PlatformSettings): Promise { try { - const getPlatformDetails = await this.prisma.platform_config.findFirst(); + const getPlatformDetails = await this.prisma.platform_config.findFirst() const platformDetails = await this.prisma.platform_config.update({ where: { - id: getPlatformDetails.id + id: getPlatformDetails.id, }, data: { externalIp: updatePlatformSettings.externalIp, inboundEndpoint: updatePlatformSettings.inboundEndpoint, sgApiKey: updatePlatformSettings.sgApiKey, emailFrom: updatePlatformSettings.emailFrom, - apiEndpoint: updatePlatformSettings.apiEndPoint - } - }); + apiEndpoint: updatePlatformSettings.apiEndPoint, + }, + }) - return platformDetails; + return platformDetails } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } async getPlatformSettings(): Promise { try { - const getPlatformSettingsList = await this.prisma.platform_config.findMany(); - return getPlatformSettingsList; + const getPlatformSettingsList = await this.prisma.platform_config.findMany() + return getPlatformSettingsList } catch (error) { - this.logger.error(`error in getPlatformSettings: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error in getPlatformSettings: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } - async updateOrgDeletedActivity(orgId: string, userId: string, deletedBy: string, recordType: RecordType, userEmail: string, txnMetadata: object): Promise { + async updateOrgDeletedActivity( + orgId: string, + userId: string, + deletedBy: string, + recordType: RecordType, + userEmail: string, + txnMetadata: object + ): Promise { try { const orgDeletedActivity = await this.prisma.user_org_delete_activity.create({ data: { @@ -709,32 +716,32 @@ export class UserRepository { deletedBy, recordType, txnMetadata, - userId - } - }); - return orgDeletedActivity; + userId, + }, + }) + return orgDeletedActivity } catch (error) { - this.logger.error(`Error in updateOrgDeletedActivity: ${error} `); - throw error; + this.logger.error(`Error in updateOrgDeletedActivity: ${error} `) + throw error } } async getUserDetailsByUserId(userId: string): Promise<{ - email: string; + email: string }> { try { const getUserDetails = await this.prisma.user.findUnique({ where: { - id: userId + id: userId, }, select: { - email: true - } - }); - return getUserDetails; + email: true, + }, + }) + return getUserDetails } catch (error) { - this.logger.error(`Error in getting user details: ${error} `); - throw error; + this.logger.error(`Error in getting user details: ${error} `) + throw error } } @@ -743,44 +750,46 @@ export class UserRepository { const users = await this.prisma.user.findMany({ where: { email: { - in: userEmails - } + in: userEmails, + }, }, select: { email: true, keycloakUserId: true, - id: true - } - }); + id: true, + }, + }) // Create a map for quick lookup of keycloakUserId, id, and email by email - const userMap = new Map(users.map(user => [user.email, { id: user.id, keycloakUserId: user.keycloakUserId, email: user.email }])); + const userMap = new Map( + users.map((user) => [user.email, { id: user.id, keycloakUserId: user.keycloakUserId, email: user.email }]) + ) // Collect the keycloakUserId, id, and email in the order of input emails - const result = userEmails.map(email => { - const user = userMap.get(email); - return { id: user?.id || null, keycloakUserId: user?.keycloakUserId || null, email }; - }); + const result = userEmails.map((email) => { + const user = userMap.get(email) + return { id: user?.id || null, keycloakUserId: user?.keycloakUserId || null, email } + }) - return result; + return result } catch (error) { - this.logger.error(`Error in getUserKeycloak: ${error}`); - throw error; + this.logger.error(`Error in getUserKeycloak: ${error}`) + throw error } } - + async storeUserRole(userId: string, userRoleId: string): Promise { try { const userRoleMapping = await this.prisma.user_role_mapping.create({ data: { userId, - userRoleId - } - }); - return userRoleMapping; + userRoleId, + }, + }) + return userRoleMapping } catch (error) { - this.logger.error(`Error in storeUserRole: ${error.message} `); - throw error; + this.logger.error(`Error in storeUserRole: ${error.message} `) + throw error } } @@ -788,31 +797,29 @@ export class UserRepository { try { const getUserRole = await this.prisma.user_role.findFirstOrThrow({ where: { - role - } - }); - return getUserRole; + role, + }, + }) + return getUserRole } catch (error) { - this.logger.error(`Error in getUserRole: ${error.message} `); - throw error; + this.logger.error(`Error in getUserRole: ${error.message} `) + throw error } } - // eslint-disable-next-line camelcase - async handleGetUserOrganizations(userId: string): Promise { - try { + // eslint-disable-next-line camelcase + async handleGetUserOrganizations(userId: string): Promise { + try { const getUserOrgs = await this.prisma.user_org_roles.findMany({ where: { - userId - } - }); - - return getUserOrgs; + userId, + }, + }) + + return getUserOrgs } catch (error) { - this.logger.error( - `Error in handleGetUserOrganizations: ${error.message}` - ); - throw error; + this.logger.error(`Error in handleGetUserOrganizations: ${error.message}`) + throw error } } -} \ No newline at end of file +} diff --git a/apps/user/src/fido/dtos/fido-user.dto.ts b/apps/user/src/fido/dtos/fido-user.dto.ts index e8a5ea82a..04c65962d 100644 --- a/apps/user/src/fido/dtos/fido-user.dto.ts +++ b/apps/user/src/fido/dtos/fido-user.dto.ts @@ -1,160 +1,159 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsArray, IsBoolean, IsOptional, IsString, ValidateNested } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { IsArray, IsBoolean, IsOptional, IsString, ValidateNested } from 'class-validator' export class GenerateRegistrationDto { - email: string; - - @IsOptional() - @ApiProperty({ example: 'false' }) - @IsBoolean({ message: 'isPasskey should be boolean' }) - deviceFlag: boolean; + email: string + + @IsOptional() + @ApiProperty({ example: 'false' }) + @IsBoolean({ message: 'isPasskey should be boolean' }) + deviceFlag: boolean } class ResponseDto { - @ApiProperty() - @IsString() - attestationObject: string; - - @ApiProperty() - @IsString() - clientDataJSON: string; - - @ApiProperty() - @IsArray() - transports: string[]; - } - - class ClientExtensionResultsDto { - @ApiProperty() - @ValidateNested() - credProps: Record; - } - - export class VerifyRegistrationDetailsDto { - @ApiProperty() - @IsString() - id: string; - - @ApiProperty() - @IsString() - rawId: string; - - @ApiProperty() - response: ResponseDto; - - @ApiProperty() - @IsString() - type: string; - - @ApiProperty() - clientExtensionResults: ClientExtensionResultsDto; - - @ApiProperty() - @IsString() - authenticatorAttachment: string; - - @ApiProperty() - @IsString() - challangeId: string; - } - - export class VerifyRegistrationPayloadDto { - @ApiProperty() - verifyRegistrationDetails: VerifyRegistrationDetailsDto; - - @ApiProperty() - @IsString() - email: string; - } - - export class GenerateAuthentication { - userName: string; - } - - + @ApiProperty() + @IsString() + attestationObject: string + + @ApiProperty() + @IsString() + clientDataJSON: string + + @ApiProperty() + @IsArray() + transports: string[] +} + +class ClientExtensionResultsDto { + @ApiProperty() + @ValidateNested() + credProps: Record +} + +export class VerifyRegistrationDetailsDto { + @ApiProperty() + @IsString() + id: string + + @ApiProperty() + @IsString() + rawId: string + + @ApiProperty() + response: ResponseDto + + @ApiProperty() + @IsString() + type: string + + @ApiProperty() + clientExtensionResults: ClientExtensionResultsDto + + @ApiProperty() + @IsString() + authenticatorAttachment: string + + @ApiProperty() + @IsString() + challangeId: string +} + +export class VerifyRegistrationPayloadDto { + @ApiProperty() + verifyRegistrationDetails: VerifyRegistrationDetailsDto + + @ApiProperty() + @IsString() + email: string +} + +export class GenerateAuthentication { + userName: string +} + class VerifyAuthenticationResponseDto { - @ApiProperty() - @IsString() - authenticatorData: string; - - @ApiProperty() - @IsString() - clientDataJSON: string; - - @ApiProperty() - @IsString() - signature: string; - - @ApiProperty() - @IsString() - userHandle: string; - } - - export class VerifyAuthenticationDto { - @ApiProperty() - @IsString() - id: string; - - @ApiProperty() - @IsString() - rawId: string; - - @ApiProperty() - response: VerifyAuthenticationResponseDto; - - @ApiProperty() - @IsString() - type: string; - - @ApiProperty() - clientExtensionResults: ClientExtensionResultsDto; - - @ApiProperty() - @IsString() - authenticatorAttachment: string; - - @ApiProperty() - @IsString() - challangeId: string; - } - - export class VerifyAuthenticationPayloadDto { - @ApiProperty() - verifyAuthenticationDetails: VerifyAuthenticationDto; - email: string; - } - - export class UpdateFidoUserDetailsDto { - @ApiProperty() - @IsString() - userName: string; - - @ApiProperty() - @IsString() - credentialId: string; - - @ApiProperty() - @IsString() - deviceFriendlyName: string; - } - - export class UserNameDto { - @ApiProperty() - @IsString() - email: string; - } - - export class credentialDto { - @ApiProperty() - @IsString() - credentialId: string; - } - - export class updateDeviceDto { - @ApiProperty() - @IsString() - credentialId: string; - - @ApiProperty() - @IsString() - deviceName: string; - } \ No newline at end of file + @ApiProperty() + @IsString() + authenticatorData: string + + @ApiProperty() + @IsString() + clientDataJSON: string + + @ApiProperty() + @IsString() + signature: string + + @ApiProperty() + @IsString() + userHandle: string +} + +export class VerifyAuthenticationDto { + @ApiProperty() + @IsString() + id: string + + @ApiProperty() + @IsString() + rawId: string + + @ApiProperty() + response: VerifyAuthenticationResponseDto + + @ApiProperty() + @IsString() + type: string + + @ApiProperty() + clientExtensionResults: ClientExtensionResultsDto + + @ApiProperty() + @IsString() + authenticatorAttachment: string + + @ApiProperty() + @IsString() + challangeId: string +} + +export class VerifyAuthenticationPayloadDto { + @ApiProperty() + verifyAuthenticationDetails: VerifyAuthenticationDto + email: string +} + +export class UpdateFidoUserDetailsDto { + @ApiProperty() + @IsString() + userName: string + + @ApiProperty() + @IsString() + credentialId: string + + @ApiProperty() + @IsString() + deviceFriendlyName: string +} + +export class UserNameDto { + @ApiProperty() + @IsString() + email: string +} + +export class credentialDto { + @ApiProperty() + @IsString() + credentialId: string +} + +export class updateDeviceDto { + @ApiProperty() + @IsString() + credentialId: string + + @ApiProperty() + @IsString() + deviceName: string +} diff --git a/apps/user/src/fido/fido.controller.ts b/apps/user/src/fido/fido.controller.ts index 676c26a6c..092f9c82f 100644 --- a/apps/user/src/fido/fido.controller.ts +++ b/apps/user/src/fido/fido.controller.ts @@ -1,87 +1,96 @@ -import { Controller, Logger } from '@nestjs/common'; -import { MessagePattern } from '@nestjs/microservices'; -import { GenerateRegistrationDto, VerifyRegistrationPayloadDto, VerifyAuthenticationPayloadDto, UpdateFidoUserDetailsDto, UserNameDto, credentialDto, updateDeviceDto, GenerateAuthentication } from './dtos/fido-user.dto'; -import { FidoService } from './fido.service'; +import { Controller, Logger } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { + GenerateAuthentication, + GenerateRegistrationDto, + UpdateFidoUserDetailsDto, + UserNameDto, + VerifyAuthenticationPayloadDto, + VerifyRegistrationPayloadDto, + credentialDto, + updateDeviceDto, +} from './dtos/fido-user.dto' +import type { FidoService } from './fido.service' @Controller('fido') export class FidoController { - constructor(private readonly fidoService: FidoService) { } - private readonly logger = new Logger('PS-Fido-controller'); + constructor(private readonly fidoService: FidoService) {} + private readonly logger = new Logger('PS-Fido-controller') - /** + /** * Description: FIDO User Registration * @param payload Registration Details * @returns Get registered user response */ - @MessagePattern({ cmd: 'generate-registration-options' }) - async generateRegistrationOption(payload: GenerateRegistrationDto): Promise { - return this.fidoService.generateRegistration(payload); - } + @MessagePattern({ cmd: 'generate-registration-options' }) + async generateRegistrationOption(payload: GenerateRegistrationDto): Promise { + return this.fidoService.generateRegistration(payload) + } - /** + /** * Description: FIDO User Registration * @param payload Verify registration * @returns Get verify registration response */ - @MessagePattern({ cmd: 'verify-registration' }) - verifyRegistration(payload: VerifyRegistrationPayloadDto): Promise { - return this.fidoService.verifyRegistration(payload); - } - /** + @MessagePattern({ cmd: 'verify-registration' }) + verifyRegistration(payload: VerifyRegistrationPayloadDto): Promise { + return this.fidoService.verifyRegistration(payload) + } + /** * Description: FIDO User Verification * @param payload Authentication details * @returns Get authentication response */ - @MessagePattern({ cmd: 'generate-authentication-options' }) - generateAuthenticationOption(payload: GenerateAuthentication): Promise { - const { userName } = payload; - return this.fidoService.generateAuthenticationOption(userName); - } - /** + @MessagePattern({ cmd: 'generate-authentication-options' }) + generateAuthenticationOption(payload: GenerateAuthentication): Promise { + const { userName } = payload + return this.fidoService.generateAuthenticationOption(userName) + } + /** * Description: FIDO User Verification * @param payload Verify authentication details * @returns Get verify authentication details response */ - @MessagePattern({ cmd: 'verify-authentication' }) - verifyAuthentication(payload: VerifyAuthenticationPayloadDto): Promise { - return this.fidoService.verifyAuthentication(payload); - } - /** + @MessagePattern({ cmd: 'verify-authentication' }) + verifyAuthentication(payload: VerifyAuthenticationPayloadDto): Promise { + return this.fidoService.verifyAuthentication(payload) + } + /** * Description: FIDO User update * @param payload User Details * @returns Get updated user detail response */ - @MessagePattern({ cmd: 'update-user' }) - updateUser(payload: UpdateFidoUserDetailsDto): Promise { - return this.fidoService.updateUser(payload); - } - /** + @MessagePattern({ cmd: 'update-user' }) + updateUser(payload: UpdateFidoUserDetailsDto): Promise { + return this.fidoService.updateUser(payload) + } + /** * Description: fetch FIDO user details * @param payload User name - * + * */ - @MessagePattern({ cmd: 'fetch-fido-user-details' }) - fetchFidoUserDetails(payload: UserNameDto):Promise { - return this.fidoService.fetchFidoUserDetails(payload.email); - } + @MessagePattern({ cmd: 'fetch-fido-user-details' }) + fetchFidoUserDetails(payload: UserNameDto): Promise { + return this.fidoService.fetchFidoUserDetails(payload.email) + } - /** + /** * Description: delete FIDO user details * @param payload credentialId - * + * */ - @MessagePattern({ cmd: 'delete-fido-user-device' }) - deleteFidoUserDevice(payload: credentialDto):Promise { - return this.fidoService.deleteFidoUserDevice(payload); - } + @MessagePattern({ cmd: 'delete-fido-user-device' }) + deleteFidoUserDevice(payload: credentialDto): Promise { + return this.fidoService.deleteFidoUserDevice(payload) + } - /** + /** * Description: update FIDO user details * @param payload credentialId and deviceName - * + * */ - @MessagePattern({ cmd: 'update-fido-user-device-name' }) - updateFidoUserDeviceName(payload: updateDeviceDto):Promise { - return this.fidoService.updateFidoUserDeviceName(payload); - } + @MessagePattern({ cmd: 'update-fido-user-device-name' }) + updateFidoUserDeviceName(payload: updateDeviceDto): Promise { + return this.fidoService.updateFidoUserDeviceName(payload) + } } diff --git a/apps/user/src/fido/fido.module.ts b/apps/user/src/fido/fido.module.ts index e3125189a..3e8c740fc 100644 --- a/apps/user/src/fido/fido.module.ts +++ b/apps/user/src/fido/fido.module.ts @@ -1,26 +1,26 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Logger, Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' -import { ClientRegistrationService } from '@credebl/client-registration'; -import { CommonModule } from '@credebl/common'; -import { FidoController } from './fido.controller'; -import { FidoService } from './fido.service'; -import { FidoUserRepository } from '../../repositories/fido-user.repository'; -import { HttpModule } from '@nestjs/axios'; -import { KeycloakUrlService } from '@credebl/keycloak-url'; -import { OrgRolesRepository } from 'libs/org-roles/repositories'; -import { OrgRolesService } from '@credebl/org-roles'; -import { PrismaService } from '@credebl/prisma-service'; -import { SupabaseService } from '@credebl/supabase'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { UserActivityService } from '@credebl/user-activity'; -import { UserDevicesRepository } from '../../repositories/user-device.repository'; -import { UserOrgRolesRepository } from 'libs/user-org-roles/repositories'; -import { UserOrgRolesService } from '@credebl/user-org-roles'; -import { UserRepository } from '../../repositories/user.repository'; -import { UserService } from '../user.service'; -import { AwsService } from '@credebl/aws'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { ClientRegistrationService } from '@credebl/client-registration' +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { KeycloakUrlService } from '@credebl/keycloak-url' +import { OrgRolesService } from '@credebl/org-roles' +import { PrismaService } from '@credebl/prisma-service' +import { SupabaseService } from '@credebl/supabase' +import { UserActivityService } from '@credebl/user-activity' +import { UserOrgRolesService } from '@credebl/user-org-roles' +import { HttpModule } from '@nestjs/axios' +import { OrgRolesRepository } from 'libs/org-roles/repositories' +import { UserActivityRepository } from 'libs/user-activity/repositories' +import { UserOrgRolesRepository } from 'libs/user-org-roles/repositories' +import { FidoUserRepository } from '../../repositories/fido-user.repository' +import { UserDevicesRepository } from '../../repositories/user-device.repository' +import { UserRepository } from '../../repositories/user.repository' +import { UserService } from '../user.service' +import { FidoController } from './fido.controller' +import { FidoService } from './fido.service' @Module({ imports: [ @@ -29,13 +29,13 @@ import { NATSClient } from '@credebl/common/NATSClient'; name: 'NATS_CLIENT', transport: Transport.NATS, options: { - servers: [`${process.env.NATS_URL}`] - } - } + servers: [`${process.env.NATS_URL}`], + }, + }, ]), HttpModule, - CommonModule -], + CommonModule, + ], controllers: [FidoController], providers: [ AwsService, @@ -55,7 +55,7 @@ import { NATSClient } from '@credebl/common/NATSClient'; UserOrgRolesRepository, UserActivityService, UserActivityRepository, - NATSClient -] + NATSClient, + ], }) -export class FidoModule { } +export class FidoModule {} diff --git a/apps/user/src/fido/fido.service.ts b/apps/user/src/fido/fido.service.ts index e5b3b90db..e1228f863 100644 --- a/apps/user/src/fido/fido.service.ts +++ b/apps/user/src/fido/fido.service.ts @@ -1,246 +1,255 @@ -import { BadRequestException, Injectable, Logger, NotFoundException, InternalServerErrorException } from '@nestjs/common'; //InternalServerErrorException -import { CommonService } from '@credebl/common'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { RpcException } from '@nestjs/microservices'; -import { FidoUserRepository } from '../../repositories/fido-user.repository'; -import { GenerateRegistrationDto, VerifyRegistrationPayloadDto, VerifyAuthenticationPayloadDto, UpdateFidoUserDetailsDto, credentialDto, updateDeviceDto } from './dtos/fido-user.dto'; -import { UserDevicesRepository } from '../../repositories/user-device.repository'; -import { PrismaService } from '@credebl/prisma-service'; -import { LoginUserDto } from 'apps/user/dtos/login-user.dto'; -import { UserService } from '../user.service'; +import type { CommonService } from '@credebl/common' +import { ResponseMessages } from '@credebl/common/response-messages' +import type { PrismaService } from '@credebl/prisma-service' +import { + BadRequestException, + Injectable, + InternalServerErrorException, + Logger, + NotFoundException, +} from '@nestjs/common' //InternalServerErrorException +import { RpcException } from '@nestjs/microservices' +import type { LoginUserDto } from 'apps/user/dtos/login-user.dto' +import type { FidoUserRepository } from '../../repositories/fido-user.repository' +import type { UserDevicesRepository } from '../../repositories/user-device.repository' +import type { UserService } from '../user.service' +import type { + GenerateRegistrationDto, + UpdateFidoUserDetailsDto, + VerifyAuthenticationPayloadDto, + VerifyRegistrationPayloadDto, + credentialDto, + updateDeviceDto, +} from './dtos/fido-user.dto' @Injectable() export class FidoService { - private readonly logger = new Logger('PS-Fido-Service'); - constructor( - private readonly fidoUserRepository: FidoUserRepository, - private readonly userDevicesRepository: UserDevicesRepository, - private readonly commonService: CommonService, - private readonly userService: UserService, - private readonly prisma: PrismaService - ) { } - async generateRegistration(payload: GenerateRegistrationDto): Promise { - try { - const { email, deviceFlag } = payload; - const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()); - if (!fidoUser && !fidoUser.id) { - throw new NotFoundException(ResponseMessages.user.error.notFound); - } - - if (!fidoUser || true === deviceFlag || false === deviceFlag) { - const generatedOption = await this.generateRegistrationOption(email.toLowerCase()); - return generatedOption; - } else if (!fidoUser.isFidoVerified) { - const generatedOption = await this.updateUserRegistrationOption(email.toLowerCase()); - return generatedOption; - } else { - throw new BadRequestException(ResponseMessages.fido.error.exists); - } - } catch (error) { - this.logger.error(`Error in generate registration option:::${error}`); - throw new RpcException(error.response); - } + private readonly logger = new Logger('PS-Fido-Service') + constructor( + private readonly fidoUserRepository: FidoUserRepository, + private readonly userDevicesRepository: UserDevicesRepository, + private readonly commonService: CommonService, + private readonly userService: UserService, + private readonly prisma: PrismaService + ) {} + async generateRegistration(payload: GenerateRegistrationDto): Promise { + try { + const { email, deviceFlag } = payload + const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()) + if (!fidoUser && !fidoUser.id) { + throw new NotFoundException(ResponseMessages.user.error.notFound) + } + + if (!fidoUser || deviceFlag === true || deviceFlag === false) { + const generatedOption = await this.generateRegistrationOption(email.toLowerCase()) + return generatedOption + } + if (!fidoUser.isFidoVerified) { + const generatedOption = await this.updateUserRegistrationOption(email.toLowerCase()) + return generatedOption + } + throw new BadRequestException(ResponseMessages.fido.error.exists) + } catch (error) { + this.logger.error(`Error in generate registration option:::${error}`) + throw new RpcException(error.response) } - - generateRegistrationOption(email: string): Promise { - const url = `${process.env.FIDO_API_ENDPOINT}/generate-registration-options/?userName=${email.toLowerCase()}`; - return this.commonService - .httpGet(url, { headers: { 'Content-Type': 'application/json' } }) - .then(async (response) => { - const { user } = response; - const updateUser = await this.fidoUserRepository.updateUserDetails(email.toLowerCase(), [ - {fidoUserId:user.id}, - {username:user.name} - ]); - if (updateUser.fidoUserId === user.id) { - return response; - } else { - throw new InternalServerErrorException(ResponseMessages.fido.error.generateRegistration); - } - }); - } - - updateUserRegistrationOption(email: string): Promise { - const url = `${process.env.FIDO_API_ENDPOINT}/generate-registration-options/?userName=${email.toLowerCase()}`; - return this.commonService - .httpGet(url, { headers: { 'Content-Type': 'application/json' } }) - .then(async (response) => { - const { user } = response; - await this.fidoUserRepository.updateUserDetails(email.toLowerCase(), [ - {fidoUserId:user.id}, - {isFidoVerified:false} - ]); - return response; - }); - } - - async verifyRegistration(verifyRegistrationDto: VerifyRegistrationPayloadDto): Promise { - try { - const { verifyRegistrationDetails, email } = verifyRegistrationDto; - const url = `${process.env.FIDO_API_ENDPOINT}/verify-registration`; - const payload = JSON.stringify(verifyRegistrationDetails); - const response = await this.commonService.httpPost(url, payload, { - headers: { 'Content-Type': 'application/json' } - }); - if (response?.verified && email.toLowerCase()) { - await this.fidoUserRepository.updateUserDetails(email.toLowerCase(), [{isFidoVerified:true}]); - const credentialID = response.newDevice.credentialID.replace(/=*$/, ''); - response.newDevice.credentialID = credentialID; - const getUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()); - await this.userDevicesRepository.createMultiDevice(response?.newDevice, getUser.id); - return response; - } else { - throw new InternalServerErrorException(ResponseMessages.fido.error.verification); - } - } catch (error) { - this.logger.error(`Error in verify registration option:::${error}`); - throw new RpcException(error); + } + + generateRegistrationOption(email: string): Promise { + const url = `${process.env.FIDO_API_ENDPOINT}/generate-registration-options/?userName=${email.toLowerCase()}` + return this.commonService + .httpGet(url, { headers: { 'Content-Type': 'application/json' } }) + .then(async (response) => { + const { user } = response + const updateUser = await this.fidoUserRepository.updateUserDetails(email.toLowerCase(), [ + { fidoUserId: user.id }, + { username: user.name }, + ]) + if (updateUser.fidoUserId === user.id) { + return response } + throw new InternalServerErrorException(ResponseMessages.fido.error.generateRegistration) + }) + } + + updateUserRegistrationOption(email: string): Promise { + const url = `${process.env.FIDO_API_ENDPOINT}/generate-registration-options/?userName=${email.toLowerCase()}` + return this.commonService + .httpGet(url, { headers: { 'Content-Type': 'application/json' } }) + .then(async (response) => { + const { user } = response + await this.fidoUserRepository.updateUserDetails(email.toLowerCase(), [ + { fidoUserId: user.id }, + { isFidoVerified: false }, + ]) + return response + }) + } + + async verifyRegistration(verifyRegistrationDto: VerifyRegistrationPayloadDto): Promise { + try { + const { verifyRegistrationDetails, email } = verifyRegistrationDto + const url = `${process.env.FIDO_API_ENDPOINT}/verify-registration` + const payload = JSON.stringify(verifyRegistrationDetails) + const response = await this.commonService.httpPost(url, payload, { + headers: { 'Content-Type': 'application/json' }, + }) + if (response?.verified && email.toLowerCase()) { + await this.fidoUserRepository.updateUserDetails(email.toLowerCase(), [{ isFidoVerified: true }]) + const credentialID = response.newDevice.credentialID.replace(/=*$/, '') + response.newDevice.credentialID = credentialID + const getUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()) + await this.userDevicesRepository.createMultiDevice(response?.newDevice, getUser.id) + return response + } + throw new InternalServerErrorException(ResponseMessages.fido.error.verification) + } catch (error) { + this.logger.error(`Error in verify registration option:::${error}`) + throw new RpcException(error) } - - async generateAuthenticationOption(email: string): Promise { - try { - const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email?.toLowerCase()); - if (fidoUser && fidoUser.id) { - const fidoMultiDevice = await this.userDevicesRepository.getfidoMultiDevice(fidoUser.id); - const credentialIds = []; - if (fidoMultiDevice) { - for (const iterator of fidoMultiDevice) { - credentialIds.push(iterator.devices['credentialID']); - } - } else { - throw new BadRequestException(ResponseMessages.fido.error.deviceNotFound); - } - const url = `${process.env.FIDO_API_ENDPOINT}/generate-authentication-options`; - return await this.commonService - .httpPost(url, credentialIds, { headers: { 'Content-Type': 'application/json' } }) - .then(async (response) => response); - } else { - throw new BadRequestException(ResponseMessages.fido.error.invalidCredentials); - } - } catch (error) { - this.logger.error(`Error in generate authentication option:::${JSON.stringify(error)}`); - throw new RpcException(error.response); + } + + async generateAuthenticationOption(email: string): Promise { + try { + const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email?.toLowerCase()) + if (fidoUser?.id) { + const fidoMultiDevice = await this.userDevicesRepository.getfidoMultiDevice(fidoUser.id) + const credentialIds = [] + if (fidoMultiDevice) { + for (const iterator of fidoMultiDevice) { + credentialIds.push(iterator.devices.credentialID) + } + } else { + throw new BadRequestException(ResponseMessages.fido.error.deviceNotFound) } + const url = `${process.env.FIDO_API_ENDPOINT}/generate-authentication-options` + return await this.commonService + .httpPost(url, credentialIds, { headers: { 'Content-Type': 'application/json' } }) + .then(async (response) => response) + } + throw new BadRequestException(ResponseMessages.fido.error.invalidCredentials) + } catch (error) { + this.logger.error(`Error in generate authentication option:::${JSON.stringify(error)}`) + throw new RpcException(error.response) } - - async verifyAuthentication(verifyAuthenticationDto: VerifyAuthenticationPayloadDto): Promise { - try { - const { verifyAuthenticationDetails, email } = verifyAuthenticationDto; - const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()); - const fidoMultiDevice = await this.userDevicesRepository.getfidoMultiDeviceDetails(fidoUser.id); - const url = `${process.env.FIDO_API_ENDPOINT}/verify-authentication`; - const payload = { verifyAuthenticationDetails: JSON.stringify(verifyAuthenticationDetails), devices: fidoMultiDevice }; - - const credentialIdChars = { - '-': '+', - '_': '/' - }; - - const verifyAuthenticationId = verifyAuthenticationDetails.id.replace(/[-_]/g, replaceCredentialId => credentialIdChars[replaceCredentialId]); - const credentialId = `${verifyAuthenticationId}`; - const getUserDevice = await this.userDevicesRepository.checkUserDeviceByCredentialId(credentialId); - if (getUserDevice) { - const loginCounter = getUserDevice?.authCounter + 1; - if (!payload.devices) { - throw new BadRequestException(ResponseMessages.fido.error.deviceNotFound); - } else { - return await this.commonService - .httpPost(url, payload, { headers: { 'Content-Type': 'application/json' } }) - .then(async (response) => { - if (true === response.verified) { - await this.userDevicesRepository.updateFidoAuthCounter(credentialId, loginCounter); - const userDetails: LoginUserDto = { - email, - isPasskey: response.verified - }; - const authDetails = await this.userService.login(userDetails); - return authDetails; - } else { - throw new BadRequestException(ResponseMessages.fido.error.deviceNotFound); - } - - }); - } - } else { - throw new InternalServerErrorException(ResponseMessages.fido.error.deviceNotFound); - } - } catch (error) { - - this.logger.error(`Error in verify authentication:::${error}`); - throw new RpcException(ResponseMessages.fido.error.deviceNotFound); + } + + async verifyAuthentication(verifyAuthenticationDto: VerifyAuthenticationPayloadDto): Promise { + try { + const { verifyAuthenticationDetails, email } = verifyAuthenticationDto + const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()) + const fidoMultiDevice = await this.userDevicesRepository.getfidoMultiDeviceDetails(fidoUser.id) + const url = `${process.env.FIDO_API_ENDPOINT}/verify-authentication` + const payload = { + verifyAuthenticationDetails: JSON.stringify(verifyAuthenticationDetails), + devices: fidoMultiDevice, + } + + const credentialIdChars = { + '-': '+', + _: '/', + } + + const verifyAuthenticationId = verifyAuthenticationDetails.id.replace( + /[-_]/g, + (replaceCredentialId) => credentialIdChars[replaceCredentialId] + ) + const credentialId = `${verifyAuthenticationId}` + const getUserDevice = await this.userDevicesRepository.checkUserDeviceByCredentialId(credentialId) + if (getUserDevice) { + const loginCounter = getUserDevice?.authCounter + 1 + if (!payload.devices) { + throw new BadRequestException(ResponseMessages.fido.error.deviceNotFound) } - } - - async updateUser(updateFidoUserDetailsDto: UpdateFidoUserDetailsDto): Promise { - try { - - const updateFidoUserDetails = JSON.stringify(updateFidoUserDetailsDto); - const updateFidoUser = await this.userDevicesRepository.updateDeviceByCredentialId(updateFidoUserDetailsDto.credentialId); - - if (updateFidoUser[0].id) { - await this.userDevicesRepository.addCredentialIdAndNameById(updateFidoUser[0].id, updateFidoUserDetails); - + return await this.commonService + .httpPost(url, payload, { headers: { 'Content-Type': 'application/json' } }) + .then(async (response) => { + if (response.verified === true) { + await this.userDevicesRepository.updateFidoAuthCounter(credentialId, loginCounter) + const userDetails: LoginUserDto = { + email, + isPasskey: response.verified, + } + const authDetails = await this.userService.login(userDetails) + return authDetails } - if (updateFidoUser[0].id) { - return 'User updated.'; - } else { - throw new InternalServerErrorException(ResponseMessages.fido.error.updateFidoUser); - } - - } catch (error) { - this.logger.error(`Error in update user details:::${error}`); - throw new RpcException(error); - } + throw new BadRequestException(ResponseMessages.fido.error.deviceNotFound) + }) + } + throw new InternalServerErrorException(ResponseMessages.fido.error.deviceNotFound) + } catch (error) { + this.logger.error(`Error in verify authentication:::${error}`) + throw new RpcException(ResponseMessages.fido.error.deviceNotFound) } - - async fetchFidoUserDetails(email: string): Promise { - try { - const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()); - if (!fidoUser) { - throw new NotFoundException(ResponseMessages.user.error.notFound); - } - const multiDevice = await this.userDevicesRepository.fidoMultiDevice(fidoUser.id); - if (multiDevice) { - return multiDevice; - } else { - throw new RpcException(Error); - } - } catch (error) { - this.logger.error(`Error in fetching the user details:::${error}`); - throw new RpcException(error); - } + } + + async updateUser(updateFidoUserDetailsDto: UpdateFidoUserDetailsDto): Promise { + try { + const updateFidoUserDetails = JSON.stringify(updateFidoUserDetailsDto) + const updateFidoUser = await this.userDevicesRepository.updateDeviceByCredentialId( + updateFidoUserDetailsDto.credentialId + ) + + if (updateFidoUser[0].id) { + await this.userDevicesRepository.addCredentialIdAndNameById(updateFidoUser[0].id, updateFidoUserDetails) + } + if (updateFidoUser[0].id) { + return 'User updated.' + } + throw new InternalServerErrorException(ResponseMessages.fido.error.updateFidoUser) + } catch (error) { + this.logger.error(`Error in update user details:::${error}`) + throw new RpcException(error) } - - async deleteFidoUserDevice(payload: credentialDto): Promise { - try { - const { credentialId } = payload; - await this.userDevicesRepository.checkUserDeviceByCredentialId(credentialId); - const deleteUserDevice = await this.userDevicesRepository.deleteUserDeviceByCredentialId(credentialId); - if (1 === deleteUserDevice.count) { - return 'Device deleted successfully'; - } else { - return 'Not deleting this device kindly verify'; - } - } catch (error) { - this.logger.error(`Error in delete user device :::${error}`); - throw new RpcException(error); - } + } + + async fetchFidoUserDetails(email: string): Promise { + try { + const fidoUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()) + if (!fidoUser) { + throw new NotFoundException(ResponseMessages.user.error.notFound) + } + const multiDevice = await this.userDevicesRepository.fidoMultiDevice(fidoUser.id) + if (multiDevice) { + return multiDevice + } + throw new RpcException(Error) + } catch (error) { + this.logger.error(`Error in fetching the user details:::${error}`) + throw new RpcException(error) } - - async updateFidoUserDeviceName(payload: updateDeviceDto): Promise { - try { - const { credentialId, deviceName } = payload; - const getUserDevice = await this.userDevicesRepository.checkUserDeviceByCredentialId(credentialId); - const updateUserDevice = await this.userDevicesRepository.updateUserDeviceByCredentialId(getUserDevice.id, deviceName); - if (1 === updateUserDevice.count) { - return 'Device name updated successfully.'; - } else { - return 'Device name has not been changed.'; - } - } catch (error) { - this.logger.error(`Error in delete user device :::${error}`); - throw new RpcException(error); - } + } + + async deleteFidoUserDevice(payload: credentialDto): Promise { + try { + const { credentialId } = payload + await this.userDevicesRepository.checkUserDeviceByCredentialId(credentialId) + const deleteUserDevice = await this.userDevicesRepository.deleteUserDeviceByCredentialId(credentialId) + if (deleteUserDevice.count === 1) { + return 'Device deleted successfully' + } + return 'Not deleting this device kindly verify' + } catch (error) { + this.logger.error(`Error in delete user device :::${error}`) + throw new RpcException(error) + } + } + + async updateFidoUserDeviceName(payload: updateDeviceDto): Promise { + try { + const { credentialId, deviceName } = payload + const getUserDevice = await this.userDevicesRepository.checkUserDeviceByCredentialId(credentialId) + const updateUserDevice = await this.userDevicesRepository.updateUserDeviceByCredentialId( + getUserDevice.id, + deviceName + ) + if (updateUserDevice.count === 1) { + return 'Device name updated successfully.' + } + return 'Device name has not been changed.' + } catch (error) { + this.logger.error(`Error in delete user device :::${error}`) + throw new RpcException(error) } + } } diff --git a/apps/user/src/main.ts b/apps/user/src/main.ts index 502c43950..a3b52e790 100644 --- a/apps/user/src/main.ts +++ b/apps/user/src/main.ts @@ -1,23 +1,23 @@ -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { NestFactory } from '@nestjs/core'; -import { UserModule } from './user.module'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { UserModule } from './user.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { const app = await NestFactory.createMicroservice(UserModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.USER_SERVICE, process.env.USER_NKEY_SEED) - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.USER_SERVICE, process.env.USER_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('User Microservice is listening to NATS '); + await app.listen() + logger.log('User Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 3616b2d92..2b497eb2b 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -1,115 +1,137 @@ -import { IOrgUsers, Payload, ICheckUserDetails, PlatformSettings, UpdateUserProfile, IUsersProfile, IUserInformation, IUserSignIn, IUserResetPassword, IUserDeletedActivity, UserKeycloakId, IUserForgotPassword} from '../interfaces/user.interface'; -import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; -import { Controller } from '@nestjs/common'; -import { MessagePattern } from '@nestjs/microservices'; -import { UserService } from './user.service'; -import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; +import type { + IResetPasswordResponse, + ISendVerificationEmail, + ISignInUser, + ISignUpUserResponse, + IUserInvitations, + IVerifyUserEmail, +} from '@credebl/common/interfaces/user.interface' +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' // eslint-disable-next-line camelcase -import { user, user_org_roles } from '@prisma/client'; -import { IUsersActivity } from 'libs/user-activity/interface'; -import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations, IResetPasswordResponse, ISignUpUserResponse } from '@credebl/common/interfaces/user.interface'; -import { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; +import type { user, user_org_roles } from '@prisma/client' +import type { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto' +import type { IUsersActivity } from 'libs/user-activity/interface' +import type { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto' +import type { VerifyEmailTokenDto } from '../dtos/verify-email.dto' +import type { + ICheckUserDetails, + IOrgUsers, + IUserDeletedActivity, + IUserForgotPassword, + IUserInformation, + IUserResetPassword, + IUserSignIn, + IUsersProfile, + Payload, + PlatformSettings, + UpdateUserProfile, + UserKeycloakId, +} from '../interfaces/user.interface' +import type { UserService } from './user.service' @Controller() export class UserController { - constructor(private readonly userService: UserService) { } + constructor(private readonly userService: UserService) {} /** * Description: Registers new user - * @param email + * @param email * @returns User's verification email sent status */ @MessagePattern({ cmd: 'send-verification-mail' }) - async sendVerificationMail(payload: { userEmailVerification: ISendVerificationEmail }): Promise { - return this.userService.sendVerificationMail(payload.userEmailVerification); + async sendVerificationMail(payload: { + userEmailVerification: ISendVerificationEmail + }): Promise { + return this.userService.sendVerificationMail(payload.userEmailVerification) } /** * Description: Verify user's email * @param email * @param verificationcode - * @returns User's email verification status + * @returns User's email verification status */ @MessagePattern({ cmd: 'user-email-verification' }) async verifyEmail(payload: { param: VerifyEmailTokenDto }): Promise { - return this.userService.verifyEmail(payload.param); + return this.userService.verifyEmail(payload.param) } - /** - * @body loginUserDto - * @returns User's access token details - */ + /** + * @body loginUserDto + * @returns User's access token details + */ @MessagePattern({ cmd: 'user-holder-login' }) async login(payload: IUserSignIn): Promise { - const loginRes = await this.userService.login(payload); - return loginRes; + const loginRes = await this.userService.login(payload) + return loginRes } @MessagePattern({ cmd: 'refresh-token-details' }) async refreshTokenDetails(refreshToken: string): Promise { - return this.userService.refreshTokenDetails(refreshToken); + return this.userService.refreshTokenDetails(refreshToken) } @MessagePattern({ cmd: 'user-reset-password' }) async resetPassword(payload: IUserResetPassword): Promise { - return this.userService.resetPassword(payload); + return this.userService.resetPassword(payload) } @MessagePattern({ cmd: 'user-set-token-password' }) - async resetTokenPassword(payload: IUserResetPassword): Promise { - return this.userService.resetTokenPassword(payload); + async resetTokenPassword(payload: IUserResetPassword): Promise { + return this.userService.resetTokenPassword(payload) } @MessagePattern({ cmd: 'user-forgot-password' }) async forgotPassword(payload: IUserForgotPassword): Promise { - return this.userService.forgotPassword(payload); + return this.userService.forgotPassword(payload) } @MessagePattern({ cmd: 'get-user-profile' }) async getProfile(payload: { id }): Promise { - return this.userService.getProfile(payload); + return this.userService.getProfile(payload) } @MessagePattern({ cmd: 'get-user-public-profile' }) async getPublicProfile(payload: { username }): Promise { - return this.userService.getPublicProfile(payload); + 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); + return this.userService.updateUserProfile(payload.updateUserProfileDto) } @MessagePattern({ cmd: 'get-user-by-supabase' }) async findSupabaseUser(payload: { id }): Promise { - return this.userService.findSupabaseUser(payload); + return this.userService.findSupabaseUser(payload) } @MessagePattern({ cmd: 'get-user-by-keycloak' }) async findKeycloakUser(payload: { id }): Promise { - return this.userService.findKeycloakUser(payload); + return this.userService.findKeycloakUser(payload) } @MessagePattern({ cmd: 'get-user-by-mail' }) async findUserByEmail(payload: { email }): Promise { - return this.userService.findUserByEmail(payload); + return this.userService.findUserByEmail(payload) } @MessagePattern({ cmd: 'get-user-by-user-id' }) async findUserByUserId(id: string): Promise { - return this.userService.findUserByUserId(id); + return this.userService.findUserByUserId(id) } /** * @returns Organization invitation data */ @MessagePattern({ cmd: 'get-org-invitations' }) - async invitations(payload: { id; status; pageNumber; pageSize; search; }): Promise { - return this.userService.invitations(payload); + async invitations(payload: { id; status; pageNumber; pageSize; search }): Promise { + return this.userService.invitations(payload) } - + /** * * @param payload @@ -117,10 +139,10 @@ export class UserController { */ @MessagePattern({ cmd: 'accept-reject-invitations' }) async acceptRejectInvitations(payload: { - acceptRejectInvitation: AcceptRejectInvitationDto; - userId: string; + acceptRejectInvitation: AcceptRejectInvitationDto + userId: string }): Promise { - return this.userService.acceptRejectInvitations(payload.acceptRejectInvitation, payload.userId); + return this.userService.acceptRejectInvitations(payload.acceptRejectInvitation, payload.userId) } /** @@ -129,86 +151,100 @@ export class UserController { * @returns organization users list */ @MessagePattern({ cmd: 'fetch-organization-user' }) - async getOrganizationUsers(payload: {orgId:string} & Payload): Promise { - return this.userService.getOrgUsers(payload.orgId, payload.pageNumber, payload.pageSize, payload.search); + async getOrganizationUsers(payload: { orgId: string } & Payload): Promise { + return this.userService.getOrgUsers(payload.orgId, payload.pageNumber, payload.pageSize, payload.search) } /** - * @param payload - * @returns organization users list - */ + * @param payload + * @returns organization users list + */ @MessagePattern({ cmd: 'fetch-users' }) - async get(payload: { pageNumber: number, pageSize: number, search: string }): Promise { - const users = this.userService.get(payload.pageNumber, payload.pageSize, payload.search); - return users; - } - - /** - * @param email - * @returns User's email exist status - * */ + async get(payload: { pageNumber: number; pageSize: number; search: string }): Promise { + 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 { - return this.userService.checkUserExist(payload.userEmail); + return this.userService.checkUserExist(payload.userEmail) } /** - * @body userInfo - * @returns User's registration status - */ + * @body userInfo + * @returns User's registration status + */ @MessagePattern({ cmd: 'add-user' }) async addUserDetailsInKeyCloak(payload: { userInfo: IUserInformation }): Promise { - return this.userService.createUserForToken(payload.userInfo); + return this.userService.createUserForToken(payload.userInfo) } // Fetch Users recent activities @MessagePattern({ cmd: 'get-user-activity' }) - async getUserActivity(payload: { userId: string, limit: number }): Promise { - return this.userService.getUserActivity(payload.userId, payload.limit); + async getUserActivity(payload: { userId: string; limit: number }): Promise { + return this.userService.getUserActivity(payload.userId, payload.limit) } @MessagePattern({ cmd: 'add-passkey' }) - async addPasskey(payload: { userEmail: string, userInfo: AddPasskeyDetailsDto }): Promise { - return this.userService.addPasskey(payload.userEmail, payload.userInfo); + async addPasskey(payload: { userEmail: string; userInfo: AddPasskeyDetailsDto }): Promise { + return this.userService.addPasskey(payload.userEmail, payload.userInfo) } - /** + /** * @returns platform settings updated status */ @MessagePattern({ cmd: 'update-platform-settings' }) async updatePlatformSettings(payload: { platformSettings: PlatformSettings }): Promise { - return this.userService.updatePlatformSettings(payload.platformSettings); + return this.userService.updatePlatformSettings(payload.platformSettings) } /** * @returns platform settings */ @MessagePattern({ cmd: 'fetch-platform-settings' }) async getPlatformSettings(): Promise { - return this.userService.getPlatformSettings(); + return this.userService.getPlatformSettings() } @MessagePattern({ cmd: 'org-deleted-activity' }) - async updateOrgDeletedActivity(payload: { orgId, userId, deletedBy, recordType, userEmail, txnMetadata }): Promise { - return this.userService.updateOrgDeletedActivity(payload.orgId, payload.userId, payload.deletedBy, payload.recordType, payload.userEmail, payload.txnMetadata); + async updateOrgDeletedActivity(payload: { + orgId + userId + deletedBy + recordType + userEmail + txnMetadata + }): Promise { + return this.userService.updateOrgDeletedActivity( + payload.orgId, + payload.userId, + payload.deletedBy, + payload.recordType, + payload.userEmail, + payload.txnMetadata + ) } @MessagePattern({ cmd: 'get-user-details-by-userId' }) async getUserDetailsByUserId(payload: { userId: string }): Promise { - const { userId } = payload; - return this.userService.getUserDetails(userId); + const { userId } = payload + return this.userService.getUserDetails(userId) } @MessagePattern({ cmd: 'get-user-keycloak-id' }) async getUserKeycloakIdByEmail(userEmails: string[]): Promise { - return this.userService.getUserKeycloakIdByEmail(userEmails); + return this.userService.getUserKeycloakIdByEmail(userEmails) } @MessagePattern({ cmd: 'get-user-info-by-user-email-keycloak' }) - async getUserByUserIdInKeycloak(payload: {email}): Promise { - return this.userService.getUserByUserIdInKeycloak(payload.email); + async getUserByUserIdInKeycloak(payload: { email }): Promise { + return this.userService.getUserByUserIdInKeycloak(payload.email) } @MessagePattern({ cmd: 'get-user-organizations' }) // eslint-disable-next-line camelcase - async getuserOrganizationByUserId(payload: {userId: string}): Promise { - return this.userService.getuserOrganizationByUserId(payload.userId); + async getuserOrganizationByUserId(payload: { userId: string }): Promise { + return this.userService.getuserOrganizationByUserId(payload.userId) } -} \ No newline at end of file +} diff --git a/apps/user/src/user.module.ts b/apps/user/src/user.module.ts index a8e262790..237cc324e 100644 --- a/apps/user/src/user.module.ts +++ b/apps/user/src/user.module.ts @@ -1,30 +1,30 @@ -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { Logger, Module } from '@nestjs/common'; -import { OrgRolesModule, OrgRolesService } from '@credebl/org-roles'; +import { OrgRolesModule, OrgRolesService } from '@credebl/org-roles' +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' -import { ClientRegistrationService } from '@credebl/client-registration'; -import { CommonModule } from '@credebl/common'; -import { FidoModule } from './fido/fido.module'; -import { KeycloakUrlService } from '@credebl/keycloak-url'; -import { OrgRolesRepository } from 'libs/org-roles/repositories'; -import { PrismaService } from '@credebl/prisma-service'; -import { SupabaseService } from '@credebl/supabase'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { UserActivityService } from '@credebl/user-activity'; -import { UserController } from './user.controller'; -import { UserOrgRolesRepository } from 'libs/user-org-roles/repositories'; -import { UserOrgRolesService } from '@credebl/user-org-roles'; -import { UserRepository } from '../repositories/user.repository'; -import { UserService } from './user.service'; -import { UserDevicesRepository } from '../repositories/user-device.repository'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { AwsService } from '@credebl/aws'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { AwsService } from '@credebl/aws' +import { ClientRegistrationService } from '@credebl/client-registration' +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { KeycloakUrlService } from '@credebl/keycloak-url' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { SupabaseService } from '@credebl/supabase' +import { UserActivityService } from '@credebl/user-activity' +import { UserOrgRolesService } from '@credebl/user-org-roles' +import { OrgRolesRepository } from 'libs/org-roles/repositories' +import { UserActivityRepository } from 'libs/user-activity/repositories' +import { UserOrgRolesRepository } from 'libs/user-org-roles/repositories' +import { UserDevicesRepository } from '../repositories/user-device.repository' +import { UserRepository } from '../repositories/user.repository' +import { FidoModule } from './fido/fido.module' +import { UserController } from './user.controller' +import { UserService } from './user.service' @Module({ imports: [ @@ -32,16 +32,18 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.USER_SERVICE, process.env.USER_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.USER_SERVICE, process.env.USER_NKEY_SEED), + }, ]), - + CommonModule, GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, + LoggerModule, + PlatformConfig, + ContextInterceptorModule, FidoModule, - OrgRolesModule -], + OrgRolesModule, + ], controllers: [UserController], providers: [ AwsService, @@ -59,7 +61,7 @@ import { NATSClient } from '@credebl/common/NATSClient'; UserActivityService, UserActivityRepository, UserDevicesRepository, - NATSClient - ] + NATSClient, + ], }) export class UserModule {} diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index aec67200e..3a708ad7f 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -2,62 +2,68 @@ import { BadRequestException, ConflictException, + HttpException, + Inject, Injectable, - Logger, + InternalServerErrorException, + type Logger, NotFoundException, UnauthorizedException, - InternalServerErrorException, - Inject, - HttpException -} from '@nestjs/common'; - - -import { ClientRegistrationService } from '@credebl/client-registration'; -import { CommonService } from '@credebl/common'; -import { EmailDto } from '@credebl/common/dtos/email.dto'; -import { LoginUserDto } from '../dtos/login-user.dto'; -import { OrgRoles } from 'libs/org-roles/enums'; -import { OrgRolesService } from '@credebl/org-roles'; -import { PrismaService } from '@credebl/prisma-service'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { URLUserEmailTemplate } from '../templates/user-email-template'; -import { UserOrgRolesService } from '@credebl/user-org-roles'; -import { UserRepository } from '../repositories/user.repository'; -import { VerifyEmailTokenDto } from '../dtos/verify-email.dto'; -import { sendEmail } from '@credebl/common/send-grid-helper-file'; +} from '@nestjs/common' + +import type { AwsService } from '@credebl/aws' +import type { ClientRegistrationService } from '@credebl/client-registration' +import type { CommonService } from '@credebl/common' +import type { NATSClient } from '@credebl/common/NATSClient' +import { toNumber } from '@credebl/common/cast.helper' +import { DISALLOWED_EMAIL_DOMAIN } from '@credebl/common/common.constant' +import { EmailDto } from '@credebl/common/dtos/email.dto' +import type { + IResetPasswordResponse, + ISendVerificationEmail, + ISignInUser, + ISignUpUserResponse, + IUserInvitations, + IVerifyUserEmail, +} from '@credebl/common/interfaces/user.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { sendEmail } from '@credebl/common/send-grid-helper-file' +import { Invitation, UserRole } from '@credebl/enum/enum' +import type { OrgRolesService } from '@credebl/org-roles' +import type { PrismaService } from '@credebl/prisma-service' +import type { SupabaseService } from '@credebl/supabase' +import type { UserActivityService } from '@credebl/user-activity' +import type { UserOrgRolesService } from '@credebl/user-org-roles' +import { type ClientProxy, RpcException } from '@nestjs/microservices' // eslint-disable-next-line camelcase -import { RecordType, user, user_org_roles } from '@prisma/client'; -import { +import type { RecordType, user, user_org_roles } from '@prisma/client' +import type { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto' +import * as jwt from 'jsonwebtoken' +import { OrgRoles } from 'libs/org-roles/enums' +import type { IUsersActivity } from 'libs/user-activity/interface' +import { v4 as uuidv4 } from 'uuid' +import validator from 'validator' +import type { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto' +import type { LoginUserDto } from '../dtos/login-user.dto' +import type { VerifyEmailTokenDto } from '../dtos/verify-email.dto' +import type { ICheckUserDetails, + IEcosystemConfig, + IOrgUsers, + IUserDeletedActivity, + IUserForgotPassword, + IUserInformation, + IUserResetPassword, + IUsersProfile, OrgInvitations, PlatformSettings, - IOrgUsers, UpdateUserProfile, - IUserInformation, - IUsersProfile, - IUserResetPassword, - IUserDeletedActivity, - UserKeycloakId, - IEcosystemConfig, - IUserForgotPassword -} from '../interfaces/user.interface'; -import { AcceptRejectInvitationDto } from '../dtos/accept-reject-invitation.dto'; -import { UserActivityService } from '@credebl/user-activity'; -import { SupabaseService } from '@credebl/supabase'; -import { UserDevicesRepository } from '../repositories/user-device.repository'; -import { v4 as uuidv4 } from 'uuid'; -import { Invitation, UserRole } from '@credebl/enum/enum'; -import validator from 'validator'; -import { DISALLOWED_EMAIL_DOMAIN } from '@credebl/common/common.constant'; -import { AwsService } from '@credebl/aws'; -import { IUsersActivity } from 'libs/user-activity/interface'; -import { ISendVerificationEmail, ISignInUser, IVerifyUserEmail, IUserInvitations, IResetPasswordResponse, ISignUpUserResponse } from '@credebl/common/interfaces/user.interface'; -import { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto'; -import { URLUserResetPasswordTemplate } from '../templates/reset-password-template'; -import { toNumber } from '@credebl/common/cast.helper'; -import * as jwt from 'jsonwebtoken'; -import { NATSClient } from '@credebl/common/NATSClient'; + UserKeycloakId, +} from '../interfaces/user.interface' +import type { UserDevicesRepository } from '../repositories/user-device.repository' +import type { UserRepository } from '../repositories/user.repository' +import { URLUserResetPasswordTemplate } from '../templates/reset-password-template' +import { URLUserEmailTemplate } from '../templates/user-email-template' @Injectable() export class UserService { @@ -74,7 +80,7 @@ export class UserService { private readonly userDevicesRepository: UserDevicesRepository, private readonly logger: Logger, @Inject('NATS_CLIENT') private readonly userServiceProxy: ClientProxy, - private readonly natsClient : NATSClient + private readonly natsClient: NATSClient ) {} /** @@ -85,78 +91,84 @@ export class UserService { async sendVerificationMail(userEmailVerification: ISendVerificationEmail): Promise { try { - const { email, brandLogoUrl, platformName, clientId, clientSecret } = userEmailVerification; - - if ('PROD' === process.env.PLATFORM_PROFILE_MODE) { + const { email, brandLogoUrl, platformName, clientId, clientSecret } = userEmailVerification + + if (process.env.PLATFORM_PROFILE_MODE === 'PROD') { // eslint-disable-next-line prefer-destructuring - const domain = email.split('@')[1]; + const domain = email.split('@')[1] if (DISALLOWED_EMAIL_DOMAIN.includes(domain)) { - throw new BadRequestException(ResponseMessages.user.error.InvalidEmailDomain); + throw new BadRequestException(ResponseMessages.user.error.InvalidEmailDomain) } } - - const userDetails = await this.userRepository.checkUserExist(email); - + + const userDetails = await this.userRepository.checkUserExist(email) + if (userDetails) { if (userDetails.isEmailVerified) { - throw new ConflictException(ResponseMessages.user.error.exists); + throw new ConflictException(ResponseMessages.user.error.exists) } else { - throw new ConflictException(ResponseMessages.user.error.verificationAlreadySent); + throw new ConflictException(ResponseMessages.user.error.verificationAlreadySent) } } - - const verifyCode = uuidv4(); - let sendVerificationMail: boolean; + + const verifyCode = uuidv4() + let sendVerificationMail: boolean try { + const token = await this.clientRegistrationService.getManagementToken(clientId, clientSecret) + const getClientData = await this.clientRegistrationService.getClientRedirectUrl(clientId, token) - const token = await this.clientRegistrationService.getManagementToken(clientId, clientSecret); - const getClientData = await this.clientRegistrationService.getClientRedirectUrl(clientId, token); + const [redirectUrl] = getClientData[0]?.redirectUris || [] - const [redirectUrl] = getClientData[0]?.redirectUris || []; - if (!redirectUrl) { - throw new NotFoundException(ResponseMessages.user.error.redirectUrlNotFound); + throw new NotFoundException(ResponseMessages.user.error.redirectUrlNotFound) } - - sendVerificationMail = await this.sendEmailForVerification(email, verifyCode, redirectUrl, clientId, brandLogoUrl, platformName); - } catch (error) { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); + + sendVerificationMail = await this.sendEmailForVerification( + email, + verifyCode, + redirectUrl, + clientId, + brandLogoUrl, + platformName + ) + } catch (_error) { + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } - + if (sendVerificationMail) { - const uniqueUsername = await this.createUsername(email, verifyCode); - userEmailVerification.username = uniqueUsername; - userEmailVerification.clientId = clientId; - userEmailVerification.clientSecret = clientSecret; - const resUser = await this.userRepository.createUser(userEmailVerification, verifyCode); - return resUser; - } + const uniqueUsername = await this.createUsername(email, verifyCode) + userEmailVerification.username = uniqueUsername + userEmailVerification.clientId = clientId + userEmailVerification.clientSecret = clientSecret + const resUser = await this.userRepository.createUser(userEmailVerification, verifyCode) + return resUser + } } catch (error) { - this.logger.error(`In Create User : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In Create User : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async createUsername(email: string, verifyCode: string): Promise { try { // eslint-disable-next-line prefer-destructuring - const emailTrim = email.split('@')[0]; + const emailTrim = email.split('@')[0] // Replace special characters with hyphens - const cleanedUsername = emailTrim.toLowerCase().replace(/[^a-zA-Z0-9_]/g, '-'); + const cleanedUsername = emailTrim.toLowerCase().replace(/[^a-zA-Z0-9_]/g, '-') // Generate a 5-digit UUID // eslint-disable-next-line prefer-destructuring - const uuid = verifyCode.split('-')[0]; + const uuid = verifyCode.split('-')[0] // Combine cleaned username and UUID - const uniqueUsername = `${cleanedUsername}-${uuid}`; + const uniqueUsername = `${cleanedUsername}-${uuid}` - return uniqueUsername; + return uniqueUsername } catch (error) { - this.logger.error(`Error in createUsername: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in createUsername: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -168,28 +180,42 @@ export class UserService { * @returns */ - async sendEmailForVerification(email: string, verificationCode: string, redirectUrl: string, clientId: string, brandLogoUrl:string, platformName: string): Promise { + async sendEmailForVerification( + email: string, + verificationCode: string, + redirectUrl: string, + clientId: string, + brandLogoUrl: string, + platformName: string + ): Promise { try { - const platformConfigData = await this.prisma.platform_config.findMany(); - - const decryptClientId = await this.commonService.decryptPassword(clientId); - const urlEmailTemplate = new URLUserEmailTemplate(); - const emailData = new EmailDto(); - emailData.emailFrom = platformConfigData[0].emailFrom; - emailData.emailTo = email; - const platform = platformName || process.env.PLATFORM_NAME; - emailData.emailSubject = `[${platform}] Verify your email to activate your account`; - - emailData.emailHtml = await urlEmailTemplate.getUserURLTemplate(email, verificationCode, redirectUrl, decryptClientId, brandLogoUrl, platformName); - const isEmailSent = await sendEmail(emailData); + const platformConfigData = await this.prisma.platform_config.findMany() + + const decryptClientId = await this.commonService.decryptPassword(clientId) + const urlEmailTemplate = new URLUserEmailTemplate() + const emailData = new EmailDto() + emailData.emailFrom = platformConfigData[0].emailFrom + emailData.emailTo = email + const platform = platformName || process.env.PLATFORM_NAME + emailData.emailSubject = `[${platform}] Verify your email to activate your account` + + emailData.emailHtml = await urlEmailTemplate.getUserURLTemplate( + email, + verificationCode, + redirectUrl, + decryptClientId, + brandLogoUrl, + platformName + ) + const isEmailSent = await sendEmail(emailData) if (isEmailSent) { - return isEmailSent; + return isEmailSent } else { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } } catch (error) { - this.logger.error(`Error in sendEmailForVerification: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in sendEmailForVerification: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -201,161 +227,166 @@ export class UserService { async verifyEmail(param: VerifyEmailTokenDto): Promise { try { - const invalidMessage = ResponseMessages.user.error.invalidEmailUrl; + const invalidMessage = ResponseMessages.user.error.invalidEmailUrl if (!param.verificationCode || !param.email) { - throw new UnauthorizedException(invalidMessage); + throw new UnauthorizedException(invalidMessage) } - const userDetails = await this.userRepository.getUserDetails(param.email); + const userDetails = await this.userRepository.getUserDetails(param.email) if (!userDetails || param.verificationCode !== userDetails.verificationCode) { - throw new UnauthorizedException(invalidMessage); + throw new UnauthorizedException(invalidMessage) } if (userDetails.isEmailVerified) { - throw new ConflictException(ResponseMessages.user.error.verifiedEmail); + throw new ConflictException(ResponseMessages.user.error.verifiedEmail) } if (param.verificationCode === userDetails.verificationCode) { - const verifiedEmail = await this.userRepository.verifyUser(param.email); - return verifiedEmail; + const verifiedEmail = await this.userRepository.verifyUser(param.email) + return verifiedEmail } } catch (error) { - this.logger.error(`error in verifyEmail: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`error in verifyEmail: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async createUserForToken(userInfo: IUserInformation): Promise { try { - const { email } = userInfo; + const { email } = userInfo if (!userInfo.email) { - throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail); + throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail) } - const checkUserDetails = await this.userRepository.getUserDetails(userInfo.email.toLowerCase()); + const checkUserDetails = await this.userRepository.getUserDetails(userInfo.email.toLowerCase()) if (!checkUserDetails) { - throw new NotFoundException(ResponseMessages.user.error.emailIsNotVerified); + throw new NotFoundException(ResponseMessages.user.error.emailIsNotVerified) } if (checkUserDetails.keycloakUserId || (!checkUserDetails.keycloakUserId && checkUserDetails.supabaseUserId)) { - throw new ConflictException(ResponseMessages.user.error.exists); + throw new ConflictException(ResponseMessages.user.error.exists) } - if (false === checkUserDetails.isEmailVerified) { - throw new NotFoundException(ResponseMessages.user.error.verifyEmail); + if (checkUserDetails.isEmailVerified === false) { + throw new NotFoundException(ResponseMessages.user.error.verifyEmail) } - const resUser = await this.userRepository.updateUserInfo(userInfo.email.toLowerCase(), userInfo); + const resUser = await this.userRepository.updateUserInfo(userInfo.email.toLowerCase(), userInfo) if (!resUser) { - throw new NotFoundException(ResponseMessages.user.error.invalidEmail); + throw new NotFoundException(ResponseMessages.user.error.invalidEmail) } - const userDetails = await this.userRepository.getUserDetails(userInfo.email.toLowerCase()); + const userDetails = await this.userRepository.getUserDetails(userInfo.email.toLowerCase()) if (!userDetails) { - throw new NotFoundException(ResponseMessages.user.error.adduser); + throw new NotFoundException(ResponseMessages.user.error.adduser) } - let keycloakDetails = null; - - const token = await this.clientRegistrationService.getManagementToken(checkUserDetails.clientId, checkUserDetails.clientSecret); + let keycloakDetails = null + + const token = await this.clientRegistrationService.getManagementToken( + checkUserDetails.clientId, + checkUserDetails.clientSecret + ) if (userInfo.isPasskey) { - const resUser = await this.userRepository.addUserPassword(email.toLowerCase(), userInfo.password); - const userDetails = await this.userRepository.getUserDetails(email.toLowerCase()); - const decryptedPassword = await this.commonService.decryptPassword(userDetails.password); + const resUser = await this.userRepository.addUserPassword(email.toLowerCase(), userInfo.password) + const userDetails = await this.userRepository.getUserDetails(email.toLowerCase()) + const decryptedPassword = await this.commonService.decryptPassword(userDetails.password) if (!resUser) { - throw new NotFoundException(ResponseMessages.user.error.invalidEmail); + throw new NotFoundException(ResponseMessages.user.error.invalidEmail) } - userInfo.password = decryptedPassword; - try { - keycloakDetails = await this.clientRegistrationService.createUser(userInfo, process.env.KEYCLOAK_REALM, token); - } catch (error) { - throw new InternalServerErrorException('Error while registering user on keycloak'); + userInfo.password = decryptedPassword + try { + keycloakDetails = await this.clientRegistrationService.createUser(userInfo, process.env.KEYCLOAK_REALM, token) + } catch (_error) { + throw new InternalServerErrorException('Error while registering user on keycloak') } } else { - const decryptedPassword = await this.commonService.decryptPassword(userInfo.password); + const decryptedPassword = await this.commonService.decryptPassword(userInfo.password) - userInfo.password = decryptedPassword; + userInfo.password = decryptedPassword - try { - keycloakDetails = await this.clientRegistrationService.createUser(userInfo, process.env.KEYCLOAK_REALM, token); - } catch (error) { - throw new InternalServerErrorException('Error while registering user on keycloak'); + try { + keycloakDetails = await this.clientRegistrationService.createUser(userInfo, process.env.KEYCLOAK_REALM, token) + } catch (_error) { + throw new InternalServerErrorException('Error while registering user on keycloak') } } - await this.userRepository.updateUserDetails(userDetails.id, - keycloakDetails.keycloakUserId.toString() - ); + await this.userRepository.updateUserDetails(userDetails.id, keycloakDetails.keycloakUserId.toString()) if (userInfo?.isHolder) { - const getUserRole = await this.userRepository.getUserRole(UserRole.HOLDER); + const getUserRole = await this.userRepository.getUserRole(UserRole.HOLDER) if (!getUserRole) { - throw new NotFoundException(ResponseMessages.user.error.userRoleNotFound); + throw new NotFoundException(ResponseMessages.user.error.userRoleNotFound) } - await this.userRepository.storeUserRole(userDetails.id, getUserRole?.id); + await this.userRepository.storeUserRole(userDetails.id, getUserRole?.id) } - const realmRoles = await this.clientRegistrationService.getAllRealmRoles(token); - - const holderRole = realmRoles.filter(role => role.name === OrgRoles.HOLDER); - const holderRoleData = 0 < holderRole.length && holderRole[0]; + const realmRoles = await this.clientRegistrationService.getAllRealmRoles(token) + + const holderRole = realmRoles.filter((role) => role.name === OrgRoles.HOLDER) + const holderRoleData = holderRole.length > 0 && holderRole[0] const payload = [ { id: holderRoleData.id, - name: holderRoleData.name - } - ]; + name: holderRoleData.name, + }, + ] - await this.clientRegistrationService.createUserHolderRole(token, keycloakDetails.keycloakUserId.toString(), payload); - const holderOrgRole = await this.orgRoleService.getRole(OrgRoles.HOLDER); - await this.userOrgRoleService.createUserOrgRole(userDetails.id, holderOrgRole.id, null, holderRoleData.id); + await this.clientRegistrationService.createUserHolderRole( + token, + keycloakDetails.keycloakUserId.toString(), + payload + ) + const holderOrgRole = await this.orgRoleService.getRole(OrgRoles.HOLDER) + await this.userOrgRoleService.createUserOrgRole(userDetails.id, holderOrgRole.id, null, holderRoleData.id) - return { userId: userDetails?.id }; + return { userId: userDetails?.id } } catch (error) { - this.logger.error(`Error in createUserForToken: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in createUserForToken: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async addPasskey(email: string, userInfo: AddPasskeyDetailsDto): Promise { try { if (!email.toLowerCase()) { - throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail); + throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail) } - const checkUserDetails = await this.userRepository.getUserDetails(email.toLowerCase()); + const checkUserDetails = await this.userRepository.getUserDetails(email.toLowerCase()) if (!checkUserDetails) { - throw new NotFoundException(ResponseMessages.user.error.invalidEmail); + throw new NotFoundException(ResponseMessages.user.error.invalidEmail) } if (!checkUserDetails.keycloakUserId) { - throw new ConflictException(ResponseMessages.user.error.notFound); + throw new ConflictException(ResponseMessages.user.error.notFound) } - if (false === checkUserDetails.isEmailVerified) { - throw new NotFoundException(ResponseMessages.user.error.emailNotVerified); + if (checkUserDetails.isEmailVerified === false) { + throw new NotFoundException(ResponseMessages.user.error.emailNotVerified) } - const decryptedPassword = await this.commonService.decryptPassword(userInfo.password); - const tokenResponse = await this.generateToken(email.toLowerCase(), decryptedPassword, checkUserDetails); + const decryptedPassword = await this.commonService.decryptPassword(userInfo.password) + const tokenResponse = await this.generateToken(email.toLowerCase(), decryptedPassword, checkUserDetails) if (!tokenResponse) { - throw new UnauthorizedException(ResponseMessages.user.error.invalidCredentials); + throw new UnauthorizedException(ResponseMessages.user.error.invalidCredentials) } - const resUser = await this.userRepository.addUserPassword(email.toLowerCase(), userInfo.password); + const resUser = await this.userRepository.addUserPassword(email.toLowerCase(), userInfo.password) if (!resUser) { - throw new NotFoundException(ResponseMessages.user.error.invalidEmail); + throw new NotFoundException(ResponseMessages.user.error.invalidEmail) } - return ResponseMessages.user.success.updateUserProfile; + return ResponseMessages.user.success.updateUserProfile } catch (error) { - this.logger.error(`Error in createUserForToken: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in createUserForToken: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } private validateEmail(email: string): void { if (!validator.isEmail(email.toLowerCase())) { - throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail); + throw new UnauthorizedException(ResponseMessages.user.error.invalidEmail) } } @@ -365,412 +396,428 @@ export class UserService { * @returns User access token details */ async login(loginUserDto: LoginUserDto): Promise { - const { email, password, isPasskey } = loginUserDto; + const { email, password, isPasskey } = loginUserDto try { - - this.validateEmail(email.toLowerCase()); - const userData = await this.userRepository.checkUserExist(email.toLowerCase()); + this.validateEmail(email.toLowerCase()) + const userData = await this.userRepository.checkUserExist(email.toLowerCase()) if (!userData) { - throw new NotFoundException(ResponseMessages.user.error.notFound); + throw new NotFoundException(ResponseMessages.user.error.notFound) } if (userData && !userData.isEmailVerified) { - throw new BadRequestException(ResponseMessages.user.error.verifyMail); + throw new BadRequestException(ResponseMessages.user.error.verifyMail) } - if (true === isPasskey && false === userData?.isFidoVerified) { - throw new UnauthorizedException(ResponseMessages.user.error.registerFido); + if (isPasskey === true && userData?.isFidoVerified === false) { + throw new UnauthorizedException(ResponseMessages.user.error.registerFido) } - if (true === isPasskey && userData?.username && true === userData?.isFidoVerified) { - const getUserDetails = await this.userRepository.getUserDetails(userData.email.toLowerCase()); - const decryptedPassword = await this.commonService.decryptPassword(getUserDetails.password); - return await this.generateToken(email.toLowerCase(), decryptedPassword, userData); + if (isPasskey === true && userData?.username && userData?.isFidoVerified === true) { + const getUserDetails = await this.userRepository.getUserDetails(userData.email.toLowerCase()) + const decryptedPassword = await this.commonService.decryptPassword(getUserDetails.password) + return await this.generateToken(email.toLowerCase(), decryptedPassword, userData) } else { - - const decryptedPassword = await this.commonService.decryptPassword(password); - return await this.generateToken(email.toLowerCase(), decryptedPassword, userData); + const decryptedPassword = await this.commonService.decryptPassword(password) + return await this.generateToken(email.toLowerCase(), decryptedPassword, userData) } } catch (error) { - this.logger.error(`In Login User : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In Login User : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async refreshTokenDetails(refreshToken: string): Promise { - try { - try { - const data = jwt.decode(refreshToken) as jwt.JwtPayload; - const userByKeycloakId = await this.userRepository.getUserByKeycloakId(data?.sub); - const tokenResponse = await this.clientRegistrationService.getAccessToken(refreshToken, userByKeycloakId?.['clientId'], userByKeycloakId?.['clientSecret']); - return tokenResponse; - } catch (error) { - throw new BadRequestException(ResponseMessages.user.error.invalidRefreshToken); - } - + try { + const data = jwt.decode(refreshToken) as jwt.JwtPayload + const userByKeycloakId = await this.userRepository.getUserByKeycloakId(data?.sub) + const tokenResponse = await this.clientRegistrationService.getAccessToken( + refreshToken, + userByKeycloakId?.clientId, + userByKeycloakId?.clientSecret + ) + return tokenResponse + } catch (_error) { + throw new BadRequestException(ResponseMessages.user.error.invalidRefreshToken) + } } catch (error) { - this.logger.error(`In refreshTokenDetails : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); - + this.logger.error(`In refreshTokenDetails : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async updateFidoVerifiedUser(email: string, isFidoVerified: boolean, password: string): Promise { if (isFidoVerified) { - await this.userRepository.addUserPassword(email.toLowerCase(), password); - return true; + await this.userRepository.addUserPassword(email.toLowerCase(), password) + return true } } /** * Forgot password - * @param forgotPasswordDto - * @returns + * @param forgotPasswordDto + * @returns */ async forgotPassword(forgotPasswordDto: IUserForgotPassword): Promise { - const { email, brandLogoUrl, platformName, endpoint } = forgotPasswordDto; + const { email, brandLogoUrl, platformName, endpoint } = forgotPasswordDto try { - this.validateEmail(email.toLowerCase()); - const userData = await this.userRepository.checkUserExist(email.toLowerCase()); + this.validateEmail(email.toLowerCase()) + const userData = await this.userRepository.checkUserExist(email.toLowerCase()) if (!userData) { - throw new NotFoundException(ResponseMessages.user.error.notFound); + throw new NotFoundException(ResponseMessages.user.error.notFound) } if (userData && !userData.isEmailVerified) { - throw new BadRequestException(ResponseMessages.user.error.verifyMail); + throw new BadRequestException(ResponseMessages.user.error.verifyMail) } - const token = uuidv4(); - const expirationTime = new Date(); - expirationTime.setHours(expirationTime.getHours() + 1); // Set expiration time to 1 hour from now - - const tokenCreated = await this.userRepository.createTokenForResetPassword(userData.id, token, expirationTime); + const token = uuidv4() + const expirationTime = new Date() + expirationTime.setHours(expirationTime.getHours() + 1) // Set expiration time to 1 hour from now + + const tokenCreated = await this.userRepository.createTokenForResetPassword(userData.id, token, expirationTime) if (!tokenCreated) { - throw new InternalServerErrorException(ResponseMessages.user.error.resetPasswordLink); + throw new InternalServerErrorException(ResponseMessages.user.error.resetPasswordLink) } try { - await this.sendEmailForResetPassword(email, brandLogoUrl, platformName, endpoint, tokenCreated.token); - } catch (error) { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); + await this.sendEmailForResetPassword(email, brandLogoUrl, platformName, endpoint, tokenCreated.token) + } catch (_error) { + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } return { id: tokenCreated.id, - email: userData.email - }; - + email: userData.email, + } } catch (error) { - this.logger.error(`Error In forgotPassword : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error In forgotPassword : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } /** * Send email for token verification of reset password - * @param email - * @param verificationCode - * @returns + * @param email + * @param verificationCode + * @returns */ - async sendEmailForResetPassword(email: string, brandLogoUrl: string, platformName: string, endpoint: string, verificationCode: string): Promise { + async sendEmailForResetPassword( + email: string, + brandLogoUrl: string, + platformName: string, + endpoint: string, + verificationCode: string + ): Promise { try { - const platformConfigData = await this.prisma.platform_config.findMany(); - - const urlEmailTemplate = new URLUserResetPasswordTemplate(); - const emailData = new EmailDto(); - emailData.emailFrom = platformConfigData[0].emailFrom; - emailData.emailTo = email; - - const platform = platformName || process.env.PLATFORM_NAME; - emailData.emailSubject = `[${platform}] Important: Password Reset Request`; - - emailData.emailHtml = await urlEmailTemplate.getUserResetPasswordTemplate(email, platform, brandLogoUrl, endpoint, verificationCode); - const isEmailSent = await sendEmail(emailData); + const platformConfigData = await this.prisma.platform_config.findMany() + + const urlEmailTemplate = new URLUserResetPasswordTemplate() + const emailData = new EmailDto() + emailData.emailFrom = platformConfigData[0].emailFrom + emailData.emailTo = email + + const platform = platformName || process.env.PLATFORM_NAME + emailData.emailSubject = `[${platform}] Important: Password Reset Request` + + emailData.emailHtml = await urlEmailTemplate.getUserResetPasswordTemplate( + email, + platform, + brandLogoUrl, + endpoint, + verificationCode + ) + const isEmailSent = await sendEmail(emailData) if (isEmailSent) { - return isEmailSent; + return isEmailSent } else { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } } catch (error) { - this.logger.error(`Error in sendEmailForResetPassword: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in sendEmailForResetPassword: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } /** * Create reset password token - * @param resetPasswordDto + * @param resetPasswordDto * @returns user details */ async resetTokenPassword(resetPasswordDto: IUserResetPassword): Promise { - - const { email, password, token } = resetPasswordDto; + const { email, password, token } = resetPasswordDto try { - this.validateEmail(email.toLowerCase()); - const userData = await this.userRepository.checkUserExist(email.toLowerCase()); + this.validateEmail(email.toLowerCase()) + const userData = await this.userRepository.checkUserExist(email.toLowerCase()) if (!userData) { - throw new NotFoundException(ResponseMessages.user.error.notFound); + throw new NotFoundException(ResponseMessages.user.error.notFound) } if (userData && !userData.isEmailVerified) { - throw new BadRequestException(ResponseMessages.user.error.verifyMail); + throw new BadRequestException(ResponseMessages.user.error.verifyMail) } - - const tokenDetails = await this.userRepository.getResetPasswordTokenDetails(userData.id, token); - if (!tokenDetails || (new Date() > tokenDetails.expiresAt)) { - throw new BadRequestException(ResponseMessages.user.error.invalidResetLink); - } + const tokenDetails = await this.userRepository.getResetPasswordTokenDetails(userData.id, token) - const decryptedPassword = await this.commonService.decryptPassword(password); - try { - + if (!tokenDetails || new Date() > tokenDetails.expiresAt) { + throw new BadRequestException(ResponseMessages.user.error.invalidResetLink) + } - const authToken = await this.clientRegistrationService.getManagementToken(userData.clientId, userData.clientSecret); - userData.password = decryptedPassword; + const decryptedPassword = await this.commonService.decryptPassword(password) + try { + const authToken = await this.clientRegistrationService.getManagementToken( + userData.clientId, + userData.clientSecret + ) + userData.password = decryptedPassword if (userData.keycloakUserId) { - await this.clientRegistrationService.resetPasswordOfUser(userData, process.env.KEYCLOAK_REALM, authToken); - } else { - const keycloakDetails = await this.clientRegistrationService.createUser(userData, process.env.KEYCLOAK_REALM, authToken); - await this.userRepository.updateUserDetails(userData.id, - keycloakDetails.keycloakUserId.toString() - ); + await this.clientRegistrationService.resetPasswordOfUser(userData, process.env.KEYCLOAK_REALM, authToken) + } else { + const keycloakDetails = await this.clientRegistrationService.createUser( + userData, + process.env.KEYCLOAK_REALM, + authToken + ) + await this.userRepository.updateUserDetails(userData.id, keycloakDetails.keycloakUserId.toString()) } - await this.updateFidoVerifiedUser(email.toLowerCase(), userData.isFidoVerified, password); - + await this.updateFidoVerifiedUser(email.toLowerCase(), userData.isFidoVerified, password) } catch (error) { - this.logger.error(`Error reseting the password`, error); - throw new InternalServerErrorException('Error while reseting user password'); + this.logger.error('Error reseting the password', error) + throw new InternalServerErrorException('Error while reseting user password') } - await this.userRepository.deleteResetPasswordToken(tokenDetails.id); + await this.userRepository.deleteResetPasswordToken(tokenDetails.id) return { id: userData.id, - email: userData.email - }; - + email: userData.email, + } } catch (error) { - this.logger.error(`Error In resetTokenPassword : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error In resetTokenPassword : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } findUserByUserId(id: string): Promise { - return this.userRepository.getUserById(id); - + return this.userRepository.getUserById(id) } async resetPassword(resetPasswordDto: IUserResetPassword): Promise { - const { email, oldPassword, newPassword } = resetPasswordDto; + const { email, oldPassword, newPassword } = resetPasswordDto try { - this.validateEmail(email.toLowerCase()); - const userData = await this.userRepository.checkUserExist(email.toLowerCase()); + this.validateEmail(email.toLowerCase()) + const userData = await this.userRepository.checkUserExist(email.toLowerCase()) if (!userData) { - throw new NotFoundException(ResponseMessages.user.error.notFound); + throw new NotFoundException(ResponseMessages.user.error.notFound) } if (userData && !userData.isEmailVerified) { - throw new BadRequestException(ResponseMessages.user.error.verifyMail); + throw new BadRequestException(ResponseMessages.user.error.verifyMail) } - const oldDecryptedPassword = await this.commonService.decryptPassword(oldPassword); - const newDecryptedPassword = await this.commonService.decryptPassword(newPassword); + const oldDecryptedPassword = await this.commonService.decryptPassword(oldPassword) + const newDecryptedPassword = await this.commonService.decryptPassword(newPassword) if (oldDecryptedPassword === newDecryptedPassword) { - throw new BadRequestException(ResponseMessages.user.error.resetSamePassword); + throw new BadRequestException(ResponseMessages.user.error.resetSamePassword) } - const tokenResponse = await this.generateToken(email.toLowerCase(), oldDecryptedPassword, userData); - + const tokenResponse = await this.generateToken(email.toLowerCase(), oldDecryptedPassword, userData) + if (tokenResponse) { - userData.password = newDecryptedPassword; - try { - let keycloakDetails = null; - const token = await this.clientRegistrationService.getManagementToken(userData.clientId, userData.clientSecret); + userData.password = newDecryptedPassword + try { + let keycloakDetails = null + const token = await this.clientRegistrationService.getManagementToken( + userData.clientId, + userData.clientSecret + ) if (userData.keycloakUserId) { - - keycloakDetails = await this.clientRegistrationService.resetPasswordOfUser(userData, process.env.KEYCLOAK_REALM, token); - await this.updateFidoVerifiedUser(email.toLowerCase(), userData.isFidoVerified, newPassword); - + keycloakDetails = await this.clientRegistrationService.resetPasswordOfUser( + userData, + process.env.KEYCLOAK_REALM, + token + ) + await this.updateFidoVerifiedUser(email.toLowerCase(), userData.isFidoVerified, newPassword) } else { - keycloakDetails = await this.clientRegistrationService.createUser(userData, process.env.KEYCLOAK_REALM, token); - await this.userRepository.updateUserDetails(userData.id, - keycloakDetails.keycloakUserId.toString() - ); - await this.updateFidoVerifiedUser(email.toLowerCase(), userData.isFidoVerified, newPassword); + keycloakDetails = await this.clientRegistrationService.createUser( + userData, + process.env.KEYCLOAK_REALM, + token + ) + await this.userRepository.updateUserDetails(userData.id, keycloakDetails.keycloakUserId.toString()) + await this.updateFidoVerifiedUser(email.toLowerCase(), userData.isFidoVerified, newPassword) } return { id: userData.id, - email: userData.email - }; - - } catch (error) { - throw new InternalServerErrorException('Error while registering user on keycloak'); + email: userData.email, + } + } catch (_error) { + throw new InternalServerErrorException('Error while registering user on keycloak') } } else { - throw new BadRequestException(ResponseMessages.user.error.invalidCredentials); + throw new BadRequestException(ResponseMessages.user.error.invalidCredentials) } - } catch (error) { - this.logger.error(`In Login User : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In Login User : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async generateToken(email: string, password: string, userData: user): Promise { + if (userData.keycloakUserId) { + try { + const tokenResponse = await this.clientRegistrationService.getUserToken( + email, + password, + userData.clientId, + userData.clientSecret + ) + tokenResponse.isRegisteredToSupabase = false + return tokenResponse + } catch (_error) { + throw new UnauthorizedException(ResponseMessages.user.error.invalidCredentials) + } + } else { + const supaInstance = await this.supabaseService.getClient() + const { data, error } = await supaInstance.auth.signInWithPassword({ + email, + password, + }) - if (userData.keycloakUserId) { + this.logger.error(`Supa Login Error::`, JSON.stringify(error)) - try { - const tokenResponse = await this.clientRegistrationService.getUserToken(email, password, userData.clientId, userData.clientSecret); - tokenResponse.isRegisteredToSupabase = false; - return tokenResponse; - } catch (error) { - throw new UnauthorizedException(ResponseMessages.user.error.invalidCredentials); - } - - } else { - const supaInstance = await this.supabaseService.getClient(); - const { data, error } = await supaInstance.auth.signInWithPassword({ - email, - password - }); - - this.logger.error(`Supa Login Error::`, JSON.stringify(error)); - - if (error) { - throw new BadRequestException(error?.message); - } - - const token = data?.session; + if (error) { + throw new BadRequestException(error?.message) + } - return { - // eslint-disable-next-line camelcase - access_token: token.access_token, - // eslint-disable-next-line camelcase - token_type: token.token_type, - // eslint-disable-next-line camelcase - expires_in: token.expires_in, - // eslint-disable-next-line camelcase - expires_at: token.expires_at, - isRegisteredToSupabase: true - }; + const token = data?.session + + return { + // eslint-disable-next-line camelcase + access_token: token.access_token, + // eslint-disable-next-line camelcase + token_type: token.token_type, + // eslint-disable-next-line camelcase + expires_in: token.expires_in, + // eslint-disable-next-line camelcase + expires_at: token.expires_at, + isRegisteredToSupabase: true, } + } } async getProfile(payload: { id }): Promise { try { - const userData = await this.userRepository.getUserById(payload.id); + const userData = await this.userRepository.getUserById(payload.id) - if ('true' === process.env.IS_ECOSYSTEM_ENABLE) { - const ecosystemSettings = await this._getEcosystemConfig(); + if (process.env.IS_ECOSYSTEM_ENABLE === 'true') { + const ecosystemSettings = await this._getEcosystemConfig() for (const setting of ecosystemSettings) { - userData[setting.key] = 'true' === setting.value; + userData[setting.key] = setting.value === 'true' } } - - return userData; + + return userData } catch (error) { - this.logger.error(`get user: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get user: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - async _getEcosystemConfig(): Promise { - const pattern = { cmd: 'get-ecosystem-config-details' }; - const payload = { }; + async _getEcosystemConfig(): Promise { + const pattern = { cmd: 'get-ecosystem-config-details' } + const payload = {} const getEcosystemConfigDetails = await this.userServiceProxy .send(pattern, payload) .toPromise() .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return getEcosystemConfigDetails; + return getEcosystemConfigDetails } async getPublicProfile(payload: { username }): Promise { try { - const userProfile = await this.userRepository.getUserPublicProfile(payload.username); + const userProfile = await this.userRepository.getUserPublicProfile(payload.username) if (!userProfile) { - throw new NotFoundException(ResponseMessages.user.error.profileNotFound); + throw new NotFoundException(ResponseMessages.user.error.profileNotFound) } - return userProfile; + return userProfile } catch (error) { - this.logger.error(`get user: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get user: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async updateUserProfile(updateUserProfileDto: UpdateUserProfile): Promise { try { - return this.userRepository.updateUserProfile(updateUserProfileDto); + return this.userRepository.updateUserProfile(updateUserProfileDto) } catch (error) { - this.logger.error(`update user profile: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`update user profile: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async findByKeycloakId(payload: { id }): Promise { try { - return this.userRepository.getUserBySupabaseId(payload.id); + return this.userRepository.getUserBySupabaseId(payload.id) } catch (error) { - this.logger.error(`get user: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get user: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async findSupabaseUser(payload: { id }): Promise { try { - return await this.userRepository.getUserBySupabaseId(payload.id); + return await this.userRepository.getUserBySupabaseId(payload.id) } catch (error) { - this.logger.error(`Error in findSupabaseUser: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in findSupabaseUser: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async findKeycloakUser(payload: { id }): Promise { try { - return await this.userRepository.getUserByKeycloakId(payload.id); + return await this.userRepository.getUserByKeycloakId(payload.id) } catch (error) { - this.logger.error(`Error in findKeycloakUser: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in findKeycloakUser: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async findUserByEmail(payload: { email }): Promise { try { - return await this.userRepository.findUserByEmail(payload.email); + return await this.userRepository.findUserByEmail(payload.email) } catch (error) { - this.logger.error(`findUserByEmail: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`findUserByEmail: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async invitations(payload: { id; status; pageNumber; pageSize; search }): Promise { try { - const userData = await this.userRepository.getUserById(payload.id); + const userData = await this.userRepository.getUserById(payload.id) if (!userData) { - throw new NotFoundException(ResponseMessages.user.error.notFound); + throw new NotFoundException(ResponseMessages.user.error.notFound) } const invitationsData = await this.getOrgInvitations( @@ -779,16 +826,15 @@ 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; - + return invitationsData } catch (error) { - this.logger.error(`Error in get invitations: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in get invitations: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -799,41 +845,39 @@ export class UserService { pageSize: number, search = '' ): Promise { - const pattern = { cmd: 'fetch-user-invitations' }; + const pattern = { cmd: 'fetch-user-invitations' } const payload = { email, status, pageNumber, pageSize, - search - }; + search, + } const invitationsData = await this.natsClient .send(this.userServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return invitationsData; + return invitationsData } async updateOrgInvitations(invitations: OrgInvitations[]): Promise { - - - const updatedInvitations = []; + const updatedInvitations = [] for (const invitation of invitations) { - const { status, id, organisation, orgId, userId, orgRoles } = invitation; + const { status, id, organisation, orgId, userId, orgRoles } = invitation - const roles = await this.orgRoleService.getOrgRolesByIds(orgRoles as string[]); + const roles = await this.orgRoleService.getOrgRolesByIds(orgRoles as string[]) updatedInvitations.push({ orgRoles: roles, @@ -841,11 +885,11 @@ export class UserService { id, orgId, organisation, - userId - }); + userId, + }) } - return updatedInvitations; + return updatedInvitations } /** @@ -854,43 +898,46 @@ export class UserService { * @param userId * @returns Organization invitation status */ - async acceptRejectInvitations(acceptRejectInvitation: AcceptRejectInvitationDto, userId: string): Promise { + async acceptRejectInvitations( + acceptRejectInvitation: AcceptRejectInvitationDto, + userId: string + ): Promise { try { - const userData = await this.userRepository.getUserById(userId); - + const userData = await this.userRepository.getUserById(userId) + if (Invitation.ACCEPTED === acceptRejectInvitation.status) { - const payload = {userId}; - const TotalOrgs = await this._getTotalOrgCount(payload); - + const payload = { userId } + const TotalOrgs = await this._getTotalOrgCount(payload) + if (TotalOrgs >= toNumber(`${process.env.MAX_ORG_LIMIT}`)) { - throw new BadRequestException(ResponseMessages.user.error.userOrgsLimit); - } + throw new BadRequestException(ResponseMessages.user.error.userOrgsLimit) + } } - return this.fetchInvitationsStatus(acceptRejectInvitation, userData.keycloakUserId, userData.email, userId); + return this.fetchInvitationsStatus(acceptRejectInvitation, userData.keycloakUserId, userData.email, userId) } catch (error) { - this.logger.error(`acceptRejectInvitations: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`acceptRejectInvitations: ${error}`) + throw new RpcException(error.response ? error.response : error) } } - async _getTotalOrgCount(payload): Promise { - const pattern = { cmd: 'get-organizations-count' }; + async _getTotalOrgCount(payload): Promise { + const pattern = { cmd: 'get-organizations-count' } const getOrganizationCount = await this.natsClient .send(this.userServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); + ) + }) - return getOrganizationCount; + return getOrganizationCount } /** @@ -907,31 +954,31 @@ export class UserService { userId: string ): Promise { try { - const pattern = { cmd: 'update-invitation-status' }; + const pattern = { cmd: 'update-invitation-status' } - const { orgId, invitationId, status } = acceptRejectInvitation; + const { orgId, invitationId, status } = acceptRejectInvitation - const payload = { userId, keycloakUserId, orgId, invitationId, status, email }; + const payload = { userId, keycloakUserId, orgId, invitationId, status, email } const invitationsData = await this.natsClient .send(this.userServiceProxy, pattern, payload) - + .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { statusCode: error.statusCode, error: error.error, - message: error.message + message: error.message, }, error.error - ); - }); + ) + }) - return invitationsData; + return invitationsData } catch (error) { - this.logger.error(`Error In fetchInvitationsStatus: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error In fetchInvitationsStatus: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -942,26 +989,25 @@ export class UserService { */ async getOrgUsers(orgId: string, pageNumber: number, pageSize: number, search: string): Promise { try { - const query = { userOrgRoles: { - some: { orgId } + some: { orgId }, }, OR: [ { firstName: { contains: search, mode: 'insensitive' } }, { lastName: { contains: search, mode: 'insensitive' } }, - { email: { contains: search, mode: 'insensitive' } } - ] - }; + { email: { contains: search, mode: 'insensitive' } }, + ], + } const filterOptions = { - orgId - }; + orgId, + } - return this.userRepository.findOrgUsers(query, pageNumber, pageSize, filterOptions); + return this.userRepository.findOrgUsers(query, pageNumber, pageSize, filterOptions) } catch (error) { - this.logger.error(`get Org Users: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get Org Users: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -976,162 +1022,173 @@ export class UserService { OR: [ { firstName: { contains: search, mode: 'insensitive' } }, { lastName: { contains: search, mode: 'insensitive' } }, - { email: { contains: search, mode: 'insensitive' } } - ] - }; + { email: { contains: search, mode: 'insensitive' } }, + ], + } - return this.userRepository.findUsers(query, pageNumber, pageSize); + return this.userRepository.findUsers(query, pageNumber, pageSize) } catch (error) { - this.logger.error(`get Users: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`get Users: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async checkUserExist(email: string): Promise { try { - const userDetails = await this.userRepository.checkUniqueUserExist(email.toLowerCase()); - let userVerificationDetails; + const userDetails = await this.userRepository.checkUniqueUserExist(email.toLowerCase()) + let userVerificationDetails if (userDetails) { userVerificationDetails = { isEmailVerified: userDetails.isEmailVerified, isFidoVerified: userDetails.isFidoVerified, - isRegistrationCompleted: null !== userDetails.keycloakUserId && undefined !== userDetails.keycloakUserId, - message:'', - userId: userDetails.id - }; - + isRegistrationCompleted: userDetails.keycloakUserId !== null && undefined !== userDetails.keycloakUserId, + message: '', + userId: userDetails.id, + } } if (userDetails && !userDetails.isEmailVerified) { - userVerificationDetails.message = ResponseMessages.user.error.verificationAlreadySent; - return userVerificationDetails; + userVerificationDetails.message = ResponseMessages.user.error.verificationAlreadySent + return userVerificationDetails } else if (userDetails && userDetails.keycloakUserId) { - userVerificationDetails.message = ResponseMessages.user.error.exists; - return userVerificationDetails; + userVerificationDetails.message = ResponseMessages.user.error.exists + return userVerificationDetails } else if (userDetails && !userDetails.keycloakUserId && userDetails.supabaseUserId) { - userVerificationDetails.message = ResponseMessages.user.error.exists; - return userVerificationDetails; - } else if (null === userDetails) { - return { + userVerificationDetails.message = ResponseMessages.user.error.exists + return userVerificationDetails + } else if (userDetails === null) { + return { isRegistrationCompleted: false, - isEmailVerified: false, - userId:null, - message: ResponseMessages.user.error.notFound - }; + isEmailVerified: false, + userId: null, + message: ResponseMessages.user.error.notFound, + } } else { - return userVerificationDetails; + return userVerificationDetails } } catch (error) { - this.logger.error(`In check User : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In check User : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getUserActivity(userId: string, limit: number): Promise { try { - return this.userActivityService.getUserActivity(userId, limit); + return this.userActivityService.getUserActivity(userId, limit) } catch (error) { - this.logger.error(`In getUserActivity : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`In getUserActivity : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } // eslint-disable-next-line camelcase async updatePlatformSettings(platformSettings: PlatformSettings): Promise { try { - const platformConfigSettings = await this.userRepository.updatePlatformSettings(platformSettings); + const platformConfigSettings = await this.userRepository.updatePlatformSettings(platformSettings) if (!platformConfigSettings) { - throw new BadRequestException(ResponseMessages.user.error.notUpdatePlatformSettings); + throw new BadRequestException(ResponseMessages.user.error.notUpdatePlatformSettings) } - return ResponseMessages.user.success.platformSettings; + return ResponseMessages.user.success.platformSettings } catch (error) { - this.logger.error(`update platform settings: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`update platform settings: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getPlatformSettings(): Promise { try { - const platformSettings = {}; - const platformConfigSettings = await this.userRepository.getPlatformSettings(); + const platformSettings = {} + const platformConfigSettings = await this.userRepository.getPlatformSettings() if (!platformConfigSettings) { - throw new BadRequestException(ResponseMessages.user.error.platformSetttingsNotFound); + throw new BadRequestException(ResponseMessages.user.error.platformSetttingsNotFound) } - platformSettings['platform_config'] = platformConfigSettings; + platformSettings.platform_config = platformConfigSettings - return platformSettings; + return platformSettings } catch (error) { - this.logger.error(`update platform settings: ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`update platform settings: ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } - async updateOrgDeletedActivity(orgId: string, userId: string, deletedBy: string, recordType: RecordType, userEmail: string, txnMetadata: object): Promise { + async updateOrgDeletedActivity( + orgId: string, + userId: string, + deletedBy: string, + recordType: RecordType, + userEmail: string, + txnMetadata: object + ): Promise { try { - return await this.userRepository.updateOrgDeletedActivity(orgId, userId, deletedBy, recordType, userEmail, txnMetadata); + return await this.userRepository.updateOrgDeletedActivity( + orgId, + userId, + deletedBy, + recordType, + userEmail, + txnMetadata + ) } catch (error) { - this.logger.error(`In updateOrgDeletedActivity : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`In updateOrgDeletedActivity : ${JSON.stringify(error)}`) + throw error } } async getUserDetails(userId: string): Promise { try { - const getUserDetails = await this.userRepository.getUserDetailsByUserId(userId); - const userEmail = getUserDetails.email; - return userEmail; + const getUserDetails = await this.userRepository.getUserDetailsByUserId(userId) + const userEmail = getUserDetails.email + return userEmail } catch (error) { - this.logger.error(`In get user details by user Id : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`In get user details by user Id : ${JSON.stringify(error)}`) + throw error } } async getUserKeycloakIdByEmail(userEmails: string[]): Promise { try { - - const getkeycloakUserIds = await this.userRepository.getUserKeycloak(userEmails); - return getkeycloakUserIds; + const getkeycloakUserIds = await this.userRepository.getUserKeycloak(userEmails) + return getkeycloakUserIds } catch (error) { - this.logger.error(`In getUserKeycloakIdByEmail : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`In getUserKeycloakIdByEmail : ${JSON.stringify(error)}`) + throw error } } async getUserByUserIdInKeycloak(email: string): Promise { try { - - const userData = await this.userRepository.checkUserExist(email.toLowerCase()); + const userData = await this.userRepository.checkUserExist(email.toLowerCase()) if (!userData) { - throw new NotFoundException(ResponseMessages.user.error.notFound); + throw new NotFoundException(ResponseMessages.user.error.notFound) } - const token = await this.clientRegistrationService.getManagementToken(userData?.clientId, userData?.clientSecret); - const getClientData = await this.clientRegistrationService.getUserInfoByUserId(userData?.keycloakUserId, token); + const token = await this.clientRegistrationService.getManagementToken(userData?.clientId, userData?.clientSecret) + const getClientData = await this.clientRegistrationService.getUserInfoByUserId(userData?.keycloakUserId, token) - return getClientData; + return getClientData } catch (error) { - this.logger.error(`In getUserByUserIdInKeycloak : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`In getUserByUserIdInKeycloak : ${JSON.stringify(error)}`) + throw error } } - // eslint-disable-next-line camelcase - async getuserOrganizationByUserId(userId: string): Promise { + // eslint-disable-next-line camelcase + async getuserOrganizationByUserId(userId: string): Promise { try { - const getOrganizationDetails = await this.userRepository.handleGetUserOrganizations(userId); + const getOrganizationDetails = await this.userRepository.handleGetUserOrganizations(userId) - if (!getOrganizationDetails) { - throw new NotFoundException(ResponseMessages.ledger.error.NotFound); - } + if (!getOrganizationDetails) { + throw new NotFoundException(ResponseMessages.ledger.error.NotFound) + } - return getOrganizationDetails; + return getOrganizationDetails } catch (error) { - this.logger.error(`Error in getuserOrganizationByUserId: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in getuserOrganizationByUserId: ${error}`) + throw new RpcException(error.response ? error.response : error) } + } } -} \ No newline at end of file diff --git a/apps/user/templates/reset-password-template.ts b/apps/user/templates/reset-password-template.ts index daa0701a4..09a1ff811 100644 --- a/apps/user/templates/reset-password-template.ts +++ b/apps/user/templates/reset-password-template.ts @@ -1,16 +1,22 @@ -import * as url from 'url'; +import * as url from 'url' export class URLUserResetPasswordTemplate { - public getUserResetPasswordTemplate(email: string, platform: string, brandLogoUrl: string, uiEndpoint: string, verificationCode: string): string { - const endpoint = uiEndpoint || process.env.FRONT_END_URL; + public getUserResetPasswordTemplate( + email: string, + platform: string, + brandLogoUrl: string, + uiEndpoint: string, + verificationCode: string + ): string { + const endpoint = uiEndpoint || process.env.FRONT_END_URL const apiUrl = url.parse( `${endpoint}/reset-password?verificationCode=${verificationCode}&email=${encodeURIComponent(email)}` - ); - - const logoUrl = brandLogoUrl || process.env.BRAND_LOGO; - const poweredBy = platform || process.env.POWERED_BY; + ) - const validUrl = apiUrl.href.replace('/:', ':'); + const logoUrl = brandLogoUrl || process.env.BRAND_LOGO + const poweredBy = platform || process.env.POWERED_BY + + const validUrl = apiUrl.href.replace('/:', ':') try { return ` @@ -59,8 +65,7 @@ export class URLUserResetPasswordTemplate { - `; - - } catch (error) {} + ` + } catch (_error) {} } } diff --git a/apps/user/templates/user-email-template.ts b/apps/user/templates/user-email-template.ts index 31cfbcdab..5a50a06c6 100644 --- a/apps/user/templates/user-email-template.ts +++ b/apps/user/templates/user-email-template.ts @@ -1,19 +1,25 @@ export class URLUserEmailTemplate { - public getUserURLTemplate(email: string, verificationCode: string, redirectUrl: string, clientId: string, brandLogoUrl:string, platformName:string): string { - + public getUserURLTemplate( + email: string, + verificationCode: string, + redirectUrl: string, + clientId: string, + brandLogoUrl: string, + platformName: string + ): string { const apiUrl = new URL( clientId === process.env.KEYCLOAK_MANAGEMENT_CLIENT_ID ? '/verify-email-success' : '', redirectUrl - ); + ) - apiUrl.searchParams.append('verificationCode', verificationCode); - apiUrl.searchParams.append('email', encodeURIComponent(email)); + apiUrl.searchParams.append('verificationCode', verificationCode) + apiUrl.searchParams.append('email', encodeURIComponent(email)) - const validUrl = apiUrl.href; + const validUrl = apiUrl.href - const logoUrl = brandLogoUrl || process.env.BRAND_LOGO; - const platform = platformName || process.env.PLATFORM_NAME; - const poweredBy = platformName || process.env.POWERED_BY; + const logoUrl = brandLogoUrl || process.env.BRAND_LOGO + const platform = platformName || process.env.PLATFORM_NAME + const poweredBy = platformName || process.env.POWERED_BY try { return ` @@ -63,7 +69,7 @@ export class URLUserEmailTemplate { - `; - } catch (error) {} + ` + } catch (_error) {} } } diff --git a/apps/user/templates/user-onboard.template.ts b/apps/user/templates/user-onboard.template.ts index 99faeb07d..8b85305bf 100644 --- a/apps/user/templates/user-onboard.template.ts +++ b/apps/user/templates/user-onboard.template.ts @@ -1,7 +1,6 @@ export class OnBoardVerificationRequest { - public getOnBoardUserRequest(name: string, email: string): string { - const year: number = new Date().getFullYear(); + const year: number = new Date().getFullYear() try { return ` @@ -82,8 +81,7 @@ export class OnBoardVerificationRequest { - `; - } catch (error) { - } + ` + } catch (_error) {} } -} \ No newline at end of file +} diff --git a/apps/user/test/app.e2e-spec.ts b/apps/user/test/app.e2e-spec.ts index ab51d4a94..4ec8c16b0 100644 --- a/apps/user/test/app.e2e-spec.ts +++ b/apps/user/test/app.e2e-spec.ts @@ -1,24 +1,21 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { UserModule } from './../src/user.module'; +import type { INestApplication } from '@nestjs/common' +import { Test, type TestingModule } from '@nestjs/testing' +import * as request from 'supertest' +import { UserModule } from './../src/user.module' describe('UserController (e2e)', () => { - let app: INestApplication; + let app: INestApplication beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [UserModule] - }).compile(); + imports: [UserModule], + }).compile() - app = moduleFixture.createNestApplication(); - await app.init(); - }); + app = moduleFixture.createNestApplication() + await app.init() + }) it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); - }); -}); + return request(app.getHttpServer()).get('/').expect(200).expect('Hello World!') + }) +}) diff --git a/apps/utility/interfaces/shortening-url.interface.ts b/apps/utility/interfaces/shortening-url.interface.ts index 7772e04ad..3528f5556 100644 --- a/apps/utility/interfaces/shortening-url.interface.ts +++ b/apps/utility/interfaces/shortening-url.interface.ts @@ -1,10 +1,10 @@ export interface IShorteningUrlData { - referenceId: string; - schemaId: string; - credDefId: string; - invitationUrl: string; - attributes: IAttributes[]; + referenceId: string + schemaId: string + credDefId: string + invitationUrl: string + attributes: IAttributes[] } export interface IAttributes { - [key: string]: string; + [key: string]: string } diff --git a/apps/utility/src/main.ts b/apps/utility/src/main.ts index 3000eedd3..6f4eff187 100644 --- a/apps/utility/src/main.ts +++ b/apps/utility/src/main.ts @@ -1,25 +1,23 @@ -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { NestFactory } from '@nestjs/core'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { UtilitiesModule } from './utilities.module'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { UtilitiesModule } from './utilities.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(UtilitiesModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.UTILITY_SERVICE, process.env.UTILITIES_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.UTILITY_SERVICE, process.env.UTILITIES_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('utilities Microservice is listening to NATS '); + await app.listen() + logger.log('utilities Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/utility/src/utilities.controller.ts b/apps/utility/src/utilities.controller.ts index f9199625d..b63eccfc8 100644 --- a/apps/utility/src/utilities.controller.ts +++ b/apps/utility/src/utilities.controller.ts @@ -1,7 +1,7 @@ -import { Controller, Logger } from '@nestjs/common'; -import { MessagePattern } from '@nestjs/microservices'; -import { UtilitiesService } from './utilities.service'; -import { IShorteningUrlData } from '../interfaces/shortening-url.interface'; +import { Controller, type Logger } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { IShorteningUrlData } from '../interfaces/shortening-url.interface' +import type { UtilitiesService } from './utilities.service' @Controller() export class UtilitiesController { @@ -12,22 +12,22 @@ export class UtilitiesController { @MessagePattern({ cmd: 'create-shortening-url' }) async createAndStoreShorteningUrl(payload: IShorteningUrlData): Promise { - return this.utilitiesService.createAndStoreShorteningUrl(payload); + return this.utilitiesService.createAndStoreShorteningUrl(payload) } @MessagePattern({ cmd: 'get-shortening-url' }) async getShorteningUrl(referenceId: string): Promise { - return this.utilitiesService.getShorteningUrl(referenceId); + return this.utilitiesService.getShorteningUrl(referenceId) } @MessagePattern({ cmd: 'store-object-return-url' }) async storeObject(payload: { persistent: boolean; storeObj: unknown }): Promise { try { - const url: string = await this.utilitiesService.storeObject(payload); - return url; + const url: string = await this.utilitiesService.storeObject(payload) + return url } catch (error) { - this.logger.error(error); - throw new Error('Error occured in Utility Microservices Controller'); + this.logger.error(error) + throw new Error('Error occured in Utility Microservices Controller') } } } diff --git a/apps/utility/src/utilities.module.ts b/apps/utility/src/utilities.module.ts index 2f547234f..764936a3a 100644 --- a/apps/utility/src/utilities.module.ts +++ b/apps/utility/src/utilities.module.ts @@ -1,18 +1,18 @@ -import { Logger, Module } from '@nestjs/common'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonModule } from '@credebl/common'; -import { CacheModule } from '@nestjs/cache-manager'; -import { PrismaService } from '@credebl/prisma-service'; -import { UtilitiesController } from './utilities.controller'; -import { UtilitiesService } from './utilities.service'; -import { UtilitiesRepository } from './utilities.repository'; -import { AwsService } from '@credebl/aws'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; +import { AwsService } from '@credebl/aws' +import { CommonModule } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { CacheModule } from '@nestjs/cache-manager' +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { UtilitiesController } from './utilities.controller' +import { UtilitiesRepository } from './utilities.repository' +import { UtilitiesService } from './utilities.service' @Module({ imports: [ @@ -20,15 +20,17 @@ import { ContextInterceptorModule } from '@credebl/context/contextInterceptorMod { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.UTILITY_SERVICE, process.env.UTILITIES_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.UTILITY_SERVICE, process.env.UTILITIES_NKEY_SEED), + }, ]), CommonModule, GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, - CacheModule.register() + LoggerModule, + PlatformConfig, + ContextInterceptorModule, + CacheModule.register(), ], controllers: [UtilitiesController], - providers: [UtilitiesService, Logger, PrismaService, UtilitiesRepository, AwsService] + providers: [UtilitiesService, Logger, PrismaService, UtilitiesRepository, AwsService], }) -export class UtilitiesModule { } +export class UtilitiesModule {} diff --git a/apps/utility/src/utilities.repository.ts b/apps/utility/src/utilities.repository.ts index 7727d1b8e..94a58d90f 100644 --- a/apps/utility/src/utilities.repository.ts +++ b/apps/utility/src/utilities.repository.ts @@ -1,51 +1,46 @@ -import { PrismaService } from "@credebl/prisma-service"; -import { Injectable, Logger } from "@nestjs/common"; +import type { PrismaService } from '@credebl/prisma-service' +import { Injectable, type Logger } from '@nestjs/common' // eslint-disable-next-line camelcase -import { shortening_url } from "@prisma/client"; +import type { shortening_url } from '@prisma/client' @Injectable() export class UtilitiesRepository { - constructor( - private readonly prisma: PrismaService, - private readonly logger: Logger - ) { } - - async saveShorteningUrl( - payload - ): Promise { - - try { - - const { referenceId, invitationPayload } = payload; - const storeShorteningUrl = await this.prisma.shortening_url.upsert({ - where: { referenceId }, - update: { invitationPayload }, - create: { referenceId, invitationPayload } - }); - - this.logger.log(`[saveShorteningUrl] - shortening url details ${referenceId}`); - return storeShorteningUrl; - } catch (error) { - this.logger.error(`Error in saveShorteningUrl: ${error} `); - throw error; - } + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger + ) {} + + async saveShorteningUrl(payload): Promise { + try { + const { referenceId, invitationPayload } = payload + const storeShorteningUrl = await this.prisma.shortening_url.upsert({ + where: { referenceId }, + update: { invitationPayload }, + create: { referenceId, invitationPayload }, + }) + + this.logger.log(`[saveShorteningUrl] - shortening url details ${referenceId}`) + return storeShorteningUrl + } catch (error) { + this.logger.error(`Error in saveShorteningUrl: ${error} `) + throw error } - - // eslint-disable-next-line camelcase - async getShorteningUrl(referenceId): Promise { - try { - - const storeShorteningUrl = await this.prisma.shortening_url.findUnique({ - where: { - referenceId - } - }); - - this.logger.log(`[getShorteningUrl] - shortening url details ${referenceId}`); - return storeShorteningUrl; - } catch (error) { - this.logger.error(`Error in getShorteningUrl: ${error} `); - throw error; - } + } + + // eslint-disable-next-line camelcase + async getShorteningUrl(referenceId): Promise { + try { + const storeShorteningUrl = await this.prisma.shortening_url.findUnique({ + where: { + referenceId, + }, + }) + + this.logger.log(`[getShorteningUrl] - shortening url details ${referenceId}`) + return storeShorteningUrl + } catch (error) { + this.logger.error(`Error in getShorteningUrl: ${error} `) + throw error } -} \ No newline at end of file + } +} diff --git a/apps/utility/src/utilities.service.ts b/apps/utility/src/utilities.service.ts index ae299f334..b61c62d91 100644 --- a/apps/utility/src/utilities.service.ts +++ b/apps/utility/src/utilities.service.ts @@ -1,63 +1,67 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { RpcException } from '@nestjs/microservices'; -import { UtilitiesRepository } from './utilities.repository'; -import { AwsService } from '@credebl/aws'; -import { S3 } from 'aws-sdk'; -import { v4 as uuidv4 } from 'uuid'; +import type { AwsService } from '@credebl/aws' +import { Injectable, type Logger } from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' +import type { S3 } from 'aws-sdk' +import { v4 as uuidv4 } from 'uuid' +import type { UtilitiesRepository } from './utilities.repository' @Injectable() export class UtilitiesService { - constructor( - private readonly logger: Logger, - private readonly utilitiesRepository: UtilitiesRepository, - private readonly awsService: AwsService - ) { } + constructor( + private readonly logger: Logger, + private readonly utilitiesRepository: UtilitiesRepository, + private readonly awsService: AwsService + ) {} - async createAndStoreShorteningUrl(payload): Promise { - try { - const { credentialId, schemaId, credDefId, invitationUrl, attributes } = payload; - const invitationPayload = { - referenceId: credentialId, - invitationPayload: { - schemaId, - credDefId, - invitationUrl, - attributes - } - }; - await this.utilitiesRepository.saveShorteningUrl(invitationPayload); - return `${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}/invitation/qr-code/${credentialId}`; - } catch (error) { - this.logger.error(`[createAndStoreShorteningUrl] - error in create shortening url: ${JSON.stringify(error)}`); - throw new RpcException(error); - } + async createAndStoreShorteningUrl(payload): Promise { + try { + const { credentialId, schemaId, credDefId, invitationUrl, attributes } = payload + const invitationPayload = { + referenceId: credentialId, + invitationPayload: { + schemaId, + credDefId, + invitationUrl, + attributes, + }, + } + await this.utilitiesRepository.saveShorteningUrl(invitationPayload) + return `${process.env.API_GATEWAY_PROTOCOL}://${process.env.API_ENDPOINT}/invitation/qr-code/${credentialId}` + } catch (error) { + this.logger.error(`[createAndStoreShorteningUrl] - error in create shortening url: ${JSON.stringify(error)}`) + throw new RpcException(error) } + } - async getShorteningUrl(referenceId: string): Promise { - try { - const getShorteningUrl = await this.utilitiesRepository.getShorteningUrl(referenceId); + async getShorteningUrl(referenceId: string): Promise { + try { + const getShorteningUrl = await this.utilitiesRepository.getShorteningUrl(referenceId) - const getInvitationUrl = { - referenceId: getShorteningUrl.referenceId, - invitationPayload: getShorteningUrl.invitationPayload - }; - - return getInvitationUrl; - } catch (error) { - this.logger.error(`[getShorteningUrl] - error in get shortening url: ${JSON.stringify(error)}`); - throw new RpcException(error); - } + const getInvitationUrl = { + referenceId: getShorteningUrl.referenceId, + invitationPayload: getShorteningUrl.invitationPayload, + } + + return getInvitationUrl + } catch (error) { + this.logger.error(`[getShorteningUrl] - error in get shortening url: ${JSON.stringify(error)}`) + throw new RpcException(error) } + } - async storeObject(payload: {persistent: boolean, storeObj: unknown}): Promise { - try { - const uuid = uuidv4(); - const uploadResult:S3.ManagedUpload.SendData = await this.awsService.storeObject(payload.persistent, uuid, payload.storeObj); - const url: string = `${process.env.SHORTENED_URL_DOMAIN}/${uploadResult.Key}`; - return url; - } catch (error) { - this.logger.error(error); - throw new Error('An error occurred while uploading data to S3. Error::::::'); - } + async storeObject(payload: { persistent: boolean; storeObj: unknown }): Promise { + try { + const uuid = uuidv4() + const uploadResult: S3.ManagedUpload.SendData = await this.awsService.storeObject( + payload.persistent, + uuid, + payload.storeObj + ) + const url: string = `${process.env.SHORTENED_URL_DOMAIN}/${uploadResult.Key}` + return url + } catch (error) { + this.logger.error(error) + throw new Error('An error occurred while uploading data to S3. Error::::::') } + } } diff --git a/apps/verification/src/interfaces/verification.interface.ts b/apps/verification/src/interfaces/verification.interface.ts index fb7520a87..977d1a7f3 100644 --- a/apps/verification/src/interfaces/verification.interface.ts +++ b/apps/verification/src/interfaces/verification.interface.ts @@ -1,276 +1,273 @@ -import { AutoAccept } from '@credebl/enum/enum'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; +import type { AutoAccept } from '@credebl/enum/enum' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' export interface IProofRequestAttribute { - attributeName?: string; - attributeNames?:string[]; - condition?: string; - value?: string; - credDefId?: string; - schemaId?: string; - credentialName?: string; + attributeName?: string + attributeNames?: string[] + condition?: string + value?: string + credDefId?: string + schemaId?: string + credentialName?: string } export enum ProofRequestType { - INDY = 'indy', - PRESENTATIONEXCHANGE = 'presentationExchange' + INDY = 'indy', + PRESENTATIONEXCHANGE = 'presentationExchange', } export interface IRequestProof { - orgId: string; - version:string; - connectionId?: string | string[]; - attributes?: IProofRequestAttribute[]; - type: ProofRequestType; - presentationDefinition?:IProofRequestPresentationDefinition; - comment: string; - autoAcceptProof: AutoAccept; - protocolVersion?: string; - emailId?: string[]; - goalCode?: string; - parentThreadId?: string; - willConfirm?: boolean; + orgId: string + version: string + connectionId?: string | string[] + attributes?: IProofRequestAttribute[] + type: ProofRequestType + presentationDefinition?: IProofRequestPresentationDefinition + comment: string + autoAcceptProof: AutoAccept + protocolVersion?: string + emailId?: string[] + goalCode?: string + parentThreadId?: string + willConfirm?: boolean } export interface IGetAllProofPresentations { - url: string; - apiKey: string; + url: string + apiKey: string } export interface IGetProofPresentationById { - url: string; - apiKey?: string; - orgId?: string; + url: string + apiKey?: string + orgId?: string } export interface IVerifyPresentation { - url: string; - apiKey?: string; - orgId?: string; + url: string + apiKey?: string + orgId?: string } export interface IVerifiedProofData { - url: string; - apiKey?: string; - orgId?: string + url: string + apiKey?: string + orgId?: string } export interface IProofPresentationData { - proofId: string; - orgId: string; - user: IUserRequest; + proofId: string + orgId: string + user: IUserRequest } interface IProofFormats { - indy: IndyProof + indy: IndyProof } interface IndyProof { - name: string; - version: string; - requested_attributes: IRequestedAttributes; - requested_predicates: IRequestedPredicates; + name: string + version: string + requested_attributes: IRequestedAttributes + requested_predicates: IRequestedPredicates } interface IRequestedAttributes { - [key: string]: IRequestedAttributesName; + [key: string]: IRequestedAttributesName } interface IRequestedAttributesName { - name?: string; - names?: string; - restrictions: IRequestedRestriction[] + name?: string + names?: string + restrictions: IRequestedRestriction[] } interface IRequestedPredicates { - [key: string]: IRequestedPredicatesName; + [key: string]: IRequestedPredicatesName } interface IRequestedPredicatesName { - name: string; - restrictions: IRequestedRestriction[] + name: string + restrictions: IRequestedRestriction[] } interface IRequestedRestriction { - cred_def_id?: string; - schema_id?: string; - schema_issuer_did?: string; - schema_name?: string; - issuer_did?: string; - schema_version?: string; + cred_def_id?: string + schema_id?: string + schema_issuer_did?: string + schema_name?: string + issuer_did?: string + schema_version?: string } export interface ISchema { - uri:string; + uri: string } export interface IFields { - path: string[]; - } + path: string[] +} export interface IConstraints { - fields: IFields[]; - } + fields: IFields[] +} export interface IInputDescriptors { - - id:string; - name?:string; - purpose?:string; - schema:ISchema[]; - constraints?:IConstraints; - + id: string + name?: string + purpose?: string + schema: ISchema[] + constraints?: IConstraints } export interface IProofRequestPresentationDefinition { - id:string; - name: string; - purpose?: string; - input_descriptors:IInputDescriptors[]; + id: string + name: string + purpose?: string + input_descriptors: IInputDescriptors[] } export interface IPresentationExchange { - presentationDefinition:IProofRequestPresentationDefinition; - + presentationDefinition: IProofRequestPresentationDefinition } export interface IPresentationExchangeProofFormats { - presentationExchange? : IPresentationExchange; - indy?: IndyProof + presentationExchange?: IPresentationExchange + indy?: IndyProof } export interface ISendPresentationExchangeProofRequestPayload { - protocolVersion: string; - comment: string; - parentThreadId?: string; - proofFormats: IPresentationExchangeProofFormats; - autoAcceptProof: string; - label?: string; + protocolVersion: string + comment: string + parentThreadId?: string + proofFormats: IPresentationExchangeProofFormats + autoAcceptProof: string + label?: string } export interface IPresentationExchangeProofRequestPayload { - url: string; - apiKey?: string; - proofRequestPayload: ISendPresentationExchangeProofRequestPayload; - orgId?: string; + url: string + apiKey?: string + proofRequestPayload: ISendPresentationExchangeProofRequestPayload + orgId?: string } export interface ISendProofRequestPayload { - protocolVersion?: string; - comment?: string; - connectionId?: string; - proofFormats?: IProofFormats; - autoAcceptProof?: AutoAccept; - label?: string; - goalCode?: string; - // TODO: [Credo-ts] Issue with parentThreadId in creating an OOB proof request. - // This causes failures in OOB connection establishment. - // parentThreadId?: string; - willConfirm?: boolean; - imageUrl?: string; - emailId?: string[] - isShortenUrl?: boolean; - type?:string; - orgId?: string; - presentationDefinition?:IProofRequestPresentationDefinition; - reuseConnection?: boolean; - recipientKey?:string; - invitationDid?: string + protocolVersion?: string + comment?: string + connectionId?: string + proofFormats?: IProofFormats + autoAcceptProof?: AutoAccept + label?: string + goalCode?: string + // TODO: [Credo-ts] Issue with parentThreadId in creating an OOB proof request. + // This causes failures in OOB connection establishment. + // parentThreadId?: string; + willConfirm?: boolean + imageUrl?: string + emailId?: string[] + isShortenUrl?: boolean + type?: string + orgId?: string + presentationDefinition?: IProofRequestPresentationDefinition + reuseConnection?: boolean + recipientKey?: string + invitationDid?: string } export interface IWSendProofRequestPayload { - protocolVersion?: string; - comment?: string; - connectionId?: string; - proofFormats?: IProofFormats; - autoAcceptProof?: string; - label?: string; - goalCode?: string; - parentThreadId?: string; - willConfirm?: boolean; - imageUrl?: string; - emailId?: string[]; - type?:string; - presentationDefinition?:IProofRequestPresentationDefinition; + protocolVersion?: string + comment?: string + connectionId?: string + proofFormats?: IProofFormats + autoAcceptProof?: string + label?: string + goalCode?: string + parentThreadId?: string + willConfirm?: boolean + imageUrl?: string + emailId?: string[] + type?: string + presentationDefinition?: IProofRequestPresentationDefinition } export interface IProofRequestPayload { - url: string; - apiKey?: string; - orgId?: string; - proofRequestPayload: ISendProofRequestPayload | ISendPresentationExchangeProofRequestPayload; + url: string + apiKey?: string + orgId?: string + proofRequestPayload: ISendProofRequestPayload | ISendPresentationExchangeProofRequestPayload } interface IWebhookPresentationProof { - threadId: string; - state: string; - connectionId + threadId: string + state: string + connectionId } export interface IWebhookProofPresentation { - metadata: object; - _tags: IWebhookPresentationProof; - id: string; - createdAt: string; - protocolVersion: string; - state: string; - connectionId: string; - presentationId: string; - threadId: string; - parentThreadId?: string; - autoAcceptProof: string; - updatedAt: string; - isVerified: boolean; - contextCorrelationId: string; - errorMessage?: string; + metadata: object + _tags: IWebhookPresentationProof + id: string + createdAt: string + protocolVersion: string + state: string + connectionId: string + presentationId: string + threadId: string + parentThreadId?: string + autoAcceptProof: string + updatedAt: string + isVerified: boolean + contextCorrelationId: string + errorMessage?: string } export interface IProofPresentation { - proofPresentationPayload: IWebhookProofPresentation; - orgId: string; + proofPresentationPayload: IWebhookProofPresentation + orgId: string } export interface IProofRequests { - proofRequestsSearchCriteria: IProofRequestSearchCriteria; - user: IUserRequest; - orgId: string; + proofRequestsSearchCriteria: IProofRequestSearchCriteria + user: IUserRequest + orgId: string } export interface IProofRequestSearchCriteria { - pageNumber: number; - pageSize: number; - sortField: string; - sortBy: string; - search: string; + pageNumber: number + pageSize: number + sortField: string + sortBy: string + search: string } -export interface IInvitation{ - invitationUrl?: string; - deepLinkURL?: string; +export interface IInvitation { + invitationUrl?: string + deepLinkURL?: string } export interface IProofRequestData { - goalCode?: string; - version:string; - parentThreadId?: string; - willConfirm?: boolean; - protocolVersion?: string; - proofFormats?:IProofFormat; - orgId: string; - connectionId?: string | string[]; - attributes?: IProofRequestAttribute[]; - type: ProofRequestType; - presentationDefinition?:IProofRequestPresentationDefinition; - comment: string; - autoAcceptProof: AutoAccept; + goalCode?: string + version: string + parentThreadId?: string + willConfirm?: boolean + protocolVersion?: string + proofFormats?: IProofFormat + orgId: string + connectionId?: string | string[] + attributes?: IProofRequestAttribute[] + type: ProofRequestType + presentationDefinition?: IProofRequestPresentationDefinition + comment: string + autoAcceptProof: AutoAccept } export interface IProofFormat { - indy: Indy; + indy: Indy } export interface Indy { - attributes: IProofAttributesData[]; + attributes: IProofAttributesData[] } export interface IProofAttributesData { - attributeName: string; - attributeNames?: string[]; - condition: string; - value: string; - credDefId: string; - schemaId: string; -} \ No newline at end of file + attributeName: string + attributeNames?: string[] + condition: string + value: string + credDefId: string + schemaId: string +} diff --git a/apps/verification/src/main.ts b/apps/verification/src/main.ts index d355b3971..265c21225 100644 --- a/apps/verification/src/main.ts +++ b/apps/verification/src/main.ts @@ -1,25 +1,23 @@ -import { NestFactory } from '@nestjs/core'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { VerificationModule } from './verification.module'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { VerificationModule } from './verification.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(VerificationModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.VERIFICATION_SERVICE, process.env.VERIFICATION_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.VERIFICATION_SERVICE, process.env.VERIFICATION_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Verification-Service Microservice is listening to NATS '); + await app.listen() + logger.log('Verification-Service Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index 13587c094..9f2e3a1fd 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -1,14 +1,17 @@ -import { IProofPresentation, IProofRequestSearchCriteria } from '../interfaces/verification.interface'; -import { IProofPresentationsListCount, IVerificationRecords } from '@credebl/common/interfaces/verification.interface'; -import { Injectable, Logger, NotFoundException } from '@nestjs/common'; +import type { + IProofPresentationsListCount, + IVerificationRecords, +} from '@credebl/common/interfaces/verification.interface' +import { Injectable, type Logger, NotFoundException } from '@nestjs/common' // eslint-disable-next-line camelcase -import { agent_invitations, org_agents, organisation, platform_config, presentations } from '@prisma/client'; +import type { agent_invitations, org_agents, organisation, platform_config, presentations } from '@prisma/client' +import type { IProofPresentation, IProofRequestSearchCriteria } from '../interfaces/verification.interface' -import { CommonService } from '@credebl/common'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { PrismaService } from '@credebl/prisma-service'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { SortValue } from '@credebl/enum/enum'; +import type { CommonService } from '@credebl/common' +import { ResponseMessages } from '@credebl/common/response-messages' +import { SortValue } from '@credebl/enum/enum' +import type { PrismaService } from '@credebl/prisma-service' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' @Injectable() export class VerificationRepository { @@ -28,18 +31,18 @@ export class VerificationRepository { try { const agentDetails = await this.prisma.org_agents.findFirst({ where: { - orgId - } - }); + orgId, + }, + }) if (!agentDetails) { - throw new NotFoundException(ResponseMessages.verification.error.notFound); + throw new NotFoundException(ResponseMessages.verification.error.notFound) } - return agentDetails; + return agentDetails } catch (error) { - this.logger.error(`[getProofPresentations] - error in get agent endpoint : ${error.message} `); - throw error; + this.logger.error(`[getProofPresentations] - error in get agent endpoint : ${error.message} `) + throw error } } @@ -52,18 +55,18 @@ export class VerificationRepository { try { const orgId = await this.prisma.org_agents.findFirst({ where: { - orgDid: issuerId + orgDid: issuerId, }, select: { orgId: true, - orgDid: true - } - }); + orgDid: true, + }, + }) - return orgId; + return orgId } catch (error) { - this.logger.error(`[getOrgId] - error in getting orgId : ${error.message} `); - throw error; + this.logger.error(`[getOrgId] - error in getting orgId : ${error.message} `) + throw error } } @@ -72,17 +75,17 @@ export class VerificationRepository { try { return this.prisma.org_agents.findFirst({ where: { - tenantId - } - }); + tenantId, + }, + }) } catch (error) { - this.logger.error(`Error in getOrganization in issuance repository: ${error.message} `); - throw error; + this.logger.error(`Error in getOrganization in issuance repository: ${error.message} `) + throw error } } async getAllProofRequests( - user: IUserRequest, + _user: IUserRequest, orgId: string, proofRequestsSearchCriteria: IProofRequestSearchCriteria ): Promise { @@ -93,8 +96,8 @@ export class VerificationRepository { OR: [ { connectionId: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } }, { state: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } }, - { presentationId: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } } - ] + { presentationId: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } }, + ], }, select: { createDateTime: true, @@ -106,30 +109,31 @@ export class VerificationRepository { presentationId: true, schemaId: true, emailId: true, - errorMessage: true + errorMessage: true, }, orderBy: { - [proofRequestsSearchCriteria.sortField]: SortValue.ASC === proofRequestsSearchCriteria.sortBy ? 'asc' : 'desc' + [proofRequestsSearchCriteria.sortField]: + SortValue.ASC === proofRequestsSearchCriteria.sortBy ? 'asc' : 'desc', }, take: Number(proofRequestsSearchCriteria.pageSize), - skip: (proofRequestsSearchCriteria.pageNumber - 1) * proofRequestsSearchCriteria.pageSize - }); + skip: (proofRequestsSearchCriteria.pageNumber - 1) * proofRequestsSearchCriteria.pageSize, + }) const proofRequestsCount = await this.prisma.presentations.count({ where: { orgId, OR: [ { connectionId: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } }, { state: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } }, - { presentationId: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } } - ] - } - }); + { presentationId: { contains: proofRequestsSearchCriteria.search, mode: 'insensitive' } }, + ], + }, + }) - return { proofRequestsCount, proofRequestsList }; + return { proofRequestsCount, proofRequestsList } } catch (error) { - this.logger.error(`[getAllProofRequests] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getAllProofRequests] - error: ${JSON.stringify(error)}`) + throw error } } @@ -137,55 +141,57 @@ export class VerificationRepository { try { const whereClause = { orgId, - ...(state ? { state } : {}) - }; + ...(state ? { state } : {}), + } const verificationRecordsCount = await this.prisma.presentations.count({ - where: whereClause - }); + where: whereClause, + }) - return verificationRecordsCount; + return verificationRecordsCount } catch (error) { - this.logger.error(`[get verification records by org Id] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[get verification records by org Id] - error: ${JSON.stringify(error)}`) + throw error } } async storeProofPresentation(payload: IProofPresentation): Promise { try { - let encryptEmailId; - let organisationId: string; - let schemaId; + let encryptEmailId: string + let organisationId: string + // biome-ignore lint/suspicious/noImplicitAnyLet: + let schemaId - const { proofPresentationPayload, orgId } = payload; + const { proofPresentationPayload, orgId } = payload //For Educreds - if (proofPresentationPayload?.['proofData']?.presentation?.presentationExchange?.verifiableCredential) { + // biome-ignore lint/complexity/useLiteralKeys: + if (proofPresentationPayload?.['proofData']?.['presentation']?.presentationExchange?.verifiableCredential) { const emailId = - proofPresentationPayload?.['proofData']?.presentation?.presentationExchange?.verifiableCredential[0] - .credentialSubject?.email; - encryptEmailId = await this.commonService.dataEncryption(emailId); + proofPresentationPayload?.['proofData']?.['presentation']?.presentationExchange?.verifiableCredential[0] + .credentialSubject?.email + encryptEmailId = await this.commonService.dataEncryption(emailId) } else { - encryptEmailId = 'Not Available'; + encryptEmailId = 'Not Available' } //For Educreds if (proofPresentationPayload?.['proofData']?.request?.presentationExchange) { schemaId = proofPresentationPayload?.['proofData']?.request?.presentationExchange?.presentation_definition - ?.input_descriptors[0].schema[0].uri; + ?.input_descriptors[0].schema[0].uri } - if ('default' !== proofPresentationPayload?.contextCorrelationId) { - const getOrganizationId = await this.getOrganizationByTenantId(proofPresentationPayload?.contextCorrelationId); - organisationId = getOrganizationId?.orgId; + if (proofPresentationPayload?.contextCorrelationId !== 'default') { + const getOrganizationId = await this.getOrganizationByTenantId(proofPresentationPayload?.contextCorrelationId) + organisationId = getOrganizationId?.orgId } else { - organisationId = orgId; + organisationId = orgId } const proofPresentationsDetails = await this.prisma.presentations.upsert({ where: { - threadId: proofPresentationPayload?.threadId + threadId: proofPresentationPayload?.threadId, }, update: { state: proofPresentationPayload.state, @@ -194,7 +200,7 @@ export class VerificationRepository { lastChangedBy: organisationId, connectionId: proofPresentationPayload.connectionId, emailId: encryptEmailId, - errorMessage: proofPresentationPayload.errorMessage + errorMessage: proofPresentationPayload.errorMessage, }, create: { connectionId: proofPresentationPayload.connectionId, @@ -206,13 +212,13 @@ export class VerificationRepository { presentationId: proofPresentationPayload.id, orgId: organisationId, schemaId, - emailId: encryptEmailId - } - }); - return proofPresentationsDetails; + emailId: encryptEmailId, + }, + }) + return proofPresentationsDetails } catch (error) { - this.logger.error(`Error in get saveProofPresentationDetails: ${error.message} `); - throw error; + this.logger.error(`Error in get saveProofPresentationDetails: ${error.message} `) + throw error } } @@ -223,10 +229,10 @@ export class VerificationRepository { // 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; + this.logger.error(`[getPlatformConfigDetails] - error: ${JSON.stringify(error)}`) + throw error } } @@ -236,10 +242,10 @@ export class VerificationRepository { */ async getOrganization(orgId: string): Promise { try { - return this.prisma.organisation.findFirst({ where: { id: orgId } }); + return this.prisma.organisation.findFirst({ where: { id: orgId } }) } catch (error) { - this.logger.error(`[getOrganization] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrganization] - error: ${JSON.stringify(error)}`) + throw error } } @@ -247,14 +253,14 @@ export class VerificationRepository { try { const { agent } = await this.prisma.org_agents_type.findFirst({ where: { - id: orgAgentId - } - }); + id: orgAgentId, + }, + }) - return agent; + return agent } catch (error) { - this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getOrgAgentType] - error: ${JSON.stringify(error)}`) + throw error } } @@ -263,15 +269,15 @@ export class VerificationRepository { try { return this.prisma.agent_invitations.findMany({ where: { - orgId + orgId, }, orderBy: { - createDateTime: 'asc' // or 'desc' for descending order - } - }); + createDateTime: 'asc', // or 'desc' for descending order + }, + }) } catch (error) { - this.logger.error(`Error in getInvitationDid in verification repository: ${error.message}`); - throw error; + this.logger.error(`Error in getInvitationDid in verification repository: ${error.message}`) + throw error } } @@ -279,18 +285,18 @@ export class VerificationRepository { try { return await this.prisma.$transaction(async (prisma) => { const recordsToDelete = await this.prisma.presentations.findMany({ - where: { orgId } - }); + where: { orgId }, + }) const deleteResult = await prisma.presentations.deleteMany({ - where: { orgId } - }); + where: { orgId }, + }) - return { deleteResult, recordsToDelete }; - }); + return { deleteResult, recordsToDelete } + }) } catch (error) { - this.logger.error(`Error in deleting verification records: ${error.message}`); - throw error; + this.logger.error(`Error in deleting verification records: ${error.message}`) + throw error } } } diff --git a/apps/verification/src/verification.controller.ts b/apps/verification/src/verification.controller.ts index 5b795d419..93c90727c 100644 --- a/apps/verification/src/verification.controller.ts +++ b/apps/verification/src/verification.controller.ts @@ -1,21 +1,21 @@ -import { +import type { + IProofPresentationDetails, + IProofPresentationList, + IVerificationRecords, +} from '@credebl/common/interfaces/verification.interface' +import type { presentations, user } from '@prisma/client' +import type { IProofPresentation, IProofPresentationData, IProofRequestData, IProofRequests, - ISendProofRequestPayload -} from './interfaces/verification.interface'; -import { - IProofPresentationDetails, - IProofPresentationList, - IVerificationRecords -} from '@credebl/common/interfaces/verification.interface'; -import { presentations, user } from '@prisma/client'; + ISendProofRequestPayload, +} from './interfaces/verification.interface' -import { Controller } from '@nestjs/common'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { MessagePattern } from '@nestjs/microservices'; -import { VerificationService } from './verification.service'; +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { Controller } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { VerificationService } from './verification.service' @Controller() export class VerificationController { @@ -28,14 +28,14 @@ export class VerificationController { */ @MessagePattern({ cmd: 'get-all-proof-presentations' }) async getProofPresentations(payload: IProofRequests): Promise { - const { user, orgId, proofRequestsSearchCriteria } = payload; - return this.verificationService.getProofPresentations(user, orgId, proofRequestsSearchCriteria); + const { user, orgId, proofRequestsSearchCriteria } = payload + return this.verificationService.getProofPresentations(user, orgId, proofRequestsSearchCriteria) } @MessagePattern({ cmd: 'get-verification-records' }) async getVerificationRecordsByOrgId(payload: { orgId: string; userId: string }): Promise { - const { orgId } = payload; - return this.verificationService.getVerificationRecords(orgId); + const { orgId } = payload + return this.verificationService.getVerificationRecords(orgId) } /** @@ -46,7 +46,7 @@ export class VerificationController { */ @MessagePattern({ cmd: 'get-proof-presentations-by-proofId' }) async getProofPresentationById(payload: { proofId: string; orgId: string; user: IUserRequest }): Promise { - return this.verificationService.getProofPresentationById(payload.proofId, payload.orgId); + return this.verificationService.getProofPresentationById(payload.proofId, payload.orgId) } /** @@ -56,7 +56,7 @@ export class VerificationController { */ @MessagePattern({ cmd: 'get-proof-presentation-details-by-issuerId' }) async getProofPresentationByIssuerId(payload: { issuerId: string; user: IUserRequest }): Promise { - return this.verificationService.getProofPresentationByIssuerId(payload.issuerId); + return this.verificationService.getProofPresentationByIssuerId(payload.issuerId) } /** @@ -66,10 +66,10 @@ export class VerificationController { */ @MessagePattern({ cmd: 'send-proof-request' }) async sendProofRequest(payload: { - requestProofDto: IProofRequestData; - user: IUserRequest; + requestProofDto: IProofRequestData + user: IUserRequest }): Promise { - return this.verificationService.sendProofRequest(payload.requestProofDto); + return this.verificationService.sendProofRequest(payload.requestProofDto) } /** @@ -80,7 +80,7 @@ export class VerificationController { */ @MessagePattern({ cmd: 'verify-presentation' }) async verifyPresentation(payload: { proofId: string; orgId: string; user: IUserRequest }): Promise { - return this.verificationService.verifyPresentation(payload.proofId, payload.orgId); + return this.verificationService.verifyPresentation(payload.proofId, payload.orgId) } /** @@ -89,26 +89,26 @@ export class VerificationController { */ @MessagePattern({ cmd: 'webhook-proof-presentation' }) async webhookProofPresentation(payload: IProofPresentation): Promise { - return this.verificationService.webhookProofPresentation(payload); + return this.verificationService.webhookProofPresentation(payload) } @MessagePattern({ cmd: 'send-out-of-band-proof-request' }) async sendOutOfBandPresentationRequest(payload: { - outOfBandRequestProof: ISendProofRequestPayload; - user: IUserRequest; + outOfBandRequestProof: ISendProofRequestPayload + user: IUserRequest }): Promise { - return this.verificationService.sendOutOfBandPresentationRequest(payload.outOfBandRequestProof, payload.user); + return this.verificationService.sendOutOfBandPresentationRequest(payload.outOfBandRequestProof, payload.user) } @MessagePattern({ cmd: 'get-verified-proof-details' }) async getVerifiedProofdetails(payload: IProofPresentationData): Promise { - const { proofId, orgId } = payload; - return this.verificationService.getVerifiedProofdetails(proofId, orgId); + const { proofId, orgId } = payload + return this.verificationService.getVerifiedProofdetails(proofId, orgId) } @MessagePattern({ cmd: 'delete-verification-records' }) async deleteVerificationRecord(payload: { orgId: string; userDetails: user }): Promise { - const { orgId, userDetails } = payload; - return this.verificationService.deleteVerificationRecords(orgId, userDetails); + const { orgId, userDetails } = payload + return this.verificationService.deleteVerificationRecords(orgId, userDetails) } } diff --git a/apps/verification/src/verification.module.ts b/apps/verification/src/verification.module.ts index d5e849965..b5a07e000 100644 --- a/apps/verification/src/verification.module.ts +++ b/apps/verification/src/verification.module.ts @@ -1,22 +1,22 @@ -import { Logger, Module } from '@nestjs/common'; -import { VerificationController } from './verification.controller'; -import { VerificationService } from './verification.service'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { CommonModule } from '@credebl/common'; -import { VerificationRepository } from './repositories/verification.repository'; -import { PrismaService } from '@credebl/prisma-service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { OutOfBandVerification } from '../templates/out-of-band-verification.template'; -import { EmailDto } from '@credebl/common/dtos/email.dto'; -import { CacheModule } from '@nestjs/cache-manager'; -import { UserActivityService } from '@credebl/user-activity'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { NATSClient } from '@credebl/common/NATSClient'; +import { CommonModule } from '@credebl/common' +import { NATSClient } from '@credebl/common/NATSClient' +import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import { EmailDto } from '@credebl/common/dtos/email.dto' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { UserActivityService } from '@credebl/user-activity' +import { CacheModule } from '@nestjs/cache-manager' +import { Logger, Module } from '@nestjs/common' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { UserActivityRepository } from 'libs/user-activity/repositories' +import { OutOfBandVerification } from '../templates/out-of-band-verification.template' +import { VerificationRepository } from './repositories/verification.repository' +import { VerificationController } from './verification.controller' +import { VerificationService } from './verification.service' @Module({ imports: [ @@ -24,23 +24,32 @@ import { NATSClient } from '@credebl/common/NATSClient'; { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.VERIFICATION_SERVICE, process.env.VERIFICATION_NKEY_SEED) - - } + options: getNatsOptions(CommonConstants.VERIFICATION_SERVICE, process.env.VERIFICATION_NKEY_SEED), + }, ]), GlobalConfigModule, - CommonModule, LoggerModule, PlatformConfig, ContextInterceptorModule, - CacheModule.register() + CommonModule, + LoggerModule, + PlatformConfig, + ContextInterceptorModule, + CacheModule.register(), ], controllers: [VerificationController], providers: [ - VerificationService, VerificationRepository, PrismaService, UserActivityService, - UserActivityRepository, Logger, OutOfBandVerification, EmailDto, NATSClient, - { - provide: MICRO_SERVICE_NAME, - useValue: 'Verification-Service' - } -] + VerificationService, + VerificationRepository, + PrismaService, + UserActivityService, + UserActivityRepository, + Logger, + OutOfBandVerification, + EmailDto, + NATSClient, + { + provide: MICRO_SERVICE_NAME, + useValue: 'Verification-Service', + }, + ], }) -export class VerificationModule { } +export class VerificationModule {} diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 49cb45d86..c3c757255 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -1,3 +1,19 @@ +import type { NATSClient } from '@credebl/common/NATSClient' +import { ATTRIBUTE_NAME_REGEX, CommonConstants } from '@credebl/common/common.constant' +import { convertUrlToDeepLinkUrl } from '@credebl/common/common.utils' +import type { EmailDto } from '@credebl/common/dtos/email.dto' +import type { ISchemaDetail } from '@credebl/common/interfaces/schema.interface' +import type { + IProofPresentationDetails, + IProofPresentationList, + IVerificationRecords, +} from '@credebl/common/interfaces/verification.interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import { sendEmail } from '@credebl/common/send-grid-helper-file' +import { AutoAccept, OrgAgentType, VerificationProcessState } from '@credebl/enum/enum' +import type { UserActivityService } from '@credebl/user-activity' +import type { IUserRequest } from '@credebl/user-request/user-request.interface' +import { CACHE_MANAGER } from '@nestjs/cache-manager' /* eslint-disable camelcase */ import { BadRequestException, @@ -6,58 +22,49 @@ import { Injectable, InternalServerErrorException, Logger, - NotFoundException -} from '@nestjs/common'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import { map } from 'rxjs/operators'; + NotFoundException, +} from '@nestjs/common' +import { type ClientProxy, RpcException } from '@nestjs/microservices' import { + RecordType, + type agent_invitations, + type org_agents, + type organisation, + type presentations, + type user, +} from '@prisma/client' +import { + API_Version, + ProofRequestLabel, + ProofRequestType, + ProofVersion, + ProtocolVersionType, + VerificationMethodLabel, +} from 'apps/api-gateway/src/verification/enum/verification.enum' +import type { Cache } from 'cache-manager' +import type { UserActivityRepository } from 'libs/user-activity/repositories' +import * as QRCode from 'qrcode' +import { from } from 'rxjs' +import { map } from 'rxjs/operators' +import type { OutOfBandVerification } from '../templates/out-of-band-verification.template' +import type { IGetAllProofPresentations, - IProofRequestSearchCriteria, IGetProofPresentationById, + IInvitation, IProofPresentation, + IProofRequestData, IProofRequestPayload, + IProofRequestSearchCriteria, IRequestProof, ISendProofRequestPayload, - IVerifyPresentation, IVerifiedProofData, - IInvitation, - IProofRequestData -} from './interfaces/verification.interface'; -import { VerificationRepository } from './repositories/verification.repository'; -import { ATTRIBUTE_NAME_REGEX, CommonConstants } from '@credebl/common/common.constant'; -import { RecordType, agent_invitations, org_agents, organisation, presentations, user } from '@prisma/client'; -import { AutoAccept, OrgAgentType, VerificationProcessState } from '@credebl/enum/enum'; -import { ResponseMessages } from '@credebl/common/response-messages'; -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'; -import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { - IProofPresentationDetails, - IProofPresentationList, - IVerificationRecords -} from '@credebl/common/interfaces/verification.interface'; -import { - API_Version, - ProofRequestLabel, - ProofRequestType, - ProofVersion, - ProtocolVersionType, - VerificationMethodLabel -} from 'apps/api-gateway/src/verification/enum/verification.enum'; -import { UserActivityService } from '@credebl/user-activity'; -import { convertUrlToDeepLinkUrl } from '@credebl/common/common.utils'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { ISchemaDetail } from '@credebl/common/interfaces/schema.interface'; -import { NATSClient } from '@credebl/common/NATSClient'; -import { from } from 'rxjs'; + IVerifyPresentation, +} from './interfaces/verification.interface' +import type { VerificationRepository } from './repositories/verification.repository' @Injectable() export class VerificationService { - private readonly logger = new Logger('VerificationService'); + private readonly logger = new Logger('VerificationService') constructor( @Inject('NATS_CLIENT') private readonly verificationServiceProxy: ClientProxy, @@ -87,93 +94,94 @@ export class VerificationService { user, orgId, proofRequestsSearchCriteria - ); + ) - const schemaIds = getProofRequestsList?.proofRequestsList?.map((schema) => schema?.schemaId).filter(Boolean); + const schemaIds = getProofRequestsList?.proofRequestsList?.map((schema) => schema?.schemaId).filter(Boolean) - const getSchemaDetails = await this._getSchemaAndOrganizationDetails(schemaIds); + const getSchemaDetails = await this._getSchemaAndOrganizationDetails(schemaIds) const proofDetails = getProofRequestsList.proofRequestsList.map((proofRequest) => { - const schemaDetail = getSchemaDetails.find((schema) => schema.schemaLedgerId === proofRequest.schemaId); + const schemaDetail = getSchemaDetails.find((schema) => schema.schemaLedgerId === proofRequest.schemaId) return { ...proofRequest, schemaName: schemaDetail ? schemaDetail?.name : '', - issuanceEntity: schemaDetail ? schemaDetail?.['organisation']?.name : '' - }; - }); + issuanceEntity: schemaDetail ? schemaDetail?.organisation?.name : '', + } + }) - if (0 === getProofRequestsList.proofRequestsCount) { - throw new NotFoundException(ResponseMessages.verification.error.proofPresentationNotFound); + if (getProofRequestsList.proofRequestsCount === 0) { + throw new NotFoundException(ResponseMessages.verification.error.proofPresentationNotFound) } const proofPresentationsResponse: { - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; + totalItems: number + hasNextPage: boolean + hasPreviousPage: boolean + nextPage: number + previousPage: number + lastPage: number data: { - createDateTime: Date; - createdBy: string; - connectionId: string; - state: string; - orgId: string; - presentationId: string; - id: string; - }[]; + createDateTime: Date + createdBy: string + connectionId: string + state: string + orgId: string + presentationId: string + id: string + }[] } = { totalItems: getProofRequestsList.proofRequestsCount, hasNextPage: proofRequestsSearchCriteria.pageSize * proofRequestsSearchCriteria.pageNumber < getProofRequestsList.proofRequestsCount, - hasPreviousPage: 1 < proofRequestsSearchCriteria.pageNumber, + hasPreviousPage: proofRequestsSearchCriteria.pageNumber > 1, nextPage: Number(proofRequestsSearchCriteria.pageNumber) + 1, previousPage: proofRequestsSearchCriteria.pageNumber - 1, lastPage: Math.ceil(getProofRequestsList.proofRequestsCount / proofRequestsSearchCriteria.pageSize), - data: proofDetails || getProofRequestsList?.proofRequestsList - }; + data: proofDetails || getProofRequestsList?.proofRequestsList, + } - return proofPresentationsResponse; + return proofPresentationsResponse } catch (error) { + console.log('') this.logger.error( `[getProofRequests] [NATS call]- error in fetch proof requests details : ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } async _getSchemaAndOrganizationDetails(templateIds: string[]): Promise { - const pattern = { cmd: 'get-schemas-details' }; + const pattern = { cmd: 'get-schemas-details' } const payload = { - templateIds - }; + templateIds, + } const schemaAndOrgDetails = await this.natsClient .send(this.verificationServiceProxy, pattern, payload) .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); - }); - return schemaAndOrgDetails; + ) + }) + return schemaAndOrgDetails } async getVerificationRecords(orgId: string): Promise { try { - return await this.verificationRepository.getVerificationRecordsCount(orgId); + return await this.verificationRepository.getVerificationRecordsCount(orgId) } catch (error) { this.logger.error( `[getVerificationRecords ] [NATS call]- error in get verification records count : ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } @@ -183,14 +191,14 @@ export class VerificationService { * @returns Get all proof presentation */ async _getProofPresentations(payload: IGetAllProofPresentations): Promise<{ - response: string; + response: string }> { try { - const pattern = { cmd: 'agent-get-proof-presentations' }; - return await this.natsCall(pattern, payload); + 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; + this.logger.error(`[_getProofPresentations] - error in get proof presentations : ${JSON.stringify(error)}`) + throw error } } @@ -201,19 +209,19 @@ export class VerificationService { */ async getProofPresentationByIssuerId(issuerId: string): Promise { try { - const orgDetails = await this.verificationRepository.getOrgDetails(issuerId); + const orgDetails = await this.verificationRepository.getOrgDetails(issuerId) const getVerifiedProofCount = await this.verificationRepository.getVerificationRecordsCount( - orgDetails?.['orgId'], + orgDetails?.orgId, VerificationProcessState.DONE - ); + ) - return getVerifiedProofCount; + return getVerifiedProofCount } catch (error) { this.logger.error( `[getProofPresentationByIssuerId] - error in get proof presentation by issuerId : ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } @@ -225,10 +233,10 @@ export class VerificationService { */ async getProofPresentationById(proofId: string, orgId: string): Promise { try { - const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId); + const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId) - const verificationMethodLabel = 'get-proof-presentation-by-id'; - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); + const verificationMethodLabel = 'get-proof-presentation-by-id' + const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId) const url = await this.getAgentUrl( verificationMethodLabel, orgAgentType, @@ -236,27 +244,26 @@ export class VerificationService { getAgentDetails?.tenantId, '', proofId - ); + ) - const payload = { orgId, url }; + const payload = { orgId, url } - const getProofPresentationById = await this._getProofPresentationById(payload); - return getProofPresentationById?.response; + const getProofPresentationById = await this._getProofPresentationById(payload) + return getProofPresentationById?.response } catch (error) { this.logger.error( `[getProofPresentationById] - error in get proof presentation by proofId : ${JSON.stringify(error)}` - ); - const errorStack = error?.response?.error?.reason; + ) + const errorStack = error?.response?.error?.reason if (errorStack) { throw new RpcException({ message: ResponseMessages.verification.error.proofNotFound, statusCode: error?.response?.status, - error: errorStack - }); - } else { - throw new RpcException(error.response ? error.response : error); + error: errorStack, + }) } + throw new RpcException(error.response ? error.response : error) } } @@ -266,19 +273,19 @@ export class VerificationService { * @returns Get proof presentation details */ async _getProofPresentationById(payload: IGetProofPresentationById): Promise<{ - response: string; + response: string }> { try { const pattern = { - cmd: 'agent-get-proof-presentation-by-id' - }; + cmd: 'agent-get-proof-presentation-by-id', + } - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { this.logger.error( `[_getProofPresentationById] - error in get proof presentation by id : ${JSON.stringify(error)}` - ); - throw error; + ) + throw error } } @@ -290,16 +297,16 @@ export class VerificationService { async sendProofRequest(requestProof: IProofRequestData): Promise { try { - const comment = requestProof.comment ? requestProof.comment : ''; - const getAgentDetails = await this.verificationRepository.getAgentEndPoint(requestProof.orgId); - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); - const verificationMethodLabel = VerificationMethodLabel.REQUEST_PROOF; + const comment = requestProof.comment ? requestProof.comment : '' + const getAgentDetails = await this.verificationRepository.getAgentEndPoint(requestProof.orgId) + const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId) + const verificationMethodLabel = VerificationMethodLabel.REQUEST_PROOF const url = await this.getAgentUrl( verificationMethodLabel, orgAgentType, getAgentDetails?.agentEndPoint, getAgentDetails?.tenantId - ); + ) // Function to create a payload const createPayload = async (connectionId: string): Promise => { @@ -309,19 +316,19 @@ export class VerificationService { autoAcceptProof: requestProof.autoAcceptProof || AutoAccept.Never, goalCode: requestProof.goalCode || undefined, parentThreadId: requestProof.parentThreadId || undefined, - willConfirm: requestProof.willConfirm || undefined - }; + willConfirm: requestProof.willConfirm || undefined, + } const payload: IProofRequestPayload = { orgId: requestProof.orgId, url, - proofRequestPayload: {} - }; + proofRequestPayload: {}, + } if (requestProof.type === ProofRequestType.INDY) { const { requestedAttributes, requestedPredicates } = await this._proofRequestPayload( requestProof as IRequestProof - ); + ) payload.proofRequestPayload = { protocolVersion: requestProof.protocolVersion || ProtocolVersionType.PROTOCOL_VERSION_1, proofFormats: { @@ -329,66 +336,65 @@ export class VerificationService { name: ProofRequestLabel.PROOF_REQUEST, version: ProofVersion.PROOF_VERSION, requested_attributes: requestedAttributes, - requested_predicates: requestedPredicates - } + requested_predicates: requestedPredicates, + }, }, - ...proofRequestPayload - }; + ...proofRequestPayload, + } } else if (requestProof.type === ProofRequestType.PRESENTATIONEXCHANGE) { payload.proofRequestPayload = { protocolVersion: requestProof.protocolVersion || ProtocolVersionType.PROTOCOL_VERSION_2, proofFormats: { presentationExchange: { - presentationDefinition: requestProof.presentationDefinition - } + presentationDefinition: requestProof.presentationDefinition, + }, }, - ...proofRequestPayload - }; + ...proofRequestPayload, + } } - return payload; - }; + return payload + } if (API_Version.VERSION_1 === requestProof.version) { const connectionIds = Array.isArray(requestProof.connectionId) ? requestProof.connectionId - : [requestProof.connectionId]; + : [requestProof.connectionId] - const responses: string[] = []; + const responses: string[] = [] for (const connectionId of connectionIds) { - const payload = await createPayload(connectionId); - const getProofPresentationById = await this._sendProofRequest(payload); - responses.push(getProofPresentationById?.response); + const payload = await createPayload(connectionId) + const getProofPresentationById = await this._sendProofRequest(payload) + responses.push(getProofPresentationById?.response) } - return responses; - } else { - const connectionId = Array.isArray(requestProof.connectionId) - ? requestProof.connectionId[0] - : requestProof.connectionId; - - const payload = await createPayload(connectionId); - const getProofPresentationById = await this._sendProofRequest(payload); - return getProofPresentationById?.response; + return responses } + const connectionId = Array.isArray(requestProof.connectionId) + ? requestProof.connectionId[0] + : requestProof.connectionId + + const payload = await createPayload(connectionId) + const getProofPresentationById = await this._sendProofRequest(payload) + return getProofPresentationById?.response } catch (error) { // Handle cases where identical attributes are used in both predicates and non-predicates. // This case is not supported in credo-ts, so we are handling in platform // TODO: Handle all credo-errors globally in platform - const errorMessage = error?.status?.message?.error?.message; + const errorMessage = error?.status?.message?.error?.message const match = errorMessage?.match( /CredoError: The proof request contains duplicate predicates and attributes: (.+)/ - ); + ) if (match) { - const [, duplicateAttributes] = match; + const [, duplicateAttributes] = match throw new RpcException({ message: `CredoError: The proof request contains duplicate attributes: ${duplicateAttributes}`, - statusCode: 500 - }); + statusCode: 500, + }) } - this.logger.error(`[sendProofRequest] - error in sending proof request: ${JSON.stringify(error)}`); - this.verificationErrorHandling(error); + this.logger.error(`[sendProofRequest] - error in sending proof request: ${JSON.stringify(error)}`) + this.verificationErrorHandling(error) } } @@ -398,17 +404,17 @@ export class VerificationService { * @returns Get requested proof presentation details */ async _sendProofRequest(payload: IProofRequestPayload): Promise<{ - response: string; + response: string }> { try { const pattern = { - cmd: 'agent-send-proof-request' - }; + cmd: 'agent-send-proof-request', + } - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`[_sendProofRequest] - error in verify presentation : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[_sendProofRequest] - error in verify presentation : ${JSON.stringify(error)}`) + throw error } } @@ -420,10 +426,10 @@ export class VerificationService { */ async verifyPresentation(proofId: string, orgId: string): Promise { try { - const getAgentData = await this.verificationRepository.getAgentEndPoint(orgId); - const orgAgentTypeData = await this.verificationRepository.getOrgAgentType(getAgentData?.orgAgentTypeId); + const getAgentData = await this.verificationRepository.getAgentEndPoint(orgId) + const orgAgentTypeData = await this.verificationRepository.getOrgAgentType(getAgentData?.orgAgentTypeId) - const verificationMethod = 'accept-presentation'; + const verificationMethod = 'accept-presentation' const url = await this.getAgentUrl( verificationMethod, @@ -432,26 +438,25 @@ export class VerificationService { getAgentData?.tenantId, '', proofId - ); + ) - const payload = { orgId, url }; - const getProofPresentationById = await this._verifyPresentation(payload); - return getProofPresentationById?.response; + const payload = { orgId, url } + const getProofPresentationById = await this._verifyPresentation(payload) + return getProofPresentationById?.response } catch (error) { this.logger.error( `[getProofPresentationById] - error in get proof presentation by proofId : ${JSON.stringify(error)}` - ); - const errorStack = error?.response?.error?.reason; + ) + const errorStack = error?.response?.error?.reason if (errorStack) { throw new RpcException({ message: ResponseMessages.verification.error.proofNotFound, statusCode: error?.response?.status, - error: errorStack - }); - } else { - throw new RpcException(error.response ? error.response : error); + error: errorStack, + }) } + throw new RpcException(error.response ? error.response : error) } } @@ -461,27 +466,27 @@ export class VerificationService { * @returns Get verified proof presentation details */ async _verifyPresentation(payload: IVerifyPresentation): Promise<{ - response: string; + response: string }> { try { const pattern = { - cmd: 'agent-verify-presentation' - }; + cmd: 'agent-verify-presentation', + } - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`[_verifyPresentation] - error in verify presentation : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[_verifyPresentation] - error in verify presentation : ${JSON.stringify(error)}`) + throw error } } async webhookProofPresentation(proofPresentationPayload: IProofPresentation): Promise { try { - const proofPresentation = await this.verificationRepository.storeProofPresentation(proofPresentationPayload); - return proofPresentation; + const proofPresentation = await this.verificationRepository.storeProofPresentation(proofPresentationPayload) + return proofPresentation } catch (error) { - this.logger.error(`[webhookProofPresentation] - error in webhook proof presentation : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[webhookProofPresentation] - error in webhook proof presentation : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -499,49 +504,49 @@ export class VerificationService { const [getAgentDetails, getOrganization] = await Promise.all([ this.verificationRepository.getAgentEndPoint(user.orgId), - this.verificationRepository.getOrganization(user.orgId) - ]); + this.verificationRepository.getOrganization(user.orgId), + ]) - const label = getOrganization?.name; + const label = getOrganization?.name if (getOrganization?.logoUrl) { - outOfBandRequestProof['imageUrl'] = getOrganization?.logoUrl; + outOfBandRequestProof.imageUrl = getOrganization?.logoUrl } - outOfBandRequestProof['label'] = label; + outOfBandRequestProof.label = label - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); - const verificationMethodLabel = 'create-request-out-of-band'; + 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 - ); + ) // Destructuring 'outOfBandRequestProof' to remove emailId, as it is not used while agent operation - const { isShortenUrl, emailId, type, reuseConnection, ...updateOutOfBandRequestProof } = outOfBandRequestProof; - let invitationDid: string | undefined; - if (true === reuseConnection) { - const data: agent_invitations[] = await this.verificationRepository.getInvitationDidByOrgId(user.orgId); - if (data && 0 < data.length) { - const [firstElement] = data; - invitationDid = firstElement?.invitationDid ?? undefined; + const { isShortenUrl, emailId, type, reuseConnection, ...updateOutOfBandRequestProof } = outOfBandRequestProof + let invitationDid: string | undefined + if (reuseConnection === true) { + const data: agent_invitations[] = await this.verificationRepository.getInvitationDidByOrgId(user.orgId) + if (data && data.length > 0) { + const [firstElement] = data + invitationDid = firstElement?.invitationDid ?? undefined } } - outOfBandRequestProof.autoAcceptProof = outOfBandRequestProof.autoAcceptProof || AutoAccept.Always; + outOfBandRequestProof.autoAcceptProof = outOfBandRequestProof.autoAcceptProof || AutoAccept.Always - let payload: IProofRequestPayload; + let payload: IProofRequestPayload if (ProofRequestType.INDY === type) { - updateOutOfBandRequestProof.protocolVersion = updateOutOfBandRequestProof.protocolVersion || 'v1'; - updateOutOfBandRequestProof.invitationDid = invitationDid || undefined; - updateOutOfBandRequestProof.imageUrl = getOrganization?.logoUrl || undefined; + updateOutOfBandRequestProof.protocolVersion = updateOutOfBandRequestProof.protocolVersion || 'v1' + updateOutOfBandRequestProof.invitationDid = invitationDid || undefined + updateOutOfBandRequestProof.imageUrl = getOrganization?.logoUrl || undefined payload = { orgId: user.orgId, url, - proofRequestPayload: updateOutOfBandRequestProof - }; + proofRequestPayload: updateOutOfBandRequestProof, + } } if (ProofRequestType.PRESENTATIONEXCHANGE === type) { @@ -563,56 +568,55 @@ export class VerificationService { id: outOfBandRequestProof.presentationDefinition.id, name: outOfBandRequestProof.presentationDefinition.name, purpose: outOfBandRequestProof?.presentationDefinition?.purpose, - input_descriptors: [...outOfBandRequestProof.presentationDefinition.input_descriptors] - } - } + input_descriptors: [...outOfBandRequestProof.presentationDefinition.input_descriptors], + }, + }, }, autoAcceptProof: outOfBandRequestProof.autoAcceptProof, - invitationDid: invitationDid || undefined - } - }; + invitationDid: invitationDid || undefined, + }, + } } if (emailId) { - const emailResponse = await this.sendEmailInBatches(payload, emailId, getAgentDetails, getOrganization); - return emailResponse; - } else { - const presentationProof: IInvitation = await this.generateOOBProofReq(payload); - const proofRequestInvitationUrl: string = presentationProof.invitationUrl; - if (isShortenUrl) { - const shortenedUrl: string = await this.storeVerificationObjectAndReturnUrl(proofRequestInvitationUrl, false); - this.logger.log('shortenedUrl', shortenedUrl); - if (shortenedUrl) { - presentationProof.invitationUrl = shortenedUrl; - presentationProof.deepLinkURL = convertUrlToDeepLinkUrl(shortenedUrl); - } - } - if (!presentationProof) { - throw new Error(ResponseMessages.verification.error.proofPresentationNotFound); + const emailResponse = await this.sendEmailInBatches(payload, emailId, getAgentDetails, getOrganization) + return emailResponse + } + const presentationProof: IInvitation = await this.generateOOBProofReq(payload) + const proofRequestInvitationUrl: string = presentationProof.invitationUrl + if (isShortenUrl) { + const shortenedUrl: string = await this.storeVerificationObjectAndReturnUrl(proofRequestInvitationUrl, false) + this.logger.log('shortenedUrl', shortenedUrl) + if (shortenedUrl) { + presentationProof.invitationUrl = shortenedUrl + presentationProof.deepLinkURL = convertUrlToDeepLinkUrl(shortenedUrl) } - return presentationProof; } + if (!presentationProof) { + throw new Error(ResponseMessages.verification.error.proofPresentationNotFound) + } + return presentationProof } catch (error) { - this.logger.error(`[sendOutOfBandPresentationRequest] - error in out of band proof request : ${error.message}`); - this.verificationErrorHandling(error); + this.logger.error(`[sendOutOfBandPresentationRequest] - error in out of band proof request : ${error.message}`) + this.verificationErrorHandling(error) } } async storeVerificationObjectAndReturnUrl(storeObj: string, persistent: boolean): Promise { //nats call in agent-service to create an invitation url - const pattern = { cmd: 'store-object-return-url' }; - const payload = { persistent, storeObj }; - const message = await this.natsCall(pattern, payload); - return message.response; + const pattern = { cmd: 'store-object-return-url' } + const payload = { persistent, storeObj } + const message = await this.natsCall(pattern, payload) + return message.response } private async generateOOBProofReq(payload: IProofRequestPayload): Promise { - const getProofPresentation = await this._sendOutOfBandProofRequest(payload); + const getProofPresentation = await this._sendOutOfBandProofRequest(payload) if (!getProofPresentation) { - throw new Error(ResponseMessages.verification.error.proofPresentationNotFound); + throw new Error(ResponseMessages.verification.error.proofPresentationNotFound) } - return getProofPresentation.response; + return getProofPresentation.response } // Currently batch size is not used, as length of emails sent is restricted to '10' @@ -623,30 +627,30 @@ export class VerificationService { organizationDetails: organisation ): Promise { try { - const accumulatedErrors = []; - const accumulatedResponse = []; + const accumulatedErrors = [] + const accumulatedResponse = [] for (const email of emailIds) { try { - const response = await this.sendOutOfBandProofRequest(payload, email, getAgentDetails, organizationDetails); - accumulatedResponse.push({ email, ...response }); + const response = await this.sendOutOfBandProofRequest(payload, email, getAgentDetails, organizationDetails) + accumulatedResponse.push({ email, ...response }) - await this.delay(500); + await this.delay(500) } catch (error) { - this.logger.error(`Error sending email to ${email}::::::`, error); - accumulatedErrors.push(error); + this.logger.error(`Error sending email to ${email}::::::`, error) + accumulatedErrors.push(error) } } - if (0 < accumulatedErrors.length) { - this.logger.error(accumulatedErrors); - throw new Error(ResponseMessages.verification.error.emailSend); + if (accumulatedErrors.length > 0) { + this.logger.error(accumulatedErrors) + throw new Error(ResponseMessages.verification.error.emailSend) } - return accumulatedResponse; - } catch (error) { - this.logger.error('[sendEmailInBatches] - error in sending email in batches'); - throw new Error(ResponseMessages.verification.error.batchEmailSend); + return accumulatedResponse + } catch (_error) { + this.logger.error('[sendEmailInBatches] - error in sending email in batches') + throw new Error(ResponseMessages.verification.error.batchEmailSend) } } @@ -654,56 +658,56 @@ export class VerificationService { async sendOutOfBandProofRequest( payload: IProofRequestPayload, email: string, - getAgentDetails: org_agents, + _getAgentDetails: org_agents, organizationDetails: organisation ): Promise { - const getProofPresentation = await this._sendOutOfBandProofRequest(payload); + const getProofPresentation = await this._sendOutOfBandProofRequest(payload) if (!getProofPresentation) { - throw new Error(ResponseMessages.verification.error.proofPresentationNotFound); + throw new Error(ResponseMessages.verification.error.proofPresentationNotFound) } - const invitationUrl = getProofPresentation?.response?.invitationUrl; + const invitationUrl = getProofPresentation?.response?.invitationUrl // Currently have shortenedUrl to store only for 30 days - const persist: boolean = false; - const shortenedUrl = await this.storeVerificationObjectAndReturnUrl(invitationUrl, persist); - const deepLinkURL = convertUrlToDeepLinkUrl(shortenedUrl); - const qrCodeOptions: QRCode.QRCodeToDataURLOptions = { type: 'image/png' }; - const outOfBandVerificationQrCode = await QRCode.toDataURL(shortenedUrl, qrCodeOptions); + const persist: boolean = false + const shortenedUrl = await this.storeVerificationObjectAndReturnUrl(invitationUrl, persist) + const deepLinkURL = convertUrlToDeepLinkUrl(shortenedUrl) + const qrCodeOptions: QRCode.QRCodeToDataURLOptions = { type: 'image/png' } + const outOfBandVerificationQrCode = await QRCode.toDataURL(shortenedUrl, qrCodeOptions) - const platformConfigData = await this.verificationRepository.getPlatformConfigDetails(); + const platformConfigData = await this.verificationRepository.getPlatformConfigDetails() if (!platformConfigData) { - throw new Error(ResponseMessages.verification.error.platformConfigNotFound); + throw new Error(ResponseMessages.verification.error.platformConfigNotFound) } - this.emailData.emailFrom = platformConfigData.emailFrom; - this.emailData.emailTo = email; - this.emailData.emailSubject = `${process.env.PLATFORM_NAME} Platform: Verification of Your Credentials`; + this.emailData.emailFrom = platformConfigData.emailFrom + this.emailData.emailTo = email + this.emailData.emailSubject = `${process.env.PLATFORM_NAME} Platform: Verification of Your Credentials` this.emailData.emailHtml = await this.outOfBandVerification.outOfBandVerification( email, organizationDetails.name, deepLinkURL - ); + ) this.emailData.emailAttachments = [ { filename: 'qrcode.png', content: outOfBandVerificationQrCode.split(';base64,')[1], contentType: 'image/png', - disposition: 'attachment' - } - ]; - const isEmailSent = await sendEmail(this.emailData); + disposition: 'attachment', + }, + ] + const isEmailSent = await sendEmail(this.emailData) if (!isEmailSent) { - throw new Error(ResponseMessages.verification.error.emailSend); + throw new Error(ResponseMessages.verification.error.emailSend) } return { isEmailSent, outOfBandRecordId: getProofPresentation?.response?.outOfBandRecord?.id, - proofRecordThId: getProofPresentation?.response?.proofRecordThId - }; + proofRecordThId: getProofPresentation?.response?.proofRecordThId, + } } /** @@ -712,35 +716,35 @@ export class VerificationService { * @returns Get requested proof presentation details */ async _sendOutOfBandProofRequest(payload: IProofRequestPayload): Promise<{ - response; + response }> { try { const pattern = { - cmd: 'agent-send-out-of-band-proof-request' - }; + cmd: 'agent-send-out-of-band-proof-request', + } - return await 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)}`); - throw error; + this.logger.error(`[_sendOutOfBandProofRequest] - error in Out Of Band Presentation : ${JSON.stringify(error)}`) + throw error } } async _proofRequestPayload(proofRequestpayload: IProofRequestData): Promise<{ - requestedAttributes; - requestedPredicates; + requestedAttributes + requestedPredicates }> { try { - let requestedAttributes = {}; - const requestedPredicates = {}; + let requestedAttributes = {} + const requestedPredicates = {} - const indyAttributes = proofRequestpayload.proofFormats?.indy; + const indyAttributes = proofRequestpayload.proofFormats?.indy if (indyAttributes && indyAttributes.attributes) { requestedAttributes = Object.fromEntries( indyAttributes.attributes.map((attribute, index) => { - const attributeElement = attribute.attributeName || attribute.attributeNames; - const attributeReferent = `additionalProp${index + 1}`; - const attributeKey = attribute.attributeName ? 'name' : 'names'; + const attributeElement = attribute.attributeName || attribute.attributeNames + const attributeReferent = `additionalProp${index + 1}` + const attributeKey = attribute.attributeName ? 'name' : 'names' if (!attribute.condition && !attribute.value) { return [ @@ -752,41 +756,41 @@ export class VerificationService { cred_def_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].credDefId ? proofRequestpayload.proofFormats.indy.attributes[index].credDefId : undefined, - schema_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].schemaId - } - ] - } - ]; + schema_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].schemaId, + }, + ], + }, + ] } else { requestedPredicates[attributeReferent] = { p_type: attribute.condition, name: attributeElement, - p_value: parseInt(attribute.value), + p_value: Number.parseInt(attribute.value), restrictions: [ { cred_def_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].credDefId ? proofRequestpayload?.proofFormats?.indy?.attributes[index].credDefId : undefined, - schema_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].schemaId - } - ] - }; + schema_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].schemaId, + }, + ], + } } - return [attributeReferent]; + return [attributeReferent] }) - ); + ) return { requestedAttributes, - requestedPredicates - }; + requestedPredicates, + } } else { - throw new BadRequestException(ResponseMessages.verification.error.proofNotSend); + throw new BadRequestException(ResponseMessages.verification.error.proofNotSend) } } catch (error) { - this.logger.error(`[proofRequestPayload] - error in proof request payload : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[proofRequestPayload] - error in proof request payload : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -804,7 +808,7 @@ export class VerificationService { proofPresentationId?: string ): Promise { try { - let url; + let url switch (verificationMethodLabel) { case 'get-proof-presentation': { url = @@ -819,8 +823,8 @@ export class VerificationService { ? `${agentEndPoint}${CommonConstants.URL_GET_PROOF_PRESENTATIONS}` : orgAgentType === OrgAgentType.SHARED ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_GET_PROOFS}`.replace('#', tenantId) - : null; - break; + : null + break } case 'get-proof-presentation-by-id': { @@ -831,8 +835,8 @@ export class VerificationService { ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_GET_PROOFS_BY_PRESENTATION_ID}` .replace('#', proofPresentationId) .replace('@', tenantId) - : null; - break; + : null + break } case 'request-proof': { @@ -841,8 +845,8 @@ export class VerificationService { ? `${agentEndPoint}${CommonConstants.URL_SEND_PROOF_REQUEST}` : orgAgentType === OrgAgentType.SHARED ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_REQUEST_PROOF}`.replace('#', tenantId) - : null; - break; + : null + break } case 'accept-presentation': { @@ -853,8 +857,8 @@ export class VerificationService { ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_ACCEPT_PRESENTATION}` .replace('@', proofPresentationId) .replace('#', tenantId) - : null; - break; + : null + break } case 'create-request-out-of-band': { @@ -863,8 +867,8 @@ export class VerificationService { ? `${agentEndPoint}${CommonConstants.URL_SEND_OUT_OF_BAND_CREATE_REQUEST}` : orgAgentType === OrgAgentType.SHARED ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_OUT_OF_BAND_CREATE_REQUEST}`.replace('#', tenantId) - : null; - break; + : null + break } case 'get-verified-proof': { @@ -875,34 +879,34 @@ export class VerificationService { ? `${agentEndPoint}${CommonConstants.URL_SHAGENT_PROOF_FORM_DATA}` .replace('@', proofPresentationId) .replace('#', tenantId) - : null; - break; + : null + break } default: { - break; + break } } if (!url) { - throw new NotFoundException(ResponseMessages.verification.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.verification.error.agentUrlNotFound) } - return url; + return url } catch (error) { - this.logger.error(`Error in get agent url: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in get agent url: ${JSON.stringify(error)}`) + throw error } } async getVerifiedProofdetails(proofId: string, orgId: string): Promise { try { - const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId); - const verificationMethodLabel = 'get-verified-proof'; - let credDefId; - let schemaId; - let certificate; - const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId); + const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId) + const verificationMethodLabel = 'get-verified-proof' + let credDefId + let schemaId + let certificate + const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId) const url = await this.getAgentUrl( verificationMethodLabel, orgAgentType, @@ -910,38 +914,38 @@ export class VerificationService { getAgentDetails?.tenantId, '', proofId - ); + ) - const payload = { orgId, url }; + const payload = { orgId, url } - const getProofPresentationById = await this._getVerifiedProofDetails(payload); + const getProofPresentationById = await this._getVerifiedProofDetails(payload) if (!getProofPresentationById?.response?.presentation) { throw new NotFoundException(ResponseMessages.verification.error.proofPresentationNotFound, { cause: new Error(), - description: ResponseMessages.errorMessages.notFound - }); + description: ResponseMessages.errorMessages.notFound, + }) } - const extractedDataArray: IProofPresentationDetails[] = []; + const extractedDataArray: IProofPresentationDetails[] = [] // For Presentation Exchange format if (getProofPresentationById?.response?.request?.presentationExchange) { const presentationDefinition = - getProofPresentationById?.response?.request?.presentationExchange?.presentation_definition; + getProofPresentationById?.response?.request?.presentationExchange?.presentation_definition const verifiableCredentials = - getProofPresentationById?.response?.presentation?.presentationExchange?.verifiableCredential; + getProofPresentationById?.response?.presentation?.presentationExchange?.verifiableCredential presentationDefinition?.input_descriptors.forEach((descriptor, index) => { - const schemaId = descriptor?.schema[0]?.uri; - const requestedAttributesForPresentationExchangeFormat = descriptor?.constraints?.fields[0]?.path; + const schemaId = descriptor?.schema[0]?.uri + const requestedAttributesForPresentationExchangeFormat = descriptor?.constraints?.fields[0]?.path - const verifiableCredential = verifiableCredentials[index]?.credentialSubject; + const verifiableCredential = verifiableCredentials[index]?.credentialSubject if (getProofPresentationById?.response) { certificate = getProofPresentationById?.response?.presentation?.presentationExchange?.verifiableCredential[0].prettyVc - ?.certificate; + ?.certificate } if ( @@ -950,191 +954,189 @@ export class VerificationService { ) { requestedAttributesForPresentationExchangeFormat.forEach((requestedAttributeKey) => { const attributeName = - requestedAttributeKey?.match(ATTRIBUTE_NAME_REGEX)?.[1] || requestedAttributeKey?.split('.').pop(); - const attributeValue = verifiableCredential?.[attributeName]; + requestedAttributeKey?.match(ATTRIBUTE_NAME_REGEX)?.[1] || requestedAttributeKey?.split('.').pop() + const attributeValue = verifiableCredential?.[attributeName] if (attributeName && attributeValue !== undefined) { const extractedData: IProofPresentationDetails = { [attributeName]: attributeValue, schemaId: schemaId || null, - certificateTemplate: certificate - }; + certificateTemplate: certificate, + } - extractedDataArray.push(extractedData); + extractedDataArray.push(extractedData) } - }); + }) } - }); + }) } // For Indy format if (getProofPresentationById?.response?.request?.indy) { - const requestedAttributes = getProofPresentationById?.response?.request?.indy?.requested_attributes; - const requestedPredicates = getProofPresentationById?.response?.request?.indy?.requested_predicates; - const revealedAttrs = getProofPresentationById?.response?.presentation?.indy?.requested_proof?.revealed_attrs; + const requestedAttributes = getProofPresentationById?.response?.request?.indy?.requested_attributes + const requestedPredicates = getProofPresentationById?.response?.request?.indy?.requested_predicates + const revealedAttrs = getProofPresentationById?.response?.presentation?.indy?.requested_proof?.revealed_attrs - if (0 !== Object.keys(requestedAttributes).length && 0 !== Object.keys(requestedPredicates).length) { + if (Object.keys(requestedAttributes).length !== 0 && Object.keys(requestedPredicates).length !== 0) { for (const key in requestedAttributes) { if (requestedAttributes.hasOwnProperty(key)) { - const requestedAttributeKey = requestedAttributes[key]; - const attributeName = requestedAttributeKey.name; + const requestedAttributeKey = requestedAttributes[key] + const attributeName = requestedAttributeKey.name if (requestedAttributeKey?.restrictions) { - credDefId = requestedAttributeKey?.restrictions[0]?.cred_def_id; - schemaId = requestedAttributeKey?.restrictions[0]?.schema_id; + credDefId = requestedAttributeKey?.restrictions[0]?.cred_def_id + schemaId = requestedAttributeKey?.restrictions[0]?.schema_id } else if (getProofPresentationById?.response?.presentation?.indy?.identifiers) { - credDefId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].cred_def_id; - schemaId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].schema_id; + credDefId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].cred_def_id + schemaId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].schema_id } if (revealedAttrs.hasOwnProperty(key)) { const extractedData: IProofPresentationDetails = { [attributeName]: revealedAttrs[key]?.raw, credDefId: credDefId || null, - schemaId: schemaId || null - }; - extractedDataArray.push(extractedData); + schemaId: schemaId || null, + } + extractedDataArray.push(extractedData) } } } for (const key in requestedPredicates) { if (requestedPredicates.hasOwnProperty(key)) { - const attribute = requestedPredicates[key]; + const attribute = requestedPredicates[key] - const attributeName = attribute?.name; + const attributeName = attribute?.name if (attribute?.restrictions) { - credDefId = attribute?.restrictions[0]?.cred_def_id; - schemaId = attribute?.restrictions[0]?.schema_id; + credDefId = attribute?.restrictions[0]?.cred_def_id + schemaId = attribute?.restrictions[0]?.schema_id } const extractedData: IProofPresentationDetails = { [attributeName]: `${attribute?.p_type}${attribute?.p_value}`, credDefId: credDefId || null, - schemaId: schemaId || null - }; - extractedDataArray.push(extractedData); + schemaId: schemaId || null, + } + extractedDataArray.push(extractedData) } } - } else if (0 !== Object.keys(requestedAttributes).length) { + } else if (Object.keys(requestedAttributes).length !== 0) { for (const key in requestedAttributes) { if (requestedAttributes.hasOwnProperty(key)) { - const attribute = requestedAttributes[key]; - const attributeName = attribute.name; - - [credDefId, schemaId] = await this._schemaCredDefRestriction(attribute, getProofPresentationById); + const attribute = requestedAttributes[key] + const attributeName = attribute.name + ;[credDefId, schemaId] = await this._schemaCredDefRestriction(attribute, getProofPresentationById) if (revealedAttrs.hasOwnProperty(key)) { const extractedData: IProofPresentationDetails = { [attributeName]: revealedAttrs[key]?.raw, credDefId: credDefId || null, - schemaId: schemaId || null - }; - extractedDataArray.push(extractedData); + schemaId: schemaId || null, + } + extractedDataArray.push(extractedData) } } } - } else if (0 !== Object.keys(requestedPredicates).length) { + } else if (Object.keys(requestedPredicates).length !== 0) { for (const key in requestedPredicates) { if (requestedPredicates.hasOwnProperty(key)) { - const attribute = requestedPredicates[key]; - const attributeName = attribute?.name; - - [credDefId, schemaId] = await this._schemaCredDefRestriction(attribute, getProofPresentationById); + const attribute = requestedPredicates[key] + const attributeName = attribute?.name + ;[credDefId, schemaId] = await this._schemaCredDefRestriction(attribute, getProofPresentationById) const extractedData: IProofPresentationDetails = { [attributeName]: `${attribute?.p_type}${attribute?.p_value}`, credDefId: credDefId || null, - schemaId: schemaId || null - }; - extractedDataArray.push(extractedData); + schemaId: schemaId || null, + } + extractedDataArray.push(extractedData) } } } else { throw new InternalServerErrorException(ResponseMessages.errorMessages.serverError, { cause: new Error(), - description: ResponseMessages.errorMessages.serverError - }); + description: ResponseMessages.errorMessages.serverError, + }) } } - return extractedDataArray; + return extractedDataArray } catch (error) { - this.logger.error(`[getVerifiedProofDetails] - error in get verified proof details : ${JSON.stringify(error)}`); - const errorStack = error?.response?.error?.reason; + this.logger.error(`[getVerifiedProofDetails] - error in get verified proof details : ${JSON.stringify(error)}`) + const errorStack = error?.response?.error?.reason if (errorStack) { throw new RpcException({ message: ResponseMessages.verification.error.verifiedProofNotFound, statusCode: error?.response?.status, - error: errorStack - }); + error: errorStack, + }) } else { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } } async _schemaCredDefRestriction(attribute, getProofPresentationById): Promise { - let credDefId; - let schemaId; + let credDefId + let schemaId if (attribute?.restrictions) { - credDefId = attribute?.restrictions[0]?.cred_def_id; - schemaId = attribute?.restrictions[0]?.schema_id; + credDefId = attribute?.restrictions[0]?.cred_def_id + schemaId = attribute?.restrictions[0]?.schema_id } else if (getProofPresentationById?.response?.presentation?.indy?.identifiers) { - credDefId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].cred_def_id; - schemaId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].schema_id; + credDefId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].cred_def_id + schemaId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].schema_id } - return [credDefId, schemaId]; + return [credDefId, schemaId] } async _getVerifiedProofDetails(payload: IVerifiedProofData): Promise<{ - response; + response }> { try { //nats call in agent for fetch verified proof details const pattern = { - cmd: 'get-agent-verified-proof-details' - }; + cmd: 'get-agent-verified-proof-details', + } - return await this.natsCall(pattern, payload); + return await this.natsCall(pattern, payload) } catch (error) { - this.logger.error(`[_getVerifiedProofDetails] - error in verified proof details : ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[_getVerifiedProofDetails] - error in verified proof details : ${JSON.stringify(error)}`) + throw error } } async _getOrgAgentApiKey(orgId: string): Promise { - const pattern = { cmd: 'get-org-agent-api-key' }; - const payload = { orgId }; + 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.natsClient.send(this.verificationServiceProxy, pattern, payload); - return message; + // biome-ignore lint/suspicious/noExplicitAny: + const message = await this.natsClient.send(this.verificationServiceProxy, pattern, payload) + return message } catch (error) { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.status, - error: error.message + error: error.message, }, error.status - ); + ) } } verificationErrorHandling(error): void { if (!error && !error?.status && !error?.status?.message && !error?.status?.message?.error) { - throw new RpcException(error.response ? error.response : 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 - }); + statusCode: error?.status?.code, + }) } } @@ -1142,38 +1144,38 @@ export class VerificationService { pattern: object, payload: object ): Promise<{ - response: string; + response: string }> { return from(this.natsClient.send(this.verificationServiceProxy, pattern, payload)) .pipe( map((response) => ({ - response + response, })) ) .toPromise() .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); + this.logger.error(`catch: ${JSON.stringify(error)}`) throw new HttpException( { status: error.statusCode, error: error.error, - message: error.message + message: error.message, }, error.error - ); - }); + ) + }) } async delay(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); + return new Promise((resolve) => setTimeout(resolve, ms)) } async deleteVerificationRecords(orgId: string, userDetails: user): Promise { try { - const deleteProofRecords = await this.verificationRepository.deleteVerificationRecordsByOrgId(orgId); + const deleteProofRecords = await this.verificationRepository.deleteVerificationRecordsByOrgId(orgId) - if (0 === deleteProofRecords?.deleteResult?.count) { - throw new NotFoundException(ResponseMessages.verification.error.verificationRecordsNotFound); + if (deleteProofRecords?.deleteResult?.count === 0) { + throw new NotFoundException(ResponseMessages.verification.error.verificationRecordsNotFound) } const statusCounts = { @@ -1185,35 +1187,35 @@ export class VerificationService { [VerificationProcessState.PRESENTATION_SENT]: 0, [VerificationProcessState.DONE]: 0, [VerificationProcessState.DECLIEND]: 0, - [VerificationProcessState.ABANDONED]: 0 - }; + [VerificationProcessState.ABANDONED]: 0, + } await Promise.all( deleteProofRecords.recordsToDelete.map(async (record) => { - statusCounts[record.state]++; + statusCounts[record.state]++ }) - ); + ) - const filteredStatusCounts = Object.fromEntries(Object.entries(statusCounts).filter((entry) => 0 < entry[1])); + const filteredStatusCounts = Object.fromEntries(Object.entries(statusCounts).filter((entry) => entry[1] > 0)) const deletedVerificationData = { deletedProofRecordsCount: deleteProofRecords?.deleteResult?.count, - deletedRecordsStatusCount: filteredStatusCounts - }; + deletedRecordsStatusCount: filteredStatusCounts, + } await this.userActivityRepository._orgDeletedActivity( orgId, userDetails, deletedVerificationData, RecordType.VERIFICATION_RECORD - ); + ) - return deleteProofRecords; + return deleteProofRecords } catch (error) { this.logger.error( `[deleteVerificationRecords] - error in deleting verification records: ${JSON.stringify(error)}` - ); - throw new RpcException(error.response ? error.response : error); + ) + throw new RpcException(error.response ? error.response : error) } } } diff --git a/apps/verification/templates/out-of-band-verification.template.ts b/apps/verification/templates/out-of-band-verification.template.ts index 46486a398..fa8996da7 100644 --- a/apps/verification/templates/out-of-band-verification.template.ts +++ b/apps/verification/templates/out-of-band-verification.template.ts @@ -1,8 +1,7 @@ export class OutOfBandVerification { - - public outOfBandVerification(email: string, orgName: string, deepLinkURL: string): string { - try { - return ` + public outOfBandVerification(email: string, orgName: string, deepLinkURL: string): string { + try { + return ` @@ -81,9 +80,7 @@ export class OutOfBandVerification { - `; - - } catch (error) { - } - } -} \ No newline at end of file + ` + } catch (_error) {} + } +} diff --git a/apps/webhook/interfaces/webhook.interfaces.ts b/apps/webhook/interfaces/webhook.interfaces.ts index 2341bc217..58aa87d40 100644 --- a/apps/webhook/interfaces/webhook.interfaces.ts +++ b/apps/webhook/interfaces/webhook.interfaces.ts @@ -1,12 +1,12 @@ export interface ICreateWebhookUrl { - webhookUrl: string; + webhookUrl: string } export interface IGetWebhookUrl { - webhookUrl: string; + webhookUrl: string } export interface IWebhookDto { - orgId: string; - webhookUrl: string; + orgId: string + webhookUrl: string } diff --git a/apps/webhook/src/main.ts b/apps/webhook/src/main.ts index 303f7f8e9..bbc630a75 100644 --- a/apps/webhook/src/main.ts +++ b/apps/webhook/src/main.ts @@ -1,25 +1,23 @@ -import { NestFactory } from '@nestjs/core'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; -import { Logger } from '@nestjs/common'; -import { MicroserviceOptions, Transport } from '@nestjs/microservices'; -import { WebhookModule } from '../src/webhook.module'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { type MicroserviceOptions, Transport } from '@nestjs/microservices' +import { HttpExceptionFilter } from 'libs/http-exception.filter' +import { WebhookModule } from '../src/webhook.module' -const logger = new Logger(); +const logger = new Logger() async function bootstrap(): Promise { - const app = await NestFactory.createMicroservice(WebhookModule, { transport: Transport.NATS, - options: getNatsOptions(CommonConstants.WEBHOOK_SERVICE, process.env.ISSUANCE_NKEY_SEED) - - }); - app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + options: getNatsOptions(CommonConstants.WEBHOOK_SERVICE, process.env.ISSUANCE_NKEY_SEED), + }) + app.useLogger(app.get(NestjsLoggerServiceAdapter)) + app.useGlobalFilters(new HttpExceptionFilter()) - await app.listen(); - logger.log('Webhook-Service Microservice is listening to NATS '); + await app.listen() + logger.log('Webhook-Service Microservice is listening to NATS ') } -bootstrap(); +bootstrap() diff --git a/apps/webhook/src/webhook.controller.ts b/apps/webhook/src/webhook.controller.ts index 8c58376b9..3443c687f 100644 --- a/apps/webhook/src/webhook.controller.ts +++ b/apps/webhook/src/webhook.controller.ts @@ -1,26 +1,26 @@ -import { Controller, Logger } from '@nestjs/common'; -import { MessagePattern } from '@nestjs/microservices'; -import { WebhookService } from './webhook.service'; -import { ICreateWebhookUrl, IGetWebhookUrl, IWebhookDto } from '../interfaces/webhook.interfaces'; -import { IWebhookUrl } from '@credebl/common/interfaces/webhook.interface'; +import type { IWebhookUrl } from '@credebl/common/interfaces/webhook.interface' +import { Controller, Logger } from '@nestjs/common' +import { MessagePattern } from '@nestjs/microservices' +import type { ICreateWebhookUrl, IGetWebhookUrl, IWebhookDto } from '../interfaces/webhook.interfaces' +import type { WebhookService } from './webhook.service' @Controller() export class WebhookController { - private readonly logger = new Logger('webhookService'); + private readonly logger = new Logger('webhookService') constructor(private readonly webhookService: WebhookService) {} @MessagePattern({ cmd: 'register-webhook' }) async registerWebhook(payload: { registerWebhookDto: IWebhookDto }): Promise { - return this.webhookService.registerWebhook(payload.registerWebhookDto); + return this.webhookService.registerWebhook(payload.registerWebhookDto) } @MessagePattern({ cmd: 'get-webhookurl' }) async getWebhookUrl(payload: IWebhookUrl): Promise { - return this.webhookService.getWebhookUrl(payload); + return this.webhookService.getWebhookUrl(payload) } @MessagePattern({ cmd: 'post-webhook-response-to-webhook-url' }) async webhookResponse(payload: { webhookUrl: string; data: object }): Promise { - return this.webhookService.webhookResponse(payload.webhookUrl, payload.data); + return this.webhookService.webhookResponse(payload.webhookUrl, payload.data) } } diff --git a/apps/webhook/src/webhook.module.ts b/apps/webhook/src/webhook.module.ts index fb6d69549..e7afcac1f 100644 --- a/apps/webhook/src/webhook.module.ts +++ b/apps/webhook/src/webhook.module.ts @@ -1,17 +1,17 @@ -import { CommonModule } from '@credebl/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { Logger, Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { ClientsModule, Transport } from '@nestjs/microservices'; -import { WebhookController } from './webhook.controller'; -import { WebhookRepository } from './webhook.repository'; -import { WebhookService } from './webhook.service'; -import { getNatsOptions } from '@credebl/common/nats.config'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { GlobalConfigModule } from '@credebl/config/global-config.module'; -import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; -import { LoggerModule } from '@credebl/logger/logger.module'; -import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; +import { CommonModule } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' +import { getNatsOptions } from '@credebl/common/nats.config' +import { ConfigModule as PlatformConfig } from '@credebl/config/config.module' +import { GlobalConfigModule } from '@credebl/config/global-config.module' +import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule' +import { LoggerModule } from '@credebl/logger/logger.module' +import { PrismaService } from '@credebl/prisma-service' +import { Logger, Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' +import { ClientsModule, Transport } from '@nestjs/microservices' +import { WebhookController } from './webhook.controller' +import { WebhookRepository } from './webhook.repository' +import { WebhookService } from './webhook.service' @Module({ imports: [ @@ -20,14 +20,16 @@ import { ContextInterceptorModule } from '@credebl/context/contextInterceptorMod { name: 'NATS_CLIENT', transport: Transport.NATS, - options: getNatsOptions(CommonConstants.WEBHOOK_SERVICE, process.env.ISSUANCE_NKEY_SEED) - } + options: getNatsOptions(CommonConstants.WEBHOOK_SERVICE, process.env.ISSUANCE_NKEY_SEED), + }, ]), CommonModule, GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule + LoggerModule, + PlatformConfig, + ContextInterceptorModule, ], controllers: [WebhookController], - providers: [WebhookService, WebhookRepository, PrismaService, Logger] + providers: [WebhookService, WebhookRepository, PrismaService, Logger], }) export class WebhookModule {} diff --git a/apps/webhook/src/webhook.repository.ts b/apps/webhook/src/webhook.repository.ts index 2f8fb3cd8..cbd1c5646 100644 --- a/apps/webhook/src/webhook.repository.ts +++ b/apps/webhook/src/webhook.repository.ts @@ -1,9 +1,9 @@ +import type { IWebhookUrl } from '@credebl/common/interfaces/webhook.interface' +import type { PrismaService } from '@credebl/prisma-service' /* eslint-disable camelcase */ -import { Injectable, Logger } from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; -import { ICreateWebhookUrl, IGetWebhookUrl } from '../interfaces/webhook.interfaces'; -import { org_agents } from '@prisma/client'; -import { IWebhookUrl } from '@credebl/common/interfaces/webhook.interface'; +import { Injectable, type Logger } from '@nestjs/common' +import type { org_agents } from '@prisma/client' +import type { ICreateWebhookUrl, IGetWebhookUrl } from '../interfaces/webhook.interfaces' @Injectable() export class WebhookRepository { constructor( @@ -15,46 +15,43 @@ export class WebhookRepository { try { const agentInfo = this.prisma.org_agents.update({ where: { - orgId + orgId, }, data: { - webhookUrl - } - }); + webhookUrl, + }, + }) - return agentInfo; + return agentInfo } catch (error) { - this.logger.error(`[registerWebhookUrl] - register webhook url details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[registerWebhookUrl] - register webhook url details: ${JSON.stringify(error)}`) + throw error } } async getWebhookUrl(getWebhook: IWebhookUrl): Promise { try { + const { tenantId, orgId } = getWebhook + let webhookUrlInfo: IGetWebhookUrl - const { tenantId, orgId } = getWebhook; - let webhookUrlInfo; - - if ((undefined === tenantId || 'default' === tenantId) && orgId) { + if ((undefined === tenantId || tenantId === 'default') && orgId) { webhookUrlInfo = await this.prisma.org_agents.findFirstOrThrow({ - where: { - orgId - } - }); - } else if (tenantId && 'default' !== tenantId) { + orgId, + }, + }) + } else if (tenantId && tenantId !== 'default') { webhookUrlInfo = await this.prisma.org_agents.findFirstOrThrow({ - where: { - tenantId - } - }); + tenantId, + }, + }) } - - return webhookUrlInfo; + + return webhookUrlInfo } catch (error) { - this.logger.error(`[getWebhookUrl] - webhook url details: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getWebhookUrl] - webhook url details: ${JSON.stringify(error)}`) + throw error } } @@ -62,12 +59,12 @@ export class WebhookRepository { try { return this.prisma.org_agents.findUnique({ where: { - orgId - } - }); + orgId, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error: ${JSON.stringify(error)}`) + throw error } } } diff --git a/apps/webhook/src/webhook.service.ts b/apps/webhook/src/webhook.service.ts index 3d3402bd2..a4dcb573c 100644 --- a/apps/webhook/src/webhook.service.ts +++ b/apps/webhook/src/webhook.service.ts @@ -1,22 +1,16 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { CommonService } from '@credebl/common'; -import { WebhookRepository } from './webhook.repository'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { ClientProxy, RpcException } from '@nestjs/microservices'; -import AsyncRetry = require('async-retry'); -import { ICreateWebhookUrl, IGetWebhookUrl, IWebhookDto } from '../interfaces/webhook.interfaces'; -import { - Inject, - Injectable, - InternalServerErrorException, - Logger, - NotFoundException -} from '@nestjs/common'; -import { IWebhookUrl } from '@credebl/common/interfaces/webhook.interface'; +import type { CommonService } from '@credebl/common' +import { ResponseMessages } from '@credebl/common/response-messages' +import { type ClientProxy, RpcException } from '@nestjs/microservices' +import type { WebhookRepository } from './webhook.repository' +import AsyncRetry = require('async-retry') +import type { IWebhookUrl } from '@credebl/common/interfaces/webhook.interface' +import { Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common' +import type { ICreateWebhookUrl, IGetWebhookUrl, IWebhookDto } from '../interfaces/webhook.interfaces' @Injectable() export class WebhookService { - private readonly logger = new Logger('WebhookService'); + private readonly logger = new Logger('WebhookService') constructor( @Inject('NATS_CLIENT') private readonly webhookProxy: ClientProxy, private readonly commonService: CommonService, @@ -30,53 +24,53 @@ export class WebhookService { factor: 2, minTimeout: 2000, onRetry(e: { message: string }, attempt: number): void { - logger.log(`Error:: ${e.message}`); - logger.log(`Attempt:: ${attempt}`); - } - }; + logger.log(`Error:: ${e.message}`) + logger.log(`Attempt:: ${attempt}`) + }, + } } async registerWebhook(registerWebhookDto: IWebhookDto): Promise { try { - const orgData = await this.webhookRepository.getOrganizationDetails(registerWebhookDto.orgId); - let webhookUrl; + const orgData = await this.webhookRepository.getOrganizationDetails(registerWebhookDto.orgId) + let webhookUrl if (!orgData) { - throw new NotFoundException(ResponseMessages.organisation.error.notFound); + throw new NotFoundException(ResponseMessages.organisation.error.notFound) } else { try { webhookUrl = await this.webhookRepository.registerWebhook( registerWebhookDto.orgId, registerWebhookDto.webhookUrl - ); - } catch (error) { - throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook); + ) + } catch (_error) { + throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook) } if (!webhookUrl) { - throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook); + throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook) } else { - return webhookUrl.webhookUrl; + return webhookUrl.webhookUrl } } } catch (error) { - this.logger.error(`[registerWebhookUrl] - register webhook url details : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[registerWebhookUrl] - register webhook url details : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } async getWebhookUrl(getWebhook: IWebhookUrl): Promise { - let webhookUrlInfo; + let webhookUrlInfo try { - webhookUrlInfo = await this.webhookRepository.getWebhookUrl(getWebhook); + webhookUrlInfo = await this.webhookRepository.getWebhookUrl(getWebhook) if (!webhookUrlInfo) { - throw new NotFoundException(ResponseMessages.webhook.error.notFound); + throw new NotFoundException(ResponseMessages.webhook.error.notFound) } - return webhookUrlInfo.webhookUrl; + return webhookUrlInfo.webhookUrl } catch (error) { - this.logger.error(`[getWebhookUrl] - webhook url details : ${JSON.stringify(error)}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`[getWebhookUrl] - webhook url details : ${JSON.stringify(error)}`) + throw new RpcException(error.response ? error.response : error) } } @@ -85,29 +79,29 @@ export class WebhookService { const response = await fetch(webhookUrl, { method: 'POST', headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', }, - body: JSON.stringify(data) - }); + body: JSON.stringify(data), + }) if (!response.ok) { - this.logger.error(`Error in sending webhook response to org webhook url:`, response.status); - throw new InternalServerErrorException(ResponseMessages.webhook.error.webhookResponse); + this.logger.error(`Error in sending webhook response to org webhook url:`, response.status) + throw new InternalServerErrorException(ResponseMessages.webhook.error.webhookResponse) } - return response; - } catch (err) { - throw new InternalServerErrorException(ResponseMessages.webhook.error.webhookResponse); + return response + } catch (_err) { + throw new InternalServerErrorException(ResponseMessages.webhook.error.webhookResponse) } } async webhookResponse(webhookUrl: string, data: object): Promise { try { - const webhookResponse = async (): Promise => this.webhookFunc(webhookUrl, data); - const response = await AsyncRetry(webhookResponse, this.retryOptions(this.logger)); - return response; + const webhookResponse = async (): Promise => this.webhookFunc(webhookUrl, data) + const response = await AsyncRetry(webhookResponse, this.retryOptions(this.logger)) + return response } catch (error) { - this.logger.error(`Error in sending webhook response to org webhook url: ${error}`); - throw new RpcException(error.response ? error.response : error); + this.logger.error(`Error in sending webhook response to org webhook url: ${error}`) + throw new RpcException(error.response ? error.response : error) } } } diff --git a/libs/aws/package.json b/libs/aws/package.json index 7e66c0b02..6b68138f9 100644 --- a/libs/aws/package.json +++ b/libs/aws/package.json @@ -3,9 +3,7 @@ "main": "src/index", "types": "src/index", "version": "0.0.1", - "files": [ - "dist" - ], + "files": ["dist"], "scripts": { "build": "pnpm run clean && pnpm run compile", "clean": "rimraf ../../dist/libs/aws", diff --git a/libs/aws/src/aws.module.ts b/libs/aws/src/aws.module.ts index 1a2a90f39..9c96698c5 100644 --- a/libs/aws/src/aws.module.ts +++ b/libs/aws/src/aws.module.ts @@ -1,8 +1,8 @@ -import { Module } from '@nestjs/common'; -import { AwsService } from './aws.service'; +import { Module } from '@nestjs/common' +import { AwsService } from './aws.service' @Module({ providers: [AwsService], - exports: [AwsService] + exports: [AwsService], }) export class AwsModule {} diff --git a/libs/aws/src/aws.service.spec.ts b/libs/aws/src/aws.service.spec.ts index f37dab349..869556ebb 100644 --- a/libs/aws/src/aws.service.spec.ts +++ b/libs/aws/src/aws.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AwsService } from './aws.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { AwsService } from './aws.service' describe('AwsService', () => { - let service: AwsService; + let service: AwsService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [AwsService] - }).compile(); + providers: [AwsService], + }).compile() - service = module.get(AwsService); - }); + service = module.get(AwsService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/libs/aws/src/aws.service.ts b/libs/aws/src/aws.service.ts index 19286edea..76cd5f562 100644 --- a/libs/aws/src/aws.service.ts +++ b/libs/aws/src/aws.service.ts @@ -1,32 +1,32 @@ -import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; -import { RpcException } from '@nestjs/microservices'; -import { S3 } from 'aws-sdk'; -import { promisify } from 'util'; +import { promisify } from 'util' +import { HttpException, HttpStatus, Injectable } from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' +import { S3 } from 'aws-sdk' @Injectable() export class AwsService { - private s3: S3; - private s4: S3; - private s3StoreObject: S3; + private s3: S3 + private s4: S3 + private s3StoreObject: S3 constructor() { this.s3 = new S3({ accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY, - region: process.env.AWS_REGION - }); + region: process.env.AWS_REGION, + }) this.s4 = new S3({ accessKeyId: process.env.AWS_PUBLIC_ACCESS_KEY, secretAccessKey: process.env.AWS_PUBLIC_SECRET_KEY, - region: process.env.AWS_PUBLIC_REGION - }); + region: process.env.AWS_PUBLIC_REGION, + }) this.s3StoreObject = new S3({ accessKeyId: process.env.AWS_S3_STOREOBJECT_ACCESS_KEY, secretAccessKey: process.env.AWS_S3_STOREOBJECT_SECRET_KEY, - region: process.env.AWS_S3_STOREOBJECT_REGION - }); + region: process.env.AWS_S3_STOREOBJECT_REGION, + }) } async uploadFileToS3Bucket( @@ -35,10 +35,10 @@ export class AwsService { filename: string, bucketName: string, encoding: string, - pathAWS: string = '' + pathAWS = '' ): Promise { - const timestamp = Date.now(); - const putObjectAsync = promisify(this.s4.putObject).bind(this.s4); + const timestamp = Date.now() + const putObjectAsync = promisify(this.s4.putObject).bind(this.s4) try { await putObjectAsync({ @@ -46,13 +46,13 @@ export class AwsService { Key: `${pathAWS}/${encodeURIComponent(filename)}-${timestamp}.${ext}`, Body: fileBuffer, ContentEncoding: encoding, - ContentType: `image/png` - }); + ContentType: `image/png`, + }) - const imageUrl = `https://${bucketName}.s3.${process.env.AWS_PUBLIC_REGION}.amazonaws.com/${pathAWS}/${encodeURIComponent(filename)}-${timestamp}.${ext}`; - return imageUrl; + const imageUrl = `https://${bucketName}.s3.${process.env.AWS_PUBLIC_REGION}.amazonaws.com/${pathAWS}/${encodeURIComponent(filename)}-${timestamp}.${ext}` + return imageUrl } catch (error) { - throw new HttpException(error, HttpStatus.SERVICE_UNAVAILABLE); + throw new HttpException(error, HttpStatus.SERVICE_UNAVAILABLE) } } @@ -60,56 +60,56 @@ export class AwsService { const params: AWS.S3.PutObjectRequest = { Bucket: process.env.AWS_BUCKET, Key: key, - Body: 'string' === typeof body ? body : body.toString() - }; + Body: typeof body === 'string' ? body : body.toString(), + } try { - await this.s3.upload(params).promise(); + await this.s3.upload(params).promise() } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } async getFile(key: string): Promise { const params: AWS.S3.GetObjectRequest = { Bucket: process.env.AWS_BUCKET, - Key: key - }; + Key: key, + } try { - return this.s3.getObject(params).promise(); + return this.s3.getObject(params).promise() } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } async deleteFile(key: string): Promise { const params: AWS.S3.DeleteObjectRequest = { Bucket: process.env.AWS_BUCKET, - Key: key - }; + Key: key, + } try { - await this.s3.deleteObject(params).promise(); + await this.s3.deleteObject(params).promise() } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } async storeObject(persistent: boolean, key: string, body: unknown): Promise { - const objKey: string = persistent.valueOf() ? `persist/${key}` : `default/${key}`; - const buf = Buffer.from(JSON.stringify(body)); + const objKey: string = persistent.valueOf() ? `persist/${key}` : `default/${key}` + const buf = Buffer.from(JSON.stringify(body)) const params: AWS.S3.PutObjectRequest = { Bucket: process.env.AWS_S3_STOREOBJECT_BUCKET, Body: buf, Key: objKey, ContentEncoding: 'base64', - ContentType: 'application/json' - }; + ContentType: 'application/json', + } try { - const receivedData = await this.s3StoreObject.upload(params).promise(); - return receivedData; + const receivedData = await this.s3StoreObject.upload(params).promise() + return receivedData } catch (error) { - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } } diff --git a/libs/aws/src/index.ts b/libs/aws/src/index.ts index 182a99dc1..605bcb029 100644 --- a/libs/aws/src/index.ts +++ b/libs/aws/src/index.ts @@ -1,2 +1,2 @@ -export * from './aws.module'; -export * from './aws.service'; +export * from './aws.module' +export * from './aws.service' diff --git a/libs/client-registration/src/client-registration.module.ts b/libs/client-registration/src/client-registration.module.ts index 9fd72ef70..2fd812ecd 100644 --- a/libs/client-registration/src/client-registration.module.ts +++ b/libs/client-registration/src/client-registration.module.ts @@ -1,8 +1,8 @@ -import { Module } from '@nestjs/common'; -import { ClientRegistrationService } from './client-registration.service'; +import { Module } from '@nestjs/common' +import { ClientRegistrationService } from './client-registration.service' @Module({ providers: [ClientRegistrationService], - exports: [ClientRegistrationService] + exports: [ClientRegistrationService], }) export class ClientRegistrationModule {} diff --git a/libs/client-registration/src/client-registration.service.spec.ts b/libs/client-registration/src/client-registration.service.spec.ts index 7d4d230b7..b9ece25c1 100644 --- a/libs/client-registration/src/client-registration.service.spec.ts +++ b/libs/client-registration/src/client-registration.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ClientRegistrationService } from './client-registration.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { ClientRegistrationService } from './client-registration.service' describe('ClientRegistrationService', () => { - let service: ClientRegistrationService; + let service: ClientRegistrationService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [ClientRegistrationService] - }).compile(); + providers: [ClientRegistrationService], + }).compile() - service = module.get(ClientRegistrationService); - }); + service = module.get(ClientRegistrationService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/libs/client-registration/src/client-registration.service.ts b/libs/client-registration/src/client-registration.service.ts index 51dbeb923..7cfd327c5 100644 --- a/libs/client-registration/src/client-registration.service.ts +++ b/libs/client-registration/src/client-registration.service.ts @@ -4,21 +4,21 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { BadRequestException, Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common'; -import * as qs from 'qs'; - -import { ClientCredentialTokenPayloadDto } from './dtos/client-credential-token-payload.dto'; -import { CommonConstants } from '@credebl/common/common.constant'; -import { CommonService } from '@credebl/common'; -import { CreateUserDto } from './dtos/create-user.dto'; -import { JwtService } from '@nestjs/jwt'; -import { KeycloakUrlService } from '@credebl/keycloak-url'; -import { accessTokenPayloadDto } from './dtos/accessTokenPayloadDto'; -import { userTokenPayloadDto } from './dtos/userTokenPayloadDto'; -import { KeycloakUserRegistrationDto } from 'apps/user/dtos/keycloak-register.dto'; -import { ResponseMessages } from '@credebl/common/response-messages'; -import { IClientRoles } from './interfaces/client.interface'; -import { IFormattedResponse } from '@credebl/common/interfaces/interface'; +import { BadRequestException, Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common' +import * as qs from 'qs' + +import type { CommonService } from '@credebl/common' +import { CommonConstants } from '@credebl/common/common.constant' +import type { IFormattedResponse } from '@credebl/common/interfaces/interface' +import { ResponseMessages } from '@credebl/common/response-messages' +import type { KeycloakUrlService } from '@credebl/keycloak-url' +import { JwtService } from '@nestjs/jwt' +import type { KeycloakUserRegistrationDto } from 'apps/user/dtos/keycloak-register.dto' +import { accessTokenPayloadDto } from './dtos/accessTokenPayloadDto' +import { ClientCredentialTokenPayloadDto } from './dtos/client-credential-token-payload.dto' +import type { CreateUserDto } from './dtos/create-user.dto' +import { userTokenPayloadDto } from './dtos/userTokenPayloadDto' +import type { IClientRoles } from './interfaces/client.interface' @Injectable() export class ClientRegistrationService { @@ -27,25 +27,25 @@ export class ClientRegistrationService { private readonly keycloakUrlService: KeycloakUrlService ) {} - private readonly logger = new Logger('ClientRegistrationService'); + private readonly logger = new Logger('ClientRegistrationService') async registerKeycloakUser(userDetails: KeycloakUserRegistrationDto, realm: string, token: string) { try { - const url = await this.keycloakUrlService.createUserURL(realm); - await this.commonService.httpPost(url, userDetails, this.getAuthHeader(token)); + const url = await this.keycloakUrlService.createUserURL(realm) + await this.commonService.httpPost(url, userDetails, this.getAuthHeader(token)) const getUserResponse = await this.commonService.httpGet( await this.keycloakUrlService.getUserByUsernameURL(realm, userDetails.email), this.getAuthHeader(token) - ); + ) if (getUserResponse[0].username === userDetails.email || getUserResponse[1].username === userDetails.email) { - return { keycloakUserId: getUserResponse[0].id }; + return { keycloakUserId: getUserResponse[0].id } } else { - throw new NotFoundException(ResponseMessages.user.error.invalidKeycloakId); + throw new NotFoundException(ResponseMessages.user.error.invalidKeycloakId) } } catch (error) { - this.logger.error(`error in keycloakUserRegistration in client-registration: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`error in keycloakUserRegistration in client-registration: ${JSON.stringify(error)}`) + throw error } } @@ -53,12 +53,12 @@ export class ClientRegistrationService { const getUserResponse = await this.commonService.httpGet( await this.keycloakUrlService.getUserByUsernameURL(realm, user.email), this.getAuthHeader(token) - ); - const userid = getUserResponse[0].id; + ) + const userid = getUserResponse[0].id - const passwordResponse = await this.resetPasswordOfKeycloakUser(realm, user.password, userid, token); + const passwordResponse = await this.resetPasswordOfKeycloakUser(realm, user.password, userid, token) - return passwordResponse; + return passwordResponse } async createUser(user: CreateUserDto, realm: string, token: string): Promise<{ keycloakUserId: string }> { @@ -79,105 +79,105 @@ export class ClientRegistrationService { view: true, mapRoles: true, impersonate: true, - manage: true + manage: true, }, realmRoles: ['mb-user'], attributes: { - ...(user.isHolder ? { userRole: `${CommonConstants.USER_HOLDER_ROLE}` } : {}) - } - }; + ...(user.isHolder ? { userRole: `${CommonConstants.USER_HOLDER_ROLE}` } : {}), + }, + } await this.commonService.httpPost( await this.keycloakUrlService.createUserURL(realm), payload, this.getAuthHeader(token) - ); + ) const getUserResponse = await this.commonService.httpGet( await this.keycloakUrlService.getUserByUsernameURL(realm, user.email), this.getAuthHeader(token) - ); - const userid = getUserResponse[0].id; + ) + const userid = getUserResponse[0].id - await this.resetPasswordOfKeycloakUser(realm, user.password, userid, token); + await this.resetPasswordOfKeycloakUser(realm, user.password, userid, token) return { - keycloakUserId: getUserResponse[0].id - }; + keycloakUserId: getUserResponse[0].id, + } } async resetPasswordOfKeycloakUser(realm: string, resetPasswordValue: string, userid: string, token: string) { const passwordPayload = { type: 'password', value: resetPasswordValue, - temporary: false - }; + temporary: false, + } const setPasswordResponse = await this.commonService.httpPut( //await this.keycloakUrlService.ResetPasswordURL(`${process.env.KEYCLOAK_CREDEBL_REALM}`, userid), await this.keycloakUrlService.ResetPasswordURL(realm, userid), passwordPayload, this.getAuthHeader(token) - ); - return setPasswordResponse; + ) + return setPasswordResponse } getAuthHeader(token: string) { - return { headers: { authorization: `Bearer ${token}` } }; + return { headers: { authorization: `Bearer ${token}` } } } async getUserInfo(token: string) { try { - const jwtService = new JwtService({}); - const decoded = jwtService.decode(token, { complete: true }); + const jwtService = new JwtService({}) + const decoded = jwtService.decode(token, { complete: true }) if (!decoded) { - throw new UnauthorizedException('Invalid token'); + throw new UnauthorizedException('Invalid token') } - const payload = decoded['payload']; + const payload = decoded.payload const userInfoResponse = await this.commonService.httpGet( - `${process.env.KEYCLOAK_DOMAIN}admin/realms/${process.env.KEYCLOAK_REALM}/users/${payload['sub']}`, + `${process.env.KEYCLOAK_DOMAIN}admin/realms/${process.env.KEYCLOAK_REALM}/users/${payload.sub}`, this.getAuthHeader(token) - ); - return userInfoResponse.data; + ) + return userInfoResponse.data } catch (error) { - this.logger.error(`[getUserInfo]: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`[getUserInfo]: ${JSON.stringify(error)}`) + throw error } } async getManagementToken(clientId: string, clientSecret: string) { try { - const payload = new ClientCredentialTokenPayloadDto(); + const payload = new ClientCredentialTokenPayloadDto() if (!clientId && !clientSecret) { - this.logger.error(`getManagementToken ::: Client ID and client secret are missing`); - throw new BadRequestException(`Client ID and client secret are missing`); + this.logger.error(`getManagementToken ::: Client ID and client secret are missing`) + throw new BadRequestException(`Client ID and client secret are missing`) } - const decryptClientId = await this.commonService.decryptPassword(clientId); - const decryptClientSecret = await this.commonService.decryptPassword(clientSecret); + const decryptClientId = await this.commonService.decryptPassword(clientId) + const decryptClientSecret = await this.commonService.decryptPassword(clientSecret) - payload.client_id = decryptClientId; - payload.client_secret = decryptClientSecret; - const mgmtTokenResponse = await this.getToken(payload); - return mgmtTokenResponse.access_token; + payload.client_id = decryptClientId + payload.client_secret = decryptClientSecret + const mgmtTokenResponse = await this.getToken(payload) + return mgmtTokenResponse.access_token } catch (error) { - this.logger.error(`Error in getManagementToken: ${JSON.stringify(error)}`); + this.logger.error(`Error in getManagementToken: ${JSON.stringify(error)}`) - throw error; + throw error } } async getManagementTokenForMobile() { - const payload = new ClientCredentialTokenPayloadDto(); - payload.client_id = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_ID; - payload.client_secret = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_SECRET; - payload.scope = 'email profile'; - - this.logger.log(`management Payload: ${JSON.stringify(payload)}`); - const mgmtTokenResponse = await this.getToken(payload); - this.logger.debug(`ClientRegistrationService management token ${JSON.stringify(mgmtTokenResponse)}`); - return mgmtTokenResponse; + const payload = new ClientCredentialTokenPayloadDto() + payload.client_id = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_ID + payload.client_secret = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_SECRET + payload.scope = 'email profile' + + this.logger.log(`management Payload: ${JSON.stringify(payload)}`) + const mgmtTokenResponse = await this.getToken(payload) + this.logger.debug(`ClientRegistrationService management token ${JSON.stringify(mgmtTokenResponse)}`) + return mgmtTokenResponse } async getClientIdAndSecret( @@ -186,64 +186,64 @@ export class ClientRegistrationService { ): Promise<{ clientId: string; clientSecret: string }> | undefined { // Client id cannot be undefined if (!clientId) { - return; + return } try { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const getClientResponse = await this.commonService.httpGet( await this.keycloakUrlService.GetClientURL(realmName, clientId), this.getAuthHeader(token) - ); - const { id } = getClientResponse[0]; - const client_id = getClientResponse[0].clientId; + ) + const { id } = getClientResponse[0] + const client_id = getClientResponse[0].clientId const response = await this.commonService.httpGet( `${process.env.KEYCLOAK_DOMAIN}${CommonConstants.URL_KEYCLOAK_CLIENT_SECRET.replace('{id}', id)}`, this.getAuthHeader(token) - ); + ) return { clientId: client_id, - clientSecret: response.value - }; + clientSecret: response.value, + } } catch (error) { - if (404 === error?.response?.statusCode) { + if (error?.response?.statusCode === 404) { } else { - this.logger.error(`Caught exception while retrieving clientSecret from Auth0: ${JSON.stringify(error)}`); - throw new Error('Unable to retrieve clientSecret from server'); + this.logger.error(`Caught exception while retrieving clientSecret from Auth0: ${JSON.stringify(error)}`) + throw new Error('Unable to retrieve clientSecret from server') } } } async deleteClient(idpId: string, token: string) { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const getClientDeleteResponse = await this.commonService.httpDelete( await this.keycloakUrlService.GetClientIdpURL(realmName, idpId), this.getAuthHeader(token) - ); + ) - this.logger.log(`Delete realm client ${JSON.stringify(getClientDeleteResponse)}`); + this.logger.log(`Delete realm client ${JSON.stringify(getClientDeleteResponse)}`) - return getClientDeleteResponse; + return getClientDeleteResponse } async createUserClientRole(idpId: string, token: string, userId: string, payload: object[]): Promise { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const createClientRolesResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetClientUserRoleURL(realmName, userId, idpId), payload, this.getAuthHeader(token) - ); + ) - this.logger.debug(`createUserClientRolesResponse ${JSON.stringify(createClientRolesResponse)}`); + this.logger.debug(`createUserClientRolesResponse ${JSON.stringify(createClientRolesResponse)}`) - return 'User client role is assigned'; + return 'User client role is assigned' } async deleteUserClientRoles(idpId: string, token: string, userId: string): Promise { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const createClientRolesResponse = await this.commonService .httpDelete( @@ -251,113 +251,113 @@ export class ClientRegistrationService { this.getAuthHeader(token) ) .then((data) => data?.data) - .catch((error) => error); + .catch((error) => error) - this.logger.debug(`deleteUserClientRoles ${JSON.stringify(createClientRolesResponse)}`); + this.logger.debug(`deleteUserClientRoles ${JSON.stringify(createClientRolesResponse)}`) - return true; + return true } async createUserHolderRole(token: string, userId: string, payload: object[]): Promise { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const createClientRolesResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetClientUserRoleURL(realmName, userId), payload, this.getAuthHeader(token) - ); + ) - this.logger.debug(`createUserHolderRole ${JSON.stringify(createClientRolesResponse)}`); + this.logger.debug(`createUserHolderRole ${JSON.stringify(createClientRolesResponse)}`) - return 'User holder role is assigned'; + return 'User holder role is assigned' } async getAllClientRoles(idpId: string, token: string): Promise { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const clientRolesResponse = await this.commonService.httpGet( await this.keycloakUrlService.GetClientRoleURL(realmName, idpId), this.getAuthHeader(token) - ); + ) - this.logger.debug(`getAllClientRoles ${JSON.stringify(clientRolesResponse)}`); + this.logger.debug(`getAllClientRoles ${JSON.stringify(clientRolesResponse)}`) - return clientRolesResponse; + return clientRolesResponse } async getClientSpecificRoles(idpId: string, token: string, roleName: string): Promise { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const clientRolesResponse = await this.commonService.httpGet( await this.keycloakUrlService.GetClientRoleURL(realmName, idpId, roleName), this.getAuthHeader(token) - ); + ) - this.logger.debug(`getClientSpecificRoles ${JSON.stringify(clientRolesResponse)}`); + this.logger.debug(`getClientSpecificRoles ${JSON.stringify(clientRolesResponse)}`) - return clientRolesResponse; + return clientRolesResponse } async getAllRealmRoles(token: string): Promise { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const realmRolesResponse = await this.commonService.httpGet( await this.keycloakUrlService.GetRealmRoleURL(realmName), this.getAuthHeader(token) - ); + ) - this.logger.debug(`getAllRealmRoles ${JSON.stringify(realmRolesResponse)}`); + this.logger.debug(`getAllRealmRoles ${JSON.stringify(realmRolesResponse)}`) - return realmRolesResponse; + return realmRolesResponse } async createClientRole(idpId: string, token: string, name: string, description: string): Promise { const payload = { clientRole: true, name, - description - }; + description, + } - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const createClientRolesResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetClientRoleURL(realmName, idpId), payload, this.getAuthHeader(token) - ); + ) - this.logger.debug(`createClientRolesResponse ${JSON.stringify(createClientRolesResponse)}`); + this.logger.debug(`createClientRolesResponse ${JSON.stringify(createClientRolesResponse)}`) - return 'Client role is created'; + return 'Client role is created' } async generateClientSecret(idpId: string, token: string): Promise { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const createClientSercretResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetClientSecretURL(realmName, idpId), {}, this.getAuthHeader(token) - ); + ) this.logger.debug( `ClientRegistrationService create realm client secret ${JSON.stringify(createClientSercretResponse)}` - ); + ) const getClientSercretResponse = await this.commonService.httpGet( await this.keycloakUrlService.GetClientSecretURL(realmName, idpId), this.getAuthHeader(token) - ); - this.logger.debug(`ClientRegistrationService get client secret ${JSON.stringify(getClientSercretResponse)}`); - this.logger.log(`${getClientSercretResponse.value}`); - const clientSecret = getClientSercretResponse.value; + ) + this.logger.debug(`ClientRegistrationService get client secret ${JSON.stringify(getClientSercretResponse)}`) + this.logger.log(`${getClientSercretResponse.value}`) + const clientSecret = getClientSercretResponse.value - return clientSecret; + return clientSecret } async createClient(orgName: string, orgId: string, token: string) { //create client for respective created realm in order to access its resources - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const clientPayload = { clientId: `${orgId}`, name: `${orgName}`, @@ -366,10 +366,10 @@ export class ClientRegistrationService { access: { view: true, configure: true, - manage: true + manage: true, }, attributes: { - orgId: `${orgId}` + orgId: `${orgId}`, }, authenticationFlowBindingOverrides: {}, authorizationServicesEnabled: false, @@ -394,39 +394,39 @@ export class ClientRegistrationService { publicClient: false, frontchannelLogout: false, fullScopeAllowed: false, - nodeReRegistrationTimeout: 0 - }; + nodeReRegistrationTimeout: 0, + } const createClientResponse = await this.commonService.httpPost( await this.keycloakUrlService.createClientURL(realmName), clientPayload, this.getAuthHeader(token) - ); - this.logger.debug(`ClientRegistrationService create realm client ${JSON.stringify(createClientResponse)}`); + ) + this.logger.debug(`ClientRegistrationService create realm client ${JSON.stringify(createClientResponse)}`) const getClientResponse = await this.commonService.httpGet( await this.keycloakUrlService.GetClientURL(realmName, `${orgId}`), this.getAuthHeader(token) - ); - this.logger.debug(`ClientRegistrationService get realm admin client ${JSON.stringify(createClientResponse)}`); - const { id } = getClientResponse[0]; - const client_id = getClientResponse[0].clientId; + ) + this.logger.debug(`ClientRegistrationService get realm admin client ${JSON.stringify(createClientResponse)}`) + const { id } = getClientResponse[0] + const client_id = getClientResponse[0].clientId const getClientSercretResponse = await this.commonService.httpGet( await this.keycloakUrlService.GetClientSecretURL(realmName, id), this.getAuthHeader(token) - ); + ) this.logger.debug( `ClientRegistrationService get realm admin client secret ${JSON.stringify(getClientSercretResponse)}` - ); - this.logger.log(`${getClientSercretResponse.value}`); - const client_secret = getClientSercretResponse.value; + ) + this.logger.log(`${getClientSercretResponse.value}`) + const client_secret = getClientSercretResponse.value return { idpId: id, clientId: client_id, - clientSecret: client_secret - }; + clientSecret: client_secret, + } } async registerApplication(name: string, organizationId: number, token: string) { @@ -439,79 +439,79 @@ export class ClientRegistrationService { cross_origin_auth: false, refresh_token: { rotation_type: 'non-rotating', - expiration_type: 'non-expiring' + expiration_type: 'non-expiring', }, jwt_configuration: { alg: 'RS256', lifetime_in_seconds: 36000, - secret_encoded: false + secret_encoded: false, }, app_type: 'non_interactive', grant_types: ['client_credentials'], custom_login_page_on: true, client_metadata: { - organizationId: organizationId.toString() - } - }; + organizationId: organizationId.toString(), + }, + } const registerAppResponse = await this.commonService.httpPost( `${process.env.KEYCLOAK_DOMAIN}${CommonConstants.URL_KEYCLOAK_MANAGEMENT_APPLICATIONS}`, payload, this.getAuthHeader(token) - ); - this.logger.debug(`ClientRegistrationService register app ${JSON.stringify(registerAppResponse)}`); + ) + this.logger.debug(`ClientRegistrationService register app ${JSON.stringify(registerAppResponse)}`) return { clientId: registerAppResponse.data.client_id, - clientSecret: registerAppResponse.data.client_secret - }; + clientSecret: registerAppResponse.data.client_secret, + } } async authorizeApi(clientId: string, scope: string[], token: string) { const existingGrantsResponse = await this.commonService.httpGet( `${process.env.KEYCLOAK_DOMAIN}${CommonConstants.URL_KEYCLOAK_MANAGEMENT_GRANTS}`, this.getAuthHeader(token) - ); + ) // If an grant matching the client id is already found, don't recreate it. - let grantResponse = { data: undefined }; - grantResponse.data = existingGrantsResponse.data.find((grant) => grant.client_id === clientId); - this.logger.debug(`ClientRegistrationService existing grant ${JSON.stringify(grantResponse)}`); + let grantResponse = { data: undefined } + grantResponse.data = existingGrantsResponse.data.find((grant) => grant.client_id === clientId) + this.logger.debug(`ClientRegistrationService existing grant ${JSON.stringify(grantResponse)}`) // Grant wasn't found, so we need to create it if (!grantResponse.data) { const payload = { client_id: clientId, audience: process.env.AUTH0_AUDIENCE, - scope - }; + scope, + } grantResponse = await this.commonService.httpPost( `${process.env.KEYCLOAK_DOMAIN}${CommonConstants.URL_KEYCLOAK_MANAGEMENT_GRANTS}`, payload, this.getAuthHeader(token) - ); - this.logger.debug(`ClientRegistrationService authorize api ${JSON.stringify(grantResponse)}`); + ) + this.logger.debug(`ClientRegistrationService authorize api ${JSON.stringify(grantResponse)}`) } - return grantResponse.data.id; + return grantResponse.data.id } async getToken(payload: ClientCredentialTokenPayloadDto) { - if ('client_credentials' !== payload.grant_type || !payload.client_id || !payload.client_secret) { - throw new Error('Invalid inputs while getting token.'); + if (payload.grant_type !== 'client_credentials' || !payload.client_id || !payload.client_secret) { + throw new Error('Invalid inputs while getting token.') } - const strURL = await this.keycloakUrlService.GetSATURL(process.env.KEYCLOAK_REALM); - this.logger.log(`getToken URL: ${strURL}`); + const strURL = await this.keycloakUrlService.GetSATURL(process.env.KEYCLOAK_REALM) + this.logger.log(`getToken URL: ${strURL}`) const config = { headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - } - }; + 'Content-Type': 'application/x-www-form-urlencoded', + }, + } const tokenResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetSATURL(process.env.KEYCLOAK_REALM), qs.stringify(payload), config - ); + ) - return tokenResponse; + return tokenResponse } async CreateConnection(clientId: string, token: string) { @@ -534,191 +534,191 @@ export class ClientRegistrationService { get_user: "function getByEmail(email, callback) {\n // This script should retrieve a user profile from your existing database,\n // without authenticating the user.\n // It is used to check if a user exists before executing flows that do not\n // require authentication (signup and password reset).\n //\n // There are three ways this script can finish:\n // 1. A user was successfully found. The profile should be in the following\n // format: https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.\n // callback(null, profile);\n // 2. A user was not found\n // callback(null);\n // 3. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n\n const msg = 'Please implement the Get User script for this database connection ' +\n 'at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", change_password: - "function changePassword(email, newPassword, callback) {\n // This script should change the password stored for the current user in your\n // database. It is executed when the user clicks on the confirmation link\n // after a reset password request.\n // The content and behavior of password confirmation emails can be customized\n // here: https://manage.auth0.com/#/emails\n // The `newPassword` parameter of this function is in plain text. It must be\n // hashed/salted to match whatever is stored in your database.\n //\n // There are three ways that this script can finish:\n // 1. The user's password was updated successfully:\n // callback(null, true);\n // 2. The user's password was not updated:\n // callback(null, false);\n // 3. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n //\n // If an error is returned, it will be passed to the query string of the page\n // where the user is being redirected to after clicking the confirmation link.\n // For example, returning `callback(new Error(\"error\"))` and redirecting to\n // https://example.com would redirect to the following URL:\n // https://example.com?email=alice%40example.com&message=error&success=false\n\n const msg = 'Please implement the Change Password script for this database ' +\n 'connection at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n" + "function changePassword(email, newPassword, callback) {\n // This script should change the password stored for the current user in your\n // database. It is executed when the user clicks on the confirmation link\n // after a reset password request.\n // The content and behavior of password confirmation emails can be customized\n // here: https://manage.auth0.com/#/emails\n // The `newPassword` parameter of this function is in plain text. It must be\n // hashed/salted to match whatever is stored in your database.\n //\n // There are three ways that this script can finish:\n // 1. The user's password was updated successfully:\n // callback(null, true);\n // 2. The user's password was not updated:\n // callback(null, false);\n // 3. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n //\n // If an error is returned, it will be passed to the query string of the page\n // where the user is being redirected to after clicking the confirmation link.\n // For example, returning `callback(new Error(\"error\"))` and redirecting to\n // https://example.com would redirect to the following URL:\n // https://example.com?email=alice%40example.com&message=error&success=false\n\n const msg = 'Please implement the Change Password script for this database ' +\n 'connection at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", }, passwordPolicy: 'good', password_complexity_options: { - min_length: 8 + min_length: 8, }, password_history: { size: 5, - enable: false + enable: false, }, password_no_personal_info: { - enable: false + enable: false, }, password_dictionary: { enable: false, - dictionary: [] + dictionary: [], }, - gateway_authentication: 'object' + gateway_authentication: 'object', }, enabled_clients: [clientId], realms: [''], - metadata: {} - }; + metadata: {}, + } const clientConnResponse = await this.commonService.httpPost( `${process.env.KEYCLOAK_DOMAIN}${CommonConstants.URL_KEYCLOAK_MANAGEMENT_CONNECTIONS}`, payload, this.getAuthHeader(token) - ); - this.logger.debug(`ClientRegistrationService create connection app ${JSON.stringify(clientConnResponse)}`); + ) + this.logger.debug(`ClientRegistrationService create connection app ${JSON.stringify(clientConnResponse)}`) return { name: clientConnResponse.data.name, - id: clientConnResponse.data.id - }; + id: clientConnResponse.data.id, + } } async getUserToken(email: string, password: string, clientId: string, clientSecret: string) { - const payload = new userTokenPayloadDto(); + const payload = new userTokenPayloadDto() if (!clientId && !clientSecret) { - this.logger.error(`getUserToken ::: Client ID and client secret are missing`); - throw new BadRequestException(`Client ID and client secret are missing`); + this.logger.error(`getUserToken ::: Client ID and client secret are missing`) + throw new BadRequestException(`Client ID and client secret are missing`) } - const decryptClientId = await this.commonService.decryptPassword(clientId); - const decryptClientSecret = await this.commonService.decryptPassword(clientSecret); + const decryptClientId = await this.commonService.decryptPassword(clientId) + const decryptClientSecret = await this.commonService.decryptPassword(clientSecret) - payload.client_id = decryptClientId; - payload.client_secret = decryptClientSecret; - payload.username = email; - payload.password = password; + payload.client_id = decryptClientId + payload.client_secret = decryptClientSecret + payload.username = email + payload.password = password if ( - 'password' !== payload.grant_type || + payload.grant_type !== 'password' || !payload.client_id || !payload.client_secret || !payload.username || !payload.password ) { - throw new Error('Invalid inputs while getting token.'); + throw new Error('Invalid inputs while getting token.') } - const strURL = await this.keycloakUrlService.GetSATURL(process.env.KEYCLOAK_REALM); - this.logger.log(`getToken URL: ${strURL}`); + const strURL = await this.keycloakUrlService.GetSATURL(process.env.KEYCLOAK_REALM) + this.logger.log(`getToken URL: ${strURL}`) const config = { headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - } - }; + 'Content-Type': 'application/x-www-form-urlencoded', + }, + } const tokenResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetSATURL(process.env.KEYCLOAK_REALM), qs.stringify(payload), config - ); + ) - return tokenResponse; + return tokenResponse } async getAccessToken(refreshToken: string, clientId: string, clientSecret: string) { try { - const payload = new accessTokenPayloadDto(); + const payload = new accessTokenPayloadDto() if (!clientId && !clientSecret) { - this.logger.error(`getAccessToken ::: Client ID and client secret are missing`); - throw new BadRequestException(`Client ID and client secret are missing`); + this.logger.error(`getAccessToken ::: Client ID and client secret are missing`) + throw new BadRequestException(`Client ID and client secret are missing`) } - const decryptClientId = await this.commonService.decryptPassword(clientId); - const decryptClientSecret = await this.commonService.decryptPassword(clientSecret); + const decryptClientId = await this.commonService.decryptPassword(clientId) + const decryptClientSecret = await this.commonService.decryptPassword(clientSecret) - payload.client_id = decryptClientId; - payload.client_secret = decryptClientSecret; + payload.client_id = decryptClientId + payload.client_secret = decryptClientSecret - payload.grant_type = 'refresh_token'; - payload.refresh_token = refreshToken; + payload.grant_type = 'refresh_token' + payload.refresh_token = refreshToken if ( - 'refresh_token' !== payload.grant_type || + payload.grant_type !== 'refresh_token' || !payload.client_id || !payload.client_secret || !payload.refresh_token ) { - throw new Error('Invalid inputs while getting token.'); + throw new Error('Invalid inputs while getting token.') } const config = { headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - } - }; + 'Content-Type': 'application/x-www-form-urlencoded', + }, + } const tokenResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetSATURL(process.env.KEYCLOAK_REALM), qs.stringify(payload), config - ); + ) - return tokenResponse; + return tokenResponse } catch (error) { - this.logger.error(`Error in getAccessToken ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in getAccessToken ${JSON.stringify(error)}`) + throw error } } async getAccessTokenHolder(refreshToken: string) { - const payload = new accessTokenPayloadDto(); - payload.grant_type = 'refresh_token'; - payload.client_id = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_ID; - payload.refresh_token = refreshToken; - payload.client_secret = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_SECRET; + const payload = new accessTokenPayloadDto() + payload.grant_type = 'refresh_token' + payload.client_id = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_ID + payload.refresh_token = refreshToken + payload.client_secret = process.env.KEYCLOAK_MANAGEMENT_ADEYA_CLIENT_SECRET - this.logger.log(`access Token for holderPayload: ${JSON.stringify(payload)}`); + this.logger.log(`access Token for holderPayload: ${JSON.stringify(payload)}`) if ( - 'refresh_token' !== payload.grant_type || + payload.grant_type !== 'refresh_token' || !payload.client_id || !payload.client_secret || !payload.refresh_token ) { - throw new Error('Bad Request'); + throw new Error('Bad Request') } - const strURL = await this.keycloakUrlService.GetSATURL('credebl-platform'); - this.logger.log(`getToken URL: ${strURL}`); + const strURL = await this.keycloakUrlService.GetSATURL('credebl-platform') + this.logger.log(`getToken URL: ${strURL}`) const config = { headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - } - }; + 'Content-Type': 'application/x-www-form-urlencoded', + }, + } const tokenResponse = await this.commonService.httpPost( await this.keycloakUrlService.GetSATURL('credebl-platform'), qs.stringify(payload), config - ); + ) - this.logger.debug(`ClientRegistrationService token ${JSON.stringify(tokenResponse)}`); - return tokenResponse; + this.logger.debug(`ClientRegistrationService token ${JSON.stringify(tokenResponse)}`) + return tokenResponse } async getClientRedirectUrl(clientId: string, token: string) { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM - const decryptClientId = await this.commonService.decryptPassword(clientId); + const decryptClientId = await this.commonService.decryptPassword(clientId) const redirectUrls = await this.commonService.httpGet( await this.keycloakUrlService.GetClientURL(realmName, decryptClientId), this.getAuthHeader(token) - ); + ) - this.logger.debug(`redirectUrls ${JSON.stringify(redirectUrls)}`); + this.logger.debug(`redirectUrls ${JSON.stringify(redirectUrls)}`) - return redirectUrls; + return redirectUrls } async getUserInfoByUserId(userId: string, token: string) { - const realmName = process.env.KEYCLOAK_REALM; + const realmName = process.env.KEYCLOAK_REALM const userInfo = await this.commonService.httpGet( await this.keycloakUrlService.GetUserInfoURL(realmName, userId), this.getAuthHeader(token) - ); + ) - this.logger.debug(`userInfo ${JSON.stringify(userInfo)}`); + this.logger.debug(`userInfo ${JSON.stringify(userInfo)}`) - return userInfo; + return userInfo } } diff --git a/libs/client-registration/src/dtos/accessTokenPayloadDto.ts b/libs/client-registration/src/dtos/accessTokenPayloadDto.ts index 18294a0bb..e5f1f125d 100644 --- a/libs/client-registration/src/dtos/accessTokenPayloadDto.ts +++ b/libs/client-registration/src/dtos/accessTokenPayloadDto.ts @@ -1,7 +1,6 @@ export class accessTokenPayloadDto { - client_id: string; - client_secret: string; - grant_type?: string = 'refresh_token'; - refresh_token: string; - } - \ No newline at end of file + client_id: string + client_secret: string + grant_type?: string = 'refresh_token' + refresh_token: string +} diff --git a/libs/client-registration/src/dtos/client-credential-token-payload.dto.ts b/libs/client-registration/src/dtos/client-credential-token-payload.dto.ts index 6e9c87de8..b24674a97 100644 --- a/libs/client-registration/src/dtos/client-credential-token-payload.dto.ts +++ b/libs/client-registration/src/dtos/client-credential-token-payload.dto.ts @@ -1,7 +1,7 @@ -export class ClientCredentialTokenPayloadDto { - client_id: string; - client_secret: string; - audience?: string; - grant_type?: string = 'client_credentials'; - scope?: string; -} +export class ClientCredentialTokenPayloadDto { + client_id: string + client_secret: string + audience?: string + grant_type?: string = 'client_credentials' + scope?: string +} diff --git a/libs/client-registration/src/dtos/create-user.dto.ts b/libs/client-registration/src/dtos/create-user.dto.ts index 146abc1e9..e5e8aebbe 100644 --- a/libs/client-registration/src/dtos/create-user.dto.ts +++ b/libs/client-registration/src/dtos/create-user.dto.ts @@ -1,23 +1,23 @@ /* eslint-disable camelcase */ -import { ApiExtraModels } from '@nestjs/swagger'; +import { ApiExtraModels } from '@nestjs/swagger' // import { Role } from 'apps/platform-service/src/entities/role.entity'; @ApiExtraModels() export class CreateUserDto { - id?: string; - username?: string; - email: string; - password: string; - logo_uri?: string; - token_lifetime?: number; - is_active?: boolean; - firstName?: string; - lastName?: string; + id?: string + username?: string + email: string + password: string + logo_uri?: string + token_lifetime?: number + is_active?: boolean + firstName?: string + lastName?: string // role?: Role; - isEmailVerified?: boolean; - createdBy?: string; - clientId?: string; - clientSecret?: string; - supabaseUserId?: string; - isHolder?: boolean; + isEmailVerified?: boolean + createdBy?: string + clientId?: string + clientSecret?: string + supabaseUserId?: string + isHolder?: boolean } diff --git a/libs/client-registration/src/dtos/userTokenPayloadDto.ts b/libs/client-registration/src/dtos/userTokenPayloadDto.ts index d1e89bf86..356f655cc 100644 --- a/libs/client-registration/src/dtos/userTokenPayloadDto.ts +++ b/libs/client-registration/src/dtos/userTokenPayloadDto.ts @@ -1,9 +1,7 @@ export class userTokenPayloadDto { - client_id: string; - client_secret: string; - username: string; - password: string; - grant_type?: string = 'password'; - - } - \ No newline at end of file + client_id: string + client_secret: string + username: string + password: string + grant_type?: string = 'password' +} diff --git a/libs/client-registration/src/index.ts b/libs/client-registration/src/index.ts index 470b28a05..fb49f3f7b 100644 --- a/libs/client-registration/src/index.ts +++ b/libs/client-registration/src/index.ts @@ -1,2 +1,2 @@ -export * from './client-registration.module'; -export * from './client-registration.service'; +export * from './client-registration.module' +export * from './client-registration.service' diff --git a/libs/client-registration/src/interfaces/client.interface.ts b/libs/client-registration/src/interfaces/client.interface.ts index 59e78a52c..5045ef670 100644 --- a/libs/client-registration/src/interfaces/client.interface.ts +++ b/libs/client-registration/src/interfaces/client.interface.ts @@ -1,8 +1,8 @@ export interface IClientRoles { - id: string - name: string - description?: string - composite?: boolean - clientRole?: boolean - containerId?: string -} \ No newline at end of file + id: string + name: string + description?: string + composite?: boolean + clientRole?: boolean + containerId?: string +} diff --git a/libs/common/package.json b/libs/common/package.json index 16a53aeb6..6d326fbd2 100644 --- a/libs/common/package.json +++ b/libs/common/package.json @@ -3,9 +3,7 @@ "main": "src/index", "types": "src/index", "version": "0.0.1", - "files": [ - "dist" - ], + "files": ["dist"], "scripts": { "build": "pnpm run clean && pnpm run compile", "clean": "rimraf ../../dist/libs/common", diff --git a/libs/common/src/NATSClient.ts b/libs/common/src/NATSClient.ts index 219a85499..fca3087bf 100644 --- a/libs/common/src/NATSClient.ts +++ b/libs/common/src/NATSClient.ts @@ -1,62 +1,63 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Inject, Injectable, Logger } from '@nestjs/common'; +import { Inject, Injectable, Logger } from '@nestjs/common' -import { ClientProxy, NatsRecordBuilder } from '@nestjs/microservices'; -import { map } from 'rxjs/operators'; -import * as nats from 'nats'; -import { firstValueFrom } from 'rxjs'; -import ContextStorageService, { ContextStorageServiceKey } from '../../context/src/contextStorageService.interface'; -import { v4 } from 'uuid'; +import { type ClientProxy, NatsRecordBuilder } from '@nestjs/microservices' +import * as nats from 'nats' +import { firstValueFrom } from 'rxjs' +import { map } from 'rxjs/operators' +import { v4 } from 'uuid' +import type ContextStorageService from '../../context/src/contextStorageService.interface' +import { ContextStorageServiceKey } from '../../context/src/contextStorageService.interface' @Injectable() export class NATSClient { - private readonly logger: Logger; + private readonly logger: Logger constructor( @Inject(ContextStorageServiceKey) private readonly contextStorageService: ContextStorageService ) { - this.logger = new Logger('NATSClient'); + this.logger = new Logger('NATSClient') } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types sendNats(serviceProxy: ClientProxy, cmd: string, payload: any): Promise { - this.logger.log(`Inside NATSClient for sendNats()`); - const pattern = { cmd }; - const headers = nats.headers(1, this.contextStorageService.getContextId()); - const record = new NatsRecordBuilder(payload).setHeaders(headers).build(); + this.logger.log(`Inside NATSClient for sendNats()`) + const pattern = { cmd } + const headers = nats.headers(1, this.contextStorageService.getContextId()) + const record = new NatsRecordBuilder(payload).setHeaders(headers).build() return serviceProxy .send(pattern, record) .pipe( map((response: string) => ({ - response + response, })) ) - .toPromise(); + .toPromise() } sendNatsMessage(serviceProxy: ClientProxy, cmd: string, payload: any): Promise { - const pattern = { cmd }; - const headers = nats.headers(1, this.contextStorageService.getContextId()); - const record = new NatsRecordBuilder(payload).setHeaders(headers).build(); + const pattern = { cmd } + const headers = nats.headers(1, this.contextStorageService.getContextId()) + const record = new NatsRecordBuilder(payload).setHeaders(headers).build() - const result = serviceProxy.send(pattern, record); + const result = serviceProxy.send(pattern, record) - return firstValueFrom(result); + return firstValueFrom(result) } send(serviceProxy: ClientProxy, pattern: object, payload: any): Promise { - let contextId = this.contextStorageService.getContextId(); + let contextId = this.contextStorageService.getContextId() if (!contextId) { - contextId = v4(); + contextId = v4() } - const headers = nats.headers(1, contextId); - const record = new NatsRecordBuilder(payload).setHeaders(headers).build(); + const headers = nats.headers(1, contextId) + const record = new NatsRecordBuilder(payload).setHeaders(headers).build() - const result = serviceProxy.send(pattern, record); + const result = serviceProxy.send(pattern, record) - return firstValueFrom(result); + return firstValueFrom(result) } } diff --git a/libs/common/src/cast.helper.ts b/libs/common/src/cast.helper.ts index a425f7dbf..1a63be5a5 100644 --- a/libs/common/src/cast.helper.ts +++ b/libs/common/src/cast.helper.ts @@ -1,4 +1,13 @@ -import { BadRequestException, PipeTransform } from '@nestjs/common'; +import { BadRequestException, type PipeTransform } from '@nestjs/common' +import { + type ValidationArguments, + type ValidationOptions, + ValidatorConstraint, + type ValidatorConstraintInterface, + isBase64, + isMimeType, + registerDecorator, +} from 'class-validator' import { DidMethod, JSONSchemaType, @@ -6,88 +15,79 @@ import { TemplateIdentifier, W3CSchemaDataType, ledgerLessDIDType, - schemaRequestType -} from '../../enum/src/enum'; -import { ICredentialData, IJsonldCredential, IPrettyVc } from './interfaces/issuance.interface'; -import { - ValidationArguments, - ValidationOptions, - ValidatorConstraint, - ValidatorConstraintInterface, - isBase64, - isMimeType, - registerDecorator -} from 'class-validator'; + schemaRequestType, +} from '../../enum/src/enum' +import type { ICredentialData, IJsonldCredential, IPrettyVc } from './interfaces/issuance.interface' -import { ISchemaFields } from './interfaces/schema.interface'; -import { ResponseMessages } from './response-messages'; -import { plainToClass } from 'class-transformer'; +import { plainToClass } from 'class-transformer' +import type { ISchemaFields } from './interfaces/schema.interface' +import { ResponseMessages } from './response-messages' interface ToNumberOptions { - default?: number; - min?: number; - max?: number; + default?: number + min?: number + max?: number } export function toLowerCase(value: string): string { - return value.toLowerCase(); + return value.toLowerCase() } export function trim(value: string): string { - if ('string' === typeof value) { - return value.trim(); + if (typeof value === 'string') { + return value.trim() } } export function toDate(value: string): Date { - return new Date(value); + return new Date(value) } export function toBoolean(value: string): boolean { // eslint-disable-next-line no-param-reassign - value = value.toLowerCase(); + value = value.toLowerCase() // return 'true' === value || '1' === value ? true : false; - return Boolean('true' === value || '1' === value); + return Boolean(value === 'true' || value === '1') } export function toNumber(value: string, opts: ToNumberOptions = {}): number { - let newValue: number = Number.parseInt(value || String(opts.default), 10); + let newValue: number = Number.parseInt(value || String(opts.default), 10) if (Number.isNaN(newValue)) { - newValue = opts.default; + newValue = opts.default } if (opts.min) { if (newValue < opts.min) { - newValue = opts.min; + newValue = opts.min } if (newValue > opts.max) { - newValue = opts.max; + newValue = opts.max } } - return newValue; + return newValue } export function ledgerName(value: string): string { - let network; - network = value.replace(':', ' '); - network = network.charAt(0).toUpperCase() + network.slice(1); - const words = network.split(' '); - network = `${words[0]} ${words[1].charAt(0).toUpperCase()}${words[1].slice(1)}`; + let network + network = value.replace(':', ' ') + network = network.charAt(0).toUpperCase() + network.slice(1) + const words = network.split(' ') + network = `${words[0]} ${words[1].charAt(0).toUpperCase()}${words[1].slice(1)}` - return network; + return network } export function isSafeString(value: string): boolean { // Define a regular expression to allow alphanumeric characters, spaces, and some special characters - const safeRegex = /^[a-zA-Z0-9\s!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*$/; + const safeRegex = /^[a-zA-Z0-9\s!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*$/ // Check if the value matches the safe regex - return safeRegex.test(value); + return safeRegex.test(value) } export const IsNotSQLInjection = @@ -101,94 +101,92 @@ export const IsNotSQLInjection = validator: { validate(value) { // Check if the value is a string - if ('string' === typeof value) { + if (typeof value === 'string') { // Regex to check for SQL injection keywords at the start - const startInjectionRegex = new RegExp( - `^\\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER|CREATE|EXEC|FROM|WHERE|AND|OR)\\b`, - 'i' - ); + const startInjectionRegex = + /^\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER|CREATE|EXEC|FROM|WHERE|AND|OR)\b/i // Check if the SQL injection pattern is present at the start if (startInjectionRegex.test(value)) { - return false; // SQL keyword present at the start + return false // SQL keyword present at the start } } - return true; // Value does not contain any SQL injection keywords + return true // Value does not contain any SQL injection keywords }, defaultMessage(args: ValidationArguments) { - return `${args.property} contains SQL injection keywords.`; - } - } - }); - }; + return `${args.property} contains SQL injection keywords.` + }, + }, + }) + } @ValidatorConstraint({ name: 'customText', async: false }) export class ImageBase64Validator implements ValidatorConstraintInterface { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-unused-vars - validate(value: string, args: ValidationArguments) { + validate(value: string, _args: ValidationArguments) { // Implement your custom validation logic here // Validation to allow option param logo - if ('' == value) { - return true; + if (value == '') { + return true } - if (!value || 'string' !== typeof value) { - throw new BadRequestException('Invalid base64 string'); + if (!value || typeof value !== 'string') { + throw new BadRequestException('Invalid base64 string') } - const parts = value.split(','); - if (2 !== parts.length) { - throw new BadRequestException('Invalid data URI'); + const parts = value.split(',') + if (parts.length !== 2) { + throw new BadRequestException('Invalid data URI') } // eslint-disable-next-line prefer-destructuring - const mimeType = parts[0].split(';')[0].split(':')[1]; + const mimeType = parts[0].split(';')[0].split(':')[1] // eslint-disable-next-line prefer-destructuring - const base64Data = parts[1]; + const base64Data = parts[1] // Validate MIME type if (!isMimeType(mimeType)) { - throw new BadRequestException('Please provide valid MIME type'); + throw new BadRequestException('Please provide valid MIME type') } // Validate base64 data - if (!isBase64(base64Data) || '' == base64Data || null == base64Data) { - throw new BadRequestException('Invalid base64 string'); + if (!isBase64(base64Data) || base64Data == '' || base64Data == null) { + throw new BadRequestException('Invalid base64 string') } - return true; + return true } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-unused-vars defaultMessage(_args: ValidationArguments) { - return 'Default message received from [ImageBase64Validator]'; + return 'Default message received from [ImageBase64Validator]' } } export class TrimStringParamPipe implements PipeTransform { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type transform(value: string) { - return plainToClass(String, value.trim()); + return plainToClass(String, value.trim()) } } //TODO: Need to add this logic in `trimstringpipe` export class EmptyStringParamPipe implements PipeTransform { - private paramName: string; + private paramName: string static forParam(paramName: string): PipeTransform { - return new EmptyStringParamPipe(paramName); + return new EmptyStringParamPipe(paramName) } private constructor(paramName: string) { - this.paramName = paramName; + this.paramName = paramName } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type transform(value: string) { - const trimmedValue = value.trim(); + const trimmedValue = value.trim() if (!trimmedValue) { - throw new BadRequestException(`${this.paramName} is required`); + throw new BadRequestException(`${this.paramName} is required`) } - return plainToClass(String, trimmedValue); + return plainToClass(String, trimmedValue) } } @@ -207,141 +205,141 @@ export class EmptyStringParamPipe implements PipeTransform { // }; export function validateSchemaPayload(schemaPayload: ISchemaFields, schemaType: string): void { - const errors: string[] = []; + const errors: string[] = [] switch (true) { case schemaRequestType.INDY === schemaType: switch (true) { case !schemaPayload?.name: - errors.push('name is required for indy schema type'); - break; - case 'string' !== typeof schemaPayload?.name: - errors.push('name must be string'); - break; + errors.push('name is required for indy schema type') + break + case typeof schemaPayload?.name !== 'string': + errors.push('name must be string') + break case !schemaPayload?.version: - errors.push('version is required for indy schema type'); - break; + errors.push('version is required for indy schema type') + break default: - break; + break } - if (!Array.isArray(schemaPayload?.attributes) || 0 === schemaPayload?.attributes.length) { - errors.push('attributes array must not be empty for indy schema type'); + if (!Array.isArray(schemaPayload?.attributes) || schemaPayload?.attributes.length === 0) { + errors.push('attributes array must not be empty for indy schema type') } else { schemaPayload?.attributes.forEach((attribute, index) => { if (!attribute) { - errors.push(`attributes are required at position ${index + 1} in indy schema type`); + errors.push(`attributes are required at position ${index + 1} in indy schema type`) } else { switch (true) { case !attribute?.displayName: - errors.push(`displayName is required at position ${index + 1} in indy schema type`); - break; + errors.push(`displayName is required at position ${index + 1} in indy schema type`) + break case !attribute?.attributeName: - errors.push(`attributeName is required at position ${index + 1} in indy schema type`); - break; + errors.push(`attributeName is required at position ${index + 1} in indy schema type`) + break case !attribute?.schemaDataType: - errors.push(`schemaDataType is required at position ${index + 1} in indy schema type`); - break; + errors.push(`schemaDataType is required at position ${index + 1} in indy schema type`) + break default: - break; + break } } - }); + }) } - break; + break case schemaRequestType.W3C === schemaType: switch (true) { case !schemaPayload?.schemaName: - errors.push('schemaName is required for w3c schema type'); - break; - case 'string' !== typeof schemaPayload?.schemaName: - errors.push('schemaName must be string'); - break; + errors.push('schemaName is required for w3c schema type') + break + case typeof schemaPayload?.schemaName !== 'string': + errors.push('schemaName must be string') + break case !schemaPayload?.did: - errors.push('did is required for w3c schema type'); - break; - case 'string' !== typeof schemaPayload?.did: - errors.push('did must be string'); - break; + errors.push('did is required for w3c schema type') + break + case typeof schemaPayload?.did !== 'string': + errors.push('did must be string') + break case !schemaPayload?.description: - errors.push('description is required for w3c schema type'); - break; - case 'string' !== typeof schemaPayload?.description: - errors.push('description must be string'); - break; + errors.push('description is required for w3c schema type') + break + case typeof schemaPayload?.description !== 'string': + errors.push('description must be string') + break default: - break; + break } - if (!Array.isArray(schemaPayload.schemaAttributes) || 0 === schemaPayload.schemaAttributes.length) { - errors.push('schemaAttributes array must not be empty for w3c schema type'); + if (!Array.isArray(schemaPayload.schemaAttributes) || schemaPayload.schemaAttributes.length === 0) { + errors.push('schemaAttributes array must not be empty for w3c schema type') } else { schemaPayload.schemaAttributes.forEach((attribute, index) => { if (!attribute) { - errors.push(`schemaAttributes are required at position ${index + 1} in w3c schema type`); + errors.push(`schemaAttributes are required at position ${index + 1} in w3c schema type`) } else { switch (true) { case !attribute.title: - errors.push(`title is required at position ${index + 1} in w3c schema type`); - break; + errors.push(`title is required at position ${index + 1} in w3c schema type`) + break case !attribute.type: - errors.push(`type is required at position ${index + 1} in w3c schema type`); - break; + errors.push(`type is required at position ${index + 1} in w3c schema type`) + break default: - break; + break } } - }); + }) } - break; + break default: - break; + break } - if (0 < errors.length) { - throw new BadRequestException(errors); + if (errors.length > 0) { + throw new BadRequestException(errors) } } export class AgentSpinupValidator { private static validateField(value: string, errorMessage: string): void { if (!value) { - throw new BadRequestException(errorMessage); + throw new BadRequestException(errorMessage) } } private static validateWalletName(walletName: string): void { - const regex = /^[a-zA-Z0-9]+$/; + const regex = /^[a-zA-Z0-9]+$/ if (!regex.test(walletName)) { throw new BadRequestException(ResponseMessages.agent.error.seedChar, { cause: new Error(), - description: 'Please enter a valid wallet name. Only alphanumeric characters are allowed.' - }); + description: 'Please enter a valid wallet name. Only alphanumeric characters are allowed.', + }) } } public static validate(agentSpinupDto): void { - this.validateWalletName(agentSpinupDto.walletName); + this.validateWalletName(agentSpinupDto.walletName) } } export const validateEmail = (email: string): boolean => { - const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; - return emailRegex.test(email); -}; + const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/ + return emailRegex.test(email) +} // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type export const createOobJsonldIssuancePayload = (JsonldCredentialDetails: IJsonldCredential, prettyVc: IPrettyVc) => { - const { credentialData, orgDid, orgId, schemaLedgerId, schemaName, isReuseConnection } = JsonldCredentialDetails; - const credentialSubject = {}; + const { credentialData, orgDid, orgId, schemaLedgerId, schemaName, isReuseConnection } = JsonldCredentialDetails + const credentialSubject = {} - const proofType = orgDid?.includes(DidMethod.POLYGON) ? ProofType.POLYGON_PROOFTYPE : ProofType.NO_LEDGER_PROOFTYPE; + const proofType = orgDid?.includes(DidMethod.POLYGON) ? ProofType.POLYGON_PROOFTYPE : ProofType.NO_LEDGER_PROOFTYPE for (const key in credentialData) { if (credentialData.hasOwnProperty(key) && TemplateIdentifier.EMAIL_COLUMN !== key) { - credentialSubject[key] = credentialData[key]; + credentialSubject[key] = credentialData[key] } } @@ -353,91 +351,91 @@ export const createOobJsonldIssuancePayload = (JsonldCredentialDetails: IJsonldC '@context': ['https://www.w3.org/2018/credentials/v1', `${schemaLedgerId}`], type: ['VerifiableCredential', `${schemaName}`], issuer: { - id: `${orgDid}` + id: `${orgDid}`, }, issuanceDate: new Date().toISOString(), credentialSubject, - prettyVc + prettyVc, }, options: { proofType, - proofPurpose: 'assertionMethod' - } - } + proofPurpose: 'assertionMethod', + }, + }, ], comment: 'string', protocolVersion: 'v2', credentialType: 'jsonld', orgId, - isReuseConnection - }; -}; + isReuseConnection, + } +} @ValidatorConstraint({ name: 'isHostPortOrDomain', async: false }) export class IsHostPortOrDomainConstraint implements ValidatorConstraintInterface { validate(value: string): boolean { // Regular expression for validating URL with host:port or domain const hostPortRegex = - /^(http:\/\/|https:\/\/)?(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)):(?:\d{1,5})(\/[^\s]*)?$/; + /^(http:\/\/|https:\/\/)?(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)):(?:\d{1,5})(\/[^\s]*)?$/ const domainRegex = - /^(http:\/\/|https:\/\/)?(?:localhost|(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,})(:\d{1,5})?(\/[^\s]*)?$/; + /^(http:\/\/|https:\/\/)?(?:localhost|(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,})(:\d{1,5})?(\/[^\s]*)?$/ - return hostPortRegex.test(value) || domainRegex.test(value); + return hostPortRegex.test(value) || domainRegex.test(value) } defaultMessage(): string { - return 'Invalid host:port or domain format'; + return 'Invalid host:port or domain format' } } export function IsHostPortOrDomain(validationOptions?: ValidationOptions) { - return function (object: object, propertyName: string): void { + return (object: object, propertyName: string): void => { registerDecorator({ target: object.constructor, propertyName, options: validationOptions, constraints: [], - validator: IsHostPortOrDomainConstraint - }); - }; + validator: IsHostPortOrDomainConstraint, + }) + } } export function checkDidLedgerAndNetwork(schemaType: string, did: string): boolean { - const cleanSchemaType = schemaType.trim().toLowerCase(); - const cleanDid = did.trim().toLowerCase(); + const cleanSchemaType = schemaType.trim().toLowerCase() + const cleanDid = did.trim().toLowerCase() if (JSONSchemaType.POLYGON_W3C === cleanSchemaType) { - return cleanDid.includes(JSONSchemaType.POLYGON_W3C); + return cleanDid.includes(JSONSchemaType.POLYGON_W3C) } if (JSONSchemaType.LEDGER_LESS === cleanSchemaType) { - return cleanDid.startsWith(ledgerLessDIDType.DID_KEY) || cleanDid.startsWith(ledgerLessDIDType.DID_WEB); + return cleanDid.startsWith(ledgerLessDIDType.DID_KEY) || cleanDid.startsWith(ledgerLessDIDType.DID_WEB) } - return false; + return false } export function validateAndUpdateIssuanceDates(data: ICredentialData[]): ICredentialData[] { // Get current date in 'YYYY-MM-DD' format // eslint-disable-next-line prefer-destructuring - const currentDate = new Date().toISOString().split('T')[0]; + const currentDate = new Date().toISOString().split('T')[0] return data.map((item) => { - const { issuanceDate } = item.credential; + const { issuanceDate } = item.credential // eslint-disable-next-line prefer-destructuring - const issuanceDateOnly = issuanceDate.split('T')[0]; + const issuanceDateOnly = issuanceDate.split('T')[0] // If the date does not match the current date, then update it if (issuanceDateOnly !== currentDate) { - item.credential.issuanceDate = new Date().toISOString(); + item.credential.issuanceDate = new Date().toISOString() } - return item; - }); + return item + }) } export function ValidateNestedStructureFields(validationOptions?: ValidationOptions) { - return function (object: object, propertyName: string): void { + return (object: object, propertyName: string): void => { registerDecorator({ name: 'validateNestedStructureFields', target: object.constructor, @@ -445,59 +443,59 @@ export function ValidateNestedStructureFields(validationOptions?: ValidationOpti options: validationOptions, validator: { validate(_, args: ValidationArguments) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const obj = args.object as any; - const { schemaDataType, properties, items } = obj; + // biome-ignore lint/suspicious/noExplicitAny: + const obj = args.object as any + const { schemaDataType, properties, items } = obj // object: must only have properties if (W3CSchemaDataType.OBJECT === schemaDataType) { - return properties !== undefined && items === undefined; + return properties !== undefined && items === undefined } // array: must only have items if (W3CSchemaDataType.ARRAY === schemaDataType) { - return items !== undefined && properties === undefined; + return items !== undefined && properties === undefined } // Others: neither properties nor items should be present - return items === undefined && properties === undefined; + return items === undefined && properties === undefined }, defaultMessage(args: ValidationArguments) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const obj = args.object as any; - const { schemaDataType, properties, items } = obj; + // biome-ignore lint/suspicious/noExplicitAny: + const obj = args.object as any + const { schemaDataType, properties, items } = obj if (W3CSchemaDataType.OBJECT === schemaDataType) { if (items !== undefined) { - return `'items' is not allowed when schemaDataType is object`; + return `'items' is not allowed when schemaDataType is object` } if (properties === undefined) { - return `'properties' is required when schemaDataType is object`; + return `'properties' is required when schemaDataType is object` } } if (W3CSchemaDataType.ARRAY === schemaDataType) { if (properties !== undefined) { - return `'properties' is not allowed when schemaDataType is array`; + return `'properties' is not allowed when schemaDataType is array` } if (items === undefined) { - return `'items' is required when schemaDataType is array`; + return `'items' is required when schemaDataType is array` } } if (W3CSchemaDataType.OBJECT !== schemaDataType && W3CSchemaDataType.ARRAY !== schemaDataType) { if (properties !== undefined) { - return `'properties' is only allowed when schemaDataType is object`; + return `'properties' is only allowed when schemaDataType is object` } if (items !== undefined) { - return `'items' is only allowed when schemaDataType is array`; + return `'items' is only allowed when schemaDataType is array` } } - return 'Invalid structure based on schemaDataType'; - } - } - }); - }; + return 'Invalid structure based on schemaDataType' + }, + }, + }) + } } diff --git a/libs/common/src/common.constant.ts b/libs/common/src/common.constant.ts index 1abbb5aac..9128b57f6 100644 --- a/libs/common/src/common.constant.ts +++ b/libs/common/src/common.constant.ts @@ -120,10 +120,9 @@ export enum CommonConstants { URL_SHAGENT_SEND_ANSWER = '/multi-tenancy/question-answer/answer/#/@', URL_SHAGENT_QUESTION_ANSWER_RECORD = '/multi-tenancy/question-answer/#', URL_SHAGENT_DELETE_SUB_WALLET = '/multi-tenancy/#', - URL_SHARED_SEND_BASIC_MESSAGE = '/multi-tenancy/basic-messages/#/@', + URL_SHARED_SEND_BASIC_MESSAGE = '/multi-tenancy/basic-messages/#/@', URL_SHAGENT_ACCEPT_PROOF_REQUEST = '/multi-tenancy/proofs/#/accept-request/@', - // PROOF SERVICES URL_SEND_PROOF_REQUEST = '/proofs/request-proof', URL_GET_PROOF_PRESENTATIONS = '/proofs', @@ -140,7 +139,7 @@ export enum CommonConstants { // CREATE KEYS CREATE_POLYGON_SECP256k1_KEY = '/polygon/create-keys', - + // Nested attribute separator NESTED_ATTRIBUTE_SEPARATOR = '~', @@ -161,7 +160,7 @@ export enum CommonConstants { // POLYGON KEYWORDS POLYGON = 'polygon', - + // DOMAIN EVENTS DOMAIN_EVENT_SCHEMA_CREATED = 'Schema Created', DOMAIN_EVENT_CRED_DEF_CREATED = 'Cred-Def Created', @@ -257,7 +256,7 @@ export enum CommonConstants { // agent status URL_AGENT_STATUS = '/agent', - + // Tenant Status PENDING_STATE = 0, REJECT_STATE = 2, @@ -284,14 +283,12 @@ export enum CommonConstants { ACTIVE_NON_ADMIN_USER = 1, ALL_NON_ADMIN_USER = 3, - // Platform admin Details - PLATFORM_ADMIN_EMAIL='platform.admin@yopmail.com', - PLATFORM_ADMIN_ORG='Platform-admin', - PLATFORM_ADMIN_ORG_ROLE='platform_admin', - - USER_HOLDER_ROLE='holder', + PLATFORM_ADMIN_EMAIL = 'platform.admin@yopmail.com', + PLATFORM_ADMIN_ORG = 'Platform-admin', + PLATFORM_ADMIN_ORG_ROLE = 'platform_admin', + USER_HOLDER_ROLE = 'holder', //onBoarding Type ONBOARDING_TYPE_ADMIN = 0, @@ -322,114 +319,112 @@ export enum CommonConstants { KEYTYPE = 'ed25519', METHOD = 'indy', NETWORK = 'bcovrin:testnet', - ROLE = 'endorser', - - //CacheInfo -CACHE_SHARED_APIKEY_KEY = "dedicatedApiKey", -CACHE_APIKEY_KEY = "sharedApiKey", -CACHE_TTL_SECONDS = 604800, - -CLOUD_WALLET_GET_PROOF_REQUEST = '/multi-tenancy/proofs', -CLOUD_WALLET_CREATE_CONNECTION_INVITATION = '/multi-tenancy/create-invitation', -CLOUD_WALLET_ACCEPT_PROOF_REQUEST = '/accept-request/', -CLOUD_WALLET_DID_LIST = '/multi-tenancy/dids/', -CLOUD_WALLET_CONNECTION_BY_ID = '/multi-tenancy/connections/', -CLOUD_WALLET_CREDENTIAL = '/multi-tenancy/credentials', -CLOUD_WALLET_BASIC_MESSAGE = '/multi-tenancy/basic-messages/', - -// Bulk-issuance -BATCH_SIZE = 100, -MAX_CONCURRENT_OPERATIONS = 50, -ISSUANCE_BATCH_SIZE = 2000, -ISSUANCE_MAX_CONCURRENT_OPERATIONS = 1000, -ISSUANCE_BATCH_DELAY = 60000, //Intially 60000 - - -// MICROSERVICES NAMES -API_GATEWAY_SERVICE = 'api-gateway', -ORGANIZATION_SERVICE = 'organization', -USER_SERVICE = 'user', -AUTH_SERVICE = 'authz', -FIDO_SERVICE = 'fido', -UTILITY_SERVICE = 'utilitites', -CONNECTION_SERVICE = 'connection', -LEDGER_SERVICE = 'ledger', -PLATFORM_SERVICE = 'platform', -SCHEMA_SERVICE = 'schema', -CREDENTIAL_DEFINITION_SERVICE = 'credential-definition', -AGENT_SERVICE = 'agent-service', -AGENT_PROVISIONING = 'agent-provisioning', -ISSUANCE_SERVICE = 'issuance', -VERIFICATION_SERVICE = 'verification', -WEBHOOK_SERVICE = 'webhook', -NOTIFICATION_SERVICE = 'notification', -GEO_LOCATION_SERVICE = 'geo-location', -CLOUD_WALLET_SERVICE = 'cloud-wallet', - -//CLOUD WALLET -RECEIVE_INVITATION_BY_URL = '/multi-tenancy/receive-invitation-url/', -ACCEPT_OFFER = '/multi-tenancy/credentials/accept-offer/', -SEED_LENGTH = 32 + ROLE = 'endorser', + + //CacheInfo + CACHE_SHARED_APIKEY_KEY = 'dedicatedApiKey', + CACHE_APIKEY_KEY = 'sharedApiKey', + CACHE_TTL_SECONDS = 604800, + + CLOUD_WALLET_GET_PROOF_REQUEST = '/multi-tenancy/proofs', + CLOUD_WALLET_CREATE_CONNECTION_INVITATION = '/multi-tenancy/create-invitation', + CLOUD_WALLET_ACCEPT_PROOF_REQUEST = '/accept-request/', + CLOUD_WALLET_DID_LIST = '/multi-tenancy/dids/', + CLOUD_WALLET_CONNECTION_BY_ID = '/multi-tenancy/connections/', + CLOUD_WALLET_CREDENTIAL = '/multi-tenancy/credentials', + CLOUD_WALLET_BASIC_MESSAGE = '/multi-tenancy/basic-messages/', + + // Bulk-issuance + BATCH_SIZE = 100, + MAX_CONCURRENT_OPERATIONS = 50, + ISSUANCE_BATCH_SIZE = 2000, + ISSUANCE_MAX_CONCURRENT_OPERATIONS = 1000, + ISSUANCE_BATCH_DELAY = 60000, //Intially 60000 + + // MICROSERVICES NAMES + API_GATEWAY_SERVICE = 'api-gateway', + ORGANIZATION_SERVICE = 'organization', + USER_SERVICE = 'user', + AUTH_SERVICE = 'authz', + FIDO_SERVICE = 'fido', + UTILITY_SERVICE = 'utilitites', + CONNECTION_SERVICE = 'connection', + LEDGER_SERVICE = 'ledger', + PLATFORM_SERVICE = 'platform', + SCHEMA_SERVICE = 'schema', + CREDENTIAL_DEFINITION_SERVICE = 'credential-definition', + AGENT_SERVICE = 'agent-service', + AGENT_PROVISIONING = 'agent-provisioning', + ISSUANCE_SERVICE = 'issuance', + VERIFICATION_SERVICE = 'verification', + WEBHOOK_SERVICE = 'webhook', + NOTIFICATION_SERVICE = 'notification', + GEO_LOCATION_SERVICE = 'geo-location', + CLOUD_WALLET_SERVICE = 'cloud-wallet', + + //CLOUD WALLET + RECEIVE_INVITATION_BY_URL = '/multi-tenancy/receive-invitation-url/', + ACCEPT_OFFER = '/multi-tenancy/credentials/accept-offer/', + SEED_LENGTH = 32, } -export const MICRO_SERVICE_NAME = Symbol('MICRO_SERVICE_NAME'); -export const ATTRIBUTE_NAME_REGEX = /\['(.*?)'\]/; - -export const postgresqlErrorCodes = []; -postgresqlErrorCodes['23503'] = 'foreign_key_violation'; -postgresqlErrorCodes['00000'] = 'successful_completion'; -postgresqlErrorCodes['01000'] = 'warning'; -postgresqlErrorCodes['0100C'] = 'dynamic_result_sets_returned'; -postgresqlErrorCodes['01008'] = 'implicit_zero_bit_padding'; -postgresqlErrorCodes['01003'] = 'null_value_eliminated_in_set_function'; -postgresqlErrorCodes['01007'] = 'privilege_not_granted'; -postgresqlErrorCodes['01006'] = 'string_data_right_truncation'; -postgresqlErrorCodes['01P01'] = 'deprecated_feature'; -postgresqlErrorCodes['02000'] = 'no_data'; - -postgresqlErrorCodes['02001'] = 'no_additional_dynamic_result_sets_returned'; -postgresqlErrorCodes['03000'] = 'sql_statement_not_yet_complete'; -postgresqlErrorCodes['08000'] = 'connection_exception'; -postgresqlErrorCodes['08003'] = 'connection_does_not_exist'; -postgresqlErrorCodes['08006'] = 'connection_failure'; -postgresqlErrorCodes['08001'] = 'sqlclient_unable_to_establish_sqlconnection'; -postgresqlErrorCodes['08004'] = 'sqlserver_rejected_establishment_of_sqlconnection'; -postgresqlErrorCodes['08007'] = 'transaction_resolution_unknown'; -postgresqlErrorCodes['08P01'] = 'protocol_violation'; -postgresqlErrorCodes['09000'] = 'triggered_action_exception'; -postgresqlErrorCodes['0A000'] = 'feature_not_supported'; -postgresqlErrorCodes['0B000'] = 'invalid_transaction_initiation'; -postgresqlErrorCodes['0F000'] = 'locator_exception'; -postgresqlErrorCodes['0F001'] = 'invalid_locator_specification'; -postgresqlErrorCodes['0L000'] = 'invalid_grantor'; -postgresqlErrorCodes['0LP01'] = 'invalid_grant_operation'; -postgresqlErrorCodes['0P000'] = 'invalid_role_specification'; -postgresqlErrorCodes['0Z000'] = 'diagnostics_exception'; -postgresqlErrorCodes['0Z002'] = 'stacked_diagnostics_accessed_without_active_handler'; -postgresqlErrorCodes['20000'] = 'case_not_found'; -postgresqlErrorCodes['21000'] = 'cardinality_violation'; -postgresqlErrorCodes['22000'] = 'data_exception'; -postgresqlErrorCodes['2202E'] = 'array_subscript_error'; -postgresqlErrorCodes['22021'] = 'character_not_in_repertoire'; -postgresqlErrorCodes['22008'] = 'datetime_field_overflow'; -postgresqlErrorCodes['22012'] = 'division_by_zero'; -postgresqlErrorCodes['22005'] = 'error_in_assignment'; -postgresqlErrorCodes['2200B'] = 'escape_character_conflict'; - -postgresqlErrorCodes['22022'] = 'indicator_overflow'; -postgresqlErrorCodes['22015'] = 'interval_field_overflow'; -postgresqlErrorCodes['2201E'] = 'invalid_argument_for_logarithm'; -postgresqlErrorCodes['22014'] = 'invalid_argument_for_ntile_function'; -postgresqlErrorCodes['22016'] = 'invalid_argument_for_nth_value_function'; -postgresqlErrorCodes['2201F'] = 'invalid_argument_for_power_function'; -postgresqlErrorCodes['2201G'] = 'invalid_argument_for_width_bucket_function'; -postgresqlErrorCodes['22018'] = 'invalid_character_value_for_cast'; -postgresqlErrorCodes['22007'] = 'invalid_datetime_format'; -postgresqlErrorCodes['22019'] = 'invalid_escape_character'; -postgresqlErrorCodes['22P02'] = 'invalid_datatype'; -postgresqlErrorCodes[''] = ''; - - -export const DISALLOWED_EMAIL_DOMAIN = [ +export const MICRO_SERVICE_NAME = Symbol('MICRO_SERVICE_NAME') +export const ATTRIBUTE_NAME_REGEX = /\['(.*?)'\]/ + +export const postgresqlErrorCodes = [] +postgresqlErrorCodes['23503'] = 'foreign_key_violation' +postgresqlErrorCodes['00000'] = 'successful_completion' +postgresqlErrorCodes['01000'] = 'warning' +postgresqlErrorCodes['0100C'] = 'dynamic_result_sets_returned' +postgresqlErrorCodes['01008'] = 'implicit_zero_bit_padding' +postgresqlErrorCodes['01003'] = 'null_value_eliminated_in_set_function' +postgresqlErrorCodes['01007'] = 'privilege_not_granted' +postgresqlErrorCodes['01006'] = 'string_data_right_truncation' +postgresqlErrorCodes['01P01'] = 'deprecated_feature' +postgresqlErrorCodes['02000'] = 'no_data' + +postgresqlErrorCodes['02001'] = 'no_additional_dynamic_result_sets_returned' +postgresqlErrorCodes['03000'] = 'sql_statement_not_yet_complete' +postgresqlErrorCodes['08000'] = 'connection_exception' +postgresqlErrorCodes['08003'] = 'connection_does_not_exist' +postgresqlErrorCodes['08006'] = 'connection_failure' +postgresqlErrorCodes['08001'] = 'sqlclient_unable_to_establish_sqlconnection' +postgresqlErrorCodes['08004'] = 'sqlserver_rejected_establishment_of_sqlconnection' +postgresqlErrorCodes['08007'] = 'transaction_resolution_unknown' +postgresqlErrorCodes['08P01'] = 'protocol_violation' +postgresqlErrorCodes['09000'] = 'triggered_action_exception' +postgresqlErrorCodes['0A000'] = 'feature_not_supported' +postgresqlErrorCodes['0B000'] = 'invalid_transaction_initiation' +postgresqlErrorCodes['0F000'] = 'locator_exception' +postgresqlErrorCodes['0F001'] = 'invalid_locator_specification' +postgresqlErrorCodes['0L000'] = 'invalid_grantor' +postgresqlErrorCodes['0LP01'] = 'invalid_grant_operation' +postgresqlErrorCodes['0P000'] = 'invalid_role_specification' +postgresqlErrorCodes['0Z000'] = 'diagnostics_exception' +postgresqlErrorCodes['0Z002'] = 'stacked_diagnostics_accessed_without_active_handler' +postgresqlErrorCodes['20000'] = 'case_not_found' +postgresqlErrorCodes['21000'] = 'cardinality_violation' +postgresqlErrorCodes['22000'] = 'data_exception' +postgresqlErrorCodes['2202E'] = 'array_subscript_error' +postgresqlErrorCodes['22021'] = 'character_not_in_repertoire' +postgresqlErrorCodes['22008'] = 'datetime_field_overflow' +postgresqlErrorCodes['22012'] = 'division_by_zero' +postgresqlErrorCodes['22005'] = 'error_in_assignment' +postgresqlErrorCodes['2200B'] = 'escape_character_conflict' + +postgresqlErrorCodes['22022'] = 'indicator_overflow' +postgresqlErrorCodes['22015'] = 'interval_field_overflow' +postgresqlErrorCodes['2201E'] = 'invalid_argument_for_logarithm' +postgresqlErrorCodes['22014'] = 'invalid_argument_for_ntile_function' +postgresqlErrorCodes['22016'] = 'invalid_argument_for_nth_value_function' +postgresqlErrorCodes['2201F'] = 'invalid_argument_for_power_function' +postgresqlErrorCodes['2201G'] = 'invalid_argument_for_width_bucket_function' +postgresqlErrorCodes['22018'] = 'invalid_character_value_for_cast' +postgresqlErrorCodes['22007'] = 'invalid_datetime_format' +postgresqlErrorCodes['22019'] = 'invalid_escape_character' +postgresqlErrorCodes['22P02'] = 'invalid_datatype' +postgresqlErrorCodes[''] = '' + +export const DISALLOWED_EMAIL_DOMAIN = [ '0x01.gq', '0x01.tk', '10mail.org', @@ -828,5 +823,5 @@ export const DISALLOWED_EMAIL_DOMAIN = [ 'zalvisual.us', 'zapto.org', 'ze.cx', - 'zeroe.ml' -]; \ No newline at end of file + 'zeroe.ml', +] diff --git a/libs/common/src/common.module.ts b/libs/common/src/common.module.ts index 2b7967c30..417113fea 100644 --- a/libs/common/src/common.module.ts +++ b/libs/common/src/common.module.ts @@ -1,11 +1,11 @@ -import { HttpModule } from '@nestjs/axios'; -import { Module } from '@nestjs/common'; +import { HttpModule } from '@nestjs/axios' +import { Module } from '@nestjs/common' -import { CommonService } from './common.service'; +import { CommonService } from './common.service' @Module({ imports: [HttpModule], providers: [CommonService], - exports: [CommonService] + exports: [CommonService], }) export class CommonModule {} diff --git a/libs/common/src/common.service.spec.ts b/libs/common/src/common.service.spec.ts index 385622c1f..f8a71da94 100644 --- a/libs/common/src/common.service.spec.ts +++ b/libs/common/src/common.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { CommonService } from './common.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { CommonService } from './common.service' describe('CommonService', () => { - let service: CommonService; + let service: CommonService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [CommonService] - }).compile(); + providers: [CommonService], + }).compile() - service = module.get(CommonService); - }); + service = module.get(CommonService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/libs/common/src/common.service.ts b/libs/common/src/common.service.ts index 68d251fce..816a06190 100644 --- a/libs/common/src/common.service.ts +++ b/libs/common/src/common.service.ts @@ -1,166 +1,169 @@ -/* 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 * as CryptoJS from 'crypto-js' -import { BadRequestException, HttpException, HttpStatus, Injectable, Logger, NotFoundException } from '@nestjs/common'; +import { BadRequestException, HttpException, HttpStatus, Injectable, Logger, NotFoundException } from '@nestjs/common' -import { CommonConstants } from './common.constant'; -import { HttpService } from '@nestjs/axios'; -import * as dotenv from 'dotenv'; -import { ResponseMessages } from './response-messages'; -import { IFormattedResponse, IOptionalParams } from './interfaces/interface'; -import { OrgAgentType } from '../../enum/src/enum'; -import { RpcException } from '@nestjs/microservices'; -dotenv.config(); +import type { HttpService } from '@nestjs/axios' +import { RpcException } from '@nestjs/microservices' +import * as dotenv from 'dotenv' +import { OrgAgentType } from '../../enum/src/enum' +import { CommonConstants } from './common.constant' +import type { IFormattedResponse, IOptionalParams } from './interfaces/interface' +import { ResponseMessages } from './response-messages' +dotenv.config() @Injectable() export class CommonService { - private readonly logger = new Logger('CommonService'); + private readonly logger = new Logger('CommonService') constructor(private readonly httpService: HttpService) {} + // biome-ignore lint/suspicious/noExplicitAny: async httpPost(url: string, payload?: any, apiKey?: any) { try { return await this.httpService .post(url, payload, apiKey) .toPromise() + // biome-ignore lint/suspicious/noExplicitAny: .then((response: any) => { - return response.data; - }); + return response.data + }) } catch (error) { - this.logger.error(`ERROR in POST : ${JSON.stringify(error)}`); - this.handleCommonErrors(error); + this.logger.error(`ERROR in POST : ${JSON.stringify(error)}`) + this.handleCommonErrors(error) } } + // biome-ignore lint/suspicious/noExplicitAny: async httpGet(url: string, config?: any) { try { return await this.httpService .get(url, config) .toPromise() - .then((data) => data.data); + .then((data) => data.data) } catch (error) { - this.logger.error(`ERROR in GET : ${JSON.stringify(error)}`); - this.handleCommonErrors(error); + this.logger.error(`ERROR in GET : ${JSON.stringify(error)}`) + this.handleCommonErrors(error) } } + // biome-ignore lint/suspicious/noExplicitAny: async httpPatch(url: string, payload?: any, apiKey?: any) { try { return await this.httpService .patch(url, payload, apiKey) .toPromise() + // biome-ignore lint/suspicious/noExplicitAny: .then((response: any) => { - return response.data; - }); + return response.data + }) } catch (error) { - this.logger.error(`ERROR in PATCH : ${JSON.stringify(error)}`); - this.handleCommonErrors(error); + this.logger.error(`ERROR in PATCH : ${JSON.stringify(error)}`) + this.handleCommonErrors(error) } } - async httpDelete(url: string, config?: unknown) { + // biome-ignore lint/suspicious/noExplicitAny: + async httpDelete(url: string, config?: unknown): Promise { try { return await this.httpService .delete(url, config) .toPromise() - .then((data) => { - return data; - }); + .then((data) => data) } catch (error) { - this.logger.error(`ERROR in DELETE : ${JSON.stringify(error.response.data)}`); - this.handleCommonErrors(error); + this.logger.error(`ERROR in DELETE : ${JSON.stringify(error.response?.data)}`) + this.handleCommonErrors(error) + throw error // rethrow to keep contract } } + // biome-ignore lint/suspicious/noExplicitAny: async httpPut(url: string, payload?: any, config?: any): Promise { try { - const response = await this.httpService.put(url, payload, config).toPromise(); + const response = await this.httpService.put(url, payload, config).toPromise() - return this.filterResponse(response); + return this.filterResponse(response) as IFormattedResponse } catch (error) { - return this.sendError(error); + return this.sendError(error) } } + // biome-ignore lint/suspicious/noExplicitAny: filterResponse(data: any) { - let response; + // biome-ignore lint/suspicious/noExplicitAny: + let response: { message: string; success: boolean; data: any } if (data.data && data.data.message !== undefined && data.data.success !== undefined) { - this.logger.debug(`CommonService: data is already a response object, return`); - response = data.data; + this.logger.debug('CommonService: data is already a response object, return') + response = data.data } else { - this.logger.debug(`CommonService: create response object: ${JSON.stringify(data?.data)}`); + this.logger.debug(`CommonService: create response object: ${JSON.stringify(data?.data)}`) // TODO: We are not using this response in the parent functions, so we can remove this response = { message: 'fetched', success: true, - data: !data.data.results ? (!data.data.result ? data.data : data.data.result) : data.data - }; + data: !data.data.results ? (!data.data.result ? data.data : data.data.result) : data.data, + } } - return response; + return response } + // biome-ignore lint/suspicious/noExplicitAny: sendError(error: any): IFormattedResponse { - this.logger.error(`in sendError: ${error} StatusCode: ${error.response?.status}`); + this.logger.error(`in sendError: ${error} StatusCode: ${error.response?.status}`) if (error.response?.status) { throw new HttpException( { statusCode: error.response.status, - error: error.response.data ? error.response.data : error.message + error: error.response.data ? error.response.data : error.message, }, error.response.status - ); - } else { - throw new HttpException( - { - statusCode: HttpStatus.INTERNAL_SERVER_ERROR, - error: error.response.data ? error.response.data : error.message - }, - HttpStatus.INTERNAL_SERVER_ERROR - ); + ) } + throw new HttpException( + { + statusCode: HttpStatus.INTERNAL_SERVER_ERROR, + error: error.response.data ? error.response.data : error.message, + }, + HttpStatus.INTERNAL_SERVER_ERROR + ) } // To validate space in string spaceValidate(text, customMessage) { - if ('' === text.toString().trim()) { - throw new BadRequestException(customMessage); + if (text.toString().trim() === '') { + throw new BadRequestException(customMessage) } } // To validate password passwordValidation(password) { const passwordRegEx = - /^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[-!@$%^*])(?=.*[!"$%*,-.\/:;=@^_])[a-zA-Z0-9!"$%*,-.\/:;=@^_]{8,}$/; + /^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[-!@$%^*])(?=.*[!"$%*,-.\/:;=@^_])[a-zA-Z0-9!"$%*,-.\/:;=@^_]{8,}$/ const defaultMessage = - 'Passwords must contain at least 8 characters, including uppercase, lowercase, numbers and special character.'; + 'Passwords must contain at least 8 characters, including uppercase, lowercase, numbers and special character.' if (!passwordRegEx.test(password.trim())) { - throw new BadRequestException(defaultMessage); + throw new BadRequestException(defaultMessage) } } // To decrypt password decryptPassword(encryptedPassword) { try { - const password = CryptoJS.AES.decrypt(encryptedPassword, process.env.CRYPTO_PRIVATE_KEY); + const password = CryptoJS.AES.decrypt(encryptedPassword, process.env.CRYPTO_PRIVATE_KEY) - const decryptedPassword = JSON.parse(password.toString(CryptoJS.enc.Utf8)); - return decryptedPassword; - } catch (error) { - throw new BadRequestException('Invalid Credentials'); + const decryptedPassword = JSON.parse(password.toString(CryptoJS.enc.Utf8)) + return decryptedPassword + } catch (_error) { + throw new BadRequestException('Invalid Credentials') } } dataEncryption(data: string) { // eslint-disable-next-line no-useless-catch try { - const encryptedToken = CryptoJS.AES.encrypt(JSON.stringify(data), process.env.CRYPTO_PRIVATE_KEY).toString(); + const encryptedToken = CryptoJS.AES.encrypt(JSON.stringify(data), process.env.CRYPTO_PRIVATE_KEY).toString() - return encryptedToken; + return encryptedToken } catch (error) { - throw error; + // biome-ignore lint/complexity/noUselessCatch: + throw error } } @@ -172,142 +175,141 @@ export class CommonService { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, - error: error.message + error: error.message, }, HttpStatus.NOT_FOUND - ); + ) } if (error.message.toString().includes(CommonConstants.RESP_ERR_HTTP_ECONNREFUSED)) { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, - error: error.message + error: error.message, }, HttpStatus.NOT_FOUND - ); + ) } if (error.toString().includes(CommonConstants.RESP_ERR_HTTP_INVALID_HEADER_VALUE)) { throw new HttpException( { statusCode: HttpStatus.UNAUTHORIZED, - error: CommonConstants.UNAUTH_MSG + error: CommonConstants.UNAUTH_MSG, }, HttpStatus.UNAUTHORIZED - ); + ) } if (error.toString().includes(CommonConstants.RESP_ERR_NOT_FOUND)) { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, - error: error.response.data ? error.response.data : error.message + error: error.response.data ? error.response.data : error.message, }, HttpStatus.NOT_FOUND - ); + ) } if (error.toString().includes(CommonConstants.RESP_BAD_REQUEST)) { throw new HttpException( { statusCode: HttpStatus.BAD_REQUEST, message: error.message, - error: error.response.data ? error.response.data : error.message + error: error.response.data ? error.response.data : error.message, }, HttpStatus.BAD_REQUEST - ); + ) } if (error.toString().includes(CommonConstants.RESP_ERR_UNPROCESSABLE_ENTITY)) { throw new HttpException( { statusCode: HttpStatus.UNPROCESSABLE_ENTITY, - error: error.response.data ? error.response.data : error.message + error: error.response.data ? error.response.data : error.message, }, HttpStatus.UNPROCESSABLE_ENTITY - ); + ) } throw new HttpException( { statusCode: error.response.status, message: error.message, - error: error.response.data ? error.response.data : error.message + error: error.response.data ? error.response.data : error.message, }, error.response.status - ); + ) } /** * This function is used to handle errors in apps with RpcException */ handleError(error): Promise { - if (error && error?.status && error?.status?.message && error?.status?.message?.error) { + if (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); + statusCode: error?.status?.code, + }) } + throw new RpcException(error.response ? error.response : error) } async checkAgentHealth(baseUrl: string, apiKey: string): Promise { if (!baseUrl || !apiKey) { - throw new BadRequestException(ResponseMessages.cloudWallet.error.agentDetails); + throw new BadRequestException(ResponseMessages.cloudWallet.error.agentDetails) } - const url = `${baseUrl}${CommonConstants.URL_AGENT_GET_ENDPOINT}`; + const url = `${baseUrl}${CommonConstants.URL_AGENT_GET_ENDPOINT}` try { const agentHealthCheck = await this.httpGet(url, { - headers: { authorization: apiKey } - }); + headers: { authorization: apiKey }, + }) if (agentHealthCheck.isInitialized) { - return true; + return true } - return false; - } catch (error) { - throw new Error(); + return false + } catch (_error) { + throw new Error() } } async createDynamicUrl(urlOptions: IOptionalParams): Promise { try { - const { alias, myDid, outOfBandId, state, theirDid, theirLabel, connectionId, threadId } = urlOptions; + const { alias, myDid, outOfBandId, state, theirDid, theirLabel, connectionId, threadId } = urlOptions // Create the dynamic URL for Search Criteria - const criteriaParams = []; + const criteriaParams = [] if (alias) { - criteriaParams.push(`alias=${alias}`); + criteriaParams.push(`alias=${alias}`) } if (myDid) { - criteriaParams.push(`myDid=${myDid}`); + criteriaParams.push(`myDid=${myDid}`) } if (outOfBandId) { - criteriaParams.push(`outOfBandId=${outOfBandId}`); + criteriaParams.push(`outOfBandId=${outOfBandId}`) } if (state) { - criteriaParams.push(`state=${state}`); + criteriaParams.push(`state=${state}`) } if (theirDid) { - criteriaParams.push(`theirDid=${theirDid}`); + criteriaParams.push(`theirDid=${theirDid}`) } if (theirLabel) { - criteriaParams.push(`theirLabel=${theirLabel}`); + criteriaParams.push(`theirLabel=${theirLabel}`) } if (threadId) { - criteriaParams.push(`threadId=${threadId}`); + criteriaParams.push(`threadId=${threadId}`) } if (connectionId) { - criteriaParams.push(`connectionId=${connectionId}`); + criteriaParams.push(`connectionId=${connectionId}`) } - if (0 < criteriaParams.length) { - const url: string = `?${criteriaParams.join('&')}`; - return url; + if (criteriaParams.length > 0) { + const url: string = `?${criteriaParams.join('&')}` + return url } - return ''; + return '' } catch (error) { - throw new Error(`Failed to create dynamic URL: ${error.message}`); + throw new Error(`Failed to create dynamic URL: ${error.message}`) } } @@ -319,32 +321,32 @@ export class CommonService { connectionId?: string ): Promise { try { - let url; + let url: string switch (label) { case 'send-basic-message': { url = orgAgentType === OrgAgentType.DEDICATED ? `${agentEndPoint}${CommonConstants.URL_SEND_BASIC_MESSAGE}`.replace('#', connectionId) : orgAgentType === OrgAgentType.SHARED - ? `${agentEndPoint}${CommonConstants.URL_SHARED_SEND_BASIC_MESSAGE}` - .replace('#', connectionId) - .replace('@', tenantId) - : null; - break; + ? `${agentEndPoint}${CommonConstants.URL_SHARED_SEND_BASIC_MESSAGE}` + .replace('#', connectionId) + .replace('@', tenantId) + : null + break } default: { - break; + break } } if (!url) { - throw new NotFoundException(ResponseMessages.issuance.error.agentUrlNotFound); + throw new NotFoundException(ResponseMessages.issuance.error.agentUrlNotFound) } - return url; + return url } catch (error) { - this.logger.error(`Error in getting basic-message Url: ${JSON.stringify(error)}`); - throw error; + this.logger.error(`Error in getting basic-message Url: ${JSON.stringify(error)}`) + throw error } } } diff --git a/libs/common/src/common.utils.ts b/libs/common/src/common.utils.ts index ed84515c3..fa4cb7408 100644 --- a/libs/common/src/common.utils.ts +++ b/libs/common/src/common.utils.ts @@ -1,23 +1,19 @@ -import { NotFoundException } from '@nestjs/common'; -import * as dotenv from 'dotenv'; -import { ResponseMessages } from './response-messages'; -import { CommonConstants } from './common.constant'; -dotenv.config(); +import { NotFoundException } from '@nestjs/common' +import * as dotenv from 'dotenv' +import { CommonConstants } from './common.constant' +import { ResponseMessages } from './response-messages' +dotenv.config() /* eslint-disable camelcase */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type -export function paginator( - items: T[], - current_page: number, - items_per_page: number -) { - const page: number = Number(current_page) || 1; - const per_page: number = Number(items_per_page) || 10; - const offset: number = (page - 1) * per_page; - const paginatedItems = items.slice(offset, offset + per_page); - const total_pages: number = Math.ceil(items.length / per_page); +export function paginator(items: T[], current_page: number, items_per_page: number) { + const page: number = Number(current_page) || 1 + const per_page: number = Number(items_per_page) || 10 + const offset: number = (page - 1) * per_page + const paginatedItems = items.slice(offset, offset + per_page) + const total_pages: number = Math.ceil(items.length / per_page) - const previousPage: number | null = 1 < page ? page - 1 : null; - const nextPage: number | null = page < total_pages ? page + 1 : null; + const previousPage: number | null = page > 1 ? page - 1 : null + const nextPage: number | null = page < total_pages ? page + 1 : null return { page, pageSize: per_page, @@ -25,8 +21,8 @@ export function paginator( nextPage, totalItems: items.length, lastPage: total_pages, - data: paginatedItems - }; + data: paginatedItems, + } } export function orderValues(key, order = 'asc') { @@ -34,40 +30,39 @@ export function orderValues(key, order = 'asc') { return function innerSort(a, b) { if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) { // property doesn't exist on either object - return 0; + return 0 } - const varA = 'string' === typeof a[key] ? a[key].toUpperCase() : a[key]; - const varB = 'string' === typeof b[key] ? b[key].toUpperCase() : b[key]; + const varA = typeof a[key] === 'string' ? a[key].toUpperCase() : a[key] + const varB = typeof b[key] === 'string' ? b[key].toUpperCase() : b[key] - let comparison = 0; + let comparison = 0 if (varA > varB) { - comparison = 1; + comparison = 1 } else if (varA < varB) { - comparison = -1; + comparison = -1 } - return 'desc' === order ? comparison * -1 : comparison; - }; + return order === 'desc' ? comparison * -1 : comparison + } } - export function convertUrlToDeepLinkUrl(url: string): string { const deepLinkDomain = process.env.DEEPLINK_DOMAIN - if(!deepLinkDomain) { + if (!deepLinkDomain) { throw new NotFoundException(ResponseMessages.shorteningUrl.error.deepLinkDomainNotFound) } - const deepLinkUrl = deepLinkDomain.concat(url); - return deepLinkUrl; + const deepLinkUrl = deepLinkDomain.concat(url) + return deepLinkUrl } export const networkNamespace = (did: string): string => { // Split the DID into segments using the colon as a delimiter - const segments = did.split(':'); - const hasPolygon = segments.some(segment => segment.includes(CommonConstants.POLYGON)); - const hasTestnet = segments.some(segment => segment.includes(CommonConstants.TESTNET)); + const segments = did.split(':') + const hasPolygon = segments.some((segment) => segment.includes(CommonConstants.POLYGON)) + const hasTestnet = segments.some((segment) => segment.includes(CommonConstants.TESTNET)) if (hasPolygon) { - return hasTestnet ? `${segments[1]}:${segments[2]}` : `${segments[1]}:${CommonConstants.MAINNET}`; + return hasTestnet ? `${segments[1]}:${segments[2]}` : `${segments[1]}:${CommonConstants.MAINNET}` } - return segments[1]; -}; \ No newline at end of file + return segments[1] +} diff --git a/libs/common/src/dtos/email.dto.ts b/libs/common/src/dtos/email.dto.ts index e395da884..6e6e1e191 100644 --- a/libs/common/src/dtos/email.dto.ts +++ b/libs/common/src/dtos/email.dto.ts @@ -1,17 +1,17 @@ export class EmailDto { - emailFrom: string; - emailTo: string; - emailSubject: string; - emailText: string; - emailHtml: string; - emailAttachments?: AttachmentJSON[]; + emailFrom: string + emailTo: string + emailSubject: string + emailText: string + emailHtml: string + emailAttachments?: AttachmentJSON[] } interface AttachmentJSON { - content: string; - filename: string; - contentType: string; - type?: string; - disposition?: string; - content_id?: string; - } \ No newline at end of file + content: string + filename: string + contentType: string + type?: string + disposition?: string + content_id?: string +} diff --git a/libs/common/src/dtos/pagination.dto.ts b/libs/common/src/dtos/pagination.dto.ts index 34995e612..f939d7bb9 100644 --- a/libs/common/src/dtos/pagination.dto.ts +++ b/libs/common/src/dtos/pagination.dto.ts @@ -1,26 +1,25 @@ -import { Type } from 'class-transformer'; -import { ApiProperty } from '@nestjs/swagger'; -import { IsNumber, IsOptional, Max, Min } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger' +import { Type } from 'class-transformer' +import { IsNumber, IsOptional, Max, Min } from 'class-validator' export class PaginationDto { - @Type(() => Number) - @ApiProperty({ required: false, default: 1 }) - @IsOptional() - @IsNumber() - @Min(1, { message: 'Page number must be greater than 0' }) - pageNumber: number = 1; + @Type(() => Number) + @ApiProperty({ required: false, default: 1 }) + @IsOptional() + @IsNumber() + @Min(1, { message: 'Page number must be greater than 0' }) + pageNumber = 1 - @ApiProperty({ required: false }) - @IsOptional() - @Type(() => String) - search: string = ''; + @ApiProperty({ required: false }) + @IsOptional() + @Type(() => String) + search = '' - @Type(() => Number) - @ApiProperty({ required: false, default: 10 }) - @IsOptional() - @IsNumber() - @Min(1, { message: 'Page size must be greater than 0' }) - @Max(100, { message: 'Page size must be less than 100' }) - pageSize: number = 10; - -} \ No newline at end of file + @Type(() => Number) + @ApiProperty({ required: false, default: 10 }) + @IsOptional() + @IsNumber() + @Min(1, { message: 'Page size must be greater than 0' }) + @Max(100, { message: 'Page size must be less than 100' }) + pageSize = 10 +} diff --git a/libs/common/src/exception-handler.ts b/libs/common/src/exception-handler.ts index 6a831f35e..70ddd2729 100644 --- a/libs/common/src/exception-handler.ts +++ b/libs/common/src/exception-handler.ts @@ -1,96 +1,91 @@ import { - ExceptionFilter, + type ArgumentsHost, Catch, - ArgumentsHost, + type ExceptionFilter, HttpException, HttpStatus, - RpcExceptionFilter, - Logger -} from '@nestjs/common'; -import { HttpAdapterHost } from '@nestjs/core'; -import { RpcException } from '@nestjs/microservices'; -import { Observable, throwError } from 'rxjs'; + Logger, + type RpcExceptionFilter, +} from '@nestjs/common' +import type { HttpAdapterHost } from '@nestjs/core' +import { RpcException } from '@nestjs/microservices' +import { type Observable, throwError } from 'rxjs' @Catch() export class AllExceptionsFilter implements ExceptionFilter { - private readonly logger = new Logger('CommonService'); - constructor(private readonly httpAdapterHost: HttpAdapterHost) { } + private readonly logger = new Logger('CommonService') + constructor(private readonly httpAdapterHost: HttpAdapterHost) {} // Add explicit types for 'exception' and 'host' - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + // biome-ignore lint/suspicious/noExplicitAny: , @typescript-eslint/explicit-module-boundary-types catch(exception: any, host: ArgumentsHost): void { + const { httpAdapter } = this.httpAdapterHost + const ctx = host.switchToHttp() + const request = ctx.getRequest() - const { httpAdapter } = this.httpAdapterHost; - const ctx = host.switchToHttp(); - const request = ctx.getRequest(); - - let httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; - let message = ''; - this.logger.error( - `AllExceptionsFilter caught error: ${JSON.stringify(exception)}` - ); + let httpStatus = HttpStatus.INTERNAL_SERVER_ERROR + let message = '' + this.logger.error(`AllExceptionsFilter caught error: ${JSON.stringify(exception)}`) switch (exception.constructor) { case HttpException: - this.logger.error(`Its HttpException`); - httpStatus = (exception as HttpException).getStatus(); - message = exception?.response?.error || exception?.message || 'Internal server error'; - break; + this.logger.error('Its HttpException') + httpStatus = (exception as HttpException).getStatus() + message = exception?.response?.error || exception?.message || 'Internal server error' + break case RpcException: - this.logger.error(`Its RpcException`); - httpStatus = exception?.code || exception?.error?.code || HttpStatus.INTERNAL_SERVER_ERROR; - message = exception?.error || exception?.error?.message?.error || 'RpcException'; - break; + this.logger.error('Its RpcException') + httpStatus = exception?.code || exception?.error?.code || HttpStatus.INTERNAL_SERVER_ERROR + message = exception?.error || exception?.error?.message?.error || 'RpcException' + break default: - this.logger.error(`Its an Unknown Exception`); - if ('Rpc Exception' === exception.message) { - this.logger.error(`RpcException`); - httpStatus = exception?.error?.code || HttpStatus.INTERNAL_SERVER_ERROR; - message = exception?.error?.message?.error || 'Internal server error'; + this.logger.error('Its an Unknown Exception') + if (exception.message === 'Rpc Exception') { + this.logger.error('RpcException') + httpStatus = exception?.error?.code || HttpStatus.INTERNAL_SERVER_ERROR + message = exception?.error?.message?.error || 'Internal server error' } else { httpStatus = - exception.response?.status || - exception.response?.statusCode || - exception.code || - exception.statusCode || - HttpStatus.INTERNAL_SERVER_ERROR; - message = - exception.response?.data?.message || - exception.response?.message || - exception?.message || - 'Internal server error'; + exception.response?.status || + exception.response?.statusCode || + exception.code || + exception.statusCode || + HttpStatus.INTERNAL_SERVER_ERROR + message = + exception.response?.data?.message || + exception.response?.message || + exception?.message || + 'Internal server error' } if (!this.isHttpErrorStatus(httpStatus)) { - this.logger.error(`httpStatus: ${httpStatus}`); - httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; + this.logger.error(`httpStatus: ${httpStatus}`) + httpStatus = HttpStatus.INTERNAL_SERVER_ERROR } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.logger.error(`Exception Filter : ${message} ${(exception as any)?.stack} ${request.method} ${request.url}`); + // biome-ignore lint/suspicious/noExplicitAny: + this.logger.error(`Exception Filter : ${message} ${(exception as any)?.stack} ${request.method} ${request.url}`) const responseBody = { statusCode: httpStatus, message, - error: exception.message - }; - httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus); - + error: exception.message, + } + httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus) } - isHttpErrorStatus(statusCode: number): boolean { - return Object.values(HttpStatus).includes(statusCode); + isHttpErrorStatus(statusCode: number): boolean { + return Object.values(HttpStatus).includes(statusCode) } - } @Catch(RpcException) export class CustomExceptionFilter implements RpcExceptionFilter { - private readonly logger = new Logger('CommonService'); + private readonly logger = new Logger('CommonService') // Add explicit types for 'exception' and 'host' - // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any - catch(exception: RpcException, host: ArgumentsHost): Observable { - this.logger.error(`CustomExceptionFilter caught error: ${JSON.stringify(exception)}`); - return throwError(() => new RpcException({ message: exception.getError(), code: HttpStatus.BAD_REQUEST })); + // biome-ignore lint/suspicious/noExplicitAny: + catch(exception: RpcException, _host: ArgumentsHost): Observable { + this.logger.error(`CustomExceptionFilter caught error: ${JSON.stringify(exception)}`) + return throwError(() => new RpcException({ message: exception.getError(), code: HttpStatus.BAD_REQUEST })) } -} \ No newline at end of file +} diff --git a/libs/common/src/index.ts b/libs/common/src/index.ts index 90573502c..f2f6a305e 100644 --- a/libs/common/src/index.ts +++ b/libs/common/src/index.ts @@ -1,3 +1,3 @@ -export * from './common.module'; -export * from './common.service'; -export * from './nats.interceptor'; +export * from './common.module' +export * from './common.service' +export * from './nats.interceptor' diff --git a/libs/common/src/interfaces/agent-service.interface.ts b/libs/common/src/interfaces/agent-service.interface.ts index 26613351d..24f951435 100644 --- a/libs/common/src/interfaces/agent-service.interface.ts +++ b/libs/common/src/interfaces/agent-service.interface.ts @@ -1,55 +1,54 @@ export interface InvitationMessage { - message: { - invitationUrl: string; - invitation: { - '@type': string; - '@id': string; - label: string; - recipientKeys: string[]; - serviceEndpoint: string; - routingKeys: string[]; - }; - outOfBandRecord: OutOfBandRecord; - recipientKey?:string - invitationDid?: string - }; + message: { + invitationUrl: string + invitation: { + '@type': string + '@id': string + label: string + recipientKeys: string[] + serviceEndpoint: string + routingKeys: string[] + } + outOfBandRecord: OutOfBandRecord + recipientKey?: string + invitationDid?: string } - - interface OutOfBandRecord { - _tags: Tags; - metadata?: { [key: string]: string }; - id: string; - createdAt: string; - outOfBandInvitation: OutOfBandInvitation; - role: string; - state: string; - autoAcceptConnection: boolean; - reusable: boolean; - updatedAt: string; - } - - interface Tags { - invitationId: string; - recipientKeyFingerprints: string[]; - role: string; - state: string; - threadId: string; - } - - interface OutOfBandInvitation { - '@type': string; - '@id': string; - label: string; - accept: string[]; - handshake_protocols: string[]; - services: OutOfBandInvitationService[]; - } - - interface OutOfBandInvitationService { - id: string; - serviceEndpoint: string; - type: string; - recipientKeys: string[]; - routingKeys: string[]; - } - \ No newline at end of file +} + +interface OutOfBandRecord { + _tags: Tags + metadata?: { [key: string]: string } + id: string + createdAt: string + outOfBandInvitation: OutOfBandInvitation + role: string + state: string + autoAcceptConnection: boolean + reusable: boolean + updatedAt: string +} + +interface Tags { + invitationId: string + recipientKeyFingerprints: string[] + role: string + state: string + threadId: string +} + +interface OutOfBandInvitation { + '@type': string + '@id': string + label: string + accept: string[] + handshake_protocols: string[] + services: OutOfBandInvitationService[] +} + +interface OutOfBandInvitationService { + id: string + serviceEndpoint: string + type: string + recipientKeys: string[] + routingKeys: string[] +} diff --git a/libs/common/src/interfaces/cloud-wallet.interface.ts b/libs/common/src/interfaces/cloud-wallet.interface.ts index f4d8ab52f..bc4662ba3 100644 --- a/libs/common/src/interfaces/cloud-wallet.interface.ts +++ b/libs/common/src/interfaces/cloud-wallet.interface.ts @@ -1,332 +1,332 @@ -import { CloudWalletType } from '../../../enum/src/enum'; -import { $Enums } from '@prisma/client'; +import type { $Enums } from '@prisma/client' +import type { CloudWalletType } from '../../../enum/src/enum' export class ICreateCloudWallet { - label: string; - connectionImageUrl?: string; - email?: string; - userId?: string; + label: string + connectionImageUrl?: string + email?: string + userId?: string } export interface ICloudWalletDetails { - label: string; - tenantId: string; - email?: string; - type: CloudWalletType; - createdBy: string; - lastChangedBy: string; - userId: string; - agentEndpoint?: string; - agentApiKey?: string; - key?: string; - connectionImageUrl?: string; + label: string + tenantId: string + email?: string + type: CloudWalletType + createdBy: string + lastChangedBy: string + userId: string + agentEndpoint?: string + agentApiKey?: string + key?: string + connectionImageUrl?: string } export interface IStoredWalletDetails { - email: string; - connectionImageUrl: string; - createDateTime: Date; - id: string; - tenantId: string; - label: string; - lastChangedDateTime: Date; + email: string + connectionImageUrl: string + createDateTime: Date + id: string + tenantId: string + label: string + lastChangedDateTime: Date } export interface IReceiveInvitation { - alias?: string; - label?: string; - imageUrl?: string; - autoAcceptConnection?: boolean; - autoAcceptInvitation?: boolean; - reuseConnection?: boolean; - acceptInvitationTimeoutMs?: number; - ourDid?: string; - invitationUrl: string; - email?: string; - userId?: string; + alias?: string + label?: string + imageUrl?: string + autoAcceptConnection?: boolean + autoAcceptInvitation?: boolean + reuseConnection?: boolean + acceptInvitationTimeoutMs?: number + ourDid?: string + invitationUrl: string + email?: string + userId?: string } export interface IAcceptOffer { - autoAcceptCredential?: string; - comment?: string; - credentialRecordId: string; - credentialFormats?: object; - email?: string; - userId?: string; + autoAcceptCredential?: string + comment?: string + credentialRecordId: string + credentialFormats?: object + email?: string + userId?: string } export interface ICreateCloudWalletDid { - seed?: string; - keyType: string; - method: string; - network?: string; - domain?: string; - role?: string; - privatekey?: string; - endpoint?: string; - did?: string; - endorserDid?: string; - email?: string; - userId?: string; + seed?: string + keyType: string + method: string + network?: string + domain?: string + role?: string + privatekey?: string + endpoint?: string + did?: string + endorserDid?: string + email?: string + userId?: string } export interface IGetStoredWalletInfo { - email: string; - userId: string; - id: string; - type: $Enums.CloudWalletType; - agentEndpoint: string; + email: string + userId: string + id: string + type: $Enums.CloudWalletType + agentEndpoint: string } export interface IConfigureCloudBaseWallet { - email: string; - walletKey: string; - apiKey: string; - agentEndpoint: string; + email: string + walletKey: string + apiKey: string + agentEndpoint: string } export interface IConfigureCloudBaseWalletPayload { - cloudBaseWalletConfigure: IConfigureCloudBaseWallet; - userId: string; + cloudBaseWalletConfigure: IConfigureCloudBaseWallet + userId: string } export interface IStoreWalletInfo { - email: string; - key: string; - agentApiKey: string; - agentEndpoint: string; - type: CloudWalletType; - userId: string; - createdBy: string; - lastChangedBy: string; + email: string + key: string + agentApiKey: string + agentEndpoint: string + type: CloudWalletType + userId: string + createdBy: string + lastChangedBy: string } export interface IGetStoredWalletInfo { - email: string; - userId: string; - id: string; - type: $Enums.CloudWalletType; - agentEndpoint: string; + email: string + userId: string + id: string + type: $Enums.CloudWalletType + agentEndpoint: string } export interface IAcceptProofRequest { - proofRecordId: string; - userId: string; - email: string; - filterByPresentationPreview?: boolean; - filterByNonRevocationRequirements?: boolean; - comment?: string; + proofRecordId: string + userId: string + email: string + filterByPresentationPreview?: boolean + filterByNonRevocationRequirements?: boolean + comment?: string } export interface IAcceptProofRequestPayload { - acceptProofRequest: IAcceptProofRequest; - userId: string; + acceptProofRequest: IAcceptProofRequest + userId: string } export interface IProofByProofId { - proofId: string; - userId: string; + proofId: string + userId: string } export interface IProofPresentation { - threadId: string; - userId: string; + threadId: string + userId: string } export interface IGetProofPresentationById { - userId: string; - email: string; - proofRecordId: string; + userId: string + email: string + proofRecordId: string } export interface IGetProofPresentation { - userId: string; - email: string; - threadId: string; + userId: string + email: string + threadId: string } export interface ICloudBaseWalletConfigure { - walletKey: string; - apiKey: string; - agentEndpoint: string; - userId: string; - email: string; + walletKey: string + apiKey: string + agentEndpoint: string + userId: string + email: string } export interface Tags { - connectionId: string; - role: string; - state: string; - threadId: string; + connectionId: string + role: string + state: string + threadId: string } export interface IProofRequestRes { - _tags: Tags; - metadata: unknown; - id: string; - createdAt: string; - protocolVersion: string; - state: string; - role: string; - connectionId: string; - threadId: string; - updatedAt: string; + _tags: Tags + metadata: unknown + id: string + createdAt: string + protocolVersion: string + state: string + role: string + connectionId: string + threadId: string + updatedAt: string } export interface CloudWallet { - id: string; - label: string; - tenantId: string; - email: string; - type: $Enums.CloudWalletType; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - userId: string; - agentEndpoint: string; - agentApiKey: string; - key: string; - connectionImageUrl: string; + id: string + label: string + tenantId: string + email: string + type: $Enums.CloudWalletType + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + userId: string + agentEndpoint: string + agentApiKey: string + key: string + connectionImageUrl: string } export interface IWalletDetailsForDidList { - userId: string; - email: string; + userId: string + email: string } export interface IConnectionDetailsById { - userId: string; - email: string; - connectionId: string; + userId: string + email: string + connectionId: string } export interface ITenantDetail { - userId?: string; - email?: string; - threadId?: string; - connectionId?: string; - state?: string; + userId?: string + email?: string + threadId?: string + connectionId?: string + state?: string } export interface ICredentialDetails { - userId: string; - email: string; - credentialRecordId: string; + userId: string + email: string + credentialRecordId: string } export interface Thread { - pthid: string; - thid: string; + pthid: string + thid: string } export interface Message { - '@type': string; - '@id': string; - '~thread': Thread; - messageType: string; + '@type': string + '@id': string + '~thread': Thread + messageType: string } export interface Data { - base64?: string; - json?: string; - links?: string[]; + base64?: string + json?: string + links?: string[] jws?: { - header: object; - signature: string; - protected: string; - }; - sha256?: string; + header: object + signature: string + protected: string + } + sha256?: string } export interface AppendedAttachment { - id: string; - description: string; - filename: string; - mimeType: string; - lastmodTime: string; - byteCount: number; - data: Data; + id: string + description: string + filename: string + mimeType: string + lastmodTime: string + byteCount: number + data: Data } export interface ICreateConnection { - label: string; - alias: string; - imageUrl: string; - multiUseInvitation: boolean; - autoAcceptConnection: boolean; - goalCode: string; - goal: string; - handshake: boolean; - handshakeProtocols: string[]; - messages: Message[]; - appendedAttachments: AppendedAttachment[]; - invitationDid: string; - recipientKey: string; - userId: string; - email: string; + label: string + alias: string + imageUrl: string + multiUseInvitation: boolean + autoAcceptConnection: boolean + goalCode: string + goal: string + handshake: boolean + handshakeProtocols: string[] + messages: Message[] + appendedAttachments: AppendedAttachment[] + invitationDid: string + recipientKey: string + userId: string + email: string } export interface Invitation { - '@type': string; - '@id': string; - label: string; - accept: string[]; - handshake_protocols: string[]; - services: Service[]; + '@type': string + '@id': string + label: string + accept: string[] + handshake_protocols: string[] + services: Service[] } export interface Service { - id: string; - type: string; - priority: number; - recipientKeys: string[]; - routingKeys: string[]; - serviceEndpoint: string; + id: string + type: string + priority: number + recipientKeys: string[] + routingKeys: string[] + serviceEndpoint: string } export interface OutOfBandRecord { - _tags: Tags; - metadata: Record; - id: string; - createdAt: string; - outOfBandInvitation: Invitation; - role: string; - state: string; - alias: string; - autoAcceptConnection: boolean; - reusable: boolean; - updatedAt: string; + _tags: Tags + metadata: Record + id: string + createdAt: string + outOfBandInvitation: Invitation + role: string + state: string + alias: string + autoAcceptConnection: boolean + reusable: boolean + updatedAt: string } export interface Tags { - recipientKeyFingerprints: string[]; + recipientKeyFingerprints: string[] } export interface IConnectionInvitationResponse { - invitationUrl: string; - invitation: Invitation; - outOfBandRecord: OutOfBandRecord; - invitationDid: string; + invitationUrl: string + invitation: Invitation + outOfBandRecord: OutOfBandRecord + invitationDid: string } export interface GetAllCloudWalletConnections { - outOfBandId?: string; - alias?: string; - myDid?: string; - theirDid?: string; - theirLabel?: string; - email?: string; - userId?: string; + outOfBandId?: string + alias?: string + myDid?: string + theirDid?: string + theirLabel?: string + email?: string + userId?: string } export interface IBasicMessage { - userId: string; - email: string; - connectionId: string; + userId: string + email: string + connectionId: string } export interface IBasicMessageDetails { - userId?: string; - email?: string; - content: string; - connectionId: string; + userId?: string + email?: string + content: string + connectionId: string } diff --git a/libs/common/src/interfaces/connection.interface.ts b/libs/common/src/interfaces/connection.interface.ts index 646b46429..476f1bbd4 100644 --- a/libs/common/src/interfaces/connection.interface.ts +++ b/libs/common/src/interfaces/connection.interface.ts @@ -1,42 +1,42 @@ 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[]; - } + 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[] +} - export interface ICreateConnectionUrl { - id: string; - orgId: string; - agentId: string; - connectionInvitation: string; - multiUse: boolean; - createDateTime: Date; - createdBy: number; - lastChangedDateTime: Date; - lastChangedBy: number; - recipientKey?:string; - invitationDid?: string +export interface ICreateConnectionUrl { + id: string + orgId: string + agentId: string + connectionInvitation: string + multiUse: boolean + createDateTime: Date + createdBy: number + lastChangedDateTime: Date + lastChangedBy: number + recipientKey?: string + invitationDid?: string } - + export interface IDeletedConnectionsRecord { - getConnectionRecords: IConnectionItem[]; + getConnectionRecords: IConnectionItem[] deleteConnectionRecords: { - count: number; - }; -} \ No newline at end of file + count: number + } +} diff --git a/libs/common/src/interfaces/cred-def.interface.ts b/libs/common/src/interfaces/cred-def.interface.ts index dc9a45f0f..b59fcc5dd 100644 --- a/libs/common/src/interfaces/cred-def.interface.ts +++ b/libs/common/src/interfaces/cred-def.interface.ts @@ -1,33 +1,32 @@ -export interface ICredDefDetails extends IPaginationDetails{ - data: ICredDefData[]; +export interface ICredDefDetails extends IPaginationDetails { + data: ICredDefData[] } export interface ICredDefData { - createDateTime: Date; - createdBy: string; - credentialDefinitionId: string; - tag: string; - schemaLedgerId: string; - schemaId: string; - orgId: string; - revocable: boolean; + createDateTime: Date + createdBy: string + credentialDefinitionId: string + tag: string + schemaLedgerId: string + schemaId: string + orgId: string + revocable: boolean } export interface IPlatformCredDefDetails { - credDefCount: number; - credDefResult: ICredDefData[]; - } + credDefCount: number + credDefResult: ICredDefData[] +} + +export interface IPaginationDetails { + 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 IPlatformCredDefsData extends IPaginationDetails{ - data: ICredDefData[]; - } - \ No newline at end of file +export interface IPlatformCredDefsData extends IPaginationDetails { + data: ICredDefData[] +} diff --git a/libs/common/src/interfaces/did.interface.ts b/libs/common/src/interfaces/did.interface.ts index 8299f06d7..9c647211f 100644 --- a/libs/common/src/interfaces/did.interface.ts +++ b/libs/common/src/interfaces/did.interface.ts @@ -1,13 +1,13 @@ export interface IDidCreate { - keyType: string; - seed?: string; - domain?: string; - network?: string; - privatekey?: string; - endpoint?: string; - method: string; - did?: string; - role?: string; - endorserDid?: string; - didDocument?: object; -} \ No newline at end of file + keyType: string + seed?: string + domain?: string + network?: string + privatekey?: string + endpoint?: string + method: string + did?: string + role?: string + endorserDid?: string + didDocument?: object +} diff --git a/libs/common/src/interfaces/geolocation.interface.ts b/libs/common/src/interfaces/geolocation.interface.ts index 3da8f1f3b..ab1c8d907 100644 --- a/libs/common/src/interfaces/geolocation.interface.ts +++ b/libs/common/src/interfaces/geolocation.interface.ts @@ -1,22 +1,22 @@ export interface CityInterface { - id: number; - name: string; - stateId: number; - stateCode: string; - countryId: number; - countryCode: string; + id: number + name: string + stateId: number + stateCode: string + countryId: number + countryCode: string } export interface CountryInterface { - id: number; - name: string; - phonecode?: string; - capital?: string; + id: number + name: string + phonecode?: string + capital?: string } export interface StateInterface { - id: number; - name: string; - countryId: number; - countryCode: string; + id: number + name: string + countryId: number + countryCode: string } diff --git a/libs/common/src/interfaces/interface.ts b/libs/common/src/interfaces/interface.ts index 4116d21f8..5e7e8d30b 100644 --- a/libs/common/src/interfaces/interface.ts +++ b/libs/common/src/interfaces/interface.ts @@ -1,63 +1,63 @@ -import { W3CSchemaDataType } from '@credebl/enum/enum'; +import type { W3CSchemaDataType } from '@credebl/enum/enum' export interface ResponseType { - statusCode: number; - message: string; - data?: Record | string; - error?: Record | string; + statusCode: number + message: string + data?: Record | string + error?: Record | string } export interface IAccessTokenData { - access_token: string; - expires_in: number; - refresh_expires_in: number; - token_type: string; - scope: string; + access_token: string + expires_in: number + refresh_expires_in: number + token_type: string + scope: string } export interface IOptionalParams { - alias?: string; - myDid?: string; - outOfBandId?: string; - state?: string; - theirDid?: string; - theirLabel?: string; - threadId?: string; - connectionId?: string; + alias?: string + myDid?: string + outOfBandId?: string + state?: string + theirDid?: string + theirLabel?: string + threadId?: string + connectionId?: string } export interface IFormattedResponse { - message: string; - data: unknown; - success: boolean; - code: number; + message: string + data: unknown + success: boolean + code: number } export interface IW3CAttributeValue { - attributeName: string; - schemaDataType: W3CSchemaDataType; - displayName: string; - isRequired: boolean; - description?: string; - minLength?: number; - maxLength?: number; - pattern?: string; - enum?: string[]; - contentEncoding?: string; - contentMediaType?: string; - minimum?: number; - maximum?: number; - exclusiveMinimum?: number; - exclusiveMaximum?: number; - multipleOf?: number; - minItems?: number; - maxItems?: number; - uniqueItems?: boolean; - items?: IW3CAttributeValue[]; - minProperties?: number; - maxProperties?: number; - additionalProperties?: boolean; - required?: string[]; - dependentRequired?: Record; - properties?: Record; + attributeName: string + schemaDataType: W3CSchemaDataType + displayName: string + isRequired: boolean + description?: string + minLength?: number + maxLength?: number + pattern?: string + enum?: string[] + contentEncoding?: string + contentMediaType?: string + minimum?: number + maximum?: number + exclusiveMinimum?: number + exclusiveMaximum?: number + multipleOf?: number + minItems?: number + maxItems?: number + uniqueItems?: boolean + items?: IW3CAttributeValue[] + minProperties?: number + maxProperties?: number + additionalProperties?: boolean + required?: string[] + dependentRequired?: Record + properties?: Record } diff --git a/libs/common/src/interfaces/issuance.interface.ts b/libs/common/src/interfaces/issuance.interface.ts index 3e9a133c3..b58b798f7 100644 --- a/libs/common/src/interfaces/issuance.interface.ts +++ b/libs/common/src/interfaces/issuance.interface.ts @@ -1,131 +1,131 @@ export interface IIssuedCredentialResponse { - createDateTime: Date; - createdBy: string; - connectionId: string; - schemaId: string; - state: string; - orgId: string; - } + 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[]; - } - interface CredentialData { - email_identifier: string; - [key: string]: string; - } - export interface IJsonldCredential { - schemaName: string; - schemaLedgerId: string; - credentialData: CredentialData - orgDid: string; - orgId: string; - isReuseConnection?: boolean; - } + totalItems: number + hasNextPage: boolean + hasPreviousPage: boolean + nextPage: number + previousPage: number + lastPage: number + data: IIssuedCredentialResponse[] +} +interface CredentialData { + email_identifier: string + [key: string]: string +} +export interface IJsonldCredential { + schemaName: string + schemaLedgerId: string + credentialData: CredentialData + orgDid: string + orgId: string + isReuseConnection?: boolean +} + +export interface ICredentialOfferResponse { + statusCode: number + message: string + data: ICredentialOfferData[] +} + +interface ICredentialOfferData { + statusCode: number + message: string + error?: string + data?: ICredentialOfferDetails +} - export interface ICredentialOfferResponse { - statusCode: number; - message: string; - data: ICredentialOfferData[]; +interface ICredentialAttribute { + 'mime-type': string + name: string + value: string +} + +interface ICredentialOfferDetails { + _tags?: { + connectionId: string + state: string + threadId: string } - - interface ICredentialOfferData { - statusCode: number; - message: string; - error?: string; - data?: ICredentialOfferDetails; + metadata?: { + '_anoncreds/credential'?: { + schemaId: string + credentialDefinitionId: string + } } - - interface ICredentialAttribute { - 'mime-type': string; - name: string; - value: string; + credentials?: unknown[] + id: string + createdAt: string + state: string + connectionId: string + threadId: string + protocolVersion: string + credentialAttributes?: ICredentialAttribute[] + autoAcceptCredential?: string + contextCorrelationId?: string +} + +interface IDeletedIssuanceRecordsCount { + count: number +} + +export interface IDeletedIssuanceRecords { + deleteResult: IDeletedIssuanceRecordsCount + recordsToDelete: IIssuedCredentialResponse[] +} + +export interface IPrettyVc { + certificate: string + size: string + orientation: string + height?: string + width?: string +} + +interface ICredentialSubject { + [key: string]: string +} + +interface ICredential { + '@context': string[] + type: string[] + issuer?: { + id: string } - - interface ICredentialOfferDetails { - _tags?: { - connectionId: string; - state: string; - threadId: string; - }; - metadata?: { - '_anoncreds/credential'?: { - schemaId: string; - credentialDefinitionId: string; - }; - }; - credentials?: unknown[]; - id: string; - createdAt: string; - state: string; - connectionId: string; - threadId: string; - protocolVersion: string; - credentialAttributes?: ICredentialAttribute[]; - autoAcceptCredential?: string; - contextCorrelationId?: string; - } - - interface IDeletedIssuanceRecordsCount { - count: number; - } - - export interface IDeletedIssuanceRecords { - deleteResult: IDeletedIssuanceRecordsCount; - recordsToDelete: IIssuedCredentialResponse[]; - } + issuanceDate?: string + credentialSubject?: ICredentialSubject +} - export interface IPrettyVc{ - certificate: string; - size: string; - orientation: string; - height?: string; - width?: string; - } +interface IOptions { + proofType: string + proofPurpose: string +} - interface ICredentialSubject { - [key: string]: string; - } - - interface ICredential { - "@context": string[]; - type: string[]; - issuer?: { - id: string; - }; - issuanceDate?: string; - credentialSubject?: ICredentialSubject; - } - - interface IOptions { - proofType: string; - proofPurpose: string; - } - - export interface ICredentialData { - emailId?: string; - connectionId?: string; - credential?: ICredential; - options?: IOptions; - } - - export interface ISchemaObject { - '$schema': string; - '$id': string; - type: string; - required: string[]; - properties: { - [key: string]: object; - }; - definitions: { - [key: string]: object; - }; - title: string; - description: string; - } \ No newline at end of file +export interface ICredentialData { + emailId?: string + connectionId?: string + credential?: ICredential + options?: IOptions +} + +export interface ISchemaObject { + $schema: string + $id: string + type: string + required: string[] + properties: { + [key: string]: object + } + definitions: { + [key: string]: object + } + title: string + description: string +} diff --git a/libs/common/src/interfaces/organization.interface.ts b/libs/common/src/interfaces/organization.interface.ts index 32d9a24d9..9511857cb 100644 --- a/libs/common/src/interfaces/organization.interface.ts +++ b/libs/common/src/interfaces/organization.interface.ts @@ -1,111 +1,109 @@ - export interface IOrganization { - id: string - createDateTime: Date - createdBy: string - lastChangedDateTime: Date - lastChangedBy: string - name: string - description: string - orgSlug: string - logoUrl: string - website: string - publicProfile: boolean - userOrgRoles: UserOrgRole[] - } - - export interface UserOrgRole { - id: string - userId: string - orgRoleId: string - orgId: string - user: User - orgRole: IOrgRoles - } - - export interface User { - email: string - username: string - id: string - firstName: string - lastName: string - isEmailVerified: boolean - } - - export interface IOrgRoles { - id: string - name: string - description: string - createDateTime: Date - createdBy: string - lastChangedDateTime: Date - lastChangedBy: string - } + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + name: string + description: string + orgSlug: string + logoUrl: string + website: string + publicProfile: boolean + userOrgRoles: UserOrgRole[] +} + +export interface UserOrgRole { + id: string + userId: string + orgRoleId: string + orgId: string + user: User + orgRole: IOrgRoles +} + +export interface User { + email: string + username: string + id: string + firstName: string + lastName: string + isEmailVerified: boolean +} + +export interface IOrgRoles { + id: string + name: string + description: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string +} export interface IOrgCredentials { - idpId?: string, - clientId: string, + idpId?: string + clientId: string clientSecret: string } export interface IOrganizationDashboard { - usersCount: number, - schemasCount: number, - credentialsCount: number, + usersCount: number + schemasCount: number + credentialsCount: number presentationsCount: number } - export interface IOrganizationInvitations { - totalPages: number; - invitations: IOrgInvitation[]; - } - - interface IOrgInvitation { - id: string, - orgId: string, - email: string, - userId: string, - status: string, - orgRoles: string[], - createDateTime: Date, - createdBy:string, - organisation: IOrganizations; - } - - interface IOrganizations { - id: string; - name: string; - logoUrl: string; - } - - export interface IDeleteOrganization { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - name: string; - description: string; - orgSlug: string; - logoUrl: string; - website: string; - publicProfile: boolean; - idpId: string; - clientId: string; - clientSecret: string; - } +export interface IOrganizationInvitations { + totalPages: number + invitations: IOrgInvitation[] +} - export interface IOrgData extends IDeleteOrganization{ - registrationNumber: string, - country: string, - city: string, - state: string - } - - export interface IOrgActivityCount { - verificationRecordsCount: number; - issuanceRecordsCount: number; - connectionRecordsCount: number; - orgUsersCount: number; - orgInvitationsCount: number; - } - \ No newline at end of file +interface IOrgInvitation { + id: string + orgId: string + email: string + userId: string + status: string + orgRoles: string[] + createDateTime: Date + createdBy: string + organisation: IOrganizations +} + +interface IOrganizations { + id: string + name: string + logoUrl: string +} + +export interface IDeleteOrganization { + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + name: string + description: string + orgSlug: string + logoUrl: string + website: string + publicProfile: boolean + idpId: string + clientId: string + clientSecret: string +} + +export interface IOrgData extends IDeleteOrganization { + registrationNumber: string + country: string + city: string + state: string +} + +export interface IOrgActivityCount { + verificationRecordsCount: number + issuanceRecordsCount: number + connectionRecordsCount: number + orgUsersCount: number + orgInvitationsCount: number +} diff --git a/libs/common/src/interfaces/response.interface.ts b/libs/common/src/interfaces/response.interface.ts index 6c1b4160a..30a4ad2af 100644 --- a/libs/common/src/interfaces/response.interface.ts +++ b/libs/common/src/interfaces/response.interface.ts @@ -1,13 +1,13 @@ export default interface IResponseType { - statusCode: number; - message?: string; - label?: string; - data?: unknown; - error?: unknown; -}; + statusCode: number + message?: string + label?: string + data?: unknown + error?: unknown +} export interface IResponse { - statusCode: number; - message: string; - label?: string; - data?: unknown; -}; + 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 2e9467280..d2e0018d3 100644 --- a/libs/common/src/interfaces/schema.interface.ts +++ b/libs/common/src/interfaces/schema.interface.ts @@ -1,118 +1,115 @@ - export interface IPaginationDetails { - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; + totalItems: number + hasNextPage: boolean + hasPreviousPage: boolean + nextPage: number + previousPage: number + lastPage: number } +export interface ISchemasWithPagination extends IPaginationDetails { + data: ISchemaData[] +} -export interface ISchemasWithPagination extends IPaginationDetails{ - data: ISchemaData[]; - } +export interface ISchemaData extends ISchema { + orgId: string +} - export interface ISchemaData extends ISchema { - orgId: string; - } +export interface ISchemaDetails extends IPaginationDetails { + data: ISchema[] +} - export interface ISchemaDetails extends IPaginationDetails{ - data: ISchema[]; +export interface IW3CSchema { + response: { + did: string + schemaId: string + schemaTxnHash: string + resourceTxnHash: string } +} +interface ISchema { + createDateTime: Date + createdBy: string + name: string + schemaLedgerId: string + version: string + attributes: string + publisherDid: string + issuerId: string +} - export interface IW3CSchema { - response: { - did: string, - schemaId: string, - schemaTxnHash: string, - resourceTxnHash: string - } - } - interface ISchema { - createDateTime: Date; - createdBy: string; - name: string; - schemaLedgerId: string; - version: string; - attributes: string; - publisherDid: string; - issuerId: string; - } - - interface Attribute { - attributeName: string; - schemaDataType: string; - displayName: string; - isRequired: boolean; - } - - export interface ISchemaDetail { - id: string; - createDateTime: string; - createdBy: string; - lastChangedDateTime: string; - lastChangedBy: string; - name: string; - version: string; - attributes: Attribute[]; - schemaLedgerId: string; - publisherDid: string; - issuerId: string; - orgId: string; - ledgerId: string; - type: string; - isSchemaArchived: boolean, - organisation: { - name: string - } - } +interface Attribute { + attributeName: string + schemaDataType: string + displayName: string + isRequired: boolean +} - export interface IPlatformSchemas { - schemasCount: number; - schemasResult: ISchemaData[]; - } - - export interface ICredDefData { - tag: string; - credentialDefinitionId: string; - schemaLedgerId: string; - revocable: boolean; - createDateTime?: Date; - } - - export interface ICredDefWithPagination extends IPaginationDetails{ - data: ICredDefData[]; +export interface ISchemaDetail { + id: string + createDateTime: string + createdBy: string + lastChangedDateTime: string + lastChangedBy: string + name: string + version: string + attributes: Attribute[] + schemaLedgerId: string + publisherDid: string + issuerId: string + orgId: string + ledgerId: string + type: string + isSchemaArchived: boolean + organisation: { + name: string } +} - export interface ICredDefWithCount { - credDefCount: number; - credDefResult: ICredDefData[]; - } +export interface IPlatformSchemas { + schemasCount: number + schemasResult: ISchemaData[] +} - export interface INetworkUrl { - networkUrl: string; - } +export interface ICredDefData { + tag: string + credentialDefinitionId: string + schemaLedgerId: string + revocable: boolean + createDateTime?: Date +} - export interface ISchemaFields { - name?: string; - schemaName?: string; - attributes?: IIndySchemaAttributesValue[]; - schemaAttributes?: IW3CSchemaAttributesValue[]; - endorse?: boolean; - version?: string; - did?: string; - description?: string; - } +export interface ICredDefWithPagination extends IPaginationDetails { + data: ICredDefData[] +} - interface IIndySchemaAttributesValue { - attributeName: string; - schemaDataType: string; - displayName: string; - } - - interface IW3CSchemaAttributesValue { - title: string; - type: string; - } - +export interface ICredDefWithCount { + credDefCount: number + credDefResult: ICredDefData[] +} + +export interface INetworkUrl { + networkUrl: string +} + +export interface ISchemaFields { + name?: string + schemaName?: string + attributes?: IIndySchemaAttributesValue[] + schemaAttributes?: IW3CSchemaAttributesValue[] + endorse?: boolean + version?: string + did?: string + description?: string +} + +interface IIndySchemaAttributesValue { + attributeName: string + schemaDataType: string + displayName: string +} + +interface IW3CSchemaAttributesValue { + title: string + type: string +} diff --git a/libs/common/src/interfaces/user.interface.ts b/libs/common/src/interfaces/user.interface.ts index 998be0e70..09e6be50a 100644 --- a/libs/common/src/interfaces/user.interface.ts +++ b/libs/common/src/interfaces/user.interface.ts @@ -1,53 +1,53 @@ export interface ISignInUser { - access_token: string; - token_type?: string; - expires_in?: number; - expires_at?: number; - refresh_token?: string; - isRegisteredToSupabase?: boolean; - } - export interface IVerifyUserEmail{ - email: string; - verificationCode: string; - } - export interface ISendVerificationEmail { - email: string; - clientId?: string; - clientSecret?: string; - username?: string; - brandLogoUrl?: string; - platformName?: string; - } - - 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; - } - - export interface IResetPasswordResponse { - id: string; - email: string; - } + access_token: string + token_type?: string + expires_in?: number + expires_at?: number + refresh_token?: string + isRegisteredToSupabase?: boolean +} +export interface IVerifyUserEmail { + email: string + verificationCode: string +} +export interface ISendVerificationEmail { + email: string + clientId?: string + clientSecret?: string + username?: string + brandLogoUrl?: string + platformName?: string +} + +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 +} + +export interface IResetPasswordResponse { + id: string + email: string +} export interface ISignUpUserResponse { userId: string -} \ No newline at end of file +} diff --git a/libs/common/src/interfaces/verification.interface.ts b/libs/common/src/interfaces/verification.interface.ts index 762512cbd..df4f1d91c 100644 --- a/libs/common/src/interfaces/verification.interface.ts +++ b/libs/common/src/interfaces/verification.interface.ts @@ -1,62 +1,62 @@ -import { Prisma } from '@prisma/client'; +import type { Prisma } from '@prisma/client' export interface IProofPresentationsListCount { - proofRequestsCount: number; - proofRequestsList: IProofPresentationItem[]; + proofRequestsCount: number + proofRequestsList: IProofPresentationItem[] } export interface IProofPresentationItem { - id: string; - createDateTime: Date; - createdBy: string; - connectionId: string; - state: string; - orgId: string; - presentationId: string; - schemaId?: string; - emailId?: string; + id: string + createDateTime: Date + createdBy: string + connectionId: string + state: string + orgId: string + presentationId: string + schemaId?: string + emailId?: string } export interface IProofPresentationList { - totalItems: number; - hasNextPage: boolean; - hasPreviousPage: boolean; - nextPage: number; - previousPage: number; - lastPage: number; - data: IProofPresentationItem[]; + totalItems: number + hasNextPage: boolean + hasPreviousPage: boolean + nextPage: number + previousPage: number + lastPage: number + data: IProofPresentationItem[] } export interface IProofPresentationDetails { - [key: string]: string; - credDefId?: string; - schemaId: string; - certificateTemplate?: string; + [key: string]: string + credDefId?: string + schemaId: string + certificateTemplate?: string } export interface IVerificationRecords { - deleteResult: Prisma.BatchPayload; - recordsToDelete: IRecords[]; + deleteResult: Prisma.BatchPayload + recordsToDelete: IRecords[] } interface IRecords { - id: string; - createDateTime: Date; - createdBy: string; - lastChangedDateTime: Date; - lastChangedBy: string; - connectionId: string; - orgId: string; - presentationId: string; - isVerified: boolean; - threadId: string; - state: string; + id: string + createDateTime: Date + createdBy: string + lastChangedDateTime: Date + lastChangedBy: string + connectionId: string + orgId: string + presentationId: string + isVerified: boolean + threadId: string + state: string } // TODO: Need to check if this is a duplicate export interface IProofRequestAttribute { - attributeName?: string; - attributeNames?: string[]; - condition?: string; - value?: string; - credDefId?: string; - schemaId?: string; - credentialName?: string; + attributeName?: string + attributeNames?: string[] + condition?: string + value?: string + credDefId?: string + schemaId?: string + credentialName?: string } diff --git a/libs/common/src/interfaces/webhook.interface.ts b/libs/common/src/interfaces/webhook.interface.ts index c483444d6..cc2b9567e 100644 --- a/libs/common/src/interfaces/webhook.interface.ts +++ b/libs/common/src/interfaces/webhook.interface.ts @@ -1,4 +1,4 @@ export interface IWebhookUrl { - orgId?: string; - tenantId?: string; - } \ No newline at end of file + orgId?: string + tenantId?: string +} diff --git a/libs/common/src/nats.config.ts b/libs/common/src/nats.config.ts index 7fd1ff011..a75633335 100644 --- a/libs/common/src/nats.config.ts +++ b/libs/common/src/nats.config.ts @@ -1,28 +1,28 @@ -import { NATSReconnects } from '../../enum/src/enum'; -import { Authenticator, nkeyAuthenticator } from 'nats'; +import { type Authenticator, nkeyAuthenticator } from 'nats' +import { NATSReconnects } from '../../enum/src/enum' export const getNatsOptions = ( serviceName: string, nkeySeed?: string ): { - servers: string[]; - authenticator?: Authenticator; - maxReconnectAttempts: NATSReconnects; - reconnectTimeWait: NATSReconnects; - queue?: string; + servers: string[] + authenticator?: Authenticator + maxReconnectAttempts: NATSReconnects + reconnectTimeWait: NATSReconnects + queue?: string } => { const baseOptions = { servers: `${process.env.NATS_URL}`.split(','), maxReconnectAttempts: NATSReconnects.maxReconnectAttempts, reconnectTimeWait: NATSReconnects.reconnectTimeWait, - queue: serviceName - }; + queue: serviceName, + } if (nkeySeed) { return { ...baseOptions, - authenticator: nkeyAuthenticator(new TextEncoder().encode(nkeySeed)) - }; + authenticator: nkeyAuthenticator(new TextEncoder().encode(nkeySeed)), + } } - return baseOptions; -}; + return baseOptions +} diff --git a/libs/common/src/nats.interceptor.ts b/libs/common/src/nats.interceptor.ts index a26c54faf..29b8dd774 100644 --- a/libs/common/src/nats.interceptor.ts +++ b/libs/common/src/nats.interceptor.ts @@ -1,21 +1,28 @@ -import { ResponseMessages } from '@credebl/common/response-messages'; -import { CallHandler, ExecutionContext, Injectable, NestInterceptor, HttpException, Logger } from '@nestjs/common'; -import { Observable, throwError } from 'rxjs'; -import { catchError } from 'rxjs/operators'; +import { ResponseMessages } from '@credebl/common/response-messages' +import { + type CallHandler, + type ExecutionContext, + HttpException, + Injectable, + Logger, + type NestInterceptor, +} from '@nestjs/common' +import { type Observable, throwError } from 'rxjs' +import { catchError } from 'rxjs/operators' @Injectable() export class NatsInterceptor implements NestInterceptor { - private readonly logger = new Logger(NatsInterceptor.name); + private readonly logger = new Logger(NatsInterceptor.name) - intercept(context: ExecutionContext, next: CallHandler): Observable { + intercept(_context: ExecutionContext, next: CallHandler): Observable { return next.handle().pipe( catchError((error) => { - if (error?.message && error?.message.includes(ResponseMessages.nats.error.natsConnect)) { - this.logger.error(`No subscribers for message: ${error.message}`); - return throwError(() => new HttpException(ResponseMessages.nats.error.noSubscribers, 500)); + if (error?.message?.includes(ResponseMessages.nats.error.natsConnect)) { + this.logger.error(`No subscribers for message: ${error.message}`) + return throwError(() => new HttpException(ResponseMessages.nats.error.noSubscribers, 500)) } - return throwError(() => error); + return throwError(() => error) }) - ); + ) } } diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 7771d1244..c3babe6b2 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -23,7 +23,7 @@ export const ResponseMessages = { refreshToken: 'Token details fetched successfully', countriesVerificationCode: 'All countries has been fetched successfully', stateVerificationCode: 'All states has been fetched successfully', - cityVerificationCode: 'All cities has been fetched successfully' + cityVerificationCode: 'All cities has been fetched successfully', }, error: { exists: 'User already exists', @@ -61,8 +61,8 @@ export const ResponseMessages = { invalidResetLink: 'Invalid or expired reset password link', invalidAccessToken: 'Authentication failed', invalidRefreshToken: 'Invalid refreshToken provided', - userOrgsLimit: 'Limit reached: You can be associated with or create maximum 10 organizations.' - } + userOrgsLimit: 'Limit reached: You can be associated with or create maximum 10 organizations.', + }, }, organisation: { success: { @@ -85,7 +85,7 @@ export const ResponseMessages = { orgDids: 'Organization DIDs fetched successfully', primaryDid: 'Primary DID updated successfully', didDetails: 'DID Details updated sucessfully', - getOrganizationActivity: 'Organization activity count fetched successfully' + getOrganizationActivity: 'Organization activity count fetched successfully', }, error: { exists: 'An organization name is already exist', @@ -118,8 +118,8 @@ export const ResponseMessages = { primaryDid: 'This DID is already set to primary DID', didNotFound: 'DID does not exist in organiation', organizationNotFound: 'Organization not found', - MaximumOrgsLimit: 'Limit reached: You can be associated with or create maximum 10 organizations.' - } + MaximumOrgsLimit: 'Limit reached: You can be associated with or create maximum 10 organizations.', + }, }, fido: { @@ -130,7 +130,7 @@ export const ResponseMessages = { generateAuthenticationOption: 'Authentication option generated successfully', deleteDevice: 'Device deleted successfully', updateDeviceName: 'Device name updated successfully', - login: 'User login successfully' + login: 'User login successfully', }, error: { exists: 'User already exists', @@ -141,15 +141,15 @@ export const ResponseMessages = { deviceNotFound: 'Device does not exist or revoked', updateFidoUser: 'Error in updating fido user.', invalidCredentials: 'Invalid Credentials', - registerFido: 'Please complete your fido registration' - } + registerFido: 'Please complete your fido registration', + }, }, schema: { success: { fetch: 'Schema retrieved successfully.', create: 'Schema created successfully.', - update: 'Schema updated successfully' + update: 'Schema updated successfully', }, error: { invalidSchemaId: 'Please provide valid schema Id', @@ -175,14 +175,14 @@ export const ResponseMessages = { W3CSchemaNotFOund: 'Error while resolving W3C schema', storeW3CSchema: 'Error while storing W3C schema', networkNotFound: 'Error while fetching network', - orgDidAndSchemaType: 'Organization DID and schema type does not match' - } + orgDidAndSchemaType: 'Organization DID and schema type does not match', + }, }, credentialDefinition: { success: { fetch: 'Credential definition fetched successfully.', create: 'Credential definition created successfully.', - template: 'Credential template fetched successfully.' + template: 'Credential template fetched successfully.', }, error: { NotFound: 'No credential definitions found.', @@ -192,18 +192,18 @@ export const ResponseMessages = { isRequired: 'Credential definition Id is required', OrgDidNotFound: 'OrgDid not found', credDefIdNotFound: 'Credential Definition Id not found', - InvalidSchemaType: 'Invalid schema type or not supported yet' - } + InvalidSchemaType: 'Invalid schema type or not supported yet', + }, }, ledger: { success: { fetch: 'Ledger details retrieved successfully.', - fetchNetworkUrl: 'Network url retrieved successfully' + fetchNetworkUrl: 'Network url retrieved successfully', }, error: { NotFound: 'No ledgers found.', - indyNamespaceisRequired: 'indyNamespace is a required' - } + indyNamespaceisRequired: 'indyNamespace is a required', + }, }, agent: { success: { @@ -215,7 +215,7 @@ export const ResponseMessages = { webhookUrlRegister: 'Webhook Url registered successfully', getWebhookUrl: 'Webhook Url fetched successfully', createKeys: 'Key-pair created successfully', - walletDelete: 'The wallet has been deleted.' + walletDelete: 'The wallet has been deleted.', }, error: { exists: 'An agent name is already exist', @@ -267,8 +267,8 @@ export const ResponseMessages = { requiredEndorserDid: 'Role or endorser DID is required', requiredPrivateKey: 'Privatekey is required for polygon method', privateKeyLength: 'Private key must be exactly 64 characters long', - requiredSeed: 'Seed is required' - } + requiredSeed: 'Seed is required', + }, }, connection: { success: { @@ -279,7 +279,7 @@ export const ResponseMessages = { questionAnswerRecord: 'Question Answer record fetched successfully', questionSend: 'Question sent successfully', deleteConnectionRecord: 'Connection records deleted', - basicMessage: 'Basic message sent successfully' + basicMessage: 'Basic message sent successfully', }, error: { invalidConnectionId: 'Invalid format for connectionId', @@ -288,8 +288,8 @@ export const ResponseMessages = { agentEndPointNotFound: 'agentEndPoint Not Found', agentUrlNotFound: 'agent url not found', connectionRecordNotFound: 'Connection records does not exists', - removeConnectionReferences: 'First you have to remove credentials data and verification data' - } + removeConnectionReferences: 'First you have to remove credentials data and verification data', + }, }, issuance: { success: { @@ -303,7 +303,7 @@ export const ResponseMessages = { notFound: 'Schema records not found', bulkProcess: 'Process initiated for bulk issuance', deleteIssuanceRecords: 'Issuance records deleted', - fileDetailsAndFileData: 'File details and File data fetched successfully' + fileDetailsAndFileData: 'File details and File data fetched successfully', }, error: { invalidCredentialRecordId: 'Please provide valid credential Record Id', @@ -340,8 +340,8 @@ export const ResponseMessages = { storeBulkData: 'Error while storing the bulk deata', issuanceRecordsNotFound: 'Issuance records does not exists', removeIssuanceData: 'First you have to remove issuance data', - ledgerMismatched: `Organization ledger mismatch detected. This template cannot be used. Please use a template created with the organization's specific ledger` - } + ledgerMismatched: `Organization ledger mismatch detected. This template cannot be used. Please use a template created with the organization's specific ledger`, + }, }, verification: { success: { @@ -350,7 +350,7 @@ export const ResponseMessages = { verifiedProofDetails: 'Proof presentation details fetched successfully.', send: 'Proof request send successfully.', verified: 'Proof presentation verified successfully.', - deleteVerificationRecord: 'Verification records deleted' + deleteVerificationRecord: 'Verification records deleted', }, error: { notFound: 'Organization agent not found', @@ -368,14 +368,14 @@ export const ResponseMessages = { emailSend: 'Unable to send email to the user', verificationRecordsNotFound: 'Verification records does not exists', removeVerificationData: 'First you have to remove verification data', - uniqueAttributes: 'Please provide unique attribute names' - } + uniqueAttributes: 'Please provide unique attribute names', + }, }, bulkIssuance: { success: { create: 'Issuance process initiated successfully', - reinitiated: 'Process reinitiated for bulk issuance' + reinitiated: 'Process reinitiated for bulk issuance', }, error: { PathNotFound: 'Path to export data not found.', @@ -389,8 +389,8 @@ export const ResponseMessages = { fileDetailsNotFound: 'File details not found.', emptyFile: 'File data is empty', emptyheader: 'File header is empty', - invalidEmails: 'Invalid emails found in the chosen file' - } + invalidEmails: 'Invalid emails found in the chosen file', + }, }, errorMessages: { forbidden: 'Forbidden Resource', @@ -398,54 +398,54 @@ export const ResponseMessages = { conflict: 'Conflict', notAcceptable: 'Not Acceptable', notFound: 'Not Found', - serverError: 'Internal Server error' + serverError: 'Internal Server error', }, webhook: { success: { webhookUrlRegister: 'Webhook Url registered successfully', - getWebhookUrl: 'Webhook Url fetched successfully' + getWebhookUrl: 'Webhook Url fetched successfully', }, error: { registerWebhook: 'Unable to register a webhook url', webhookResponse: 'Error in sending webhook response to org webhook url', - notFound: 'Webhook url not found' - } + notFound: 'Webhook url not found', + }, }, shorteningUrl: { success: { getshorteningUrl: 'Shortening Url fetched successfully', - createShorteningUrl: 'Shortening Url created successfully' + createShorteningUrl: 'Shortening Url created successfully', }, error: { - deepLinkDomainNotFound: 'Deeplink Domain not found. Please make sure to add it in your environment variables' - } + deepLinkDomainNotFound: 'Deeplink Domain not found. Please make sure to add it in your environment variables', + }, }, notification: { success: { register: 'Notification webhook registration process completed successfully', - sendNotification: 'Notification sent successfully' + sendNotification: 'Notification sent successfully', }, error: { notFound: 'Notification record not found.', - invalidUrl: 'Invalid URL' - } + invalidUrl: 'Invalid URL', + }, }, storeObject: { success: { - storeObject: 'Data stored successfully' - } + storeObject: 'Data stored successfully', + }, }, geolocation: { success: { countriesVerificationCode: 'All countries has been fetched successfully', stateVerificationCode: 'All states has been fetched successfully', - cityVerificationCode: 'All cities has been fetched successfully' + cityVerificationCode: 'All cities has been fetched successfully', }, error: { stateNotFound: 'No states found for provided countryId.Please provide valid countryId', - citiesNotFound: 'No cities found for provided stateId and countryId.Please provide valid stateId and countryId' - } + citiesNotFound: 'No cities found for provided stateId and countryId.Please provide valid stateId and countryId', + }, }, cloudWallet: { success: { @@ -462,7 +462,7 @@ export const ResponseMessages = { credentials: 'Credentials fetched successfully', credentialByRecordId: 'Credential fetched successfully', connectionList: 'Connection list fetched successfully', - basicMessageByConnectionId: 'Basic message fetched successfully' + basicMessageByConnectionId: 'Basic message fetched successfully', }, error: { baseWalletNotFound: 'Base wallet configuration not found', @@ -478,15 +478,15 @@ export const ResponseMessages = { agentAlreadyExist: 'Agent already exist.', platformAdminRecordNotFound: 'Platform admin reocrd not exist.', notFoundBaseWallet: 'The base wallet record is missing.', - walletRecordNotFound: 'Wallet record not found.' - } + walletRecordNotFound: 'Wallet record not found.', + }, }, nats: { success: {}, error: { noSubscribers: 'No subscribers for the requested message. Error while connecting to NATS, service might not be started', - natsConnect: 'Empty response. There are no subscribers listening to that message' - } - } -}; + natsConnect: 'Empty response. There are no subscribers listening to that message', + }, + }, +} diff --git a/libs/common/src/send-grid-helper-file.ts b/libs/common/src/send-grid-helper-file.ts index 623d118e1..2fa50ec47 100644 --- a/libs/common/src/send-grid-helper-file.ts +++ b/libs/common/src/send-grid-helper-file.ts @@ -1,12 +1,10 @@ -import * as sendgrid from '@sendgrid/mail'; -import * as dotenv from 'dotenv'; -import { EmailDto } from './dtos/email.dto'; +import * as sendgrid from '@sendgrid/mail' +import * as dotenv from 'dotenv' +import type { EmailDto } from './dtos/email.dto' -dotenv.config(); +dotenv.config() -sendgrid.setApiKey( - process.env.SENDGRID_API_KEY -); +sendgrid.setApiKey(process.env.SENDGRID_API_KEY) export const sendEmail = async (EmailDto: EmailDto): Promise => { try { @@ -16,12 +14,13 @@ export const sendEmail = async (EmailDto: EmailDto): Promise => { subject: EmailDto.emailSubject, text: EmailDto.emailText, html: EmailDto.emailHtml, - attachments: EmailDto.emailAttachments - }; - return await sendgrid.send(msg).then(() => true).catch(() => false); - - } catch (error) { - return false; + attachments: EmailDto.emailAttachments, + } + return await sendgrid + .send(msg) + .then(() => true) + .catch(() => false) + } catch (_error) { + return false } - -}; +} diff --git a/libs/common/src/validator.ts b/libs/common/src/validator.ts index 3de39afb0..178e55fca 100644 --- a/libs/common/src/validator.ts +++ b/libs/common/src/validator.ts @@ -1,70 +1,71 @@ -import { DidMethod } from '../../enum/src/enum'; -import { IDidCreate } from './interfaces/did.interface'; -import { BadRequestException } from '@nestjs/common'; -import { ResponseMessages } from './response-messages'; -import { IProofRequestAttribute } from './interfaces/verification.interface'; +import { BadRequestException } from '@nestjs/common' +import { DidMethod } from '../../enum/src/enum' +import type { IDidCreate } from './interfaces/did.interface' +import type { IProofRequestAttribute } from './interfaces/verification.interface' +import { ResponseMessages } from './response-messages' +// biome-ignore lint/complexity/noStaticOnlyClass: export class Validator { static validateDid(createDid: IDidCreate): void { - const errors = []; + const errors = [] switch (true) { case DidMethod.WEB === createDid.method && !createDid.domain: - errors.push(ResponseMessages.agent.error.requiredDomain); - break; + errors.push(ResponseMessages.agent.error.requiredDomain) + break case (createDid.method === DidMethod.INDY || createDid.method === DidMethod.POLYGON) && !createDid.network: - errors.push(ResponseMessages.agent.error.requiredNetwork); - break; + errors.push(ResponseMessages.agent.error.requiredNetwork) + break case (createDid.method === DidMethod.INDY || createDid.method === DidMethod.POLYGON) && - 'ed25519' !== createDid.keyType: - errors.push(ResponseMessages.agent.error.keyType); - break; + createDid.keyType !== 'ed25519': + errors.push(ResponseMessages.agent.error.keyType) + break case (createDid.method === DidMethod.WEB || createDid.method === DidMethod.KEY) && - !('ed25519' === createDid.keyType || 'bls12381g2' === createDid.keyType): - errors.push(ResponseMessages.agent.error.keyTypeWeb); - break; + !(createDid.keyType === 'ed25519' || createDid.keyType === 'bls12381g2'): + errors.push(ResponseMessages.agent.error.keyTypeWeb) + break case DidMethod.INDY === createDid.method && !(createDid.role || createDid.endorserDid): - errors.push(ResponseMessages.agent.error.requiredEndorserDid); - break; + errors.push(ResponseMessages.agent.error.requiredEndorserDid) + break case DidMethod.POLYGON === createDid.method && !createDid.privatekey: - errors.push(ResponseMessages.agent.error.requiredPrivateKey); - break; - case DidMethod.POLYGON === createDid.method && createDid.privatekey && 64 !== createDid.privatekey.length: - errors.push(ResponseMessages.agent.error.privateKeyLength); - break; + errors.push(ResponseMessages.agent.error.requiredPrivateKey) + break + case DidMethod.POLYGON === createDid.method && createDid.privatekey && createDid.privatekey.length !== 64: + errors.push(ResponseMessages.agent.error.privateKeyLength) + break case (DidMethod.INDY === createDid.method || DidMethod.KEY === createDid.method || DidMethod.WEB === createDid.method) && !createDid.seed: - errors.push(ResponseMessages.agent.error.requiredSeed); - break; + errors.push(ResponseMessages.agent.error.requiredSeed) + break default: - break; + break } - if (0 < errors.length) { - throw new BadRequestException(errors); + if (errors.length > 0) { + throw new BadRequestException(errors) } } static validateIndyProofAttributes(attributes: IProofRequestAttribute[]): void { - const seenAttributes = new Map(); + const seenAttributes = new Map() for (const attribute of attributes) { const key = attribute.schemaId || attribute.credDefId ? `${attribute.schemaId || ''}:${attribute.credDefId || ''}` - : 'default'; + : 'default' if (!seenAttributes.has(key)) { - seenAttributes.set(key, new Set()); + seenAttributes.set(key, new Set()) } - const attributeNames = seenAttributes.get(key); + const attributeNames = seenAttributes.get(key) if (attributeNames.has(attribute.attributeName)) { - throw new BadRequestException(ResponseMessages.verification.error.uniqueAttributes); + throw new BadRequestException(ResponseMessages.verification.error.uniqueAttributes) } - attributeNames.add(attribute.attributeName); + attributeNames.add(attribute.attributeName) } } } diff --git a/libs/common/tsconfig.json b/libs/common/tsconfig.json index 6a8e212c8..9607e81fc 100644 --- a/libs/common/tsconfig.json +++ b/libs/common/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "declaration": true, + "declaration": true } } diff --git a/libs/config/src/config.module.ts b/libs/config/src/config.module.ts index dc9972dcb..c81b772a0 100644 --- a/libs/config/src/config.module.ts +++ b/libs/config/src/config.module.ts @@ -1,16 +1,16 @@ -import { Global, Module } from '@nestjs/common'; -import { ConfigModule as NestConfigModule } from '@nestjs/config'; -import { ConfigService } from './config.service'; +import { Global, Module } from '@nestjs/common' +import { ConfigModule as NestConfigModule } from '@nestjs/config' +import { ConfigService } from './config.service' @Global() @Module({ imports: [ NestConfigModule.forRoot({ - isGlobal: true - }) + isGlobal: true, + }), ], controllers: [], providers: [ConfigService], - exports: [ConfigService] + exports: [ConfigService], }) export class ConfigModule {} diff --git a/libs/config/src/config.service.ts b/libs/config/src/config.service.ts index f94305b82..7ebcdc6fb 100644 --- a/libs/config/src/config.service.ts +++ b/libs/config/src/config.service.ts @@ -1,28 +1,28 @@ -import { DevelopmentEnvironment } from '@credebl/enum/enum'; -import { Injectable } from '@nestjs/common'; -import { ConfigService as NestConfigService } from '@nestjs/config'; +import { DevelopmentEnvironment } from '@credebl/enum/enum' +import { Injectable } from '@nestjs/common' +import type { ConfigService as NestConfigService } from '@nestjs/config' @Injectable() export class ConfigService { constructor(private readonly configService: NestConfigService) {} get isProduction(): boolean { - return DevelopmentEnvironment.PRODUCTION === this.environment; + return DevelopmentEnvironment.PRODUCTION === this.environment } get isDevelopment(): boolean { - return DevelopmentEnvironment.DEVELOPMENT === this.environment; + return DevelopmentEnvironment.DEVELOPMENT === this.environment } get isTest(): boolean { - return DevelopmentEnvironment.TEST === this.environment; + return DevelopmentEnvironment.TEST === this.environment } get slackWebhookUrl(): string { - return this.configService.get('SLACK_INC_WEBHOOK_URL'); + return this.configService.get('SLACK_INC_WEBHOOK_URL') } private get environment(): string { - return this.configService.get('NODE_ENV'); + return this.configService.get('NODE_ENV') } } diff --git a/libs/config/src/global-config.module.ts b/libs/config/src/global-config.module.ts index ecc5f8750..a914c176f 100644 --- a/libs/config/src/global-config.module.ts +++ b/libs/config/src/global-config.module.ts @@ -1,14 +1,14 @@ -import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; -import { Module, Global } from '@nestjs/common'; +import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import { Global, Module } from '@nestjs/common' @Global() @Module({ providers: [ { provide: MICRO_SERVICE_NAME, - useValue: 'DefaultServiceName' - } + useValue: 'DefaultServiceName', + }, ], - exports: [MICRO_SERVICE_NAME] + exports: [MICRO_SERVICE_NAME], }) -export class GlobalConfigModule {} \ No newline at end of file +export class GlobalConfigModule {} diff --git a/libs/config/src/index.ts b/libs/config/src/index.ts index 8d518dbf6..17b6f8231 100644 --- a/libs/config/src/index.ts +++ b/libs/config/src/index.ts @@ -1,3 +1,3 @@ -export * from './config.service'; -export * from './config.module'; -export * from './global-config.module'; \ No newline at end of file +export * from './config.service' +export * from './config.module' +export * from './global-config.module' diff --git a/libs/context/src/contextInterceptorModule.ts b/libs/context/src/contextInterceptorModule.ts index a80a712f9..566b431d9 100644 --- a/libs/context/src/contextInterceptorModule.ts +++ b/libs/context/src/contextInterceptorModule.ts @@ -1,13 +1,13 @@ -import { ExecutionContext, Global, Module} from '@nestjs/common'; -import { v4 } from 'uuid'; -import { ClsModule } from 'nestjs-cls'; +import { type ExecutionContext, Global, Module } from '@nestjs/common' +import { ClsModule } from 'nestjs-cls' +import { v4 } from 'uuid' -import { ContextStorageServiceKey } from './contextStorageService.interface'; -import NestjsClsContextStorageService from './nestjsClsContextStorageService'; +import { ContextStorageServiceKey } from './contextStorageService.interface' +import NestjsClsContextStorageService from './nestjsClsContextStorageService' - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const isNullUndefinedOrEmpty = (obj: any): boolean => null === obj || obj === undefined || ('object' === typeof obj && 0 === Object.keys(obj).length); +// biome-ignore lint/suspicious/noExplicitAny: +const isNullUndefinedOrEmpty = (obj: any): boolean => + obj === null || obj === undefined || (typeof obj === 'object' && Object.keys(obj).length === 0) @Global() @Module({ @@ -17,29 +17,25 @@ const isNullUndefinedOrEmpty = (obj: any): boolean => null === obj || obj === un interceptor: { mount: true, - generateId: true, - idGenerator: (context: ExecutionContext) => { - const rpcContext = context.switchToRpc().getContext(); - const headers = rpcContext.getHeaders(); + generateId: true, + idGenerator: (context: ExecutionContext) => { + const rpcContext = context.switchToRpc().getContext() + const headers = rpcContext.getHeaders() if (!isNullUndefinedOrEmpty(headers)) { - return context.switchToRpc().getContext().getHeaders()['_description']; - } else { - return v4(); + return context.switchToRpc().getContext().getHeaders()?._description } - } - - } - }) + return v4() + }, + }, + }), ], controllers: [], providers: [ { provide: ContextStorageServiceKey, - useClass: NestjsClsContextStorageService - } + useClass: NestjsClsContextStorageService, + }, ], - exports: [ContextStorageServiceKey] + exports: [ContextStorageServiceKey], }) - export class ContextInterceptorModule {} - diff --git a/libs/context/src/contextModule.ts b/libs/context/src/contextModule.ts index 4bfb9e2c3..166bc02d2 100644 --- a/libs/context/src/contextModule.ts +++ b/libs/context/src/contextModule.ts @@ -1,9 +1,9 @@ -import { Global, Module } from '@nestjs/common'; -import { v4 } from 'uuid'; -import { ClsModule } from 'nestjs-cls'; +import { Global, Module } from '@nestjs/common' +import { ClsModule } from 'nestjs-cls' +import { v4 } from 'uuid' -import { ContextStorageServiceKey } from './contextStorageService.interface'; -import NestjsClsContextStorageService from './nestjsClsContextStorageService'; +import { ContextStorageServiceKey } from './contextStorageService.interface' +import NestjsClsContextStorageService from './nestjsClsContextStorageService' @Global() @Module({ @@ -13,17 +13,17 @@ import NestjsClsContextStorageService from './nestjsClsContextStorageService'; middleware: { mount: true, generateId: true, - idGenerator: (req: Request) => req.headers['x-correlation-id'] ?? v4() - } - }) + idGenerator: (req: Request) => req.headers['x-correlation-id'] ?? v4(), + }, + }), ], controllers: [], providers: [ { provide: ContextStorageServiceKey, - useClass: NestjsClsContextStorageService - } + useClass: NestjsClsContextStorageService, + }, ], - exports: [ContextStorageServiceKey] + exports: [ContextStorageServiceKey], }) export class ContextModule {} diff --git a/libs/context/src/contextStorageService.interface.ts b/libs/context/src/contextStorageService.interface.ts index 2ad6d8f20..cadb2442a 100644 --- a/libs/context/src/contextStorageService.interface.ts +++ b/libs/context/src/contextStorageService.interface.ts @@ -1,8 +1,8 @@ -export const ContextStorageServiceKey = Symbol(); +export const ContextStorageServiceKey = Symbol() export default interface ContextStorageService { - setContextId(contextId: string): void; - getContextId(): string; - get(key: string): T | undefined; - set(key: string, value: T): void; + setContextId(contextId: string): void + getContextId(): string + get(key: string): T | undefined + set(key: string, value: T): void } diff --git a/libs/context/src/index.ts b/libs/context/src/index.ts index 1466bbdd3..34600c254 100644 --- a/libs/context/src/index.ts +++ b/libs/context/src/index.ts @@ -1,2 +1,2 @@ -export * from './contextInterceptorModule'; -export * from './contextModule'; +export * from './contextInterceptorModule' +export * from './contextModule' diff --git a/libs/context/src/nestjsClsContextStorageService.ts b/libs/context/src/nestjsClsContextStorageService.ts index 00107f21e..32f253dae 100644 --- a/libs/context/src/nestjsClsContextStorageService.ts +++ b/libs/context/src/nestjsClsContextStorageService.ts @@ -1,27 +1,24 @@ -import ContextStorageService from './contextStorageService.interface'; -import { CLS_ID, ClsService } from 'nestjs-cls'; -import { Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common' +import { CLS_ID, type ClsService } from 'nestjs-cls' +import type ContextStorageService from './contextStorageService.interface' @Injectable() -export default class NestjsClsContextStorageService - implements ContextStorageService -{ - constructor(private readonly cls: ClsService) { - } +export default class NestjsClsContextStorageService implements ContextStorageService { + constructor(private readonly cls: ClsService) {} public get(key: string): T | undefined { - return this.cls.get(key); + return this.cls.get(key) } - public setContextId(id: string) : void { - this.cls.set(CLS_ID, id); + public setContextId(id: string): void { + this.cls.set(CLS_ID, id) } public getContextId(): string | undefined { - return this.cls.getId(); + return this.cls.getId() } public set(key: string, value: T): void { - this.cls.set(key, value); + this.cls.set(key, value) } -} \ No newline at end of file +} diff --git a/libs/enum/src/enum.module.ts b/libs/enum/src/enum.module.ts index 3d3e871ff..3ce79884b 100644 --- a/libs/enum/src/enum.module.ts +++ b/libs/enum/src/enum.module.ts @@ -1,8 +1,8 @@ -import { Module } from '@nestjs/common'; -import { EnumService } from './enum.service'; +import { Module } from '@nestjs/common' +import { EnumService } from './enum.service' @Module({ providers: [EnumService], - exports: [EnumService] + exports: [EnumService], }) export class EnumModule {} diff --git a/libs/enum/src/enum.service.spec.ts b/libs/enum/src/enum.service.spec.ts index 59f9cbe13..f1e4fa6e3 100644 --- a/libs/enum/src/enum.service.spec.ts +++ b/libs/enum/src/enum.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { EnumService } from './enum.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { EnumService } from './enum.service' describe('EnumService', () => { - let service: EnumService; + let service: EnumService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [EnumService] - }).compile(); + providers: [EnumService], + }).compile() - service = module.get(EnumService); - }); + service = module.get(EnumService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/libs/enum/src/enum.service.ts b/libs/enum/src/enum.service.ts index 6b825b134..6a666e357 100644 --- a/libs/enum/src/enum.service.ts +++ b/libs/enum/src/enum.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common' @Injectable() export class EnumService {} diff --git a/libs/enum/src/enum.ts b/libs/enum/src/enum.ts index e0811acbb..5b66f8be3 100644 --- a/libs/enum/src/enum.ts +++ b/libs/enum/src/enum.ts @@ -1,11 +1,11 @@ export enum NATSReconnects { maxReconnectAttempts = (10 * 60) / 5, // 10 minutes with a reconnection attempt every 5 seconds - reconnectTimeWait = 5000 // 5 second delay between reconnection attempts + reconnectTimeWait = 5000, // 5 second delay between reconnection attempts } export enum SortValue { ASC = 'asc', - DESC = 'desc' + DESC = 'desc', } export enum SortFields { @@ -15,26 +15,26 @@ export enum SortFields { VERSION = 'version', LEDGER_ID = 'schemaLedgerId', PUBLISHER_DID = 'publisherDid', - ISSUER_ID = 'issuerId' + ISSUER_ID = 'issuerId', } export enum CredDefSortFields { CREATED_DATE_TIME = 'createDateTime', TAG = 'tag', LEDGER_ID = 'schemaLedgerId', - CRED_DEF_ID = 'credentialDefinitionId' + CRED_DEF_ID = 'credentialDefinitionId', } export enum AgentType { // TODO: Change to Credo AFJ = 'AFJ', - ACAPY = 'ACAPY' + ACAPY = 'ACAPY', } export enum DevelopmentEnvironment { PRODUCTION = 'production', DEVELOPMENT = 'development', - TEST = 'test' + TEST = 'test', } export declare enum KeyType { @@ -46,14 +46,14 @@ export declare enum KeyType { P256 = 'p256', P384 = 'p384', P521 = 'p521', - K256 = 'k256' + K256 = 'k256', } export enum DidMethod { INDY = 'indy', KEY = 'key', WEB = 'web', - POLYGON = 'polygon' + POLYGON = 'polygon', } export enum Ledgers { @@ -61,87 +61,87 @@ export enum Ledgers { Indicio_Testnet = 'Indicio Testnet', Indicio_Demonet = 'Indicio Demonet', Indicio_Mainnet = 'Indicio Mainnet', - Not_Applicable = 'NA' + Not_Applicable = 'NA', } export enum Invitation { ACCEPTED = 'accepted', REJECTED = 'rejected', - PENDING = 'pending' + PENDING = 'pending', } export enum EndorserTransactionType { SCHEMA = 'schema', - CREDENTIAL_DEFINITION = 'credential-definition' + CREDENTIAL_DEFINITION = 'credential-definition', } export enum schemaRequestType { W3C = 'w3c', - INDY = 'indy' + INDY = 'indy', } export enum OrgAgentType { DEDICATED = 'DEDICATED', - SHARED = 'SHARED' + SHARED = 'SHARED', } export enum AgentSpinUpStatus { PENDING = 0, PROCESSED = 1, - COMPLETED = 2 + COMPLETED = 2, } export enum UserCertificateId { WINNER = 'Winner', PARTICIPANT = 'Participant', ARBITER = 'Arbiter', - WORLD_RECORD = 'WorldRecord' + WORLD_RECORD = 'WorldRecord', } export enum NodeEnvironment { DEVELOPMENT = 'DEV', - PRODUCTION = 'PROD' + PRODUCTION = 'PROD', } export enum AutoAccept { Always = 'always', ContentApproved = 'contentApproved', - Never = 'never' + Never = 'never', } export enum SortMembers { CREATED_DATE_TIME = 'createDateTime', STATUS = 'status', ID = 'id', - ORGANIZATION = 'organization' + ORGANIZATION = 'organization', } const transitionMap: { [key in Invitation]: Invitation[] } = { [Invitation.PENDING]: [Invitation.ACCEPTED, Invitation.REJECTED], [Invitation.ACCEPTED]: [], - [Invitation.REJECTED]: [] -}; + [Invitation.REJECTED]: [], +} export const transition = (currentStatus: Invitation, nextStatus: Invitation): boolean => - transitionMap[currentStatus].includes(nextStatus); + transitionMap[currentStatus].includes(nextStatus) export enum SchemaType { INDY = 'indy', - W3C_Schema = 'w3c' + W3C_Schema = 'w3c', } export enum IssueCredentialType { JSONLD = 'jsonld', - INDY = 'indy' + INDY = 'indy', } export enum TemplateIdentifier { - EMAIL_COLUMN = 'email_identifier' + EMAIL_COLUMN = 'email_identifier', } export enum PromiseResult { REJECTED = 'rejected', - FULFILLED = 'fulfilled' + FULFILLED = 'fulfilled', } export enum PrismaTables { @@ -156,7 +156,7 @@ export enum PrismaTables { USER_ACTIVITY = 'user_activity', USER_ORG_ROLES = 'user_org_roles', ORG_INVITATIONS = 'org_invitations', - ORGANIZATION = 'organization' + ORGANIZATION = 'organization', } export enum IssuanceProcessState { @@ -170,7 +170,7 @@ export enum IssuanceProcessState { CREDENTIAL_ISSUED = 'credential-issued', CREDENTIAL_RECEIVED = 'credential-received', DONE = 'done', - ABANDONED = 'abandoned' + ABANDONED = 'abandoned', } export enum VerificationProcessState { @@ -182,7 +182,7 @@ export enum VerificationProcessState { PRESENTATION_RECEIVED = 'presentation-received', DECLIEND = 'declined', ABANDONED = 'abandoned', - DONE = 'done' + DONE = 'done', } export enum ConnectionProcessState { @@ -195,12 +195,12 @@ export enum ConnectionProcessState { RESPONSE_SENT = 'response-sent', RESPONSE_RECEIVED = 'response-received', COMPLETE = 'completed', - ABANDONED = 'abandoned' + ABANDONED = 'abandoned', } export enum SchemaTypeEnum { JSON = 'json', - INDY = 'indy' + INDY = 'indy', } export enum W3CSchemaDataType { @@ -210,50 +210,50 @@ export enum W3CSchemaDataType { DATE_TIME = 'datetime-local', ARRAY = 'array', OBJECT = 'object', - BOOLEAN = 'boolean' + BOOLEAN = 'boolean', } export enum IndySchemaDataType { NUMBER = 'number', STRING = 'string', DATE_TIME = 'datetime-local', - BOOLEAN = 'boolean' + BOOLEAN = 'boolean', } export enum JSONSchemaType { POLYGON_W3C = 'polygon', - LEDGER_LESS = 'no_ledger' + LEDGER_LESS = 'no_ledger', } export enum NetworkNamespace { - POLYGON_TESTNET = 'polygon:testnet' + POLYGON_TESTNET = 'polygon:testnet', } export enum LedgerLessMethods { WEB = 'web', - KEY = 'key' + KEY = 'key', } export enum LedgerLessConstant { - NO_LEDGER = 'no_ledger' + NO_LEDGER = 'no_ledger', } export enum ledgerLessDIDType { DID_KEY = 'did:key', - DID_WEB = 'did:web' + DID_WEB = 'did:web', } export enum CloudWalletType { BASE_WALLET = 'CLOUD_BASE_WALLET', - SUB_WALLET = 'CLOUD_SUB_WALLET' + SUB_WALLET = 'CLOUD_SUB_WALLET', } export enum UserRole { DEFAULT_USER = 'DEFAULT_USER', - HOLDER = 'HOLDER' + HOLDER = 'HOLDER', } export enum ProofType { POLYGON_PROOFTYPE = 'EcdsaSecp256k1Signature2019', - NO_LEDGER_PROOFTYPE = 'Ed25519Signature2018' + NO_LEDGER_PROOFTYPE = 'Ed25519Signature2018', } diff --git a/libs/enum/src/index.ts b/libs/enum/src/index.ts index 535c1bd49..68f10b7c5 100644 --- a/libs/enum/src/index.ts +++ b/libs/enum/src/index.ts @@ -1,2 +1,2 @@ -export * from './enum.module'; -export * from './enum.service'; +export * from './enum.module' +export * from './enum.service' diff --git a/libs/http-exception.filter.ts b/libs/http-exception.filter.ts index c7dc008fb..f6e864c71 100644 --- a/libs/http-exception.filter.ts +++ b/libs/http-exception.filter.ts @@ -1,30 +1,30 @@ -import { Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common'; -import { RpcException } from '@nestjs/microservices'; -import { PrismaClientKnownRequestError, PrismaClientValidationError } from '@prisma/client/runtime/library'; -import { Observable, throwError } from 'rxjs'; +import { Catch, type ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common' +import { RpcException } from '@nestjs/microservices' +import { PrismaClientKnownRequestError, PrismaClientValidationError } from '@prisma/client/runtime/library' +import { type Observable, throwError } from 'rxjs' @Catch() export class HttpExceptionFilter implements ExceptionFilter { - private readonly logger = new Logger('CommonService'); + private readonly logger = new Logger('CommonService') - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + // biome-ignore lint/suspicious/noExplicitAny: , @typescript-eslint/explicit-module-boundary-types catch(exception: any): Observable { - this.logger.error(`AnyExceptionFilter caught error: ${JSON.stringify(exception)}`); + this.logger.error(`AnyExceptionFilter caught error: ${JSON.stringify(exception)}`) - let httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; - let message = ''; + let httpStatus = HttpStatus.INTERNAL_SERVER_ERROR + let message = '' switch (exception.constructor) { case HttpException: - this.logger.error(`Its HttpException`); - httpStatus = exception.getStatus() || HttpStatus.BAD_REQUEST; - message = exception?.getResponse() || exception.message; - break; + this.logger.error('Its HttpException') + httpStatus = exception.getStatus() || HttpStatus.BAD_REQUEST + message = exception?.getResponse() || exception.message + break case RpcException: - this.logger.error(`Its RpcException`); - return throwError(() => exception.getError()); - break; + this.logger.error('Its RpcException') + return throwError(() => exception.getError()) + break case PrismaClientKnownRequestError: - this.logger.error(`Its PrismaClientKnownRequestError`); + this.logger.error('Its PrismaClientKnownRequestError') switch (exception.code) { case 'P2002': // Unique constraint failed on the {constraint} case 'P2000': // The provided value for the column is too long for the column's type. Column: {column_name} @@ -35,45 +35,45 @@ export class HttpExceptionFilter implements ExceptionFilter { case 'P2011': // Null constraint violation on the {constraint} case 'P2017': // The records for relation {relation_name} between the {parent_name} and {child_name} models are not connected. case 'P2021': // The table {table} does not exist in the current database. - case 'P2022': // The column {column} does not exist in the current database. - httpStatus = HttpStatus.BAD_REQUEST; - message = exception?.response?.message || exception?.message; - break; + case 'P2022': // The column {column} does not exist in the current database. + httpStatus = HttpStatus.BAD_REQUEST + message = exception?.response?.message || exception?.message + break case 'P2023': // Inconsistent column data: {message} - httpStatus = HttpStatus.BAD_REQUEST; - message = exception?.meta?.message || exception?.message; - break; + httpStatus = HttpStatus.BAD_REQUEST + message = exception?.meta?.message || exception?.message + break case 'P2018': // The required connected records were not found. {details} case 'P2025': // An operation failed because it depends on one or more records that were required but not found. {cause} case 'P2015': // A related record could not be found. {details} - httpStatus = HttpStatus.NOT_FOUND; - message = exception?.message; - break; + httpStatus = HttpStatus.NOT_FOUND + message = exception?.message + break default: - httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; - message = exception?.response?.message || exception?.message || 'Internal server error'; + httpStatus = HttpStatus.INTERNAL_SERVER_ERROR + message = exception?.response?.message || exception?.message || 'Internal server error' } - break; + break case PrismaClientValidationError: - this.logger.error(`Its PrismaClientValidationError`); - httpStatus = HttpStatus.BAD_REQUEST; - message = exception?.message || exception?.response?.message; - break; + this.logger.error('Its PrismaClientValidationError') + httpStatus = HttpStatus.BAD_REQUEST + message = exception?.message || exception?.response?.message + break default: - this.logger.error(`Its an Unknown Exception`); + this.logger.error('Its an Unknown Exception') // eslint-disable-next-line no-case-declarations httpStatus = exception.response?.status || exception.response?.statusCode || exception.code || - HttpStatus.INTERNAL_SERVER_ERROR; + HttpStatus.INTERNAL_SERVER_ERROR // eslint-disable-next-line no-case-declarations message = exception.response?.data?.message || exception.response?.message || exception?.message || - 'Internal server error'; + 'Internal server error' } - return throwError(() => new RpcException({ message, code: httpStatus })); + return throwError(() => new RpcException({ message, code: httpStatus })) } -} \ No newline at end of file +} diff --git a/libs/keycloak-url/src/index.ts b/libs/keycloak-url/src/index.ts index 4457df5ce..18c606117 100644 --- a/libs/keycloak-url/src/index.ts +++ b/libs/keycloak-url/src/index.ts @@ -1,2 +1,2 @@ -export * from './keycloak-url.module'; -export * from './keycloak-url.service'; +export * from './keycloak-url.module' +export * from './keycloak-url.service' diff --git a/libs/keycloak-url/src/keycloak-url.module.ts b/libs/keycloak-url/src/keycloak-url.module.ts index 02d0c52ea..b87a89b61 100644 --- a/libs/keycloak-url/src/keycloak-url.module.ts +++ b/libs/keycloak-url/src/keycloak-url.module.ts @@ -1,8 +1,8 @@ -import { Module } from '@nestjs/common'; -import { KeycloakUrlService } from './keycloak-url.service'; +import { Module } from '@nestjs/common' +import { KeycloakUrlService } from './keycloak-url.service' @Module({ providers: [KeycloakUrlService], - exports: [KeycloakUrlService] + exports: [KeycloakUrlService], }) export class KeycloakUrlModule {} diff --git a/libs/keycloak-url/src/keycloak-url.service.ts b/libs/keycloak-url/src/keycloak-url.service.ts index fc259d1c2..db6cad4a0 100644 --- a/libs/keycloak-url/src/keycloak-url.service.ts +++ b/libs/keycloak-url/src/keycloak-url.service.ts @@ -1,132 +1,74 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common' @Injectable() export class KeycloakUrlService { - private readonly logger = new Logger('KeycloakUrlService'); + private readonly logger = new Logger('KeycloakUrlService') - - async createUserURL( - realm: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users`; - } - - async getUserByUsernameURL( - realm: string, - username: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users?username=${username}`; + async createUserURL(realm: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users` } - async GetUserInfoURL( - realm: string, - userid: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userid}`; - } - - async GetSATURL( - realm: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}realms/${realm}/protocol/openid-connect/token`; - } - - async ResetPasswordURL( - realm: string, - userid: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userid}/reset-password`; + async getUserByUsernameURL(realm: string, username: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users?username=${username}` } - - async CreateRealmURL():Promise { - return `${process.env.KEYCLOAK_DOMAIN}admin/realms`; + async GetUserInfoURL(realm: string, userid: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userid}` } - async createClientURL( - realm: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients`; + async GetSATURL(realm: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}realms/${realm}/protocol/openid-connect/token` } - async GetClientURL( - realm: string, - clientid: string - ):Promise { + async ResetPasswordURL(realm: string, userid: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userid}/reset-password` + } - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients?clientId=${clientid}`; - } + async CreateRealmURL(): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms` + } - async GetClientSecretURL( - realm: string, - clientid: string - ):Promise { + async createClientURL(realm: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients` + } - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${clientid}/client-secret`; + async GetClientURL(realm: string, clientid: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients?clientId=${clientid}` } - async GetClientRoleURL( - realm: string, - clientid: string, - roleName = '' - ):Promise { + async GetClientSecretURL(realm: string, clientid: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${clientid}/client-secret` + } - if ('' === roleName) { - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${clientid}/roles`; + async GetClientRoleURL(realm: string, clientid: string, roleName = ''): Promise { + if (roleName === '') { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${clientid}/roles` } - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${clientid}/roles/${roleName}`; - + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${clientid}/roles/${roleName}` } - async GetRealmRoleURL( - realm: string, - roleName = '' - ):Promise { - - if ('' === roleName) { - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/roles`; + async GetRealmRoleURL(realm: string, roleName = ''): Promise { + if (roleName === '') { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/roles` } - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/roles/${roleName}`; - + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/roles/${roleName}` } - async GetClientUserRoleURL( - realm: string, - userId: string, - clientId?: string - ):Promise { - + async GetClientUserRoleURL(realm: string, userId: string, clientId?: string): Promise { if (clientId) { - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userId}/role-mappings/clients/${clientId}`; + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userId}/role-mappings/clients/${clientId}` } - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userId}/role-mappings/realm`; - + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/users/${userId}/role-mappings/realm` } - - async GetClientIdpURL( - realm: string, - idp: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${idp}`; + async GetClientIdpURL(realm: string, idp: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients/${idp}` } - async GetClient( - realm: string, - clientId: string - ):Promise { - - return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients?clientId=${clientId}`; + async GetClient(realm: string, clientId: string): Promise { + return `${process.env.KEYCLOAK_DOMAIN}admin/realms/${realm}/clients?clientId=${clientId}` } - } diff --git a/libs/logger/src/index.ts b/libs/logger/src/index.ts index bbf7c26d2..e3268eaa0 100644 --- a/libs/logger/src/index.ts +++ b/libs/logger/src/index.ts @@ -1,2 +1,2 @@ -export * from './logger.module'; -export * from './logger.service'; +export * from './logger.module' +export * from './logger.service' diff --git a/libs/logger/src/log.ts b/libs/logger/src/log.ts index 7456ef7b4..013c52c08 100644 --- a/libs/logger/src/log.ts +++ b/libs/logger/src/log.ts @@ -1,27 +1,26 @@ export enum LogLevel { - Emergency = 'emergency', // One or more systems are unusable. - Fatal = 'fatal', // A person must take an action immediately - Error = 'error', // Error events are likely to cause problems - Warn = 'warn', // Warning events might cause problems in the future and deserve eyes - Info = 'info', // Routine information, such as ongoing status or performance - Debug = 'debug', // Debug or trace information - } - - export interface Log { - timestamp: number; // Unix timestamp - level: LogLevel; // Log level - message: string; // Log message - data: LogData; // Log data - } - - export interface LogData { - organization?: string; // Organization or project name - context?: string; // Bounded Context name - app?: string; // Application or Microservice name - sourceClass?: string; // Classname of the source - correlationId?: string; // Correlation ID - error?: Error; // Error object - // eslint-disable-next-line @typescript-eslint/no-explicit-any - props?: NodeJS.Dict; // Additional custom properties - } - \ No newline at end of file + Emergency = 'emergency', // One or more systems are unusable. + Fatal = 'fatal', // A person must take an action immediately + Error = 'error', // Error events are likely to cause problems + Warn = 'warn', // Warning events might cause problems in the future and deserve eyes + Info = 'info', // Routine information, such as ongoing status or performance + Debug = 'debug', // Debug or trace information +} + +export interface Log { + timestamp: number // Unix timestamp + level: LogLevel // Log level + message: string // Log message + data: LogData // Log data +} + +export interface LogData { + organization?: string // Organization or project name + context?: string // Bounded Context name + app?: string // Application or Microservice name + sourceClass?: string // Classname of the source + correlationId?: string // Correlation ID + error?: Error // Error object + // biome-ignore lint/suspicious/noExplicitAny: + props?: NodeJS.Dict // Additional custom properties +} diff --git a/libs/logger/src/logger.interface.ts b/libs/logger/src/logger.interface.ts index 012a874dd..714ea20ad 100644 --- a/libs/logger/src/logger.interface.ts +++ b/libs/logger/src/logger.interface.ts @@ -1,20 +1,15 @@ -import { LogData, LogLevel } from '@credebl/logger/log'; +import type { LogData, LogLevel } from '@credebl/logger/log' -export const LoggerBaseKey = Symbol(); -export const LoggerKey = Symbol(); +export const LoggerBaseKey = Symbol() +export const LoggerKey = Symbol() export default interface Logger { - log( - level: LogLevel, - message: string | Error, - data?: LogData, - profile?: string, - ): void; - debug(message: string, data?: LogData, profile?: string): void; - info(message: string, data?: LogData, profile?: string): void; - warn(message: string | Error, data?: LogData, profile?: string): void; - error(message: string | Error, data?: LogData, profile?: string): void; - fatal(message: string | Error, data?: LogData, profile?: string): void; - emergency(message: string | Error, data?: LogData, profile?: string): void; - startProfile(id: string): void; -}; + log(level: LogLevel, message: string | Error, data?: LogData, profile?: string): void + debug(message: string, data?: LogData, profile?: string): void + info(message: string, data?: LogData, profile?: string): void + warn(message: string | Error, data?: LogData, profile?: string): void + error(message: string | Error, data?: LogData, profile?: string): void + fatal(message: string | Error, data?: LogData, profile?: string): void + emergency(message: string | Error, data?: LogData, profile?: string): void + startProfile(id: string): void +} diff --git a/libs/logger/src/logger.module.ts b/libs/logger/src/logger.module.ts index c7529d380..247908f86 100644 --- a/libs/logger/src/logger.module.ts +++ b/libs/logger/src/logger.module.ts @@ -1,24 +1,14 @@ -import { - Global, - Inject, - MiddlewareConsumer, - Module, - NestModule -} from '@nestjs/common'; +import { Global, Inject, type MiddlewareConsumer, Module, type NestModule } from '@nestjs/common' -import WinstonLogger, { - WinstonLoggerTransportsKey -} from '@credebl/logger/winstonLogger'; -import Logger, { - LoggerBaseKey, - LoggerKey -} from '@credebl/logger/logger.interface'; -import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; -import ConsoleTransport from '@credebl/logger/transports/consoleTransport'; -import * as morgan from 'morgan'; -import { ConfigService } from '../../config/src/config.service'; -import LoggerService from '@credebl/logger/logger.service'; -import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; +import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import type Logger from '@credebl/logger/logger.interface' +import { LoggerBaseKey, LoggerKey } from '@credebl/logger/logger.interface' +import LoggerService from '@credebl/logger/logger.service' +import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter' +import ConsoleTransport from '@credebl/logger/transports/consoleTransport' +import WinstonLogger, { WinstonLoggerTransportsKey } from '@credebl/logger/winstonLogger' +import * as morgan from 'morgan' +import { ConfigService } from '../../config/src/config.service' @Global() @Module({ @@ -27,31 +17,31 @@ import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; providers: [ { provide: LoggerBaseKey, - useClass: WinstonLogger + useClass: WinstonLogger, }, { provide: LoggerKey, - useClass: LoggerService + useClass: LoggerService, }, { provide: NestjsLoggerServiceAdapter, // eslint-disable-next-line @typescript-eslint/explicit-function-return-type useFactory: (logger: Logger) => new NestjsLoggerServiceAdapter(logger), - inject: [LoggerKey] + inject: [LoggerKey], }, { provide: WinstonLoggerTransportsKey, // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-unused-vars - useFactory: (configService: ConfigService) => { - const transports = []; + useFactory: (_configService: ConfigService) => { + const transports = [] - transports.push(ConsoleTransport.createColorize()); - return transports; + transports.push(ConsoleTransport.createColorize()) + return transports }, - inject: [ConfigService, MICRO_SERVICE_NAME] - } + inject: [ConfigService, MICRO_SERVICE_NAME], + }, ], - exports: [LoggerKey, NestjsLoggerServiceAdapter] + exports: [LoggerKey, NestjsLoggerServiceAdapter], }) export class LoggerModule implements NestModule { public constructor( @@ -66,12 +56,12 @@ export class LoggerModule implements NestModule { stream: { write: (message: string) => { this.logger.debug(message, { - sourceClass: 'RequestLogger' - }); - } - } + sourceClass: 'RequestLogger', + }) + }, + }, }) ) - .forRoutes('*'); + .forRoutes('*') } } diff --git a/libs/logger/src/logger.service.ts b/libs/logger/src/logger.service.ts index 69e3e69d5..ad0e95bfa 100644 --- a/libs/logger/src/logger.service.ts +++ b/libs/logger/src/logger.service.ts @@ -1,21 +1,19 @@ -import { Inject, Injectable, Scope } from '@nestjs/common'; -import { INQUIRER } from '@nestjs/core'; -import Logger, { - LoggerBaseKey -} from '@credebl/logger/logger.interface'; -import { LogData, LogLevel } from '@credebl/logger/log'; -import { ConfigService } from '@nestjs/config'; -import ContextStorageService, { - ContextStorageServiceKey -} from '@credebl/context/contextStorageService.interface'; -import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; +import { MICRO_SERVICE_NAME } from '@credebl/common/common.constant' +import type ContextStorageService from '@credebl/context/contextStorageService.interface' +import { ContextStorageServiceKey } from '@credebl/context/contextStorageService.interface' +import type { LogData, LogLevel } from '@credebl/logger/log' +import type Logger from '@credebl/logger/logger.interface' +import { LoggerBaseKey } from '@credebl/logger/logger.interface' +import { Inject, Injectable, Scope } from '@nestjs/common' +import type { ConfigService } from '@nestjs/config' +import { INQUIRER } from '@nestjs/core' @Injectable({ scope: Scope.TRANSIENT }) export default class LoggerService implements Logger { - private readonly sourceClass: string; - private readonly organization: string; - private readonly context: string; - private readonly app: string; + private readonly sourceClass: string + private readonly organization: string + private readonly context: string + private readonly app: string public constructor( @Inject(LoggerBaseKey) private readonly logger: Logger, @@ -26,44 +24,39 @@ export default class LoggerService implements Logger { @Inject(MICRO_SERVICE_NAME) private readonly microserviceName: string ) { // Set the source class from the parent class - this.sourceClass = parentClass?.constructor?.name; + this.sourceClass = parentClass?.constructor?.name // Set the organization, context and app from the environment variables - this.organization = configService.get('ORGANIZATION'); - this.context = configService.get('CONTEXT'); - this.app = configService.get('APP'); + this.organization = configService.get('ORGANIZATION') + this.context = configService.get('CONTEXT') + this.app = configService.get('APP') } - public log( - level: LogLevel, - message: string | Error, - data?: LogData, - profile?: string, - ): void { - return this.logger.log(level, message, this.getLogData(data), profile); + public log(level: LogLevel, message: string | Error, data?: LogData, profile?: string): void { + this.logger.log(level, message, this.getLogData(data), profile) } - public debug(message: string, data?: LogData, profile?: string) : void { - return this.logger.debug(message, this.getLogData(data), profile); + public debug(message: string, data?: LogData, profile?: string): void { + this.logger.debug(message, this.getLogData(data), profile) } - public info(message: string, data?: LogData, profile?: string) : void { - return this.logger.info(message, this.getLogData(data), profile); + public info(message: string, data?: LogData, profile?: string): void { + this.logger.info(message, this.getLogData(data), profile) } - public warn(message: string | Error, data?: LogData, profile?: string) : void { - return this.logger.warn(message, this.getLogData(data), profile); + public warn(message: string | Error, data?: LogData, profile?: string): void { + this.logger.warn(message, this.getLogData(data), profile) } - public error(message: string | Error, data?: LogData, profile?: string) : void { - return this.logger.error(message, this.getLogData(data), profile); + public error(message: string | Error, data?: LogData, profile?: string): void { + this.logger.error(message, this.getLogData(data), profile) } - public fatal(message: string | Error, data?: LogData, profile?: string) : void { - return this.logger.fatal(message, this.getLogData(data), profile); + public fatal(message: string | Error, data?: LogData, profile?: string): void { + this.logger.fatal(message, this.getLogData(data), profile) } - public emergency(message: string | Error, data?: LogData, profile?: string) : void { - return this.logger.emergency(message, this.getLogData(data), profile); + public emergency(message: string | Error, data?: LogData, profile?: string): void { + this.logger.emergency(message, this.getLogData(data), profile) } private getLogData(data?: LogData): LogData { @@ -73,12 +66,11 @@ export default class LoggerService implements Logger { context: data?.context || this.context, app: data?.app || this.app, sourceClass: data?.sourceClass || this.sourceClass, - correlationId: - data?.correlationId || this.contextStorageService.getContextId() - }; + correlationId: data?.correlationId || this.contextStorageService.getContextId(), + } } - public startProfile(id: string) : void { - this.logger.startProfile(id); + public startProfile(id: string): void { + this.logger.startProfile(id) } } diff --git a/libs/logger/src/logging.interceptor.ts b/libs/logger/src/logging.interceptor.ts index 7a96ee996..79ad98d9a 100644 --- a/libs/logger/src/logging.interceptor.ts +++ b/libs/logger/src/logging.interceptor.ts @@ -1,47 +1,47 @@ -import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Inject } from '@nestjs/common'; -import { Observable, throwError } from 'rxjs'; -import { catchError } from 'rxjs/operators'; +import { type CallHandler, type ExecutionContext, Inject, Injectable, type NestInterceptor } from '@nestjs/common' +import { type Observable, throwError } from 'rxjs' +import { catchError } from 'rxjs/operators' -import ContextStorageService, { ContextStorageServiceKey } from '@credebl/context/contextStorageService.interface'; -import Logger, { LoggerKey } from './logger.interface'; -import { ClsService } from 'nestjs-cls'; -import { v4 } from 'uuid'; +import type ContextStorageService from '@credebl/context/contextStorageService.interface' +import { ContextStorageServiceKey } from '@credebl/context/contextStorageService.interface' +import type { ClsService } from 'nestjs-cls' +import { v4 } from 'uuid' +import type Logger from './logger.interface' +import { LoggerKey } from './logger.interface' -const isNullUndefinedOrEmpty = (obj: any): boolean => obj === null || obj === undefined || (typeof obj === 'object' && Object.keys(obj).length === 0); +// biome-ignore lint/suspicious/noExplicitAny: +const isNullUndefinedOrEmpty = (obj: any): boolean => + obj === null || obj === undefined || (typeof obj === 'object' && Object.keys(obj).length === 0) @Injectable() export class LoggingInterceptor implements NestInterceptor { constructor( private readonly clsService: ClsService, @Inject(ContextStorageServiceKey) - private readonly contextStorageService: ContextStorageService, - @Inject(LoggerKey) private readonly _logger: Logger, + private readonly contextStorageService: ContextStorageService, + @Inject(LoggerKey) private readonly _logger: Logger ) {} - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: intercept(context: ExecutionContext, next: CallHandler): Observable { - return this.clsService.run(() => { + return this.clsService.run(() => { + this._logger.info('In LoggingInterceptor configuration') + const rpcContext = context.switchToRpc().getContext() + const headers = rpcContext.getHeaders() - this._logger.info('In LoggingInterceptor configuration'); - const rpcContext = context.switchToRpc().getContext(); - const headers = rpcContext.getHeaders(); - - if (!isNullUndefinedOrEmpty(headers)) { - this.contextStorageService.set('x-correlation-id', headers._description); - this.contextStorageService.setContextId(headers._description); - } else { - const newContextId = v4(); - this.contextStorageService.set('x-correlation-id', newContextId); - this.contextStorageService.setContextId(newContextId); - } - - return next.handle().pipe( - catchError((err) => { - this._logger.error(err); - return throwError(() => err); - }) - ); - - }); + if (!isNullUndefinedOrEmpty(headers)) { + this.contextStorageService.set('x-correlation-id', headers._description) + this.contextStorageService.setContextId(headers._description) + } else { + const newContextId = v4() + this.contextStorageService.set('x-correlation-id', newContextId) + this.contextStorageService.setContextId(newContextId) + } + return next.handle().pipe( + catchError((err) => { + this._logger.error(err) + return throwError(() => err) + }) + ) + }) } - } diff --git a/libs/logger/src/nestjsLoggerServiceAdapter.ts b/libs/logger/src/nestjsLoggerServiceAdapter.ts index 9ebae39d0..ba451db53 100644 --- a/libs/logger/src/nestjsLoggerServiceAdapter.ts +++ b/libs/logger/src/nestjsLoggerServiceAdapter.ts @@ -1,43 +1,40 @@ -import { ConsoleLogger } from '@nestjs/common'; -import Logger from '@credebl/logger/logger.interface'; -import { LoggerService } from '@nestjs/common/services/logger.service'; -import { LogData } from '@credebl/logger/log'; - -export default class NestjsLoggerServiceAdapter - extends ConsoleLogger - implements LoggerService -{ +import type { LogData } from '@credebl/logger/log' +import type Logger from '@credebl/logger/logger.interface' +import { ConsoleLogger } from '@nestjs/common' +import type { LoggerService } from '@nestjs/common/services/logger.service' + +export default class NestjsLoggerServiceAdapter extends ConsoleLogger implements LoggerService { public constructor(private readonly logger: Logger) { - super(); + super() } - public info(message: any, ...optionalParams: any[]) : void { - return this.logger.info(message, this.getLogData(optionalParams)); + public info(message: string, ...optionalParams: unknown[]): void { + this.logger.info(message, this.getLogData(optionalParams)) } - public log(message: any, ...optionalParams: any[]) : void { - return this.logger.info(message, this.getLogData(optionalParams)); + public log(message: string, ...optionalParams: unknown[]): void { + this.logger.info(message, this.getLogData(optionalParams)) } - public error(message: any, ...optionalParams: any[]) : void { - return this.logger.error(message, this.getLogData(optionalParams)); + public error(message: string, ...optionalParams: unknown[]): void { + this.logger.error(message, this.getLogData(optionalParams)) } - public warn(message: any, ...optionalParams: any[]) : void { - return this.logger.warn(message, this.getLogData(optionalParams)); + public warn(message: string, ...optionalParams: unknown[]) { + this.logger.warn(message, this.getLogData(optionalParams)) } - public debug(message: any, ...optionalParams: any[]) : void { - return this.logger.debug(message, this.getLogData(optionalParams)); + public debug(message: string, ...optionalParams: unknown[]) { + this.logger.debug(message, this.getLogData(optionalParams)) } - public verbose(message: any, ...optionalParams: any[]) : void { - return this.logger.info(message, this.getLogData(optionalParams)); + public verbose(message: string, ...optionalParams: unknown[]): void { + this.logger.info(message, this.getLogData(optionalParams)) } - private getLogData(...optionalParams: any[]) : LogData { + private getLogData(optionalParams: unknown[]): LogData { return { - sourceClass: optionalParams[0] ? optionalParams[0] : undefined, - }; + sourceClass: typeof optionalParams[0] === 'string' ? optionalParams[0] : undefined, + } } } diff --git a/libs/logger/src/transports/consoleTransport.ts b/libs/logger/src/transports/consoleTransport.ts index e12b6c029..389925c12 100644 --- a/libs/logger/src/transports/consoleTransport.ts +++ b/libs/logger/src/transports/consoleTransport.ts @@ -1,6 +1,6 @@ +import { LogLevel } from '@credebl/logger/log' /* eslint-disable @typescript-eslint/no-explicit-any */ -import * as winston from 'winston'; -import { LogLevel } from '@credebl/logger/log'; +import * as winston from 'winston' enum LogColors { red = '\x1b[31m', @@ -12,14 +12,14 @@ enum LogColors { pink = '\x1b[38;5;206m', } interface LogData { - label?: string; - '@timestamp'?: string; - correlationId?: string; - sourceClass?: string; - error?: string; - durationMs?: number; - stack?: string; - props?: Record; + label?: string + '@timestamp'?: string + correlationId?: string + sourceClass?: string + error?: string + durationMs?: number + stack?: string + props?: Record } export default class ConsoleTransport { @@ -27,53 +27,49 @@ export default class ConsoleTransport { return new winston.transports.Console({ format: winston.format.combine( winston.format.printf((log) => { - const data = log.data as LogData; - const color = ConsoleTransport.mapLogLevelColor(log.level as LogLevel); - const prefix = data.label ? `[${data.label}]` : ''; - const timestamp = data['@timestamp']; + const data = log.data as LogData + const color = ConsoleTransport.mapLogLevelColor(log.level as LogLevel) + const prefix = data.label ? `[${data.label}]` : '' + const timestamp = data['@timestamp'] const correlationId = data.correlationId ? `(${ConsoleTransport.colorize(LogColors.cyan, data.correlationId)})` - : ''; - const level = ConsoleTransport.colorize(color, log.level.toUpperCase()); + : '' + const level = ConsoleTransport.colorize(color, log.level.toUpperCase()) const sourceClass = data.sourceClass ? `${ConsoleTransport.colorize(LogColors.yellow, `[${data.sourceClass}]`)}` - : ''; - const message = ConsoleTransport.colorize(color, `${log.message}`); - const error = data.error ? ` - ${data.error}` : ''; - const duration = data.durationMs !== undefined - ? ` +${data.durationMs}ms` - : ''; - const stack = data.stack ? ` - ${data.stack}` : ''; - const props = data.props - ? `\n - Props: ${JSON.stringify(data.props, null, 4)}` - : ''; + : '' + const message = ConsoleTransport.colorize(color, `${log.message}`) + const error = data.error ? ` - ${data.error}` : '' + const duration = data.durationMs !== undefined ? ` +${data.durationMs}ms` : '' + const stack = data.stack ? ` - ${data.stack}` : '' + const props = data.props ? `\n - Props: ${JSON.stringify(data.props, null, 4)}` : '' - return `${ConsoleTransport.colorize(color, `${prefix} -`)} ${timestamp} ${correlationId} ${level} ${sourceClass} ${message}${error}${duration}${stack}${props}`; + return `${ConsoleTransport.colorize(color, `${prefix} -`)} ${timestamp} ${correlationId} ${level} ${sourceClass} ${message}${error}${duration}${stack}${props}` }) - ) - }); + ), + }) } private static colorize(color: LogColors, message: string): string { - return `${color}${message}\x1b[0m`; + return `${color}${message}\x1b[0m` } private static mapLogLevelColor(level: LogLevel): LogColors { switch (level) { case LogLevel.Debug: - return LogColors.blue; + return LogColors.blue case LogLevel.Info: - return LogColors.green; + return LogColors.green case LogLevel.Warn: - return LogColors.yellow; + return LogColors.yellow case LogLevel.Error: - return LogColors.red; + return LogColors.red case LogLevel.Fatal: - return LogColors.magenta; + return LogColors.magenta case LogLevel.Emergency: - return LogColors.pink; + return LogColors.pink default: - return LogColors.cyan; + return LogColors.cyan } } } diff --git a/libs/logger/src/transports/fileTransport.ts b/libs/logger/src/transports/fileTransport.ts index 6c27a564f..fa05dc13c 100644 --- a/libs/logger/src/transports/fileTransport.ts +++ b/libs/logger/src/transports/fileTransport.ts @@ -1,4 +1,4 @@ -import DailyRotateFile = require('winston-daily-rotate-file'); +import DailyRotateFile = require('winston-daily-rotate-file') export default class FileTransport { public static create() { @@ -8,7 +8,7 @@ export default class FileTransport { datePattern: 'YYYY-MM-DD-HH', zippedArchive: true, maxSize: '20m', - maxFiles: '14d' - }); + maxFiles: '14d', + }) } } diff --git a/libs/logger/src/winstonLogger.ts b/libs/logger/src/winstonLogger.ts index d2a8b0ef8..f8954edb6 100644 --- a/libs/logger/src/winstonLogger.ts +++ b/libs/logger/src/winstonLogger.ts @@ -1,62 +1,58 @@ -import * as winston from 'winston'; -import { Inject, Injectable } from '@nestjs/common'; -import { LogData, LogLevel } from '@credebl/logger/log'; -import Logger from '@credebl/logger/logger.interface'; -import * as Elasticsearch from 'winston-elasticsearch'; -import * as ecsFormat from '@elastic/ecs-winston-format'; - -export const WinstonLoggerTransportsKey = Symbol(); -let esTransport; -if ('true' === process.env.ELK_LOG?.toLowerCase()) { +import { type LogData, LogLevel } from '@credebl/logger/log' +import type Logger from '@credebl/logger/logger.interface' +import * as ecsFormat from '@elastic/ecs-winston-format' +import { Inject, Injectable } from '@nestjs/common' +import * as winston from 'winston' +import * as Elasticsearch from 'winston-elasticsearch' + +export const WinstonLoggerTransportsKey = Symbol() +let esTransport: winston.transport +if (process.env.ELK_LOG?.toLowerCase() === 'true') { const esTransportOpts = { - level: `${process.env.LOG_LEVEL}`, - clientOpts: { node: `${process.env.ELK_LOG_PATH}`, - auth: { - username: `${process.env.ELK_USERNAME}`, - password: `${process.env.ELK_PASSWORD}` + level: `${process.env.LOG_LEVEL}`, + clientOpts: { + node: `${process.env.ELK_LOG_PATH}`, + auth: { + username: `${process.env.ELK_USERNAME}`, + password: `${process.env.ELK_PASSWORD}`, + }, + }, } - } -}; -esTransport = new Elasticsearch.ElasticsearchTransport(esTransportOpts); - -esTransport.on('error', (error) => { - console.error('Error caught in logger', error); -}); + esTransport = new Elasticsearch.ElasticsearchTransport(esTransportOpts) + esTransport.on('error', (error) => { + console.error('Error caught in logger', error) + }) } - @Injectable() export default class WinstonLogger implements Logger { - private readonly logger: winston.Logger; + private readonly logger: winston.Logger - public constructor( - @Inject(WinstonLoggerTransportsKey) transports: winston.transport[] - ) { - if(esTransport){ - transports.push(esTransport); + public constructor(@Inject(WinstonLoggerTransportsKey) transports: winston.transport[]) { + if (esTransport) { + transports.push(esTransport) } - - + // Create winston logger - this.logger = winston.createLogger(this.getLoggerFormatOptions(transports)); - + this.logger = winston.createLogger(this.getLoggerFormatOptions(transports)) } - private getLoggerFormatOptions(transports: winston.transport[]) : winston.LoggerOptions { + private getLoggerFormatOptions(transports: winston.transport[]): winston.LoggerOptions { // Setting log levels for winston - const levels: any = {}; - let cont = 0; + const levels = {} + let cont = 0 + // biome-ignore lint/complexity/noForEach: Object.values(LogLevel).forEach((level) => { - levels[level] = cont; - cont++; - }); + levels[level] = cont + cont++ + }) return { level: LogLevel.Debug, levels, - // format: ecsFormat.ecsFormat({ convertReqRes: true }), - format: winston.format.combine( + // format: ecsFormat.ecsFormat({ convertReqRes: true }), + format: winston.format.combine( ecsFormat.ecsFormat({ convertReqRes: true }), // Add timestamp and format the date // winston.format.timestamp({ @@ -65,78 +61,70 @@ export default class WinstonLogger implements Logger { // Errors will be logged with stack trace winston.format.errors({ stack: true }), // Add custom Log fields to the log - winston.format((info, opts) => { + winston.format((info, _opts) => { // Info contains an Error property if (info.error && info.error instanceof Error) { - info.stack = info.error.stack; - info.error = undefined; + info.stack = info.error.stack + info.error = undefined } - info.label = `${info.organization}.${info.context}.${info.app}`; + info.label = `${info.organization}.${info.context}.${info.app}` - return info; + return info })(), // Add custom fields to the data property winston.format.metadata({ key: 'data', - fillExcept: ['timestamp', 'level', 'message'] + fillExcept: ['timestamp', 'level', 'message'], }), // Format the log as JSON - winston.format.json(), + winston.format.json() ), transports, - exceptionHandlers: transports - }; + exceptionHandlers: transports, + } } - public log( - level: LogLevel, - message: string | Error, - data?: LogData, - profile?: string - ) : void { + public log(level: LogLevel, message: string | Error, data?: LogData, profile?: string): void { const logData = { level: level, message: message instanceof Error ? message.message : message, error: message instanceof Error ? message : undefined, - ...data - }; + ...data, + } if (profile) { - this.logger.profile(profile, logData); + this.logger.profile(profile, logData) } else { - this.logger.log(logData); + this.logger.log(logData) } } - - public debug(message: string, data?: LogData, profile?: string) : void { - this.log(LogLevel.Debug, message, data, profile); + public debug(message: string, data?: LogData, profile?: string): void { + this.log(LogLevel.Debug, message, data, profile) } - public info(message: string, data?: LogData, profile?: string) : void { - this.log(LogLevel.Info, message, data, profile); + public info(message: string, data?: LogData, profile?: string): void { + this.log(LogLevel.Info, message, data, profile) } - public warn(message: string | Error, data?: LogData, profile?: string) : void { - this.log(LogLevel.Warn, message, data, profile); + public warn(message: string | Error, data?: LogData, profile?: string): void { + this.log(LogLevel.Warn, message, data, profile) } - public error(message: string | Error, data?: LogData, profile?: string) : void { - this.log(LogLevel.Error, message, data, profile); + public error(message: string | Error, data?: LogData, profile?: string): void { + this.log(LogLevel.Error, message, data, profile) } - public fatal(message: string | Error, data?: LogData, profile?: string) : void { - this.log(LogLevel.Fatal, message, data, profile); + public fatal(message: string | Error, data?: LogData, profile?: string): void { + this.log(LogLevel.Fatal, message, data, profile) } - public emergency(message: string | Error, data?: LogData, profile?: string) : void { - this.log(LogLevel.Emergency, message, data, profile); + public emergency(message: string | Error, data?: LogData, profile?: string): void { + this.log(LogLevel.Emergency, message, data, profile) } - public startProfile(id: string) : void { - this.logger.profile(id); + public startProfile(id: string): void { + this.logger.profile(id) } } - - diff --git a/libs/nest-cli.json b/libs/nest-cli.json index eae42f5bc..a75229f97 100644 --- a/libs/nest-cli.json +++ b/libs/nest-cli.json @@ -13,4 +13,4 @@ "compilerOptions": { "webpack": true } -} \ No newline at end of file +} diff --git a/libs/org-roles/enums/index.ts b/libs/org-roles/enums/index.ts index 298bc93b4..6d2604614 100644 --- a/libs/org-roles/enums/index.ts +++ b/libs/org-roles/enums/index.ts @@ -1,10 +1,10 @@ export enum OrgRoles { - OWNER = 'owner', - SUPER_ADMIN = 'super_admin', - ADMIN = 'admin', - ISSUER = 'issuer', - VERIFIER = 'verifier', - HOLDER = 'holder', - MEMBER = 'member', - PLATFORM_ADMIN = 'platform_admin', -} \ No newline at end of file + OWNER = 'owner', + SUPER_ADMIN = 'super_admin', + ADMIN = 'admin', + ISSUER = 'issuer', + VERIFIER = 'verifier', + HOLDER = 'holder', + MEMBER = 'member', + PLATFORM_ADMIN = 'platform_admin', +} diff --git a/libs/org-roles/interfaces/org-roles.interface.ts b/libs/org-roles/interfaces/org-roles.interface.ts index ec63e63c1..3d8d55315 100644 --- a/libs/org-roles/interfaces/org-roles.interface.ts +++ b/libs/org-roles/interfaces/org-roles.interface.ts @@ -1,9 +1,9 @@ export interface IOrgRoles { - id: string; - name: string; - description: string; - createDateTime?: Date; - createdBy?: string; - lastChangedDateTime?: Date; - lastChangedBy?: string; -} \ No newline at end of file + id: string + name: string + description: string + createDateTime?: Date + createdBy?: string + lastChangedDateTime?: Date + lastChangedBy?: string +} diff --git a/libs/org-roles/repositories/index.ts b/libs/org-roles/repositories/index.ts index 37b160774..08371ab61 100644 --- a/libs/org-roles/repositories/index.ts +++ b/libs/org-roles/repositories/index.ts @@ -1,63 +1,63 @@ -import { Injectable, InternalServerErrorException, Logger } from '@nestjs/common'; +import { Injectable, InternalServerErrorException, type Logger } from '@nestjs/common' -import { PrismaService } from '@credebl/prisma-service'; +import type { PrismaService } from '@credebl/prisma-service' // eslint-disable-next-line camelcase -import { org_roles } from '@prisma/client'; -import { OrgRoles } from '../enums'; -import { IOrgRoles } from '../interfaces/org-roles.interface'; +import type { org_roles } from '@prisma/client' +import { OrgRoles } from '../enums' +import type { IOrgRoles } from '../interfaces/org-roles.interface' @Injectable() export class OrgRolesRepository { - constructor(private readonly prisma: PrismaService, private readonly logger: Logger) {} + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger + ) {} // eslint-disable-next-line camelcase async getRole(roleName: string): Promise { try { const roleDetails = await this.prisma.org_roles.findFirst({ where: { - name: roleName - } - }); - return roleDetails; + name: roleName, + }, + }) + return roleDetails } catch (error) { - this.logger.error(`In get role repository: ${JSON.stringify(error)}`); - throw new InternalServerErrorException('Bad Request'); + this.logger.error(`In get role repository: ${JSON.stringify(error)}`) + throw new InternalServerErrorException('Bad Request') } } - - - async getOrgRoles(): Promise { - try { - const roleDetails = await this.prisma.org_roles.findMany(); - const filteredRoles = roleDetails.filter(role => role.name !== OrgRoles.PLATFORM_ADMIN); - return filteredRoles; - } catch (error) { - this.logger.error(`In get org-roles repository: ${JSON.stringify(error)}`); - throw new InternalServerErrorException('Bad Request'); - - } + async getOrgRoles(): Promise { + try { + const roleDetails = await this.prisma.org_roles.findMany() + const filteredRoles = roleDetails.filter((role) => role.name !== OrgRoles.PLATFORM_ADMIN) + return filteredRoles + } catch (error) { + this.logger.error(`In get org-roles repository: ${JSON.stringify(error)}`) + throw new InternalServerErrorException('Bad Request') } + } - // eslint-disable-next-line camelcase + // eslint-disable-next-line camelcase async getOrgRolesByIds(orgRoles: string[]): Promise { - try { - const roleDetails = await this.prisma.org_roles.findMany({ - where: { - id:{ - in:orgRoles - } - }, - select: { - id: true, - name: true, - description: true - } - }); - return roleDetails; - } catch (error) { - this.logger.error(`In get org-roles by id repository : ${JSON.stringify(error)}`); - throw error; - } + try { + const roleDetails = await this.prisma.org_roles.findMany({ + where: { + id: { + in: orgRoles, + }, + }, + select: { + id: true, + name: true, + description: true, + }, + }) + return roleDetails + } catch (error) { + this.logger.error(`In get org-roles by id repository : ${JSON.stringify(error)}`) + throw error } -} \ No newline at end of file + } +} diff --git a/libs/org-roles/src/index.ts b/libs/org-roles/src/index.ts index 50cd30f84..7cc6f0dc8 100644 --- a/libs/org-roles/src/index.ts +++ b/libs/org-roles/src/index.ts @@ -1,2 +1,2 @@ -export * from './org-roles.module'; -export * from './org-roles.service'; +export * from './org-roles.module' +export * from './org-roles.service' diff --git a/libs/org-roles/src/org-roles.module.ts b/libs/org-roles/src/org-roles.module.ts index a53dff126..3f0413876 100644 --- a/libs/org-roles/src/org-roles.module.ts +++ b/libs/org-roles/src/org-roles.module.ts @@ -1,11 +1,11 @@ -import { PrismaService } from '@credebl/prisma-service'; -import { Logger } from '@nestjs/common'; -import { Module } from '@nestjs/common'; -import { OrgRolesRepository } from '../repositories'; -import { OrgRolesService } from './org-roles.service'; +import { PrismaService } from '@credebl/prisma-service' +import { Logger } from '@nestjs/common' +import { Module } from '@nestjs/common' +import { OrgRolesRepository } from '../repositories' +import { OrgRolesService } from './org-roles.service' @Module({ providers: [OrgRolesService, OrgRolesRepository, Logger, PrismaService], - exports: [OrgRolesService] + exports: [OrgRolesService], }) export class OrgRolesModule {} diff --git a/libs/org-roles/src/org-roles.service.ts b/libs/org-roles/src/org-roles.service.ts index a7ce01cdf..081e2ff57 100644 --- a/libs/org-roles/src/org-roles.service.ts +++ b/libs/org-roles/src/org-roles.service.ts @@ -1,25 +1,27 @@ -import { Injectable } from '@nestjs/common'; -import { Logger } from '@nestjs/common'; -import { OrgRolesRepository } from '../repositories'; +import { Injectable } from '@nestjs/common' +import type { Logger } from '@nestjs/common' // eslint-disable-next-line camelcase -import { org_roles } from '@prisma/client'; -import { IOrgRoles } from '../interfaces/org-roles.interface'; +import type { org_roles } from '@prisma/client' +import type { IOrgRoles } from '../interfaces/org-roles.interface' +import type { OrgRolesRepository } from '../repositories' @Injectable() export class OrgRolesService { - - constructor(private readonly orgRoleRepository: OrgRolesRepository, private readonly logger: Logger) { } + constructor( + private readonly orgRoleRepository: OrgRolesRepository, + private readonly logger: Logger + ) {} - // eslint-disable-next-line camelcase - async getRole(roleName: string): Promise { - return this.orgRoleRepository.getRole(roleName); - } + // eslint-disable-next-line camelcase + async getRole(roleName: string): Promise { + return this.orgRoleRepository.getRole(roleName) + } - async getOrgRoles(): Promise< IOrgRoles[]> { - return this.orgRoleRepository.getOrgRoles(); - } + async getOrgRoles(): Promise { + return this.orgRoleRepository.getOrgRoles() + } - // eslint-disable-next-line camelcase - async getOrgRolesByIds(orgRoleIds: string[]): Promise { - return this.orgRoleRepository.getOrgRolesByIds(orgRoleIds); - } + // eslint-disable-next-line camelcase + async getOrgRolesByIds(orgRoleIds: string[]): Promise { + return this.orgRoleRepository.getOrgRolesByIds(orgRoleIds) + } } diff --git a/libs/org-roles/tsconfig.lib.json b/libs/org-roles/tsconfig.lib.json index c9d40a1d0..56723e0f3 100644 --- a/libs/org-roles/tsconfig.lib.json +++ b/libs/org-roles/tsconfig.lib.json @@ -6,4 +6,4 @@ }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] -} \ No newline at end of file +} diff --git a/libs/prisma-service/cli.ts b/libs/prisma-service/cli.ts index 668a6358c..4e6a45c4e 100644 --- a/libs/prisma-service/cli.ts +++ b/libs/prisma-service/cli.ts @@ -3,106 +3,102 @@ /* eslint-disable @typescript-eslint/no-var-requires */ // eslint-disable-next-line camelcase -const {createInterface} = require('readline'); +const { createInterface } = require('readline') -const { PrismaClient } = require('@prisma/client'); -const { createClient } = require('@supabase/supabase-js'); +const { PrismaClient } = require('@prisma/client') +const { createClient } = require('@supabase/supabase-js') -const prisma = new PrismaClient(); +const prisma = new PrismaClient() -const clientInstance = createClient( - process.env.SUPABASE_URL, - process.env.SUPABASE_KEY, - { - auth: { - persistSession: false //or true - } - } -); +const clientInstance = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY, { + auth: { + persistSession: false, //or true + }, +}) const readline = createInterface({ input: process.stdin, - output: process.stdout -}); + output: process.stdout, +}) -const readLineAsync = msg => new Promise(resolve => { - readline.question(msg, userRes => { - resolve(userRes); - }); - }); +const readLineAsync = (msg) => + new Promise((resolve) => { + readline.question(msg, (userRes) => { + resolve(userRes) + }) + }) // eslint-disable-next-line camelcase const getRole = async (roleName) => { try { const roleDetails = await prisma.org_roles.findFirst({ where: { - name: roleName - } - }); - return roleDetails; + name: roleName, + }, + }) + return roleDetails } catch (error) { - console.error('An error occurred in getRole:', error); + console.error('An error occurred in getRole:', error) } -}; +} -const createUserOrgRole = async(userId, roleId) => { +const createUserOrgRole = async (userId, roleId) => { try { const data = { orgRole: { connect: { id: roleId } }, - user: { connect: { id: userId } } - }; + user: { connect: { id: userId } }, + } const saveResponse = await prisma.user_org_roles.create({ - data - }); + data, + }) - return saveResponse; + return saveResponse } catch (error) { - console.error('An error occurred in createUserOrgRole:', error); + console.error('An error occurred in createUserOrgRole:', error) } -}; +} const createUser = async () => { - const firstName = await readLineAsync('Enter your first name: '); - const lastName = await readLineAsync('Enter your last name: '); - const email = await readLineAsync('Enter email address: '); - const password = await readLineAsync('Enter your password: '); + const firstName = await readLineAsync('Enter your first name: ') + const lastName = await readLineAsync('Enter your last name: ') + const email = await readLineAsync('Enter email address: ') + const password = await readLineAsync('Enter your password: ') try { const supaUser = await clientInstance.auth.signUp({ email: email.toString(), - password: password.toString() - }); + password: password.toString(), + }) - const supaId = supaUser.data?.user?.id; + const supaId = supaUser.data?.user?.id const user = await prisma.user.create({ data: { - 'firstName': firstName.toString(), - 'lastName': lastName.toString(), - 'email': email.toString(), - 'username': email.toString(), - 'password': '', - 'verificationCode': '', - 'isEmailVerified': true, - 'supabaseUserId': supaId - } - }); - - const platformRoleData = await getRole('platform_admin'); - - await createUserOrgRole(user.id, platformRoleData['id']); - - console.log('Platform admin user created'); - -} catch (e) { - console.error('An error occurred in createUser:', e); + firstName: firstName.toString(), + lastName: lastName.toString(), + email: email.toString(), + username: email.toString(), + password: '', + verificationCode: '', + isEmailVerified: true, + supabaseUserId: supaId, + }, + }) + + const platformRoleData = await getRole('platform_admin') + + await createUserOrgRole(user.id, platformRoleData.id) + + console.log('Platform admin user created') + } catch (e) { + console.error('An error occurred in createUser:', e) + } } -}; async function main() { - await createUser(); - readline.close(); + await createUser() + readline.close() } -main().catch((e) => console.error(e)); +main().catch((e) => console.error(e)) diff --git a/libs/prisma-service/prisma/seed.ts b/libs/prisma-service/prisma/seed.ts index 22919fec1..f3cb79888 100644 --- a/libs/prisma-service/prisma/seed.ts +++ b/libs/prisma-service/prisma/seed.ts @@ -1,507 +1,491 @@ -import * as fs from 'fs'; +import * as fs from 'fs' -import { Logger } from '@nestjs/common'; -import { PrismaClient } from '@prisma/client'; -import { CommonConstants } from '../../common/src/common.constant'; -import * as CryptoJS from 'crypto-js'; -import { exec } from 'child_process'; -import * as util from 'util'; -const execPromise = util.promisify(exec); +import { exec } from 'child_process' +import * as util from 'util' +import { Logger } from '@nestjs/common' +import { PrismaClient } from '@prisma/client' +import * as CryptoJS from 'crypto-js' +import { CommonConstants } from '../../common/src/common.constant' +const execPromise = util.promisify(exec) -const prisma = new PrismaClient(); -const logger = new Logger('Init seed DB'); -let platformUserId = ''; +const prisma = new PrismaClient() +const logger = new Logger('Init seed DB') +let platformUserId = '' -const configData = fs.readFileSync(`${process.cwd()}/prisma/data/credebl-master-table.json`, 'utf8'); +const configData = fs.readFileSync(`${process.cwd()}/prisma/data/credebl-master-table.json`, 'utf8') const createPlatformConfig = async (): Promise => { - try { - const existPlatformAdmin = await prisma.platform_config.findMany(); - - if (0 === existPlatformAdmin.length) { - const { platformConfigData } = JSON.parse(configData); - const platformConfig = await prisma.platform_config.create({ - data: platformConfigData - }); - - logger.log(platformConfig); - } else { - logger.log('Already seeding in platform config'); - } - } catch (error) { - logger.error('An error occurred seeding platformConfig:', error); - throw error; + try { + const existPlatformAdmin = await prisma.platform_config.findMany() + + if (existPlatformAdmin.length === 0) { + const { platformConfigData } = JSON.parse(configData) + const platformConfig = await prisma.platform_config.create({ + data: platformConfigData, + }) + + logger.log(platformConfig) + } else { + logger.log('Already seeding in platform config') } -}; + } catch (error) { + logger.error('An error occurred seeding platformConfig:', error) + throw error + } +} const createOrgRoles = async (): Promise => { - try { - const { orgRoleData } = JSON.parse(configData); - const roleNames = orgRoleData.map(role => role.name); - const existOrgRole = await prisma.org_roles.findMany({ - where: { - name: { - in: roleNames - } - } - }); - - if (0 === existOrgRole.length) { - const orgRoles = await prisma.org_roles.createMany({ - data: orgRoleData - }); - - logger.log(orgRoles); - } else { - logger.log('Already seeding in org role'); - } + try { + const { orgRoleData } = JSON.parse(configData) + const roleNames = orgRoleData.map((role) => role.name) + const existOrgRole = await prisma.org_roles.findMany({ + where: { + name: { + in: roleNames, + }, + }, + }) + + if (existOrgRole.length === 0) { + const orgRoles = await prisma.org_roles.createMany({ + data: orgRoleData, + }) - } catch (error) { - logger.error('An error occurred seeding orgRoles:', error); - throw error; + logger.log(orgRoles) + } else { + logger.log('Already seeding in org role') } -}; + } catch (error) { + logger.error('An error occurred seeding orgRoles:', error) + throw error + } +} const createAgentTypes = async (): Promise => { - try { - const { agentTypeData } = JSON.parse(configData); - - const agentType = agentTypeData.map(agentType => agentType.agent); - const existAgentType = await prisma.agents_type.findMany({ - where: { - agent: { - in: agentType - } - } - }); - - if (0 === existAgentType.length) { - const agentTypes = await prisma.agents_type.createMany({ - data: agentTypeData - }); - - logger.log(agentTypes); - } else { - logger.log('Already seeding in agent type'); - } + try { + const { agentTypeData } = JSON.parse(configData) + + const agentType = agentTypeData.map((agentType) => agentType.agent) + const existAgentType = await prisma.agents_type.findMany({ + where: { + agent: { + in: agentType, + }, + }, + }) + if (existAgentType.length === 0) { + const agentTypes = await prisma.agents_type.createMany({ + data: agentTypeData, + }) - } catch (error) { - logger.error('An error occurred seeding agentTypes:', error); - throw error; + logger.log(agentTypes) + } else { + logger.log('Already seeding in agent type') } -}; + } catch (error) { + logger.error('An error occurred seeding agentTypes:', error) + throw error + } +} const createOrgAgentTypes = async (): Promise => { - try { - const { orgAgentTypeData } = JSON.parse(configData); - const orgAgentType = orgAgentTypeData.map(orgAgentType => orgAgentType.agent); - const existAgentType = await prisma.org_agents_type.findMany({ - where: { - agent: { - in: orgAgentType - } - } - }); - - if (0 === existAgentType.length) { - const orgAgentTypes = await prisma.org_agents_type.createMany({ - data: orgAgentTypeData - }); - - logger.log(orgAgentTypes); - } else { - logger.log('Already seeding in org agent type'); - } + try { + const { orgAgentTypeData } = JSON.parse(configData) + const orgAgentType = orgAgentTypeData.map((orgAgentType) => orgAgentType.agent) + const existAgentType = await prisma.org_agents_type.findMany({ + where: { + agent: { + in: orgAgentType, + }, + }, + }) + if (existAgentType.length === 0) { + const orgAgentTypes = await prisma.org_agents_type.createMany({ + data: orgAgentTypeData, + }) - } catch (error) { - logger.error('An error occurred seeding orgAgentTypes:', error); - throw error; + logger.log(orgAgentTypes) + } else { + logger.log('Already seeding in org agent type') } -}; + } catch (error) { + logger.error('An error occurred seeding orgAgentTypes:', error) + throw error + } +} 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 existPlatformAdminUser = await prisma.user.findMany({ - where: { - email: platformAdminData.email - } - }); - - if (0 === existPlatformAdminUser.length) { - const platformUser = await prisma.user.create({ - data: platformAdminData - }); + try { + const { platformAdminData } = JSON.parse(configData) + platformAdminData.email = process.env.PLATFORM_ADMIN_EMAIL + platformAdminData.username = process.env.PLATFORM_ADMIN_EMAIL + + const existPlatformAdminUser = await prisma.user.findMany({ + where: { + email: platformAdminData.email, + }, + }) - platformUserId = platformUser.id; + if (existPlatformAdminUser.length === 0) { + const platformUser = await prisma.user.create({ + data: platformAdminData, + }) - logger.log(platformUser); - } else { - logger.log('Already seeding in user'); - } + platformUserId = platformUser.id - } catch (error) { - logger.error('An error occurred seeding platformUser:', error); - throw error; + logger.log(platformUser) + } else { + logger.log('Already seeding in user') } -}; - + } catch (error) { + logger.error('An error occurred seeding platformUser:', error) + throw error + } +} const createPlatformOrganization = async (): Promise => { - try { - const { platformAdminOrganizationData } = JSON.parse(configData); - platformAdminOrganizationData.createdBy = platformUserId; - platformAdminOrganizationData.lastChangedBy = platformUserId; - - const existPlatformAdminUser = await prisma.organisation.findMany({ - where: { - name: platformAdminOrganizationData.name - } - }); - - if (0 === existPlatformAdminUser.length) { - const platformOrganization = await prisma.organisation.create({ - data: platformAdminOrganizationData - }); - - logger.log(platformOrganization); - } else { - logger.log('Already seeding in organization'); - } + try { + const { platformAdminOrganizationData } = JSON.parse(configData) + platformAdminOrganizationData.createdBy = platformUserId + platformAdminOrganizationData.lastChangedBy = platformUserId + + const existPlatformAdminUser = await prisma.organisation.findMany({ + where: { + name: platformAdminOrganizationData.name, + }, + }) - } catch (error) { - logger.error('An error occurred seeding platformOrganization:', error); - throw error; + if (existPlatformAdminUser.length === 0) { + const platformOrganization = await prisma.organisation.create({ + data: platformAdminOrganizationData, + }) + + logger.log(platformOrganization) + } else { + logger.log('Already seeding in organization') } -}; + } catch (error) { + logger.error('An error occurred seeding platformOrganization:', error) + throw error + } +} const createPlatformUserOrgRoles = async (): Promise => { - try { - - const userId = await prisma.user.findUnique({ - where: { - email: `${CommonConstants.PLATFORM_ADMIN_EMAIL}` - } - }); - - const orgId = await prisma.organisation.findFirst({ - where: { - name: `${CommonConstants.PLATFORM_ADMIN_ORG}` - } - }); - - const orgRoleId = await prisma.org_roles.findUnique({ - where: { - name: `${CommonConstants.PLATFORM_ADMIN_ORG_ROLE}` - } - }); - - if (!userId && !orgId && !orgRoleId) { - const platformOrganization = await prisma.user_org_roles.create({ - data: { - userId: userId.id, - orgRoleId: orgRoleId.id, - orgId: orgId.id - } - }); - logger.log(platformOrganization); - } else { - logger.log('Already seeding in org_roles'); - } + try { + const userId = await prisma.user.findUnique({ + where: { + email: `${CommonConstants.PLATFORM_ADMIN_EMAIL}`, + }, + }) + const orgId = await prisma.organisation.findFirst({ + where: { + name: `${CommonConstants.PLATFORM_ADMIN_ORG}`, + }, + }) + + const orgRoleId = await prisma.org_roles.findUnique({ + where: { + name: `${CommonConstants.PLATFORM_ADMIN_ORG_ROLE}`, + }, + }) - } catch (error) { - logger.error('An error occurred seeding platformOrganization:', error); - throw error; + if (!userId && !orgId && !orgRoleId) { + const platformOrganization = await prisma.user_org_roles.create({ + data: { + userId: userId.id, + orgRoleId: orgRoleId.id, + orgId: orgId.id, + }, + }) + logger.log(platformOrganization) + } else { + logger.log('Already seeding in org_roles') } -}; + } catch (error) { + logger.error('An error occurred seeding platformOrganization:', error) + throw error + } +} const createLedger = async (): Promise => { - try { - const { ledgerData } = JSON.parse(configData); - - const existingLedgers = await prisma.ledgers.findMany(); - - if (0 === existingLedgers.length) { - const createLedger = await prisma.ledgers.createMany({ - data: ledgerData - }); - logger.log('All ledgers inserted:', createLedger); - } else { - const updatesNeeded = []; - - if (existingLedgers.length !== ledgerData.length) { - updatesNeeded.push(ledgerData); - if (0 < updatesNeeded.length) { - await prisma.ledgers.deleteMany(); - - const createLedger = await prisma.ledgers.createMany({ - data: ledgerData - }); - logger.log('Updated ledgers:', createLedger); - } else { - logger.log('No changes in ledger data'); - } + try { + const { ledgerData } = JSON.parse(configData) + + const existingLedgers = await prisma.ledgers.findMany() + + if (existingLedgers.length === 0) { + const createLedger = await prisma.ledgers.createMany({ + data: ledgerData, + }) + logger.log('All ledgers inserted:', createLedger) + } else { + const updatesNeeded = [] + + if (existingLedgers.length !== ledgerData.length) { + updatesNeeded.push(ledgerData) + if (updatesNeeded.length > 0) { + await prisma.ledgers.deleteMany() + + const createLedger = await prisma.ledgers.createMany({ + data: ledgerData, + }) + logger.log('Updated ledgers:', createLedger) } else { - logger.log('No changes in ledger data'); + logger.log('No changes in ledger data') } + } else { + logger.log('No changes in ledger data') } - } catch (error) { - logger.error('An error occurred seeding createLedger:', error); - throw error; } - }; + } catch (error) { + logger.error('An error occurred seeding createLedger:', error) + throw error + } +} const createLedgerConfig = async (): Promise => { - try { - const { ledgerConfig } = JSON.parse(configData); - - const ledgerConfigList = await prisma.ledgerConfig.findMany(); - - const checkDataIsEqual = (ledgerConfig, ledgerConfigList): boolean => { - if (ledgerConfig.length !== ledgerConfigList.length) { - return false; - } - - for (let i = 0; i < ledgerConfig.length; i++) { - const config1 = ledgerConfig[i]; - const config2 = ledgerConfigList.find(item => item.name === config1.name && JSON.stringify(item.details) === JSON.stringify(config1.details)); - - if (!config2) { - return false; - } - } - return true; - }; - - if (0 === ledgerConfigList.length) { - const configDetails = await prisma.ledgerConfig.createMany({ - data: ledgerConfig - }); - logger.log('Ledger config created:', configDetails); - - } else if (!checkDataIsEqual(ledgerConfig, ledgerConfigList)) { - await prisma.ledgerConfig.deleteMany({}); - const configDetails = await prisma.ledgerConfig.createMany({ - data: ledgerConfig - }); - logger.log('Existing ledger config deleted and new ones created:', configDetails); - } else { - logger.log('Already seeding in ledger config'); + try { + const { ledgerConfig } = JSON.parse(configData) + + const ledgerConfigList = await prisma.ledgerConfig.findMany() + + const checkDataIsEqual = (ledgerConfig, ledgerConfigList): boolean => { + if (ledgerConfig.length !== ledgerConfigList.length) { + return false + } + + for (let i = 0; i < ledgerConfig.length; i++) { + const config1 = ledgerConfig[i] + const config2 = ledgerConfigList.find( + (item) => item.name === config1.name && JSON.stringify(item.details) === JSON.stringify(config1.details) + ) + + if (!config2) { + return false } - } catch (error) { - logger.error('An error occurred while configuring ledger:', error); - throw error; + } + return true } -}; + + if (ledgerConfigList.length === 0) { + const configDetails = await prisma.ledgerConfig.createMany({ + data: ledgerConfig, + }) + logger.log('Ledger config created:', configDetails) + } else if (!checkDataIsEqual(ledgerConfig, ledgerConfigList)) { + await prisma.ledgerConfig.deleteMany({}) + const configDetails = await prisma.ledgerConfig.createMany({ + data: ledgerConfig, + }) + logger.log('Existing ledger config deleted and new ones created:', configDetails) + } else { + logger.log('Already seeding in ledger config') + } + } catch (error) { + logger.error('An error occurred while configuring ledger:', error) + throw error + } +} const createUserRole = async (): Promise => { - try { - const { userRoleData } = JSON.parse(configData); - - const userRoleDetails = userRoleData.map(userRole => userRole.role); - const existUserRole = await prisma.user_role.findMany({ - where: { - role: { - in: userRoleDetails - } - } - }); - - if (0 === existUserRole.length) { - const userRole = await prisma.user_role.createMany({ - data: userRoleData - }); - - logger.log(userRole); - } else { - logger.log('Already seeding in user role'); - } + try { + const { userRoleData } = JSON.parse(configData) + + const userRoleDetails = userRoleData.map((userRole) => userRole.role) + const existUserRole = await prisma.user_role.findMany({ + where: { + role: { + in: userRoleDetails, + }, + }, + }) + if (existUserRole.length === 0) { + const userRole = await prisma.user_role.createMany({ + data: userRoleData, + }) - } catch (error) { - logger.error('An error occurred seeding user role:', error); - throw error; + logger.log(userRole) + } else { + logger.log('Already seeding in user role') } -}; + } catch (error) { + logger.error('An error occurred seeding user role:', error) + throw error + } +} const migrateOrgAgentDids = async (): Promise => { - try { - const orgAgents = await prisma.org_agents.findMany({ - where: { - walletName: { - not: 'platform-admin' - } - } - }); - - const orgDids = orgAgents.map((agent) => agent.orgDid).filter((did) => null !== did && '' !== did); - const existingDids = await prisma.org_dids.findMany({ - where: { - did: { - in: orgDids - } - } - }); - - const filteredOrgAgents = orgAgents.filter( - (agent) => null !== agent.orgDid && '' !== agent.orgDid - ); - - // If there are org DIDs that do not exist in org_dids table - if (orgDids.length !== existingDids.length) { - const newOrgAgents = filteredOrgAgents.filter( - (agent) => !existingDids.some((did) => did.did === agent.orgDid) - ); - - const newDidRecords = newOrgAgents.map((agent) => ({ - orgId: agent.orgId, - did: agent.orgDid, - didDocument: agent.didDocument, - isPrimaryDid: true, - createdBy: agent.createdBy, - lastChangedBy: agent.lastChangedBy, - orgAgentId: agent.id - })); - - const didInsertResult = await prisma.org_dids.createMany({ - data: newDidRecords - }); - - logger.log(didInsertResult); - } else { - logger.log('No new DIDs to migrate in migrateOrgAgentDids'); - } - } catch (error) { - logger.error('An error occurred during migrateOrgAgentDids:', error); - throw error; + try { + const orgAgents = await prisma.org_agents.findMany({ + where: { + walletName: { + not: 'platform-admin', + }, + }, + }) + + const orgDids = orgAgents.map((agent) => agent.orgDid).filter((did) => did !== null && did !== '') + const existingDids = await prisma.org_dids.findMany({ + where: { + did: { + in: orgDids, + }, + }, + }) + + const filteredOrgAgents = orgAgents.filter((agent) => agent.orgDid !== null && agent.orgDid !== '') + + // If there are org DIDs that do not exist in org_dids table + if (orgDids.length !== existingDids.length) { + const newOrgAgents = filteredOrgAgents.filter((agent) => !existingDids.some((did) => did.did === agent.orgDid)) + + const newDidRecords = newOrgAgents.map((agent) => ({ + orgId: agent.orgId, + did: agent.orgDid, + didDocument: agent.didDocument, + isPrimaryDid: true, + createdBy: agent.createdBy, + lastChangedBy: agent.lastChangedBy, + orgAgentId: agent.id, + })) + + const didInsertResult = await prisma.org_dids.createMany({ + data: newDidRecords, + }) + + logger.log(didInsertResult) + } else { + logger.log('No new DIDs to migrate in migrateOrgAgentDids') } -}; + } catch (error) { + logger.error('An error occurred during migrateOrgAgentDids:', error) + throw error + } +} const addSchemaType = async (): Promise => { - try { - const emptyTypeSchemaList = await prisma.schema.findMany({ - where: { - OR: [ - { type: null }, - { type: '' } - ] - } - }); - if (0 < emptyTypeSchemaList.length) { - const updatePromises = emptyTypeSchemaList.map((schema) => prisma.schema.update({ - where: { id: schema.id }, - data: { type: 'indy' } - }) - ); - await Promise.all(updatePromises); - - logger.log('Schemas updated successfully'); - } else { - logger.log('No schemas to update'); - } - } catch (error) { - logger.error('An error occurred during addSchemaType:', error); - throw error; + try { + const emptyTypeSchemaList = await prisma.schema.findMany({ + where: { + OR: [{ type: null }, { type: '' }], + }, + }) + if (emptyTypeSchemaList.length > 0) { + const updatePromises = emptyTypeSchemaList.map((schema) => + prisma.schema.update({ + where: { id: schema.id }, + data: { type: 'indy' }, + }) + ) + await Promise.all(updatePromises) + + logger.log('Schemas updated successfully') + } else { + logger.log('No schemas to update') } -}; + } catch (error) { + logger.error('An error occurred during addSchemaType:', error) + throw error + } +} const importGeoLocationMasterData = async (): Promise => { - try { - const scriptPath = process.env.GEO_LOCATION_MASTER_DATA_IMPORT_SCRIPT; - const dbUrl = process.env.DATABASE_URL; - - if (!scriptPath || !dbUrl) { - throw new Error('Environment variables GEO_LOCATION_MASTER_DATA_IMPORT_SCRIPT or DATABASE_URL are not set.'); - } - - const command = `${process.cwd()}/${scriptPath} ${dbUrl}`; - - const { stdout, stderr } = await execPromise(command); - - if (stdout) { - logger.log(`Shell script output: ${stdout}`); - } - if (stderr) { - logger.error(`Shell script error: ${stderr}`); - } - } catch (error) { - logger.error('An error occurred during importGeoLocationMasterData:', error); - throw error; + try { + const scriptPath = process.env.GEO_LOCATION_MASTER_DATA_IMPORT_SCRIPT + const dbUrl = process.env.DATABASE_URL + + if (!scriptPath || !dbUrl) { + throw new Error('Environment variables GEO_LOCATION_MASTER_DATA_IMPORT_SCRIPT or DATABASE_URL are not set.') } - }; -const encryptClientCredential = async (clientCredential: string): Promise => { - try { - const encryptedToken = CryptoJS.AES.encrypt(JSON.stringify(clientCredential), process.env.CRYPTO_PRIVATE_KEY).toString(); + const command = `${process.cwd()}/${scriptPath} ${dbUrl}` + + const { stdout, stderr } = await execPromise(command) - return encryptedToken; - } catch (error) { - logger.error('An error occurred during encryptClientCredential:', error); - throw error; + if (stdout) { + logger.log(`Shell script output: ${stdout}`) + } + if (stderr) { + logger.error(`Shell script error: ${stderr}`) } -}; + } catch (error) { + logger.error('An error occurred during importGeoLocationMasterData:', error) + throw error + } +} + +const encryptClientCredential = async (clientCredential: string): Promise => { + try { + const encryptedToken = CryptoJS.AES.encrypt( + JSON.stringify(clientCredential), + process.env.CRYPTO_PRIVATE_KEY + ).toString() + + return encryptedToken + } catch (error) { + logger.error('An error occurred during encryptClientCredential:', error) + throw error + } +} const updateClientCredential = async (): Promise => { - try { - const scriptPath = process.env.UPDATE_CLIENT_CREDENTIAL_SCRIPT; - const dbUrl = process.env.DATABASE_URL; - const clientId = process.env.KEYCLOAK_MANAGEMENT_CLIENT_ID; - const clientSecret = process.env.KEYCLOAK_MANAGEMENT_CLIENT_SECRET; - - if (!scriptPath || !dbUrl || !clientId || !clientSecret) { - throw new Error('Environment variables UPDATE_CLIENT_CREDENTIAL_SCRIPT or DATABASE_URL or clientId or clientSecret are not set.'); - } - - const encryptedClientId = await encryptClientCredential(process.env.KEYCLOAK_MANAGEMENT_CLIENT_ID); - const encryptedClientSecret = await encryptClientCredential(process.env.KEYCLOAK_MANAGEMENT_CLIENT_SECRET); - - const command = `${process.cwd()}/${scriptPath} ${dbUrl} ${encryptedClientId} ${encryptedClientSecret}`; - - const { stdout, stderr } = await execPromise(command); - - if (stdout) { - logger.log(`Shell script output: ${stdout}`); - } - if (stderr) { - logger.error(`Shell script error: ${stderr}`); - } - - } catch (error) { - logger.error('An error occurred during updateClientCredential:', error); - throw error; + try { + const scriptPath = process.env.UPDATE_CLIENT_CREDENTIAL_SCRIPT + const dbUrl = process.env.DATABASE_URL + const clientId = process.env.KEYCLOAK_MANAGEMENT_CLIENT_ID + const clientSecret = process.env.KEYCLOAK_MANAGEMENT_CLIENT_SECRET + + if (!scriptPath || !dbUrl || !clientId || !clientSecret) { + throw new Error( + 'Environment variables UPDATE_CLIENT_CREDENTIAL_SCRIPT or DATABASE_URL or clientId or clientSecret are not set.' + ) } -}; + const encryptedClientId = await encryptClientCredential(process.env.KEYCLOAK_MANAGEMENT_CLIENT_ID) + const encryptedClientSecret = await encryptClientCredential(process.env.KEYCLOAK_MANAGEMENT_CLIENT_SECRET) -async function main(): Promise { + const command = `${process.cwd()}/${scriptPath} ${dbUrl} ${encryptedClientId} ${encryptedClientSecret}` + + const { stdout, stderr } = await execPromise(command) + + if (stdout) { + logger.log(`Shell script output: ${stdout}`) + } + if (stderr) { + logger.error(`Shell script error: ${stderr}`) + } + } catch (error) { + logger.error('An error occurred during updateClientCredential:', error) + throw error + } +} - await createPlatformConfig(); - await createOrgRoles(); - await createAgentTypes(); - await createPlatformUser(); - await createPlatformOrganization(); - await createPlatformUserOrgRoles(); - await createOrgAgentTypes(); - await createLedger(); - await createLedgerConfig(); - await createUserRole(); - await migrateOrgAgentDids(); - await addSchemaType(); - await importGeoLocationMasterData(); - await updateClientCredential(); +async function main(): Promise { + await createPlatformConfig() + await createOrgRoles() + await createAgentTypes() + await createPlatformUser() + await createPlatformOrganization() + await createPlatformUserOrgRoles() + await createOrgAgentTypes() + await createLedger() + await createLedgerConfig() + await createUserRole() + await migrateOrgAgentDids() + await addSchemaType() + await importGeoLocationMasterData() + await updateClientCredential() } main() - .then(async () => { - await prisma.$disconnect(); - }) - .catch(async (error) => { - logger.error(`In prisma seed initialize`, error); - await prisma.$disconnect(); - process.exit(1); - }); \ No newline at end of file + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (error) => { + logger.error('In prisma seed initialize', error) + await prisma.$disconnect() + process.exit(1) + }) diff --git a/libs/prisma-service/src/index.ts b/libs/prisma-service/src/index.ts index cd925ece3..137e3b919 100644 --- a/libs/prisma-service/src/index.ts +++ b/libs/prisma-service/src/index.ts @@ -1,2 +1,2 @@ -export * from './prisma-service.module'; -export * from './prisma-service.service'; +export * from './prisma-service.module' +export * from './prisma-service.service' diff --git a/libs/prisma-service/src/prisma-service.module.ts b/libs/prisma-service/src/prisma-service.module.ts index 73c39b1d7..5dff4ffee 100644 --- a/libs/prisma-service/src/prisma-service.module.ts +++ b/libs/prisma-service/src/prisma-service.module.ts @@ -1,8 +1,8 @@ -import { Module } from '@nestjs/common'; -import { PrismaService } from './prisma-service.service'; +import { Module } from '@nestjs/common' +import { PrismaService } from './prisma-service.service' @Module({ providers: [PrismaService], - exports: [PrismaService] + exports: [PrismaService], }) export class PrismaServiceModule {} diff --git a/libs/prisma-service/src/prisma-service.service.ts b/libs/prisma-service/src/prisma-service.service.ts index 5acc4e3d1..adfc2dc15 100644 --- a/libs/prisma-service/src/prisma-service.service.ts +++ b/libs/prisma-service/src/prisma-service.service.ts @@ -1,13 +1,11 @@ -import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common'; -import { PrismaClient } from '@prisma/client'; +import { type INestApplication, Injectable, type OnModuleInit } from '@nestjs/common' +import { PrismaClient } from '@prisma/client' @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { - UserDevicesRepository: any; async onModuleInit(): Promise { - await this.$connect(); + await this.$connect() } - async enableShutdownHooks(app: INestApplication): Promise { - } -} \ No newline at end of file + async enableShutdownHooks(_app: INestApplication): Promise {} +} diff --git a/libs/service/base.service.ts b/libs/service/base.service.ts index 6e95dc780..07dfc9886 100644 --- a/libs/service/base.service.ts +++ b/libs/service/base.service.ts @@ -1,9 +1,8 @@ -import { Logger } from '@nestjs/common'; +import { Logger } from '@nestjs/common' export class BaseService { - protected logger; - + protected logger + constructor(loggerName: string) { - this.logger = new Logger(loggerName); + this.logger = new Logger(loggerName) } - -} \ No newline at end of file +} diff --git a/libs/service/nats.options.ts b/libs/service/nats.options.ts index 6051ec0f3..d6fe85cdf 100644 --- a/libs/service/nats.options.ts +++ b/libs/service/nats.options.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -import { NatsOptions, Transport } from '@nestjs/microservices'; +import { type NatsOptions, Transport } from '@nestjs/microservices' // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const commonNatsOptions = (name: string, isClient = true) => { const common: NatsOptions = { @@ -8,11 +8,9 @@ export const commonNatsOptions = (name: string, isClient = true) => { url: `nats://${process.env.NATS_HOST}:${process.env.NATS_PORT}`, name, maxReconnectAttempts: -1, - reconnectTimeWait: 3000 - } - }; - const result = isClient - ? { ...common, options: { ...common.options, reconnect: true } } - : common; - return result; -}; + reconnectTimeWait: 3000, + }, + } + const result = isClient ? { ...common, options: { ...common.options, reconnect: true } } : common + return result +} diff --git a/libs/supabase/src/index.ts b/libs/supabase/src/index.ts index 1b4bbcdf4..8e0eae9e3 100644 --- a/libs/supabase/src/index.ts +++ b/libs/supabase/src/index.ts @@ -1,2 +1,2 @@ -export * from './supabase.module'; -export * from './supabase.service'; +export * from './supabase.module' +export * from './supabase.service' diff --git a/libs/supabase/src/supabase.module.ts b/libs/supabase/src/supabase.module.ts index 1cd0a3c77..096ec0646 100644 --- a/libs/supabase/src/supabase.module.ts +++ b/libs/supabase/src/supabase.module.ts @@ -1,8 +1,8 @@ -import { Module } from '@nestjs/common'; -import { SupabaseService } from './supabase.service'; +import { Module } from '@nestjs/common' +import { SupabaseService } from './supabase.service' @Module({ providers: [SupabaseService], - exports: [SupabaseService] + exports: [SupabaseService], }) export class SupabaseModule {} diff --git a/libs/supabase/src/supabase.service.ts b/libs/supabase/src/supabase.service.ts index 83acf5d6f..d4ee66e57 100644 --- a/libs/supabase/src/supabase.service.ts +++ b/libs/supabase/src/supabase.service.ts @@ -1,33 +1,26 @@ -import { Injectable, Logger, Scope } from '@nestjs/common'; -import { SupabaseClient, createClient } from '@supabase/supabase-js'; +import { Injectable, Logger, Scope } from '@nestjs/common' +import { type SupabaseClient, createClient } from '@supabase/supabase-js' @Injectable({ scope: Scope.REQUEST }) export class SupabaseService { + private readonly logger = new Logger(SupabaseService.name) + private clientInstance: SupabaseClient - private readonly logger = new Logger(SupabaseService.name); - private clientInstance: SupabaseClient; - constructor( - ) { } + // biome-ignore lint/suspicious/noExplicitAny: + getClient(): SupabaseClient { + this.logger.log('getting supabase client...') - // eslint-disable-next-line @typescript-eslint/no-explicit-any - getClient(): SupabaseClient { - this.logger.log('getting supabase client...'); - - if (this.clientInstance) { - this.logger.log('client exists - returning for current Scope.REQUEST'); - return this.clientInstance; - } + if (this.clientInstance) { + this.logger.log('client exists - returning for current Scope.REQUEST') + return this.clientInstance + } - this.logger.log('initialising new supabase client for new Scope.REQUEST'); + this.logger.log('initialising new supabase client for new Scope.REQUEST') - this.clientInstance = createClient( - - process.env.SUPABASE_URL, - process.env.SUPABASE_KEY - ); + this.clientInstance = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY) - this.logger.log('auth has been set!'); + this.logger.log('auth has been set!') - return this.clientInstance; - } + return this.clientInstance + } } diff --git a/libs/user-activity/interface/index.ts b/libs/user-activity/interface/index.ts index 87ba1685b..f0a8fb3af 100644 --- a/libs/user-activity/interface/index.ts +++ b/libs/user-activity/interface/index.ts @@ -1,9 +1,9 @@ export interface IUsersActivity { - id: string, - orgId: string, - userId: string, - details: string, - action: string, - lastChangedDateTime: Date, - createDateTime: Date, -} \ No newline at end of file + id: string + orgId: string + userId: string + details: string + action: string + lastChangedDateTime: Date + createDateTime: Date +} diff --git a/libs/user-activity/repositories/index.ts b/libs/user-activity/repositories/index.ts index 7895ea825..c3da44428 100644 --- a/libs/user-activity/repositories/index.ts +++ b/libs/user-activity/repositories/index.ts @@ -1,82 +1,88 @@ +import type { PrismaService } from '@credebl/prisma-service' /* eslint-disable camelcase */ -import { HttpException, Inject, Injectable, Logger } from '@nestjs/common'; -import { IUsersActivity} from '../interface'; -import { PrismaService } from '@credebl/prisma-service'; -import { RecordType, user, user_activity } from '@prisma/client'; -import { map } from 'rxjs'; -import { ClientProxy } from '@nestjs/microservices'; +import { HttpException, Inject, Injectable, type Logger } from '@nestjs/common' +import type { ClientProxy } from '@nestjs/microservices' +import type { RecordType, user, user_activity } from '@prisma/client' +import { map } from 'rxjs' +import type { IUsersActivity } from '../interface' @Injectable() export class UserActivityRepository { - constructor(private readonly prisma: PrismaService, private readonly logger: Logger, + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger, @Inject('NATS_CLIENT') private readonly userActivityServiceProxy: ClientProxy - ) { } + ) {} + async logActivity(userId: string, orgId: string, action: string, details: string): Promise { + return this.prisma.user_activity.create({ + data: { + userId, + orgId, + action, + details, + createdBy: userId, + lastChangedBy: userId, + }, + }) + } - async logActivity(userId: string, orgId: string, action: string, details: string): Promise { - return this.prisma.user_activity.create({ - data: { - userId, - orgId, - action, - details, - createdBy: userId, - lastChangedBy: userId - } - }); - } + async getRecentActivities(userId: string, limit: number): Promise { + return this.prisma.user_activity.findMany({ + where: { + userId, + }, + select: { + id: true, + userId: true, + orgId: true, + action: true, + details: true, + createDateTime: true, + lastChangedDateTime: true, + }, + orderBy: { + createDateTime: 'desc', + }, + take: limit, + }) + } - async getRecentActivities(userId: string, limit: number): Promise { - return this.prisma.user_activity.findMany({ - where: { - userId - }, - select: { - id: true, - userId: true, - orgId: true, - action: true, - details: true, - createDateTime:true, - lastChangedDateTime: true - }, - orderBy: { - createDateTime: 'desc' + async _orgDeletedActivity( + orgId: string, + user: user, + txnMetadata: object, + recordType: RecordType + ): Promise<{ + message: string + }> { + try { + const pattern = { cmd: 'org-deleted-activity' } + const payload = { orgId, userId: user?.id, deletedBy: user?.id, recordType, userEmail: user?.email, txnMetadata } + + return this.userActivityServiceProxy + .send(pattern, payload) + .pipe( + map((message) => ({ + message, + })) + ) + .toPromise() + .catch((error) => { + this.logger.error(`catch: ${JSON.stringify(error)}`) + + throw new HttpException( + { + status: error?.error?.statusCode, + error: error?.error?.error, + message: error?.error?.message ?? error?.message, }, - take: limit - }); + error.error + ) + }) + } catch (error) { + this.logger.error(`[_orgDeletedActivity] - error in delete wallet : ${JSON.stringify(error)}`) + throw error } - - async _orgDeletedActivity(orgId: string, user: user, txnMetadata: object, recordType: RecordType): Promise<{ - message: string; - }> { - try { - const pattern = { cmd: 'org-deleted-activity' }; - const payload = { orgId, userId: user?.id, deletedBy: user?.id, recordType, userEmail: user?.email, txnMetadata }; - - return this.userActivityServiceProxy - .send(pattern, payload) - .pipe( - map((message) => ({ - message - })) - ) - .toPromise() - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - - throw new HttpException( - { - status: error?.error?.statusCode, - error: error?.error?.error, - message: error?.error?.message ?? error?.message - }, - error.error - ); - }); - } catch (error) { - this.logger.error(`[_orgDeletedActivity] - error in delete wallet : ${JSON.stringify(error)}`); - throw error; - } - } -} \ No newline at end of file + } +} diff --git a/libs/user-activity/src/index.ts b/libs/user-activity/src/index.ts index 9b8fb5972..c64ebe839 100644 --- a/libs/user-activity/src/index.ts +++ b/libs/user-activity/src/index.ts @@ -1,2 +1,2 @@ -export * from './user-activity.module'; -export * from './user-activity.service'; +export * from './user-activity.module' +export * from './user-activity.service' diff --git a/libs/user-activity/src/user-activity.module.ts b/libs/user-activity/src/user-activity.module.ts index 2ac446d9d..3e80136c0 100644 --- a/libs/user-activity/src/user-activity.module.ts +++ b/libs/user-activity/src/user-activity.module.ts @@ -1,11 +1,11 @@ -import { Logger, Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common' -import { PrismaService } from '@credebl/prisma-service'; -import { UserActivityRepository } from '../repositories'; -import { UserActivityService } from './user-activity.service'; +import { PrismaService } from '@credebl/prisma-service' +import { UserActivityRepository } from '../repositories' +import { UserActivityService } from './user-activity.service' @Module({ providers: [UserActivityService, UserActivityRepository, Logger, PrismaService], - exports: [UserActivityService] + exports: [UserActivityService], }) export class UserActivityModule {} diff --git a/libs/user-activity/src/user-activity.service.ts b/libs/user-activity/src/user-activity.service.ts index f90f4f00a..e6c67bf10 100644 --- a/libs/user-activity/src/user-activity.service.ts +++ b/libs/user-activity/src/user-activity.service.ts @@ -1,22 +1,18 @@ /* eslint-disable camelcase */ -import { Injectable } from '@nestjs/common'; -import { UserActivityRepository } from '../repositories'; -import { user_activity } from '@prisma/client'; -import { IUsersActivity } from '../interface'; +import { Injectable } from '@nestjs/common' +import type { user_activity } from '@prisma/client' +import type { IUsersActivity } from '../interface' +import type { UserActivityRepository } from '../repositories' @Injectable() export class UserActivityService { + constructor(private readonly userActivityRepository: UserActivityRepository) {} - constructor( - private readonly userActivityRepository: UserActivityRepository - ) { } + async createActivity(userId: string, orgId: string, action: string, details: string): Promise { + return this.userActivityRepository.logActivity(userId, orgId, action, details) + } - async createActivity(userId: string, orgId: string, action: string, details: string): Promise { - - return this.userActivityRepository.logActivity(userId, orgId, action, details); - } - - async getUserActivity(userId: string, limit: number): Promise { - return this.userActivityRepository.getRecentActivities(userId, limit); - } + async getUserActivity(userId: string, limit: number): Promise { + return this.userActivityRepository.getRecentActivities(userId, limit) + } } diff --git a/libs/user-org-roles/repositories/index.ts b/libs/user-org-roles/repositories/index.ts index 5458796cd..3d38e3f94 100644 --- a/libs/user-org-roles/repositories/index.ts +++ b/libs/user-org-roles/repositories/index.ts @@ -1,16 +1,19 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, type Logger } from '@nestjs/common' -import { InternalServerErrorException } from '@nestjs/common'; -import { PrismaService } from '@credebl/prisma-service'; +import type { PrismaService } from '@credebl/prisma-service' +import { InternalServerErrorException } from '@nestjs/common' // eslint-disable-next-line camelcase -import { user_org_roles } from '@prisma/client'; -import { Prisma } from '@prisma/client'; +import type { user_org_roles } from '@prisma/client' +import type { Prisma } from '@prisma/client' -type UserOrgRolesWhereUniqueInput = Prisma.user_org_rolesWhereUniqueInput; +type UserOrgRolesWhereUniqueInput = Prisma.user_org_rolesWhereUniqueInput @Injectable() export class UserOrgRolesRepository { - constructor(private readonly prisma: PrismaService, private readonly logger: Logger) {} + constructor( + private readonly prisma: PrismaService, + private readonly logger: Logger + ) {} /** * @@ -19,35 +22,33 @@ export class UserOrgRolesRepository { */ // eslint-disable-next-line camelcase async createUserOrgRole(userId: string, roleId: string, orgId?: string, idpRoleId?: string): Promise { - try { const data: { - orgRole: { connect: { id: string } }; - user: { connect: { id: string } }; - organisation?: { connect: { id: string } }; + orgRole: { connect: { id: string } } + user: { connect: { id: string } } + organisation?: { connect: { id: string } } idpRoleId?: string } = { orgRole: { connect: { id: roleId } }, - user: { connect: { id: userId } } - }; + user: { connect: { id: userId } }, + } if (orgId) { - data.organisation = { connect: { id: orgId } }; + data.organisation = { connect: { id: orgId } } } if (idpRoleId) { - data.idpRoleId = idpRoleId; + data.idpRoleId = idpRoleId } const saveResponse = await this.prisma.user_org_roles.create({ - data - }); - - return saveResponse; - + data, + }) + + return saveResponse } catch (error) { - this.logger.error(`UserOrgRolesRepository:: createUserOrgRole: ${error}`); - throw new InternalServerErrorException('User Org Role not created'); + this.logger.error(`UserOrgRolesRepository:: createUserOrgRole: ${error}`) + throw new InternalServerErrorException('User Org Role not created') } } @@ -61,22 +62,22 @@ export class UserOrgRolesRepository { try { return this.prisma.user_org_roles.findMany({ where: { - ...queryOptions + ...queryOptions, }, include: { organisation: { include: { // eslint-disable-next-line camelcase org_agents: true, - orgInvitations: true - } + orgInvitations: true, + }, }, - orgRole: true - } - }); + orgRole: true, + }, + }) } catch (error) { - this.logger.error(`error: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } @@ -84,23 +85,22 @@ export class UserOrgRolesRepository { try { return this.prisma.user_org_roles.update({ where: { ...queryOptions }, - data: { ...updateData } - }); + data: { ...updateData }, + }) } catch (error) { - this.logger.error(`error in findAndUpdate: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error in findAndUpdate: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } async deleteMany(queryOptions: object): Promise { try { return this.prisma.user_org_roles.deleteMany({ - where: { ...queryOptions } - }); + where: { ...queryOptions }, + }) } catch (error) { - this.logger.error(`error in deleteMany: ${JSON.stringify(error)}`); - throw new InternalServerErrorException(error); + this.logger.error(`error in deleteMany: ${JSON.stringify(error)}`) + throw new InternalServerErrorException(error) } } - } diff --git a/libs/user-org-roles/src/index.ts b/libs/user-org-roles/src/index.ts index be7c557e1..ed4c55fdb 100644 --- a/libs/user-org-roles/src/index.ts +++ b/libs/user-org-roles/src/index.ts @@ -1,2 +1,2 @@ -export * from './user-org-roles.module'; -export * from './user-org-roles.service'; +export * from './user-org-roles.module' +export * from './user-org-roles.service' diff --git a/libs/user-org-roles/src/user-org-roles.module.ts b/libs/user-org-roles/src/user-org-roles.module.ts index be4c0b84f..dff7cd1a1 100644 --- a/libs/user-org-roles/src/user-org-roles.module.ts +++ b/libs/user-org-roles/src/user-org-roles.module.ts @@ -1,11 +1,11 @@ -import { PrismaService } from '@credebl/prisma-service'; -import { Logger } from '@nestjs/common'; -import { Module } from '@nestjs/common'; -import { UserOrgRolesRepository } from '../repositories'; -import { UserOrgRolesService } from './user-org-roles.service'; +import { PrismaService } from '@credebl/prisma-service' +import { Logger } from '@nestjs/common' +import { Module } from '@nestjs/common' +import { UserOrgRolesRepository } from '../repositories' +import { UserOrgRolesService } from './user-org-roles.service' @Module({ providers: [UserOrgRolesService, UserOrgRolesRepository, Logger, PrismaService], - exports: [UserOrgRolesService] + exports: [UserOrgRolesService], }) export class UserOrgRolesModule {} diff --git a/libs/user-org-roles/src/user-org-roles.service.ts b/libs/user-org-roles/src/user-org-roles.service.ts index 0b87cd9cf..22b451bd2 100644 --- a/libs/user-org-roles/src/user-org-roles.service.ts +++ b/libs/user-org-roles/src/user-org-roles.service.ts @@ -1,7 +1,7 @@ -import { Injectable } from '@nestjs/common'; -import { UserOrgRolesRepository } from '../repositories'; +import { Injectable } from '@nestjs/common' // eslint-disable-next-line camelcase -import { user_org_roles } from '@prisma/client'; +import type { user_org_roles } from '@prisma/client' +import type { UserOrgRolesRepository } from '../repositories' @Injectable() export class UserOrgRolesService { @@ -14,65 +14,60 @@ export class UserOrgRolesService { */ // eslint-disable-next-line camelcase async createUserOrgRole(userId: string, roleId: string, orgId?: string, idpRoleId?: string): Promise { - return this.userOrgRoleRepository.createUserOrgRole(userId, roleId, orgId, idpRoleId); + return this.userOrgRoleRepository.createUserOrgRole(userId, roleId, orgId, idpRoleId) } - /** - * - * @param userId - * @param orgId + * + * @param userId + * @param orgId * @returns Boolean response for user exist */ async checkUserOrgExist(userId: string, orgId: string): Promise { const queryOptions = { userId, - orgId - }; - const userOrgDetails = await this.userOrgRoleRepository.getUserOrgData(queryOptions); + orgId, + } + const userOrgDetails = await this.userOrgRoleRepository.getUserOrgData(queryOptions) - if (userOrgDetails && 0 === userOrgDetails.length) { - return false; + if (userOrgDetails && userOrgDetails.length === 0) { + return false } - return true; + return true } - /** - * - * @param userId - * @param orgId - * @param roleIds - * @returns + * + * @param userId + * @param orgId + * @param roleIds + * @returns */ async updateUserOrgRole( userId: string, orgId: string, - roleIdList: {roleId: string, idpRoleId: string}[] - ): Promise { - + roleIdList: { roleId: string; idpRoleId: string }[] + ): Promise { for (const roleData of roleIdList) { - this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId); + this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId) } - return true; + return true } /** - * - * @param userId - * @param orgId + * + * @param userId + * @param orgId * @returns Delete user org roles */ async deleteOrgRoles(userId: string, orgId: string): Promise { - const queryOptions = { userId, - orgId - }; - - return this.userOrgRoleRepository.deleteMany(queryOptions); + orgId, + } + return this.userOrgRoleRepository.deleteMany(queryOptions) } } diff --git a/libs/user-request/src/index.ts b/libs/user-request/src/index.ts index 0799fc9ba..ccc68efa7 100644 --- a/libs/user-request/src/index.ts +++ b/libs/user-request/src/index.ts @@ -1,2 +1,2 @@ -export * from './user-request.module'; -export * from './user-request.service'; +export * from './user-request.module' +export * from './user-request.service' diff --git a/libs/user-request/src/user-request.interface.ts b/libs/user-request/src/user-request.interface.ts index 93a703215..c6dfd1917 100644 --- a/libs/user-request/src/user-request.interface.ts +++ b/libs/user-request/src/user-request.interface.ts @@ -1,57 +1,55 @@ export interface IUserRequest { - userId: string; - email: string; - orgId: string; - agentEndPoint?: string; - apiKey?: string; - tenantId?: string; - tenantName?: string; - tenantOrgId?: string; - userRoleOrgPermissions?: IUserRoleOrgPerms[]; - orgName?: string; - selectedOrg: ISelectedOrg; + userId: string + email: string + orgId: string + agentEndPoint?: string + apiKey?: string + tenantId?: string + tenantName?: string + tenantOrgId?: string + userRoleOrgPermissions?: IUserRoleOrgPerms[] + orgName?: string + selectedOrg: ISelectedOrg } export interface ISelectedOrg { - id: string; - userId: string; - orgRoleId: string; - orgId: string; - orgRole: object; - organisation: object; + id: string + userId: string + orgRoleId: string + orgId: string + orgRole: object + organisation: object } export interface IOrganization { - name: string; - description: string; - org_agents: IOrgAgent[] - + name: string + description: string + org_agents: IOrgAgent[] } export interface IOrgAgent { - orgDid: string; - verkey: string; - agentEndPoint: string; - agentOptions: string; - walletName: string; - agentsTypeId: string; - orgId: string; + orgDid: string + verkey: string + agentEndPoint: string + agentOptions: string + walletName: string + agentsTypeId: string + orgId: string } export class IUserRoleOrgPerms { - id: string; - role: IUserRole; - Organization: IUserOrg; + id: string + role: IUserRole + Organization: IUserOrg } export class IUserRole { - id: string; - name: string; - permissions: string[]; - + id: string + name: string + permissions: string[] } export class IUserOrg { - id: string; - orgName: string; -} \ No newline at end of file + id: string + orgName: string +} diff --git a/libs/user-request/src/user-request.module.ts b/libs/user-request/src/user-request.module.ts index b1b50ffd8..ff5fadbea 100644 --- a/libs/user-request/src/user-request.module.ts +++ b/libs/user-request/src/user-request.module.ts @@ -1,8 +1,8 @@ -import { Module } from '@nestjs/common'; -import { UserRequestService } from './user-request.service'; +import { Module } from '@nestjs/common' +import { UserRequestService } from './user-request.service' @Module({ providers: [UserRequestService], - exports: [UserRequestService] + exports: [UserRequestService], }) export class UserRequestModule {} diff --git a/libs/user-request/src/user-request.service.spec.ts b/libs/user-request/src/user-request.service.spec.ts index acc591d94..86614d164 100644 --- a/libs/user-request/src/user-request.service.spec.ts +++ b/libs/user-request/src/user-request.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { UserRequestService } from './user-request.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { UserRequestService } from './user-request.service' describe('UserRequestService', () => { - let service: UserRequestService; + let service: UserRequestService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [UserRequestService] - }).compile(); + providers: [UserRequestService], + }).compile() - service = module.get(UserRequestService); - }); + service = module.get(UserRequestService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/libs/user-request/src/user-request.service.ts b/libs/user-request/src/user-request.service.ts index 1aa672185..d63358222 100644 --- a/libs/user-request/src/user-request.service.ts +++ b/libs/user-request/src/user-request.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common' @Injectable() export class UserRequestService {} diff --git a/libs/validations/arrayKeyword.ts b/libs/validations/arrayKeyword.ts index e2ad17116..bd771d01a 100644 --- a/libs/validations/arrayKeyword.ts +++ b/libs/validations/arrayKeyword.ts @@ -1,3 +1,3 @@ -import Keyword from './keyword'; +import Keyword from './keyword' export default class ArrayKeyword extends Keyword {} diff --git a/libs/validations/exclusiveMaximum.ts b/libs/validations/exclusiveMaximum.ts index bc717ff9d..5e62ab776 100644 --- a/libs/validations/exclusiveMaximum.ts +++ b/libs/validations/exclusiveMaximum.ts @@ -1,28 +1,28 @@ -import NumberKeyword from './numberKeyword'; +import NumberKeyword from './numberKeyword' export default class ExclusiveMaximum extends NumberKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if ('number' === typeof value) { - this._value = value; - } else { - throw new Error('value must be a number'); - } + if (typeof value === 'number') { + this._value = value + } else { + throw new Error('value must be a number') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.exclusiveMaximum = this.value; - return context; + context.exclusiveMaximum = this.value + return context } } diff --git a/libs/validations/exclusiveMinimum.ts b/libs/validations/exclusiveMinimum.ts index 653c1d1b9..f89c583d0 100644 --- a/libs/validations/exclusiveMinimum.ts +++ b/libs/validations/exclusiveMinimum.ts @@ -1,28 +1,28 @@ -import NumberKeyword from './numberKeyword'; +import NumberKeyword from './numberKeyword' export default class ExclusiveMinimum extends NumberKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if ('number' === typeof value) { - this._value = value; - } else { - throw new Error('value must be a number'); - } + if (typeof value === 'number') { + this._value = value + } else { + throw new Error('value must be a number') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.exclusiveMinimum = this.value; - return context; + context.exclusiveMinimum = this.value + return context } } diff --git a/libs/validations/keyword.ts b/libs/validations/keyword.ts index dc57e4b4c..d1ccc467b 100644 --- a/libs/validations/keyword.ts +++ b/libs/validations/keyword.ts @@ -1,7 +1,7 @@ export default class Keyword { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - json(context): any { - return context || {}; - } + // biome-ignore lint/suspicious/noExplicitAny: + // biome-ignore lint/suspicious/noExplicitAny: + json(context): any { + return context || {} } - \ No newline at end of file +} diff --git a/libs/validations/maxItems.ts b/libs/validations/maxItems.ts index 7329cdd5a..055205834 100644 --- a/libs/validations/maxItems.ts +++ b/libs/validations/maxItems.ts @@ -1,28 +1,28 @@ -import ArrayKeyword from './arrayKeyword'; +import ArrayKeyword from './arrayKeyword' export default class MaxItems extends ArrayKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if (0 <= value && Number.isInteger(value)) { - this._value = value; - } else { - throw new Error('value must be an integer and greater than or equal to 0'); - } + if (value >= 0 && Number.isInteger(value)) { + this._value = value + } else { + throw new Error('value must be an integer and greater than or equal to 0') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.maxItems = this.value; - return context; + context.maxItems = this.value + return context } } diff --git a/libs/validations/maxLength.ts b/libs/validations/maxLength.ts index b935afb60..fc074c5aa 100644 --- a/libs/validations/maxLength.ts +++ b/libs/validations/maxLength.ts @@ -1,28 +1,27 @@ -import StringKeyword from './stringKeyword'; +import StringKeyword from './stringKeyword' export default class MaxLength extends StringKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - - if (0 <= value && Number.isInteger(value)) { - this._value = value; + if (value >= 0 && Number.isInteger(value)) { + this._value = value } else { - throw new Error('value must be an integer and greater than or equal to 0'); + throw new Error('value must be an integer and greater than or equal to 0') } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.maxLength = this.value; - return context; + context.maxLength = this.value + return context } } diff --git a/libs/validations/maximum.ts b/libs/validations/maximum.ts index c871228d2..9b068ef1c 100644 --- a/libs/validations/maximum.ts +++ b/libs/validations/maximum.ts @@ -1,28 +1,28 @@ -import NumberKeyword from './numberKeyword'; +import NumberKeyword from './numberKeyword' export default class Maximum extends NumberKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if ('number' === typeof value) { - this._value = value; - } else { - throw new Error('value must be a number'); - } + if (typeof value === 'number') { + this._value = value + } else { + throw new Error('value must be a number') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.maximum = this.value; - return context; + context.maximum = this.value + return context } } diff --git a/libs/validations/minItems.ts b/libs/validations/minItems.ts index 98d4c57bb..cb43f5d62 100644 --- a/libs/validations/minItems.ts +++ b/libs/validations/minItems.ts @@ -1,28 +1,28 @@ -import ArrayKeyword from './arrayKeyword'; +import ArrayKeyword from './arrayKeyword' export default class MinItems extends ArrayKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if (0 <= value && Number.isInteger(value)) { - this._value = value; - } else { - throw new Error('value must be an integer and greater than or equal to 0'); - } + if (value >= 0 && Number.isInteger(value)) { + this._value = value + } else { + throw new Error('value must be an integer and greater than or equal to 0') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.minItems = this.value; - return context; + context.minItems = this.value + return context } } diff --git a/libs/validations/minLength.ts b/libs/validations/minLength.ts index 2d97bcda2..a4f7d0592 100644 --- a/libs/validations/minLength.ts +++ b/libs/validations/minLength.ts @@ -1,28 +1,28 @@ -import StringKeyword from './stringKeyword'; +import StringKeyword from './stringKeyword' export default class MinLength extends StringKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if (0 <= value && Number.isInteger(value)) { - this._value = value; + if (value >= 0 && Number.isInteger(value)) { + this._value = value } else { - throw new Error('value must be an integer and greater than or equal to 0'); + throw new Error('value must be an integer and greater than or equal to 0') } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.minLength = this.value; - return context; + context.minLength = this.value + return context } } diff --git a/libs/validations/minimum.ts b/libs/validations/minimum.ts index 05b70ff2a..287badf66 100644 --- a/libs/validations/minimum.ts +++ b/libs/validations/minimum.ts @@ -1,28 +1,28 @@ -import NumberKeyword from './numberKeyword'; +import NumberKeyword from './numberKeyword' export default class Minimum extends NumberKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if ('number' === typeof value) { - this._value = value; - } else { - throw new Error('value must be a number'); - } + if (typeof value === 'number') { + this._value = value + } else { + throw new Error('value must be a number') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.minimum = this.value; - return context; + context.minimum = this.value + return context } } diff --git a/libs/validations/multipleOf.ts b/libs/validations/multipleOf.ts index bead8736b..ab525869b 100644 --- a/libs/validations/multipleOf.ts +++ b/libs/validations/multipleOf.ts @@ -1,28 +1,28 @@ -import NumberKeyword from './numberKeyword'; +import NumberKeyword from './numberKeyword' export default class MultipleOf extends NumberKeyword { - private _value: number; + private _value: number constructor(value: number) { - super(); - this.value = value; + super() + this.value = value } get value(): number { - return this._value; + return this._value } set value(value: number) { - if ('number' === typeof value && 0 < value) { - this._value = value; - } else { - throw new Error('value must be a number greater than 0'); - } + if (typeof value === 'number' && value > 0) { + this._value = value + } else { + throw new Error('value must be a number greater than 0') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.multipleOf = this.value; - return context; + context.multipleOf = this.value + return context } } diff --git a/libs/validations/numberKeyword.ts b/libs/validations/numberKeyword.ts index 7f16cdab5..25fc106b1 100644 --- a/libs/validations/numberKeyword.ts +++ b/libs/validations/numberKeyword.ts @@ -1,3 +1,3 @@ -import Keyword from './keyword'; +import Keyword from './keyword' export default class NumberKeyword extends Keyword {} diff --git a/libs/validations/objectKeyword.ts b/libs/validations/objectKeyword.ts index 07882c60d..deb0f33e8 100644 --- a/libs/validations/objectKeyword.ts +++ b/libs/validations/objectKeyword.ts @@ -1,3 +1,3 @@ -import Keyword from './keyword'; +import Keyword from './keyword' export default class ObjectKeyword extends Keyword {} diff --git a/libs/validations/pattern.ts b/libs/validations/pattern.ts index 556a1e535..88d3a12fe 100644 --- a/libs/validations/pattern.ts +++ b/libs/validations/pattern.ts @@ -1,33 +1,33 @@ -import StringKeyword from './stringKeyword'; +import StringKeyword from './stringKeyword' export default class Pattern extends StringKeyword { - private _value: string; + private _value: string constructor(value: string) { - super(); - this.value = value; + super() + this.value = value } get value(): string { - return this._value; + return this._value } set value(value: string) { - if ('string' === typeof value) { - try { - new RegExp(value); - this._value = value; - } catch (e) { - throw new Error('value must be a valid regular expression pattern'); - } - } else { - throw new Error('value must be a string'); + if (typeof value === 'string') { + try { + new RegExp(value) + this._value = value + } catch (_e) { + throw new Error('value must be a valid regular expression pattern') } + } else { + throw new Error('value must be a string') + } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.pattern = this.value; - return context; + context.pattern = this.value + return context } } diff --git a/libs/validations/stringKeyword.ts b/libs/validations/stringKeyword.ts index 0c5fd217f..37b68821c 100644 --- a/libs/validations/stringKeyword.ts +++ b/libs/validations/stringKeyword.ts @@ -1,3 +1,3 @@ -import Keyword from './keyword'; +import Keyword from './keyword' -export default class StringKeyword extends Keyword {} \ No newline at end of file +export default class StringKeyword extends Keyword {} diff --git a/libs/validations/uniqueItems.ts b/libs/validations/uniqueItems.ts index a47d539e6..46c64b63b 100644 --- a/libs/validations/uniqueItems.ts +++ b/libs/validations/uniqueItems.ts @@ -1,28 +1,28 @@ -import ArrayKeyword from './arrayKeyword'; +import ArrayKeyword from './arrayKeyword' export default class UniqueItems extends ArrayKeyword { - private _value: boolean; + private _value: boolean constructor(value: boolean) { - super(); - this.value = value; + super() + this.value = value } get value(): boolean { - return this._value; + return this._value } set value(value: boolean) { - if ('boolean' === typeof value) { - this._value = value; + if (typeof value === 'boolean') { + this._value = value } else { - throw new Error('value must be a boolean'); + throw new Error('value must be a boolean') } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: json(context: Record = {}): Record { - context.uniqueItems = this.value; - return context; + context.uniqueItems = this.value + return context } } diff --git a/package.json b/package.json index 91e6af493..4704b3cfd 100755 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@types/async-retry": "^1.4.5", "@types/crypto-js": "^4.1.1", "@types/json2csv": "^5.0.5", + "@types/jsonwebtoken": "^9.0.9", "@types/pdfkit": "^0.12.6", "async-retry": "^1.3.3", "auth0-js": "^9.22.1", @@ -78,12 +79,12 @@ "jwks-rsa": "^3.0.1", "linebyline": "^1.3.0", "moment": "^2.29.3", - "multer": "1.4.5-lts.1", "morgan": "^1.10.0", + "multer": "1.4.5-lts.1", "nanoid": "^4.0.2", "nats": "^2.15.1", - "nestjs-rate-limiter": "^3.1.0", "nestjs-cls": "^4.3.0", + "nestjs-rate-limiter": "^3.1.0", "nestjs-supabase-auth": "^1.0.9", "nestjs-typeorm-paginate": "^4.0.4", "node-html-to-image": "^4.0.0", @@ -149,16 +150,10 @@ "typescript": "^5.1.6" }, "lint-staged": { - "**/*.{js,ts}": [ - "biome check --write" - ] + "**/*.{js,ts}": ["biome check --write"] }, "jest": { - "moduleFileExtensions": [ - "js", - "json", - "ts" - ], + "moduleFileExtensions": ["js", "json", "ts"], "rootDir": ".", "testRegex": ".spec.ts$", "transform": { @@ -166,10 +161,7 @@ }, "coverageDirectory": "./coverage", "testEnvironment": "node", - "roots": [ - "/apps/", - "/libs/" - ], + "roots": ["/apps/", "/libs/"], "moduleNameMapper": { "@credebl/common/(.*)": "/libs/common/src/$1", "@credebl/common": "/libs/common/src", diff --git a/scripts/taskdef/agent-provisioning-taskdef.json b/scripts/taskdef/agent-provisioning-taskdef.json index 292b15c74..c758b015d 100644 --- a/scripts/taskdef/agent-provisioning-taskdef.json +++ b/scripts/taskdef/agent-provisioning-taskdef.json @@ -1,78 +1,76 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "agent_provisioning", + "image": "%REPOSITORY_URI%:AGENT-PROVISIONING_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "agent_provisioning", - "image": "%REPOSITORY_URI%:AGENT-PROVISIONING_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [ - { - "sourceVolume": "agent-config", - "containerPath": "/app/agent-provisioning/AFJ/agent-config", - "readOnly": false - }, - { - "sourceVolume": "port-file", - "containerPath": "/app/agent-provisioning/AFJ/port-file", - "readOnly": false - } - ], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - ], - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512", - "volumes": [ + ], + "mountPoints": [ { - "name": "agent-config", - "efsVolumeConfiguration": { - "fileSystemId": "${EFS}", - "rootDirectory": "/", - "transitEncryption": "ENABLED", - "authorizationConfig": { - "accessPointId": "${AGENT_CONFIG_ACCESS_POINT}", - "iam": "DISABLED" - } - } + "sourceVolume": "agent-config", + "containerPath": "/app/agent-provisioning/AFJ/agent-config", + "readOnly": false }, { - "name": "port-file", - "efsVolumeConfiguration": { - "fileSystemId": "${EFS}", - "rootDirectory": "/", - "transitEncryption": "ENABLED", - "authorizationConfig": { - "accessPointId": "${PORT_FILE_ACCESS_POINT}", - "iam": "DISABLED" - } - } + "sourceVolume": "port-file", + "containerPath": "/app/agent-provisioning/AFJ/port-file", + "readOnly": false } - ] + ], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512", + "volumes": [ + { + "name": "agent-config", + "efsVolumeConfiguration": { + "fileSystemId": "${EFS}", + "rootDirectory": "/", + "transitEncryption": "ENABLED", + "authorizationConfig": { + "accessPointId": "${AGENT_CONFIG_ACCESS_POINT}", + "iam": "DISABLED" + } + } + }, + { + "name": "port-file", + "efsVolumeConfiguration": { + "fileSystemId": "${EFS}", + "rootDirectory": "/", + "transitEncryption": "ENABLED", + "authorizationConfig": { + "accessPointId": "${PORT_FILE_ACCESS_POINT}", + "iam": "DISABLED" + } + } + } + ] } diff --git a/scripts/taskdef/agent-service-taskdef.json b/scripts/taskdef/agent-service-taskdef.json index 0fb698780..6449af688 100644 --- a/scripts/taskdef/agent-service-taskdef.json +++ b/scripts/taskdef/agent-service-taskdef.json @@ -1,42 +1,39 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "agent", + "image": "%REPOSITORY_URI%:AGENT-SERVICE_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "agent", - "image": "%REPOSITORY_URI%:AGENT-SERVICE_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - } - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - "taskRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + } + } + } + ], + "taskRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/api-gateway-taskdef.json b/scripts/taskdef/api-gateway-taskdef.json index 34435749e..577b9e616 100644 --- a/scripts/taskdef/api-gateway-taskdef.json +++ b/scripts/taskdef/api-gateway-taskdef.json @@ -1,68 +1,66 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "api_gateway", + "image": "%REPOSITORY_URI%:API_GATEWAY_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [ { - "name": "api_gateway", - "image": "%REPOSITORY_URI%:API_GATEWAY_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [ - { - "containerPort": 5000, - "hostPort": 5000, - "protocol": "tcp" - } - ], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [ - { - "sourceVolume": "uploadedFiles", - "containerPath": "/app/uploadedFiles", - "readOnly": false - } - ], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "containerPort": 5000, + "hostPort": 5000, + "protocol": "tcp" } - ], - - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512", - "volumes": [ + ], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "uploadedFiles", - "efsVolumeConfiguration": { - "fileSystemId": "${EFS}", - "rootDirectory": "/", - "transitEncryption": "ENABLED", - "authorizationConfig": { - "accessPointId": "${UPLOADFILES_ACCESS_POINT}", - "iam": "DISABLED" - } - } + "value": "${S3_ARN}", + "type": "s3" } - ] + ], + "mountPoints": [ + { + "sourceVolume": "uploadedFiles", + "containerPath": "/app/uploadedFiles", + "readOnly": false + } + ], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512", + "volumes": [ + { + "name": "uploadedFiles", + "efsVolumeConfiguration": { + "fileSystemId": "${EFS}", + "rootDirectory": "/", + "transitEncryption": "ENABLED", + "authorizationConfig": { + "accessPointId": "${UPLOADFILES_ACCESS_POINT}", + "iam": "DISABLED" + } + } + } + ] } diff --git a/scripts/taskdef/connection-taskdef.json b/scripts/taskdef/connection-taskdef.json index 452d8fcff..7b47dd221 100644 --- a/scripts/taskdef/connection-taskdef.json +++ b/scripts/taskdef/connection-taskdef.json @@ -1,42 +1,39 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "connection", + "image": "%REPOSITORY_URI%:CONNECTION_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "connection", - "image": "%REPOSITORY_URI%:CONNECTION_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/issuance-service-taskdef.json b/scripts/taskdef/issuance-service-taskdef.json index 8d4832f22..ea64de3a7 100644 --- a/scripts/taskdef/issuance-service-taskdef.json +++ b/scripts/taskdef/issuance-service-taskdef.json @@ -1,61 +1,59 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "issuance", + "image": "%REPOSITORY_URI%:ISSUANCE_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "issuance", - "image": "%REPOSITORY_URI%:ISSUANCE_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [ - { - "sourceVolume": "uploadedFiles", - "containerPath": "/app/uploadedFiles", - "readOnly": false - } - ], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - ], - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512", - "volumes": [ + ], + "mountPoints": [ { - "name": "uploadedFiles", - "efsVolumeConfiguration": { - "fileSystemId": "${EFS}", - "rootDirectory": "/", - "transitEncryption": "ENABLED", - "authorizationConfig": { - "accessPointId": "${UPLOADFILES_ACCESS_POINT}", - "iam": "DISABLED" - } - } + "sourceVolume": "uploadedFiles", + "containerPath": "/app/uploadedFiles", + "readOnly": false } - ] + ], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512", + "volumes": [ + { + "name": "uploadedFiles", + "efsVolumeConfiguration": { + "fileSystemId": "${EFS}", + "rootDirectory": "/", + "transitEncryption": "ENABLED", + "authorizationConfig": { + "accessPointId": "${UPLOADFILES_ACCESS_POINT}", + "iam": "DISABLED" + } + } + } + ] } diff --git a/scripts/taskdef/ledger-taskdef.json b/scripts/taskdef/ledger-taskdef.json index 23c9950a7..06707ba81 100644 --- a/scripts/taskdef/ledger-taskdef.json +++ b/scripts/taskdef/ledger-taskdef.json @@ -1,43 +1,40 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "ledger", + "image": "%REPOSITORY_URI%:LEDGER_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "ledger", - "image": "%REPOSITORY_URI%:LEDGER_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/notification-taskdef.json b/scripts/taskdef/notification-taskdef.json index 3ab1d2157..9a8009886 100644 --- a/scripts/taskdef/notification-taskdef.json +++ b/scripts/taskdef/notification-taskdef.json @@ -1,42 +1,39 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "notification", + "image": "%REPOSITORY_URI%:NOTIFICATION_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "notification", - "image": "%REPOSITORY_URI%:NOTIFICATION_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - } - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - "taskRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + } + } + } + ], + "taskRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/organization-taskdef.json b/scripts/taskdef/organization-taskdef.json index 1738b09da..909d5b0ed 100644 --- a/scripts/taskdef/organization-taskdef.json +++ b/scripts/taskdef/organization-taskdef.json @@ -1,43 +1,40 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "organization", + "image": "%REPOSITORY_URI%:ORGANIZATION_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "organization", - "image": "%REPOSITORY_URI%:ORGANIZATION_v_%BUILD_NUMBER%", - "cpu":256 , - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/user-taskdef.json b/scripts/taskdef/user-taskdef.json index bf291d698..9f2073038 100644 --- a/scripts/taskdef/user-taskdef.json +++ b/scripts/taskdef/user-taskdef.json @@ -1,43 +1,40 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "user", + "image": "%REPOSITORY_URI%:USER_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "user", - "image": "%REPOSITORY_URI%:USER_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/utility-taskdef.json b/scripts/taskdef/utility-taskdef.json index 240cdb1a5..070c331c8 100644 --- a/scripts/taskdef/utility-taskdef.json +++ b/scripts/taskdef/utility-taskdef.json @@ -1,42 +1,39 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "utility", + "image": "%REPOSITORY_URI%:UTILITY_V_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "utility", - "image": "%REPOSITORY_URI%:UTILITY_V_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/verfication-taskdef.json b/scripts/taskdef/verfication-taskdef.json index e9aedf8cd..ade9e03a7 100644 --- a/scripts/taskdef/verfication-taskdef.json +++ b/scripts/taskdef/verfication-taskdef.json @@ -1,43 +1,40 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "verification", + "image": "%REPOSITORY_URI%:VERIFICATION_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "verification", - "image": "%REPOSITORY_URI%:VERIFICATION_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" } diff --git a/scripts/taskdef/webhook-taskdef.json b/scripts/taskdef/webhook-taskdef.json index 025c126f8..0574ddb3e 100644 --- a/scripts/taskdef/webhook-taskdef.json +++ b/scripts/taskdef/webhook-taskdef.json @@ -1,42 +1,39 @@ { - "family": "${FAMILY}", - "containerDefinitions": [ + "family": "${FAMILY}", + "containerDefinitions": [ + { + "name": "webhook", + "image": "%REPOSITORY_URI%:WEBHOOK_v_%BUILD_NUMBER%", + "cpu": 256, + "memory": 512, + "portMappings": [], + "essential": true, + "environment": [], + "environmentFiles": [ { - "name": "webhook", - "image": "%REPOSITORY_URI%:WEBHOOK_v_%BUILD_NUMBER%", - "cpu": 256, - "memory": 512, - "portMappings": [], - "essential": true, - "environment": [], - "environmentFiles": [ - { - "value": "${S3_ARN}", - "type": "s3" - } - ], - "mountPoints": [], - "volumesFrom": [], - "ulimits": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-create-group": "true", - "awslogs-group": "/ecs/${FAMILY}", - "awslogs-region": "${AWS_REGION}", - "awslogs-stream-prefix": "ecs" - }, - "secretOptions": [] - } + "value": "${S3_ARN}", + "type": "s3" } - - ], - "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", - "networkMode": "awsvpc", - "placementConstraints": [], - "requiresCompatibilities": [ - "FARGATE" - ], - "cpu": "256", - "memory": "512" -} \ No newline at end of file + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/${FAMILY}", + "awslogs-region": "${AWS_REGION}", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + "executionRoleArn": "arn:aws:iam::${ACCOUNT_ID}:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "placementConstraints": [], + "requiresCompatibilities": ["FARGATE"], + "cpu": "256", + "memory": "512" +} diff --git a/tsconfig.json b/tsconfig.json index 74a5fa904..3297f6be6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,112 +2,41 @@ "extends": "./tsconfig.build.json", "compilerOptions": { "paths": { - "@credebl/common": [ - "libs/common/src" - ], - "@credebl/common/*": [ - "libs/common/src/*" - ], - "@credebl/keycloak-url": [ - "libs/keycloak-url/src" - ], - "@credebl/keycloak-url/*": [ - "libs/keycloak-url/src/*" - ], - "@credebl/client-registration": [ - "libs/client-registration/src" - ], - "@credebl/client-registration/*": [ - "libs/client-registration/src/*" - ], - "@credebl/prisma": [ - "libs/prisma/src" - ], - "@credebl/prisma/*": [ - "libs/prisma/src/*" - ], - "@credebl/repositories": [ - "libs/repositories/src" - ], - "@credebl/repositories/*": [ - "libs/repositories/src/*" - ], - "@credebl/user-request": [ - "libs/user-request/src" - ], - "@credebl/user-request/*": [ - "libs/user-request/src/*" - ], - "@credebl/logger": [ - "libs/logger/src" - ], - "@credebl/logger/*": [ - "libs/logger/src/*" - ], - "@credebl/enum": [ - "libs/enum/src" - ], - "@credebl/enum/*": [ - "libs/enum/src/*" - ], - "@credebl/prisma-service": [ - "libs/prisma-service/src" - ], - "@credebl/prisma-service/*": [ - "libs/prisma-service/src/*" - ], - "@credebl/org-roles": [ - "libs/org-roles/src" - ], - "@credebl/org-roles/*": [ - "libs/org-roles/src/*" - ], - "@credebl/user-org-roles": [ - "libs/user-org-roles/src" - ], - "@credebl/user-org-roles/*": [ - "libs/user-org-roles/src/*" - ], - "@credebl/user-activity": [ - "libs/user-activity/src" - ], - "@credebl/user-activity/*": [ - "libs/user-activity/src/*" - ], - "@credebl/supabase": [ - "libs/supabase/src" - ], - "@credebl/supabase/*": [ - "libs/supabase/src/*" - ], - "@credebl/aws": [ - "libs/aws/src" - ], - "@credebl/aws/*": [ - "libs/aws/src/*" - ], - "credebl/utility": [ - "libs/utility/src" - ], - "credebl/utility/*": [ - "libs/utility/src/*" - ], - "@credebl/config": [ - "libs/config/src" - ], - "@credebl/config/*": [ - "libs/config/src/*" - ], - "@credebl/context": [ - "libs/context/src" - ], - "@credebl/context/*": [ - "libs/context/src/*" - ] + "@credebl/common": ["libs/common/src"], + "@credebl/common/*": ["libs/common/src/*"], + "@credebl/keycloak-url": ["libs/keycloak-url/src"], + "@credebl/keycloak-url/*": ["libs/keycloak-url/src/*"], + "@credebl/client-registration": ["libs/client-registration/src"], + "@credebl/client-registration/*": ["libs/client-registration/src/*"], + "@credebl/prisma": ["libs/prisma/src"], + "@credebl/prisma/*": ["libs/prisma/src/*"], + "@credebl/repositories": ["libs/repositories/src"], + "@credebl/repositories/*": ["libs/repositories/src/*"], + "@credebl/user-request": ["libs/user-request/src"], + "@credebl/user-request/*": ["libs/user-request/src/*"], + "@credebl/logger": ["libs/logger/src"], + "@credebl/logger/*": ["libs/logger/src/*"], + "@credebl/enum": ["libs/enum/src"], + "@credebl/enum/*": ["libs/enum/src/*"], + "@credebl/prisma-service": ["libs/prisma-service/src"], + "@credebl/prisma-service/*": ["libs/prisma-service/src/*"], + "@credebl/org-roles": ["libs/org-roles/src"], + "@credebl/org-roles/*": ["libs/org-roles/src/*"], + "@credebl/user-org-roles": ["libs/user-org-roles/src"], + "@credebl/user-org-roles/*": ["libs/user-org-roles/src/*"], + "@credebl/user-activity": ["libs/user-activity/src"], + "@credebl/user-activity/*": ["libs/user-activity/src/*"], + "@credebl/supabase": ["libs/supabase/src"], + "@credebl/supabase/*": ["libs/supabase/src/*"], + "@credebl/aws": ["libs/aws/src"], + "@credebl/aws/*": ["libs/aws/src/*"], + "credebl/utility": ["libs/utility/src"], + "credebl/utility/*": ["libs/utility/src/*"], + "@credebl/config": ["libs/config/src"], + "@credebl/config/*": ["libs/config/src/*"], + "@credebl/context": ["libs/context/src"], + "@credebl/context/*": ["libs/context/src/*"] } }, - "exclude": [ - "node_modules", - "dist" - ] -} \ No newline at end of file + "exclude": ["node_modules", "dist"] +} From 36961535947bae6a7e285636adb2814f29ba5d20 Mon Sep 17 00:00:00 2001 From: Sahil Kamble Date: Thu, 15 May 2025 19:05:10 +0530 Subject: [PATCH 10/23] chore/update-env-demo (#1250) * chore: remove unwanted values from .env.demo Signed-off-by: Sahil Kamble * chore: remove unwanted values from agent.env Signed-off-by: Sahil Kamble --------- Signed-off-by: Sahil Kamble --- .env.demo | 6 +++--- agent.env | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.demo b/.env.demo index f9130b987..369af85d3 100644 --- a/.env.demo +++ b/.env.demo @@ -29,7 +29,7 @@ NATS_URL=nats://your-ip:4222 REDIS_HOST=your-ip REDIS_PORT=6379 -SENDGRID_API_KEY= +SENDGRID_API_KEY= WALLET_STORAGE_HOST=your-ip WALLET_STORAGE_PORT=5432 @@ -76,7 +76,7 @@ AWS_ORG_LOGO_BUCKET_NAME= # Required (As connecting to org requires Shortened url) AWS_S3_STOREOBJECT_ACCESS_KEY= AWS_S3_STOREOBJECT_SECRET_KEY= -AWS_S3_STOREOBJECT_REGION= +AWS_S3_STOREOBJECT_REGION= AWS_S3_STOREOBJECT_BUCKET= # Please refere AWS to determine your bucket url @@ -84,7 +84,7 @@ AWS_S3_STOREOBJECT_BUCKET= SHORTENED_URL_DOMAIN='https://AWS_S3_STOREOBJECT_REGION.amazonaws.com/AWS_S3_STOREOBJECT_BUCKET' DEEPLINK_DOMAIN='https://link.credebl.id?url=' -ENABLE_CORS_IP_LIST=http://localhost:3000, http://localhost:3001, http://localhost:5000,http://localhost:8085,https://verify.credebl.id,https://verifyed.credebl.id,https://verify-api.credebl.id,https://qa.credebl.id,https://dev.credebl.id,https://credebl.id +ENABLE_CORS_IP_LIST=http://localhost:3000,http://localhost:3001,http://localhost:5000,http://localhost:8085 USER_NKEY_SEED= API_GATEWAY_NKEY_SEED= diff --git a/agent.env b/agent.env index 1398f6239..41bf0c008 100644 --- a/agent.env +++ b/agent.env @@ -20,7 +20,7 @@ RPC_URL=https://polygon-rpc.com # RPC_URL=https://rpc-amoy.polygon.technology # Add url and token from your file server -SERVER_URL=https://schema.credebl.id +SERVER_URL= FILE_SERVER_TOKEN= BCOVRIN_TEST_GENESIS='{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node1","blskey":"4N8aUNHSgjQVgkpm8nhNEfDf6txHznoYREg9kirmJrkivgL4oSEimFF6nsQ6M41QvhM2Z33nves5vfSn9n1UwNFJBYtWVnHYMATn76vLuL3zU88KyeAYcHfsih3He6UHcXDxcaecHVz6jhCYz1P2UZn2bDVruL5wXpehgBfBaLKm3Ba","blskey_pop":"RahHYiCvoNCtPTrVtP7nMC5eTYrsUA8WjXbdhNc8debh1agE9bGiJxWBXYNFbnJXoXhWFMvyqhqhRoq737YQemH5ik9oL7R4NTTCz2LEZhkgLJzB3QRQqJyBNyv7acbdHrAT8nQ9UkLbaVL9NBpnWXBTw4LEMePaSHEw66RzPNdAX1","client_ip":"138.197.138.255","client_port":9702,"node_ip":"138.197.138.255","node_port":9701,"services":["VALIDATOR"]},"dest":"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv"},"metadata":{"from":"Th7MpTaRZVRYnPiabds81Y"},"type":"0"},"txnMetadata":{"seqNo":1,"txnId":"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62"},"ver":"1"} From 9b2303cbbd9aa0fa0415bf3e1d98b50d20fe6054 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 15 May 2025 19:38:45 +0530 Subject: [PATCH 11/23] fix: biomejs issues Signed-off-by: Krishna Waske --- .../src/agent-service.service.ts | 12 ++-- .../api-gateway/src/authz/authz.middleware.ts | 7 +- apps/api-gateway/src/authz/jwt.strategy.ts | 4 +- .../api-gateway/src/dtos/create-schema.dto.ts | 2 +- .../src/issuance/issuance.controller.ts | 6 +- .../libs/helpers/attributes.extractor.ts | 15 ++--- apps/issuance/src/issuance.repository.ts | 3 +- apps/issuance/src/issuance.service.ts | 7 -- apps/organization/src/organization.service.ts | 34 +++++----- apps/user/src/user.service.ts | 28 ++++---- .../repositories/verification.repository.ts | 10 +-- apps/verification/src/verification.service.ts | 66 ++++++++++--------- apps/webhook/src/webhook.service.ts | 30 ++++----- biome.json | 9 +-- libs/aws/src/aws.service.ts | 2 +- .../src/client-registration.service.ts | 15 ++--- libs/common/src/NATSClient.ts | 6 +- libs/common/src/cast.helper.ts | 8 +-- libs/common/src/common.utils.ts | 2 +- libs/common/src/exception-handler.ts | 2 +- libs/http-exception.filter.ts | 1 + libs/logger/src/winstonLogger.ts | 6 +- libs/prisma-service/cli.ts | 13 ++-- 23 files changed, 132 insertions(+), 156 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index 7229a01c4..fec343728 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -277,7 +277,6 @@ export class AgentServiceService { .map((result, index) => (result.status === 'rejected' ? index : -1)) .filter((index) => index !== -1) - // biome-ignore lint/complexity/noForEach: rejectedIndices.forEach((index) => { switch (index) { case 0: @@ -638,7 +637,7 @@ export class AgentServiceService { private async _getDidMethod(payload: IStoreOrgAgentDetails, agentDid: object): Promise { const { agentEndPoint, apiKey, seed, keyType, method, network, role } = payload const getDidDoc = 'get-did-doc' - // biome-ignore lint/complexity/useLiteralKeys: + const getDidMethodUrl = `${agentEndPoint}${CommonConstants.URL_AGENT_GET_DID}/${agentDid['did']}` return this._retryAgentSpinup( getDidMethodUrl, @@ -649,7 +648,7 @@ export class AgentServiceService { method, network, role, - // biome-ignore lint/complexity/useLiteralKeys: + `${agentDid['did']}` ) } @@ -660,9 +659,8 @@ export class AgentServiceService { orgAgentTypeId: string ): IStoreOrgAgentDetails { return { - // biome-ignore lint/complexity/useLiteralKeys: did: getDidMethod['didDocument']?.id, - // biome-ignore lint/complexity/useLiteralKeys: + verkey: getDidMethod['didDocument']?.verificationMethod[0]?.publicKeyBase58, isDidPublic: true, agentSpinUpStatus: AgentSpinUpStatus.COMPLETED, @@ -995,9 +993,9 @@ export class AgentServiceService { const createdDidDetails = { orgId, - // biome-ignore lint/complexity/useLiteralKeys: + did: didDetails?.['did'] ?? didDetails?.['didState']?.['did'], - // biome-ignore lint/complexity/useLiteralKeys: + didDocument: didDetails?.['didDocument'] ?? didDetails?.['didDoc'] ?? didDetails?.['didState']?.['didDocument'], isPrimaryDid, orgAgentId: agentDetails.id, diff --git a/apps/api-gateway/src/authz/authz.middleware.ts b/apps/api-gateway/src/authz/authz.middleware.ts index 783c2bedc..c933827df 100644 --- a/apps/api-gateway/src/authz/authz.middleware.ts +++ b/apps/api-gateway/src/authz/authz.middleware.ts @@ -34,7 +34,7 @@ export class AuthzMiddleware implements NestMiddleware { } // TODO: add type to decoded - // biome-ignore lint/complexity/useLiteralKeys: + return decoded['payload'] } @@ -54,7 +54,7 @@ export class AuthzMiddleware implements NestMiddleware { } const requestor = new RequestingUser() - // biome-ignore lint/complexity/useLiteralKeys: + const tenant = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response if (tenant) { @@ -87,10 +87,8 @@ export class AuthzMiddleware implements NestMiddleware { if (payload.hasOwnProperty('clientId')) { this.logger.log(`tenant requestor.permissions: ${JSON.stringify(requestor)}`) } else { - // biome-ignore lint/complexity/useLiteralKeys: requestor.email = payload['email'] - // biome-ignore lint/complexity/useLiteralKeys: const userData = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response this.logger.debug(`User by keycloak ID ${userData.id}`) @@ -107,7 +105,6 @@ export class AuthzMiddleware implements NestMiddleware { } } - // biome-ignore lint/complexity/useLiteralKeys: req['requestor'] = requestor next() diff --git a/apps/api-gateway/src/authz/jwt.strategy.ts b/apps/api-gateway/src/authz/jwt.strategy.ts index fe7129ab2..3a7bf5046 100644 --- a/apps/api-gateway/src/authz/jwt.strategy.ts +++ b/apps/api-gateway/src/authz/jwt.strategy.ts @@ -61,7 +61,6 @@ export class JwtStrategy extends PassportStrategy(Strategy) { // biome-ignore lint/suspicious/noPrototypeBuiltins: if (payload.hasOwnProperty('client_id')) { - // biome-ignore lint/complexity/useLiteralKeys: const orgDetails: IOrganization = await this.organizationService.findOrganizationOwner(payload['client_id']) this.logger.log('Organization details fetched') @@ -91,9 +90,8 @@ export class JwtStrategy extends PassportStrategy(Strategy) { throw new NotFoundException(ResponseMessages.user.error.notFound) } //TODO patch to QA - // biome-ignore lint/complexity/useLiteralKeys: + if (userInfo?.['attributes']?.userRole) { - // biome-ignore lint/complexity/useLiteralKeys: userDetails.userRole = userInfo?.['attributes']?.userRole } diff --git a/apps/api-gateway/src/dtos/create-schema.dto.ts b/apps/api-gateway/src/dtos/create-schema.dto.ts index 77263b239..0ab15ce88 100644 --- a/apps/api-gateway/src/dtos/create-schema.dto.ts +++ b/apps/api-gateway/src/dtos/create-schema.dto.ts @@ -188,7 +188,7 @@ export class W3CAttributeValue { @Transform(({ value }) => { if (value && typeof value === 'object') { const result = {} - // biome-ignore lint/complexity/noForEach: + Object.entries(value).forEach(([key, propValue]) => { result[key] = plainToClass(W3CAttributeValue, propValue, { enableImplicitConversion: false, diff --git a/apps/api-gateway/src/issuance/issuance.controller.ts b/apps/api-gateway/src/issuance/issuance.controller.ts index 36fc2bfb8..f0375a317 100644 --- a/apps/api-gateway/src/issuance/issuance.controller.ts +++ b/apps/api-gateway/src/issuance/issuance.controller.ts @@ -386,7 +386,7 @@ export class IssuanceController { type: schemaType, templateId, fileKey, - // biome-ignore lint/complexity/useLiteralKeys: + fileName: fileDetails['fileName'] || file?.filename || file?.originalname, isValidateSchema, } @@ -541,9 +541,9 @@ export class IssuanceController { reqPayload = { templateId: credDefId, fileKey, - // biome-ignore lint/complexity/useLiteralKeys: + fileName: fileDetails['fileName'] || file?.filename || file?.originalname, - // biome-ignore lint/complexity/useLiteralKeys: + type: fileDetails?.['type'], } } diff --git a/apps/issuance/libs/helpers/attributes.extractor.ts b/apps/issuance/libs/helpers/attributes.extractor.ts index 024521b81..563c8ae89 100644 --- a/apps/issuance/libs/helpers/attributes.extractor.ts +++ b/apps/issuance/libs/helpers/attributes.extractor.ts @@ -9,7 +9,6 @@ export function extractAttributeNames( inNestedArray = false ): string[] { if (Array.isArray(attributeObj)) { - // biome-ignore lint/complexity/noForEach: attributeObj.forEach((item) => { extractAttributeNames(item, parentKey, result, inNestedArray) }) @@ -27,19 +26,17 @@ export function extractAttributeNames( if (attributeObj.hasOwnProperty('items') && Array.isArray(attributeObj.items)) { // Always use index 0 for items in an array // biome-ignore lint/suspicious/noExplicitAny: - // biome-ignore lint/complexity/noForEach: + attributeObj.items.forEach((item: any) => { extractAttributeNames(item, `${newParentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}0`, result, true) }) // biome-ignore lint/suspicious/noPrototypeBuiltins: } else if (attributeObj.hasOwnProperty('properties')) { - // biome-ignore lint/complexity/noForEach: Object.entries(attributeObj.properties).forEach(([key, value]) => { const propertyKey = `${newParentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}${key}` extractAttributeNames(value, propertyKey, result, inNestedArray) }) } else { - // biome-ignore lint/complexity/noForEach: Object.entries(attributeObj).forEach(([key, value]) => { if (!['attributeName', 'items', 'properties'].includes(key)) { extractAttributeNames(value, newParentKey, result, inNestedArray) @@ -71,7 +68,6 @@ function mergeArrayObjects(obj): void { // Process arrays if (Array.isArray(value)) { - // biome-ignore lint/complexity/noForEach: value.forEach((item) => { if (item && typeof item === 'object') { mergeArrayObjects(item) @@ -88,7 +84,7 @@ function mergeArrayObjects(obj): void { const tempArray = [] // First, add all numeric keys to the array - // biome-ignore lint/complexity/noForEach: + numericKeys .sort((a, b) => Number.parseInt(a) - Number.parseInt(b)) .forEach((k) => { @@ -109,7 +105,6 @@ function mergeArrayObjects(obj): void { tempArray[index] = {} } - // biome-ignore lint/complexity/noForEach: nonNumericKeys.forEach((k) => { tempArray[index][k] = value[k] }) @@ -131,14 +126,14 @@ function mergeArrayObjects(obj): void { if (Object.prototype.hasOwnProperty.call(obj, key)) { if (Array.isArray(obj[key])) { // Look for patterns like "field1", "field2" in each array element - // biome-ignore lint/complexity/noForEach: + obj[key].forEach((item) => { if (item && typeof item === 'object') { const keys = Object.keys(item) const prefixMap = new Map() // Group keys by prefix - // biome-ignore lint/complexity/noForEach: + keys.forEach((k) => { const match = k.match(/^([^0-9]+)(\d{1,10})$/) if (match) { @@ -158,7 +153,7 @@ function mergeArrayObjects(obj): void { const tempArray = [] // Sort by index and populate array - // biome-ignore lint/complexity/noForEach: + matches .sort((a, b) => a.index - b.index) .forEach((match) => { diff --git a/apps/issuance/src/issuance.repository.ts b/apps/issuance/src/issuance.repository.ts index e94e287c6..3c442696a 100644 --- a/apps/issuance/src/issuance.repository.ts +++ b/apps/issuance/src/issuance.repository.ts @@ -515,9 +515,8 @@ export class IssuanceRepository { fileUploadId: fileUpload, }, }) - } else { - throw error } + throw error } catch (error) { this.logger.error(`[saveFileUploadData] - error: ${JSON.stringify(error)}`) throw error diff --git a/apps/issuance/src/issuance.service.ts b/apps/issuance/src/issuance.service.ts index 93f2890f5..e97680e93 100644 --- a/apps/issuance/src/issuance.service.ts +++ b/apps/issuance/src/issuance.service.ts @@ -164,11 +164,9 @@ export class IssuanceService { const schemaResponseError = [] const attributesArray: IAttributes[] = JSON.parse(schemaResponse.attributes) - // biome-ignore lint/complexity/noForEach: attributesArray.forEach((attribute) => { if (attribute.attributeName && attribute.isRequired) { credentialData.forEach((credential, i) => { - // biome-ignore lint/complexity/noForEach: credential.attributes.forEach((attr) => { if (attr.name === attribute.attributeName && attribute.isRequired && !attr.value) { schemaResponseError.push(`Attribute ${attribute.attributeName} is required at position ${i + 1}`) @@ -349,10 +347,8 @@ export class IssuanceService { const schemadetailsResponseError = [] const attributesArray: IAttributes[] = JSON.parse(schemadetailsResponse.attributes) - // biome-ignore lint/complexity/noForEach: attributesArray.forEach((attribute) => { if (attribute.attributeName && attribute.isRequired) { - // biome-ignore lint/complexity/noForEach: payload.attributes.forEach((attr) => { if (attr.name === attribute.attributeName && attribute.isRequired && !attr.value) { schemadetailsResponseError.push( @@ -1386,7 +1382,6 @@ export class IssuanceService { const { email_identifier, ...rest } = row const newRow = { ...rest } - // biome-ignore lint/complexity/noForEach: attributesArray.forEach((attr) => { if (!(attr?.attributeName in newRow)) { throw new BadRequestException(`Missing attribute ${attr?.attributeName} in CSV data`) @@ -1993,9 +1988,7 @@ export class IssuanceService { const errorFileData = [] filedata.forEach((attr, i) => { - // biome-ignore lint/complexity/noForEach: attr.forEach((eachElement) => { - // biome-ignore lint/complexity/noForEach: attributesArray.forEach((eachItem) => { if (eachItem.attributeName === eachElement.header) { if (eachItem.isRequired && !eachElement.value) { diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index 01543eec9..c70179e98 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -43,10 +43,12 @@ import type { UpdateInvitationDto } from '../dtos/update-invitation.dt' import type { IClientCredentials, ICreateConnectionUrl, + IDidDetails, IDidList, IEcosystemOrgStatus, IGetOrgById, IGetOrganization, + ILedgerNameSpace, IOrgDetails, IOrgRole, IPrimaryDidDetails, @@ -224,8 +226,8 @@ export class OrganizationService { const dids = await this.organizationRepository.getDids(orgId) const noPrimaryDid = dids.every((orgDids) => orgDids.isPrimaryDid === false) - let existingPrimaryDid - let priviousDidFalse + let existingPrimaryDid: IDidDetails + let priviousDidFalse: IDidDetails if (!noPrimaryDid) { existingPrimaryDid = await this.organizationRepository.getPerviousPrimaryDid(orgId) @@ -248,7 +250,7 @@ export class OrganizationService { nameSpace = null } - let network + let network: ILedgerNameSpace if (nameSpace !== null) { network = await this.organizationRepository.getNetworkByNameSpace(nameSpace) } else { @@ -454,10 +456,9 @@ export class OrganizationService { const maskedString = '*'.repeat(inputString.length - 8) + lastFiveCharacters return maskedString - } else { - // If the inputString is less than 5 characters, return the original string - return inputString } + // If the inputString is less than 5 characters, return the original string + return inputString } async isValidBase64(value: string): Promise { @@ -532,6 +533,7 @@ export class OrganizationService { updateOrgDto.logo = undefined } + // biome-ignore lint/suspicious/noImplicitAnyLet: let organizationDetails const checkAgentIsExists = await this.organizationRepository.getAgentInvitationDetails(orgId) @@ -636,7 +638,8 @@ export class OrganizationService { throw new NotFoundException(ResponseMessages.organisation.error.organizationNotFound) } - let orgIds + let orgIds: string[] + // biome-ignore lint/suspicious/noImplicitAnyLet: let updatedOrgs if (process.env.IS_ECOSYSTEM_ENABLE === 'true') { @@ -1286,7 +1289,7 @@ export class OrganizationService { this.userOrgRoleService.deleteOrgRoles(userId, orgId), ]) - if (deletedUserRoleRecords.count === 0) { + if (deletedUserRoleRecords['count'] === 0) { throw new InternalServerErrorException(ResponseMessages.organisation.error.updateUserRoles) } @@ -1333,7 +1336,7 @@ export class OrganizationService { const deleteUserRecords = await this.userOrgRoleService.deleteOrgRoles(userId, orgId) - if (deleteUserRecords.count === 0) { + if (deleteUserRecords['count'] === 0) { throw new InternalServerErrorException(ResponseMessages.organisation.error.updateUserRoles) } @@ -1342,9 +1345,8 @@ export class OrganizationService { } return true - } else { - return this.updateUserClientRoles(roleIds, organizationDetails.idpId, userId, organizationDetails.id) } + return this.updateUserClientRoles(roleIds, organizationDetails.idpId, userId, organizationDetails.id) } catch (error) { this.logger.error(`Error in updateUserRoles: ${JSON.stringify(error)}`) throw new RpcException(error.response ? error.response : error) @@ -1731,17 +1733,17 @@ export class OrganizationService { async registerOrgsMapUsers(): Promise { try { - const unregisteredOrgsList = await this.organizationRepository.getUnregisteredClientOrgs() + const unregisteredOrgsList: organisation[] = await this.organizationRepository.getUnregisteredClientOrgs() if (!unregisteredOrgsList || unregisteredOrgsList.length === 0) { throw new NotFoundException('Unregistered client organizations not found') } for (const org of unregisteredOrgsList) { - const userOrgRoles = org.userOrgRoles.length > 0 && org.userOrgRoles + const userOrgRoles = org['userOrgRoles'].length > 0 && org['userOrgRoles'] const ownerUserList = - org.userOrgRoles.length > 0 && + org['userOrgRoles'].length > 0 && userOrgRoles.filter((userOrgRole) => userOrgRole.orgRole.name === OrgRoles.OWNER) const ownerUser = ownerUserList.length > 0 && ownerUserList[0].user @@ -1799,7 +1801,7 @@ export class OrganizationService { this.userOrgRoleService.deleteOrgRoles(user.id, orgObj.id), ]) - this.logger.log(`deletedUserRoleRecords::`, deletedUserRoleRecords) + this.logger.log('deletedUserRoleRecords::', deletedUserRoleRecords) deletedUserDetails.push(user.id) } @@ -1817,7 +1819,7 @@ export class OrganizationService { matchedClientRoles.map((role) => ({ roleId: role.roleId, idpRoleId: role.idpRoleId })) ), ]) - this.logger.log(`Organization client created and users mapped to roles`) + this.logger.log('Organization client created and users mapped to roles') } } } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 3a708ad7f..ef158f0f2 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -106,9 +106,8 @@ export class UserService { if (userDetails) { if (userDetails.isEmailVerified) { throw new ConflictException(ResponseMessages.user.error.exists) - } else { - throw new ConflictException(ResponseMessages.user.error.verificationAlreadySent) } + throw new ConflictException(ResponseMessages.user.error.verificationAlreadySent) } const verifyCode = uuidv4() @@ -210,9 +209,8 @@ export class UserService { const isEmailSent = await sendEmail(emailData) if (isEmailSent) { return isEmailSent - } else { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } catch (error) { this.logger.error(`Error in sendEmailForVerification: ${JSON.stringify(error)}`) throw new RpcException(error.response ? error.response : error) @@ -417,10 +415,9 @@ export class UserService { const getUserDetails = await this.userRepository.getUserDetails(userData.email.toLowerCase()) const decryptedPassword = await this.commonService.decryptPassword(getUserDetails.password) return await this.generateToken(email.toLowerCase(), decryptedPassword, userData) - } else { - const decryptedPassword = await this.commonService.decryptPassword(password) - return await this.generateToken(email.toLowerCase(), decryptedPassword, userData) } + const decryptedPassword = await this.commonService.decryptPassword(password) + return await this.generateToken(email.toLowerCase(), decryptedPassword, userData) } catch (error) { this.logger.error(`In Login User : ${JSON.stringify(error)}`) throw new RpcException(error.response ? error.response : error) @@ -532,9 +529,8 @@ export class UserService { const isEmailSent = await sendEmail(emailData) if (isEmailSent) { return isEmailSent - } else { - throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } + throw new InternalServerErrorException(ResponseMessages.user.error.emailSend) } catch (error) { this.logger.error(`Error in sendEmailForResetPassword: ${JSON.stringify(error)}`) throw new RpcException(error.response ? error.response : error) @@ -692,7 +688,7 @@ export class UserService { password, }) - this.logger.error(`Supa Login Error::`, JSON.stringify(error)) + this.logger.error('Supa Login Error::', JSON.stringify(error)) if (error) { throw new BadRequestException(error?.message) @@ -1049,22 +1045,24 @@ export class UserService { if (userDetails && !userDetails.isEmailVerified) { userVerificationDetails.message = ResponseMessages.user.error.verificationAlreadySent return userVerificationDetails - } else if (userDetails && userDetails.keycloakUserId) { + } + if (userDetails?.keycloakUserId) { userVerificationDetails.message = ResponseMessages.user.error.exists return userVerificationDetails - } else if (userDetails && !userDetails.keycloakUserId && userDetails.supabaseUserId) { + } + if (userDetails && !userDetails.keycloakUserId && userDetails.supabaseUserId) { userVerificationDetails.message = ResponseMessages.user.error.exists return userVerificationDetails - } else if (userDetails === null) { + } + if (userDetails === null) { return { isRegistrationCompleted: false, isEmailVerified: false, userId: null, message: ResponseMessages.user.error.notFound, } - } else { - return userVerificationDetails } + return userVerificationDetails } catch (error) { this.logger.error(`In check User : ${JSON.stringify(error)}`) throw new RpcException(error.response ? error.response : error) diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index 9f2e3a1fd..ca9bbb464 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -165,10 +165,10 @@ export class VerificationRepository { const { proofPresentationPayload, orgId } = payload //For Educreds - // biome-ignore lint/complexity/useLiteralKeys: - if (proofPresentationPayload?.['proofData']?.['presentation']?.presentationExchange?.verifiableCredential) { + + if (proofPresentationPayload?.['proofData']?.['presentation']?.presentationExchange?.verifiableCredential) { const emailId = - proofPresentationPayload?.['proofData']?.['presentation']?.presentationExchange?.verifiableCredential[0] + proofPresentationPayload?.proofData?.presentation?.presentationExchange?.verifiableCredential[0] .credentialSubject?.email encryptEmailId = await this.commonService.dataEncryption(emailId) } else { @@ -176,9 +176,9 @@ export class VerificationRepository { } //For Educreds - if (proofPresentationPayload?.['proofData']?.request?.presentationExchange) { + if (proofPresentationPayload?.proofData?.request?.presentationExchange) { schemaId = - proofPresentationPayload?.['proofData']?.request?.presentationExchange?.presentation_definition + proofPresentationPayload?.proofData?.request?.presentationExchange?.presentation_definition ?.input_descriptors[0].schema[0].uri } diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index c3c757255..8f12f6a39 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -144,7 +144,6 @@ export class VerificationService { return proofPresentationsResponse } catch (error) { - console.log('') this.logger.error( `[getProofRequests] [NATS call]- error in fetch proof requests details : ${JSON.stringify(error)}` ) @@ -212,7 +211,7 @@ export class VerificationService { const orgDetails = await this.verificationRepository.getOrgDetails(issuerId) const getVerifiedProofCount = await this.verificationRepository.getVerificationRecordsCount( - orgDetails?.orgId, + orgDetails?.['orgId'], VerificationProcessState.DONE ) @@ -739,7 +738,7 @@ export class VerificationService { const requestedPredicates = {} const indyAttributes = proofRequestpayload.proofFormats?.indy - if (indyAttributes && indyAttributes.attributes) { + if (indyAttributes?.attributes) { requestedAttributes = Object.fromEntries( indyAttributes.attributes.map((attribute, index) => { const attributeElement = attribute.attributeName || attribute.attributeNames @@ -761,20 +760,19 @@ export class VerificationService { ], }, ] - } else { - requestedPredicates[attributeReferent] = { - p_type: attribute.condition, - name: attributeElement, - p_value: Number.parseInt(attribute.value), - restrictions: [ - { - cred_def_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].credDefId - ? proofRequestpayload?.proofFormats?.indy?.attributes[index].credDefId - : undefined, - schema_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].schemaId, - }, - ], - } + } + requestedPredicates[attributeReferent] = { + p_type: attribute.condition, + name: attributeElement, + p_value: Number.parseInt(attribute.value), + restrictions: [ + { + cred_def_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].credDefId + ? proofRequestpayload?.proofFormats?.indy?.attributes[index].credDefId + : undefined, + schema_id: proofRequestpayload?.proofFormats?.indy?.attributes[index].schemaId, + }, + ], } return [attributeReferent] @@ -785,9 +783,8 @@ export class VerificationService { requestedAttributes, requestedPredicates, } - } else { - throw new BadRequestException(ResponseMessages.verification.error.proofNotSend) } + throw new BadRequestException(ResponseMessages.verification.error.proofNotSend) } catch (error) { this.logger.error(`[proofRequestPayload] - error in proof request payload : ${JSON.stringify(error)}`) throw new RpcException(error.response ? error.response : error) @@ -808,7 +805,7 @@ export class VerificationService { proofPresentationId?: string ): Promise { try { - let url + let url: string switch (verificationMethodLabel) { case 'get-proof-presentation': { url = @@ -903,8 +900,11 @@ export class VerificationService { try { const getAgentDetails = await this.verificationRepository.getAgentEndPoint(orgId) const verificationMethodLabel = 'get-verified-proof' + // biome-ignore lint/suspicious/noImplicitAnyLet: let credDefId + // biome-ignore lint/suspicious/noImplicitAnyLet: let schemaId + // biome-ignore lint/suspicious/noImplicitAnyLet: let certificate const orgAgentType = await this.verificationRepository.getOrgAgentType(getAgentDetails?.orgAgentTypeId) const url = await this.getAgentUrl( @@ -978,6 +978,7 @@ export class VerificationService { if (Object.keys(requestedAttributes).length !== 0 && Object.keys(requestedPredicates).length !== 0) { for (const key in requestedAttributes) { + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (requestedAttributes.hasOwnProperty(key)) { const requestedAttributeKey = requestedAttributes[key] const attributeName = requestedAttributeKey.name @@ -990,6 +991,7 @@ export class VerificationService { schemaId = getProofPresentationById?.response?.presentation?.indy?.identifiers[0].schema_id } + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (revealedAttrs.hasOwnProperty(key)) { const extractedData: IProofPresentationDetails = { [attributeName]: revealedAttrs[key]?.raw, @@ -1002,6 +1004,7 @@ export class VerificationService { } for (const key in requestedPredicates) { + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (requestedPredicates.hasOwnProperty(key)) { const attribute = requestedPredicates[key] @@ -1022,11 +1025,13 @@ export class VerificationService { } } else if (Object.keys(requestedAttributes).length !== 0) { for (const key in requestedAttributes) { + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (requestedAttributes.hasOwnProperty(key)) { const attribute = requestedAttributes[key] const attributeName = attribute.name ;[credDefId, schemaId] = await this._schemaCredDefRestriction(attribute, getProofPresentationById) + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (revealedAttrs.hasOwnProperty(key)) { const extractedData: IProofPresentationDetails = { [attributeName]: revealedAttrs[key]?.raw, @@ -1039,6 +1044,7 @@ export class VerificationService { } } else if (Object.keys(requestedPredicates).length !== 0) { for (const key in requestedPredicates) { + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (requestedPredicates.hasOwnProperty(key)) { const attribute = requestedPredicates[key] const attributeName = attribute?.name @@ -1070,15 +1076,14 @@ export class VerificationService { statusCode: error?.response?.status, error: errorStack, }) - } else { - throw new RpcException(error.response ? error.response : error) } + throw new RpcException(error.response ? error.response : error) } } async _schemaCredDefRestriction(attribute, getProofPresentationById): Promise { - let credDefId - let schemaId + let credDefId: string + let schemaId: string if (attribute?.restrictions) { credDefId = attribute?.restrictions[0]?.cred_def_id @@ -1130,14 +1135,13 @@ export class VerificationService { verificationErrorHandling(error): void { 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, - }) } + throw new RpcException({ + message: error?.status?.message?.error?.reason + ? error?.status?.message?.error?.reason + : error?.status?.message?.error, + statusCode: error?.status?.code, + }) } async natsCall( diff --git a/apps/webhook/src/webhook.service.ts b/apps/webhook/src/webhook.service.ts index a4dcb573c..b31e13888 100644 --- a/apps/webhook/src/webhook.service.ts +++ b/apps/webhook/src/webhook.service.ts @@ -33,25 +33,24 @@ export class WebhookService { async registerWebhook(registerWebhookDto: IWebhookDto): Promise { try { const orgData = await this.webhookRepository.getOrganizationDetails(registerWebhookDto.orgId) + // biome-ignore lint/suspicious/noImplicitAnyLet: let webhookUrl if (!orgData) { throw new NotFoundException(ResponseMessages.organisation.error.notFound) - } else { - try { - webhookUrl = await this.webhookRepository.registerWebhook( - registerWebhookDto.orgId, - registerWebhookDto.webhookUrl - ) - } catch (_error) { - throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook) - } + } + try { + webhookUrl = await this.webhookRepository.registerWebhook( + registerWebhookDto.orgId, + registerWebhookDto.webhookUrl + ) + } catch (_error) { + throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook) + } - if (!webhookUrl) { - throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook) - } else { - return webhookUrl.webhookUrl - } + if (!webhookUrl) { + throw new InternalServerErrorException(ResponseMessages.webhook.error.registerWebhook) } + return webhookUrl.webhookUrl } catch (error) { this.logger.error(`[registerWebhookUrl] - register webhook url details : ${JSON.stringify(error)}`) throw new RpcException(error.response ? error.response : error) @@ -59,6 +58,7 @@ export class WebhookService { } async getWebhookUrl(getWebhook: IWebhookUrl): Promise { + // biome-ignore lint/suspicious/noImplicitAnyLet: let webhookUrlInfo try { webhookUrlInfo = await this.webhookRepository.getWebhookUrl(getWebhook) @@ -85,7 +85,7 @@ export class WebhookService { }) if (!response.ok) { - this.logger.error(`Error in sending webhook response to org webhook url:`, response.status) + this.logger.error('Error in sending webhook response to org webhook url:', response.status) throw new InternalServerErrorException(ResponseMessages.webhook.error.webhookResponse) } return response diff --git a/biome.json b/biome.json index 010cb8340..403957889 100644 --- a/biome.json +++ b/biome.json @@ -51,16 +51,13 @@ "noInvalidUseBeforeDeclaration": "error" }, "suspicious": { - "noConsole": "error" + "noConsole": "warn" }, "complexity": { "noBannedTypes": "error", - "useLiteralKeys": { - "level": "warn", - "fix": "safe" - }, + "useLiteralKeys": "off", "noForEach": { - "level": "warn" + "level": "off" } }, "performance": { diff --git a/libs/aws/src/aws.service.ts b/libs/aws/src/aws.service.ts index 76cd5f562..66d071a39 100644 --- a/libs/aws/src/aws.service.ts +++ b/libs/aws/src/aws.service.ts @@ -46,7 +46,7 @@ export class AwsService { Key: `${pathAWS}/${encodeURIComponent(filename)}-${timestamp}.${ext}`, Body: fileBuffer, ContentEncoding: encoding, - ContentType: `image/png`, + ContentType: 'image/png', }) const imageUrl = `https://${bucketName}.s3.${process.env.AWS_PUBLIC_REGION}.amazonaws.com/${pathAWS}/${encodeURIComponent(filename)}-${timestamp}.${ext}` diff --git a/libs/client-registration/src/client-registration.service.ts b/libs/client-registration/src/client-registration.service.ts index 7cfd327c5..74ea334e7 100644 --- a/libs/client-registration/src/client-registration.service.ts +++ b/libs/client-registration/src/client-registration.service.ts @@ -40,9 +40,8 @@ export class ClientRegistrationService { ) if (getUserResponse[0].username === userDetails.email || getUserResponse[1].username === userDetails.email) { return { keycloakUserId: getUserResponse[0].id } - } else { - throw new NotFoundException(ResponseMessages.user.error.invalidKeycloakId) } + throw new NotFoundException(ResponseMessages.user.error.invalidKeycloakId) } catch (error) { this.logger.error(`error in keycloakUserRegistration in client-registration: ${JSON.stringify(error)}`) throw error @@ -150,8 +149,8 @@ export class ClientRegistrationService { try { const payload = new ClientCredentialTokenPayloadDto() if (!clientId && !clientSecret) { - this.logger.error(`getManagementToken ::: Client ID and client secret are missing`) - throw new BadRequestException(`Client ID and client secret are missing`) + this.logger.error('getManagementToken ::: Client ID and client secret are missing') + throw new BadRequestException('Client ID and client secret are missing') } const decryptClientId = await this.commonService.decryptPassword(clientId) @@ -575,8 +574,8 @@ export class ClientRegistrationService { async getUserToken(email: string, password: string, clientId: string, clientSecret: string) { const payload = new userTokenPayloadDto() if (!clientId && !clientSecret) { - this.logger.error(`getUserToken ::: Client ID and client secret are missing`) - throw new BadRequestException(`Client ID and client secret are missing`) + this.logger.error('getUserToken ::: Client ID and client secret are missing') + throw new BadRequestException('Client ID and client secret are missing') } const decryptClientId = await this.commonService.decryptPassword(clientId) @@ -618,8 +617,8 @@ export class ClientRegistrationService { try { const payload = new accessTokenPayloadDto() if (!clientId && !clientSecret) { - this.logger.error(`getAccessToken ::: Client ID and client secret are missing`) - throw new BadRequestException(`Client ID and client secret are missing`) + this.logger.error('getAccessToken ::: Client ID and client secret are missing') + throw new BadRequestException('Client ID and client secret are missing') } const decryptClientId = await this.commonService.decryptPassword(clientId) diff --git a/libs/common/src/NATSClient.ts b/libs/common/src/NATSClient.ts index fca3087bf..d1ffd6064 100644 --- a/libs/common/src/NATSClient.ts +++ b/libs/common/src/NATSClient.ts @@ -19,9 +19,9 @@ export class NATSClient { this.logger = new Logger('NATSClient') } - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + // biome-ignore lint/suspicious/noExplicitAny: sendNats(serviceProxy: ClientProxy, cmd: string, payload: any): Promise { - this.logger.log(`Inside NATSClient for sendNats()`) + this.logger.log('Inside NATSClient for sendNats()') const pattern = { cmd } const headers = nats.headers(1, this.contextStorageService.getContextId()) const record = new NatsRecordBuilder(payload).setHeaders(headers).build() @@ -36,6 +36,7 @@ export class NATSClient { .toPromise() } + // biome-ignore lint/suspicious/noExplicitAny: sendNatsMessage(serviceProxy: ClientProxy, cmd: string, payload: any): Promise { const pattern = { cmd } const headers = nats.headers(1, this.contextStorageService.getContextId()) @@ -46,6 +47,7 @@ export class NATSClient { return firstValueFrom(result) } + // biome-ignore lint/suspicious/noExplicitAny: send(serviceProxy: ClientProxy, pattern: object, payload: any): Promise { let contextId = this.contextStorageService.getContextId() diff --git a/libs/common/src/cast.helper.ts b/libs/common/src/cast.helper.ts index 1a63be5a5..8ffb70ba6 100644 --- a/libs/common/src/cast.helper.ts +++ b/libs/common/src/cast.helper.ts @@ -73,7 +73,7 @@ export function toNumber(value: string, opts: ToNumberOptions = {}): number { } export function ledgerName(value: string): string { - let network + let network: string network = value.replace(':', ' ') network = network.charAt(0).toUpperCase() + network.slice(1) const words = network.split(' ') @@ -127,7 +127,7 @@ export class ImageBase64Validator implements ValidatorConstraintInterface { validate(value: string, _args: ValidationArguments) { // Implement your custom validation logic here // Validation to allow option param logo - if (value == '') { + if (value === '') { return true } if (!value || typeof value !== 'string') { @@ -147,7 +147,7 @@ export class ImageBase64Validator implements ValidatorConstraintInterface { throw new BadRequestException('Please provide valid MIME type') } // Validate base64 data - if (!isBase64(base64Data) || base64Data == '' || base64Data == null) { + if (!isBase64(base64Data) || base64Data === '' || base64Data == null) { throw new BadRequestException('Invalid base64 string') } return true @@ -321,7 +321,7 @@ export class AgentSpinupValidator { } public static validate(agentSpinupDto): void { - this.validateWalletName(agentSpinupDto.walletName) + AgentSpinupValidator.validateWalletName(agentSpinupDto.walletName) } } diff --git a/libs/common/src/common.utils.ts b/libs/common/src/common.utils.ts index fa4cb7408..5fb81695d 100644 --- a/libs/common/src/common.utils.ts +++ b/libs/common/src/common.utils.ts @@ -26,8 +26,8 @@ export function paginator(items: T[], current_page: number, items_per_page: n } export function orderValues(key, order = 'asc') { - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types return function innerSort(a, b) { + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) { // property doesn't exist on either object return 0 diff --git a/libs/common/src/exception-handler.ts b/libs/common/src/exception-handler.ts index 70ddd2729..23c09515d 100644 --- a/libs/common/src/exception-handler.ts +++ b/libs/common/src/exception-handler.ts @@ -84,7 +84,7 @@ export class CustomExceptionFilter implements RpcExceptionFilter { // Add explicit types for 'exception' and 'host' // biome-ignore lint/suspicious/noExplicitAny: - catch(exception: RpcException, _host: ArgumentsHost): Observable { + catch(exception: RpcException, _host: ArgumentsHost): Observable { this.logger.error(`CustomExceptionFilter caught error: ${JSON.stringify(exception)}`) return throwError(() => new RpcException({ message: exception.getError(), code: HttpStatus.BAD_REQUEST })) } diff --git a/libs/http-exception.filter.ts b/libs/http-exception.filter.ts index f6e864c71..3858eb896 100644 --- a/libs/http-exception.filter.ts +++ b/libs/http-exception.filter.ts @@ -22,6 +22,7 @@ export class HttpExceptionFilter implements ExceptionFilter { case RpcException: this.logger.error('Its RpcException') return throwError(() => exception.getError()) + // biome-ignore lint/correctness/noUnreachable: break case PrismaClientKnownRequestError: this.logger.error('Its PrismaClientKnownRequestError') diff --git a/libs/logger/src/winstonLogger.ts b/libs/logger/src/winstonLogger.ts index f8954edb6..01395819f 100644 --- a/libs/logger/src/winstonLogger.ts +++ b/libs/logger/src/winstonLogger.ts @@ -20,9 +20,7 @@ if (process.env.ELK_LOG?.toLowerCase() === 'true') { } esTransport = new Elasticsearch.ElasticsearchTransport(esTransportOpts) - esTransport.on('error', (error) => { - console.error('Error caught in logger', error) - }) + esTransport.on('error', (_error) => {}) } @Injectable() @@ -42,7 +40,7 @@ export default class WinstonLogger implements Logger { // Setting log levels for winston const levels = {} let cont = 0 - // biome-ignore lint/complexity/noForEach: + Object.values(LogLevel).forEach((level) => { levels[level] = cont cont++ diff --git a/libs/prisma-service/cli.ts b/libs/prisma-service/cli.ts index 4e6a45c4e..98963e723 100644 --- a/libs/prisma-service/cli.ts +++ b/libs/prisma-service/cli.ts @@ -37,8 +37,7 @@ const getRole = async (roleName) => { }, }) return roleDetails - } catch (error) { - console.error('An error occurred in getRole:', error) + } catch (_error) { } } @@ -54,8 +53,7 @@ const createUserOrgRole = async (userId, roleId) => { }) return saveResponse - } catch (error) { - console.error('An error occurred in createUserOrgRole:', error) + } catch (_error) { } } @@ -89,10 +87,7 @@ const createUser = async () => { const platformRoleData = await getRole('platform_admin') await createUserOrgRole(user.id, platformRoleData.id) - - console.log('Platform admin user created') - } catch (e) { - console.error('An error occurred in createUser:', e) + } catch (_e) { } } @@ -101,4 +96,4 @@ async function main() { readline.close() } -main().catch((e) => console.error(e)) +main().catch((_e) => ) From 6ff63b9e081a83f63686ec6015a2371c3be60f73 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 15 May 2025 19:49:49 +0530 Subject: [PATCH 12/23] fix: biomejs issues Signed-off-by: Krishna Waske --- apps/issuance/libs/helpers/attributes.extractor.ts | 1 - .../interfaces/credential-definition.interface.ts | 1 + apps/user/src/user.service.ts | 3 ++- biome.json | 11 ++++++++--- libs/common/src/cast.helper.ts | 6 ++++-- libs/logger/src/transports/consoleTransport.ts | 2 ++ libs/logger/src/transports/fileTransport.ts | 1 + libs/prisma-service/cli.ts | 13 +++++++++---- 8 files changed, 27 insertions(+), 11 deletions(-) diff --git a/apps/issuance/libs/helpers/attributes.extractor.ts b/apps/issuance/libs/helpers/attributes.extractor.ts index 563c8ae89..896cd7ac3 100644 --- a/apps/issuance/libs/helpers/attributes.extractor.ts +++ b/apps/issuance/libs/helpers/attributes.extractor.ts @@ -26,7 +26,6 @@ export function extractAttributeNames( if (attributeObj.hasOwnProperty('items') && Array.isArray(attributeObj.items)) { // Always use index 0 for items in an array // biome-ignore lint/suspicious/noExplicitAny: - attributeObj.items.forEach((item: any) => { extractAttributeNames(item, `${newParentKey}${CommonConstants.NESTED_ATTRIBUTE_SEPARATOR}0`, result, true) }) diff --git a/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts b/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts index 0d75d966d..3e315d4c5 100644 --- a/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts +++ b/apps/ledger/src/credential-definition/interfaces/credential-definition.interface.ts @@ -33,6 +33,7 @@ export interface GetCredDefFromTenantPayload { } export interface CredDefSchema { + // biome-ignore lint/suspicious/noExplicitAny: [x: string]: any credentialDefinitionId?: string schemaCredDefName: string diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index ef158f0f2..f1be322c3 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -1032,6 +1032,7 @@ export class UserService { async checkUserExist(email: string): Promise { try { const userDetails = await this.userRepository.checkUniqueUserExist(email.toLowerCase()) + // biome-ignore lint/suspicious/noImplicitAnyLet: let userVerificationDetails if (userDetails) { userVerificationDetails = { @@ -1103,7 +1104,7 @@ export class UserService { throw new BadRequestException(ResponseMessages.user.error.platformSetttingsNotFound) } - platformSettings.platform_config = platformConfigSettings + platformSettings['platform_config'] = platformConfigSettings return platformSettings } catch (error) { diff --git a/biome.json b/biome.json index 403957889..e85bdccaf 100644 --- a/biome.json +++ b/biome.json @@ -11,7 +11,7 @@ "formatter": { "indentStyle": "space", "lineWidth": 120, - "ignore": ["**/node_modules", "**/dist", "**/.idea", "**/coverage", "**/pnpm-lock.yaml"] + "ignore": ["**/node_modules", "**/dist", "**/.idea", "**/coverage", "**/pnpm-lock.yaml", "*.json"] }, "javascript": { "parser": { @@ -51,7 +51,11 @@ "noInvalidUseBeforeDeclaration": "error" }, "suspicious": { - "noConsole": "warn" + "noConsole": { + "level": "warn", + "fix": "none", + "options": { "allow": []} + } }, "complexity": { "noBannedTypes": "error", @@ -76,7 +80,8 @@ "**/coverage", "**/pnpm-lock.yaml", "**/test/*", - "*.spec.ts" + "*.spec.ts", + "*.json" ] } } diff --git a/libs/common/src/cast.helper.ts b/libs/common/src/cast.helper.ts index 8ffb70ba6..8de16751c 100644 --- a/libs/common/src/cast.helper.ts +++ b/libs/common/src/cast.helper.ts @@ -45,11 +45,11 @@ export function toDate(value: string): Date { export function toBoolean(value: string): boolean { // eslint-disable-next-line no-param-reassign - value = value.toLowerCase() + const _value = value.toLowerCase() // return 'true' === value || '1' === value ? true : false; - return Boolean(value === 'true' || value === '1') + return Boolean(_value === 'true' || _value === '1') } export function toNumber(value: string, opts: ToNumberOptions = {}): number { @@ -303,6 +303,7 @@ export function validateSchemaPayload(schemaPayload: ISchemaFields, schemaType: } } +// biome-ignore lint/complexity/noStaticOnlyClass: export class AgentSpinupValidator { private static validateField(value: string, errorMessage: string): void { if (!value) { @@ -338,6 +339,7 @@ export const createOobJsonldIssuancePayload = (JsonldCredentialDetails: IJsonldC const proofType = orgDid?.includes(DidMethod.POLYGON) ? ProofType.POLYGON_PROOFTYPE : ProofType.NO_LEDGER_PROOFTYPE for (const key in credentialData) { + // biome-ignore lint/suspicious/noPrototypeBuiltins: if (credentialData.hasOwnProperty(key) && TemplateIdentifier.EMAIL_COLUMN !== key) { credentialSubject[key] = credentialData[key] } diff --git a/libs/logger/src/transports/consoleTransport.ts b/libs/logger/src/transports/consoleTransport.ts index 389925c12..4559b46df 100644 --- a/libs/logger/src/transports/consoleTransport.ts +++ b/libs/logger/src/transports/consoleTransport.ts @@ -19,9 +19,11 @@ interface LogData { error?: string durationMs?: number stack?: string + // biome-ignore lint/suspicious/noExplicitAny: props?: Record } +// biome-ignore lint/complexity/noStaticOnlyClass: export default class ConsoleTransport { public static createColorize(): winston.transports.ConsoleTransportInstance { return new winston.transports.Console({ diff --git a/libs/logger/src/transports/fileTransport.ts b/libs/logger/src/transports/fileTransport.ts index fa05dc13c..e4dbb2320 100644 --- a/libs/logger/src/transports/fileTransport.ts +++ b/libs/logger/src/transports/fileTransport.ts @@ -1,5 +1,6 @@ import DailyRotateFile = require('winston-daily-rotate-file') +// biome-ignore lint/complexity/noStaticOnlyClass: export default class FileTransport { public static create() { return new DailyRotateFile({ diff --git a/libs/prisma-service/cli.ts b/libs/prisma-service/cli.ts index 98963e723..4e6a45c4e 100644 --- a/libs/prisma-service/cli.ts +++ b/libs/prisma-service/cli.ts @@ -37,7 +37,8 @@ const getRole = async (roleName) => { }, }) return roleDetails - } catch (_error) { + } catch (error) { + console.error('An error occurred in getRole:', error) } } @@ -53,7 +54,8 @@ const createUserOrgRole = async (userId, roleId) => { }) return saveResponse - } catch (_error) { + } catch (error) { + console.error('An error occurred in createUserOrgRole:', error) } } @@ -87,7 +89,10 @@ const createUser = async () => { const platformRoleData = await getRole('platform_admin') await createUserOrgRole(user.id, platformRoleData.id) - } catch (_e) { + + console.log('Platform admin user created') + } catch (e) { + console.error('An error occurred in createUser:', e) } } @@ -96,4 +101,4 @@ async function main() { readline.close() } -main().catch((_e) => ) +main().catch((e) => console.error(e)) From 72f30fba0bf47ab2fef245810e81e010f8952491 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 15 May 2025 19:51:02 +0530 Subject: [PATCH 13/23] fix: biomejs issues Signed-off-by: Krishna Waske --- biome.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biome.json b/biome.json index e85bdccaf..a8fcececc 100644 --- a/biome.json +++ b/biome.json @@ -54,7 +54,7 @@ "noConsole": { "level": "warn", "fix": "none", - "options": { "allow": []} + "options": {} } }, "complexity": { From a23bd4ecf8945f69f4d1f05955a194e1021a9264 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Fri, 16 May 2025 11:26:13 +0530 Subject: [PATCH 14/23] fix: remove eslint imports Signed-off-by: Krishna Waske --- .../repositories/agent-service.repository.ts | 25 ++++++------------- .../src/authz/dtos/forgot-password.dto.ts | 3 +-- .../src/connection/dtos/connection.dto.ts | 1 - .../src/issuance/dtos/issuance.dto.ts | 3 +-- .../src/notification/dtos/notification.dto.ts | 3 +-- .../dtos/create-organization-dto.ts | 3 +-- .../src/user/dto/create-user.dto.ts | 3 +-- .../src/verification/dto/request-proof.dto.ts | 7 +++--- .../src/cloud-wallet.repository.ts | 8 ++---- apps/connection/src/connection.repository.ts | 19 ++++++-------- .../src/interfaces/connection.interfaces.ts | 1 - .../interfaces/issuance.interfaces.ts | 1 - apps/issuance/src/issuance.repository.ts | 8 +++--- apps/ledger/src/ledger.service.ts | 2 +- .../src/repositories/ledger.repository.ts | 2 +- .../repositories/organization.repository.ts | 5 ++-- apps/organization/src/organization.service.ts | 18 +++---------- .../user/repositories/fido-user.repository.ts | 4 +-- .../repositories/user-device.repository.ts | 14 +++++------ apps/user/repositories/user.repository.ts | 14 ++++------- apps/user/src/user.controller.ts | 3 +-- apps/user/src/user.service.ts | 11 +++----- apps/utility/src/utilities.repository.ts | 3 +-- .../repositories/verification.repository.ts | 8 +++--- libs/org-roles/repositories/index.ts | 4 +-- libs/org-roles/src/org-roles.service.ts | 4 +-- libs/prisma-service/cli.ts | 2 -- libs/user-org-roles/repositories/index.ts | 7 +++--- .../src/user-org-roles.service.ts | 4 +-- 29 files changed, 66 insertions(+), 124 deletions(-) diff --git a/apps/agent-service/src/repositories/agent-service.repository.ts b/apps/agent-service/src/repositories/agent-service.repository.ts index 3058ffc90..607a917f1 100644 --- a/apps/agent-service/src/repositories/agent-service.repository.ts +++ b/apps/agent-service/src/repositories/agent-service.repository.ts @@ -1,7 +1,7 @@ import { AgentType, PrismaTables } from '@credebl/enum/enum' import type { PrismaService } from '@credebl/prisma-service' import { ConflictException, Injectable, type Logger } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { Prisma, ledgerConfig, @@ -37,7 +37,7 @@ export class AgentServiceRepository { * Get platform config details * @returns */ - // eslint-disable-next-line camelcase + async getPlatformConfigDetails(): Promise { try { return this.prisma.platform_config.findFirst() @@ -99,7 +99,6 @@ export class AgentServiceRepository { } } - // eslint-disable-next-line camelcase async createOrgAgent(agentSpinUpStatus: number, userId: string): Promise { try { return this.prisma.org_agents.create({ @@ -118,7 +117,6 @@ export class AgentServiceRepository { } } - // eslint-disable-next-line camelcase async removeOrgAgent(id: string): Promise { try { if (id) { @@ -134,7 +132,6 @@ export class AgentServiceRepository { } } - // eslint-disable-next-line camelcase async getAgentDetailsByOrgId(orgId: string): Promise { try { const agentDetails = await this.prisma.org_agents.findFirst({ @@ -154,7 +151,7 @@ export class AgentServiceRepository { * @param storeAgentDetails * @returns */ - // eslint-disable-next-line camelcase + async storeOrgAgentDetails(storeOrgAgentDetails: IStoreOrgAgentDetails): Promise { try { const { id, userId, ledgerId, did, didDoc, ...commonFields } = storeOrgAgentDetails @@ -168,7 +165,6 @@ export class AgentServiceRepository { orgDid: did, } - // eslint-disable-next-line camelcase const query: Promise = id ? this.prisma.org_agents.update({ where: { id }, @@ -188,7 +184,7 @@ export class AgentServiceRepository { * @param storeDidDetails * @returns did details */ - // eslint-disable-next-line camelcase + async storeDidDetails(storeDidDetails: IStoreDidDetails): Promise { try { const { orgId, did, didDocument, isPrimaryDid, userId, orgAgentId } = storeDidDetails @@ -215,7 +211,7 @@ export class AgentServiceRepository { * @param did * @returns did details */ - // eslint-disable-next-line camelcase + async setPrimaryDid(orgDid: string, orgId: string, didDocument: Prisma.JsonValue): Promise { try { return await this.prisma.org_agents.update({ @@ -233,7 +229,6 @@ export class AgentServiceRepository { } } - // eslint-disable-next-line camelcase async updateLedgerId(orgId: string, ledgerId: string): Promise { try { return await this.prisma.org_agents.update({ @@ -255,7 +250,7 @@ export class AgentServiceRepository { * @param orgId * @returns */ - // eslint-disable-next-line camelcase + async getAgentDetails(orgId: string): Promise { try { if (orgId) { @@ -274,14 +269,12 @@ export class AgentServiceRepository { } } - // eslint-disable-next-line camelcase async platformAdminAgent(platformOrg: string): Promise { return this.prisma.organisation.findFirstOrThrow({ where: { name: platformOrg, }, select: { - // eslint-disable-next-line camelcase org_agents: { select: { agentSpinUpStatus: true, @@ -397,7 +390,7 @@ export class AgentServiceRepository { * @param orgId * @returns Agent health details */ - // eslint-disable-next-line camelcase + async getOrgAgentDetails(orgId: string): Promise { try { if (orgId) { @@ -414,7 +407,6 @@ export class AgentServiceRepository { } } - // eslint-disable-next-line camelcase async getOrgAgentType(orgAgentId: string): Promise { try { const orgAgent = await this.prisma.org_agents_type.findUnique({ @@ -444,7 +436,6 @@ export class AgentServiceRepository { } } - // eslint-disable-next-line camelcase async getAgentApiKey(orgId: string): Promise { try { if (orgId) { @@ -511,7 +502,7 @@ export class AgentServiceRepository { async deleteOrgAgentByOrg(orgId: string): Promise<{ orgDid: Prisma.BatchPayload agentInvitation: Prisma.BatchPayload - // eslint-disable-next-line camelcase + deleteOrgAgent: org_agents }> { const tablesToCheck = [ diff --git a/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts b/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts index 32d360488..67a621c01 100644 --- a/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts +++ b/apps/api-gateway/src/authz/dtos/forgot-password.dto.ts @@ -17,9 +17,8 @@ export class ForgotPasswordDto { @IsOptional() @IsUrl( { - // eslint-disable-next-line camelcase require_protocol: true, - // eslint-disable-next-line camelcase + require_tld: true, }, { message: 'brandLogoUrl should be a valid URL' } diff --git a/apps/api-gateway/src/connection/dtos/connection.dto.ts b/apps/api-gateway/src/connection/dtos/connection.dto.ts index a3d1f22b2..7a230b341 100644 --- a/apps/api-gateway/src/connection/dtos/connection.dto.ts +++ b/apps/api-gateway/src/connection/dtos/connection.dto.ts @@ -352,7 +352,6 @@ class InvitationDto { @ApiPropertyOptional() @IsOptional() @IsString({ each: true }) - // eslint-disable-next-line camelcase handshake_protocols: string[] @ApiProperty() diff --git a/apps/api-gateway/src/issuance/dtos/issuance.dto.ts b/apps/api-gateway/src/issuance/dtos/issuance.dto.ts index 873a807b1..2e40b61be 100644 --- a/apps/api-gateway/src/issuance/dtos/issuance.dto.ts +++ b/apps/api-gateway/src/issuance/dtos/issuance.dto.ts @@ -564,9 +564,8 @@ export class ClientDetails { @IsOptional() @IsUrl( { - // eslint-disable-next-line camelcase require_protocol: true, - // eslint-disable-next-line camelcase + require_tld: true, }, { message: 'brandLogoUrl should be a valid URL' } diff --git a/apps/api-gateway/src/notification/dtos/notification.dto.ts b/apps/api-gateway/src/notification/dtos/notification.dto.ts index e92484916..99f3eb7be 100644 --- a/apps/api-gateway/src/notification/dtos/notification.dto.ts +++ b/apps/api-gateway/src/notification/dtos/notification.dto.ts @@ -37,9 +37,8 @@ export class RegisterOrgWebhhookEndpointDto { @IsNotEmpty({ message: 'notificationWebhook is required.' }) @IsString({ message: 'notificationWebhook must be in string format.' }) @IsUrl({ - // eslint-disable-next-line camelcase require_protocol: true, // require URL protocol (e.g., http:// or https://) - // eslint-disable-next-line camelcase + require_tld: true, // require top-level domain (e.g., .com, .net) }) notificationWebhook: string diff --git a/apps/api-gateway/src/organization/dtos/create-organization-dto.ts b/apps/api-gateway/src/organization/dtos/create-organization-dto.ts index 166ed1a8d..cea981869 100644 --- a/apps/api-gateway/src/organization/dtos/create-organization-dto.ts +++ b/apps/api-gateway/src/organization/dtos/create-organization-dto.ts @@ -35,9 +35,8 @@ export class CreateOrganizationDto extends GeoLocationDto { @IsNotEmpty({ message: 'notificationWebhook is required.' }) @IsString({ message: 'notificationWebhook must be in string format.' }) @IsUrl({ - // eslint-disable-next-line camelcase require_protocol: true, // require URL protocol (e.g., http:// or https://) - // eslint-disable-next-line camelcase + require_tld: true, // require top-level domain (e.g., .com, .net) }) notificationWebhook?: 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 225842361..3e5cd59c3 100644 --- a/apps/api-gateway/src/user/dto/create-user.dto.ts +++ b/apps/api-gateway/src/user/dto/create-user.dto.ts @@ -26,9 +26,8 @@ export class UserEmailVerificationDto { @IsOptional() @IsUrl( { - // eslint-disable-next-line camelcase require_protocol: true, - // eslint-disable-next-line camelcase + require_tld: true, }, { message: 'brandLogoUrl should be a valid URL' } diff --git a/apps/api-gateway/src/verification/dto/request-proof.dto.ts b/apps/api-gateway/src/verification/dto/request-proof.dto.ts index 02b11f967..6982bbf16 100644 --- a/apps/api-gateway/src/verification/dto/request-proof.dto.ts +++ b/apps/api-gateway/src/verification/dto/request-proof.dto.ts @@ -162,7 +162,6 @@ export class ProofRequestPresentationDefinition { @ArrayMinSize(1) @ValidateNested({ each: true }) @Type(() => InputDescriptors) - // eslint-disable-next-line camelcase input_descriptors: InputDescriptors[] } @@ -237,7 +236,7 @@ export class RequestProofDtoBase extends ProofPayload { example: { id: '32f54163-7166-48f1-93d8-ff217bdb0653', purpose: 'Used for KYC verification.', - // eslint-disable-next-line camelcase + input_descriptors: [ { id: 'healthcare_input_1', @@ -375,7 +374,7 @@ export class SendProofRequestPayload { indy: { name: 'Verify national identity', version: '1.0', - // eslint-disable-next-line camelcase + requested_attributes: { verifynameAddress: { names: ['name', 'address'], @@ -386,7 +385,7 @@ export class SendProofRequestPayload { restrictions: [{ schema_id: 'KU583UbI4yAKfaBTSz1rqG:2:Birth Certificate:1.0.0' }], }, }, - // eslint-disable-next-line camelcase + requested_predicates: {}, }, }, diff --git a/apps/cloud-wallet/src/cloud-wallet.repository.ts b/apps/cloud-wallet/src/cloud-wallet.repository.ts index 23d8178b0..ffbbf9066 100644 --- a/apps/cloud-wallet/src/cloud-wallet.repository.ts +++ b/apps/cloud-wallet/src/cloud-wallet.repository.ts @@ -7,7 +7,7 @@ import type { import type { CloudWalletType } from '@credebl/enum/enum' import type { PrismaService } from '@credebl/prisma-service' import { Injectable, type Logger } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { cloud_wallet_user_info, user } from '@prisma/client' @Injectable() @@ -17,7 +17,6 @@ export class CloudWalletRepository { private readonly logger: Logger ) {} - // eslint-disable-next-line camelcase async getCloudWalletDetails(type: CloudWalletType): Promise { try { const agentDetails = await this.prisma.cloud_wallet_user_info.findFirstOrThrow({ @@ -32,7 +31,6 @@ export class CloudWalletRepository { } } - // eslint-disable-next-line camelcase async checkUserExist(email: string): Promise { try { const agentDetails = await this.prisma.cloud_wallet_user_info.findUnique({ @@ -46,7 +44,7 @@ export class CloudWalletRepository { throw error } } - // eslint-disable-next-line camelcase + async storeCloudWalletDetails(cloudWalletDetails: ICloudWalletDetails): Promise { try { const { @@ -92,7 +90,6 @@ export class CloudWalletRepository { } } - // eslint-disable-next-line camelcase async getCloudWalletInfo(email: string): Promise { try { const walletInfoData = await this.prisma.cloud_wallet_user_info.findUnique({ @@ -136,7 +133,6 @@ export class CloudWalletRepository { } } - // eslint-disable-next-line camelcase async getCloudSubWallet(userId: string): Promise { try { const cloudSubWalletDetails = await this.prisma.cloud_wallet_user_info.findFirstOrThrow({ diff --git a/apps/connection/src/connection.repository.ts b/apps/connection/src/connection.repository.ts index 63931c2bc..2e9593a61 100644 --- a/apps/connection/src/connection.repository.ts +++ b/apps/connection/src/connection.repository.ts @@ -4,7 +4,7 @@ import { PrismaTables, SortValue } from '@credebl/enum/enum' import type { PrismaService } from '@credebl/prisma-service' import type { IUserRequest } from '@credebl/user-request/user-request.interface' import { ConflictException, Injectable, type Logger } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { agent_invitations, org_agents, platform_config, shortening_url } from '@prisma/client' import type { IConnectionSearchCriteria, ICreateConnection, OrgAgent } from './interfaces/connection.interfaces' // import { OrgAgent } from './interfaces/connection.interfaces'; @@ -20,7 +20,7 @@ export class ConnectionRepository { * @param connectionId * @returns Get getAgentEndPoint details */ - // eslint-disable-next-line camelcase + async getAgentEndPoint(orgId: string): Promise { try { const agentDetails = await this.prisma.org_agents.findFirst({ @@ -45,13 +45,12 @@ export class ConnectionRepository { * @param orgId * @returns Get connection details */ - // eslint-disable-next-line camelcase + async saveAgentConnectionInvitations( connectionInvitation: string, agentId: string, orgId: string, invitationDid: string - // eslint-disable-next-line camelcase ): Promise { try { const agentDetails = await this.prisma.agent_invitations.create({ @@ -75,7 +74,7 @@ export class ConnectionRepository { * @param orgId * @returns Get connection details */ - // eslint-disable-next-line camelcase + async getConnectionInvitationByOrgId(orgId: string): Promise { try { const agentInvitationDetails = await this.prisma.agent_invitations.findFirst({ @@ -111,7 +110,7 @@ export class ConnectionRepository { * @param orgId * @returns Get connection details */ - // eslint-disable-next-line camelcase + async saveConnectionWebhook(payload: ICreateConnection): Promise { try { let organisationId: string @@ -195,7 +194,7 @@ export class ConnectionRepository { * @param connectionInvitationUrl * @returns Get storeShorteningUrl details */ - // eslint-disable-next-line camelcase + async storeShorteningUrl(referenceId: string): Promise { try { return this.prisma.shortening_url.create({ @@ -210,7 +209,6 @@ export class ConnectionRepository { } } - // eslint-disable-next-line camelcase async getOrganization(tenantId: string): Promise { try { return this.prisma.org_agents.findFirst({ @@ -229,7 +227,7 @@ export class ConnectionRepository { * @param referenceId * @returns Get storeShorteningUrl details */ - // eslint-disable-next-line camelcase + async getShorteningUrl(referenceId: string): Promise { try { return this.prisma.shortening_url.findFirst({ @@ -247,7 +245,7 @@ export class ConnectionRepository { * Get platform config details * @returns */ - // eslint-disable-next-line camelcase + async getPlatformConfigDetails(): Promise { try { return this.prisma.platform_config.findFirst() @@ -373,7 +371,6 @@ export class ConnectionRepository { } } - // eslint-disable-next-line camelcase async getInvitationDidByOrgId(orgId: string): Promise { try { return this.prisma.agent_invitations.findMany({ diff --git a/apps/connection/src/interfaces/connection.interfaces.ts b/apps/connection/src/interfaces/connection.interfaces.ts index d6d2d0d8f..35572fa6e 100644 --- a/apps/connection/src/interfaces/connection.interfaces.ts +++ b/apps/connection/src/interfaces/connection.interfaces.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line camelcase import type { IUserRequest } from '@credebl/user-request/user-request.interface' import type { organisation } from '@prisma/client' import type { UserRoleOrgPermsDto } from 'apps/api-gateway/src/dtos/user-role-org-perms.dto' diff --git a/apps/issuance/interfaces/issuance.interfaces.ts b/apps/issuance/interfaces/issuance.interfaces.ts index 3e4d22a7c..ed19937ce 100644 --- a/apps/issuance/interfaces/issuance.interfaces.ts +++ b/apps/issuance/interfaces/issuance.interfaces.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line camelcase import type { AutoAccept, SchemaType } from '@credebl/enum/enum' import type { Prisma, organisation } from '@prisma/client' diff --git a/apps/issuance/src/issuance.repository.ts b/apps/issuance/src/issuance.repository.ts index 3c442696a..eb352c8f6 100644 --- a/apps/issuance/src/issuance.repository.ts +++ b/apps/issuance/src/issuance.repository.ts @@ -7,7 +7,7 @@ import { type Logger, NotFoundException, } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { agent_invitations, credentials, @@ -47,7 +47,7 @@ export class IssuanceRepository { * @param connectionId * @returns Get getAgentEndPoint details */ - // eslint-disable-next-line camelcase + async getAgentEndPoint(orgId: string): Promise { try { const agentDetails = await this.prisma.org_agents.findFirst({ @@ -186,7 +186,7 @@ export class IssuanceRepository { * @param connectionId * @returns Get saved credential details */ - // eslint-disable-next-line camelcase + async saveIssuedCredentialDetails(payload: IssueCredentialWebhookPayload): Promise { try { let organisationId: string @@ -255,7 +255,7 @@ export class IssuanceRepository { * Get platform config details * @returns */ - // eslint-disable-next-line camelcase + async getPlatformConfigDetails(): Promise { try { return this.prisma.platform_config.findFirst() diff --git a/apps/ledger/src/ledger.service.ts b/apps/ledger/src/ledger.service.ts index 58faab9e3..dca182a99 100644 --- a/apps/ledger/src/ledger.service.ts +++ b/apps/ledger/src/ledger.service.ts @@ -2,7 +2,7 @@ import type { INetworkUrl } from '@credebl/common/interfaces/schema.interface' import { ResponseMessages } from '@credebl/common/response-messages' import { Injectable, NotFoundException } from '@nestjs/common' import { RpcException } from '@nestjs/microservices' -// eslint-disable-next-line camelcase + import type { ledgers } from '@prisma/client' import { BaseService } from 'libs/service/base.service' import type { LedgerDetails } from './interfaces/ledgers.interface' diff --git a/apps/ledger/src/repositories/ledger.repository.ts b/apps/ledger/src/repositories/ledger.repository.ts index c5b957f26..7dc79c394 100644 --- a/apps/ledger/src/repositories/ledger.repository.ts +++ b/apps/ledger/src/repositories/ledger.repository.ts @@ -1,7 +1,7 @@ import type { INetworkUrl } from '@credebl/common/interfaces/schema.interface' import type { PrismaService } from '@credebl/prisma-service' import { Injectable, Logger } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { ledgers } from '@prisma/client' import type { LedgerDetails } from '../interfaces/ledgers.interface' import type { ISchemasList, ISchemasResult } from '../schema/interfaces/schema.interface' diff --git a/apps/organization/repositories/organization.repository.ts b/apps/organization/repositories/organization.repository.ts index ecfb55d3b..d3f2cc903 100644 --- a/apps/organization/repositories/organization.repository.ts +++ b/apps/organization/repositories/organization.repository.ts @@ -8,7 +8,7 @@ import { type Logger, NotFoundException, } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { Prisma, agent_invitations, @@ -886,7 +886,6 @@ export class OrganizationRepository { } } - // eslint-disable-next-line camelcase async getAllOrganizationDid(orgId: string): Promise { try { return this.prisma.org_dids.findMany({ @@ -1162,7 +1161,7 @@ export class OrganizationRepository { id: { in: orgIds }, OR: [ { name: { contains: search, mode: 'insensitive' } }, - // eslint-disable-next-line camelcase + { org_agents: { some: { orgDid: { contains: search, mode: 'insensitive' } } } }, ], }, diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index c70179e98..d70e107c3 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -32,7 +32,7 @@ import { } from '@nestjs/common' import { type ClientProxy, RpcException } from '@nestjs/microservices' /* eslint-disable prefer-destructuring */ -// eslint-disable-next-line camelcase + import { RecordType, type org_invitations, type organisation, type user } from '@prisma/client' import type { Cache } from 'cache-manager' import { OrgRoles } from 'libs/org-roles/enums' @@ -99,7 +99,6 @@ export class OrganizationService { * @returns */ - // eslint-disable-next-line camelcase async createOrganization( createOrgDto: CreateOrganizationDto, userId: string, @@ -198,7 +197,6 @@ export class OrganizationService { * @returns */ - // eslint-disable-next-line camelcase async setPrimaryDid(orgId: string, did: string, id: string): Promise { try { const organizationExist = await this.organizationRepository.getOrgProfile(orgId) @@ -513,7 +511,6 @@ export class OrganizationService { * @returns */ - // eslint-disable-next-line camelcase async updateOrganization(updateOrgDto: IUpdateOrganization, userId: string, orgId: string): Promise { try { const organizationExist = await this.organizationRepository.checkOrganizationNameExist(updateOrgDto.name) @@ -702,9 +699,9 @@ export class OrganizationService { async authenticateClientKeycloak(clientId: string, clientSecret: string): Promise { try { const payload = new ClientCredentialTokenPayloadDto() - // eslint-disable-next-line camelcase + payload.client_id = clientId - // eslint-disable-next-line camelcase + payload.client_secret = clientSecret try { @@ -1128,7 +1125,6 @@ export class OrganizationService { } async updateClientInvitation( - // eslint-disable-next-line camelcase invitation: org_invitations, idpId: string, userId: string, @@ -1242,13 +1238,7 @@ export class OrganizationService { } } - async updateUserClientRoles( - // eslint-disable-next-line camelcase - roleIds: string[], - idpId: string, - userId: string, - orgId: string - ): Promise { + async updateUserClientRoles(roleIds: string[], idpId: string, userId: string, orgId: string): Promise { const userDetails = await this.organizationRepository.getUser(userId) const token = await this.clientRegistrationService.getManagementToken( userDetails.clientId, diff --git a/apps/user/repositories/fido-user.repository.ts b/apps/user/repositories/fido-user.repository.ts index 0c38a54e7..2daa0d124 100644 --- a/apps/user/repositories/fido-user.repository.ts +++ b/apps/user/repositories/fido-user.repository.ts @@ -51,7 +51,6 @@ export class FidoUserRepository { * @returns User exist details */ - // eslint-disable-next-line camelcase async checkFidoUserExist(email: string): Promise { try { return this.prisma.user.findFirstOrThrow({ @@ -71,7 +70,6 @@ export class FidoUserRepository { * @returns User details */ - // eslint-disable-next-line camelcase async getUserDetails(email: string): Promise { try { return this.prisma.user.findFirst({ @@ -90,7 +88,7 @@ export class FidoUserRepository { * @param tenantDetails * @returns Updates organization details */ - // eslint-disable-next-line camelcase + async updateFidoUserDetails(email: string, fidoUserId: string, username: string): Promise { try { const updateUserDetails = await this.prisma.user.update({ diff --git a/apps/user/repositories/user-device.repository.ts b/apps/user/repositories/user-device.repository.ts index d268b16b7..9bafd9221 100644 --- a/apps/user/repositories/user-device.repository.ts +++ b/apps/user/repositories/user-device.repository.ts @@ -1,7 +1,7 @@ import type { PrismaService } from '@credebl/prisma-service' import { Injectable, type Logger, NotFoundException } from '@nestjs/common' import { InternalServerErrorException } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { Prisma, user_devices } from '@prisma/client' type FidoMultiDevicePayload = { @@ -27,7 +27,6 @@ export class UserDevicesRepository { * @returns User exist details */ - // eslint-disable-next-line camelcase async checkUserDevice(userId: string): Promise { try { return this.prisma.user_devices.findFirst({ @@ -46,7 +45,7 @@ export class UserDevicesRepository { * @param createFidoMultiDevice * @returns Device details */ - // eslint-disable-next-line camelcase + async createMultiDevice(newDevice: Prisma.JsonValue, userId: string): Promise { try { const saveResponse = await this.prisma.user_devices.create({ @@ -70,7 +69,7 @@ export class UserDevicesRepository { * @param userId * @returns Device details */ - // eslint-disable-next-line camelcase + async fidoMultiDevice(userId: string): Promise { try { const userDetails = await this.prisma.user_devices.findMany({ @@ -95,7 +94,6 @@ export class UserDevicesRepository { * @param userId * @returns Get all device details */ - // eslint-disable-next-line camelcase, @typescript-eslint/no-explicit-any async getfidoMultiDevice(userId: string): Promise { try { const fidoMultiDevice = await this.prisma.user_devices.findMany({ @@ -186,7 +184,7 @@ export class UserDevicesRepository { * @param credentialId * @returns Device detail for specific credentialId */ - // eslint-disable-next-line camelcase + async checkUserDeviceByCredentialId(credentialId: string): Promise { try { return await this.prisma.user_devices.findFirst({ @@ -205,7 +203,7 @@ export class UserDevicesRepository { * @param credentialId * @returns Delete device */ - // eslint-disable-next-line camelcase + async deleteUserDeviceByCredentialId(credentialId: string): Promise { try { return await this.prisma.user_devices.updateMany({ @@ -268,7 +266,7 @@ export class UserDevicesRepository { * @param deviceFriendlyName * @returns Update device name for specific credentialId */ - // eslint-disable-next-line camelcase + async addCredentialIdAndNameById(id: string, updateFidoUserDetails: string): Promise { try { return await this.prisma.user_devices.update({ diff --git a/apps/user/repositories/user.repository.ts b/apps/user/repositories/user.repository.ts index 7f17c1e41..2ccdd56ee 100644 --- a/apps/user/repositories/user.repository.ts +++ b/apps/user/repositories/user.repository.ts @@ -3,7 +3,7 @@ import type { UserRole } from '@credebl/enum/enum' import type { PrismaService } from '@credebl/prisma-service' import { Injectable, InternalServerErrorException, type Logger, NotFoundException } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { RecordType, schema, token, user, user_org_roles } from '@prisma/client' import type { IOrgUsers, @@ -71,7 +71,6 @@ export class UserRepository { * @returns User exist details */ - // eslint-disable-next-line camelcase async checkUserExist(email: string): Promise { try { return this.prisma.user.findFirst({ @@ -180,7 +179,6 @@ export class UserRepository { orgRole: true, organisation: { include: { - // eslint-disable-next-line camelcase org_agents: true, }, }, @@ -221,7 +219,6 @@ export class UserRepository { orgRole: true, organisation: { include: { - // eslint-disable-next-line camelcase org_agents: true, }, }, @@ -360,7 +357,7 @@ export class UserRepository { * @param tenantDetails * @returns Updates organization details */ - // eslint-disable-next-line camelcase + async updateUserDetails(id: string, keycloakId: string): Promise { try { const updateUserDetails = await this.prisma.user.update({ @@ -384,7 +381,7 @@ export class UserRepository { * @param userInfo * @returns Updates user details */ - // eslint-disable-next-line camelcase + async updateUserInfo(email: string, userInfo: IUserInformation): Promise { try { const updateUserDetails = await this.prisma.user.update({ @@ -450,7 +447,7 @@ export class UserRepository { description: true, orgSlug: true, logoUrl: true, - // eslint-disable-next-line camelcase + org_agents: { select: { id: true, @@ -581,7 +578,7 @@ export class UserRepository { * @param userInfo * @returns Updates user credentials */ - // eslint-disable-next-line camelcase + async addUserPassword(email: string, userInfo: string): Promise { try { const updateUserDetails = await this.prisma.user.update({ @@ -807,7 +804,6 @@ export class UserRepository { } } - // eslint-disable-next-line camelcase async handleGetUserOrganizations(userId: string): Promise { try { const getUserOrgs = await this.prisma.user_org_roles.findMany({ diff --git a/apps/user/src/user.controller.ts b/apps/user/src/user.controller.ts index 2b497eb2b..94ad977fb 100644 --- a/apps/user/src/user.controller.ts +++ b/apps/user/src/user.controller.ts @@ -8,7 +8,7 @@ import type { } from '@credebl/common/interfaces/user.interface' import { Controller } from '@nestjs/common' import { MessagePattern } from '@nestjs/microservices' -// eslint-disable-next-line camelcase + import type { user, user_org_roles } from '@prisma/client' import type { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto' import type { IUsersActivity } from 'libs/user-activity/interface' @@ -243,7 +243,6 @@ export class UserController { } @MessagePattern({ cmd: 'get-user-organizations' }) - // eslint-disable-next-line camelcase async getuserOrganizationByUserId(payload: { userId: string }): Promise { return this.userService.getuserOrganizationByUserId(payload.userId) } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index f1be322c3..c4f06ce62 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -35,7 +35,7 @@ import type { SupabaseService } from '@credebl/supabase' import type { UserActivityService } from '@credebl/user-activity' import type { UserOrgRolesService } from '@credebl/user-org-roles' import { type ClientProxy, RpcException } from '@nestjs/microservices' -// eslint-disable-next-line camelcase + import type { RecordType, user, user_org_roles } from '@prisma/client' import type { AddPasskeyDetailsDto } from 'apps/api-gateway/src/user/dto/add-user.dto' import * as jwt from 'jsonwebtoken' @@ -697,13 +697,12 @@ export class UserService { const token = data?.session return { - // eslint-disable-next-line camelcase access_token: token.access_token, - // eslint-disable-next-line camelcase + token_type: token.token_type, - // eslint-disable-next-line camelcase + expires_in: token.expires_in, - // eslint-disable-next-line camelcase + expires_at: token.expires_at, isRegisteredToSupabase: true, } @@ -1079,7 +1078,6 @@ export class UserService { } } - // eslint-disable-next-line camelcase async updatePlatformSettings(platformSettings: PlatformSettings): Promise { try { const platformConfigSettings = await this.userRepository.updatePlatformSettings(platformSettings) @@ -1175,7 +1173,6 @@ export class UserService { } } - // eslint-disable-next-line camelcase async getuserOrganizationByUserId(userId: string): Promise { try { const getOrganizationDetails = await this.userRepository.handleGetUserOrganizations(userId) diff --git a/apps/utility/src/utilities.repository.ts b/apps/utility/src/utilities.repository.ts index 94a58d90f..26681ac84 100644 --- a/apps/utility/src/utilities.repository.ts +++ b/apps/utility/src/utilities.repository.ts @@ -1,6 +1,6 @@ import type { PrismaService } from '@credebl/prisma-service' import { Injectable, type Logger } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { shortening_url } from '@prisma/client' @Injectable() @@ -27,7 +27,6 @@ export class UtilitiesRepository { } } - // eslint-disable-next-line camelcase async getShorteningUrl(referenceId): Promise { try { const storeShorteningUrl = await this.prisma.shortening_url.findUnique({ diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index ca9bbb464..bdefac78b 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -3,7 +3,7 @@ import type { IVerificationRecords, } from '@credebl/common/interfaces/verification.interface' import { Injectable, type Logger, NotFoundException } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { agent_invitations, org_agents, organisation, platform_config, presentations } from '@prisma/client' import type { IProofPresentation, IProofRequestSearchCriteria } from '../interfaces/verification.interface' @@ -26,7 +26,7 @@ export class VerificationRepository { * @param orgId * @returns */ - // eslint-disable-next-line camelcase + async getAgentEndPoint(orgId: string): Promise { try { const agentDetails = await this.prisma.org_agents.findFirst({ @@ -70,7 +70,6 @@ export class VerificationRepository { } } - // eslint-disable-next-line camelcase async getOrganizationByTenantId(tenantId: string): Promise { try { return this.prisma.org_agents.findFirst({ @@ -226,7 +225,7 @@ export class VerificationRepository { * Get platform config details * @returns */ - // eslint-disable-next-line camelcase + async getPlatformConfigDetails(): Promise { try { return this.prisma.platform_config.findFirst() @@ -264,7 +263,6 @@ export class VerificationRepository { } } - // eslint-disable-next-line camelcase async getInvitationDidByOrgId(orgId: string): Promise { try { return this.prisma.agent_invitations.findMany({ diff --git a/libs/org-roles/repositories/index.ts b/libs/org-roles/repositories/index.ts index 08371ab61..dbbab5aa3 100644 --- a/libs/org-roles/repositories/index.ts +++ b/libs/org-roles/repositories/index.ts @@ -1,7 +1,7 @@ import { Injectable, InternalServerErrorException, type Logger } from '@nestjs/common' import type { PrismaService } from '@credebl/prisma-service' -// eslint-disable-next-line camelcase + import type { org_roles } from '@prisma/client' import { OrgRoles } from '../enums' import type { IOrgRoles } from '../interfaces/org-roles.interface' @@ -13,7 +13,6 @@ export class OrgRolesRepository { private readonly logger: Logger ) {} - // eslint-disable-next-line camelcase async getRole(roleName: string): Promise { try { const roleDetails = await this.prisma.org_roles.findFirst({ @@ -39,7 +38,6 @@ export class OrgRolesRepository { } } - // eslint-disable-next-line camelcase async getOrgRolesByIds(orgRoles: string[]): Promise { try { const roleDetails = await this.prisma.org_roles.findMany({ diff --git a/libs/org-roles/src/org-roles.service.ts b/libs/org-roles/src/org-roles.service.ts index 081e2ff57..e42be9ce7 100644 --- a/libs/org-roles/src/org-roles.service.ts +++ b/libs/org-roles/src/org-roles.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common' import type { Logger } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { org_roles } from '@prisma/client' import type { IOrgRoles } from '../interfaces/org-roles.interface' import type { OrgRolesRepository } from '../repositories' @@ -11,7 +11,6 @@ export class OrgRolesService { private readonly logger: Logger ) {} - // eslint-disable-next-line camelcase async getRole(roleName: string): Promise { return this.orgRoleRepository.getRole(roleName) } @@ -20,7 +19,6 @@ export class OrgRolesService { return this.orgRoleRepository.getOrgRoles() } - // eslint-disable-next-line camelcase async getOrgRolesByIds(orgRoleIds: string[]): Promise { return this.orgRoleRepository.getOrgRolesByIds(orgRoleIds) } diff --git a/libs/prisma-service/cli.ts b/libs/prisma-service/cli.ts index 4e6a45c4e..32d29f416 100644 --- a/libs/prisma-service/cli.ts +++ b/libs/prisma-service/cli.ts @@ -2,7 +2,6 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/no-var-requires */ -// eslint-disable-next-line camelcase const { createInterface } = require('readline') const { PrismaClient } = require('@prisma/client') @@ -28,7 +27,6 @@ const readLineAsync = (msg) => }) }) -// eslint-disable-next-line camelcase const getRole = async (roleName) => { try { const roleDetails = await prisma.org_roles.findFirst({ diff --git a/libs/user-org-roles/repositories/index.ts b/libs/user-org-roles/repositories/index.ts index 3d38e3f94..da4f2f6b2 100644 --- a/libs/user-org-roles/repositories/index.ts +++ b/libs/user-org-roles/repositories/index.ts @@ -2,7 +2,7 @@ import { Injectable, type Logger } from '@nestjs/common' import type { PrismaService } from '@credebl/prisma-service' import { InternalServerErrorException } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { user_org_roles } from '@prisma/client' import type { Prisma } from '@prisma/client' @@ -20,7 +20,7 @@ export class UserOrgRolesRepository { * @param createUserDto * @returns user details */ - // eslint-disable-next-line camelcase + async createUserOrgRole(userId: string, roleId: string, orgId?: string, idpRoleId?: string): Promise { try { const data: { @@ -57,7 +57,7 @@ export class UserOrgRolesRepository { * @param * @returns organizations details */ - // eslint-disable-next-line camelcase + async getUserOrgData(queryOptions: object): Promise { try { return this.prisma.user_org_roles.findMany({ @@ -67,7 +67,6 @@ export class UserOrgRolesRepository { include: { organisation: { include: { - // eslint-disable-next-line camelcase org_agents: true, orgInvitations: true, }, diff --git a/libs/user-org-roles/src/user-org-roles.service.ts b/libs/user-org-roles/src/user-org-roles.service.ts index 22b451bd2..57e49eed0 100644 --- a/libs/user-org-roles/src/user-org-roles.service.ts +++ b/libs/user-org-roles/src/user-org-roles.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common' -// eslint-disable-next-line camelcase + import type { user_org_roles } from '@prisma/client' import type { UserOrgRolesRepository } from '../repositories' @@ -12,7 +12,7 @@ export class UserOrgRolesService { * @param createUserDto * @returns user details */ - // eslint-disable-next-line camelcase + async createUserOrgRole(userId: string, roleId: string, orgId?: string, idpRoleId?: string): Promise { return this.userOrgRoleRepository.createUserOrgRole(userId, roleId, orgId, idpRoleId) } From 2d063a514a663b60375018dc0c65a986d318f857 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Fri, 16 May 2025 11:43:17 +0530 Subject: [PATCH 15/23] fix: biome console Signed-off-by: Krishna Waske --- biome.json | 6 +++--- libs/prisma-service/cli.ts | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/biome.json b/biome.json index a8fcececc..0a03ca737 100644 --- a/biome.json +++ b/biome.json @@ -52,9 +52,9 @@ }, "suspicious": { "noConsole": { - "level": "warn", - "fix": "none", - "options": {} + "level": "error", + "fix": "safe", + "options": { "allow": [] } } }, "complexity": { diff --git a/libs/prisma-service/cli.ts b/libs/prisma-service/cli.ts index 32d29f416..d20eecd1f 100644 --- a/libs/prisma-service/cli.ts +++ b/libs/prisma-service/cli.ts @@ -36,6 +36,7 @@ const getRole = async (roleName) => { }) return roleDetails } catch (error) { + // biome-ignore lint/suspicious/noConsole: console.error('An error occurred in getRole:', error) } } @@ -53,6 +54,7 @@ const createUserOrgRole = async (userId, roleId) => { return saveResponse } catch (error) { + // biome-ignore lint/suspicious/noConsole: console.error('An error occurred in createUserOrgRole:', error) } } @@ -88,8 +90,10 @@ const createUser = async () => { await createUserOrgRole(user.id, platformRoleData.id) + // biome-ignore lint/suspicious/noConsole: console.log('Platform admin user created') } catch (e) { + // biome-ignore lint/suspicious/noConsole: console.error('An error occurred in createUser:', e) } } @@ -98,5 +102,5 @@ async function main() { await createUser() readline.close() } - +// biome-ignore lint/suspicious/noConsole: main().catch((e) => console.error(e)) From 0764799511e2ecd7ae171b11bafbf597469f918a Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Mon, 19 May 2025 15:37:01 +0530 Subject: [PATCH 16/23] fix noForEach warn Signed-off-by: Krishna Waske --- biome.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 0a03ca737..15dbaedb4 100644 --- a/biome.json +++ b/biome.json @@ -61,7 +61,7 @@ "noBannedTypes": "error", "useLiteralKeys": "off", "noForEach": { - "level": "off" + "level": "warn" } }, "performance": { From 88c200298a05bc3bfb79a08394e0d3e8d9a712d9 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Mon, 19 May 2025 15:42:58 +0530 Subject: [PATCH 17/23] fix json include for formatting Signed-off-by: Krishna Waske --- biome.json | 5 ++--- tsconfig.build.json | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/biome.json b/biome.json index 15dbaedb4..723cb6c4a 100644 --- a/biome.json +++ b/biome.json @@ -11,7 +11,7 @@ "formatter": { "indentStyle": "space", "lineWidth": 120, - "ignore": ["**/node_modules", "**/dist", "**/.idea", "**/coverage", "**/pnpm-lock.yaml", "*.json"] + "ignore": ["**/node_modules", "**/dist", "**/.idea", "**/coverage", "**/pnpm-lock.yaml"] }, "javascript": { "parser": { @@ -80,8 +80,7 @@ "**/coverage", "**/pnpm-lock.yaml", "**/test/*", - "*.spec.ts", - "*.json" + "*.spec.ts" ] } } diff --git a/tsconfig.build.json b/tsconfig.build.json index ea4da31b2..a63f48989 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -9,7 +9,7 @@ "sourceMap": true, "outDir": "./dist", "baseUrl": "./", - "incremental": true, + "incremental": true }, "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] -} \ No newline at end of file +} From 31ed07b282a34f8505efaa1a7bef95b84f29b0ab Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Mon, 19 May 2025 15:44:48 +0530 Subject: [PATCH 18/23] fix useliteral as warn Signed-off-by: Krishna Waske --- biome.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 723cb6c4a..330242871 100644 --- a/biome.json +++ b/biome.json @@ -59,7 +59,7 @@ }, "complexity": { "noBannedTypes": "error", - "useLiteralKeys": "off", + "useLiteralKeys": "warn", "noForEach": { "level": "warn" } From 4a5ca8f59f057def2d4090f8a0694c89382f891a Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Mon, 19 May 2025 15:53:52 +0530 Subject: [PATCH 19/23] chore: minor lint Signed-off-by: Krishna Waske --- apps/verification/src/verification.service.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 8e3cd30cb..6477373ae 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -250,14 +250,16 @@ export class VerificationService { const getProofPresentationById = await this._getProofPresentationById(payload) return getProofPresentationById?.response } catch (error) { - this.logger.error(`[getProofPresentationById] - error in get proof presentation by proofId : ${JSON.stringify(error)}`); - const errorMessage = error?.response?.error?.reason || error?.message; + this.logger.error( + `[getProofPresentationById] - error in get proof presentation by proofId : ${JSON.stringify(error)}` + ) + const errorMessage = error?.response?.error?.reason || error?.message if (errorMessage?.includes('not found')) { - throw new NotFoundException(errorMessage); + throw new NotFoundException(errorMessage) } - throw new RpcException(error.response ? error.response : error); + throw new RpcException(error.response ? error.response : error) } } From 0570b85e4f1e802978f17ad5c04330ab35882245 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Tue, 20 May 2025 15:56:07 +0530 Subject: [PATCH 20/23] fix: minor changes Signed-off-by: Krishna Waske --- biome.json | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/biome.json b/biome.json index 330242871..c3d0f4279 100644 --- a/biome.json +++ b/biome.json @@ -71,16 +71,6 @@ } } }, - "ignore": [ - "**/*.eslintrc.js", - "**/*.json", - "**/node_modules", - "**/dist", - "**/.idea", - "**/coverage", - "**/pnpm-lock.yaml", - "**/test/*", - "*.spec.ts" - ] + "ignore": ["**/node_modules", "**/dist", "**/.idea", "**/coverage", "**/pnpm-lock.yaml", "**/test/*", "*.spec.ts"] } } From 8620d487400eb92ed2e02b0dbbab20df905bb964 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Wed, 21 May 2025 16:18:49 +0530 Subject: [PATCH 21/23] fix: git bot security issues Signed-off-by: Krishna Waske --- .../src/agent-provisioning.service.ts | 120 +++++++++++++----- .../src/issuance/issuance.controller.ts | 10 +- 2 files changed, 90 insertions(+), 40 deletions(-) diff --git a/apps/agent-provisioning/src/agent-provisioning.service.ts b/apps/agent-provisioning/src/agent-provisioning.service.ts index b83c01585..9bd6252da 100644 --- a/apps/agent-provisioning/src/agent-provisioning.service.ts +++ b/apps/agent-provisioning/src/agent-provisioning.service.ts @@ -1,5 +1,5 @@ import * as fs from 'fs' -import { exec } from 'node:child_process' +import { execFile } from 'node:child_process' import { AgentType } from '@credebl/enum/enum' import { Injectable, type Logger, NotFoundException } from '@nestjs/common' import { RpcException } from '@nestjs/microservices' @@ -37,49 +37,107 @@ export class AgentProvisioningService { indyLedger, inboundEndpoint, } = payload + // TODO: remove this code after testing + // 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} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${ + // process.env.SCHEMA_FILE_SERVER_URL + // } ${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((resolve) => { + // exec(walletProvision, async (_err, stdout, stderr) => { + // this.logger.log(`shell script output: ${stdout}`) + // if (stderr) { + // this.logger.log(`shell script error: ${stderr}`) + // } + + // const agentEndpointPath = `${process.cwd()}${ + // process.env.AFJ_AGENT_ENDPOINT_PATH + // }${orgId}_${containerName}.json` + // const agentTokenPath = `${process.cwd()}${process.env.AFJ_AGENT_TOKEN_PATH}${orgId}_${containerName}.json` + + // const agentEndPointExists = await this.checkFileExistence(agentEndpointPath) + // const agentTokenExists = await this.checkFileExistence(agentTokenPath) + + // let agentEndPoint: string + // let agentToken: string + + // if (agentEndPointExists && agentTokenExists) { + // this.logger.log('Both files exist') + // agentEndPoint = fs.readFileSync(agentEndpointPath, 'utf8') + // agentToken = fs.readFileSync(agentTokenPath, 'utf8') + // // Proceed with accessing the files if needed + // } else { + // this.logger.log('One or both files do not exist') + // throw new NotFoundException(`${agentEndpointPath} or ${agentTokenPath} files do not exist `) + // } + + // resolve({ + // agentEndPoint: JSON.parse(agentEndPoint).CONTROLLER_ENDPOINT, + // agentToken: JSON.parse(agentToken).token, + // }) + // }) + // }) + // return spinUpResponse + // } 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} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${ - process.env.SCHEMA_FILE_SERVER_URL - } ${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((resolve) => { - exec(walletProvision, async (_err, stdout, stderr) => { + const scriptPath = process.cwd() + process.env.AFJ_AGENT_SPIN_UP + + const args: string[] = [ + orgId, + externalIp, + walletName, + walletPassword, + seed, + webhookEndpoint, + walletStorageHost, + walletStoragePort, + walletStorageUser, + walletStoragePassword, + containerName, + protocol, + tenant, + credoImage, + indyLedger, + inboundEndpoint, + process.env.SCHEMA_FILE_SERVER_URL, + process.env.AGENT_HOST, + process.env.AWS_ACCOUNT_ID, + process.env.S3_BUCKET_ARN, + process.env.CLUSTER_NAME, + process.env.TESKDEFINITION_FAMILY, + ].map(String) + + const spinUpResponse: Promise = new Promise((resolve, reject) => { + execFile(scriptPath, args, async (_err, stdout, stderr) => { this.logger.log(`shell script output: ${stdout}`) if (stderr) { this.logger.log(`shell script error: ${stderr}`) } - const agentEndpointPath = `${process.cwd()}${ - process.env.AFJ_AGENT_ENDPOINT_PATH - }${orgId}_${containerName}.json` - const agentTokenPath = `${process.cwd()}${process.env.AFJ_AGENT_TOKEN_PATH}${orgId}_${containerName}.json` - - const agentEndPointExists = await this.checkFileExistence(agentEndpointPath) - const agentTokenExists = await this.checkFileExistence(agentTokenPath) - - let agentEndPoint: string - let agentToken: string - - if (agentEndPointExists && agentTokenExists) { - this.logger.log('Both files exist') - agentEndPoint = fs.readFileSync(agentEndpointPath, 'utf8') - agentToken = fs.readFileSync(agentTokenPath, 'utf8') - // Proceed with accessing the files if needed - } else { - this.logger.log('One or both files do not exist') - throw new NotFoundException(`${agentEndpointPath} or ${agentTokenPath} files do not exist `) + const endpointFile = `${process.cwd()}${process.env.AFJ_AGENT_ENDPOINT_PATH}${orgId}_${containerName}.json` + const tokenFile = `${process.cwd()}${process.env.AFJ_AGENT_TOKEN_PATH}${orgId}_${containerName}.json` + + const endpointExists = await this.checkFileExistence(endpointFile) + const tokenExists = await this.checkFileExistence(tokenFile) + + if (!endpointExists || !tokenExists) { + return reject(new NotFoundException(`${endpointFile} or ${tokenFile} files do not exist`)) } - resolve({ + const agentEndPoint = fs.readFileSync(endpointFile, 'utf8') + const agentToken = fs.readFileSync(tokenFile, 'utf8') + + return resolve({ agentEndPoint: JSON.parse(agentEndPoint).CONTROLLER_ENDPOINT, agentToken: JSON.parse(agentToken).token, }) }) }) + return spinUpResponse } if (agentType === AgentType.ACAPY) { diff --git a/apps/api-gateway/src/issuance/issuance.controller.ts b/apps/api-gateway/src/issuance/issuance.controller.ts index f0375a317..15314c06b 100644 --- a/apps/api-gateway/src/issuance/issuance.controller.ts +++ b/apps/api-gateway/src/issuance/issuance.controller.ts @@ -5,10 +5,6 @@ import type { IResponse } from '@credebl/common/interfaces/response.interface' import { ResponseMessages } from '@credebl/common/response-messages' import { SchemaType } from '@credebl/enum/enum' import type { IUserRequest } from '@credebl/user-request/user-request.interface' -/* eslint-disable default-param-last */ -/* eslint-disable no-param-reassign */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable camelcase */ import { BadRequestException, Body, @@ -292,11 +288,7 @@ export class IssuanceController { .status(HttpStatus.OK) .send(templateData.fileContent) } catch (error) { - return res - .status(error.statusCode || HttpStatus.INTERNAL_SERVER_ERROR) - .header('Content-Type', 'application/json') - .header('Content-Disposition', '') - .send(error) + throw new RpcException(error.response ? error.response : error) } } /** From d6bee2a4f3cd0abcd766602a93beb435b9707d65 Mon Sep 17 00:00:00 2001 From: Tipu_Singh Date: Tue, 27 May 2025 10:23:16 +0530 Subject: [PATCH 22/23] fix: sonar cloud issue Signed-off-by: Tipu_Singh --- .../dtos/update-revocation-registry.dto.ts | 2 +- .../src/client-registration.service.ts | 116 +++++++++--------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts b/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts index a172ad811..ecd384b29 100644 --- a/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts +++ b/apps/api-gateway/src/dtos/update-revocation-registry.dto.ts @@ -6,7 +6,7 @@ export class UpdateRevocationRegistryUriDto { revoc_reg_id?: string @ApiProperty({ example: - 'http://192.168.56.133:5000/revocation/registry/WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0/tails-file', + 'https://192.168.56.133:5000/revocation/registry/WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0/tails-file', }) // tslint:disable-next-line: variable-name path?: string diff --git a/libs/client-registration/src/client-registration.service.ts b/libs/client-registration/src/client-registration.service.ts index 74ea334e7..cf29394f2 100644 --- a/libs/client-registration/src/client-registration.service.ts +++ b/libs/client-registration/src/client-registration.service.ts @@ -512,64 +512,64 @@ export class ClientRegistrationService { return tokenResponse } - - async CreateConnection(clientId: string, token: string) { - const payload = { - name: 'TestConnection1', - display_name: 'Connectiondisplay', - strategy: 'auth0', - options: { - enabledDatabaseCustomization: true, - import_mode: false, - customScripts: { - login: - "function login(email, password, callback) {\n //this example uses the \"pg\" library\n //more info here: https://github.com/brianc/node-postgres\n\n const bcrypt = require('bcrypt');\n const postgres = require('pg');\n\n const conString = `postgres://${configuration.pg_user}:${configuration.pg_pass}@${configuration.pg_ip}/${configuration.pg_db}`;\n postgres.connect(conString, function (err, client, done) {\n if (err) return callback(err);\n\t\t\t\n const query = 'SELECT id, email, password FROM public.user WHERE email = $1 or username = $1';\n client.query(query, [email], function (err, result) {\n // NOTE: always call done() here to close\n // the connection to the database\n done();\n\n if (err || result.rows.length === 0) return callback(err || new WrongUsernameOrPasswordError(email));\n\n const user = result.rows[0];\n\n //if(password === user.password) {\n this.logger.log(email);\n if (password === user.password) return callback(err || new WrongUsernameOrPasswordError(email));\n\n return callback(null, {\n user_id: user.id,\n email: user.email\n });\n });\n \n });\n //});\n}", - create: - 'function create(user, callback) {\n // This script should create a user entry in your existing database. It will\n // be executed when a user attempts to sign up, or when a user is created\n // through the Auth0 dashboard or API.\n // When this script has finished executing, the Login script will be\n // executed immediately afterwards, to verify that the user was created\n // successfully.\n //\n // The user object will always contain the following properties:\n // * email: the user\'s email\n // * password: the password entered by the user, in plain text\n // * tenant: the name of this Auth0 account\n // * client_id: the client ID of the application where the user signed up, or\n // API key if created through the API or Auth0 dashboard\n // * connection: the name of this database connection\n //\n // There are three ways this script can finish:\n // 1. A user was successfully created\n // callback(null);\n // 2. This user already exists in your database\n // callback(new ValidationError("user_exists", "my error message"));\n // 3. Something went wrong while trying to reach your database\n // callback(new Error("my error message"));\n\n const msg = \'Please implement the Create script for this database connection \' +\n \'at https://manage.auth0.com/#/connections/database\';\n return callback(new Error(msg));\n}\n', - delete: - "function remove(id, callback) {\n // This script remove a user from your existing database.\n // It is executed whenever a user is deleted from the API or Auth0 dashboard.\n //\n // There are two ways that this script can finish:\n // 1. The user was removed successfully:\n // callback(null);\n // 2. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n\n const msg = 'Please implement the Delete script for this database ' +\n 'connection at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", - verify: - "function verify(email, callback) {\n // This script should mark the current user's email address as verified in\n // your database.\n // It is executed whenever a user clicks the verification link sent by email.\n // These emails can be customized at https://manage.auth0.com/#/emails.\n // It is safe to assume that the user's email already exists in your database,\n // because verification emails, if enabled, are sent immediately after a\n // successful signup.\n //\n // There are two ways that this script can finish:\n // 1. The user's email was verified successfully\n // callback(null, true);\n // 2. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n //\n // If an error is returned, it will be passed to the query string of the page\n // where the user is being redirected to after clicking the verification link.\n // For example, returning `callback(new Error(\"error\"))` and redirecting to\n // https://example.com would redirect to the following URL:\n // https://example.com?email=alice%40example.com&message=error&success=false\n\n const msg = 'Please implement the Verify script for this database connection ' +\n 'at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", - get_user: - "function getByEmail(email, callback) {\n // This script should retrieve a user profile from your existing database,\n // without authenticating the user.\n // It is used to check if a user exists before executing flows that do not\n // require authentication (signup and password reset).\n //\n // There are three ways this script can finish:\n // 1. A user was successfully found. The profile should be in the following\n // format: https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.\n // callback(null, profile);\n // 2. A user was not found\n // callback(null);\n // 3. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n\n const msg = 'Please implement the Get User script for this database connection ' +\n 'at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", - change_password: - "function changePassword(email, newPassword, callback) {\n // This script should change the password stored for the current user in your\n // database. It is executed when the user clicks on the confirmation link\n // after a reset password request.\n // The content and behavior of password confirmation emails can be customized\n // here: https://manage.auth0.com/#/emails\n // The `newPassword` parameter of this function is in plain text. It must be\n // hashed/salted to match whatever is stored in your database.\n //\n // There are three ways that this script can finish:\n // 1. The user's password was updated successfully:\n // callback(null, true);\n // 2. The user's password was not updated:\n // callback(null, false);\n // 3. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n //\n // If an error is returned, it will be passed to the query string of the page\n // where the user is being redirected to after clicking the confirmation link.\n // For example, returning `callback(new Error(\"error\"))` and redirecting to\n // https://example.com would redirect to the following URL:\n // https://example.com?email=alice%40example.com&message=error&success=false\n\n const msg = 'Please implement the Change Password script for this database ' +\n 'connection at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", - }, - passwordPolicy: 'good', - password_complexity_options: { - min_length: 8, - }, - password_history: { - size: 5, - enable: false, - }, - password_no_personal_info: { - enable: false, - }, - password_dictionary: { - enable: false, - dictionary: [], - }, - - gateway_authentication: 'object', - }, - enabled_clients: [clientId], - realms: [''], - metadata: {}, - } - - const clientConnResponse = await this.commonService.httpPost( - `${process.env.KEYCLOAK_DOMAIN}${CommonConstants.URL_KEYCLOAK_MANAGEMENT_CONNECTIONS}`, - payload, - this.getAuthHeader(token) - ) - this.logger.debug(`ClientRegistrationService create connection app ${JSON.stringify(clientConnResponse)}`) - - return { - name: clientConnResponse.data.name, - id: clientConnResponse.data.id, - } - } + //TODO: This is an old code which is not used anymore, need to remove it after testing + // async CreateConnection(clientId: string, token: string) { + // const payload = { + // name: 'TestConnection1', + // display_name: 'Connectiondisplay', + // strategy: 'auth0', + // options: { + // enabledDatabaseCustomization: true, + // import_mode: false, + // customScripts: { + // login: + // "function login(email, password, callback) {\n //this example uses the \"pg\" library\n //more info here: https://github.com/brianc/node-postgres\n\n const bcrypt = require('bcrypt');\n const postgres = require('pg');\n\n const conString = `postgres://${configuration.pg_user}:${configuration.pg_pass}@${configuration.pg_ip}/${configuration.pg_db}`;\n postgres.connect(conString, function (err, client, done) {\n if (err) return callback(err);\n\t\t\t\n const query = 'SELECT id, email, password FROM public.user WHERE email = $1 or username = $1';\n client.query(query, [email], function (err, result) {\n // NOTE: always call done() here to close\n // the connection to the database\n done();\n\n if (err || result.rows.length === 0) return callback(err || new WrongUsernameOrPasswordError(email));\n\n const user = result.rows[0];\n\n //if(password === user.password) {\n this.logger.log(email);\n if (password === user.password) return callback(err || new WrongUsernameOrPasswordError(email));\n\n return callback(null, {\n user_id: user.id,\n email: user.email\n });\n });\n \n });\n //});\n}", + // create: + // 'function create(user, callback) {\n // This script should create a user entry in your existing database. It will\n // be executed when a user attempts to sign up, or when a user is created\n // through the Auth0 dashboard or API.\n // When this script has finished executing, the Login script will be\n // executed immediately afterwards, to verify that the user was created\n // successfully.\n //\n // The user object will always contain the following properties:\n // * email: the user\'s email\n // * password: the password entered by the user, in plain text\n // * tenant: the name of this Auth0 account\n // * client_id: the client ID of the application where the user signed up, or\n // API key if created through the API or Auth0 dashboard\n // * connection: the name of this database connection\n //\n // There are three ways this script can finish:\n // 1. A user was successfully created\n // callback(null);\n // 2. This user already exists in your database\n // callback(new ValidationError("user_exists", "my error message"));\n // 3. Something went wrong while trying to reach your database\n // callback(new Error("my error message"));\n\n const msg = \'Please implement the Create script for this database connection \' +\n \'at https://manage.auth0.com/#/connections/database\';\n return callback(new Error(msg));\n}\n', + // delete: + // "function remove(id, callback) {\n // This script remove a user from your existing database.\n // It is executed whenever a user is deleted from the API or Auth0 dashboard.\n //\n // There are two ways that this script can finish:\n // 1. The user was removed successfully:\n // callback(null);\n // 2. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n\n const msg = 'Please implement the Delete script for this database ' +\n 'connection at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", + // verify: + // "function verify(email, callback) {\n // This script should mark the current user's email address as verified in\n // your database.\n // It is executed whenever a user clicks the verification link sent by email.\n // These emails can be customized at https://manage.auth0.com/#/emails.\n // It is safe to assume that the user's email already exists in your database,\n // because verification emails, if enabled, are sent immediately after a\n // successful signup.\n //\n // There are two ways that this script can finish:\n // 1. The user's email was verified successfully\n // callback(null, true);\n // 2. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n //\n // If an error is returned, it will be passed to the query string of the page\n // where the user is being redirected to after clicking the verification link.\n // For example, returning `callback(new Error(\"error\"))` and redirecting to\n // https://example.com would redirect to the following URL:\n // https://example.com?email=alice%40example.com&message=error&success=false\n\n const msg = 'Please implement the Verify script for this database connection ' +\n 'at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", + // get_user: + // "function getByEmail(email, callback) {\n // This script should retrieve a user profile from your existing database,\n // without authenticating the user.\n // It is used to check if a user exists before executing flows that do not\n // require authentication (signup and password reset).\n //\n // There are three ways this script can finish:\n // 1. A user was successfully found. The profile should be in the following\n // format: https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.\n // callback(null, profile);\n // 2. A user was not found\n // callback(null);\n // 3. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n\n const msg = 'Please implement the Get User script for this database connection ' +\n 'at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", + // change_password: + // "function changePassword(email, newPassword, callback) {\n // This script should change the password stored for the current user in your\n // database. It is executed when the user clicks on the confirmation link\n // after a reset password request.\n // The content and behavior of password confirmation emails can be customized\n // here: https://manage.auth0.com/#/emails\n // The `newPassword` parameter of this function is in plain text. It must be\n // hashed/salted to match whatever is stored in your database.\n //\n // There are three ways that this script can finish:\n // 1. The user's password was updated successfully:\n // callback(null, true);\n // 2. The user's password was not updated:\n // callback(null, false);\n // 3. Something went wrong while trying to reach your database:\n // callback(new Error(\"my error message\"));\n //\n // If an error is returned, it will be passed to the query string of the page\n // where the user is being redirected to after clicking the confirmation link.\n // For example, returning `callback(new Error(\"error\"))` and redirecting to\n // https://example.com would redirect to the following URL:\n // https://example.com?email=alice%40example.com&message=error&success=false\n\n const msg = 'Please implement the Change Password script for this database ' +\n 'connection at https://manage.auth0.com/#/connections/database';\n return callback(new Error(msg));\n}\n", + // }, + // passwordPolicy: 'good', + // password_complexity_options: { + // min_length: 8, + // }, + // password_history: { + // size: 5, + // enable: false, + // }, + // password_no_personal_info: { + // enable: false, + // }, + // password_dictionary: { + // enable: false, + // dictionary: [], + // }, + + // gateway_authentication: 'object', + // }, + // enabled_clients: [clientId], + // realms: [''], + // metadata: {}, + // } + + // const clientConnResponse = await this.commonService.httpPost( + // `${process.env.KEYCLOAK_DOMAIN}${CommonConstants.URL_KEYCLOAK_MANAGEMENT_CONNECTIONS}`, + // payload, + // this.getAuthHeader(token) + // ) + // this.logger.debug(`ClientRegistrationService create connection app ${JSON.stringify(clientConnResponse)}`) + + // return { + // name: clientConnResponse.data.name, + // id: clientConnResponse.data.id, + // } + // } async getUserToken(email: string, password: string, clientId: string, clientSecret: string) { const payload = new userTokenPayloadDto() From ec2459d705994b4bdea38baf823b8512adee7a9e Mon Sep 17 00:00:00 2001 From: RinkalBhojani Date: Mon, 2 Jun 2025 15:15:32 +0530 Subject: [PATCH 23/23] fix: fixed sonar issues --- .../src/agent-service.service.ts | 63 ++++++------ .../agent-service/dto/agent-service.dto.ts | 6 -- .../agent-service/dto/create-tenant.dto.ts | 6 -- .../api-gateway/src/agent/agent.controller.ts | 2 +- apps/api-gateway/src/agent/agent.service.ts | 4 +- .../api-gateway/src/authz/authz.middleware.ts | 99 ++++++++++--------- .../src/issuance/dtos/multi-connection.dto.ts | 13 +-- apps/issuance/src/issuance.service.ts | 10 +- apps/ledger/src/schema/schema.service.ts | 37 ++++--- apps/organization/src/organization.service.ts | 10 +- apps/user/src/fido/fido.service.ts | 3 +- apps/user/src/user.service.ts | 4 +- .../src/prisma-service.service.ts | 4 +- 13 files changed, 118 insertions(+), 143 deletions(-) diff --git a/apps/agent-service/src/agent-service.service.ts b/apps/agent-service/src/agent-service.service.ts index fec343728..effd93ce9 100644 --- a/apps/agent-service/src/agent-service.service.ts +++ b/apps/agent-service/src/agent-service.service.ts @@ -28,8 +28,6 @@ import type { InvitationMessage } from '@credebl/common/interfaces/agent-service import { ResponseMessages } from '@credebl/common/response-messages' import { AgentSpinUpStatus, AgentType, DidMethod, Ledgers, OrgAgentType, PromiseResult } from '@credebl/enum/enum' import type { PrismaService } from '@credebl/prisma-service' -import { CACHE_MANAGER } from '@nestjs/cache-manager' -import { WebSocketGateway } from '@nestjs/websockets' import { RecordType, type ledgers, @@ -41,10 +39,9 @@ import { import type { ConnectionService } from 'apps/connection/src/connection.service' import type { GetSchemaAgentRedirection } from 'apps/ledger/src/schema/schema.interface' import * as retry from 'async-retry' -import type { Cache } from 'cache-manager' import * as CryptoJS from 'crypto-js' import type { UserActivityRepository } from 'libs/user-activity/repositories' -import { from } from 'rxjs' +import { firstValueFrom, from } from 'rxjs' import { type Socket, io } from 'socket.io-client' import { type AgentHealthData, @@ -93,7 +90,6 @@ export class AgentServiceService { private readonly commonService: CommonService, private readonly connectionService: ConnectionService, @Inject('NATS_CLIENT') private readonly agentServiceProxy: ClientProxy, - @Inject(CACHE_MANAGER) private cacheService: Cache, private readonly userActivityRepository: UserActivityRepository, private readonly natsClient: NATSClient ) {} @@ -494,7 +490,7 @@ export class AgentServiceService { try { if (agentSpinupDto.method !== DidMethod.KEY && agentSpinupDto.method !== DidMethod.WEB) { const { network } = agentSpinupDto - const ledger = await ledgerName(network) + const ledger = ledgerName(network) const ledgerList = (await this._getALlLedgerDetails()) as unknown as LedgerListResponse const isLedgerExist = ledgerList.response.find((existingLedgers) => existingLedgers.name === ledger) if (!isLedgerExist) { @@ -614,7 +610,7 @@ export class AgentServiceService { /** * Organization storage data */ - const storeOrgAgentData = await this._buildStoreOrgAgentData(payload, getDidMethod, `${orgAgentTypeId}`) + const storeOrgAgentData = this._buildStoreOrgAgentData(payload, getDidMethod, `${orgAgentTypeId}`) /** * Store org agent details */ @@ -678,7 +674,7 @@ export class AgentServiceService { private async _handleError(payload: IStoreOrgAgentDetails, error: Error): Promise { if (payload.clientSocketId) { - const socket = await io(`${process.env.SOCKET_HOST}`, { + const socket = io(`${process.env.SOCKET_HOST}`, { reconnection: true, reconnectionDelay: 5000, reconnectionAttempts: Number.POSITIVE_INFINITY, @@ -810,7 +806,7 @@ export class AgentServiceService { return agentStatusResponse } catch (error) { this.logger.error(`error in create tenant : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -827,7 +823,7 @@ export class AgentServiceService { let ledger: string | string[] const { network } = payload if (network) { - ledger = await ledgerName(network) + ledger = ledgerName(network) } else { ledger = Ledgers.Not_Applicable } @@ -950,7 +946,7 @@ export class AgentServiceService { return tenantDetails } catch (error) { this.logger.error(`error in create wallet : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -985,7 +981,7 @@ export class AgentServiceService { const didDetails = await this.getDidDetails(url, payload, getApiKey) const getDidByOrg = await this.agentServiceRepository.getOrgDid(orgId) - await this.checkDidExistence(getDidByOrg, didDetails) + this.checkDidExistence(getDidByOrg, didDetails) if (isPrimaryDid) { await this.updateAllDidsToNonPrimary(orgId, getDidByOrg) @@ -1017,7 +1013,7 @@ export class AgentServiceService { error: error?.response?.error?.message, }) } - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1115,7 +1111,7 @@ export class AgentServiceService { return createKeyPairResponse } catch (error) { this.logger.error(`error in createSecp256k1KeyPair : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1295,7 +1291,7 @@ export class AgentServiceService { return schemaResponse } catch (error) { this.logger.error(`Error in creating schema: ${error}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1455,7 +1451,7 @@ export class AgentServiceService { return getProofPresentationById } catch (error) { this.logger.error(`Error in proof presentation by id in agent service : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1499,7 +1495,7 @@ export class AgentServiceService { return verifyPresentation } catch (error) { this.logger.error(`Error in verify proof presentation in agent service : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1522,7 +1518,7 @@ export class AgentServiceService { return getConnectionsByconnectionId } catch (error) { this.logger.error(`Error in getConnectionsByconnectionId in agent service : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1564,7 +1560,7 @@ export class AgentServiceService { return agentHealthData } catch (error) { this.logger.error(`Agent health details : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1601,7 +1597,7 @@ export class AgentServiceService { return getVerifiedProofDetails } catch (error) { this.logger.error(`Error in get verified proof details in agent service : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1757,7 +1753,7 @@ export class AgentServiceService { }) } catch (error) { this.logger.error(`Error in delete wallet in agent service: ${JSON.stringify(error.message)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1769,19 +1765,16 @@ export class AgentServiceService { const payload = { did, } - const updatedSchemaInfo = await this.agentServiceProxy - .send(pattern, payload) - .toPromise() - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`) - throw new HttpException( - { - status: error.status, - error: error.message, - }, - error.status - ) - }) + const updatedSchemaInfo = firstValueFrom(this.agentServiceProxy.send(pattern, payload)).catch((error) => { + this.logger.error(`catch: ${JSON.stringify(error)}`) + throw new HttpException( + { + status: error.status, + error: error.message, + }, + error.status + ) + }) return updatedSchemaInfo } @@ -1882,7 +1875,7 @@ export class AgentServiceService { return getQuestionAnswersRecord } catch (error) { this.logger.error(`Error in getQuestionAnswersRecord in agent service : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } 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 d1bdf6f28..29d84c3ea 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 @@ -23,12 +23,6 @@ export class AgentSpinupDto extends CreateDidDto { @IsNotEmpty({ message: 'Password is required.' }) walletPassword?: string - @ApiPropertyOptional({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) - @IsOptional() - @Transform(({ value }) => trim(value)) - @IsString({ message: 'did must be in string format.' }) - did?: string - @ApiPropertyOptional({ example: 'ojIckSD2jqNzOqIrAGzL' }) @IsOptional() clientSocketId?: string 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 bb0c2c64a..a488abec4 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 @@ -17,11 +17,5 @@ export class CreateTenantDto extends CreateDidDto { @IsString({ message: 'did must be in string format.' }) clientSocketId?: string - @ApiProperty({ example: 'XzFjo1RTZ2h9UVFCnPUyaQ' }) - @IsOptional() - @ApiPropertyOptional() - @IsString({ message: 'did must be in string format.' }) - did?: string - orgId: string } diff --git a/apps/api-gateway/src/agent/agent.controller.ts b/apps/api-gateway/src/agent/agent.controller.ts index 1bb413a8f..19b0526c8 100644 --- a/apps/api-gateway/src/agent/agent.controller.ts +++ b/apps/api-gateway/src/agent/agent.controller.ts @@ -111,7 +111,7 @@ export class AgentController { @ApiResponse({ status: HttpStatus.CREATED, description: 'Success', type: ApiResponseDto }) @ApiUnauthorizedResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden', type: ForbiddenErrorDto }) - walletProvision(@Body() walletUserDetails: WalletDetailsDto, @User() user: object): Promise { + walletProvision(@Body() walletUserDetails: WalletDetailsDto, @User() user: IUserRequestInterface): Promise { this.logger.log(`**** Spin up the agent...${JSON.stringify(walletUserDetails)}`) const regex = /^[a-zA-Z0-9]+$/ diff --git a/apps/api-gateway/src/agent/agent.service.ts b/apps/api-gateway/src/agent/agent.service.ts index f5680dad0..3b8da9ead 100644 --- a/apps/api-gateway/src/agent/agent.service.ts +++ b/apps/api-gateway/src/agent/agent.service.ts @@ -41,7 +41,7 @@ export class AgentService extends BaseService { return this.natsClient.sendNats(this.agentServiceProxy, 'create-local-did', user) } - async walletProvision(walletUserDetails: WalletDetailsDto, user: user) { + async walletProvision(walletUserDetails: WalletDetailsDto, user: IUserRequestInterface) { this.logger.log(`**** walletProvision called...${JSON.stringify(walletUserDetails)}`) const payload = { walletUserDetails, user } return await this.natsClient.sendNats(this.agentServiceProxy, 'wallet-provision', payload) @@ -59,7 +59,7 @@ export class AgentService extends BaseService { * Description: Calling agent service for assign-public-did * @param did */ - assignPublicDid(id: number, user: user) { + assignPublicDid(id: number, user: IUserRequestInterface) { this.logger.log('**** assignPublicDid called...') const payload = { id, user } return this.natsClient.sendNats(this.agentServiceProxy, 'assign-public-did-org', payload) diff --git a/apps/api-gateway/src/authz/authz.middleware.ts b/apps/api-gateway/src/authz/authz.middleware.ts index c933827df..6037d6201 100644 --- a/apps/api-gateway/src/authz/authz.middleware.ts +++ b/apps/api-gateway/src/authz/authz.middleware.ts @@ -54,63 +54,66 @@ export class AuthzMiddleware implements NestMiddleware { } const requestor = new RequestingUser() - const tenant = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response + if (!tenant) { + req['requestor'] = requestor + return next() + } - if (tenant) { - this.logger.log(`tenant this.authService.getUserByKeycloakUserId: ${tenant.keycloakUserId}`) - this.logger.log(`tenant id: ${tenant.id}`) - - requestor.tenant_name = `${tenant.firstName} ${tenant.lastName}` - requestor.tenant_id = tenant.id - requestor.userRoleOrgPermissions = tenant.userRoleOrgMap - requestor.orgId = tenant.userRoleOrgMap[0].organization.id - requestor.apiKey = tenant.userRoleOrgMap[0].organization.apiKey - requestor.agentEndPoint = tenant.userRoleOrgMap[0].organization.agentEndPoint - - let tenantOrgInfo: { id: string } - - for (const item of tenant.userRoleOrgMap) { - this.logger.log(`${JSON.stringify(item.organization.orgRole)}`) - - if (item.organization.orgRole.id === CommonConstants.ORG_TENANT_ROLE) { - this.logger.log(`In Tenant Org matched id : ${item.organization.id}`) - tenantOrgInfo = item.organization - } - } - - if (tenantOrgInfo != null) { - requestor.tenantOrgId = tenantOrgInfo.id - } - - // biome-ignore lint/suspicious/noPrototypeBuiltins: - if (payload.hasOwnProperty('clientId')) { - this.logger.log(`tenant requestor.permissions: ${JSON.stringify(requestor)}`) - } else { - requestor.email = payload['email'] - - const userData = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response - - this.logger.debug(`User by keycloak ID ${userData.id}`) - - requestor.userId = userData?.id - requestor.name = `${userData.firstName} ${userData.lastName}` - - if (userData?.organization != null) { - this.logger.log(`Org Not Null: ${userData?.organization.Id} `) - requestor.orgId = userData?.organization.id - } - - this.logger.log(` user id ${userData.id}`) - } + this.populateRequestorFromTenant(tenant, requestor) + // biome-ignore lint: Not able to replace 'using Object.hasOwn() instead of using Object.hasOwnProperty()' + if (!payload.hasOwnProperty('clientId')) { + await this.populateRequestorFromUser(payload, requestor) + } else { + this.logger.log(`tenant requestor.permissions: ${JSON.stringify(requestor)}`) } req['requestor'] = requestor - next() } catch (error) { this.logger.error(`RequestorMiddleware Error in middleware: ${error} ${JSON.stringify(error)}`) next(new HttpException(error, 500)) } } + + // biome-ignore lint: This is temporary fix need to define type for 'tenant' + private populateRequestorFromTenant(tenant: any, requestor: RequestingUser): void { + this.logger.log(`tenant this.authService.getUserByKeycloakUserId: ${tenant.keycloakUserId}`) + this.logger.log(`tenant id: ${tenant.id}`) + + requestor.tenant_name = `${tenant.firstName} ${tenant.lastName}` + requestor.tenant_id = tenant.id + requestor.userRoleOrgPermissions = tenant.userRoleOrgMap + requestor.orgId = tenant.userRoleOrgMap[0].organization.id + requestor.apiKey = tenant.userRoleOrgMap[0].organization.apiKey + requestor.agentEndPoint = tenant.userRoleOrgMap[0].organization.agentEndPoint + + const tenantOrg = tenant.userRoleOrgMap.find( + (item) => item.organization.orgRole.id === CommonConstants.ORG_TENANT_ROLE + )?.organization + + if (tenantOrg) { + this.logger.log(`In Tenant Org matched id : ${tenantOrg.id}`) + requestor.tenantOrgId = tenantOrg.id + } + } + + // biome-ignore lint: This is temporary fix need to define type for 'payload' + private async populateRequestorFromUser(payload: any, requestor: RequestingUser): Promise { + requestor.email = payload['email'] + const userData = (await this.authService.getUserByKeycloakUserId(payload['sub']))?.response + + if (!userData) return + + this.logger.debug(`User by keycloak ID ${userData.id}`) + requestor.userId = userData.id + requestor.name = `${userData.firstName} ${userData.lastName}` + + if (userData.organization != null) { + this.logger.log(`Org Not Null: ${userData.organization.id}`) + requestor.orgId = userData.organization.id + } + + this.logger.log(` user id ${userData.id}`) + } } diff --git a/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts b/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts index b7e965fae..ef9357ee0 100644 --- a/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts +++ b/apps/api-gateway/src/issuance/dtos/multi-connection.dto.ts @@ -1,13 +1,11 @@ import { trim } from '@credebl/common/cast.helper' -import { AutoAccept } from '@credebl/enum/enum' -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { ApiProperty } from '@nestjs/swagger' import { Transform, Type } from 'class-transformer' import { ArrayMaxSize, ArrayMinSize, IsArray, IsBoolean, - IsEnum, IsNotEmpty, IsObject, IsOptional, @@ -99,15 +97,6 @@ export class IssueCredentialDto extends CredentialsIssuanceDto { @Type(() => ConnectionAttributes) credentialData: ConnectionAttributes[] - @ApiPropertyOptional() - @IsOptional() - @IsString({ message: 'auto accept proof must be in string' }) - @IsNotEmpty({ message: 'please provide valid auto accept proof' }) - @IsEnum(AutoAccept, { - message: `Invalid auto accept credential. It should be one of: ${Object.values(AutoAccept).join(', ')}`, - }) - autoAcceptCredential?: string - @ApiProperty({ example: false, }) diff --git a/apps/issuance/src/issuance.service.ts b/apps/issuance/src/issuance.service.ts index e97680e93..937e80607 100644 --- a/apps/issuance/src/issuance.service.ts +++ b/apps/issuance/src/issuance.service.ts @@ -129,7 +129,7 @@ export class IssuanceService { this.logger.error( `[getIssuanceRecords ] [NATS call]- error in get issuance records count : ${JSON.stringify(error)}` ) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -197,7 +197,7 @@ export class IssuanceService { const url = await this.getAgentUrl(issuanceMethodLabel, orgAgentType, agentEndPoint, agentDetails?.tenantId) if (payload.credentialType === IssueCredentialType.JSONLD) { - await validateAndUpdateIssuanceDates(credentialData) + validateAndUpdateIssuanceDates(credentialData) } const issuancePromises = credentialData.map(async (credentials) => { @@ -779,7 +779,7 @@ export class IssuanceService { const agentDetails = await this.issuanceRepository.getAgentEndPoint(orgId) if (IssueCredentialType.JSONLD === credentialType) { - await validateAndUpdateIssuanceDates(credentialOffer) + validateAndUpdateIssuanceDates(credentialOffer) const schemaIds = credentialOffer?.map((item) => { const context: string[] = item?.credential?.['@context'] @@ -1783,7 +1783,7 @@ export class IssuanceService { return ResponseMessages.bulkIssuance.success.reinitiated } catch (error) { - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1863,7 +1863,7 @@ export class IssuanceService { width: jobDetails?.width, } - oobIssuancepayload = await createOobJsonldIssuancePayload(JsonldCredentialDetails, prettyVc) + oobIssuancepayload = createOobJsonldIssuancePayload(JsonldCredentialDetails, prettyVc) oobIssuancepayload.isValidateSchema = jobDetails?.isValidateSchema } diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index c505366d9..995b6b591 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -35,7 +35,7 @@ import type { Prisma, schema } from '@prisma/client' import { w3cSchemaBuilder } from 'apps/ledger/libs/helpers/w3c.schema.builder' import type { Cache } from 'cache-manager' import { BaseService } from 'libs/service/base.service' -import { from } from 'rxjs' +import { firstValueFrom, from } from 'rxjs' import { map } from 'rxjs/operators' import { v4 as uuidv4 } from 'uuid' import { W3CSchemaVersion } from './enum/schema.enum' @@ -269,7 +269,7 @@ export class SchemaService extends BaseService { } catch (error) { this.logger.error(`[createSchema] - outer Error: ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -293,7 +293,7 @@ export class SchemaService extends BaseService { } const { agentEndPoint } = agentDetails - const ledgerAndNetworkDetails = await checkDidLedgerAndNetwork(schemaPayload.schemaType, agentDetails.orgDid) + const ledgerAndNetworkDetails = checkDidLedgerAndNetwork(schemaPayload.schemaType, agentDetails.orgDid) if (!ledgerAndNetworkDetails) { throw new BadRequestException(ResponseMessages.schema.error.orgDidAndSchemaType, { cause: new Error(), @@ -311,7 +311,7 @@ export class SchemaService extends BaseService { url = `${agentEndPoint}${CommonConstants.SHARED_CREATE_POLYGON_W3C_SCHEMA}${tenantId}` } - const schemaObject = await w3cSchemaBuilder(attributes, schemaName, description) + const schemaObject = w3cSchemaBuilder(attributes, schemaName, description) if (!schemaObject) { throw new BadRequestException(ResponseMessages.schema.error.schemaBuilder, { cause: new Error(), @@ -392,7 +392,7 @@ export class SchemaService extends BaseService { description: ResponseMessages.errorMessages.notFound, }) } - const indyNamespace = await networkNamespace(schemaDetails?.did) + const indyNamespace = networkNamespace(schemaDetails?.did) if (indyNamespace === LedgerLessMethods.WEB || indyNamespace === LedgerLessMethods.KEY) { ledgerDetails = await this.schemaRepository.getLedgerByNamespace(LedgerLessConstant.NO_LEDGER) } else { @@ -431,24 +431,23 @@ export class SchemaService extends BaseService { const pattern = { cmd: 'agent-create-schema', } - const schemaResponse = await from(this.natsClient.send(this.schemaServiceProxy, pattern, payload)) - .pipe( + const schemaResponse = firstValueFrom( + from(this.natsClient.send(this.schemaServiceProxy, pattern, payload)).pipe( map((response) => ({ response, })) ) - .toPromise() - .catch((error) => { - this.logger.error(`Error in creating schema : ${JSON.stringify(error)}`) - throw new HttpException( - { - status: error.statusCode, - error: error.error, - message: error.message, - }, - error.error - ) - }) + ).catch((error) => { + this.logger.error(`Error in creating schema : ${JSON.stringify(error)}`) + throw new HttpException( + { + status: error.statusCode, + error: error.error, + message: error.message, + }, + error.error + ) + }) return schemaResponse } diff --git a/apps/organization/src/organization.service.ts b/apps/organization/src/organization.service.ts index d70e107c3..38e1fe8f4 100644 --- a/apps/organization/src/organization.service.ts +++ b/apps/organization/src/organization.service.ts @@ -519,7 +519,7 @@ export class OrganizationService { throw new ConflictException(ResponseMessages.organisation.error.exists) } - const orgSlug = await this.createOrgSlug(updateOrgDto.name) + const orgSlug = this.createOrgSlug(updateOrgDto.name) updateOrgDto.orgSlug = orgSlug updateOrgDto.userId = userId @@ -779,7 +779,7 @@ export class OrganizationService { return organizationDetails } catch (error) { this.logger.error(`In create organization : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -802,14 +802,14 @@ export class OrganizationService { pageSize, search ) - for await (const item of getOrganization.invitations) { + for (const item of getOrganization.invitations) { const getOrgRoles = await this.orgRoleService.getOrgRolesByIds(item.orgRoles) ;(item.orgRoles as object) = getOrgRoles } return getOrganization } catch (error) { this.logger.error(`In create organization : ${JSON.stringify(error)}`) - throw new RpcException(error.response ? error.response : error) + throw new RpcException(error.response ?? error) } } @@ -1661,7 +1661,7 @@ export class OrganizationService { emailData.emailTo = email emailData.emailSubject = `Removal of participation of “${orgName}”` - emailData.emailHtml = await urlEmailTemplate.sendDeleteOrgMemberEmailTemplate(email, orgName, orgRole) + emailData.emailHtml = urlEmailTemplate.sendDeleteOrgMemberEmailTemplate(email, orgName, orgRole) //Email is sent to user for the verification through emailData const isEmailSent = await sendEmail(emailData) diff --git a/apps/user/src/fido/fido.service.ts b/apps/user/src/fido/fido.service.ts index e1228f863..af7a39eae 100644 --- a/apps/user/src/fido/fido.service.ts +++ b/apps/user/src/fido/fido.service.ts @@ -96,7 +96,8 @@ export class FidoService { }) if (response?.verified && email.toLowerCase()) { await this.fidoUserRepository.updateUserDetails(email.toLowerCase(), [{ isFidoVerified: true }]) - const credentialID = response.newDevice.credentialID.replace(/=*$/, '') + // TODO: Test below changes from (/=*$/, '') to (/=+$/, '') + const credentialID = response.newDevice.credentialID.replace(/=+$/, '') response.newDevice.credentialID = credentialID const getUser = await this.fidoUserRepository.checkFidoUserExist(email.toLowerCase()) await this.userDevicesRepository.createMultiDevice(response?.newDevice, getUser.id) diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index c4f06ce62..08df71df3 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -198,7 +198,7 @@ export class UserService { const platform = platformName || process.env.PLATFORM_NAME emailData.emailSubject = `[${platform}] Verify your email to activate your account` - emailData.emailHtml = await urlEmailTemplate.getUserURLTemplate( + emailData.emailHtml = urlEmailTemplate.getUserURLTemplate( email, verificationCode, redirectUrl, @@ -519,7 +519,7 @@ export class UserService { const platform = platformName || process.env.PLATFORM_NAME emailData.emailSubject = `[${platform}] Important: Password Reset Request` - emailData.emailHtml = await urlEmailTemplate.getUserResetPasswordTemplate( + emailData.emailHtml = urlEmailTemplate.getUserResetPasswordTemplate( email, platform, brandLogoUrl, diff --git a/libs/prisma-service/src/prisma-service.service.ts b/libs/prisma-service/src/prisma-service.service.ts index adfc2dc15..593fb66dd 100644 --- a/libs/prisma-service/src/prisma-service.service.ts +++ b/libs/prisma-service/src/prisma-service.service.ts @@ -7,5 +7,7 @@ export class PrismaService extends PrismaClient implements OnModuleInit { await this.$connect() } - async enableShutdownHooks(_app: INestApplication): Promise {} + async enableShutdownHooks(_app: INestApplication): Promise { + // This method is intentionally left empty. + } }