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/package-lock.json b/package-lock.json index 9968245..83d1b5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,65 +1,71 @@ { - "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": { "@aws-sdk/client-secrets-manager": "^3.112.0", - "@grpc/grpc-js": "^1.5.10", - "@grpc/proto-loader": "^0.6.9", - "@nestjs/common": "^8.4.3", + "@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/microservices": "^8.4.7", "@nestjs/passport": "^8.2.2", - "@nestjs/platform-express": "^8.4.3", + "@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", - "dotenv": "^14.2.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-hubspot": "^0.1.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" }, @@ -81,19 +87,20 @@ } }, "node_modules/@angular-devkit/core": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.0.2.tgz", - "integrity": "sha512-lT875LhgO+23HvjUmuCZomH/0ivetzo8xsaT+7YM8SeUpmjsNTpTA/xNAQ4uD4JGscsJeCKsGT/zJIwPAAe6vQ==", + "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.11.0", + "ajv": "8.9.0", "ajv-formats": "2.1.1", - "jsonc-parser": "3.0.0", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", "rxjs": "6.6.7", "source-map": "0.7.3" }, "engines": { - "node": "^14.15.0 || >=16.10.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" }, @@ -106,6 +113,22 @@ } } }, + "node_modules/@angular-devkit/core/node_modules/ajv": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", + "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@angular-devkit/core/node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -125,41 +148,41 @@ "dev": true }, "node_modules/@angular-devkit/schematics": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.0.2.tgz", - "integrity": "sha512-NCAYwvQBL71MbAzeF8XOM9LXYfZbUK7THYCW8UteKDY4Df6EdVOGhBdWY2LstAkZeVCaQWSJU7FcVRS9Ulvg0A==", + "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": "14.0.2", + "@angular-devkit/core": "13.3.6", "jsonc-parser": "3.0.0", - "magic-string": "0.26.1", + "magic-string": "0.25.7", "ora": "5.4.1", "rxjs": "6.6.7" }, "engines": { - "node": "^14.15.0 || >=16.10.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" } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-14.0.2.tgz", - "integrity": "sha512-baqwuiN56mPFVVhthZHwvltjPNrczijM6Hvk9wYqlNeYuawqDD8h57u3PMGzgr9SKLHyCoFNwMQ0B57FN7oXtA==", + "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, "dependencies": { - "@angular-devkit/core": "14.0.2", - "@angular-devkit/schematics": "14.0.2", + "@angular-devkit/core": "13.3.6", + "@angular-devkit/schematics": "13.3.6", "ansi-colors": "4.1.1", - "inquirer": "8.2.4", - "symbol-observable": "4.0.0", - "yargs-parser": "21.0.1" + "inquirer": "8.2.0", + "minimist": "1.2.6", + "symbol-observable": "4.0.0" }, "bin": { "schematics": "bin/schematics.js" }, "engines": { - "node": "^14.15.0 || >=16.10.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" } @@ -181,9 +204,9 @@ } }, "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", + "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==", "dev": true, "dependencies": { "ansi-escapes": "^4.2.1", @@ -196,14 +219,13 @@ "mute-stream": "0.0.8", "ora": "^5.4.1", "run-async": "^2.4.0", - "rxjs": "^7.5.5", + "rxjs": "^7.2.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" + "through": "^2.3.6" }, "engines": { - "node": ">=12.0.0" + "node": ">=8.0.0" } }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { @@ -2235,14 +2257,14 @@ } }, "node_modules/@nestjs/cli": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.7.tgz", - "integrity": "sha512-wvdH9FLpLPj3HVyYVAVLgy4QJSUALVBzaOtd+eAkZgubkhteao+P1Qnqhu7Sugyiv2/bV5yVOJm7x7yqgueJ9g==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.8.tgz", + "integrity": "sha512-y5Imcw1EY0OxD3POAM7SLUB1rFdn5FjbfSsyJrokjKmXY+i6KcBdbRrv3Ox7aeJ4W7wXuckIXZEUlK6lC52dnA==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.0.2", - "@angular-devkit/schematics": "14.0.2", - "@angular-devkit/schematics-cli": "14.0.2", + "@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", @@ -2584,15 +2606,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@nestjs/schematics/node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.4" - } - }, "node_modules/@nestjs/schematics/node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -3031,11 +3044,29 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, + "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.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", @@ -3047,6 +3078,47 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "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", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", @@ -7595,15 +7667,12 @@ } }, "node_modules/magic-string": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.1.tgz", - "integrity": "sha512-ndThHmvgtieXe8J/VGPjG+Apu7v7ItcD5mhEIvOscWjPF/ccOiLxHaSuCAS2G+3x4GKsAbT8u7zdyamupui8Tg==", + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dev": true, "dependencies": { - "sourcemap-codec": "^1.4.8" - }, - "engines": { - "node": ">=12" + "sourcemap-codec": "^1.4.4" } }, "node_modules/make-dir": { @@ -8191,12 +8260,26 @@ "url": "https://github.com/sponsors/jaredhanson" } }, - "node_modules/passport-hubspot": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/passport-hubspot/-/passport-hubspot-0.1.0.tgz", - "integrity": "sha512-Bccm0kMRK+CoTQzQyB5OixC8PQsIo+GKLcTVpaabZHYOEcgCnccbTSehsgCejhuaq+UFVfsv8G2v5lVZphYoJQ==", + "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.1.2" + "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": { @@ -8211,6 +8294,23 @@ "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", @@ -10360,15 +10460,6 @@ "node": ">=10" } }, - "node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/yargs/node_modules/yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", @@ -10399,18 +10490,31 @@ } }, "@angular-devkit/core": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.0.2.tgz", - "integrity": "sha512-lT875LhgO+23HvjUmuCZomH/0ivetzo8xsaT+7YM8SeUpmjsNTpTA/xNAQ4uD4JGscsJeCKsGT/zJIwPAAe6vQ==", + "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.11.0", + "ajv": "8.9.0", "ajv-formats": "2.1.1", - "jsonc-parser": "3.0.0", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", "rxjs": "6.6.7", "source-map": "0.7.3" }, "dependencies": { + "ajv": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", + "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -10429,14 +10533,14 @@ } }, "@angular-devkit/schematics": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.0.2.tgz", - "integrity": "sha512-NCAYwvQBL71MbAzeF8XOM9LXYfZbUK7THYCW8UteKDY4Df6EdVOGhBdWY2LstAkZeVCaQWSJU7FcVRS9Ulvg0A==", + "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": "14.0.2", + "@angular-devkit/core": "13.3.6", "jsonc-parser": "3.0.0", - "magic-string": "0.26.1", + "magic-string": "0.25.7", "ora": "5.4.1", "rxjs": "6.6.7" }, @@ -10459,17 +10563,17 @@ } }, "@angular-devkit/schematics-cli": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-14.0.2.tgz", - "integrity": "sha512-baqwuiN56mPFVVhthZHwvltjPNrczijM6Hvk9wYqlNeYuawqDD8h57u3PMGzgr9SKLHyCoFNwMQ0B57FN7oXtA==", + "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": "14.0.2", - "@angular-devkit/schematics": "14.0.2", + "@angular-devkit/core": "13.3.6", + "@angular-devkit/schematics": "13.3.6", "ansi-colors": "4.1.1", - "inquirer": "8.2.4", - "symbol-observable": "4.0.0", - "yargs-parser": "21.0.1" + "inquirer": "8.2.0", + "minimist": "1.2.6", + "symbol-observable": "4.0.0" }, "dependencies": { "chalk": { @@ -10483,9 +10587,9 @@ } }, "inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "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", @@ -10498,11 +10602,10 @@ "mute-stream": "0.0.8", "ora": "^5.4.1", "run-async": "^2.4.0", - "rxjs": "^7.5.5", + "rxjs": "^7.2.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" + "through": "^2.3.6" } } } @@ -12135,14 +12238,14 @@ } }, "@nestjs/cli": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-8.2.7.tgz", - "integrity": "sha512-wvdH9FLpLPj3HVyYVAVLgy4QJSUALVBzaOtd+eAkZgubkhteao+P1Qnqhu7Sugyiv2/bV5yVOJm7x7yqgueJ9g==", + "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": "14.0.2", - "@angular-devkit/schematics": "14.0.2", - "@angular-devkit/schematics-cli": "14.0.2", + "@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", @@ -12322,15 +12425,6 @@ "uri-js": "^4.2.2" } }, - "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -12712,11 +12806,29 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "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.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", @@ -12728,6 +12840,47 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "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", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", @@ -16203,12 +16356,12 @@ "dev": true }, "magic-string": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.1.tgz", - "integrity": "sha512-ndThHmvgtieXe8J/VGPjG+Apu7v7ItcD5mhEIvOscWjPF/ccOiLxHaSuCAS2G+3x4GKsAbT8u7zdyamupui8Tg==", + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dev": true, "requires": { - "sourcemap-codec": "^1.4.8" + "sourcemap-codec": "^1.4.4" } }, "make-dir": { @@ -16652,12 +16805,20 @@ "utils-merge": "^1.0.1" } }, - "passport-hubspot": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/passport-hubspot/-/passport-hubspot-0.1.0.tgz", - "integrity": "sha512-Bccm0kMRK+CoTQzQyB5OixC8PQsIo+GKLcTVpaabZHYOEcgCnccbTSehsgCejhuaq+UFVfsv8G2v5lVZphYoJQ==", + "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.1.2" + "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": { @@ -16669,6 +16830,22 @@ "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", @@ -18238,12 +18415,6 @@ } } }, - "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "dev": true - }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 671f5f9..eae8d4d 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": "", @@ -25,59 +25,65 @@ }, "dependencies": { "@aws-sdk/client-secrets-manager": "^3.112.0", - "@grpc/grpc-js": "^1.5.10", - "@grpc/proto-loader": "^0.6.9", - "@nestjs/common": "^8.4.3", + "@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/microservices": "^8.4.7", "@nestjs/passport": "^8.2.2", - "@nestjs/platform-express": "^8.4.3", + "@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", - "dotenv": "^14.2.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-hubspot": "^0.1.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 f511377..8c8a9f0 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -29,17 +29,24 @@ 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 { HubspotStrategy } from './modules/oauth/passport-strategies/hubspot'; 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 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: [ @@ -51,6 +58,7 @@ const transformationClient = new TransformationsClientConfiguration(); HealthController, CatalogController, OauthController, + ConnectorController, ], providers: [ { provide: 'OAUTH_SECRETS', useValue: getOauthSecrets() }, @@ -58,6 +66,7 @@ const transformationClient = new TransformationsClientConfiguration(); TransformationsService, OutputsService, PipelinesService, + ConnectorClientService, HealthService, InputsClientService, TransformationsClientService, @@ -66,7 +75,14 @@ const transformationClient = new TransformationsClientConfiguration(); AuthClientService, PermissionsClientService, CatalogService, + { + provide: APP_GUARD, + useClass: AuthenticationGuard, + }, HubspotStrategy, + FacebookStrategy, + GoogleStrategy, + MailChimpStrategy, { provide: APP_GUARD, useClass: AuthenticationGuard, @@ -98,6 +114,10 @@ const transformationClient = new TransformationsClientConfiguration(); name: 'PIPELINES_PACKAGE', ...pipelineClient.config(), }, + { + name: 'CONNECTOR_PACKAGE', + ...connectorClient.config(), + }, ]), ], }) 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/inputs/client.service.ts b/src/clients/inputs/client.service.ts index 7082ccd..88582c8 100644 --- a/src/clients/inputs/client.service.ts +++ b/src/clients/inputs/client.service.ts @@ -64,7 +64,7 @@ export class InputsClientService implements OnModuleInit { const structReturn = await lastValueFrom( this.inputService.Create(grpcPayload), - ).catch((err) => { + ).catch((err: { details: string }) => { if (err.details === 'Item Not found!') { throw new NotFoundException('Input not found'); } diff --git a/src/clients/pipelines/client.service.ts b/src/clients/pipelines/client.service.ts index 028fe1a..b10af2f 100644 --- a/src/clients/pipelines/client.service.ts +++ b/src/clients/pipelines/client.service.ts @@ -1,9 +1,15 @@ -import { HttpException, Inject, OnModuleInit } from '@nestjs/common'; +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, @@ -30,30 +36,16 @@ export class PipelinesClientService implements OnModuleInit { async create(@Payload() createPipelineDto: ICreatePipelineDto) { console.log('PipelinesClientService', 'Create'); - - const createPipelineResponse = await new Promise((resolve, reject) => { - this.pipelineService - .Create(objectSnakeToCamel(createPipelineDto)) - .subscribe({ - next(x) { - resolve(x); - }, - error(err) { - console.log('Observable Error'); - reject(err); - }, - complete() { - console.log('done'); - }, - }); - }) - .then((res) => res) - .catch((err) => { - if (err.details == 'Invalid Request') { - throw new HttpException(err.details, 400); - } - throw new HttpException(err.details, 500); - }); + 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 fec1592..71690c3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,8 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { writeFileSync } from 'fs'; import helmet from 'helmet'; +import documentEmpty from '../swagger_empty.json'; + import { AppModule } from './app.module'; async function bootstrap() { @@ -18,7 +20,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() @@ -29,6 +31,9 @@ async function bootstrap() { 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); } bootstrap(); diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 62709eb..97e1794 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -26,6 +26,7 @@ import { PermissionsClientService } from '../../clients/permissions/client.servi import { Permissions } from '../../authentication/permissions.enum'; import ErrorBuilder from '../../utils/ErrorBuilder'; +import { LoginDto } from './dtos/login'; @ApiTags('Auth') @Controller('auth') 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/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/inputs/inputs.controller.ts b/src/modules/inputs/inputs.controller.ts index 4e47326..cf403eb 100644 --- a/src/modules/inputs/inputs.controller.ts +++ b/src/modules/inputs/inputs.controller.ts @@ -10,7 +10,6 @@ import { import { InputsService } from './inputs.service'; import { InputsClientService } from 'src/clients/inputs/client.service'; import { UpdateInputRequest } from 'src/clients/inputs/interfaces'; -import { InputNewCreateRequest } from '@victorradael/protospack'; import { Permissions } from '../../authentication/permissions.enum'; import { AuthenticateCondition } from 'src/authentication/authentication.decorator'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; diff --git a/src/modules/oauth/oauth.controller.ts b/src/modules/oauth/oauth.controller.ts index 93f129f..7feebae 100644 --- a/src/modules/oauth/oauth.controller.ts +++ b/src/modules/oauth/oauth.controller.ts @@ -1,16 +1,9 @@ -import { - BadRequestException, - Controller, - Get, - Query, - Redirect, - Req, - UseGuards, -} from '@nestjs/common'; +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') @@ -40,15 +33,85 @@ export class OauthController { @Get('hubspot/callback') @UseGuards(AuthGuard('hubspot')) @Redirect() - async oauthHubspotCallback(@Req() req, @Query('state') customer_id) { - const { authInfo } = req; - if (!authInfo) throw new BadRequestException('Oauth tokens not found'); - const { accessToken, refreshToken } = authInfo; + 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: 'hubspot', - credentials: { access_token: accessToken, refresh_token: refreshToken }, + 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.ts b/src/modules/oauth/passport-strategies/hubspot-strategy.ts similarity index 100% rename from src/modules/oauth/passport-strategies/hubspot.ts rename to src/modules/oauth/passport-strategies/hubspot-strategy.ts 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/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/utils/OauthSecrets.ts b/src/utils/OauthSecrets.ts index 39e5415..a5786fa 100644 --- a/src/utils/OauthSecrets.ts +++ b/src/utils/OauthSecrets.ts @@ -13,6 +13,7 @@ export class OauthSecrets { hubspot = new OauthSecretsObject(); google = new OauthSecretsObject(); mailchimp = new OauthSecretsObject(); + facebook = new OauthSecretsObject(); } export async function getOauthSecrets() { const secrets = new OauthSecrets(); @@ -25,7 +26,15 @@ export async function getOauthSecrets() { const res = await secretsManagerClient .send(getSecretComand) .catch(() => null); - if (res) secrets[key] = JSON.parse(res.SecretString); + 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/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 } }