diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4d89bc6..6d51f77 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: docker-compose -f build.docker-compose.yml run -e NPM_TOKEN=${NPM_TOKEN} --rm --entrypoint="npm run test" maestro - name: Remove Docker's Trash - continue-on-error: true + if: always() run: | - docker system prune - docker rmi -f $(docker images -aq) + docker system prune --volumes -a -f + docker system df diff --git a/.releaserc.json b/.releaserc.json index 8aa0def..4f6d6b7 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -5,18 +5,18 @@ { "preset": "eslint", "releaseRules": [ - { "tag": "FIX", "release": "patch" }, + { "tag": "BREAKING", "release": "major" }, { "tag": "FEAT", "release": "minor" }, { "tag": "UPDATE", "release": "minor" }, { "tag": "UPGRADE", "release": "minor" }, - { "tag": "BREAKING", "release": "major" }, - { "tag": "DOCS", "release": "patch" }, { "tag": "CHORE", "release": "minor" }, - { "tag": "BUILD", "release": "patch" }, { "tag": "REFACTOR", "release": "minor" }, + { "tag": "PERF", "release": "minor" }, + { "tag": "FIX", "release": "patch" }, + { "tag": "DOCS", "release": "patch" }, + { "tag": "BUILD", "release": "patch" }, { "tag": "TEST", "release": "patch" }, - { "tag": "CI", "release": "patch" }, - { "tag": "PERF", "release": "minor" } + { "tag": "CI", "release": "patch" } ] } ], diff --git a/Insomnia_2022-06-23.zip b/Insomnia_2022-06-23.zip new file mode 100644 index 0000000..7103d04 Binary files /dev/null and b/Insomnia_2022-06-23.zip differ diff --git a/nest-cli.json b/nest-cli.json index 066d065..2edc9db 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -2,7 +2,12 @@ "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { - "assets": ["**/*.proto"], + "assets": [ + "**/*.proto" + ], + "plugins": [ + "@nestjs/swagger" + ], "watchAssets": true } -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 10da7d5..18e80a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,61 +1,73 @@ { - "name": "grpc-server-and-client-nestjs-micro-pattern", + "name": "maestro", "version": "0.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "grpc-server-and-client-nestjs-micro-pattern", + "name": "maestro", "version": "0.0.0", "license": "UNLICENSED", "dependencies": { - "@grpc/grpc-js": "^1.5.10", - "@grpc/proto-loader": "^0.6.9", - "@nestjs/common": "^8.4.3", + "@aws-sdk/client-secrets-manager": "^3.112.0", + "@grpc/grpc-js": "^1.6.7", + "@grpc/proto-loader": "^0.6.13", + "@nestjs/common": "^8.4.7", "@nestjs/config": "^1.2.1", - "@nestjs/core": "^8.4.3", + "@nestjs/core": "^8.4.7", "@nestjs/mapped-types": "*", - "@nestjs/microservices": "^8.4.3", - "@nestjs/platform-express": "^8.4.3", + "@nestjs/microservices": "^8.4.7", + "@nestjs/passport": "^8.2.2", + "@nestjs/platform-express": "^8.4.7", "@nestjs/schedule": "^1.1.0", "@nestjs/swagger": "^5.2.1", "@victorradael/protospack": "2.5.0", + "@victorradael/protospack-v2": "1.1.1", "axios": "^0.25.0", "cron-parser": "^4.4.0", "dadosfera-logs": "^1.0.0-alpha.10", - "dotenv": "^14.2.0", + "dotenv": "^14.3.2", "elastic-apm-node": "^3.36.0", - "helmet": "^5.0.2", + "helmet": "^5.1.0", "jsonwebtoken": "^8.5.1", "jwk-to-pem": "^2.0.5", + "passport": "^0.6.0", + "passport-facebook": "^3.0.0", + "passport-google-oauth20": "^2.0.0", + "passport-hubspot-oauth2": "^1.0.3", + "passport-mailchimp": "^1.1.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.5.5", - "swagger-ui-express": "^4.3.0" + "swagger-ui-express": "^4.4.0" }, "devDependencies": { - "@nestjs/cli": "^8.2.4", - "@nestjs/schematics": "^8.0.8", - "@nestjs/testing": "^8.4.3", + "@nestjs/cli": "^8.2.8", + "@nestjs/schematics": "^8.0.11", + "@nestjs/testing": "^8.4.7", "@types/express": "^4.17.13", "@types/jest": "27.0.2", "@types/jsonwebtoken": "^8.5.8", "@types/jwk-to-pem": "^2.0.1", - "@types/node": "^16.11.26", + "@types/multer": "^1.4.7", + "@types/node": "^16.11.41", + "@types/passport-facebook": "^2.1.11", + "@types/passport-google-oauth20": "^2.0.11", + "@types/passport-oauth2": "^1.4.11", "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^5.17.0", - "@typescript-eslint/parser": "^5.17.0", - "eslint": "^8.12.0", + "@typescript-eslint/eslint-plugin": "^5.29.0", + "@typescript-eslint/parser": "^5.29.0", + "eslint": "^8.18.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^27.5.1", - "nock": "^13.2.4", - "prettier": "^2.6.1", + "nock": "^13.2.7", + "prettier": "^2.7.1", "source-map-support": "^0.5.20", - "supertest": "^6.1.3", - "ts-jest": "^27.1.4", - "ts-loader": "^9.2.7", - "ts-node": "^10.7.0", + "supertest": "^6.2.3", + "ts-jest": "^27.1.5", + "ts-loader": "^9.3.1", + "ts-node": "^10.8.1", "tsconfig-paths": "^3.14.1", "typescript": "^4.6.3" }, @@ -135,12 +147,13 @@ } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "13.3.5", + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-13.3.6.tgz", + "integrity": "sha512-5tTuu9gbXM0bMk0sin4phmWA3U1Qz53zT/rpEfzQ/+c/s8CoqZ5N1qOnYtemRct3Jxsz1kn4TBpHeriR4r5hHg==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-devkit/core": "13.3.5", - "@angular-devkit/schematics": "13.3.5", + "@angular-devkit/core": "13.3.6", + "@angular-devkit/schematics": "13.3.6", "ansi-colors": "4.1.1", "inquirer": "8.2.0", "minimist": "1.2.6", @@ -155,10 +168,80 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/core": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.6.tgz", + "integrity": "sha512-ZmD586B+RnM2CG5+jbXh2NVfIydTc/yKSjppYDDOv4I530YBm6vpfZMwClpiNk6XLbMv7KqX4Tlr4wfxlPYYbA==", + "dev": true, + "dependencies": { + "ajv": "8.9.0", + "ajv-formats": "2.1.1", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.7", + "source-map": "0.7.3" + }, + "engines": { + "node": "^12.20.0 || ^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/schematics": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.6.tgz", + "integrity": "sha512-yLh5xc92C/FiaAp27coPiKWpSUmwoXF7vMxbJYJTyOXlt0mUITAEAwtrZQNr4yAxW/yvgTdyg7PhXaveQNTUuQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "13.3.6", + "jsonc-parser": "3.0.0", + "magic-string": "0.25.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^12.20.0 || ^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, "node_modules/@angular-devkit/schematics-cli/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -172,8 +255,9 @@ }, "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { "version": "8.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", + "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -194,6 +278,12 @@ "node": ">=8.0.0" } }, + "node_modules/@angular-devkit/schematics-cli/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "6.6.7", "dev": true, @@ -210,6 +300,859 @@ "dev": true, "license": "0BSD" }, + "node_modules/@aws-crypto/ie11-detection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.0.tgz", + "integrity": "sha512-pkVXf/dq6PITJ0jzYZ69VhL8VFOFoPZLZqtU/12SGnzYuJOOGNfF41q9GxdI1yqC8R13Rq3jOLKDFpUJFT5eTA==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz", + "integrity": "sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==", + "dependencies": { + "@aws-crypto/ie11-detection": "^2.0.0", + "@aws-crypto/sha256-js": "^2.0.0", + "@aws-crypto/supports-web-crypto": "^2.0.0", + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz", + "integrity": "sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==", + "dependencies": { + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.0.tgz", + "integrity": "sha512-Ge7WQ3E0OC7FHYprsZV3h0QIcpdyJLvIeg+uTuHqRYm8D6qCFJoiC+edSzSyFiHtZf+NOQDJ1q46qxjtzIY2nA==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.1.tgz", + "integrity": "sha512-JJmFFwvbm08lULw4Nm5QOLg8+lAQeC8aCXK5xrtxntYzYXCGfHwUJ4Is3770Q7HmICsXthGQ+ZsDL7C2uH3yBQ==", + "dependencies": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/abort-controller": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.110.0.tgz", + "integrity": "sha512-zok/WEVuK7Jh6V9YeA56pNZtxUASon9LTkS7vE65A4UFmNkPGNBCNgoiBcbhWfxwrZ8wtXcQk6rtUut39831mA==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.118.1.tgz", + "integrity": "sha512-vKqjidFStTNVX9cw1xzGpP+1LlRszS7RXC9ZnlcolvQEWF/gL9nODXCEDrEoTzBmQuQ0XAxWzvEDGgRee/e2eQ==", + "dependencies": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/client-sts": "3.118.1", + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/credential-provider-node": "3.118.1", + "@aws-sdk/fetch-http-handler": "3.110.0", + "@aws-sdk/hash-node": "3.110.0", + "@aws-sdk/invalid-dependency": "3.110.0", + "@aws-sdk/middleware-content-length": "3.110.0", + "@aws-sdk/middleware-host-header": "3.110.0", + "@aws-sdk/middleware-logger": "3.110.0", + "@aws-sdk/middleware-recursion-detection": "3.110.0", + "@aws-sdk/middleware-retry": "3.118.1", + "@aws-sdk/middleware-serde": "3.110.0", + "@aws-sdk/middleware-signing": "3.110.0", + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/middleware-user-agent": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/node-http-handler": "3.118.1", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/smithy-client": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "@aws-sdk/util-base64-node": "3.55.0", + "@aws-sdk/util-body-length-browser": "3.55.0", + "@aws-sdk/util-body-length-node": "3.55.0", + "@aws-sdk/util-defaults-mode-browser": "3.110.0", + "@aws-sdk/util-defaults-mode-node": "3.110.0", + "@aws-sdk/util-user-agent-browser": "3.110.0", + "@aws-sdk/util-user-agent-node": "3.118.0", + "@aws-sdk/util-utf8-browser": "3.109.0", + "@aws-sdk/util-utf8-node": "3.109.0", + "tslib": "^2.3.1", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.118.1.tgz", + "integrity": "sha512-dvufBhoE+sVo2sB9+m39GaxmvCKskWLy2hqv+cqyh5poqSWlCZaliRJFpq/rwQm15lUfrHoD8b+NSNEUIVJf9w==", + "dependencies": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/fetch-http-handler": "3.110.0", + "@aws-sdk/hash-node": "3.110.0", + "@aws-sdk/invalid-dependency": "3.110.0", + "@aws-sdk/middleware-content-length": "3.110.0", + "@aws-sdk/middleware-host-header": "3.110.0", + "@aws-sdk/middleware-logger": "3.110.0", + "@aws-sdk/middleware-recursion-detection": "3.110.0", + "@aws-sdk/middleware-retry": "3.118.1", + "@aws-sdk/middleware-serde": "3.110.0", + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/middleware-user-agent": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/node-http-handler": "3.118.1", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/smithy-client": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "@aws-sdk/util-base64-node": "3.55.0", + "@aws-sdk/util-body-length-browser": "3.55.0", + "@aws-sdk/util-body-length-node": "3.55.0", + "@aws-sdk/util-defaults-mode-browser": "3.110.0", + "@aws-sdk/util-defaults-mode-node": "3.110.0", + "@aws-sdk/util-user-agent-browser": "3.110.0", + "@aws-sdk/util-user-agent-node": "3.118.0", + "@aws-sdk/util-utf8-browser": "3.109.0", + "@aws-sdk/util-utf8-node": "3.109.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.118.1.tgz", + "integrity": "sha512-i144bIUf+KmKJp00g08V/QPOh4v0xDIO7IX7m7ngkDlttIWGg9lXDcWhiRU+j0z72uv48D9em3nibJdFCjZjrA==", + "dependencies": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/credential-provider-node": "3.118.1", + "@aws-sdk/fetch-http-handler": "3.110.0", + "@aws-sdk/hash-node": "3.110.0", + "@aws-sdk/invalid-dependency": "3.110.0", + "@aws-sdk/middleware-content-length": "3.110.0", + "@aws-sdk/middleware-host-header": "3.110.0", + "@aws-sdk/middleware-logger": "3.110.0", + "@aws-sdk/middleware-recursion-detection": "3.110.0", + "@aws-sdk/middleware-retry": "3.118.1", + "@aws-sdk/middleware-sdk-sts": "3.110.0", + "@aws-sdk/middleware-serde": "3.110.0", + "@aws-sdk/middleware-signing": "3.110.0", + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/middleware-user-agent": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/node-http-handler": "3.118.1", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/smithy-client": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "@aws-sdk/util-base64-node": "3.55.0", + "@aws-sdk/util-body-length-browser": "3.55.0", + "@aws-sdk/util-body-length-node": "3.55.0", + "@aws-sdk/util-defaults-mode-browser": "3.110.0", + "@aws-sdk/util-defaults-mode-node": "3.110.0", + "@aws-sdk/util-user-agent-browser": "3.110.0", + "@aws-sdk/util-user-agent-node": "3.118.0", + "@aws-sdk/util-utf8-browser": "3.109.0", + "@aws-sdk/util-utf8-node": "3.109.0", + "entities": "2.2.0", + "fast-xml-parser": "3.19.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@aws-sdk/config-resolver": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.110.0.tgz", + "integrity": "sha512-7VvtKy4CL63BAktQ2vgsjhWDSXpkXO5YdiI56LQnHztrvSuJBBaxJ7R1p/k0b2tEUhYKUziAIW8EKE/7EGPR4g==", + "dependencies": { + "@aws-sdk/signature-v4": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-config-provider": "3.109.0", + "@aws-sdk/util-middleware": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.110.0.tgz", + "integrity": "sha512-oFU3IYk/Bl5tdsz1qigtm3I25a9cvXPqlE8VjYjxVDdLujF5zd/4HLbhP4GQWhpEwZmM1ijcSNfLcyywVevTZg==", + "dependencies": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-imds": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.110.0.tgz", + "integrity": "sha512-atl+7/dAB+8fG9XI2fYyCgXKYDbOzot65VAwis+14bOEUCVp7PCJifBEZ/L8GEq564p+Fa2p1IpV0wuQXxqFUQ==", + "dependencies": { + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.118.1.tgz", + "integrity": "sha512-Ri05NMc0T2BT7O/6iS+tVwwPtF4Y+BbJrAwoeGApYI9gJqrRSSJ1I2oSye2UV/Ty49n3NmZGtQ+LZJjXShVFSw==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.110.0", + "@aws-sdk/credential-provider-imds": "3.110.0", + "@aws-sdk/credential-provider-sso": "3.118.1", + "@aws-sdk/credential-provider-web-identity": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.118.1.tgz", + "integrity": "sha512-+DntbY0Foi5aIx1+6hNMUCSd2Oa109X6AJBdiUpwuRQu7+9wK0MBEzyi6Ap5QCa6/ThMQgq0PenR2Bwdl39fXw==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.110.0", + "@aws-sdk/credential-provider-imds": "3.110.0", + "@aws-sdk/credential-provider-ini": "3.118.1", + "@aws-sdk/credential-provider-process": "3.110.0", + "@aws-sdk/credential-provider-sso": "3.118.1", + "@aws-sdk/credential-provider-web-identity": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.110.0.tgz", + "integrity": "sha512-JJcZePvRTfQHYj/+EEY13yItnZH/e8exlARFUjN0L13UrgHpOJtDQBa+YBHXo6MbTFQh+re25z2kzc+zOYSMNQ==", + "dependencies": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.118.1.tgz", + "integrity": "sha512-oycFvPBcmfO2WAz5GfLrfGg+HbYA090gnNw5YknMtWewujXkgZ18AMhBsyRw/+mlHpbcFv/w1Gq0RgeTGSssRg==", + "dependencies": { + "@aws-sdk/client-sso": "3.118.1", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.110.0.tgz", + "integrity": "sha512-e4e5u7v3fsUFZsMcFMhMy1NdJBQpunYcLwpYlszm3OEICwTTekQ+hVvnVRd134doHvzepE4yp9sAop0Cj+IRVQ==", + "dependencies": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/fetch-http-handler": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.110.0.tgz", + "integrity": "sha512-vk+K4GeCZL2J2rtvKO+T0Q7i3MDpEGZBMg5K2tj9sMcEQwty0BF0aFnP7Eu2l4/Zif2z1mWuUFM2WcZI6DVnbw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/querystring-builder": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/hash-node": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.110.0.tgz", + "integrity": "sha512-wakl+kP2O8wTGYiQ3InZy+CVfGrIpFfq9fo4zif9PZac0BbUbguUU1dkY34uZiaf+4o2/9MoDYrHU2HYeXKxWw==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-buffer-from": "3.55.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/invalid-dependency": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.110.0.tgz", + "integrity": "sha512-O8J1InmtJkoiUMbQDtxBfOzgigBp9iSVsNXQrhs2qHh3826cJOfE7NGT3u+NMw73Pk5j2cfmOh1+7k/76IqxOg==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/is-array-buffer": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.55.0.tgz", + "integrity": "sha512-NbiPHVYuPxdqdFd6FxzzN3H1BQn/iWA3ri3Ry7AyLeP/tGs1yzEWMwf8BN8TSMALI0GXT6Sh0GDWy3Ok5xB6DA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-content-length": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.110.0.tgz", + "integrity": "sha512-hKU+zdqfAJQg22LXMVu/z35nNIHrVAKpVKPe9+WYVdL/Z7JKUPK7QymqKGOyDuDbzW6OxyulC1zKGEX12zGmdA==", + "dependencies": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.110.0.tgz", + "integrity": "sha512-/Cknn1vL2LTlclI0MX2RzmtdPlCJ5palCRXxm/mod1oHwg4oNTKRlUX3LUD+L8g7JuJ4h053Ch9KS/A0vanE5Q==", + "dependencies": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.110.0.tgz", + "integrity": "sha512-+pz+a+8dfTnzLj79nHrv3aONMp/N36/erMd+7JXeR84QEosVLrFBUwKA8x5x6O3s1iBbQzRKMYEIuja9xn1BPA==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.110.0.tgz", + "integrity": "sha512-Wav782zd7bcd1e6txRob76CDOdVOaUQ8HXoywiIm/uFrEEUZvhs2mgnXjVUVCMBUehdNgnL99z420aS13JeL/Q==", + "dependencies": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-retry": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.118.1.tgz", + "integrity": "sha512-Dh0EgO3yPHEaRC6CVrofgAMdUQaG0Kkl466iVFHN5n5kExQvCtvpMHwO9N7kqaq9lXten3yhzboRNLIo98E1Kw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/service-error-classification": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-middleware": "3.110.0", + "tslib": "^2.3.1", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.110.0.tgz", + "integrity": "sha512-EjY/YFdlr5jECde6qIrTIyGBbn/34CKcQGKvmvRd31+3qaClIJLAwNuHfcVzWvCUGbAslsfvdbOpLju33pSQRA==", + "dependencies": { + "@aws-sdk/middleware-signing": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/signature-v4": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-serde": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.110.0.tgz", + "integrity": "sha512-brVupxgEAmcZ9cZvdHEH8zncjvGKIiud8pOe4fiimp5NpHmjBLew4jUbnOKNZNAjaidcKUtz//cxtutD6yXEww==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.110.0.tgz", + "integrity": "sha512-y6ZKrGYfgDlFMzWhZmoq5J1UctBgZOUvMmnU9sSeZ020IlEPiOxFMvR0Zu6TcYThp8uy3P0wyjQtGYeTl9Z/kA==", + "dependencies": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/signature-v4": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-stack": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.110.0.tgz", + "integrity": "sha512-iaLHw6ctOuGa9UxNueU01Xes+15dR+mqioRpUOUZ9Zx+vhXVpD7C8lnNqhRnYeFXs10/rNIzASgsIrAHTlnlIQ==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.110.0.tgz", + "integrity": "sha512-Y6FgiZr99DilYq6AjeaaWcNwVlSQpNGKrILzvV4Tmz03OaBIspe4KL+8EZ2YA/sAu5Lpw80vItdezqDOwGAlnQ==", + "dependencies": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/node-config-provider": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.110.0.tgz", + "integrity": "sha512-46p4dCPGYctuybTQTwLpjenA1QFHeyJw/OyggGbtUJUy+833+ldnAwcPVML2aXJKUKv3APGI8vq1kaloyNku3Q==", + "dependencies": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/node-http-handler": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.118.1.tgz", + "integrity": "sha512-pfWVAUNJEs0UW0KkDqq2/VCz9PIpvg4mYEfCVZ4jR+Rv8F7UezNeM3FrEdHk8dfYShH+OV0hFskHBQJhw1BX2Q==", + "dependencies": { + "@aws-sdk/abort-controller": "3.110.0", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/querystring-builder": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/property-provider": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.110.0.tgz", + "integrity": "sha512-7NkpmYeOkK3mhWBNU+/zSDqwzeaSPH1qrq4L//WV7WS/weYyE/jusQeZoOxVsuZQnQEXHt5O2hKVeUwShl12xA==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/protocol-http": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.110.0.tgz", + "integrity": "sha512-qdi2gCbJiyPyLn+afebPNp/5nVCRh1X7t7IRIFl3FHVEC+o54u/ojay/MLZ4M/+X9Fa4Zxsb0Wpp3T0xAHVDBg==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/querystring-builder": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.110.0.tgz", + "integrity": "sha512-7V3CDXj519izmbBn9ZE68ymASwGriA+Aq+cb/yHSVtffnvXjPtvONNw7G/5iVblisGLSCUe2hSvpYtcaXozbHw==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-uri-escape": "3.55.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/querystring-parser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.110.0.tgz", + "integrity": "sha512-//pJHH7hrhdDMZGBPKXKymmC/tJM7gFT0w/qbu/yd3Wm4W2fMB+8gkmj6EZctx7jrsWlfRQuvFejKqEfapur/g==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/service-error-classification": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.110.0.tgz", + "integrity": "sha512-ccgCE0pU/4RmXR6CP3fLAdhPAve7bK/yXBbGzpSHGAQOXqNxYzOsAvQ30Jg6X+qjLHsI/HR2pLIE65z4k6tynw==", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/shared-ini-file-loader": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.110.0.tgz", + "integrity": "sha512-E1ERoqEoG206XNBYWCKLgHkzCbTxdpDEGbsLET2DnvjFsT0s9p2dPvVux3bYl7JVAhyGduE+qcqWk7MzhFCBNQ==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.110.0.tgz", + "integrity": "sha512-utxxdllOnmQDhbpipnFAbuQ4c2pwefZ+2hi48jKvQRULQ2PO4nxLmdZm6B0FXaTijbKsyO7GrMik+EZ6mi3ARQ==", + "dependencies": { + "@aws-sdk/is-array-buffer": "3.55.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-hex-encoding": "3.109.0", + "@aws-sdk/util-middleware": "3.110.0", + "@aws-sdk/util-uri-escape": "3.55.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/smithy-client": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.110.0.tgz", + "integrity": "sha512-gNLYrmdAe/1hVF2Nv2LF4OkL1A0a1o708pEMZHzql9xP164omRDaLrGDhz9tH7tsJEgLz+Bf4E8nTuISeDwvGg==", + "dependencies": { + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.110.0.tgz", + "integrity": "sha512-dLVoqODU3laaqNFPyN1QLtlQnwX4gNPMXptEBIt/iJpuZf66IYJe6WCzVZGt4Zfa1CnUmrlA428AzdcA/KCr2A==", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/url-parser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.110.0.tgz", + "integrity": "sha512-tILFB8/Q73yzgO0dErJNnELmmBszd0E6FucwAnG3hfDefjqCBe09Q/1yhu2aARXyRmZa4AKp0sWcdwIWHc8dnA==", + "dependencies": { + "@aws-sdk/querystring-parser": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-base64-browser": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.109.0.tgz", + "integrity": "sha512-lAZ6fyDGiRLaIsKT9qh7P9FGuNyZ4gAbr1YOSQk/5mHtaTuUvxlPptZuInNM/0MPQm6lpcot00D8IWTucn4PbA==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-base64-node": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.55.0.tgz", + "integrity": "sha512-UQ/ZuNoAc8CFMpSiRYmevaTsuRKzLwulZTnM8LNlIt9Wx1tpNvqp80cfvVj7yySKROtEi20wq29h31dZf1eYNQ==", + "dependencies": { + "@aws-sdk/util-buffer-from": "3.55.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-body-length-browser": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.55.0.tgz", + "integrity": "sha512-Ei2OCzXQw5N6ZkTMZbamUzc1z+z1R1Ja5tMEagz5BxuX4vWdBObT+uGlSzL8yvTbjoPjnxWA2aXyEqaUP3JS8Q==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-body-length-node": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.55.0.tgz", + "integrity": "sha512-lU1d4I+9wJwydduXs0SxSfd+mHKjxeyd39VwOv6i2KSwWkPbji9UQqpflKLKw+r45jL7+xU/zfeTUg5Tt/3Gew==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-buffer-from": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.55.0.tgz", + "integrity": "sha512-uVzKG1UgvnV7XX2FPTylBujYMKBPBaq/qFBxfl0LVNfrty7YjpfieQxAe6yRLD+T0Kir/WDQwGvYC+tOYG3IGA==", + "dependencies": { + "@aws-sdk/is-array-buffer": "3.55.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-config-provider": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.109.0.tgz", + "integrity": "sha512-GrAZl/aBv0A28LkyNyq8SPJ5fmViCwz80fWLMeWx/6q5AbivuILogjlWwEZSvZ9zrlHOcFC0+AnCa5pQrjaslw==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-defaults-mode-browser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.110.0.tgz", + "integrity": "sha512-Y2dcOOD20S3bv/IjUqpdKIiDt6995SXNG5Pu/LeSdXNyLCOIm9rX4gHTxl9fC1KK5M/gR9fGJ362f67WwqEEqw==", + "dependencies": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@aws-sdk/util-defaults-mode-node": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.110.0.tgz", + "integrity": "sha512-Cr3Z5nyrw1KowjbW76xp8hkT/zJtYjAVZ9PS4l84KxIicbVvDOBpxG3yNddkuQcavmlH6G4wH9uM5DcnpKDncg==", + "dependencies": { + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/credential-provider-imds": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@aws-sdk/util-hex-encoding": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.109.0.tgz", + "integrity": "sha512-s8CgTNrn3cLkrdiohfxLuOYPCanzvHn/aH5RW6DaMoeQiG5Hl9QUiP/WtdQ9QQx3xvpQFpmvxIaSBwSgFNLQxA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.55.0.tgz", + "integrity": "sha512-0sPmK2JaJE2BbTcnvybzob/VrFKCXKfN4CUKcvn0yGg/me7Bz+vtzQRB3Xp+YSx+7OtWxzv63wsvHoAnXvgxgg==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-middleware": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.110.0.tgz", + "integrity": "sha512-PTVWrI5fA9d5hHJs6RzX2dIS2jRQ3uW073Fm0BePpQeDdZrEk+S5KNwRhUtpN6sdSV45vm6S9rrjZUG51qwGmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-uri-escape": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.55.0.tgz", + "integrity": "sha512-mmdDLUpFCN2nkfwlLdOM54lTD528GiGSPN1qb8XtGLgZsJUmg3uJSFIN2lPeSbEwJB3NFjVas/rnQC48i7mV8w==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.110.0.tgz", + "integrity": "sha512-rNdhmHDMV5dNJctqlBWimkZLJRB+x03DB+61pm+SKSFk6gPIVIvc1WNXqDFphkiswT4vA13ZUkGHzt+N4+noQQ==", + "dependencies": { + "@aws-sdk/types": "3.110.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.118.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.118.0.tgz", + "integrity": "sha512-7j21HNumxMkeUpgoMX8o3y66k+qMSEkCPCMGnoiiMtgfWX9SY0S/fLwR1nDBw8HI3NthRXfgWdAXUu8K3Kjp6g==", + "dependencies": { + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.109.0.tgz", + "integrity": "sha512-FmcGSz0v7Bqpl1SE8G1Gc0CtDpug+rvqNCG/szn86JApD/f5x8oByjbEiAyTU2ZH2VevUntx6EW68ulHyH+x+w==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-utf8-node": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.109.0.tgz", + "integrity": "sha512-Ti/ZBdvz2eSTElsucjzNmzpyg2MwfD1rXmxD0hZuIF8bPON/0+sZYnWd5CbDw9kgmhy28dmKue086tbZ1G0iLQ==", + "dependencies": { + "@aws-sdk/util-buffer-from": "3.55.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.16.7", "dev": true, @@ -852,13 +1795,14 @@ } }, "node_modules/@grpc/proto-loader": { - "version": "0.6.12", - "license": "Apache-2.0", + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", - "protobufjs": "^6.10.0", + "protobufjs": "^6.11.3", "yargs": "^16.2.0" }, "bin": { @@ -1330,13 +2274,14 @@ } }, "node_modules/@nestjs/cli": { - "version": "8.2.6", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.8.tgz", + "integrity": "sha512-y5Imcw1EY0OxD3POAM7SLUB1rFdn5FjbfSsyJrokjKmXY+i6KcBdbRrv3Ox7aeJ4W7wXuckIXZEUlK6lC52dnA==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-devkit/core": "13.3.5", - "@angular-devkit/schematics": "13.3.5", - "@angular-devkit/schematics-cli": "13.3.5", + "@angular-devkit/core": "13.3.6", + "@angular-devkit/schematics": "13.3.6", + "@angular-devkit/schematics-cli": "13.3.6", "@nestjs/schematics": "^8.0.3", "chalk": "3.0.0", "chokidar": "3.5.3", @@ -1353,8 +2298,8 @@ "tree-kill": "1.2.2", "tsconfig-paths": "3.14.1", "tsconfig-paths-webpack-plugin": "3.5.2", - "typescript": "4.6.4", - "webpack": "5.72.1", + "typescript": "4.7.4", + "webpack": "5.73.0", "webpack-node-externals": "3.0.0" }, "bin": { @@ -1365,21 +2310,73 @@ "npm": ">= 6.11.0" } }, - "node_modules/@nestjs/cli/node_modules/typescript": { - "version": "4.6.4", + "node_modules/@nestjs/cli/node_modules/@angular-devkit/core": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.6.tgz", + "integrity": "sha512-ZmD586B+RnM2CG5+jbXh2NVfIydTc/yKSjppYDDOv4I530YBm6vpfZMwClpiNk6XLbMv7KqX4Tlr4wfxlPYYbA==", "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "dependencies": { + "ajv": "8.9.0", + "ajv-formats": "2.1.1", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.7", + "source-map": "0.7.3" }, "engines": { - "node": ">=4.2.0" + "node": "^12.20.0 || ^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, + "node_modules/@nestjs/cli/node_modules/@angular-devkit/schematics": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.6.tgz", + "integrity": "sha512-yLh5xc92C/FiaAp27coPiKWpSUmwoXF7vMxbJYJTyOXlt0mUITAEAwtrZQNr4yAxW/yvgTdyg7PhXaveQNTUuQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "13.3.6", + "jsonc-parser": "3.0.0", + "magic-string": "0.25.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^12.20.0 || ^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/cli/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@nestjs/cli/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/@nestjs/common": { - "version": "8.4.5", - "license": "MIT", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-8.4.7.tgz", + "integrity": "sha512-m/YsbcBal+gA5CFrDpqXqsSfylo+DIQrkFY3qhVIltsYRfu8ct8J9pqsTO6OPf3mvqdOpFGrV5sBjoyAzOBvsw==", "dependencies": { "axios": "0.27.2", "iterare": "1.2.1", @@ -1452,9 +2449,10 @@ } }, "node_modules/@nestjs/core": { - "version": "8.4.5", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-8.4.7.tgz", + "integrity": "sha512-XB9uexHqzr2xkPo6QSiQWJJttyYYLmvQ5My64cFvWFi7Wk2NIus0/xUNInwX3kmFWB6pF1ab5Y2ZBvWdPwGBhw==", "hasInstallScript": true, - "license": "MIT", "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", @@ -1507,11 +2505,11 @@ } }, "node_modules/@nestjs/microservices": { - "version": "8.4.5", - "license": "MIT", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-8.4.7.tgz", + "integrity": "sha512-JZX29tBWbbPa+Q06QcCbwKTyEsOFHAPrxgfEkRNwoaiEqqCsITT9w2n5bcz3vlUurdpy5dIgX3/almbitghbKg==", "dependencies": { "iterare": "1.2.1", - "json-socket": "0.3.0", "tslib": "2.4.0" }, "funding": { @@ -1563,14 +2561,24 @@ } } }, + "node_modules/@nestjs/passport": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-8.2.2.tgz", + "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==", + "peerDependencies": { + "@nestjs/common": "^6.0.0 || ^7.0.0 || ^8.0.0", + "passport": "^0.4.0 || ^0.5.0 || ^0.6.0" + } + }, "node_modules/@nestjs/platform-express": { - "version": "8.4.5", - "license": "MIT", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-8.4.7.tgz", + "integrity": "sha512-lPE5Ltg2NbQGRQIwXWY+4cNrXhJdycbxFDQ8mNxSIuv+LbrJBIdEB/NONk+LLn9N/8d2+I2LsIETGQrPvsejBg==", "dependencies": { "body-parser": "1.20.0", "cors": "2.8.5", "express": "4.18.1", - "multer": "1.4.4", + "multer": "1.4.4-lts.1", "tslib": "2.4.0" }, "funding": { @@ -1635,11 +2643,11 @@ } }, "node_modules/@nestjs/testing": { - "version": "8.4.5", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.7.tgz", + "integrity": "sha512-aedpeJFicTBeiTCvJWUG45WMMS53f5eu8t2fXsfjsU1t+WdDJqYcZyrlCzA4dL1B7MfbqaTURdvuVVHTmJO8ag==", "dev": true, - "license": "MIT", "dependencies": { - "optional": "0.1.4", "tslib": "2.4.0" }, "funding": { @@ -1663,8 +2671,9 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1675,16 +2684,18 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1992,15 +3003,80 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/multer": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz", + "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/node": { - "version": "16.11.36", - "license": "MIT" + "version": "16.11.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.41.tgz", + "integrity": "sha512-mqoYK2TnVjdkGk8qXAVGc/x9nSaTpSrFaGFm43BUH3IdoBV0nta6hYaGmdOvIMlbHJbUEVen3gvwpwovAZKNdQ==" + }, + "node_modules/@types/oauth": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz", + "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/object-hash": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz", + "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==" }, "node_modules/@types/parse-json": { "version": "4.0.0", "dev": true, "license": "MIT" }, + "node_modules/@types/passport": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.9.tgz", + "integrity": "sha512-9+ilzUhmZQR4JP49GdC2O4UdDE3POPLwpmaTC/iLkW7l0TZCXOo1zsTnnlXPq6rP1UsUZPfbAV4IUdiwiXyC7g==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/passport-facebook": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@types/passport-facebook/-/passport-facebook-2.1.11.tgz", + "integrity": "sha512-YsZUZryJvHt2E/WdR22FlnCi9ckMwkGR+FwCcXq830rOvruhXJHJtKSXSD+Kn4phBsrEpqoP4xX6fFuEodk20A==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/passport": "*" + } + }, + "node_modules/@types/passport-google-oauth20": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.11.tgz", + "integrity": "sha512-9XMT1GfwhZL7UQEiCepLef55RNPHkbrCtsU7rsWPTEOsmu5qVIW8nSemtB4p+P24CuOhA+IKkv8LsPThYghGww==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/passport": "*", + "@types/passport-oauth2": "*" + } + }, + "node_modules/@types/passport-oauth2": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.11.tgz", + "integrity": "sha512-KUNwmGhe/3xPbjkzkPwwcPmyFwfyiSgtV1qOrPBLaU4i4q9GSCdAOyCbkFG0gUxAyEmYwqo9OAF/rjPjJ6ImdA==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/oauth": "*", + "@types/passport": "*" + } + }, "node_modules/@types/prettier": { "version": "2.6.3", "dev": true, @@ -2061,13 +3137,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.0.tgz", + "integrity": "sha512-lvhRJ2pGe2V9MEU46ELTdiHgiAFZPKtLhiU5wlnaYpMc2+c1R8fh8i80ZAa665drvjHKUJyRRGg3gEm1If54ow==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.26.0", - "@typescript-eslint/type-utils": "5.26.0", - "@typescript-eslint/utils": "5.26.0", + "@typescript-eslint/scope-manager": "5.30.0", + "@typescript-eslint/type-utils": "5.30.0", + "@typescript-eslint/utils": "5.30.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -2093,13 +3170,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.0.tgz", + "integrity": "sha512-2oYYUws5o2liX6SrFQ5RB88+PuRymaM2EU02/9Ppoyu70vllPnHVO7ioxDdq/ypXHA277R04SVjxvwI8HmZpzA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.26.0", - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/typescript-estree": "5.26.0", + "@typescript-eslint/scope-manager": "5.30.0", + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/typescript-estree": "5.30.0", "debug": "^4.3.4" }, "engines": { @@ -2119,12 +3197,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.0.tgz", + "integrity": "sha512-3TZxvlQcK5fhTBw5solQucWSJvonXf5yua5nx8OqK94hxdrT7/6W3/CS42MLd/f1BmlmmbGEgQcTHHCktUX5bQ==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/visitor-keys": "5.26.0" + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/visitor-keys": "5.30.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2135,11 +3214,12 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.0.tgz", + "integrity": "sha512-GF8JZbZqSS+azehzlv/lmQQ3EU3VfWYzCczdZjJRxSEeXDQkqFhCBgFhallLDbPwQOEQ4MHpiPfkjKk7zlmeNg==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "5.26.0", + "@typescript-eslint/utils": "5.30.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2160,9 +3240,10 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.0.tgz", + "integrity": "sha512-vfqcBrsRNWw/LBXyncMF/KrUTYYzzygCSsVqlZ1qGu1QtGs6vMkt3US0VNSQ05grXi5Yadp3qv5XZdYLjpp8ag==", "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2172,12 +3253,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.0.tgz", + "integrity": "sha512-hDEawogreZB4n1zoqcrrtg/wPyyiCxmhPLpZ6kmWfKF5M5G0clRLaEexpuWr31fZ42F96SlD/5xCt1bT5Qm4Nw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/visitor-keys": "5.26.0", + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/visitor-keys": "5.30.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2198,14 +3280,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-0bIgOgZflLKIcZsWvfklsaQTM3ZUbmtH0rJ1hKyV3raoUYyeZwcjQ8ZUJTzS7KnhNcsVT1Rxs7zeeMHEhGlltw==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.26.0", - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/typescript-estree": "5.26.0", + "@typescript-eslint/scope-manager": "5.30.0", + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/typescript-estree": "5.30.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -2221,11 +3304,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.0.tgz", + "integrity": "sha512-6WcIeRk2DQ3pHKxU1Ni0qMXJkjO/zLjBymlYBy/53qxe7yjEFSvzKLDToJjURUhSl2Fzhkl4SMXQoETauF74cw==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.26.0", + "@typescript-eslint/types": "5.30.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2244,6 +3328,15 @@ "rxjs": "^7.5.5" } }, + "node_modules/@victorradael/protospack-v2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@victorradael/protospack-v2/-/protospack-v2-1.1.1.tgz", + "integrity": "sha512-K9SuHcCGa7wynbzTG1aVnODksajTKfr9+tDHw6qfFfPwBruJXv5HsbMMylizAg+HTgEr/D6h/L1PO05rygDJCw==", + "dependencies": { + "rxjs": "^7.5.5", + "ts-proto": "^1.112.2" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "dev": true, @@ -2526,8 +3619,9 @@ }, "node_modules/ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -2609,8 +3703,9 @@ }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -2815,6 +3910,14 @@ ], "license": "MIT" }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -2904,6 +4007,11 @@ "version": "2.0.0", "license": "MIT" }, + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "license": "MIT", @@ -3484,6 +4592,11 @@ "node": ">=10" } }, + "node_modules/dataloader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", + "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==" + }, "node_modules/debug": { "version": "4.3.4", "license": "MIT", @@ -3601,8 +4714,9 @@ }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -3859,6 +4973,14 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-callsites": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/error-callsites/-/error-callsites-2.0.4.tgz", @@ -4046,9 +5168,10 @@ } }, "node_modules/eslint": { - "version": "8.16.0", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.18.0.tgz", + "integrity": "sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==", "dev": true, - "license": "MIT", "dependencies": { "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", @@ -4454,8 +5577,9 @@ }, "node_modules/fast-glob": { "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -4530,10 +5654,23 @@ "end-of-stream": "^1.4.1" } }, + "node_modules/fast-xml-parser": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz", + "integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==", + "bin": { + "xml2js": "cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, "node_modules/fastq": { "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -4950,8 +6087,9 @@ }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -6578,9 +7716,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-socket": { - "version": "0.3.0" - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true, @@ -6774,11 +7909,6 @@ "version": "4.1.1", "license": "MIT" }, - "node_modules/lodash.set": { - "version": "4.3.2", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -6962,8 +8092,9 @@ }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } @@ -7130,13 +8261,14 @@ "integrity": "sha512-+I10J3wKNoKddNxn0CNpoZ3eTZuqxjNM3b1GImVx22+ePI+Y15P8g/j3WsbP0fhzzrFzrtjOAoq5NCCucswXOQ==" }, "node_modules/nock": { - "version": "13.2.4", + "version": "13.2.7", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.7.tgz", + "integrity": "sha512-R6NUw7RIPtKwgK7jskuKoEi4VFMqIHtV2Uu9K/Uegc4TA5cqe+oNMYslZcUmnVNQCTG6wcSqUBaGTDd7sq5srg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", + "lodash": "^4.17.21", "propagate": "^2.0.0" }, "engines": { @@ -7219,6 +8351,11 @@ "dev": true, "license": "MIT" }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" + }, "node_modules/object-assign": { "version": "4.1.1", "license": "MIT", @@ -7330,11 +8467,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optional": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, "node_modules/optional-js": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", @@ -7497,6 +8629,130 @@ "node": ">= 0.8" } }, + "node_modules/passport": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, + "node_modules/passport-facebook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-3.0.0.tgz", + "integrity": "sha512-K/qNzuFsFISYAyC1Nma4qgY/12V3RSLFdFVsPKXiKZt434wOvthFW1p7zKa1iQihQMRhaWorVE1o3Vi1o+ZgeQ==", + "dependencies": { + "passport-oauth2": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-google-oauth20": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", + "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==", + "dependencies": { + "passport-oauth2": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-hubspot-oauth2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/passport-hubspot-oauth2/-/passport-hubspot-oauth2-1.0.3.tgz", + "integrity": "sha512-YQyZ9dMxyDJI4vHtq/FXKxEQx39EdODWkn7yp+y12FQBKUXEWN4p2XRO5znwTKyFc1ALwDgCGRxNnRpx7F7gZA==", + "dependencies": { + "passport-oauth": "~1.0.0", + "pkginfo": "0.2.x" + }, + "engines": { + "node": ">= 6.2" + } + }, + "node_modules/passport-mailchimp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/passport-mailchimp/-/passport-mailchimp-1.1.0.tgz", + "integrity": "sha512-drCP+TMv1hcFCZ8Nbjx2gzq4ovYyvGZzH8I9RiaVD5ArvaWL3BAf6KJsNMxoPPwZAZi5SX5NqbG46I+5cUzweg==", + "dependencies": { + "passport-oauth2": "^1.3.0", + "pkginfo": "^0.4.0" + } + }, + "node_modules/passport-mailchimp/node_modules/pkginfo": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", + "integrity": "sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-oauth": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-oauth/-/passport-oauth-1.0.0.tgz", + "integrity": "sha512-4IZNVsZbN1dkBzmEbBqUxDG8oFOIK81jqdksE3HEb/vI3ib3FMjbiZZ6MTtooyYZzmKu0BfovjvT1pdGgIq+4Q==", + "dependencies": { + "passport-oauth1": "1.x.x", + "passport-oauth2": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-oauth1": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", + "integrity": "sha512-Sv2YWodC6jN12M/OXwmR4BIXeeIHjjbwYTQw4kS6tHK4zYzSEpxBgSJJnknBjICA5cj0ju3FSnG1XmHgIhYnLg==", + "dependencies": { + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "utils-merge": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, + "node_modules/passport-oauth2": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.6.1.tgz", + "integrity": "sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ==", + "dependencies": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/path-exists": { "version": "4.0.0", "dev": true, @@ -7536,6 +8792,11 @@ "node": ">=8" } }, + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" + }, "node_modules/picocolors": { "version": "1.0.0", "dev": true, @@ -7593,6 +8854,14 @@ "node": ">=8" } }, + "node_modules/pkginfo": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.3.tgz", + "integrity": "sha512-7W7wTrE/NsY8xv/DTGjwNIyNah81EQH0MWcTzrHL6pOpMocOGZc0Mbdz9aXxSrp+U0mSmkU8jrNCDCfUs3sOBg==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/pluralize": { "version": "8.0.0", "dev": true, @@ -7610,9 +8879,9 @@ } }, "node_modules/prettier": { - "version": "2.6.2", - "dev": true, - "license": "MIT", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "bin": { "prettier": "bin-prettier.js" }, @@ -7763,6 +9032,8 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -7777,8 +9048,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/quick-format-unescaped": { "version": "4.0.4", @@ -7981,8 +9251,9 @@ }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -8016,6 +9287,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -8031,7 +9304,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -8632,8 +9904,9 @@ }, "node_modules/symbol-observable": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10" } @@ -8905,9 +10178,10 @@ } }, "node_modules/ts-loader": { - "version": "9.3.0", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.3.1.tgz", + "integrity": "sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -8938,9 +10212,10 @@ } }, "node_modules/ts-node": { - "version": "10.8.0", + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", + "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", "dev": true, - "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -8987,6 +10262,48 @@ "node": ">=0.4.0" } }, + "node_modules/ts-poet": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-4.14.0.tgz", + "integrity": "sha512-hLGzWo3H3GLjVubftvaycGSconJrNpjjdpn43Lthnu61l/R2CaPIu+1JhaWZyqh2yj5NaOv+wZ5zoSJzDouAHw==", + "dependencies": { + "lodash": "^4.17.15", + "prettier": "^2.5.1" + } + }, + "node_modules/ts-proto": { + "version": "1.115.5", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.115.5.tgz", + "integrity": "sha512-JGk6hln3JP0T0wJlqIOUGE/qHDYcI547hrJwAzeLq1E2l7IdYnYiAJRsvJEOsvotIyZXMbHNlZedIZEVIPAspQ==", + "dependencies": { + "@types/object-hash": "^1.3.0", + "dataloader": "^1.4.0", + "object-hash": "^1.3.1", + "protobufjs": "^6.11.3", + "ts-poet": "^4.11.0", + "ts-proto-descriptors": "1.6.0" + }, + "bin": { + "protoc-gen-ts_proto": "protoc-gen-ts_proto" + } + }, + "node_modules/ts-proto-descriptors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-1.6.0.tgz", + "integrity": "sha512-Vrhue2Ti99us/o76mGy28nF3W/Uanl1/8detyJw2yyRwiBC5yxy+hEZqQ/ZX2PbZ1vyCpJ51A9L4PnCCnkBMTQ==", + "dependencies": { + "long": "^4.0.0", + "protobufjs": "^6.8.8" + } + }, + "node_modules/ts-proto/node_modules/object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "dev": true, @@ -9119,9 +10436,10 @@ } }, "node_modules/typescript": { - "version": "4.7.2", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9130,6 +10448,11 @@ "node": ">=4.2.0" } }, + "node_modules/uid2": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", + "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -9284,9 +10607,10 @@ } }, "node_modules/webpack": { - "version": "5.72.1", + "version": "5.73.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", + "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -9711,19 +11035,72 @@ } }, "@angular-devkit/schematics-cli": { - "version": "13.3.5", + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-13.3.6.tgz", + "integrity": "sha512-5tTuu9gbXM0bMk0sin4phmWA3U1Qz53zT/rpEfzQ/+c/s8CoqZ5N1qOnYtemRct3Jxsz1kn4TBpHeriR4r5hHg==", "dev": true, "requires": { - "@angular-devkit/core": "13.3.5", - "@angular-devkit/schematics": "13.3.5", + "@angular-devkit/core": "13.3.6", + "@angular-devkit/schematics": "13.3.6", "ansi-colors": "4.1.1", "inquirer": "8.2.0", "minimist": "1.2.6", "symbol-observable": "4.0.0" }, "dependencies": { + "@angular-devkit/core": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.6.tgz", + "integrity": "sha512-ZmD586B+RnM2CG5+jbXh2NVfIydTc/yKSjppYDDOv4I530YBm6vpfZMwClpiNk6XLbMv7KqX4Tlr4wfxlPYYbA==", + "dev": true, + "requires": { + "ajv": "8.9.0", + "ajv-formats": "2.1.1", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.7", + "source-map": "0.7.3" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } + } + }, + "@angular-devkit/schematics": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.6.tgz", + "integrity": "sha512-yLh5xc92C/FiaAp27coPiKWpSUmwoXF7vMxbJYJTyOXlt0mUITAEAwtrZQNr4yAxW/yvgTdyg7PhXaveQNTUuQ==", + "dev": true, + "requires": { + "@angular-devkit/core": "13.3.6", + "jsonc-parser": "3.0.0", + "magic-string": "0.25.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } + } + }, "chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -9732,6 +11109,8 @@ }, "inquirer": { "version": "8.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", + "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -9749,9 +11128,729 @@ "strip-ansi": "^6.0.0", "through": "^2.3.6" } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true } } }, + "@aws-crypto/ie11-detection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.0.tgz", + "integrity": "sha512-pkVXf/dq6PITJ0jzYZ69VhL8VFOFoPZLZqtU/12SGnzYuJOOGNfF41q9GxdI1yqC8R13Rq3jOLKDFpUJFT5eTA==", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/sha256-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz", + "integrity": "sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==", + "requires": { + "@aws-crypto/ie11-detection": "^2.0.0", + "@aws-crypto/sha256-js": "^2.0.0", + "@aws-crypto/supports-web-crypto": "^2.0.0", + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/sha256-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz", + "integrity": "sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==", + "requires": { + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/supports-web-crypto": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.0.tgz", + "integrity": "sha512-Ge7WQ3E0OC7FHYprsZV3h0QIcpdyJLvIeg+uTuHqRYm8D6qCFJoiC+edSzSyFiHtZf+NOQDJ1q46qxjtzIY2nA==", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.1.tgz", + "integrity": "sha512-JJmFFwvbm08lULw4Nm5QOLg8+lAQeC8aCXK5xrtxntYzYXCGfHwUJ4Is3770Q7HmICsXthGQ+ZsDL7C2uH3yBQ==", + "requires": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-sdk/abort-controller": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.110.0.tgz", + "integrity": "sha512-zok/WEVuK7Jh6V9YeA56pNZtxUASon9LTkS7vE65A4UFmNkPGNBCNgoiBcbhWfxwrZ8wtXcQk6rtUut39831mA==", + "requires": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/client-secrets-manager": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.118.1.tgz", + "integrity": "sha512-vKqjidFStTNVX9cw1xzGpP+1LlRszS7RXC9ZnlcolvQEWF/gL9nODXCEDrEoTzBmQuQ0XAxWzvEDGgRee/e2eQ==", + "requires": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/client-sts": "3.118.1", + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/credential-provider-node": "3.118.1", + "@aws-sdk/fetch-http-handler": "3.110.0", + "@aws-sdk/hash-node": "3.110.0", + "@aws-sdk/invalid-dependency": "3.110.0", + "@aws-sdk/middleware-content-length": "3.110.0", + "@aws-sdk/middleware-host-header": "3.110.0", + "@aws-sdk/middleware-logger": "3.110.0", + "@aws-sdk/middleware-recursion-detection": "3.110.0", + "@aws-sdk/middleware-retry": "3.118.1", + "@aws-sdk/middleware-serde": "3.110.0", + "@aws-sdk/middleware-signing": "3.110.0", + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/middleware-user-agent": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/node-http-handler": "3.118.1", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/smithy-client": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "@aws-sdk/util-base64-node": "3.55.0", + "@aws-sdk/util-body-length-browser": "3.55.0", + "@aws-sdk/util-body-length-node": "3.55.0", + "@aws-sdk/util-defaults-mode-browser": "3.110.0", + "@aws-sdk/util-defaults-mode-node": "3.110.0", + "@aws-sdk/util-user-agent-browser": "3.110.0", + "@aws-sdk/util-user-agent-node": "3.118.0", + "@aws-sdk/util-utf8-browser": "3.109.0", + "@aws-sdk/util-utf8-node": "3.109.0", + "tslib": "^2.3.1", + "uuid": "^8.3.2" + } + }, + "@aws-sdk/client-sso": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.118.1.tgz", + "integrity": "sha512-dvufBhoE+sVo2sB9+m39GaxmvCKskWLy2hqv+cqyh5poqSWlCZaliRJFpq/rwQm15lUfrHoD8b+NSNEUIVJf9w==", + "requires": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/fetch-http-handler": "3.110.0", + "@aws-sdk/hash-node": "3.110.0", + "@aws-sdk/invalid-dependency": "3.110.0", + "@aws-sdk/middleware-content-length": "3.110.0", + "@aws-sdk/middleware-host-header": "3.110.0", + "@aws-sdk/middleware-logger": "3.110.0", + "@aws-sdk/middleware-recursion-detection": "3.110.0", + "@aws-sdk/middleware-retry": "3.118.1", + "@aws-sdk/middleware-serde": "3.110.0", + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/middleware-user-agent": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/node-http-handler": "3.118.1", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/smithy-client": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "@aws-sdk/util-base64-node": "3.55.0", + "@aws-sdk/util-body-length-browser": "3.55.0", + "@aws-sdk/util-body-length-node": "3.55.0", + "@aws-sdk/util-defaults-mode-browser": "3.110.0", + "@aws-sdk/util-defaults-mode-node": "3.110.0", + "@aws-sdk/util-user-agent-browser": "3.110.0", + "@aws-sdk/util-user-agent-node": "3.118.0", + "@aws-sdk/util-utf8-browser": "3.109.0", + "@aws-sdk/util-utf8-node": "3.109.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/client-sts": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.118.1.tgz", + "integrity": "sha512-i144bIUf+KmKJp00g08V/QPOh4v0xDIO7IX7m7ngkDlttIWGg9lXDcWhiRU+j0z72uv48D9em3nibJdFCjZjrA==", + "requires": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/credential-provider-node": "3.118.1", + "@aws-sdk/fetch-http-handler": "3.110.0", + "@aws-sdk/hash-node": "3.110.0", + "@aws-sdk/invalid-dependency": "3.110.0", + "@aws-sdk/middleware-content-length": "3.110.0", + "@aws-sdk/middleware-host-header": "3.110.0", + "@aws-sdk/middleware-logger": "3.110.0", + "@aws-sdk/middleware-recursion-detection": "3.110.0", + "@aws-sdk/middleware-retry": "3.118.1", + "@aws-sdk/middleware-sdk-sts": "3.110.0", + "@aws-sdk/middleware-serde": "3.110.0", + "@aws-sdk/middleware-signing": "3.110.0", + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/middleware-user-agent": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/node-http-handler": "3.118.1", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/smithy-client": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "@aws-sdk/util-base64-node": "3.55.0", + "@aws-sdk/util-body-length-browser": "3.55.0", + "@aws-sdk/util-body-length-node": "3.55.0", + "@aws-sdk/util-defaults-mode-browser": "3.110.0", + "@aws-sdk/util-defaults-mode-node": "3.110.0", + "@aws-sdk/util-user-agent-browser": "3.110.0", + "@aws-sdk/util-user-agent-node": "3.118.0", + "@aws-sdk/util-utf8-browser": "3.109.0", + "@aws-sdk/util-utf8-node": "3.109.0", + "entities": "2.2.0", + "fast-xml-parser": "3.19.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/config-resolver": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.110.0.tgz", + "integrity": "sha512-7VvtKy4CL63BAktQ2vgsjhWDSXpkXO5YdiI56LQnHztrvSuJBBaxJ7R1p/k0b2tEUhYKUziAIW8EKE/7EGPR4g==", + "requires": { + "@aws-sdk/signature-v4": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-config-provider": "3.109.0", + "@aws-sdk/util-middleware": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-env": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.110.0.tgz", + "integrity": "sha512-oFU3IYk/Bl5tdsz1qigtm3I25a9cvXPqlE8VjYjxVDdLujF5zd/4HLbhP4GQWhpEwZmM1ijcSNfLcyywVevTZg==", + "requires": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-imds": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.110.0.tgz", + "integrity": "sha512-atl+7/dAB+8fG9XI2fYyCgXKYDbOzot65VAwis+14bOEUCVp7PCJifBEZ/L8GEq564p+Fa2p1IpV0wuQXxqFUQ==", + "requires": { + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/url-parser": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-ini": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.118.1.tgz", + "integrity": "sha512-Ri05NMc0T2BT7O/6iS+tVwwPtF4Y+BbJrAwoeGApYI9gJqrRSSJ1I2oSye2UV/Ty49n3NmZGtQ+LZJjXShVFSw==", + "requires": { + "@aws-sdk/credential-provider-env": "3.110.0", + "@aws-sdk/credential-provider-imds": "3.110.0", + "@aws-sdk/credential-provider-sso": "3.118.1", + "@aws-sdk/credential-provider-web-identity": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-node": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.118.1.tgz", + "integrity": "sha512-+DntbY0Foi5aIx1+6hNMUCSd2Oa109X6AJBdiUpwuRQu7+9wK0MBEzyi6Ap5QCa6/ThMQgq0PenR2Bwdl39fXw==", + "requires": { + "@aws-sdk/credential-provider-env": "3.110.0", + "@aws-sdk/credential-provider-imds": "3.110.0", + "@aws-sdk/credential-provider-ini": "3.118.1", + "@aws-sdk/credential-provider-process": "3.110.0", + "@aws-sdk/credential-provider-sso": "3.118.1", + "@aws-sdk/credential-provider-web-identity": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-process": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.110.0.tgz", + "integrity": "sha512-JJcZePvRTfQHYj/+EEY13yItnZH/e8exlARFUjN0L13UrgHpOJtDQBa+YBHXo6MbTFQh+re25z2kzc+zOYSMNQ==", + "requires": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-sso": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.118.1.tgz", + "integrity": "sha512-oycFvPBcmfO2WAz5GfLrfGg+HbYA090gnNw5YknMtWewujXkgZ18AMhBsyRw/+mlHpbcFv/w1Gq0RgeTGSssRg==", + "requires": { + "@aws-sdk/client-sso": "3.118.1", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-web-identity": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.110.0.tgz", + "integrity": "sha512-e4e5u7v3fsUFZsMcFMhMy1NdJBQpunYcLwpYlszm3OEICwTTekQ+hVvnVRd134doHvzepE4yp9sAop0Cj+IRVQ==", + "requires": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/fetch-http-handler": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.110.0.tgz", + "integrity": "sha512-vk+K4GeCZL2J2rtvKO+T0Q7i3MDpEGZBMg5K2tj9sMcEQwty0BF0aFnP7Eu2l4/Zif2z1mWuUFM2WcZI6DVnbw==", + "requires": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/querystring-builder": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-base64-browser": "3.109.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/hash-node": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.110.0.tgz", + "integrity": "sha512-wakl+kP2O8wTGYiQ3InZy+CVfGrIpFfq9fo4zif9PZac0BbUbguUU1dkY34uZiaf+4o2/9MoDYrHU2HYeXKxWw==", + "requires": { + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-buffer-from": "3.55.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/invalid-dependency": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.110.0.tgz", + "integrity": "sha512-O8J1InmtJkoiUMbQDtxBfOzgigBp9iSVsNXQrhs2qHh3826cJOfE7NGT3u+NMw73Pk5j2cfmOh1+7k/76IqxOg==", + "requires": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/is-array-buffer": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.55.0.tgz", + "integrity": "sha512-NbiPHVYuPxdqdFd6FxzzN3H1BQn/iWA3ri3Ry7AyLeP/tGs1yzEWMwf8BN8TSMALI0GXT6Sh0GDWy3Ok5xB6DA==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-content-length": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.110.0.tgz", + "integrity": "sha512-hKU+zdqfAJQg22LXMVu/z35nNIHrVAKpVKPe9+WYVdL/Z7JKUPK7QymqKGOyDuDbzW6OxyulC1zKGEX12zGmdA==", + "requires": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-host-header": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.110.0.tgz", + "integrity": "sha512-/Cknn1vL2LTlclI0MX2RzmtdPlCJ5palCRXxm/mod1oHwg4oNTKRlUX3LUD+L8g7JuJ4h053Ch9KS/A0vanE5Q==", + "requires": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-logger": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.110.0.tgz", + "integrity": "sha512-+pz+a+8dfTnzLj79nHrv3aONMp/N36/erMd+7JXeR84QEosVLrFBUwKA8x5x6O3s1iBbQzRKMYEIuja9xn1BPA==", + "requires": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-recursion-detection": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.110.0.tgz", + "integrity": "sha512-Wav782zd7bcd1e6txRob76CDOdVOaUQ8HXoywiIm/uFrEEUZvhs2mgnXjVUVCMBUehdNgnL99z420aS13JeL/Q==", + "requires": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-retry": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.118.1.tgz", + "integrity": "sha512-Dh0EgO3yPHEaRC6CVrofgAMdUQaG0Kkl466iVFHN5n5kExQvCtvpMHwO9N7kqaq9lXten3yhzboRNLIo98E1Kw==", + "requires": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/service-error-classification": "3.110.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-middleware": "3.110.0", + "tslib": "^2.3.1", + "uuid": "^8.3.2" + } + }, + "@aws-sdk/middleware-sdk-sts": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.110.0.tgz", + "integrity": "sha512-EjY/YFdlr5jECde6qIrTIyGBbn/34CKcQGKvmvRd31+3qaClIJLAwNuHfcVzWvCUGbAslsfvdbOpLju33pSQRA==", + "requires": { + "@aws-sdk/middleware-signing": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/signature-v4": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-serde": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.110.0.tgz", + "integrity": "sha512-brVupxgEAmcZ9cZvdHEH8zncjvGKIiud8pOe4fiimp5NpHmjBLew4jUbnOKNZNAjaidcKUtz//cxtutD6yXEww==", + "requires": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-signing": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.110.0.tgz", + "integrity": "sha512-y6ZKrGYfgDlFMzWhZmoq5J1UctBgZOUvMmnU9sSeZ020IlEPiOxFMvR0Zu6TcYThp8uy3P0wyjQtGYeTl9Z/kA==", + "requires": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/signature-v4": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-stack": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.110.0.tgz", + "integrity": "sha512-iaLHw6ctOuGa9UxNueU01Xes+15dR+mqioRpUOUZ9Zx+vhXVpD7C8lnNqhRnYeFXs10/rNIzASgsIrAHTlnlIQ==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-user-agent": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.110.0.tgz", + "integrity": "sha512-Y6FgiZr99DilYq6AjeaaWcNwVlSQpNGKrILzvV4Tmz03OaBIspe4KL+8EZ2YA/sAu5Lpw80vItdezqDOwGAlnQ==", + "requires": { + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/node-config-provider": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.110.0.tgz", + "integrity": "sha512-46p4dCPGYctuybTQTwLpjenA1QFHeyJw/OyggGbtUJUy+833+ldnAwcPVML2aXJKUKv3APGI8vq1kaloyNku3Q==", + "requires": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/shared-ini-file-loader": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/node-http-handler": { + "version": "3.118.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.118.1.tgz", + "integrity": "sha512-pfWVAUNJEs0UW0KkDqq2/VCz9PIpvg4mYEfCVZ4jR+Rv8F7UezNeM3FrEdHk8dfYShH+OV0hFskHBQJhw1BX2Q==", + "requires": { + "@aws-sdk/abort-controller": "3.110.0", + "@aws-sdk/protocol-http": "3.110.0", + "@aws-sdk/querystring-builder": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/property-provider": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.110.0.tgz", + "integrity": "sha512-7NkpmYeOkK3mhWBNU+/zSDqwzeaSPH1qrq4L//WV7WS/weYyE/jusQeZoOxVsuZQnQEXHt5O2hKVeUwShl12xA==", + "requires": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/protocol-http": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.110.0.tgz", + "integrity": "sha512-qdi2gCbJiyPyLn+afebPNp/5nVCRh1X7t7IRIFl3FHVEC+o54u/ojay/MLZ4M/+X9Fa4Zxsb0Wpp3T0xAHVDBg==", + "requires": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/querystring-builder": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.110.0.tgz", + "integrity": "sha512-7V3CDXj519izmbBn9ZE68ymASwGriA+Aq+cb/yHSVtffnvXjPtvONNw7G/5iVblisGLSCUe2hSvpYtcaXozbHw==", + "requires": { + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-uri-escape": "3.55.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/querystring-parser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.110.0.tgz", + "integrity": "sha512-//pJHH7hrhdDMZGBPKXKymmC/tJM7gFT0w/qbu/yd3Wm4W2fMB+8gkmj6EZctx7jrsWlfRQuvFejKqEfapur/g==", + "requires": { + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/service-error-classification": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.110.0.tgz", + "integrity": "sha512-ccgCE0pU/4RmXR6CP3fLAdhPAve7bK/yXBbGzpSHGAQOXqNxYzOsAvQ30Jg6X+qjLHsI/HR2pLIE65z4k6tynw==" + }, + "@aws-sdk/shared-ini-file-loader": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.110.0.tgz", + "integrity": "sha512-E1ERoqEoG206XNBYWCKLgHkzCbTxdpDEGbsLET2DnvjFsT0s9p2dPvVux3bYl7JVAhyGduE+qcqWk7MzhFCBNQ==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/signature-v4": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.110.0.tgz", + "integrity": "sha512-utxxdllOnmQDhbpipnFAbuQ4c2pwefZ+2hi48jKvQRULQ2PO4nxLmdZm6B0FXaTijbKsyO7GrMik+EZ6mi3ARQ==", + "requires": { + "@aws-sdk/is-array-buffer": "3.55.0", + "@aws-sdk/types": "3.110.0", + "@aws-sdk/util-hex-encoding": "3.109.0", + "@aws-sdk/util-middleware": "3.110.0", + "@aws-sdk/util-uri-escape": "3.55.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/smithy-client": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.110.0.tgz", + "integrity": "sha512-gNLYrmdAe/1hVF2Nv2LF4OkL1A0a1o708pEMZHzql9xP164omRDaLrGDhz9tH7tsJEgLz+Bf4E8nTuISeDwvGg==", + "requires": { + "@aws-sdk/middleware-stack": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.110.0.tgz", + "integrity": "sha512-dLVoqODU3laaqNFPyN1QLtlQnwX4gNPMXptEBIt/iJpuZf66IYJe6WCzVZGt4Zfa1CnUmrlA428AzdcA/KCr2A==" + }, + "@aws-sdk/url-parser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.110.0.tgz", + "integrity": "sha512-tILFB8/Q73yzgO0dErJNnELmmBszd0E6FucwAnG3hfDefjqCBe09Q/1yhu2aARXyRmZa4AKp0sWcdwIWHc8dnA==", + "requires": { + "@aws-sdk/querystring-parser": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-base64-browser": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.109.0.tgz", + "integrity": "sha512-lAZ6fyDGiRLaIsKT9qh7P9FGuNyZ4gAbr1YOSQk/5mHtaTuUvxlPptZuInNM/0MPQm6lpcot00D8IWTucn4PbA==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-base64-node": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.55.0.tgz", + "integrity": "sha512-UQ/ZuNoAc8CFMpSiRYmevaTsuRKzLwulZTnM8LNlIt9Wx1tpNvqp80cfvVj7yySKROtEi20wq29h31dZf1eYNQ==", + "requires": { + "@aws-sdk/util-buffer-from": "3.55.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-body-length-browser": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.55.0.tgz", + "integrity": "sha512-Ei2OCzXQw5N6ZkTMZbamUzc1z+z1R1Ja5tMEagz5BxuX4vWdBObT+uGlSzL8yvTbjoPjnxWA2aXyEqaUP3JS8Q==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-body-length-node": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.55.0.tgz", + "integrity": "sha512-lU1d4I+9wJwydduXs0SxSfd+mHKjxeyd39VwOv6i2KSwWkPbji9UQqpflKLKw+r45jL7+xU/zfeTUg5Tt/3Gew==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-buffer-from": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.55.0.tgz", + "integrity": "sha512-uVzKG1UgvnV7XX2FPTylBujYMKBPBaq/qFBxfl0LVNfrty7YjpfieQxAe6yRLD+T0Kir/WDQwGvYC+tOYG3IGA==", + "requires": { + "@aws-sdk/is-array-buffer": "3.55.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-config-provider": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.109.0.tgz", + "integrity": "sha512-GrAZl/aBv0A28LkyNyq8SPJ5fmViCwz80fWLMeWx/6q5AbivuILogjlWwEZSvZ9zrlHOcFC0+AnCa5pQrjaslw==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-defaults-mode-browser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.110.0.tgz", + "integrity": "sha512-Y2dcOOD20S3bv/IjUqpdKIiDt6995SXNG5Pu/LeSdXNyLCOIm9rX4gHTxl9fC1KK5M/gR9fGJ362f67WwqEEqw==", + "requires": { + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-defaults-mode-node": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.110.0.tgz", + "integrity": "sha512-Cr3Z5nyrw1KowjbW76xp8hkT/zJtYjAVZ9PS4l84KxIicbVvDOBpxG3yNddkuQcavmlH6G4wH9uM5DcnpKDncg==", + "requires": { + "@aws-sdk/config-resolver": "3.110.0", + "@aws-sdk/credential-provider-imds": "3.110.0", + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/property-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-hex-encoding": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.109.0.tgz", + "integrity": "sha512-s8CgTNrn3cLkrdiohfxLuOYPCanzvHn/aH5RW6DaMoeQiG5Hl9QUiP/WtdQ9QQx3xvpQFpmvxIaSBwSgFNLQxA==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-locate-window": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.55.0.tgz", + "integrity": "sha512-0sPmK2JaJE2BbTcnvybzob/VrFKCXKfN4CUKcvn0yGg/me7Bz+vtzQRB3Xp+YSx+7OtWxzv63wsvHoAnXvgxgg==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-middleware": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.110.0.tgz", + "integrity": "sha512-PTVWrI5fA9d5hHJs6RzX2dIS2jRQ3uW073Fm0BePpQeDdZrEk+S5KNwRhUtpN6sdSV45vm6S9rrjZUG51qwGmA==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-uri-escape": { + "version": "3.55.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.55.0.tgz", + "integrity": "sha512-mmdDLUpFCN2nkfwlLdOM54lTD528GiGSPN1qb8XtGLgZsJUmg3uJSFIN2lPeSbEwJB3NFjVas/rnQC48i7mV8w==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-user-agent-browser": { + "version": "3.110.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.110.0.tgz", + "integrity": "sha512-rNdhmHDMV5dNJctqlBWimkZLJRB+x03DB+61pm+SKSFk6gPIVIvc1WNXqDFphkiswT4vA13ZUkGHzt+N4+noQQ==", + "requires": { + "@aws-sdk/types": "3.110.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-user-agent-node": { + "version": "3.118.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.118.0.tgz", + "integrity": "sha512-7j21HNumxMkeUpgoMX8o3y66k+qMSEkCPCMGnoiiMtgfWX9SY0S/fLwR1nDBw8HI3NthRXfgWdAXUu8K3Kjp6g==", + "requires": { + "@aws-sdk/node-config-provider": "3.110.0", + "@aws-sdk/types": "3.110.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-utf8-browser": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.109.0.tgz", + "integrity": "sha512-FmcGSz0v7Bqpl1SE8G1Gc0CtDpug+rvqNCG/szn86JApD/f5x8oByjbEiAyTU2ZH2VevUntx6EW68ulHyH+x+w==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-utf8-node": { + "version": "3.109.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.109.0.tgz", + "integrity": "sha512-Ti/ZBdvz2eSTElsucjzNmzpyg2MwfD1rXmxD0hZuIF8bPON/0+sZYnWd5CbDw9kgmhy28dmKue086tbZ1G0iLQ==", + "requires": { + "@aws-sdk/util-buffer-from": "3.55.0", + "tslib": "^2.3.1" + } + }, "@babel/code-frame": { "version": "7.16.7", "dev": true, @@ -10185,12 +12284,14 @@ } }, "@grpc/proto-loader": { - "version": "0.6.12", + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", "requires": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", - "protobufjs": "^6.10.0", + "protobufjs": "^6.11.3", "yargs": "^16.2.0" } }, @@ -10524,12 +12625,14 @@ } }, "@nestjs/cli": { - "version": "8.2.6", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.8.tgz", + "integrity": "sha512-y5Imcw1EY0OxD3POAM7SLUB1rFdn5FjbfSsyJrokjKmXY+i6KcBdbRrv3Ox7aeJ4W7wXuckIXZEUlK6lC52dnA==", "dev": true, "requires": { - "@angular-devkit/core": "13.3.5", - "@angular-devkit/schematics": "13.3.5", - "@angular-devkit/schematics-cli": "13.3.5", + "@angular-devkit/core": "13.3.6", + "@angular-devkit/schematics": "13.3.6", + "@angular-devkit/schematics-cli": "13.3.6", "@nestjs/schematics": "^8.0.3", "chalk": "3.0.0", "chokidar": "3.5.3", @@ -10546,19 +12649,59 @@ "tree-kill": "1.2.2", "tsconfig-paths": "3.14.1", "tsconfig-paths-webpack-plugin": "3.5.2", - "typescript": "4.6.4", - "webpack": "5.72.1", + "typescript": "4.7.4", + "webpack": "5.73.0", "webpack-node-externals": "3.0.0" }, "dependencies": { - "typescript": { - "version": "4.6.4", + "@angular-devkit/core": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.6.tgz", + "integrity": "sha512-ZmD586B+RnM2CG5+jbXh2NVfIydTc/yKSjppYDDOv4I530YBm6vpfZMwClpiNk6XLbMv7KqX4Tlr4wfxlPYYbA==", + "dev": true, + "requires": { + "ajv": "8.9.0", + "ajv-formats": "2.1.1", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.7", + "source-map": "0.7.3" + } + }, + "@angular-devkit/schematics": { + "version": "13.3.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.6.tgz", + "integrity": "sha512-yLh5xc92C/FiaAp27coPiKWpSUmwoXF7vMxbJYJTyOXlt0mUITAEAwtrZQNr4yAxW/yvgTdyg7PhXaveQNTUuQ==", + "dev": true, + "requires": { + "@angular-devkit/core": "13.3.6", + "jsonc-parser": "3.0.0", + "magic-string": "0.25.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true } } }, "@nestjs/common": { - "version": "8.4.5", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-8.4.7.tgz", + "integrity": "sha512-m/YsbcBal+gA5CFrDpqXqsSfylo+DIQrkFY3qhVIltsYRfu8ct8J9pqsTO6OPf3mvqdOpFGrV5sBjoyAzOBvsw==", "requires": { "axios": "0.27.2", "iterare": "1.2.1", @@ -10598,7 +12741,9 @@ } }, "@nestjs/core": { - "version": "8.4.5", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-8.4.7.tgz", + "integrity": "sha512-XB9uexHqzr2xkPo6QSiQWJJttyYYLmvQ5My64cFvWFi7Wk2NIus0/xUNInwX3kmFWB6pF1ab5Y2ZBvWdPwGBhw==", "requires": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", @@ -10614,15 +12759,24 @@ "requires": {} }, "@nestjs/microservices": { - "version": "8.4.5", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-8.4.7.tgz", + "integrity": "sha512-JZX29tBWbbPa+Q06QcCbwKTyEsOFHAPrxgfEkRNwoaiEqqCsITT9w2n5bcz3vlUurdpy5dIgX3/almbitghbKg==", "requires": { "iterare": "1.2.1", - "json-socket": "0.3.0", "tslib": "2.4.0" } }, + "@nestjs/passport": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-8.2.2.tgz", + "integrity": "sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw==", + "requires": {} + }, "@nestjs/platform-express": { - "version": "8.4.5", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-8.4.7.tgz", + "integrity": "sha512-lPE5Ltg2NbQGRQIwXWY+4cNrXhJdycbxFDQ8mNxSIuv+LbrJBIdEB/NONk+LLn9N/8d2+I2LsIETGQrPvsejBg==", "requires": { "body-parser": "1.20.0", "cors": "2.8.5", @@ -10658,15 +12812,18 @@ } }, "@nestjs/testing": { - "version": "8.4.5", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.4.7.tgz", + "integrity": "sha512-aedpeJFicTBeiTCvJWUG45WMMS53f5eu8t2fXsfjsU1t+WdDJqYcZyrlCzA4dL1B7MfbqaTURdvuVVHTmJO8ag==", "dev": true, "requires": { - "optional": "0.1.4", "tslib": "2.4.0" } }, "@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", @@ -10675,10 +12832,14 @@ }, "@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", @@ -10925,13 +13086,79 @@ "version": "1.3.2", "dev": true }, + "@types/multer": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz", + "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/node": { - "version": "16.11.36" + "version": "16.11.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.41.tgz", + "integrity": "sha512-mqoYK2TnVjdkGk8qXAVGc/x9nSaTpSrFaGFm43BUH3IdoBV0nta6hYaGmdOvIMlbHJbUEVen3gvwpwovAZKNdQ==" + }, + "@types/oauth": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz", + "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/object-hash": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz", + "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==" }, "@types/parse-json": { "version": "4.0.0", "dev": true }, + "@types/passport": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.9.tgz", + "integrity": "sha512-9+ilzUhmZQR4JP49GdC2O4UdDE3POPLwpmaTC/iLkW7l0TZCXOo1zsTnnlXPq6rP1UsUZPfbAV4IUdiwiXyC7g==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/passport-facebook": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@types/passport-facebook/-/passport-facebook-2.1.11.tgz", + "integrity": "sha512-YsZUZryJvHt2E/WdR22FlnCi9ckMwkGR+FwCcXq830rOvruhXJHJtKSXSD+Kn4phBsrEpqoP4xX6fFuEodk20A==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/passport": "*" + } + }, + "@types/passport-google-oauth20": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.11.tgz", + "integrity": "sha512-9XMT1GfwhZL7UQEiCepLef55RNPHkbrCtsU7rsWPTEOsmu5qVIW8nSemtB4p+P24CuOhA+IKkv8LsPThYghGww==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/passport": "*", + "@types/passport-oauth2": "*" + } + }, + "@types/passport-oauth2": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.11.tgz", + "integrity": "sha512-KUNwmGhe/3xPbjkzkPwwcPmyFwfyiSgtV1qOrPBLaU4i4q9GSCdAOyCbkFG0gUxAyEmYwqo9OAF/rjPjJ6ImdA==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/oauth": "*", + "@types/passport": "*" + } + }, "@types/prettier": { "version": "2.6.3", "dev": true @@ -10983,12 +13210,14 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.0.tgz", + "integrity": "sha512-lvhRJ2pGe2V9MEU46ELTdiHgiAFZPKtLhiU5wlnaYpMc2+c1R8fh8i80ZAa665drvjHKUJyRRGg3gEm1If54ow==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.26.0", - "@typescript-eslint/type-utils": "5.26.0", - "@typescript-eslint/utils": "5.26.0", + "@typescript-eslint/scope-manager": "5.30.0", + "@typescript-eslint/type-utils": "5.30.0", + "@typescript-eslint/utils": "5.30.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -10998,42 +13227,52 @@ } }, "@typescript-eslint/parser": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.0.tgz", + "integrity": "sha512-2oYYUws5o2liX6SrFQ5RB88+PuRymaM2EU02/9Ppoyu70vllPnHVO7ioxDdq/ypXHA277R04SVjxvwI8HmZpzA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.26.0", - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/typescript-estree": "5.26.0", + "@typescript-eslint/scope-manager": "5.30.0", + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/typescript-estree": "5.30.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.0.tgz", + "integrity": "sha512-3TZxvlQcK5fhTBw5solQucWSJvonXf5yua5nx8OqK94hxdrT7/6W3/CS42MLd/f1BmlmmbGEgQcTHHCktUX5bQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/visitor-keys": "5.26.0" + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/visitor-keys": "5.30.0" } }, "@typescript-eslint/type-utils": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.0.tgz", + "integrity": "sha512-GF8JZbZqSS+azehzlv/lmQQ3EU3VfWYzCczdZjJRxSEeXDQkqFhCBgFhallLDbPwQOEQ4MHpiPfkjKk7zlmeNg==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.26.0", + "@typescript-eslint/utils": "5.30.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.0.tgz", + "integrity": "sha512-vfqcBrsRNWw/LBXyncMF/KrUTYYzzygCSsVqlZ1qGu1QtGs6vMkt3US0VNSQ05grXi5Yadp3qv5XZdYLjpp8ag==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.0.tgz", + "integrity": "sha512-hDEawogreZB4n1zoqcrrtg/wPyyiCxmhPLpZ6kmWfKF5M5G0clRLaEexpuWr31fZ42F96SlD/5xCt1bT5Qm4Nw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/visitor-keys": "5.26.0", + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/visitor-keys": "5.30.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -11042,22 +13281,26 @@ } }, "@typescript-eslint/utils": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-0bIgOgZflLKIcZsWvfklsaQTM3ZUbmtH0rJ1hKyV3raoUYyeZwcjQ8ZUJTzS7KnhNcsVT1Rxs7zeeMHEhGlltw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.26.0", - "@typescript-eslint/types": "5.26.0", - "@typescript-eslint/typescript-estree": "5.26.0", + "@typescript-eslint/scope-manager": "5.30.0", + "@typescript-eslint/types": "5.30.0", + "@typescript-eslint/typescript-estree": "5.30.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.26.0", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.0.tgz", + "integrity": "sha512-6WcIeRk2DQ3pHKxU1Ni0qMXJkjO/zLjBymlYBy/53qxe7yjEFSvzKLDToJjURUhSl2Fzhkl4SMXQoETauF74cw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.26.0", + "@typescript-eslint/types": "5.30.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -11069,6 +13312,15 @@ "rxjs": "^7.5.5" } }, + "@victorradael/protospack-v2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@victorradael/protospack-v2/-/protospack-v2-1.1.1.tgz", + "integrity": "sha512-K9SuHcCGa7wynbzTG1aVnODksajTKfr9+tDHw6qfFfPwBruJXv5HsbMMylizAg+HTgEr/D6h/L1PO05rygDJCw==", + "requires": { + "rxjs": "^7.5.5", + "ts-proto": "^1.112.2" + } + }, "@webassemblyjs/ast": { "version": "1.11.1", "dev": true, @@ -11284,6 +13536,8 @@ }, "ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-escapes": { @@ -11332,6 +13586,8 @@ }, "array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "asap": { @@ -11481,6 +13737,11 @@ "version": "1.5.1", "dev": true }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, "basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -11556,6 +13817,11 @@ } } }, + "bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + }, "brace-expansion": { "version": "1.1.11", "requires": { @@ -11943,6 +14209,11 @@ "whatwg-url": "^8.0.0" } }, + "dataloader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", + "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==" + }, "debug": { "version": "4.3.4", "requires": { @@ -12011,6 +14282,8 @@ }, "dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { "path-type": "^4.0.0" @@ -12212,6 +14485,11 @@ "tapable": "^2.2.0" } }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, "error-callsites": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/error-callsites/-/error-callsites-2.0.4.tgz", @@ -12339,7 +14617,9 @@ } }, "eslint": { - "version": "8.16.0", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.18.0.tgz", + "integrity": "sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==", "dev": true, "requires": { "@eslint/eslintrc": "^1.3.0", @@ -12610,6 +14890,8 @@ }, "fast-glob": { "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -12671,8 +14953,15 @@ "end-of-stream": "^1.4.1" } }, + "fast-xml-parser": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz", + "integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==" + }, "fastq": { "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -12938,6 +15227,8 @@ }, "globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -14019,9 +16310,6 @@ "version": "1.0.0", "dev": true }, - "json-socket": { - "version": "0.3.0" - }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "dev": true @@ -14160,10 +16448,6 @@ "lodash.once": { "version": "4.1.1" }, - "lodash.set": { - "version": "4.3.2", - "dev": true - }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -14292,6 +16576,8 @@ }, "merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "methods": { @@ -14399,12 +16685,14 @@ "integrity": "sha512-+I10J3wKNoKddNxn0CNpoZ3eTZuqxjNM3b1GImVx22+ePI+Y15P8g/j3WsbP0fhzzrFzrtjOAoq5NCCucswXOQ==" }, "nock": { - "version": "13.2.4", + "version": "13.2.7", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.7.tgz", + "integrity": "sha512-R6NUw7RIPtKwgK7jskuKoEi4VFMqIHtV2Uu9K/Uegc4TA5cqe+oNMYslZcUmnVNQCTG6wcSqUBaGTDd7sq5srg==", "dev": true, "requires": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", - "lodash.set": "^4.3.2", + "lodash": "^4.17.21", "propagate": "^2.0.0" } }, @@ -14459,6 +16747,11 @@ "version": "2.2.0", "dev": true }, + "oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" + }, "object-assign": { "version": "4.1.1" }, @@ -14534,10 +16827,6 @@ "mimic-fn": "^2.1.0" } }, - "optional": { - "version": "0.1.4", - "dev": true - }, "optional-js": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", @@ -14642,6 +16931,93 @@ "parseurl": { "version": "1.3.3" }, + "passport": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + } + }, + "passport-facebook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-3.0.0.tgz", + "integrity": "sha512-K/qNzuFsFISYAyC1Nma4qgY/12V3RSLFdFVsPKXiKZt434wOvthFW1p7zKa1iQihQMRhaWorVE1o3Vi1o+ZgeQ==", + "requires": { + "passport-oauth2": "1.x.x" + } + }, + "passport-google-oauth20": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", + "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==", + "requires": { + "passport-oauth2": "1.x.x" + } + }, + "passport-hubspot-oauth2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/passport-hubspot-oauth2/-/passport-hubspot-oauth2-1.0.3.tgz", + "integrity": "sha512-YQyZ9dMxyDJI4vHtq/FXKxEQx39EdODWkn7yp+y12FQBKUXEWN4p2XRO5znwTKyFc1ALwDgCGRxNnRpx7F7gZA==", + "requires": { + "passport-oauth": "~1.0.0", + "pkginfo": "0.2.x" + } + }, + "passport-mailchimp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/passport-mailchimp/-/passport-mailchimp-1.1.0.tgz", + "integrity": "sha512-drCP+TMv1hcFCZ8Nbjx2gzq4ovYyvGZzH8I9RiaVD5ArvaWL3BAf6KJsNMxoPPwZAZi5SX5NqbG46I+5cUzweg==", + "requires": { + "passport-oauth2": "^1.3.0", + "pkginfo": "^0.4.0" + }, + "dependencies": { + "pkginfo": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", + "integrity": "sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==" + } + } + }, + "passport-oauth": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-oauth/-/passport-oauth-1.0.0.tgz", + "integrity": "sha512-4IZNVsZbN1dkBzmEbBqUxDG8oFOIK81jqdksE3HEb/vI3ib3FMjbiZZ6MTtooyYZzmKu0BfovjvT1pdGgIq+4Q==", + "requires": { + "passport-oauth1": "1.x.x", + "passport-oauth2": "1.x.x" + } + }, + "passport-oauth1": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", + "integrity": "sha512-Sv2YWodC6jN12M/OXwmR4BIXeeIHjjbwYTQw4kS6tHK4zYzSEpxBgSJJnknBjICA5cj0ju3FSnG1XmHgIhYnLg==", + "requires": { + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "utils-merge": "1.x.x" + } + }, + "passport-oauth2": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.6.1.tgz", + "integrity": "sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ==", + "requires": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==" + }, "path-exists": { "version": "4.0.0", "dev": true @@ -14663,6 +17039,11 @@ "version": "4.0.0", "dev": true }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" + }, "picocolors": { "version": "1.0.0", "dev": true @@ -14701,6 +17082,11 @@ "find-up": "^4.0.0" } }, + "pkginfo": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.2.3.tgz", + "integrity": "sha512-7W7wTrE/NsY8xv/DTGjwNIyNah81EQH0MWcTzrHL6pOpMocOGZc0Mbdz9aXxSrp+U0mSmkU8jrNCDCfUs3sOBg==" + }, "pluralize": { "version": "8.0.0", "dev": true @@ -14710,8 +17096,9 @@ "dev": true }, "prettier": { - "version": "2.6.2", - "dev": true + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==" }, "prettier-linter-helpers": { "version": "1.0.0", @@ -14808,6 +17195,8 @@ }, "queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "quick-format-unescaped": { @@ -14947,6 +17336,8 @@ }, "reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rfdc": { @@ -14966,6 +17357,8 @@ }, "run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { "queue-microtask": "^1.2.2" @@ -15386,6 +17779,8 @@ }, "symbol-observable": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", "dev": true }, "symbol-tree": { @@ -15547,7 +17942,9 @@ } }, "ts-loader": { - "version": "9.3.0", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.3.1.tgz", + "integrity": "sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -15567,7 +17964,9 @@ } }, "ts-node": { - "version": "10.8.0", + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", + "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -15591,6 +17990,44 @@ } } }, + "ts-poet": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-4.14.0.tgz", + "integrity": "sha512-hLGzWo3H3GLjVubftvaycGSconJrNpjjdpn43Lthnu61l/R2CaPIu+1JhaWZyqh2yj5NaOv+wZ5zoSJzDouAHw==", + "requires": { + "lodash": "^4.17.15", + "prettier": "^2.5.1" + } + }, + "ts-proto": { + "version": "1.115.5", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.115.5.tgz", + "integrity": "sha512-JGk6hln3JP0T0wJlqIOUGE/qHDYcI547hrJwAzeLq1E2l7IdYnYiAJRsvJEOsvotIyZXMbHNlZedIZEVIPAspQ==", + "requires": { + "@types/object-hash": "^1.3.0", + "dataloader": "^1.4.0", + "object-hash": "^1.3.1", + "protobufjs": "^6.11.3", + "ts-poet": "^4.11.0", + "ts-proto-descriptors": "1.6.0" + }, + "dependencies": { + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" + } + } + }, + "ts-proto-descriptors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-1.6.0.tgz", + "integrity": "sha512-Vrhue2Ti99us/o76mGy28nF3W/Uanl1/8detyJw2yyRwiBC5yxy+hEZqQ/ZX2PbZ1vyCpJ51A9L4PnCCnkBMTQ==", + "requires": { + "long": "^4.0.0", + "protobufjs": "^6.8.8" + } + }, "tsconfig-paths": { "version": "3.14.1", "dev": true, @@ -15682,9 +18119,16 @@ } }, "typescript": { - "version": "4.7.2", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true }, + "uid2": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", + "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -15793,7 +18237,9 @@ "dev": true }, "webpack": { - "version": "5.72.1", + "version": "5.73.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", + "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", diff --git a/package.json b/package.json index 236952e..1d8f4c8 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "grpc-server-and-client-nestjs-micro-pattern", + "name": "maestro", "version": "0.0.0", "description": "", "author": "", @@ -24,56 +24,68 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { - "@grpc/grpc-js": "^1.5.10", - "@grpc/proto-loader": "^0.6.9", - "@nestjs/common": "^8.4.3", + "@aws-sdk/client-secrets-manager": "^3.112.0", + "@grpc/grpc-js": "^1.6.7", + "@grpc/proto-loader": "^0.6.13", + "@nestjs/common": "^8.4.7", "@nestjs/config": "^1.2.1", - "@nestjs/core": "^8.4.3", + "@nestjs/core": "^8.4.7", "@nestjs/mapped-types": "*", - "@nestjs/microservices": "^8.4.3", - "@nestjs/platform-express": "^8.4.3", + "@nestjs/microservices": "^8.4.7", + "@nestjs/passport": "^8.2.2", + "@nestjs/platform-express": "^8.4.7", "@nestjs/schedule": "^1.1.0", "@nestjs/swagger": "^5.2.1", "@victorradael/protospack": "2.5.0", + "@victorradael/protospack-v2": "1.1.1", "axios": "^0.25.0", "cron-parser": "^4.4.0", "dadosfera-logs": "^1.0.0-alpha.10", - "dotenv": "^14.2.0", "elastic-apm-node": "^3.36.0", - "helmet": "^5.0.2", + "dotenv": "^14.3.2", + "helmet": "^5.1.0", "jsonwebtoken": "^8.5.1", "jwk-to-pem": "^2.0.5", + "passport": "^0.6.0", + "passport-facebook": "^3.0.0", + "passport-google-oauth20": "^2.0.0", + "passport-hubspot-oauth2": "^1.0.3", + "passport-mailchimp": "^1.1.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.5.5", - "swagger-ui-express": "^4.3.0" + "swagger-ui-express": "^4.4.0" }, "overrides": { "multer": "1.4.5-lts.1" }, "devDependencies": { - "@nestjs/cli": "^8.2.4", - "@nestjs/schematics": "^8.0.8", - "@nestjs/testing": "^8.4.3", + "@nestjs/cli": "^8.2.8", + "@nestjs/schematics": "^8.0.11", + "@nestjs/testing": "^8.4.7", "@types/express": "^4.17.13", "@types/jest": "27.0.2", "@types/jsonwebtoken": "^8.5.8", "@types/jwk-to-pem": "^2.0.1", - "@types/node": "^16.11.26", + "@types/node": "^16.11.41", + "@types/passport-facebook": "^2.1.11", + "@types/passport-google-oauth20": "^2.0.11", + "@types/passport-oauth2": "^1.4.11", + "@types/multer": "^1.4.7", "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^5.17.0", - "@typescript-eslint/parser": "^5.17.0", - "eslint": "^8.12.0", + "@typescript-eslint/eslint-plugin": "^5.29.0", + "@typescript-eslint/parser": "^5.29.0", + "eslint": "^8.18.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^27.5.1", - "nock": "^13.2.4", - "prettier": "^2.6.1", + "nock": "^13.2.7", + "prettier": "^2.7.1", "source-map-support": "^0.5.20", - "supertest": "^6.1.3", - "ts-jest": "^27.1.4", - "ts-loader": "^9.2.7", - "ts-node": "^10.7.0", + "supertest": "^6.2.3", + "ts-jest": "^27.1.5", + "ts-loader": "^9.3.1", + "ts-node": "^10.8.1", "tsconfig-paths": "^3.14.1", "typescript": "^4.6.3" }, diff --git a/src/app.module.ts b/src/app.module.ts index ed4e039..f418d7c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,10 +1,8 @@ -import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; +import { Module } from '@nestjs/common'; import { ClientsModule } from '@nestjs/microservices'; import { ConfigModule } from '@nestjs/config'; import { DadosferaLogger } from 'dadosfera-logs'; -import { LoggerMiddleware } from './middlewares/authentication'; - import { InputsController } from './modules/inputs/inputs.controller'; import { TransformationsController } from './modules/transformations/transformations.controller'; import { OutputsController } from './modules/outputs/outputs.controllers'; @@ -16,28 +14,40 @@ import { InputsService } from './modules/inputs/inputs.service'; import { TransformationsService } from './modules/transformations/transformations.service'; import { OutputsService } from './modules/outputs/outputs.service'; import { PipelinesService } from './modules/pipelines/pipelines.service'; -// import { AuthService } from './modules/auth/auth.service'; import { HealthService } from './modules/health/health.service'; +import { AuthClientService } from './clients/auth/client.service'; import { InputsClientService } from './clients/inputs/client.service'; import { TransformationsClientService } from './clients/transformations/client.service'; import { OutputsClientService } from './clients/outputs/client.service'; import { PipelinesClientService } from './clients/pipelines/client.service'; -import { AuthClientService } from './clients/auth/client.service'; +import { PermissionsClientService } from './clients/permissions/client.service'; import { OutputsClientConfiguration } from './clients/outputs/client.config'; import { TransformationsClientConfiguration } from './clients/transformations/client.config'; -import { AuthClient } from './clients/auth/client.config'; +import { DucClient } from './clients/duc/client.config'; import { InputsClientConfiguration } from './clients/inputs/client.config'; import { PipelinesClientConfiguration } from './clients/pipelines/client.config'; import { CatalogController } from './modules/catalog/catalog.controller'; import { CatalogService } from './modules/catalog/catalog.service'; +import { OauthController } from './modules/oauth/oauth.controller'; +import { getOauthSecrets } from './utils/OauthSecrets'; +import { HubspotStrategy } from './modules/oauth/passport-strategies/hubspot-strategy'; +import { FacebookStrategy } from './modules/oauth/passport-strategies/facebook-strategy'; +import { AuthenticationGuard } from './authentication/authentication.guard'; +import { APP_GUARD } from '@nestjs/core'; +import { GoogleStrategy } from './modules/oauth/passport-strategies/google-strategy'; +import { MailChimpStrategy } from './modules/oauth/passport-strategies/mailchimp-strategy'; +import { ConnectorClientConfiguration } from './clients/connector/client.config'; +import { ConnectorController } from './modules/connector/connector.controller'; +import { ConnectorClientService } from './clients/connector/client.service'; -const authClient = new AuthClient(); +const ducClient = new DucClient(); const inputClient = new InputsClientConfiguration(); const outputClient = new OutputsClientConfiguration(); const pipelineClient = new PipelinesClientConfiguration(); const transformationClient = new TransformationsClientConfiguration(); +const connectorClient = new ConnectorClientConfiguration(); @Module({ controllers: [ @@ -48,21 +58,37 @@ const transformationClient = new TransformationsClientConfiguration(); AuthController, HealthController, CatalogController, + OauthController, + ConnectorController, ], providers: [ DadosferaLogger, + { provide: 'OAUTH_SECRETS', useValue: getOauthSecrets() }, InputsService, TransformationsService, OutputsService, PipelinesService, - // AuthService, + ConnectorClientService, HealthService, InputsClientService, TransformationsClientService, OutputsClientService, PipelinesClientService, AuthClientService, + PermissionsClientService, CatalogService, + { + provide: APP_GUARD, + useClass: AuthenticationGuard, + }, + HubspotStrategy, + FacebookStrategy, + GoogleStrategy, + MailChimpStrategy, + { + provide: APP_GUARD, + useClass: AuthenticationGuard, + }, ], imports: [ ConfigModule.forRoot({ @@ -74,7 +100,6 @@ const transformationClient = new TransformationsClientConfiguration(); name: 'INPUTS_PACKAGE', ...inputClient.config(), }, - { name: 'TRANSFORMATIONS_PACKAGE', ...transformationClient.config(), @@ -84,26 +109,18 @@ const transformationClient = new TransformationsClientConfiguration(); ...outputClient.config(), }, { - name: 'AUTH_PACKAGE', - ...authClient.config(), + name: 'DUC_PACKAGE', + ...ducClient.config(), }, { name: 'PIPELINES_PACKAGE', ...pipelineClient.config(), }, + { + name: 'CONNECTOR_PACKAGE', + ...connectorClient.config(), + }, ]), ], }) -export class AppModule implements NestModule { - configure(consumer: MiddlewareConsumer) { - consumer - .apply(LoggerMiddleware) - .forRoutes( - InputsController, - TransformationsController, - OutputsController, - PipelinesController, - CatalogController, - ); - } -} +export class AppModule {} diff --git a/src/authentication/authentication.decorator.ts b/src/authentication/authentication.decorator.ts new file mode 100644 index 0000000..e840f54 --- /dev/null +++ b/src/authentication/authentication.decorator.ts @@ -0,0 +1,28 @@ +import { SetMetadata, applyDecorators } from '@nestjs/common'; +import { Request } from 'express'; +import { Permission } from './permissions.enum'; + +export const PERMISSIONS_KEY = '__PERMISSIONS__'; +export const MUST_BE_AUTHENTICATED_KEY = '__MUST_BE_AUTHENTICATED__'; +export const CUSTOM_AUTHENTICATION_FUNCTION_KEY = + '__CUSTOM_AUTHENTICATION_FUNCTION__'; + +export type AuthenticationFunction = (req: Request, user: any) => boolean; + +export function RequirePermissions(...permissions: Permission[]) { + return applyDecorators( + SetMetadata(PERMISSIONS_KEY, permissions), + SetMetadata(MUST_BE_AUTHENTICATED_KEY, true), + ); +} + +export function AuthenticateCondition(func: AuthenticationFunction) { + return applyDecorators( + SetMetadata(CUSTOM_AUTHENTICATION_FUNCTION_KEY, func), + SetMetadata(MUST_BE_AUTHENTICATED_KEY, true), + ); +} + +export function Authenticated() { + return SetMetadata(MUST_BE_AUTHENTICATED_KEY, true); +} diff --git a/src/authentication/authentication.guard.ts b/src/authentication/authentication.guard.ts new file mode 100644 index 0000000..00edbd6 --- /dev/null +++ b/src/authentication/authentication.guard.ts @@ -0,0 +1,162 @@ +import { + Injectable, + CanActivate, + OnApplicationBootstrap, + ExecutionContext, + Logger, +} from '@nestjs/common'; +import { Reflector } from '@nestjs/core'; +import assert from 'assert'; +import jwt from 'jsonwebtoken'; + +import { AuthClientService } from '../clients/auth/client.service'; +import { Permission } from './permissions.enum'; +import { + AuthenticationFunction, + PERMISSIONS_KEY, + CUSTOM_AUTHENTICATION_FUNCTION_KEY, + MUST_BE_AUTHENTICATED_KEY, +} from './authentication.decorator'; +import ErrorBuilder from '../utils/ErrorBuilder'; +import ErrorCodes from '../utils/errorCodes'; + +@Injectable() +export class AuthenticationGuard + implements CanActivate, OnApplicationBootstrap +{ + private readonly logger = new Logger(AuthenticationGuard.name); + + pems: Map; + + constructor( + private reflector: Reflector, + private authClient: AuthClientService, + ) { + this.pems = new Map(); + } + + async onApplicationBootstrap() { + return this.loadDucJWKS(); + } + + async loadDucJWKS() { + const { keys } = await this.authClient.getPublicKeys(); + + keys.forEach((key) => { + this.pems.set(key.kid, key.pem); + }); + } + + canActivate(ctx: ExecutionContext): boolean { + const requiredPermissions = this.reflector.getAllAndOverride( + PERMISSIONS_KEY, + [ctx.getHandler(), ctx.getClass()], + ); + const customAuthenticationFunction = + this.reflector.getAllAndOverride( + CUSTOM_AUTHENTICATION_FUNCTION_KEY, + [ctx.getHandler(), ctx.getClass()], + ); + const mustBeAuthenticated = this.reflector.getAllAndOverride( + MUST_BE_AUTHENTICATED_KEY, + [ctx.getHandler(), ctx.getClass()], + ); + + const request = ctx.switchToHttp().getRequest(); + const accessToken = this.verifyToken(request, mustBeAuthenticated); + + if (!accessToken) { + // couldn't load valid token + + if (!mustBeAuthenticated) { + // no need to be authenticated + return true; + } + + throw new ErrorBuilder(ErrorCodes.AUTH.UNAUTHORIZED); + } + + if ( + typeof customAuthenticationFunction === 'function' && + !customAuthenticationFunction(request, request.user) + ) { + // custom authentication function forbidden this request + throw new ErrorBuilder(ErrorCodes.AUTH.FORBIDDEN); + } + + if ( + Array.isArray(requiredPermissions) && + requiredPermissions.length > 0 && + !this.matchPermissions(requiredPermissions, accessToken.permissions) + ) { + // couldn't match permissions + throw new ErrorBuilder(ErrorCodes.AUTH.FORBIDDEN); + } + + return true; + } + + private verifyToken(request, mustBeAuthenticated: boolean) { + const accessToken = request.get('Authorization'); + let accessTokenPayload; + + // If the user isn't authenticated, an error will occurr anywhere here. + // Fancy error avoidance isn't performed by purpose, such as avoiding to access null values. + try { + const accessTokenDecoded: any = jwt.decode(accessToken, { + complete: true, + }); + + /*assert( + accessTokenDecoded.payload.iss === 'duc', + 'token should be issued by DUC', + );*/ + + assert( + accessTokenDecoded.payload.token_use === 'access', + 'should be an access token', + ); + + const { kid } = accessTokenDecoded.header; + const pemValue: string = this.pems.get(kid); + + jwt.verify(accessToken, pemValue); + accessTokenPayload = accessTokenDecoded.payload; + } catch (err) { + // log errors if authentication is required + if (mustBeAuthenticated) { + this.logger.log('Unable to verify duc access token\n' + err.stack); + } + + return false; + } + + request.accessTokenPayload = accessTokenPayload; + request.user = { + user_id: accessTokenPayload.user_id, + username: accessTokenPayload.username, + permissions: accessTokenPayload.permissions, + customer_id: accessTokenPayload.customer_id, + customer_name: accessTokenPayload.customer_name, + customer_tier: accessTokenPayload.customer_tier, + }; + // TODO: for backwards compatibility. remove in the future + request.body.info = { + user_id: accessTokenPayload.user_id, + customer_id: accessTokenPayload.customer_id, + customer: accessTokenPayload.customer_name, + customer_tier: accessTokenPayload.customer_tier, + }; + + return accessTokenPayload; + } + + private matchPermissions( + requiredPermissions: Permission[], + userPermissions: number[], + ) { + return requiredPermissions.some((permission) => + userPermissions.includes(permission.seqid), + ); + } +} diff --git a/src/authentication/permissions.enum.ts b/src/authentication/permissions.enum.ts new file mode 100644 index 0000000..2c8a47d --- /dev/null +++ b/src/authentication/permissions.enum.ts @@ -0,0 +1,244 @@ +import { Logger } from '@nestjs/common'; +import assert from 'assert'; + +const logger = new Logger(); + +export enum PermissionUsages { + PUBLIC = 'public', + INTERNAL = 'internal', +} + +export interface Permission { + seqid: number; + claim: string; + usage: PermissionUsages; +} + +/* +- like field numbers in gRPC, avoid to change (or reuse previously used) seqids once its deployed to DUC +- it is possible to update claim and usage, not seqid +*/ + +/*export const Permissions: { + [P in keyof any]: { [Q in keyof any]: Permission }; +} = {*/ +export const Permissions = { + AUTH: { + CREATE: { + seqid: 18, + claim: 'POST /auth', + usage: PermissionUsages.PUBLIC, + }, + }, + + PIPELINE: { + CREATE: { + seqid: 23, + claim: 'POST /pipelines', + usage: PermissionUsages.PUBLIC, + }, + GET: { + seqid: 13, + claim: 'GET /pipelines', + usage: PermissionUsages.PUBLIC, + }, + UPDATE: { + seqid: 29, + claim: 'PUT /pipelines', + usage: PermissionUsages.PUBLIC, + }, + DELETE: { + seqid: 5, + claim: 'DELETE /pipelines', + usage: PermissionUsages.PUBLIC, + }, + }, + + INPUT: { + CREATE: { + seqid: 21, + claim: 'POST /inputs', + usage: PermissionUsages.PUBLIC, + }, + GET: { + seqid: 9, + claim: 'GET /inputs', + usage: PermissionUsages.PUBLIC, + }, + UPDATE: { + seqid: 27, + claim: 'PUT /inputs', + usage: PermissionUsages.PUBLIC, + }, + UPDATE_PARTIAL: { + seqid: 17, + claim: 'PATCH /inputs', + usage: PermissionUsages.PUBLIC, + }, + DELETE: { + seqid: 3, + claim: 'DELETE /inputs', + usage: PermissionUsages.PUBLIC, + }, + GET_ENTITIES: { + seqid: 10, + claim: 'GET /inputs/available-entities', + usage: PermissionUsages.PUBLIC, + }, + }, + + OUTPUT: { + CREATE: { + seqid: 22, + claim: 'POST /outputs', + usage: PermissionUsages.PUBLIC, + }, + GET: { + seqid: 12, + claim: 'GET /outputs', + usage: PermissionUsages.PUBLIC, + }, + UPDATE: { + seqid: 28, + claim: 'PUT /outputs', + usage: PermissionUsages.PUBLIC, + }, + DELETE: { + seqid: 4, + claim: 'DELETE /outputs', + usage: PermissionUsages.PUBLIC, + }, + }, + + TRANSFORMATIONS: { + CREATE: { + seqid: 24, + claim: 'POST /transformations', + usage: PermissionUsages.PUBLIC, + }, + GET: { + seqid: 15, + claim: 'GET /transformations', + usage: PermissionUsages.PUBLIC, + }, + UPDATE: { + seqid: 30, + claim: 'PUT /transformations', + usage: PermissionUsages.PUBLIC, + }, + DELETE: { + seqid: 6, + claim: 'DELETE /transformations', + usage: PermissionUsages.PUBLIC, + }, + }, + + CATALOG: { + CREATE: { + seqid: 19, + claim: 'POST /catalog', + usage: PermissionUsages.PUBLIC, + }, + GET: { + seqid: 7, + claim: 'GET /catalog', + usage: PermissionUsages.PUBLIC, + }, + UPDATE: { + seqid: 25, + claim: 'PUT /catalog', + usage: PermissionUsages.PUBLIC, + }, + DELETE: { + seqid: 1, + claim: 'DELETE /catalog', + usage: PermissionUsages.PUBLIC, + }, + }, + + CONNECTORS: { + CREATE: { + seqid: 20, + claim: 'POST /connectors', + usage: PermissionUsages.PUBLIC, + }, + GET: { + seqid: 8, + claim: 'GET /connectors', + usage: PermissionUsages.PUBLIC, + }, + UPDATE: { + seqid: 26, + claim: 'PUT /connectors', + usage: PermissionUsages.PUBLIC, + }, + DELETE: { + seqid: 2, + claim: 'DELETE /connectors', + usage: PermissionUsages.PUBLIC, + }, + }, + + SNOWFLAKE: { + OPEN: { + seqid: 14, + claim: 'GET /snowflake', + usage: PermissionUsages.PUBLIC, + }, + }, + + ZENDESK: { + OPEN: { + seqid: 16, + claim: 'GET /zendesk', + usage: PermissionUsages.PUBLIC, + }, + }, + + METABASE: { + OPEN: { + seqid: 11, + claim: 'GET /metabase', + usage: PermissionUsages.PUBLIC, + }, + }, + + ORCHEST: { + INTELLIGENCE: { + seqid: 31, + claim: 'intelligence:open', + usage: PermissionUsages.PUBLIC, + }, + APP_BUILDER: { + seqid: 32, + claim: 'app-builder:open', + usage: PermissionUsages.PUBLIC, + }, + MACHINE_LEARNING: { + seqid: 33, + claim: 'machine-learning:open', + usage: PermissionUsages.PUBLIC, + }, + }, +}; + +// traverses the object searching for duplicate seqids or claims (executes at runtime) +let nextAvailableSeqid = 0; +const seqids = Object.values(Permissions).flatMap((namespace) => + Object.values(namespace).map(({ seqid }) => seqid), +); +const claims = Object.values(Permissions).flatMap((namespace) => + Object.values(namespace).map(({ claim }) => claim), +); +Object.values(Permissions).map((namespace) => + Object.values(namespace).map(({ seqid, claim }) => { + const seqidsCount = seqids.filter((x) => x === seqid).length; + assert(seqidsCount === 1, `seqid ${seqid} count is not 1`); + + const claimsCount = claims.filter((x) => x === claim).length; + assert(claimsCount === 1, `claim '${claim}' count is not 1`); + nextAvailableSeqid = Math.max(nextAvailableSeqid, seqid); + }), +); + +logger.log(`next available seqid ${nextAvailableSeqid + 1}`); diff --git a/src/authentication/user.decorator.ts b/src/authentication/user.decorator.ts new file mode 100644 index 0000000..d5fe984 --- /dev/null +++ b/src/authentication/user.decorator.ts @@ -0,0 +1,23 @@ +import { createParamDecorator, ExecutionContext } from '@nestjs/common'; + +import ErrorBuilder from '../utils/ErrorBuilder'; +import ErrorCodes from '../utils/errorCodes'; + +export interface RequestUser { + user_id: string; + username: string; + permissions: string; + customer_id: string; + customer_name: string; + customer_tier: string; +} + +export const User = createParamDecorator((data: any, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest(); + + if (!request.user && data?.required) { + throw new ErrorBuilder(ErrorCodes.AUTH.UNAUTHORIZED); + } + + return request.user; +}); diff --git a/src/clients/auth/client.service.ts b/src/clients/auth/client.service.ts index e73da86..d4bac16 100644 --- a/src/clients/auth/client.service.ts +++ b/src/clients/auth/client.service.ts @@ -1,374 +1,151 @@ -import { OnModuleInit, Inject } from '@nestjs/common'; +import { Logger, OnModuleInit, Inject } from '@nestjs/common'; import { ClientGrpc } from '@nestjs/microservices'; import { DadosferaLogger } from 'dadosfera-logs'; +import { ProtoServices } from '@victorradael/protospack-v2/dist/lib/Duc'; +import { AuthProtoService as AuthServiceInterface } from '@victorradael/protospack-v2/dist/lib/Duc/interfaces/write-service'; import { - DucServicesNames, - AuthServiceInterface, + AuthGetPublicKeysResponse, AuthSignInRequest, + AuthSignInResponse, AuthRefreshAccessTokenRequest, - AuthConfirmationRequest, - AuthResendConfirmationCodeRequest, + AuthRefreshAccessTokenResponse, AuthEnableTotpMfaRequest, + AuthEnableTotpMfaResponse, AuthDisableTotpMfaRequest, + AuthDisableTotpMfaResponse, AuthDismissTotpMfaRequest, + AuthDismissTotpMfaResponse, AuthVerifyTotpMfaRequest, + AuthVerifyTotpMfaResponse, AuthChangePasswordRequest, + AuthChangePasswordResponse, AuthResetPasswordRequest, + AuthResetPasswordResponse, AuthVerifyResetPasswordCodeRequest, + AuthVerifyResetPasswordCodeResponse, AuthConfirmResetPasswordRequest, -} from '@victorradael/protospack'; + AuthConfirmResetPasswordResponse, +} from '@victorradael/protospack-v2/dist/lib/Duc/interfaces/messages'; + +import grpcHandler from '../../utils/grpcHandler'; export class AuthClientService implements OnModuleInit { + private readonly logger = new Logger(AuthClientService.name); + private authService: AuthServiceInterface; - logger: any; - constructor( - @Inject(DadosferaLogger) - dadosferaLogger: DadosferaLogger, - @Inject('AUTH_PACKAGE') private readonly grpcClient: ClientGrpc, - ) { - this.logger = dadosferaLogger.logger; - } + constructor(@Inject('DUC_PACKAGE') private readonly grpcClient: ClientGrpc) {} onModuleInit() { this.authService = this.grpcClient.getService( - DucServicesNames.AuthProtoService, + ProtoServices.AuthProtoService, ); } - async signIn({ username, password, totp }: AuthSignInRequest): Promise { - this.logger.info('AuthClientService - SignIn'); + async getPublicKeys() { + this.logger.log('GetPublicKeys'); - const signInResponse = await new Promise((resolve, reject) => { - this.authService.signIn({ username, password, totp }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - return signInResponse; + return grpcHandler( + this.authService.AuthGetPublicKeys({}), + ); } - async enableTotpMFA({ - accessToken, - password, - }: AuthEnableTotpMfaRequest): Promise { - this.logger.info('AuthClientService - enableTotpMFA'); + async signIn({ username, password, totp }: AuthSignInRequest) { + this.logger.log('SignIn'); - const enableTotpMFAResponse = await new Promise((resolve, reject) => { - this.authService.enableTotpMfa({ accessToken, password }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return enableTotpMFAResponse; + return grpcHandler( + this.authService.AuthSignIn({ username, password, totp }), + ); } - async disableTotpMFA({ - accessToken, - password, - }: AuthDisableTotpMfaRequest): Promise { - this.logger.info('AuthClientService - disableTotpMFA'); + async refreshAccessToken({ refreshToken }: AuthRefreshAccessTokenRequest) { + this.logger.log('RefreshAccessToken'); - const disableTotpMFAResponse = await new Promise((resolve, reject) => { - this.authService.disableTotpMfa({ accessToken, password }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return disableTotpMFAResponse; - } - - async dismissTotpMFA({ - accessToken, - }: AuthDismissTotpMfaRequest): Promise { - this.logger.info('AuthClientService - dismissTotpMFA'); - - const dismissTotpMFAResponse = await new Promise((resolve, reject) => { - this.authService.dismissTotpMfa({ accessToken }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return dismissTotpMFAResponse; - } - - async verifyTotp({ - accessToken, - totp, - }: AuthVerifyTotpMfaRequest): Promise { - this.logger.info('AuthClientService - disableTotpMFA'); - - const verifyTotpResponse = await new Promise((resolve, reject) => { - this.authService.verifyTotp({ accessToken, totp }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return verifyTotpResponse; - } - - async confirmRegister({ - username, - code, - }: AuthConfirmationRequest): Promise { - this.logger.info('AuthClientService - confirmRegister'); - - const tokens = await new Promise((resolve, reject) => { - this.authService.confirmRegister({ username, code }).subscribe({ - next(x) { - resolve(x); - }, - error(err) { - reject(err); - }, - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - return tokens; - } - - async resendeConfirmationCode({ - username, - }: AuthResendConfirmationCodeRequest): Promise { - this.logger.info('AuthClientService - resendConfirmationCode'); - - const authResendConfirmationCodeRequestReturn = await new Promise( - (resolve, reject) => { - this.authService.resendConfirmationCode({ username }).subscribe({ - next(x) { - resolve(x); - }, - error(err) { - reject(err); - }, - complete() { - //console.log('done'); - }, - }); - }, - ) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - return authResendConfirmationCodeRequestReturn; - } - - async refreshAccessToken({ - refreshToken, - }: AuthRefreshAccessTokenRequest): Promise { - this.logger.info('AuthClientService - RefreshAccessToken'); - - const refreshAccessTokenResponse = await new Promise((resolve, reject) => { - this.authService.refreshAccessToken({ refreshToken }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return refreshAccessTokenResponse; + return grpcHandler( + this.authService.AuthRefreshAccessToken({ refreshToken }), + ); } async changePassword({ accessToken, oldPassword, newPassword, - }: AuthChangePasswordRequest): Promise { - this.logger.info('AuthClientService - ChangePassword'); + }: AuthChangePasswordRequest) { + this.logger.log('ChangePassword'); - const changePasswordResponse = await new Promise((resolve, reject) => { - this.authService - .changePassword({ - accessToken, - oldPassword, - newPassword, - }) - .subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return changePasswordResponse; + return grpcHandler( + this.authService.AuthChangePassword({ + accessToken, + oldPassword, + newPassword, + }), + ); } - async resetPassword({ username }: AuthResetPasswordRequest): Promise { - this.logger.info('AuthClientService - resetPassword'); + async resetPassword({ username }: AuthResetPasswordRequest) { + this.logger.log('resetPassword'); - const resetPasswordResponse = await new Promise((resolve, reject) => { - this.authService.resetPassword({ username }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return resetPasswordResponse; + return grpcHandler( + this.authService.AuthResetPassword({ username }), + ); } async verifyResetPasswordCode({ username, code, - }: AuthVerifyResetPasswordCodeRequest): Promise { - this.logger.info('AuthClientService - verifyResetPasswordCode'); + }: AuthVerifyResetPasswordCodeRequest) { + this.logger.log('verifyResetPasswordCode'); - const verifyResetPasswordCodeResponse = await new Promise( - (resolve, reject) => { - this.authService.verifyResetPasswordCode({ username, code }).subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - //console.log('done'); - }, - }); - }, - ) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); - - return verifyResetPasswordCodeResponse; + return grpcHandler( + this.authService.AuthVerifyResetPasswordCode({ username, code }), + ); } async confirmResetPassword({ username, code, newPassword, - }: AuthConfirmResetPasswordRequest): Promise { - this.logger.info('AuthClientService - confirmResetPassword'); + }: AuthConfirmResetPasswordRequest) { + this.logger.log('confirmResetPassword'); - const confirmResetPasswordResponse = await new Promise( - (resolve, reject) => { - this.authService - .confirmResetPassword({ username, code, newPassword }) - .subscribe({ - next: resolve, - error: (err) => reject(err.details), - complete() { - console.log('done'); - }, - }); - }, - ) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err); - throw new Error(err); - }); + return grpcHandler( + this.authService.AuthConfirmResetPassword({ + username, + code, + newPassword, + }), + ); + } - return confirmResetPasswordResponse; + async enableTotpMFA({ accessToken, password }: AuthEnableTotpMfaRequest) { + this.logger.log('enableTotpMFA'); + + return grpcHandler( + this.authService.AuthEnableTotpMfa({ accessToken, password }), + ); + } + + async disableTotpMFA({ accessToken, password }: AuthDisableTotpMfaRequest) { + this.logger.log('disableTotpMFA'); + + return grpcHandler( + this.authService.AuthDisableTotpMfa({ accessToken, password }), + ); + } + + async dismissTotpMFA({ accessToken }: AuthDismissTotpMfaRequest) { + this.logger.log('dismissTotpMFA'); + + return grpcHandler( + this.authService.AuthDismissTotpMfa({ accessToken }), + ); + } + + async verifyTotp({ accessToken, totp }: AuthVerifyTotpMfaRequest) { + this.logger.log('disableTotpMFA'); + + return grpcHandler( + this.authService.AuthVerifyTotpMfa({ accessToken, totp }), + ); } } diff --git a/src/clients/connector/client.config.ts b/src/clients/connector/client.config.ts new file mode 100644 index 0000000..61db9a1 --- /dev/null +++ b/src/clients/connector/client.config.ts @@ -0,0 +1,31 @@ +import { credentials } from '@grpc/grpc-js'; +import { ClientOptions, Transport } from '@nestjs/microservices'; +import { ConnectorManager } from '@victorradael/protospack-v2'; + +export class ConnectorClientConfiguration { + config(): ClientOptions { + return { + transport: Transport.GRPC, + options: { + url: process.env.INFACTORY_URL, + package: [ + ConnectorManager.ProtoPackages.WritePackage, + ConnectorManager.ProtoPackages.ReadPackage, + ], + credentials: + process.env.LOCAL_ENV === 'local' + ? undefined + : credentials.createSsl(), + protoPath: [ + ConnectorManager.ProtoPaths.WriteFilePath, + ConnectorManager.ProtoPaths.ReadFilePath, + ], + loader: { + enums: String, + objects: true, + arrays: true, + }, + }, + }; + } +} diff --git a/src/clients/connector/client.service.ts b/src/clients/connector/client.service.ts new file mode 100644 index 0000000..e9b4ed1 --- /dev/null +++ b/src/clients/connector/client.service.ts @@ -0,0 +1,266 @@ +import { + OnModuleInit, + Inject, + HttpException, + HttpStatus, +} from '@nestjs/common'; +import { ClientGrpc } from '@nestjs/microservices'; +import { ConnectorManager } from '@victorradael/protospack-v2'; +import { from } from 'rxjs'; + +export class ConnectorClientService implements OnModuleInit { + private connectorServiceRead: ConnectorManager.ReadService.ConnectorManagerReadServices; + private connectorServiceWrite: ConnectorManager.WriteService.ConnectorManagerWriteServices; + constructor( + @Inject('CONNECTOR_PACKAGE') private readonly grpcClient: ClientGrpc, + ) {} + + onModuleInit() { + this.connectorServiceWrite = + this.grpcClient.getService( + ConnectorManager.ProtoServices.ConnectorManagerWriteServices, + ); + + this.connectorServiceRead = + this.grpcClient.getService( + ConnectorManager.ProtoServices.ConnectorManagerReadServices, + ); + } + + async uploadConnector(uploadConnector) { + const connector: ConnectorManager.Entities.ConnectorCreateRequest = { + file: { + buffer: uploadConnector.file.buffer, + mimetypes: uploadConnector.file.mimetype, + }, + connector: JSON.stringify(uploadConnector.connector), + }; + const serviceBody: ConnectorManager.Messages.RegisterConnectorRequest = { + connector, + }; + + const observable = from( + this.connectorServiceWrite.RegisterConnector(serviceBody), + ); + + const result = await new Promise((resolve, reject) => { + observable.subscribe({ + next(x) { + resolve(x); + }, + error(err) { + console.log('Observable Error'); + reject(err); + }, + complete() { + console.log('done'); + }, + }); + }).catch((err) => { + console.log(err.details); + throw new HttpException( + err.details, + err.code === 6 ? HttpStatus.CONFLICT : 400, + ); + }); + + console.log('ConnectorClientService', 'Upload'); + + return result; + } + + async uploadFile(uploadFile) { + const body: ConnectorManager.Messages.UploadFileRequest = { + file: { + buffer: uploadFile.file.buffer, + mimetypes: uploadFile.file.mimetype, + }, + name: uploadFile.name, + }; + + const observable = from(this.connectorServiceWrite.UploadFile(body)); + + const result = await new Promise((resolve, reject) => { + observable.subscribe({ + next(x) { + resolve(x); + }, + error(err) { + console.log('Observable Error'); + reject(err); + }, + complete() { + console.log('done'); + }, + }); + }).catch((err) => { + console.log(err.details); + throw new HttpException( + err.details, + err.code === 6 ? HttpStatus.CONFLICT : 400, + ); + }); + + console.log('ConnectorClientService', 'Upload'); + + return result; + } + + async getAllConnectors(body) { + const observable = from( + this.connectorServiceRead.GetAllConnectors({ + search: body.search, + filters: JSON.stringify(body.filters), + }), + ); + const result = await new Promise((resolve, reject) => { + observable.subscribe({ + next(x) { + resolve(x); + }, + error(err) { + console.log('Observable Error'); + reject(err); + }, + complete() { + console.log('done'); + }, + }); + }).catch((err) => { + throw new HttpException( + err.details, + err.code === 6 ? HttpStatus.CONFLICT : 400, + ); + }); + + console.log('ConnectorClientService', 'getAllConnectors'); + + return result; + } + + async getConnectorDetails(plugin: string) { + const observable = from( + this.connectorServiceRead.GetConnectorDetails({ + plugin, + }), + ); + const result = await new Promise((resolve, reject) => { + observable.subscribe({ + next(x) { + resolve(x); + }, + error(err) { + console.log('Observable Error'); + reject(err); + }, + complete() { + console.log('done'); + }, + }); + }).catch((err) => { + throw new HttpException( + err.details, + err.code === 6 ? HttpStatus.CONFLICT : 400, + ); + }); + + console.log('ConnectorClientService', 'getAllConnectors'); + + return result; + } + + async getConnector(plugin: string) { + const observable = from( + this.connectorServiceRead.GetConnector({ + plugin, + }), + ); + const result = await new Promise((resolve, reject) => { + observable.subscribe({ + next(x) { + resolve(x); + }, + error(err) { + console.log('Observable Error'); + reject(err); + }, + complete() { + console.log('done'); + }, + }); + }).catch((err) => { + throw new HttpException( + err.details, + err.code === 6 ? HttpStatus.CONFLICT : 400, + ); + }); + + console.log('ConnectorClientService', 'getAllConnectors'); + + return result; + } + + async deleteConnector(plugin: string, version: string) { + const observable = from( + this.connectorServiceWrite.DeleteConnector({ + version, + plugin, + }), + ); + const result = await new Promise((resolve, reject) => { + observable.subscribe({ + next(x) { + resolve(x); + }, + error(err) { + console.log('Observable Error'); + reject(err); + }, + complete() { + console.log('done'); + }, + }); + }).catch((err) => { + throw new HttpException( + err.details, + err.code === 6 ? HttpStatus.CONFLICT : 400, + ); + }); + + console.log('ConnectorClientService', 'getAllConnectors'); + + return result; + } + + async updateConnector({ plugin, changes }) { + const observable = from( + this.connectorServiceWrite.UpdateConnector({ + plugin, + changes, + }), + ); + const result = await new Promise((resolve, reject) => { + observable.subscribe({ + next(x) { + resolve(x); + }, + error(err) { + console.log('Observable Error'); + reject(err); + }, + complete() { + console.log('done'); + }, + }); + }).catch((err) => { + throw new HttpException( + err.details, + err.code === 6 ? HttpStatus.CONFLICT : 400, + ); + }); + + console.log('ConnectorClientService', 'getAllConnectors'); + + return result; + } +} diff --git a/src/clients/auth/client.config.ts b/src/clients/duc/client.config.ts similarity index 66% rename from src/clients/auth/client.config.ts rename to src/clients/duc/client.config.ts index 82cce15..e1f5de6 100644 --- a/src/clients/auth/client.config.ts +++ b/src/clients/duc/client.config.ts @@ -1,20 +1,23 @@ import { credentials } from '@grpc/grpc-js'; import { ClientOptions, Transport } from '@nestjs/microservices'; +import { + ProtoPackages, + ProtoPaths, +} from '@victorradael/protospack-v2/dist/lib/Duc'; -import { DucProtoFilePath, DucPackages } from '@victorradael/protospack'; - -export class AuthClient { +export class DucClient { config(): ClientOptions { return { transport: Transport.GRPC, options: { url: process.env.DUC_URL, - package: DucPackages, + package: ProtoPackages.WritePackage, credentials: process.env.LOCAL_ENV ? undefined : credentials.createSsl(), - protoPath: DucProtoFilePath, + protoPath: ProtoPaths.WriteFilePath, loader: { + keepCase: true, enums: String, objects: true, arrays: true, diff --git a/src/clients/inputs/client.service.ts b/src/clients/inputs/client.service.ts index 19d966b..5855ff7 100644 --- a/src/clients/inputs/client.service.ts +++ b/src/clients/inputs/client.service.ts @@ -3,6 +3,8 @@ import { Inject, HttpException, HttpStatus, + NotFoundException, + InternalServerErrorException, } from '@nestjs/common'; import { ClientGrpc } from '@nestjs/microservices'; import { @@ -14,7 +16,7 @@ import { TestConnectionGetColumnsRequest, TestConnectionRequest, } from '@victorradael/protospack'; -import axios from 'axios'; +import axios, { AxiosRequestConfig } from 'axios'; import { lastValueFrom } from 'rxjs'; import { InputModel } from 'src/modules/inputs/dtos/input.model'; import { @@ -23,6 +25,8 @@ import { } from 'src/utils/CaseConverter'; import { mustache } from 'src/utils/mustache'; import { DadosferaLogger } from 'dadosfera-logs'; +import { OauthSecrets } from 'src/utils/OauthSecrets'; +import { URLSearchParams } from 'url'; import { IIdRequest, UpdateInputRequest } from './interfaces'; export class InputsClientService implements OnModuleInit { @@ -32,11 +36,12 @@ export class InputsClientService implements OnModuleInit { @Inject(DadosferaLogger) dadosferaLogger: DadosferaLogger, @Inject('INPUTS_PACKAGE') private readonly grpcClient: ClientGrpc, + @Inject('OAUTH_SECRETS') private readonly oauthSecrets: OauthSecrets, ) { this.logger = dadosferaLogger.logger; } - onModuleInit() { + async onModuleInit() { this.inputService = this.grpcClient.getService('InputService'); } @@ -54,7 +59,7 @@ export class InputsClientService implements OnModuleInit { async createGeneric(createInputGeneric) { this.logger.info('InputClientService - Create'); const { info, ...data } = createInputGeneric; - data.credentials = await this.getInputTokens(data); + // data.credentials = await this.getInputTokens(data); if (data.options) delete data.options; if (data.credentials.oauth_code) delete data.credentials.oauth_code; const grpcPayload = { @@ -65,7 +70,12 @@ export class InputsClientService implements OnModuleInit { const structReturn = await lastValueFrom( this.inputService.Create(grpcPayload), - ); + ).catch((err: { details: string }) => { + if (err.details === 'Item Not found!') { + throw new NotFoundException('Input not found'); + } + throw new InternalServerErrorException(err.details); + }); objectCamelToSnake(structReturn); const inputCreated = DecodeGrpcStruct(structReturn.input); return { input: inputCreated }; @@ -221,64 +231,66 @@ export class InputsClientService implements OnModuleInit { switch (plugin) { case 'hubspot': return { - client_id: process.env.HUBSPOT_CLIENT_ID || '', - client_secret: process.env.HUBSPOT_CLIENT_SECRET || '', + client_id: this.oauthSecrets.hubspot.client_id || '', + client_secret: this.oauthSecrets.hubspot.client_secret || '', }; } return {}; } async getInputTokens(input: InputModel) { - const { credentials, options } = input; - const credentialsTokens: any = {}; + const { credentials } = input; + let credentialsTokens = {}; switch (credentials.connection_type) { case 'oauth': - const { oauth } = options; - const { get_tokens_url_params, get_tokens_set_response } = oauth; - const secrets = await this.getAuthSecrets(input.plugin); - if (oauth.content_type === 'application/x-www-form-urlencoded') { - const requestParams = new URLSearchParams(); - const get_tokens_url_params_string = mustache(get_tokens_url_params, { - ...secrets, - ...credentials, - }); - let get_tokens_url_params_obj: Record = {}; - try { - get_tokens_url_params_obj = JSON.parse( - get_tokens_url_params_string, - ); - } catch (error) { - throw new HttpException( - 'Erro transformando get_tokens_url_params', - 400, - ); - } - const { redirect_uri } = get_tokens_url_params_obj; - for (const key in get_tokens_url_params_obj) { - const value = get_tokens_url_params_obj[key]; - requestParams.append(key, value); - } - const { data } = await axios - .post(options.oauth.get_tokens_url, requestParams) - .catch((err) => { - this.logger.info(err.response.data); - throw new HttpException( - err.response.data.message, - err.response.status, - ); - }); - for (const key in get_tokens_set_response) { - const responseKey = get_tokens_set_response[key]; - credentialsTokens[key] = data[responseKey]; - } - credentialsTokens.redirect_uri = redirect_uri; - } + credentialsTokens = await this.getOauthTokens(input); break; } return { ...credentials, ...credentialsTokens }; } - // getOauthTokens(input){ + async getOauthTokens(input: InputModel) { + const tokens: Record = {}; + const { options, credentials } = input; + const { oauth } = options; + const { get_tokens_url_params, get_tokens_set_response } = oauth; + const secrets = await this.getAuthSecrets(input.plugin); + const get_tokens_url_params_string = mustache(get_tokens_url_params, { + ...secrets, + ...credentials, + }); + let get_tokens_url_params_obj: Record = {}; + try { + get_tokens_url_params_obj = JSON.parse(get_tokens_url_params_string); + } catch (error) { + throw new HttpException('Erro transformando get_tokens_url_params', 400); + } + let params = {}; + switch (oauth.content_type) { + case 'application/x-www-form-urlencoded': + params = new URLSearchParams(get_tokens_url_params_obj); + params = params.toString(); + break; + default: + break; + } + const axiosRequestConfig: AxiosRequestConfig = { + url: oauth.get_tokens_url, + method: oauth.get_tokens_method || 'POST', + data: params, + headers: { 'content-type': oauth.content_type || 'application/json' }, + }; - // } + const { data } = await axios(axiosRequestConfig).catch((err) => { + console.log(err.response.data); + throw new HttpException(err.response.data.message, err.response.status); + }); + for (const key in get_tokens_set_response) { + const responseKey = get_tokens_set_response[key]; + tokens[key] = data[responseKey]; + } + const { redirect_uri } = get_tokens_url_params_obj; + tokens.redirect_uri = redirect_uri; + return tokens; + } async getAvailableEntities(data) { this.logger.info('InputClientService - GetAvailableEntities'); diff --git a/src/clients/permissions/client.service.ts b/src/clients/permissions/client.service.ts new file mode 100644 index 0000000..7e9236b --- /dev/null +++ b/src/clients/permissions/client.service.ts @@ -0,0 +1,33 @@ +import { Logger, OnModuleInit, Inject } from '@nestjs/common'; +import { ClientGrpc } from '@nestjs/microservices'; + +import { ProtoServices } from '@victorradael/protospack-v2/dist/lib/Duc'; +import { PermissionsProtoService as PermissionsServiceInterface } from '@victorradael/protospack-v2/dist/lib/Duc/interfaces/write-service'; +import { + Empty, + InjectPermissionsRequest, +} from '@victorradael/protospack-v2/dist/lib/Duc/interfaces/messages'; + +import grpcHandler from '../../utils/grpcHandler'; + +export class PermissionsClientService implements OnModuleInit { + private readonly logger = new Logger(PermissionsClientService.name); + + private permissionsService: PermissionsServiceInterface; + constructor(@Inject('DUC_PACKAGE') private readonly grpcClient: ClientGrpc) {} + + onModuleInit() { + this.permissionsService = + this.grpcClient.getService( + ProtoServices.PermissionsProtoService, + ); + } + + async injectPermissions({ permissions }: InjectPermissionsRequest) { + this.logger.log('InjectPermissions'); + + return grpcHandler( + this.permissionsService.InjectPermissions({ permissions }), + ); + } +} diff --git a/src/clients/pipelines/client.service.ts b/src/clients/pipelines/client.service.ts index 79d93cc..626f013 100644 --- a/src/clients/pipelines/client.service.ts +++ b/src/clients/pipelines/client.service.ts @@ -1,10 +1,15 @@ -import { HttpException, Inject, OnModuleInit } from '@nestjs/common'; -import { DadosferaLogger } from 'dadosfera-logs'; +import { + BadRequestException, + Inject, + InternalServerErrorException, + OnModuleInit, +} from '@nestjs/common'; import { ClientGrpc, Payload } from '@nestjs/microservices'; import { PipelineServicesNames, PipelinesServiceInterface, } from '@victorradael/protospack'; +import { lastValueFrom } from 'rxjs'; import { objectCamelToSnake, objectSnakeToCamel, @@ -15,6 +20,7 @@ import { IIdRequest, IUpdatePipelineRequest, } from './interfaces'; +import { DadosferaLogger } from 'dadosfera-logs'; export class PipelinesClientService implements OnModuleInit { private pipelineService: PipelinesServiceInterface; @@ -35,34 +41,17 @@ export class PipelinesClientService implements OnModuleInit { } async create(@Payload() createPipelineDto: ICreatePipelineDto) { - this.logger.info('PipelinesClientService - Create'); - - const createPipelineResponse = await new Promise((resolve, reject) => { - this.pipelineService - .Create(objectSnakeToCamel(createPipelineDto)) - .subscribe({ - next(x) { - resolve(x); - }, - error(err) { - reject(err); - }, - complete() { - // console.log('done'); - }, - }); - }) - .then((res) => { - this.logger.info('Done'); - return res; - }) - .catch((err) => { - this.logger.error(err.message); - if (err.details == 'Invalid Request') { - throw new HttpException(err.details, 400); - } - throw new HttpException(err.details, 500); - }); + console.log('PipelinesClientService', 'Create'); + const createPipelineResponse = await lastValueFrom( + this.pipelineService.Create(objectSnakeToCamel(createPipelineDto)), + ).catch((error: { details: string }) => { + if (error.details.includes('INVALID_REQUEST')) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [errorType, message] = error.details.split('|'); + throw new BadRequestException(message); + } + throw new InternalServerErrorException(error.details); + }); return createPipelineResponse; } diff --git a/src/main.ts b/src/main.ts index 42be8bd..27fc6fe 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,6 +4,9 @@ import apm from 'elastic-apm-node'; import { writeFileSync } from 'fs'; import helmet from 'helmet'; import { DadosferaLogger } from 'dadosfera-logs'; + +import documentEmpty from '../swagger_empty.json'; + import { AppModule } from './app.module'; async function bootstrap() { @@ -46,7 +49,7 @@ async function bootstrap() { app.use(helmet()); const config = new DocumentBuilder() - .setTitle('Maestro Grpc Documentation') + .setTitle('Maestro') .setDescription('Documentation for Maestro gateway') .setVersion('1.0') .addBearerAuth() @@ -54,7 +57,11 @@ async function bootstrap() { const document = SwaggerModule.createDocument(app, config); writeFileSync('./swagger.json', JSON.stringify(document)); - SwaggerModule.setup('api', app, document); + if (process.env.ENV != 'stg' && process.env.ENV != 'prd') + SwaggerModule.setup('api', app, document); + + const swaggerDoc = process.env.ENV === 'dev' ? document : documentEmpty; + SwaggerModule.setup('api', app, swaggerDoc); await app.listen(3333); } diff --git a/src/middlewares/authentication.ts b/src/middlewares/authentication.ts deleted file mode 100644 index aa6d45f..0000000 --- a/src/middlewares/authentication.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; -import axios from 'axios'; -import { - ForbiddenException, - InternalServerErrorException, - NestMiddleware, - UnauthorizedException, - UseFilters, -} from '@nestjs/common'; -import jwkToPem from 'jwk-to-pem'; -import { decode, verify } from 'jsonwebtoken'; -import { HttpExceptionFilter } from '../error/http-exception.filter'; - -@UseFilters(new HttpExceptionFilter()) -export class LoggerMiddleware implements NestMiddleware { - use = async (request: Request, response: Response, next: NextFunction) => { - const idToken = request.get('Dadosfera-User'); - const accessToken = request.get('Authorization'); - const privateKey = process.env.JWT_PRIVATE_KEY; - let requiredRoute = ''; - const requiredMethod = request.method.trim(); - if (request.route.path.split('/').length >= 2) { - requiredRoute = request.route.path.split('/')[1].trim(); - } - - verify(idToken, privateKey, (err) => { - if (err) { - throw new UnauthorizedException(); - } - }); - const jwtDecoded: any = decode(idToken); - - const permissions = jwtDecoded.user.permissions; - - const clientId = jwtDecoded.user.customerId; - const customer = jwtDecoded.user.customer; - const userId = jwtDecoded.user.id; - const customer_tier = jwtDecoded.user.customer_tier; - await verifyToken(accessToken); - - let havePermission = false; - const permission = permissions.find((permission) => { - permission = permission.split('/'); - const method = permission[0].trim(); - const route = permission[1].trim(); - - if (method === requiredMethod && route === requiredRoute) { - return permission; - } - }); - - if (permission) { - havePermission = true; - } - - if (havePermission) { - request.body.info = { - customer_id: clientId, - user_id: userId, - customer, - customer_tier, - }; - next(); - } else { - throw new ForbiddenException(); - } - }; -} - -let pems: { [key: string]: Record }[]; - -const setUp = async (region: string, id: string) => { - const URL = `https://cognito-idp.${region}.amazonaws.com/${id}/.well-known/jwks.json`; - - try { - const response = await axios.get(URL); - - if (response.status !== 200) { - throw new InternalServerErrorException(); - } - const data = await response.data; - const { keys } = data; - - pems = keys.map((key: any) => { - const modulus = key.n; - const exponent = key.e; - const keyType = key.kty; - const jwk = { kty: keyType, n: modulus, e: exponent }; - const pem = jwkToPem(jwk); - const keyId = key.kid; - - return { [keyId]: pem }; - }); - } catch (error) { - // console.log(error); - // console.log('Error! Unable to download JWKs'); - } -}; - -const verifyToken = async (accessToken: string) => { - const awsRegion = process.env.AWS_REGION; - const awsPoolId = process.env.AWS_IDENTITY_POOL_ID; - - try { - await setUp(awsRegion, awsPoolId); - if (!accessToken) { - throw new UnauthorizedException(); - } - - const user: any = decode(accessToken, { complete: true }); - - if (user === null) { - throw new UnauthorizedException(); - } - - const { kid } = user.header; - const pem = pems.filter((item: any) => item[kid]); - const pemValue: any = pem[0][kid]; - - if (!pem) { - throw new UnauthorizedException(); - } - - verify(accessToken, pemValue, (err: any) => { - if (err) { - throw new UnauthorizedException(); - } - - return; - }); - } catch (error) { - throw new UnauthorizedException(); - } -}; diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 67e1a5b..97e1794 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -1,68 +1,73 @@ import { + Logger, Body, Controller, Headers, Post, HttpCode, HttpStatus, - Inject, + OnApplicationBootstrap, } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; import { AuthSignInRequest, AuthRefreshAccessTokenRequest, - AuthEnableTotpMfaRequest, - AuthDisableTotpMfaRequest, - AuthVerifyTotpMfaRequest, AuthChangePasswordRequest, AuthResetPasswordRequest, AuthVerifyResetPasswordCodeRequest, AuthConfirmResetPasswordRequest, -} from '@victorradael/protospack'; + AuthEnableTotpMfaRequest, + AuthDisableTotpMfaRequest, + AuthVerifyTotpMfaRequest, +} from '@victorradael/protospack-v2/dist/lib/Duc/interfaces/messages'; + +import { AuthClientService } from '../../clients/auth/client.service'; +import { PermissionsClientService } from '../../clients/permissions/client.service'; +import { Permissions } from '../../authentication/permissions.enum'; -import { AuthClientService } from 'src/clients/auth/client.service'; -import { DadosferaLogger } from 'dadosfera-logs'; import ErrorBuilder from '../../utils/ErrorBuilder'; +import { LoginDto } from './dtos/login'; +@ApiTags('Auth') @Controller('auth') -export class AuthController { - logger: any; +export class AuthController implements OnApplicationBootstrap { + private readonly logger = new Logger(AuthController.name); + constructor( - @Inject(DadosferaLogger) - dadosferaLogger: DadosferaLogger, private authClient: AuthClientService, - ) { - this.logger = dadosferaLogger.logger; - } + private permissionsClient: PermissionsClientService, + ) {} - // DEPRECADO! - @Post() - @HttpCode(HttpStatus.OK) - async signIn_old(@Body() body: AuthSignInRequest) { - this.logger.info(`/auth - SignIn_old`); + // internally used to send permissions to duc on microservice startup + async onApplicationBootstrap() { + this.logger.log('sending permissions to DUC...'); - return this.signIn(body); - } + const permissions = Object.values(Permissions).flatMap((namespace) => + Object.values(namespace), + ); - @Post('login') - @HttpCode(HttpStatus.OK) - async signIn_login(@Body() body: AuthSignInRequest) { - this.logger.info(`/auth - SignIn_login`); + return this.permissionsClient + .injectPermissions({ permissions }) + .catch((err: ErrorBuilder) => { + if ( + err.code === 'No connection established' && + process.env.LOCAL_ENV === 'true' + ) { + return this.logger.log( + "couldn't connect to DUC. suppresing in local env", + ); + } - return this.signIn(body); + throw err; + }); } @Post('sign-in') @HttpCode(HttpStatus.OK) async signIn(@Body() { username, password, totp }: AuthSignInRequest) { - this.logger.info(`/auth - SignIn`); + this.logger.log(`/auth`, 'SignIn'); - const tokens = await this.authClient - .signIn({ username, password, totp }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return tokens; + return this.authClient.signIn({ username, password, totp }); } @Post('refresh-access-token') @@ -70,15 +75,63 @@ export class AuthController { async refreshAccessToken( @Body() { refreshToken }: AuthRefreshAccessTokenRequest, ) { - this.logger.info(`/auth - RefreshAccessToken`); + this.logger.log(`/auth`, 'RefreshAccessToken'); - const accessToken = await this.authClient - .refreshAccessToken({ refreshToken }) - .catch((err) => { - throw ErrorBuilder(err); - }); + return this.authClient.refreshAccessToken({ refreshToken }); + } - return accessToken; + @Post('change-password') + @HttpCode(HttpStatus.OK) + async changePassword( + @Body() body: AuthChangePasswordRequest, + @Headers() headers, + ) { + this.logger.log(`/auth`, 'change-password'); + + const { oldPassword, newPassword } = body; + const { authorization: accessToken } = headers; + + return this.authClient.changePassword({ + accessToken, + oldPassword, + newPassword, + }); + } + + @Post('reset-password') + @HttpCode(HttpStatus.OK) + async resetPassword(@Body() body: AuthResetPasswordRequest) { + this.logger.log(`/auth`, 'reset-password'); + + const { username } = body; + + return this.authClient.resetPassword({ username }); + } + + @Post('verify-reset-password-code') + @HttpCode(HttpStatus.OK) + async verifyResetPasswordCode( + @Body() body: AuthVerifyResetPasswordCodeRequest, + ) { + this.logger.log(`/auth`, 'verify-reset-password-code'); + + const { username, code } = body; + + return this.authClient.verifyResetPasswordCode({ username, code }); + } + + @Post('confirm-reset-password') + @HttpCode(HttpStatus.OK) + async confirmResetPassword(@Body() body: AuthConfirmResetPasswordRequest) { + this.logger.log(`/auth`, 'confirm-reset-password'); + + const { username, code, newPassword } = body; + + return this.authClient.confirmResetPassword({ + username, + code, + newPassword, + }); } @Post('enable-totp') @@ -87,18 +140,12 @@ export class AuthController { @Body() body: AuthEnableTotpMfaRequest, @Headers() headers, ) { - this.logger.info(`/auth - enable-totp`); + this.logger.log(`/auth`, 'enable-totp'); const { password } = body; const { authorization: accessToken } = headers; - const response = await this.authClient - .enableTotpMFA({ accessToken, password }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; + return this.authClient.enableTotpMFA({ accessToken, password }); } @Post('disable-totp') @@ -107,129 +154,32 @@ export class AuthController { @Body() body: AuthDisableTotpMfaRequest, @Headers() headers, ) { - this.logger.info(`/auth - disable-totp`); + this.logger.log(`/auth`, 'disable-totp'); const { password } = body; const { authorization: accessToken } = headers; - const response = await this.authClient - .disableTotpMFA({ accessToken, password }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; + return this.authClient.disableTotpMFA({ accessToken, password }); } @Post('dismiss-totp') @HttpCode(HttpStatus.OK) async dismissTotpMFA(@Headers() headers) { - this.logger.info(`/auth - disable-totp`); + this.logger.log(`/auth`, 'disable-totp'); const { authorization: accessToken } = headers; - const response = await this.authClient - .dismissTotpMFA({ accessToken }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; + return this.authClient.dismissTotpMFA({ accessToken }); } @Post('verify-totp') @HttpCode(HttpStatus.OK) - async verifyTotp( - @Body() body: AuthVerifyTotpMfaRequest, - @Headers() headers, - ): Promise { - this.logger.info(`/auth - enable-totp`); + async verifyTotp(@Body() body: AuthVerifyTotpMfaRequest, @Headers() headers) { + this.logger.log(`/auth`, 'enable-totp'); const { totp } = body; const { authorization: accessToken } = headers; - const response = await this.authClient - .verifyTotp({ accessToken, totp }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; - } - - @Post('change-password') - @HttpCode(HttpStatus.OK) - async changePassword( - @Body() body: AuthChangePasswordRequest, - @Headers() headers, - ): Promise { - this.logger.info(`/auth - change-password`); - - const { oldPassword, newPassword } = body; - const { authorization: accessToken } = headers; - - const response = await this.authClient - .changePassword({ - accessToken, - oldPassword, - newPassword, - }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; - } - - @Post('reset-password') - @HttpCode(HttpStatus.OK) - async resetPassword(@Body() body: AuthResetPasswordRequest): Promise { - this.logger.info(`/auth - reset-password`); - - const { username } = body; - - const response = await this.authClient - .resetPassword({ username }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; - } - - @Post('verify-reset-password-code') - @HttpCode(HttpStatus.OK) - async verifyResetPasswordCode( - @Body() body: AuthVerifyResetPasswordCodeRequest, - ): Promise { - this.logger.info(`/auth - verify-reset-password-code`); - - const { username, code } = body; - - const response = await this.authClient - .verifyResetPasswordCode({ username, code }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; - } - - @Post('confirm-reset-password') - @HttpCode(HttpStatus.OK) - async confirmResetPassword( - @Body() body: AuthConfirmResetPasswordRequest, - ): Promise { - this.logger.info(`/auth - confirm-reset-password`); - - const { username, code, newPassword } = body; - - const response = await this.authClient - .confirmResetPassword({ username, code, newPassword }) - .catch((err) => { - throw ErrorBuilder(err); - }); - - return response; + return this.authClient.verifyTotp({ accessToken, totp }); } } diff --git a/src/modules/auth/auth.service.spec.ts b/src/modules/auth/auth.service.spec.ts deleted file mode 100644 index bc390a2..0000000 --- a/src/modules/auth/auth.service.spec.ts +++ /dev/null @@ -1,152 +0,0 @@ -import nock from 'nock'; -import { LoggerMiddleware } from '../../middlewares/authentication'; -import { NextFunction, Request, Response } from 'express'; -import { ConsoleLogger, UnauthorizedException } from '@nestjs/common'; - -describe('PipelinesGrpcServerService', () => { - // let mockRequest: Partial; - // let mockResponse: Partial; - // const nextFunction: NextFunction = jest.fn(); - - // beforeEach(() => { - // mockRequest = { - // headers: {}, - // body: { - // info: {}, - // }, - // }; - // mockResponse = { - // json: jest.fn(), - // }; - // }); - - it('should be defined', () => { - expect(2 + 2).toBe(4); - }); - - // it('Should be able to pass auth', async () => { - // const awsRegion = process.env.AWS_REGION; - // const awsPoolId = process.env.AWS_IDENTITY_POOL_ID; - // const cognitoRes = { - // keys: [ - // { - // alg: 'RS256', - // e: 'AQAB', - // kid: 'z3VA3+i9JZY3JFDJTNWOap8RY+B7C6mFedaqCuvLvqA=', - // kty: 'RSA', - // n: 'vIGCQDkPA_eQUoaGDUsCyK_Whr76mNW0kZ1uac6ZnyY6hsjUIjvwehqv-ux3cQo4rQZQVFcoh8n9cK5jguz4GVdD972vIxoEdyv32nBFVr5e1PBunKJ2Y32GTR_Hl0XiE0hRe1v6cWuTqiC4qm1NY7tXYL3mI9L6s9ztNbhmG_V44y26PdhL4vRVrJaHOAmCs-77U-QYAC7Llkpmjh-8tG1zt9_FJ237cpBUVOuhD-7Nm32_eB9wddBGfBw0F10ko_KJoU-7683_Kv8k9coJzFUSONId-bfnLOzs8j1L6ZAHipXCR7rpmuRYzXztjp4Wmm2zPUToWLdMEy0Hq1OWmw', - // use: 'sig', - // }, - // { - // alg: 'RS256', - // e: 'AQAB', - // kid: 'u+1W9pi+clp8LaPhZVrv4dXMqRkTRD02YWhbm0NvsUw=', - // kty: 'RSA', - // n: 'noGq1cRMAKJPWahqfC_zWasYovSUycaS1basMfEoh3ePLc9zRgmyfiVKYzLRosHMe1uk0Y5ekCBKnWA8Yl7I84Yt7IIIaE44oJjSEGBKT3m8i8YaXzawaNs63KPkRh8553o3KzL75bQWcI_ABKqkf-uAKSCl_XotBGkzLUl4hIOYtAtRGEfKaNMPqyTCT5Zn71pMd0isppaUiTW2T5QLsZV1IBp46aSrl_D5Q_FTsJT7feobQVoHp2zfIorCpkfTXBTBMQTEBFSDyPbc6cULl48VKxp0B0GEwR_kYCEHEVzf41LQcUWZUE0OdBychijkSc9MZJnBWUYQZyedJILWnQ', - // use: 'sig', - // }, - // ], - // }; - - // nock( - // `https://cognito-idp.${awsRegion}.amazonaws.com/${awsPoolId}/.well-known/jwks.json`, - // ) - // .persist() - // .get('') - // .reply(200, cognitoRes); - - // mockRequest.headers['Dadosfera-User'] = - // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiZTljYjI1ZGEtMTQyOC00NDJjLTg5NjItYTdkNmQxNjhkODUyIiwibmFtZSI6InJvZHJpZ28uemFtYm9uaSIsInVzZXJuYW1lIjoicm9kcmlnby56YW1ib25pQGRhZG9zZmVyYS5haSIsInJ1bGVJZCI6IjIxNzdmZjg4LThmY2ItNDRlNS1hYzYxLWNjYmU2Y2M3MGU4ZCIsImN1c3RvbWVySWQiOiIxMTI5ODBhMy0wYTEyLTQxYzktYmZmZC03OTFjZjdjYTg3YTIiLCJtZmFTdGF0dXMiOiJwZW5kaW5nIiwiY3JlYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwidXBkYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwicGVybWlzc2lvbnMiOlsiUE9TVCAvcGlwZWxpbmVzIiwiR0VUIC9waXBlbGluZXMiLCJQVVQgL3BpcGVsaW5lcyIsIkRFTEVURSAvcGlwZWxpbmVzIiwiUE9TVCAvaW5wdXRzIiwiR0VUIC9pbnB1dHMiLCJQVVQgL2lucHV0cyIsIkRFTEVURSAvaW5wdXRzIiwiUE9TVCAvb3V0cHV0cyIsIkdFVCAvb3V0cHV0cyIsIlBVVCAvb3V0cHV0cyIsIkRFTEVURSAvb3V0cHV0cyIsIlBPU1QgL3RyYW5zZm9ybWF0aW9ucyIsIkdFVCAvdHJhbnNmb3JtYXRpb25zIiwiUFVUIC90cmFuc2Zvcm1hdGlvbnMiLCJERUxFVEUgL3RyYW5zZm9ybWF0aW9ucyIsIlBPU1QgL2NhdGFsb2ciLCJHRVQgL2NhdGFsb2ciLCJQVVQgL2NhdGFsb2ciLCJERUxFVEUgL2NhdGFsb2ciLCJQT1NUIC9hdXRoIiwiR0VUIC9tZXRhYmFzZSIsIkdFVCAvc25vd2ZsYWtlIl0sImN1c3RvbWVyIjoiZGFkb3NmZXJhIn0sImlhdCI6MTY1MzY1NjE2NywiZXhwIjoxNjUzNzQyNTY3fQ.eeNEEUk_95KOxM-objS7gXz-SCVkNFYpEP688MfLkdI'; - // mockRequest.headers['Authorization'] = - // 'eyJraWQiOiJ1KzFXOXBpK2NscDhMYVBoWlZydjRkWE1xUmtUUkQwMllXaGJtME52c1V3PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxYjkyZmFkMC1iNWVlLTQwMzAtOGRmYy1hZWM0MGQzYzdkYmUiLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9OVXY3WTJTeGoiLCJjbGllbnRfaWQiOiI0N3RrY3Jxc2NuajY3bWhnYmg3dXQ1YnJzNCIsIm9yaWdpbl9qdGkiOiJhZWJjNjA5NC1hYTJmLTRiZmUtOWExZi01ZWVhYTVmYzAwNDAiLCJldmVudF9pZCI6IjBhY2NjMzJiLTllNzktNGY2NS1iMDFiLWZhZGJlYzFhZWFiNiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE2NTM2NTYxNjcsImV4cCI6MTY1MzY1Nzk2NywiaWF0IjoxNjUzNjU2MTY3LCJqdGkiOiIyYTgzNDhmOC0xNDhlLTQ3NjctODcxYi00M2UyOGRjNjc2NTkiLCJ1c2VybmFtZSI6InJvZHJpZ28uemFtYm9uaUBkYWRvc2ZlcmEuYWkifQ.UgIgeGEH2olNgqPly8cymNgWIZJz5n9N4yeKgTusfGsu5h-TWP_jVhPoCvFoixO2XKzFjSCvKwlKQYZyB74jLQLs-j5C5KGBdOea1HX7pUnEfEVtBINd1kcHib5YpGYq3MHG1uVx8vNJS3XviwgYg4rgNWA4du-QbhMicdRyHolYM-dWxuxtkwTRWMe1Vw6KlTctFsvUWx1GMgjp37tsLONcp3B8OsYXfiR764K_pBNs5gMhJ39gJ7NHHLWkJrtrUTpIoHWaZS_HEgvVyQiJENQvK_bPDMPm_lyF1dW-JBgot4TpAxMmvV1XGabkzycIcAOwUaPsKBlMphgunz1Ffw'; - // mockRequest.method = 'GET'; - // mockRequest.route = { - // path: '/inputs/', - // stack: [ - // { - // method: 'get', - // }, - // ], - // methods: { - // get: true, - // }, - // }; - // const authMiddleware = new LoggerMiddleware(); - - // await authMiddleware.useTest( - // mockRequest as Request, - // mockResponse as Response, - // nextFunction, - // ); - // expect(nextFunction).toHaveBeenCalled(); - // }); - - // it('Should not be able to pass auth', async () => { - // const awsRegion = process.env.AWS_REGION; - // const awsPoolId = process.env.AWS_IDENTITY_POOL_ID; - // const cognitoRes = { - // keys: [ - // { - // alg: 'RS256', - // e: 'AQAB', - // kid: 'z3VA3+i9JZY3JFDJTNWOap8RY+B7C6mFedaqCuvLvqA=', - // kty: 'RSA', - // n: 'vIGCQDkPA_eQUoaGDUsCyK_Whr76mNW0kZ1uac6ZnyY6hsjUIjvwehqv-ux3cQo4rQZQVFcoh8n9cK5jguz4GVdD972vIxoEdyv32nBFVr5e1PBunKJ2Y32GTR_Hl0XiE0hRe1v6cWuTqiC4qm1NY7tXYL3mI9L6s9ztNbhmG_V44y26PdhL4vRVrJaHOAmCs-77U-QYAC7Llkpmjh-8tG1zt9_FJ237cpBUVOuhD-7Nm32_eB9wddBGfBw0F10ko_KJoU-7683_Kv8k9coJzFUSONId-bfnLOzs8j1L6ZAHipXCR7rpmuRYzXztjp4Wmm2zPUToWLdMEy0Hq1OWmw', - // use: 'sig', - // }, - // { - // alg: 'RS256', - // e: 'AQAB', - // kid: 'u+1W9pi+clp8LaPhZVrv4dXMqRkTRD02YWhbm0NvsUw=', - // kty: 'RSA', - // n: 'noGq1cRMAKJPWahqfC_zWasYovSUycaS1basMfEoh3ePLc9zRgmyfiVKYzLRosHMe1uk0Y5ekCBKnWA8Yl7I84Yt7IIIaE44oJjSEGBKT3m8i8YaXzawaNs63KPkRh8553o3KzL75bQWcI_ABKqkf-uAKSCl_XotBGkzLUl4hIOYtAtRGEfKaNMPqyTCT5Zn71pMd0isppaUiTW2T5QLsZV1IBp46aSrl_D5Q_FTsJT7feobQVoHp2zfIorCpkfTXBTBMQTEBFSDyPbc6cULl48VKxp0B0GEwR_kYCEHEVzf41LQcUWZUE0OdBychijkSc9MZJnBWUYQZyedJILWnQ', - // use: 'sig', - // }, - // ], - // }; - - // nock( - // `https://cognito-idp.${awsRegion}.amazonaws.com/${awsPoolId}/.well-known/jwks.json`, - // ) - // .persist() - // .get('') - // .reply(200, cognitoRes); - - // mockRequest.headers['Dadosfera-User'] = - // 'asdeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiZTljYjI1ZGEtMTQyOC00NDJjLTg5NjItYTdkNmQxNjhkODUyIiwibmFtZSI6InJvZHJpZ28uemFtYm9uaSIsInVzZXJuYW1lIjoicm9kcmlnby56YW1ib25pQGRhZG9zZmVyYS5haSIsInJ1bGVJZCI6IjIxNzdmZjg4LThmY2ItNDRlNS1hYzYxLWNjYmU2Y2M3MGU4ZCIsImN1c3RvbWVySWQiOiIxMTI5ODBhMy0wYTEyLTQxYzktYmZmZC03OTFjZjdjYTg3YTIiLCJtZmFTdGF0dXMiOiJwZW5kaW5nIiwiY3JlYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwidXBkYXRlZEF0IjoiMjAyMi0wNS0xM1QxNTowOTowOS4xMzhaIiwicGVybWlzc2lvbnMiOlsiUE9TVCAvcGlwZWxpbmVzIiwiR0VUIC9waXBlbGluZXMiLCJQVVQgL3BpcGVsaW5lcyIsIkRFTEVURSAvcGlwZWxpbmVzIiwiUE9TVCAvaW5wdXRzIiwiR0VUIC9pbnB1dHMiLCJQVVQgL2lucHV0cyIsIkRFTEVURSAvaW5wdXRzIiwiUE9TVCAvb3V0cHV0cyIsIkdFVCAvb3V0cHV0cyIsIlBVVCAvb3V0cHV0cyIsIkRFTEVURSAvb3V0cHV0cyIsIlBPU1QgL3RyYW5zZm9ybWF0aW9ucyIsIkdFVCAvdHJhbnNmb3JtYXRpb25zIiwiUFVUIC90cmFuc2Zvcm1hdGlvbnMiLCJERUxFVEUgL3RyYW5zZm9ybWF0aW9ucyIsIlBPU1QgL2NhdGFsb2ciLCJHRVQgL2NhdGFsb2ciLCJQVVQgL2NhdGFsb2ciLCJERUxFVEUgL2NhdGFsb2ciLCJQT1NUIC9hdXRoIiwiR0VUIC9tZXRhYmFzZSIsIkdFVCAvc25vd2ZsYWtlIl0sImN1c3RvbWVyIjoiZGFkb3NmZXJhIn0sImlhdCI6MTY1MzY1NjE2NywiZXhwIjoxNjUzNzQyNTY3fQ.eeNEEUk_95KOxM-objS7gXz-SCVkNFYpEP688MfLkdI'; - // mockRequest.headers['Authorization'] = - // 'asdeyJraWQiOiJ1KzFXOXBpK2NscDhMYVBoWlZydjRkWE1xUmtUUkQwMllXaGJtME52c1V3PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxYjkyZmFkMC1iNWVlLTQwMzAtOGRmYy1hZWM0MGQzYzdkYmUiLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9OVXY3WTJTeGoiLCJjbGllbnRfaWQiOiI0N3RrY3Jxc2NuajY3bWhnYmg3dXQ1YnJzNCIsIm9yaWdpbl9qdGkiOiJhZWJjNjA5NC1hYTJmLTRiZmUtOWExZi01ZWVhYTVmYzAwNDAiLCJldmVudF9pZCI6IjBhY2NjMzJiLTllNzktNGY2NS1iMDFiLWZhZGJlYzFhZWFiNiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE2NTM2NTYxNjcsImV4cCI6MTY1MzY1Nzk2NywiaWF0IjoxNjUzNjU2MTY3LCJqdGkiOiIyYTgzNDhmOC0xNDhlLTQ3NjctODcxYi00M2UyOGRjNjc2NTkiLCJ1c2VybmFtZSI6InJvZHJpZ28uemFtYm9uaUBkYWRvc2ZlcmEuYWkifQ.UgIgeGEH2olNgqPly8cymNgWIZJz5n9N4yeKgTusfGsu5h-TWP_jVhPoCvFoixO2XKzFjSCvKwlKQYZyB74jLQLs-j5C5KGBdOea1HX7pUnEfEVtBINd1kcHib5YpGYq3MHG1uVx8vNJS3XviwgYg4rgNWA4du-QbhMicdRyHolYM-dWxuxtkwTRWMe1Vw6KlTctFsvUWx1GMgjp37tsLONcp3B8OsYXfiR764K_pBNs5gMhJ39gJ7NHHLWkJrtrUTpIoHWaZS_HEgvVyQiJENQvK_bPDMPm_lyF1dW-JBgot4TpAxMmvV1XGabkzycIcAOwUaPsKBlMphgunz1Ffw'; - // mockRequest.method = 'GET'; - // mockRequest.route = { - // path: '/inputs/', - // stack: [ - // { - // method: 'get', - // }, - // ], - // methods: { - // get: true, - // }, - // }; - // const authMiddleware = new LoggerMiddleware(); - - // // const t = await authMiddleware.useTest( - // // mockRequest as Request, - // // mockResponse as Response, - // // nextFunction, - // // ); - // // expect(nextFunction).toHaveBeenCalled(); - - // expect(async () => { - // const t = await authMiddleware.useTest( - // mockRequest as Request, - // mockResponse as Response, - // nextFunction, - // ); - // console.log(t); - // }).toThrow('Unauthorized'); - - // expect(1).toBe(2); - // // expect(t).toThrow(UnauthorizedException); - // }); -}); diff --git a/src/modules/auth/dtos/login.ts b/src/modules/auth/dtos/login.ts new file mode 100644 index 0000000..cae27fd --- /dev/null +++ b/src/modules/auth/dtos/login.ts @@ -0,0 +1,12 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class LoginDto { + @ApiProperty() + username: string; + + @ApiProperty() + password: string; + + @ApiProperty({ required: false }) + totp: string; +} diff --git a/src/modules/catalog/catalog.controller.ts b/src/modules/catalog/catalog.controller.ts index 484458a..7c44f81 100644 --- a/src/modules/catalog/catalog.controller.ts +++ b/src/modules/catalog/catalog.controller.ts @@ -8,9 +8,32 @@ import { Post, Query, } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { AuthenticateCondition } from '../../authentication/authentication.decorator'; +import { Permissions } from '../../authentication/permissions.enum'; import { CatalogService } from './catalog.service'; import { DadosferaLogger } from 'dadosfera-logs'; + +@ApiTags('Catalog') @Controller('catalog') +@AuthenticateCondition((req, user) => { + let action; + + switch (req.method) { + case 'POST': + action = 'CREATE'; + break; + + case 'PUT': + action = 'UPDATE'; + break; + + default: + action = req.method; + } + + return user.permissions.includes(Permissions.CATALOG[action].seqid); +}) export class CatalogController { logger: any; constructor( diff --git a/src/modules/connector/connector.controller.ts b/src/modules/connector/connector.controller.ts new file mode 100644 index 0000000..e5bf810 --- /dev/null +++ b/src/modules/connector/connector.controller.ts @@ -0,0 +1,210 @@ +import { + Body, + Controller, + Delete, + Get, + HttpException, + Param, + Put, + Post, + Query, + UploadedFile, + UseInterceptors, +} from '@nestjs/common'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { ApiBearerAuth, ApiConsumes, ApiTags } from '@nestjs/swagger'; +import { ConnectorClientService } from 'src/clients/connector/client.service'; +import { AddTagDto } from './dtos/add-tag'; +import { CreateConnectorDto } from './dtos/create-connector'; +import { DeleteConnectorDto } from './dtos/delete-connector'; +import { GetAllDto } from './dtos/get-all'; +import { RemoveTagDto } from './dtos/remove-tag'; +import { UpdateDto } from './dtos/update'; +import { UploadFileDto } from './dtos/upload-file'; + +@ApiTags('connectors') +@ApiBearerAuth() +@Controller('connectors') +export class ConnectorController { + constructor(private connectorClientService: ConnectorClientService) {} + + @Post() + @ApiConsumes('multipart/form-data') + @UseInterceptors(FileInterceptor('file')) + async uploadConnector( + @UploadedFile() file, + @Body() body: CreateConnectorDto, + ) { + console.log(`/upload`, 'Upload Connector Route'); + + const response = await this.connectorClientService.uploadConnector({ + file, + connector: JSON.parse(body.connector), + }); + + return response; + } + + @Post('/upload') + @ApiConsumes('multipart/form-data') + @UseInterceptors(FileInterceptor('file')) + async uploadFile(@UploadedFile() file, @Body() { name }: UploadFileDto) { + console.log(`/upload`, 'Upload Connector Route'); + + const response = await this.connectorClientService.uploadFile({ + file, + name, + }); + + return response; + } + + @Get() + async getAllConnectors(@Query() queries: GetAllDto) { + console.log(`/upload`, 'Upload Connector Route'); + + const { filters, search } = queries; + + const response: any = await this.connectorClientService.getAllConnectors({ + filters: filters || {}, + search: search || '', + }); + + const connectors = JSON.parse(response.connectors).connectors; + + return { + message: response.message, + connectors, + }; + } + + @Get('/:plugin') + async getConnector( + @Param('plugin') plugin: string, + @Query('version') version: string, + ) { + console.log(`/upload`, 'Upload Connector Route'); + + const pluginId = `${plugin}-${version}`; + + const response: any = await this.connectorClientService.getConnector( + pluginId, + ); + + return { + message: response.message || 'ok', + connector: { ...JSON.parse(response.connector) }, + }; + } + + @Get('/:plugin/details') + async getConnectorDetails( + @Param('plugin') plugin: string, + @Query('version') version: string, + ) { + console.log(`/upload`, 'Upload Connector Route'); + + const pluginId = `${plugin}-${version}`; + + const response: any = await this.connectorClientService.getConnectorDetails( + pluginId, + ); + + return { + message: response.message || 'ok', + connector: { ...JSON.parse(response.connector) }, + }; + } + + @Put('/:plugin') + @ApiConsumes('multipart/form-data') + async updateConnector( + @Param('plugin') plugin: string, + @Body() body: UpdateDto, + ) { + console.log(`/upload`, 'Upload Connector Route'); + + const changes = body; + + const response: any = await this.connectorClientService.updateConnector({ + plugin, + changes: JSON.stringify(changes), + }); + + return { + message: response.message || 'ok', + connector: { ...JSON.parse(response.connector) }, + }; + } + + @Put('/:plugin/add-tag') + async addTagOnConnector( + @Param('plugin') plugin: string, + @Body() body: AddTagDto, + ) { + console.log(`/upload`, 'Upload Connector Route'); + + const { tags } = body; + + if (!tags || !(typeof tags === 'object') || !tags.length) { + throw new HttpException('Not found tags attributes', 400); + } + + const changes = { plugin, tags }; + + const response: any = await this.connectorClientService.updateConnector({ + plugin, + changes: JSON.stringify(changes), + }); + + return { + message: response.message || 'ok', + connector: { ...JSON.parse(response.connector) }, + }; + } + + @Put('/:plugin/remove-tag') + async removeTagOnConnector( + @Param('plugin') plugin: string, + @Body() body: RemoveTagDto, + ) { + console.log(`/upload`, 'Upload Connector Route'); + + const { tags } = body; + const remove = tags; + + if (!remove || !(typeof remove === 'object') || !remove.length) { + throw new HttpException('Not found remove attribute', 400); + } + + const changes = { plugin, remove }; + + const response: any = await this.connectorClientService.updateConnector({ + plugin, + changes: JSON.stringify(changes), + }); + + return { + message: response.message || 'ok', + connector: { ...JSON.parse(response.connector) }, + }; + } + + @Delete('/:plugin') + async deleteConnector( + @Param('plugin') plugin: string, + @Body() { version }: DeleteConnectorDto, + ) { + console.log(`/upload`, 'Upload Connector Route'); + + const response: any = await this.connectorClientService.deleteConnector( + plugin, + version, + ); + + return { + message: response.message || 'ok', + connector: { ...JSON.parse(response.connector) }, + }; + } +} diff --git a/src/modules/connector/dtos/add-tag.ts b/src/modules/connector/dtos/add-tag.ts new file mode 100644 index 0000000..7c04a23 --- /dev/null +++ b/src/modules/connector/dtos/add-tag.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class AddTagDto { + @ApiProperty() + tags: string[]; +} diff --git a/src/modules/connector/dtos/create-connector.ts b/src/modules/connector/dtos/create-connector.ts new file mode 100644 index 0000000..2cdc4d6 --- /dev/null +++ b/src/modules/connector/dtos/create-connector.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class CreateConnectorDto { + @ApiProperty({ format: 'binary' }) + file: string; + + @ApiProperty() + connector: string; +} diff --git a/src/modules/connector/dtos/delete-connector.ts b/src/modules/connector/dtos/delete-connector.ts new file mode 100644 index 0000000..6db5547 --- /dev/null +++ b/src/modules/connector/dtos/delete-connector.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class DeleteConnectorDto { + @ApiProperty() + version: string; +} diff --git a/src/modules/connector/dtos/get-all.ts b/src/modules/connector/dtos/get-all.ts new file mode 100644 index 0000000..f5e3469 --- /dev/null +++ b/src/modules/connector/dtos/get-all.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class GetAllDto { + @ApiProperty() + search: string; + + @ApiProperty() + filters: object; +} diff --git a/src/modules/connector/dtos/remove-tag.ts b/src/modules/connector/dtos/remove-tag.ts new file mode 100644 index 0000000..9de619b --- /dev/null +++ b/src/modules/connector/dtos/remove-tag.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class RemoveTagDto { + @ApiProperty() + tags: string[]; +} diff --git a/src/modules/connector/dtos/update.ts b/src/modules/connector/dtos/update.ts new file mode 100644 index 0000000..5262fde --- /dev/null +++ b/src/modules/connector/dtos/update.ts @@ -0,0 +1,42 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class UpdateDto { + @ApiProperty({ format: 'binary', required: false }) + file?: string; + + @ApiProperty() + version: string; + + @ApiProperty({ required: false }) + category?: string; + + @ApiProperty({ required: false }) + plugin?: string; + + @ApiProperty({ required: false }) + image?: string; + + @ApiProperty({ required: false }) + docs?: string; + + @ApiProperty({ required: false }) + name?: string; + + @ApiProperty({ + required: false, + description: 'skip_select_entities: boolean skip_select_columns: boolean;', + }) + options?: { + skip_select_entities: boolean; + skip_select_columns: boolean; + }; + + @ApiProperty({ + required: false, + type: 'array', + items: { + properties: {}, + }, + }) + connection_controls?: object[]; +} diff --git a/src/modules/connector/dtos/upload-file.ts b/src/modules/connector/dtos/upload-file.ts new file mode 100644 index 0000000..d167f3f --- /dev/null +++ b/src/modules/connector/dtos/upload-file.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class UploadFileDto { + @ApiProperty({ format: 'binary' }) + file: string; + + @ApiProperty() + name: string; +} diff --git a/src/modules/health/health.controller.ts b/src/modules/health/health.controller.ts index 86445fb..1617c9c 100644 --- a/src/modules/health/health.controller.ts +++ b/src/modules/health/health.controller.ts @@ -1,6 +1,8 @@ import { Controller, Get } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; import { HealthService } from './health.service'; +@ApiTags('Health') @Controller('health') export class HealthController { constructor(private readonly healthService: HealthService) {} diff --git a/src/modules/inputs/dtos/input.model.ts b/src/modules/inputs/dtos/input.model.ts index 89914d1..ca6034c 100644 --- a/src/modules/inputs/dtos/input.model.ts +++ b/src/modules/inputs/dtos/input.model.ts @@ -1,5 +1,6 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Info } from 'src/clients/inputs/interfaces'; +import { Method } from 'axios'; export class InputModel { category: string; @@ -15,6 +16,7 @@ export class InputModel { options?: { oauth?: { get_tokens_url: string; + get_tokens_method?: Method; get_tokens_url_params: string; get_tokens_set_response: Record; content_type: string; @@ -173,6 +175,8 @@ export class TestConnectionRes { database_tables: string[]; } export class CreateInputReq { + @ApiPropertyOptional() + id: string; @ApiProperty() plugin: string; @ApiProperty() diff --git a/src/modules/inputs/inputs.controller.ts b/src/modules/inputs/inputs.controller.ts index 920439d..ae37db6 100644 --- a/src/modules/inputs/inputs.controller.ts +++ b/src/modules/inputs/inputs.controller.ts @@ -12,6 +12,8 @@ import { InputsService } from './inputs.service'; import { DadosferaLogger } from 'dadosfera-logs'; import { InputsClientService } from 'src/clients/inputs/client.service'; import { UpdateInputRequest } from 'src/clients/inputs/interfaces'; +import { Permissions } from '../../authentication/permissions.enum'; +import { AuthenticateCondition } from 'src/authentication/authentication.decorator'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; import { CreateInputReq, @@ -26,6 +28,35 @@ import { @ApiTags('inputs') @Controller('inputs') +@AuthenticateCondition((req, user) => { + let action: any; + + switch (req.method) { + case 'POST': + action = 'CREATE'; + break; + + case 'PUT': + action = 'UPDATE'; + break; + + case 'PATCH': + action = 'UPDATE_PARTIAL'; + break; + + default: + action = req.method; + } + + if ( + `${req.method} ${req.route.path}` === + 'GET /inputs/available-entities/:plugin' + ) { + action = 'GET_ENTITIES'; + } + + return user.permissions.includes(Permissions.INPUT[action].seqid); +}) export class InputsController { inputService: InputsService; logger: any; @@ -57,8 +88,7 @@ export class InputsController { customer: data.info.customer, }); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.testConnection(data); + const response = await this.inputService.testConnection(data); return response; } @@ -74,8 +104,7 @@ export class InputsController { }, ); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.getColumns(data); + const response = await this.inputService.getColumns(data); return response; } @@ -88,8 +117,18 @@ export class InputsController { customer: createInputDto.info.customer, }); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.create(createInputDto); + const response = await this.inputService.create(createInputDto); + + return response; + } + + @Post(':id') + @ApiOkResponse({ type: Input }) + async reCreate(@Param('id') id: string, @Body() input: CreateInputReq) { + if (!id) id = id; + console.log(`POST /${id}`, 'ON RECREATE ROUTE'); + + const response = await this.inputService.reCreate(input); return response; } @@ -101,9 +140,7 @@ export class InputsController { customer: body.info.customer, }); - const inputService = new InputsService(this.inputsClientService); - - const response = await inputService.findAll(body); + const response = await this.inputService.findAll(body); return response; } @@ -115,9 +152,8 @@ export class InputsController { user: body.info.user_id, customer: body.info.customer, }); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.findOne({ id, ...body }); + const response = await this.inputService.findOne({ id, ...body }); return response; } @@ -132,9 +168,8 @@ export class InputsController { user: updateInputDto.info.user_id, customer: updateInputDto.info.costumer_id, }); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.update(id, updateInputDto, info); + const response = await this.inputService.update(id, updateInputDto, info); return response; } @@ -148,9 +183,7 @@ export class InputsController { customer: data.info.customer, }); - const inputService = new InputsService(this.inputsClientService); - - const response = await inputService.remove({ id, ...data }); + const response = await this.inputService.remove({ id, ...data }); return response; } diff --git a/src/modules/inputs/inputs.service.ts b/src/modules/inputs/inputs.service.ts index 2d41455..a7c3715 100644 --- a/src/modules/inputs/inputs.service.ts +++ b/src/modules/inputs/inputs.service.ts @@ -75,6 +75,13 @@ export class InputsService { const adjustedInput = this.adjustInputPayload(response.input); return { ...response, input: adjustedInput }; } + async reCreate(data) { + const { info, cron } = data; + if (cron) this.validateCron({ info, cron }); + const response = await this.inputClient.createGeneric(data); + const adjustedInput = this.adjustInputPayload(response.input); + return { ...response, input: adjustedInput }; + } async getAvailableEntities(data): Promise<{ entities: string[] }> { return await this.inputClient.getAvailableEntities(data); } diff --git a/src/modules/oauth/oauth.controller.ts b/src/modules/oauth/oauth.controller.ts new file mode 100644 index 0000000..7feebae --- /dev/null +++ b/src/modules/oauth/oauth.controller.ts @@ -0,0 +1,117 @@ +import { Controller, Get, Redirect, Req, UseGuards } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { AuthGuard } from '@nestjs/passport'; +import { InputsClientService } from 'src/clients/inputs/client.service'; +import { InputsService } from '../inputs/inputs.service'; +import { Request } from 'express'; + +@ApiTags('oauth') +@Controller('oauth') +export class OauthController { + inputService: InputsService; + frontendRedirectUri = ''; + constructor(private inputsClientService: InputsClientService) { + this.inputService = new InputsService(this.inputsClientService); + switch (process.env.ENV) { + case 'dev': + case 'stg': + this.frontendRedirectUri = `https://app.${process.env.ENV}.dadosfera.ai/coletix/auth-callback`; + break; + case 'prd': + this.frontendRedirectUri = `https://app.dadosfera.ai/coletix/auth-callback`; + break; + default: + this.frontendRedirectUri = `http://localhost:4200/coletix/auth-callback`; + } + } + @Get('hubspot') + @UseGuards(AuthGuard('hubspot')) + async oauthHubspot() { + return true; + } + + @Get('hubspot/callback') + @UseGuards(AuthGuard('hubspot')) + @Redirect() + async oauthHubspotCallback(@Req() req) { + return await this.callback(req, 'hubspot'); + } + + @Get('googleads') + @UseGuards(AuthGuard('google')) + async oauthGoogleAds() { + return true; + } + + @Get('googleads/callback') + @UseGuards(AuthGuard('google')) + @Redirect() + async oauthGoogleAdsCallback(@Req() req) { + return await this.callback(req, 'googleads'); + } + + @Get('google-sheets') + @UseGuards(AuthGuard('google')) + async oauthGoogleSheets() { + return true; + } + + @Get('google-sheets/callback') + @UseGuards(AuthGuard('google')) + @Redirect() + async oauthGoogleSheetsCallback(@Req() req) { + return await this.callback(req, 'google-sheets'); + } + + @Get('facebook') + @UseGuards(AuthGuard('facebook')) + async oauthFacebook() { + return true; + } + + @Get('facebook/callback') + @UseGuards(AuthGuard('facebook')) + @Redirect() + async oauthFacebookCallback(@Req() req) { + return await this.callback(req, 'facebook'); + } + + @Get('mailchimp') + @UseGuards(AuthGuard('mailchimp')) + async oauthMailchimp() { + return true; + } + + @Get('mailchimp/callback') + @UseGuards(AuthGuard('mailchimp')) + @Redirect() + async oauthMailchimpCallback(@Req() req) { + return await this.callback(req, 'mailchimp'); + } + + async callback(@Req() req: Request, plugin) { + const { error, state: customer_id } = req.query; + + if (error) + return { + url: `${this.frontendRedirectUri}?error=${error}`, + }; + const request: any = req; + const { authInfo } = request; + + if (!authInfo) + return { + url: `${this.frontendRedirectUri}?error=invalid_credentials`, + }; + + const { accessToken: access_token, refreshToken: refresh_token } = authInfo; + + const response = await this.inputService.create({ + info: { customer_id, customer: 'customer', user_id: 'empty' }, + plugin, + credentials: { access_token, refresh_token }, + }); + + return { url: `${this.frontendRedirectUri}?input_id=${response.input.id}` }; + } +} diff --git a/src/modules/oauth/passport-strategies/facebook-strategy.ts b/src/modules/oauth/passport-strategies/facebook-strategy.ts new file mode 100644 index 0000000..f8e5ec5 --- /dev/null +++ b/src/modules/oauth/passport-strategies/facebook-strategy.ts @@ -0,0 +1,32 @@ +import { + Profile, + Strategy, + StrategyOptionWithRequest, + VerifyFunction, +} from 'passport-facebook'; +import { PassportStrategy } from '@nestjs/passport'; +import { Inject, Injectable } from '@nestjs/common'; +import { OauthSecrets } from 'src/utils/OauthSecrets'; + +@Injectable() +export class FacebookStrategy extends PassportStrategy(Strategy) { + constructor( + @Inject('OAUTH_SECRETS') + private readonly oauthSecrets: OauthSecrets, + ) { + const options: StrategyOptionWithRequest = { + clientID: oauthSecrets.facebook.client_id, + clientSecret: oauthSecrets.facebook.client_secret, + callbackURL: oauthSecrets.facebook.redirect_uri, + passReqToCallback: true, + }; + const verify: VerifyFunction = ( + accessToken: string, + refreshToken: string, + profile: Profile, + done: (error: any, user?: any, info?: any) => void, + ) => done(null, profile, { accessToken, refreshToken }); + + super(options, verify); + } +} diff --git a/src/modules/oauth/passport-strategies/google-strategy.ts b/src/modules/oauth/passport-strategies/google-strategy.ts new file mode 100644 index 0000000..0c9c1dc --- /dev/null +++ b/src/modules/oauth/passport-strategies/google-strategy.ts @@ -0,0 +1,68 @@ +import { Profile, Strategy, StrategyOptions } from 'passport-google-oauth20'; +import { PassportStrategy } from '@nestjs/passport'; +import { Inject, Injectable } from '@nestjs/common'; +import { OauthSecrets } from 'src/utils/OauthSecrets'; + +@Injectable() +export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { + redirect_uri: string; + constructor( + @Inject('OAUTH_SECRETS') + private readonly oauthSecrets: OauthSecrets, + ) { + const options: StrategyOptions = { + clientID: oauthSecrets.google.client_id, + clientSecret: oauthSecrets.google.client_secret, + callbackURL: '/oauth/googleads/callback', + }; + const verify = ( + accessToken: string, + refreshToken: string, + profile: Profile, + done, + ) => { + console.log('verify'); + return done(null, profile, { accessToken, refreshToken }); + }; + + super(options, verify); + switch (process.env.ENV) { + case 'dev': + case 'stg': + this.redirect_uri = `https://maestro.${process.env.ENV}.dadosfera.ai/oauth`; + break; + case 'prd': + this.redirect_uri = `https://maestro.dadosfera.ai/oauth`; + break; + default: + this.redirect_uri = `/oauth`; + break; + } + } + + authenticate(req, options) { + const plugin: string = req.route.path + .replace('/oauth/', '') + .replace('/callback', ''); + + const { customer_id } = req.query; + options.scope = ['https://www.googleapis.com/auth/userinfo.email']; + options.callbackURL = `${this.redirect_uri}/${plugin}/callback`; + + switch (plugin) { + case 'googleads': + options.scope.push('https://www.googleapis.com/auth/adwords'); + break; + case 'google-sheets': + options.scope.push( + 'https://www.googleapis.com/auth/drive.metadata.readonly', + 'https://www.googleapis.com/auth/spreadsheets.readonly', + ); + break; + } + options.state = customer_id; + options.accessType = 'offline'; + options.prompt = 'consent'; + super.authenticate(req, options); + } +} diff --git a/src/modules/oauth/passport-strategies/hubspot-strategy.ts b/src/modules/oauth/passport-strategies/hubspot-strategy.ts new file mode 100644 index 0000000..2e33567 --- /dev/null +++ b/src/modules/oauth/passport-strategies/hubspot-strategy.ts @@ -0,0 +1,33 @@ +import { Strategy } from 'passport-hubspot-oauth2'; +import { PassportStrategy } from '@nestjs/passport'; +import { Inject, Injectable } from '@nestjs/common'; +import { OauthSecrets } from 'src/utils/OauthSecrets'; + +@Injectable() +export class HubspotStrategy extends PassportStrategy(Strategy) { + constructor( + @Inject('OAUTH_SECRETS') + private readonly oauthSecrets: OauthSecrets, + ) { + super( + { + clientID: oauthSecrets.hubspot.client_id, + clientSecret: oauthSecrets.hubspot.client_secret, + callbackURL: oauthSecrets.hubspot.redirect_uri, + redirectUri: oauthSecrets.hubspot.redirect_uri, + scope: + 'automation business-intelligence oauth forms integration-sync sales-email-read crm.lists.read crm.objects.contacts.read crm.schemas.contacts.read crm.objects.companies.read crm.objects.deals.read crm.schemas.companies.read crm.schemas.deals.read crm.objects.owners.read crm.objects.quotes.read crm.schemas.quotes.read crm.objects.line_items.read crm.schemas.line_items.read', + passReqToCallback: true, + }, + (accessToken, refreshToken, tokenInfo, profile, done) => { + return done(null, profile, { accessToken, refreshToken, tokenInfo }); + }, + ); + } + + authenticate(req, options) { + const { customer_id } = req.query; + options.state = customer_id; + super.authenticate(req, options); + } +} diff --git a/src/modules/oauth/passport-strategies/mailchimp-strategy.ts b/src/modules/oauth/passport-strategies/mailchimp-strategy.ts new file mode 100644 index 0000000..b2e1ccd --- /dev/null +++ b/src/modules/oauth/passport-strategies/mailchimp-strategy.ts @@ -0,0 +1,35 @@ +import { Strategy } from 'passport-mailchimp'; +import { PassportStrategy } from '@nestjs/passport'; +import { Inject, Injectable, Req } from '@nestjs/common'; +import { OauthSecrets } from 'src/utils/OauthSecrets'; + +@Injectable() +export class MailChimpStrategy extends PassportStrategy(Strategy, 'mailchimp') { + constructor( + @Inject('OAUTH_SECRETS') + private readonly oauthSecrets: OauthSecrets, + ) { + const options = { + clientID: oauthSecrets.mailchimp.client_id, + clientSecret: oauthSecrets.mailchimp.client_secret, + callbackURL: oauthSecrets.mailchimp.redirect_uri, + scope: '', + }; + const verify = ( + accessToken: string, + refreshToken: string, + profile: any, + done, + ) => { + return done(null, profile, { accessToken, refreshToken }); + }; + + super(options, verify); + } + + authenticate(@Req() req, options) { + const { customer_id } = req.query; + options.state = customer_id; + super.authenticate(req, options); + } +} diff --git a/src/modules/outputs/outputs.controllers.ts b/src/modules/outputs/outputs.controllers.ts index e7ce188..c443215 100644 --- a/src/modules/outputs/outputs.controllers.ts +++ b/src/modules/outputs/outputs.controllers.ts @@ -9,10 +9,33 @@ import { Put, } from '@nestjs/common'; import { Payload } from '@nestjs/microservices'; +import { ApiTags } from '@nestjs/swagger'; import { OutputsClientService } from 'src/clients/outputs/client.service'; +import { AuthenticateCondition } from 'src/authentication/authentication.decorator'; +import { Permissions } from '../../authentication/permissions.enum'; import { OutputsService } from './outputs.service'; import { DadosferaLogger } from 'dadosfera-logs'; + +@ApiTags('Outputs') @Controller('outputs') +@AuthenticateCondition((req, user) => { + let action; + + switch (req.method) { + case 'POST': + action = 'CREATE'; + break; + + case 'PUT': + action = 'UPDATE'; + break; + + default: + action = req.method; + } + + return user.permissions.includes(Permissions.OUTPUT[action].seqid); +}) export class OutputsController { logger: any; constructor( diff --git a/src/modules/pipelines/pipelines.controller.ts b/src/modules/pipelines/pipelines.controller.ts index 2cc68fe..d34a23e 100644 --- a/src/modules/pipelines/pipelines.controller.ts +++ b/src/modules/pipelines/pipelines.controller.ts @@ -8,11 +8,33 @@ import { Post, Put, } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; import { PipelinesClientService } from 'src/clients/pipelines/client.service'; +import { AuthenticateCondition } from 'src/authentication/authentication.decorator'; +import { Permissions } from '../../authentication/permissions.enum'; import { PipelinesService } from './pipelines.service'; import { DadosferaLogger } from 'dadosfera-logs'; +@ApiTags('Pipelines') @Controller('pipelines') +@AuthenticateCondition((req, user) => { + let action; + + switch (req.method) { + case 'POST': + action = 'CREATE'; + break; + + case 'PUT': + action = 'UPDATE'; + break; + + default: + action = req.method; + } + + return user.permissions.includes(Permissions.PIPELINE[action].seqid); +}) export class PipelinesController { logger: any; constructor( diff --git a/src/modules/pipelines/pipelines.service.ts b/src/modules/pipelines/pipelines.service.ts index f0987f0..416ae97 100644 --- a/src/modules/pipelines/pipelines.service.ts +++ b/src/modules/pipelines/pipelines.service.ts @@ -17,19 +17,14 @@ export class PipelinesService { } async create(createPipelineDto) { - try { - const createPipelineResponse = await this.pipelineClient.create( - createPipelineDto, - ); + const createPipelineResponse = await this.pipelineClient.create( + createPipelineDto, + ); - const pipeline = objectCamelToSnake(createPipelineResponse); - this.adjustPayload(pipeline.pipeline); + const pipeline = objectCamelToSnake(createPipelineResponse); + this.adjustPayload(pipeline.pipeline); - return pipeline; - } catch (err) { - console.log(err); - throw new HttpException(err.message, HttpStatus.NOT_FOUND); - } + return pipeline; } async findOne(data: IIdRequest) { diff --git a/src/modules/transformations/transformations.controller.ts b/src/modules/transformations/transformations.controller.ts index 419c978..71b2d21 100644 --- a/src/modules/transformations/transformations.controller.ts +++ b/src/modules/transformations/transformations.controller.ts @@ -9,11 +9,34 @@ import { Put, } from '@nestjs/common'; import { Payload } from '@nestjs/microservices'; +import { ApiTags } from '@nestjs/swagger'; import { TransformationsClientService } from 'src/clients/transformations/client.service'; import { IIdRequest } from 'src/clients/transformations/interfaces'; +import { AuthenticateCondition } from 'src/authentication/authentication.decorator'; +import { Permissions } from '../../authentication/permissions.enum'; import { TransformationsService } from './transformations.service'; import { DadosferaLogger } from 'dadosfera-logs'; + +@ApiTags('Transformations') @Controller('transformations') +@AuthenticateCondition((req, user) => { + let action; + + switch (req.method) { + case 'POST': + action = 'CREATE'; + break; + + case 'PUT': + action = 'UPDATE'; + break; + + default: + action = req.method; + } + + return user.permissions.includes(Permissions.TRANSFORMATIONS[action].seqid); +}) export class TransformationsController { logger: any; constructor( diff --git a/src/utils/ErrorBuilder.ts b/src/utils/ErrorBuilder.ts index a95f71b..fd7095d 100644 --- a/src/utils/ErrorBuilder.ts +++ b/src/utils/ErrorBuilder.ts @@ -1,131 +1,145 @@ -import { HttpStatus, HttpException } from '@nestjs/common'; +import { HttpStatus, HttpException, Logger } from '@nestjs/common'; +import { RpcException } from '@nestjs/microservices'; import ErrorCodes from './errorCodes'; -function Builder({ statusCode, message, error, code }) { - return new HttpException({ statusCode, message, error, code }, statusCode); -} - -export default function ErrorBuilder(code: string) { - console.log(code); - +function enrichErrorCode(code: string) { switch (code) { case ErrorCodes.AUTH.WRONG_CREDENTIALS: - return Builder({ + return { statusCode: HttpStatus.UNAUTHORIZED, error: 'Não autenticado', message: 'Usuário ou senha incorretos', code, - }); + }; case ErrorCodes.AUTH.WRONG_PASSWORD_CONFIRMATION: - return Builder({ + return { statusCode: HttpStatus.UNAUTHORIZED, error: 'Senha incorreta', message: 'Confirmação de senha incorreta', code, - }); + }; case ErrorCodes.AUTH.TOTP_NOT_ENABLED: - return Builder({ + return { statusCode: HttpStatus.PRECONDITION_FAILED, error: 'Não permitido', message: 'A autenticação multifator não está habilitada', code, - }); + }; case ErrorCodes.AUTH.TOTP_ALREADY_ENABLED: - return Builder({ + return { statusCode: HttpStatus.PRECONDITION_FAILED, error: 'Não permitido', message: 'A autenticação multifator já está habilitada', code, - }); + }; case ErrorCodes.AUTH.TOTP_ALREADY_DISABLED: - return Builder({ + return { statusCode: HttpStatus.PRECONDITION_FAILED, error: 'Não permitido', message: 'A autenticação multifator já está desabilitada', code, - }); + }; case ErrorCodes.AUTH.TOTP_REQUIRED: - return Builder({ + return { statusCode: HttpStatus.UNAUTHORIZED, error: 'Não autenticado', message: 'Informe o token de autenticação multifator', code, - }); + }; case ErrorCodes.AUTH.CODE_MISMATCH: case ErrorCodes.AUTH.CODE_ALREADY_USED: - return Builder({ + return { statusCode: HttpStatus.UNAUTHORIZED, error: 'Não autenticado', message: 'Token de autenticação multifator inválido', code, - }); + }; case ErrorCodes.AUTH.RESET_PASSWORD_CODE_EXPIRED: - return Builder({ + return { statusCode: HttpStatus.UNAUTHORIZED, error: 'Não permitido', message: 'Token para recuperar senha expirado', code, - }); + }; case ErrorCodes.AUTH.RESET_PASSWORD_CODE_INVALID: - return Builder({ + return { statusCode: HttpStatus.UNAUTHORIZED, error: 'Não permitido', message: 'Token para recuperar senha inválido', code, - }); + }; case ErrorCodes.AUTH.WEAK_NEW_PASSWORD: - return Builder({ + return { statusCode: HttpStatus.BAD_REQUEST, error: 'Não permitido', message: 'Senha muito fraca. Escolha uma senha mais forte', code, - }); + }; case ErrorCodes.RATE_LIMIT: - return Builder({ + return { statusCode: HttpStatus.TOO_MANY_REQUESTS, error: 'Limite excedido', message: 'Você tentou realizar essa operação muitas vezes. Tente novamente mais tarde', code, - }); + }; case ErrorCodes.AUTH.UNAUTHORIZED: - return Builder({ + return { statusCode: HttpStatus.UNAUTHORIZED, error: 'Não autenticado', message: 'É necessário estar logado para realizar essa operação', code, - }); + }; case ErrorCodes.AUTH.FORBIDDEN: - return Builder({ + return { statusCode: HttpStatus.FORBIDDEN, error: 'Não autorizado', message: 'Você não tem permissões suficientes para realizar essa operação', code, - }); + }; case ErrorCodes.INTERNAL: case ErrorCodes.UNKNOWN: default: - return Builder({ + return { statusCode: HttpStatus.INTERNAL_SERVER_ERROR, error: 'Desconhecido', message: 'Erro desconhecido. Tente novamente ou entre em contato com o suporte', code: ErrorCodes.UNKNOWN, - }); + }; + } +} + +const logger = new Logger(); + +export default class ErrorBuilder extends HttpException { + code: string; + + constructor(code: string | RpcException) { + if (typeof code !== 'string') { + logger.log(code.stack); + code = (code as any).details as string; + } else { + logger.log(code); + } + + const { statusCode, message, error, code: rCode } = enrichErrorCode(code); + super({ statusCode, message, error, code: rCode }, statusCode); + this.code = code; } } diff --git a/src/utils/OauthSecrets.ts b/src/utils/OauthSecrets.ts new file mode 100644 index 0000000..a5786fa --- /dev/null +++ b/src/utils/OauthSecrets.ts @@ -0,0 +1,40 @@ +import { + SecretsManagerClient, + GetSecretValueCommand, +} from '@aws-sdk/client-secrets-manager'; + +class OauthSecretsObject { + client_id = ''; + client_secret = ''; + redirect_uri = ''; +} +// @Injectable() +export class OauthSecrets { + hubspot = new OauthSecretsObject(); + google = new OauthSecretsObject(); + mailchimp = new OauthSecretsObject(); + facebook = new OauthSecretsObject(); +} +export async function getOauthSecrets() { + const secrets = new OauthSecrets(); + const path = process.env.SM_OAUTH_PATH; + const secretsManagerClient = new SecretsManagerClient({}); + for (const key in secrets) { + const getSecretComand = new GetSecretValueCommand({ + SecretId: `${path}/${key}`, + }); + const res = await secretsManagerClient + .send(getSecretComand) + .catch(() => null); + if (res) { + secrets[key] = JSON.parse(res.SecretString); + } else { + secrets[key] = { + client_id: 'id', + client_secret: 'id', + redirect_uri: 'id', + }; + } + } + return secrets; +} diff --git a/src/utils/grpcHandler.ts b/src/utils/grpcHandler.ts new file mode 100644 index 0000000..0e7d77b --- /dev/null +++ b/src/utils/grpcHandler.ts @@ -0,0 +1,19 @@ +import { Logger } from '@nestjs/common'; +import { RpcException } from '@nestjs/microservices'; +import { from } from 'rxjs'; + +import ErrorBuilder from './ErrorBuilder'; + +const logger = new Logger(); + +export default async function grpcHandler(method: Promise) { + return new Promise((resolve, reject) => { + from(method).subscribe({ + next: resolve, + error: reject, + complete: () => logger.log('done'), + }); + }).catch((err: RpcException) => { + throw new ErrorBuilder(err); + }); +} diff --git a/swagger.json b/swagger.json index 18440db..837addc 100644 --- a/swagger.json +++ b/swagger.json @@ -1 +1 @@ -{"openapi":"3.0.0","paths":{"/inputs/available-entities/{plugin}":{"get":{"operationId":"InputsController_getAvailableEntities","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAvailableEntitiesRes"}}}}},"tags":["inputs"]}},"/inputs/test-connection":{"post":{"operationId":"InputsController_testConnection","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionRes"}}}}},"tags":["inputs"]}},"/inputs/test-connection/get-columns":{"post":{"operationId":"InputsController_getColumns","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsRes"}}}}},"tags":["inputs"]}},"/inputs":{"post":{"operationId":"InputsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInputReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Input"}}}}},"tags":["inputs"]},"get":{"operationId":"InputsController_findAll","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]}},"/inputs/{id}":{"get":{"operationId":"InputsController_findOne","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]},"patch":{"operationId":"InputsController_update","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]},"delete":{"operationId":"InputsController_delete","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]}},"/transformations":{"post":{"operationId":"TransformationsController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"TransformationsController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/transformations/{id}":{"get":{"operationId":"TransformationsController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"TransformationsController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"TransformationsController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/outputs":{"post":{"operationId":"OutputsController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"OutputsController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/outputs/{id}":{"get":{"operationId":"OutputsController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"OutputsController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"OutputsController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/start/{id}":{"post":{"operationId":"PipelinesController_activate","parameters":[],"responses":{"201":{"description":""}}}},"/pipelines/{id}/status":{"get":{"operationId":"PipelinesController_getPipelineStatus","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/{id}/{details}":{"get":{"operationId":"PipelinesController_getPipelineLogs","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines":{"post":{"operationId":"PipelinesController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"PipelinesController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/{id}":{"get":{"operationId":"PipelinesController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"PipelinesController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"PipelinesController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/auth":{"post":{"operationId":"AuthController_signIn_old","parameters":[],"responses":{"200":{"description":""}}}},"/auth/login":{"post":{"operationId":"AuthController_signIn_login","parameters":[],"responses":{"200":{"description":""}}}},"/auth/sign-in":{"post":{"operationId":"AuthController_signIn","parameters":[],"responses":{"200":{"description":""}}}},"/auth/refresh-access-token":{"post":{"operationId":"AuthController_refreshAccessToken","parameters":[],"responses":{"200":{"description":""}}}},"/auth/enable-totp":{"post":{"operationId":"AuthController_enableTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/disable-totp":{"post":{"operationId":"AuthController_disableTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/dismiss-totp":{"post":{"operationId":"AuthController_dismissTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/verify-totp":{"post":{"operationId":"AuthController_verifyTotp","parameters":[],"responses":{"200":{"description":""}}}},"/auth/change-password":{"post":{"operationId":"AuthController_changePassword","parameters":[],"responses":{"200":{"description":""}}}},"/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","parameters":[],"responses":{"200":{"description":""}}}},"/auth/verify-reset-password-code":{"post":{"operationId":"AuthController_verifyResetPasswordCode","parameters":[],"responses":{"200":{"description":""}}}},"/auth/confirm-reset-password":{"post":{"operationId":"AuthController_confirmResetPassword","parameters":[],"responses":{"200":{"description":""}}}},"/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/all":{"get":{"operationId":"CatalogController_catalogAll","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data_apps":{"get":{"operationId":"CatalogController_dataAppsAll","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data_apps/{id}":{"delete":{"operationId":"CatalogController_dataAppsOne","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/dashboard-metabase":{"get":{"operationId":"CatalogController_getAllDashboardMetabase","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/dashboard-metabase/{id}":{"get":{"operationId":"CatalogController_getOneDashboardMetabase","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-metadata":{"get":{"operationId":"CatalogController_getAllTableMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneTableMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/column-metadata":{"get":{"operationId":"CatalogController_getOneColumnMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/column-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneColumnMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-preview":{"get":{"operationId":"CatalogController_getOneDataPreview","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-status":{"get":{"operationId":"CatalogController_createDataStatus","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-description":{"get":{"operationId":"CatalogController_getDataDescription","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataDescription","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-docs":{"get":{"operationId":"CatalogController_getDataDocs","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataDocs","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-rating":{"get":{"operationId":"CatalogController_getDataRating","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataRating","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/summary-rating/{id}":{"get":{"operationId":"CatalogController_getSummaryRating","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-comment":{"get":{"operationId":"CatalogController_getDataComment","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataComment","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-review":{"get":{"operationId":"CatalogController_getDataReview","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/tags":{"post":{"operationId":"CatalogController_createTags","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"CatalogController_findAllTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/tags/{id}":{"delete":{"operationId":"CatalogController_deleteTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-tags":{"post":{"operationId":"CatalogController_createTableTags","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"CatalogController_getAllTableTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-tags/{id}":{"delete":{"operationId":"CatalogController_deleteTableTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-rules":{"get":{"operationId":"CatalogController_getTableRules","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-rules/{id}":{"delete":{"operationId":"CatalogController_deleteTableRules","parameters":[],"responses":{"200":{"description":""}}}}},"info":{"title":"Maestro Grpc Documentation","description":"Documentation for Maestro gateway","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetAvailableEntitiesRes":{"type":"object","properties":{"entities":{"type":"array","items":{"type":"string"}}},"required":["entities"]},"CredentialsJdbc":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"}}},"TestConnectionReq":{"type":"object","properties":{"plugin":{"type":"string"},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"},"info":{"type":"object"}},"required":["plugin","credentials"]},"TestConnectionRes":{"type":"object","properties":{"connection_state":{"type":"boolean"},"total_entities":{"type":"number"},"database_tables":{"type":"array","items":{"type":"string"}}},"required":["connection_state","total_entities","database_tables"]},"TestConnectionGetColumnsReq":{"type":"object","properties":{"plugin":{"type":"string"},"tables":{"type":"array","items":{"type":"string"}},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"},"id":{"type":"string"},"info":{"type":"object"}},"required":["plugin","tables"]},"TestConnectionGetColumnsRes":{"type":"object","properties":{"tables":{"type":"array","items":{"type":"string"}}},"required":["tables"]},"FileFormatParams":{"type":"object","properties":{"file_format":{"type":"string"},"encoding":{"type":"string"}}},"GoogleAnalyticsClientSecrets":{"type":"object","properties":{"type":{"type":"string"},"project_id":{"type":"string"},"private_key_id":{"type":"string"},"private_key":{"type":"string"},"client_email":{"type":"string"},"client_id":{"type":"string"},"auth_uri":{"type":"string"},"token_uri":{"type":"string"},"auth_provider_x509_cert_url":{"type":"string"},"client_x509_cert_url":{"type":"string"}},"required":["type","project_id","private_key_id","private_key","client_email","client_id","auth_uri","token_uri","auth_provider_x509_cert_url","client_x509_cert_url"]},"Credentials":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"},"connection_type":{"type":"string"},"client_aws_access_key_id":{"type":"string"},"client_aws_secret_access_key":{"type":"string"},"client_bucket":{"type":"string"},"file_to_extract":{"type":"string"},"file_format_params":{"$ref":"#/components/schemas/FileFormatParams"},"view_id":{"type":"string"},"client_secrets":{"$ref":"#/components/schemas/GoogleAnalyticsClientSecrets"},"start_date":{"type":"string"},"end_date":{"type":"string"},"oauth_code":{"type":"string"}},"required":["connection_type"]},"OauthObject":{"type":"object","properties":{"get_tokens_url":{"type":"string"},"get_tokens_url_params":{"type":"string"},"get_tokens_set_response":{"type":"object"},"content_type":{"type":"string"}}},"InputOptions":{"type":"object","properties":{"oauth":{"$ref":"#/components/schemas/OauthObject"},"skip_select_columns":{"type":"boolean"},"skip_select_entities":{"type":"boolean"},"skip_transformation":{"type":"boolean"}}},"CreateInputReq":{"type":"object","properties":{"plugin":{"type":"string"},"category":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"name":{"type":"string"},"options":{"$ref":"#/components/schemas/InputOptions"},"info":{"type":"object"}},"required":["plugin","category","credentials","name"]},"Input":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string"},"plugin":{"type":"string"},"name":{"type":"string"},"cron":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"client_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"info":{"type":"object"}},"required":["id","category","plugin","name","cron","credentials","client_id","created_at","updated_at"]}}}} \ No newline at end of file +{"openapi":"3.0.0","paths":{"/inputs/available-entities/{plugin}":{"get":{"operationId":"InputsController_getAvailableEntities","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAvailableEntitiesRes"}}}}},"tags":["inputs"]}},"/inputs/test-connection":{"post":{"operationId":"InputsController_testConnection","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionRes"}}}},"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["inputs"]}},"/inputs/test-connection/get-columns":{"post":{"operationId":"InputsController_getColumns","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsRes"}}}},"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["inputs"]}},"/inputs":{"post":{"operationId":"InputsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInputReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Input"}}}},"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["inputs"]},"get":{"operationId":"InputsController_findAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["inputs"]}},"/inputs/{id}":{"post":{"operationId":"InputsController_reCreate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInputReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Input"}}}},"201":{"description":""}},"tags":["inputs"]},"get":{"operationId":"InputsController_findOne","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["inputs"]},"patch":{"operationId":"InputsController_update","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["inputs"]},"delete":{"operationId":"InputsController_delete","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["inputs"]}},"/transformations":{"post":{"operationId":"TransformationsController_create","parameters":[],"responses":{"201":{"description":""}},"tags":["Transformations"]},"get":{"operationId":"TransformationsController_findAll","parameters":[],"responses":{"200":{"description":""}},"tags":["Transformations"]}},"/transformations/{id}":{"get":{"operationId":"TransformationsController_findOne","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Transformations"]},"put":{"operationId":"TransformationsController_update","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Transformations"]},"delete":{"operationId":"TransformationsController_delete","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Transformations"]}},"/outputs":{"post":{"operationId":"OutputsController_create","parameters":[],"responses":{"201":{"description":""}},"tags":["Outputs"]},"get":{"operationId":"OutputsController_findAll","parameters":[],"responses":{"200":{"description":""}},"tags":["Outputs"]}},"/outputs/{id}":{"get":{"operationId":"OutputsController_findOne","parameters":[],"responses":{"200":{"description":""}},"tags":["Outputs"]},"put":{"operationId":"OutputsController_update","parameters":[],"responses":{"200":{"description":""}},"tags":["Outputs"]},"delete":{"operationId":"OutputsController_delete","parameters":[],"responses":{"200":{"description":""}},"tags":["Outputs"]}},"/pipelines/start/{id}":{"post":{"operationId":"PipelinesController_activate","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Pipelines"]}},"/pipelines/{id}/status":{"get":{"operationId":"PipelinesController_getPipelineStatus","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Pipelines"]}},"/pipelines/{id}/{details}":{"get":{"operationId":"PipelinesController_getPipelineLogs","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Pipelines"]}},"/pipelines":{"post":{"operationId":"PipelinesController_create","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Pipelines"]},"get":{"operationId":"PipelinesController_findAll","parameters":[],"responses":{"200":{"description":""}},"tags":["Pipelines"]}},"/pipelines/{id}":{"get":{"operationId":"PipelinesController_findOne","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Pipelines"]},"put":{"operationId":"PipelinesController_update","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Pipelines"]},"delete":{"operationId":"PipelinesController_delete","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Pipelines"]}},"/auth/sign-in":{"post":{"operationId":"AuthController_signIn","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/refresh-access-token":{"post":{"operationId":"AuthController_refreshAccessToken","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/change-password":{"post":{"operationId":"AuthController_changePassword","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/verify-reset-password-code":{"post":{"operationId":"AuthController_verifyResetPasswordCode","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/confirm-reset-password":{"post":{"operationId":"AuthController_confirmResetPassword","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/enable-totp":{"post":{"operationId":"AuthController_enableTotpMFA","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/disable-totp":{"post":{"operationId":"AuthController_disableTotpMFA","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/dismiss-totp":{"post":{"operationId":"AuthController_dismissTotpMFA","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/auth/verify-totp":{"post":{"operationId":"AuthController_verifyTotp","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Auth"]}},"/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":""}},"tags":["Health"]}},"/catalog/all":{"get":{"operationId":"CatalogController_catalogAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data_apps":{"get":{"operationId":"CatalogController_dataAppsAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data_apps/{id}":{"delete":{"operationId":"CatalogController_dataAppsOne","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/dashboard-metabase":{"get":{"operationId":"CatalogController_getAllDashboardMetabase","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/dashboard-metabase/{id}":{"get":{"operationId":"CatalogController_getOneDashboardMetabase","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/table-metadata":{"get":{"operationId":"CatalogController_getAllTableMetadata","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/table-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneTableMetadata","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/column-metadata":{"get":{"operationId":"CatalogController_getOneColumnMetadata","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/column-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneColumnMetadata","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data-preview":{"get":{"operationId":"CatalogController_getOneDataPreview","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data-status":{"get":{"operationId":"CatalogController_createDataStatus","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data-description":{"get":{"operationId":"CatalogController_getDataDescription","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]},"post":{"operationId":"CatalogController_createDataDescription","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data-docs":{"get":{"operationId":"CatalogController_getDataDocs","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]},"post":{"operationId":"CatalogController_createDataDocs","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data-rating":{"get":{"operationId":"CatalogController_getDataRating","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]},"post":{"operationId":"CatalogController_createDataRating","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/summary-rating/{id}":{"get":{"operationId":"CatalogController_getSummaryRating","parameters":[],"responses":{"200":{"description":""}},"tags":["Catalog"]}},"/catalog/data-comment":{"get":{"operationId":"CatalogController_getDataComment","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]},"post":{"operationId":"CatalogController_createDataComment","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/data-review":{"get":{"operationId":"CatalogController_getDataReview","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/tags":{"post":{"operationId":"CatalogController_createTags","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]},"get":{"operationId":"CatalogController_findAllTags","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/tags/{id}":{"delete":{"operationId":"CatalogController_deleteTags","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/table-tags":{"post":{"operationId":"CatalogController_createTableTags","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]},"get":{"operationId":"CatalogController_getAllTableTags","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/table-tags/{id}":{"delete":{"operationId":"CatalogController_deleteTableTags","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/table-rules":{"get":{"operationId":"CatalogController_getTableRules","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/catalog/table-rules/{id}":{"delete":{"operationId":"CatalogController_deleteTableRules","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Catalog"]}},"/oauth/hubspot":{"get":{"operationId":"OauthController_oauthHubspot","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"boolean"}}}}},"tags":["oauth"]}},"/oauth/hubspot/callback":{"get":{"operationId":"OauthController_oauthHubspotCallback","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}},"/oauth/googleads":{"get":{"operationId":"OauthController_oauthGoogleAds","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"boolean"}}}}},"tags":["oauth"]}},"/oauth/googleads/callback":{"get":{"operationId":"OauthController_oauthGoogleAdsCallback","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}},"/oauth/google-sheets":{"get":{"operationId":"OauthController_oauthGoogleSheets","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"boolean"}}}}},"tags":["oauth"]}},"/oauth/google-sheets/callback":{"get":{"operationId":"OauthController_oauthGoogleSheetsCallback","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}},"/oauth/facebook":{"get":{"operationId":"OauthController_oauthFacebook","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"boolean"}}}}},"tags":["oauth"]}},"/oauth/facebook/callback":{"get":{"operationId":"OauthController_oauthFacebookCallback","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}},"/oauth/mailchimp":{"get":{"operationId":"OauthController_oauthMailchimp","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"boolean"}}}}},"tags":["oauth"]}},"/oauth/mailchimp/callback":{"get":{"operationId":"OauthController_oauthMailchimpCallback","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}},"/connectors":{"post":{"operationId":"ConnectorController_uploadConnector","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateConnectorDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["connectors"],"security":[{"bearer":[]}]},"get":{"operationId":"ConnectorController_getAllConnectors","parameters":[{"name":"search","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["connectors"],"security":[{"bearer":[]}]}},"/connectors/upload":{"post":{"operationId":"ConnectorController_uploadFile","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UploadFileDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["connectors"],"security":[{"bearer":[]}]}},"/connectors/{plugin}":{"get":{"operationId":"ConnectorController_getConnector","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}},{"name":"version","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["connectors"],"security":[{"bearer":[]}]},"put":{"operationId":"ConnectorController_updateConnector","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["connectors"],"security":[{"bearer":[]}]},"delete":{"operationId":"ConnectorController_deleteConnector","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteConnectorDto"}}}},"responses":{"200":{"description":""}},"tags":["connectors"],"security":[{"bearer":[]}]}},"/connectors/{plugin}/details":{"get":{"operationId":"ConnectorController_getConnectorDetails","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}},{"name":"version","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["connectors"],"security":[{"bearer":[]}]}},"/connectors/{plugin}/add-tag":{"put":{"operationId":"ConnectorController_addTagOnConnector","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTagDto"}}}},"responses":{"200":{"description":""}},"tags":["connectors"],"security":[{"bearer":[]}]}},"/connectors/{plugin}/remove-tag":{"put":{"operationId":"ConnectorController_removeTagOnConnector","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveTagDto"}}}},"responses":{"200":{"description":""}},"tags":["connectors"],"security":[{"bearer":[]}]}}},"info":{"title":"Maestro","description":"Documentation for Maestro gateway","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetAvailableEntitiesRes":{"type":"object","properties":{"entities":{"type":"array","items":{"type":"string"}}},"required":["entities"]},"CredentialsJdbc":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"}}},"TestConnectionReq":{"type":"object","properties":{"plugin":{"type":"string"},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"},"info":{"type":"object"}},"required":["plugin","credentials"]},"TestConnectionRes":{"type":"object","properties":{"connection_state":{"type":"boolean"},"total_entities":{"type":"number"},"database_tables":{"type":"array","items":{"type":"string"}}},"required":["connection_state","total_entities","database_tables"]},"TestConnectionGetColumnsReq":{"type":"object","properties":{"plugin":{"type":"string"},"tables":{"type":"array","items":{"type":"string"}},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"},"id":{"type":"string"},"info":{"type":"object"}},"required":["plugin","tables"]},"TestConnectionGetColumnsRes":{"type":"object","properties":{"tables":{"type":"array","items":{"type":"string"}}},"required":["tables"]},"FileFormatParams":{"type":"object","properties":{"file_format":{"type":"string"},"encoding":{"type":"string"}}},"GoogleAnalyticsClientSecrets":{"type":"object","properties":{"type":{"type":"string"},"project_id":{"type":"string"},"private_key_id":{"type":"string"},"private_key":{"type":"string"},"client_email":{"type":"string"},"client_id":{"type":"string"},"auth_uri":{"type":"string"},"token_uri":{"type":"string"},"auth_provider_x509_cert_url":{"type":"string"},"client_x509_cert_url":{"type":"string"}},"required":["type","project_id","private_key_id","private_key","client_email","client_id","auth_uri","token_uri","auth_provider_x509_cert_url","client_x509_cert_url"]},"Credentials":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"},"connection_type":{"type":"string"},"client_aws_access_key_id":{"type":"string"},"client_aws_secret_access_key":{"type":"string"},"client_bucket":{"type":"string"},"file_to_extract":{"type":"string"},"file_format_params":{"$ref":"#/components/schemas/FileFormatParams"},"view_id":{"type":"string"},"client_secrets":{"$ref":"#/components/schemas/GoogleAnalyticsClientSecrets"},"start_date":{"type":"string"},"end_date":{"type":"string"},"oauth_code":{"type":"string"}},"required":["connection_type"]},"OauthObject":{"type":"object","properties":{"get_tokens_url":{"type":"string"},"get_tokens_url_params":{"type":"string"},"get_tokens_set_response":{"type":"object"},"content_type":{"type":"string"}}},"InputOptions":{"type":"object","properties":{"oauth":{"$ref":"#/components/schemas/OauthObject"},"skip_select_columns":{"type":"boolean"},"skip_select_entities":{"type":"boolean"},"skip_transformation":{"type":"boolean"}}},"CreateInputReq":{"type":"object","properties":{"id":{"type":"string"},"plugin":{"type":"string"},"category":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"name":{"type":"string"},"options":{"$ref":"#/components/schemas/InputOptions"},"info":{"type":"object"}},"required":["plugin","category","credentials","name"]},"Input":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string"},"plugin":{"type":"string"},"name":{"type":"string"},"cron":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"client_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"info":{"type":"object"}},"required":["id","category","plugin","name","cron","credentials","client_id","created_at","updated_at"]},"CreateConnectorDto":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"connector":{"type":"string"}},"required":["file","connector"]},"UploadFileDto":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"name":{"type":"string"}},"required":["file","name"]},"UpdateDto":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"version":{"type":"string"},"category":{"type":"string"},"plugin":{"type":"string"},"image":{"type":"string"},"docs":{"type":"string"},"name":{"type":"string"},"options":{"type":"object","description":"skip_select_entities: boolean skip_select_columns: boolean;"},"connection_controls":{"type":"array","items":{"properties":{}}}},"required":["version"]},"AddTagDto":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"}}},"required":["tags"]},"RemoveTagDto":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"}}},"required":["tags"]},"DeleteConnectorDto":{"type":"object","properties":{"version":{"type":"string"}},"required":["version"]}}}} \ No newline at end of file diff --git a/swagger_empty.json b/swagger_empty.json new file mode 100644 index 0000000..d0eb1b4 --- /dev/null +++ b/swagger_empty.json @@ -0,0 +1,17 @@ +{ + "openapi": "3.0.0", + "paths": { + }, + "info": { + "title": "404", + "description": "", + "version": "", + "contact": {} + }, + "tags": [], + "servers": [], + "components": { + + "schemas": {} + } +} diff --git a/tsconfig.json b/tsconfig.json index 3923786..f20e56f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,6 +17,7 @@ "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, - "noFallthroughCasesInSwitch": false + "noFallthroughCasesInSwitch": false, + "resolveJsonModule": true } }