From e5dd67c9cedc67a74808e26413653044fbd5e12f Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Thu, 9 Feb 2023 14:43:35 -0300 Subject: [PATCH 01/53] =?UTF-8?q?instala=C3=A7oes=20e=20pastas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + package-lock.json | 3079 ++++++++++++++++++++++++++++++++ package.json | 43 + queries.sql | 0 src/app.ts | 13 + src/data/BaseDatabase.ts | 21 + src/index.ts | 1 + src/services/IdGenerator.ts | 6 + src/services/TokenGenerator.ts | 0 tsconfig.json | 11 + 10 files changed, 3177 insertions(+) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 queries.sql create mode 100644 src/app.ts create mode 100644 src/data/BaseDatabase.ts create mode 100644 src/index.ts create mode 100644 src/services/IdGenerator.ts create mode 100644 src/services/TokenGenerator.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..935306f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +node_modules +.env \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5d2f7ba --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3079 @@ +{ + "name": "barros-cookenu9", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "barros-cookenu9", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@types/node": "^18.13.0", + "bcryptjs": "^2.4.3", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "jsonwebtoken": "^9.0.0", + "knex": "^2.4.2", + "mysql": "^2.18.1", + "typescript": "^4.9.5", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "@types/cors": "^2.8.13", + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.1", + "@types/knex": "^0.16.1", + "@types/uuid": "^9.0.0", + "cors": "^2.8.5", + "ts-node-dev": "^2.0.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/bcryptjs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", + "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", + "integrity": "sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/knex": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@types/knex/-/knex-0.16.1.tgz", + "integrity": "sha512-54gWD1HWwdVx5iLHaJ1qxH3I6KyBsj5fFqzRpXFn7REWiEB2jwspeVCombNsocSrqPd7IRPqKrsIME7/cD+TFQ==", + "deprecated": "This is a stub types definition. knex provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "knex": "*" + } + }, + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", + "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==", + "dev": true + }, + "node_modules/@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/dynamic-dedupe": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", + "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==", + "dev": true, + "dependencies": { + "xtend": "^4.0.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/getopts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/jsonwebtoken": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "dependencies": { + "jws": "^3.2.2", + "lodash": "^4.17.21", + "ms": "^2.1.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/knex": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/knex/-/knex-2.4.2.tgz", + "integrity": "sha512-tMI1M7a+xwHhPxjbl/H9K1kHX+VncEYcvCx5K00M16bWvpYPKAZd6QrCu68PtHAdIZNQPWZn0GVhqVBEthGWCg==", + "dependencies": { + "colorette": "2.0.19", + "commander": "^9.1.0", + "debug": "4.3.4", + "escalade": "^3.1.1", + "esm": "^3.2.25", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", + "interpret": "^2.2.0", + "lodash": "^4.17.21", + "pg-connection-string": "2.5.0", + "rechoir": "^0.8.0", + "resolve-from": "^5.0.0", + "tarn": "^3.0.2", + "tildify": "2.0.0" + }, + "bin": { + "knex": "bin/cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependenciesMeta": { + "better-sqlite3": { + "optional": true + }, + "mysql": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-native": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/knex/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/knex/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "dependencies": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mysql/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tarn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", + "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/tildify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node-dev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz", + "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.1", + "dynamic-dedupe": "^0.3.0", + "minimist": "^1.2.6", + "mkdirp": "^1.0.4", + "resolve": "^1.0.0", + "rimraf": "^2.6.1", + "source-map-support": "^0.5.12", + "tree-kill": "^1.2.2", + "ts-node": "^10.4.0", + "tsconfig": "^7.0.0" + }, + "bin": { + "ts-node-dev": "lib/bin.js", + "tsnd": "lib/bin.js" + }, + "engines": { + "node": ">=0.8.0" + }, + "peerDependencies": { + "node-notifier": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "dev": true, + "dependencies": { + "@types/strip-bom": "^3.0.0", + "@types/strip-json-comments": "0.0.30", + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@types/bcryptjs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", + "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "dev": true + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/jsonwebtoken": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", + "integrity": "sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/knex": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@types/knex/-/knex-0.16.1.tgz", + "integrity": "sha512-54gWD1HWwdVx5iLHaJ1qxH3I6KyBsj5fFqzRpXFn7REWiEB2jwspeVCombNsocSrqPd7IRPqKrsIME7/cD+TFQ==", + "dev": true, + "requires": { + "knex": "*" + } + }, + "@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "dev": true + }, + "@types/node": { + "version": "18.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", + "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "requires": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==", + "dev": true + }, + "@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, + "@types/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, + "bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "dynamic-dedupe": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", + "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==", + "dev": true, + "requires": { + "xtend": "^4.0.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "getopts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "jsonwebtoken": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "requires": { + "jws": "^3.2.2", + "lodash": "^4.17.21", + "ms": "^2.1.1", + "semver": "^7.3.8" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "knex": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/knex/-/knex-2.4.2.tgz", + "integrity": "sha512-tMI1M7a+xwHhPxjbl/H9K1kHX+VncEYcvCx5K00M16bWvpYPKAZd6QrCu68PtHAdIZNQPWZn0GVhqVBEthGWCg==", + "requires": { + "colorette": "2.0.19", + "commander": "^9.1.0", + "debug": "4.3.4", + "escalade": "^3.1.1", + "esm": "^3.2.25", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", + "interpret": "^2.2.0", + "lodash": "^4.17.21", + "pg-connection-string": "2.5.0", + "rechoir": "^0.8.0", + "resolve-from": "^5.0.0", + "tarn": "^3.0.2", + "tildify": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "requires": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "requires": { + "resolve": "^1.20.0" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "tarn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", + "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==" + }, + "tildify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "ts-node-dev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz", + "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==", + "dev": true, + "requires": { + "chokidar": "^3.5.1", + "dynamic-dedupe": "^0.3.0", + "minimist": "^1.2.6", + "mkdirp": "^1.0.4", + "resolve": "^1.0.0", + "rimraf": "^2.6.1", + "source-map-support": "^0.5.12", + "tree-kill": "^1.2.2", + "ts-node": "^10.4.0", + "tsconfig": "^7.0.0" + } + }, + "tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "dev": true, + "requires": { + "@types/strip-bom": "^3.0.0", + "@types/strip-json-comments": "0.0.30", + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0226d9f --- /dev/null +++ b/package.json @@ -0,0 +1,43 @@ +{ + "name": "barros-cookenu9", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "ts-node-dev ./src/index.ts", + "start": "tsc && node ./build/index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/future4code/Barros-cookenu9.git" + }, + "keywords": [], + "author": "Bianca Pacolla, Caroline Martins,Leonardo Barros", + "license": "ISC", + "bugs": { + "url": "https://github.com/future4code/Barros-cookenu9/issues" + }, + "homepage": "https://github.com/future4code/Barros-cookenu9#readme", + "dependencies": { + "@types/node": "^18.13.0", + "bcryptjs": "^2.4.3", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "jsonwebtoken": "^9.0.0", + "knex": "^2.4.2", + "mysql": "^2.18.1", + "typescript": "^4.9.5", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "@types/cors": "^2.8.13", + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.1", + "@types/knex": "^0.16.1", + "@types/uuid": "^9.0.0", + "cors": "^2.8.5", + "ts-node-dev": "^2.0.0" + } +} diff --git a/queries.sql b/queries.sql new file mode 100644 index 0000000..e69de29 diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..60b17cd --- /dev/null +++ b/src/app.ts @@ -0,0 +1,13 @@ +import express from "express" + +import cors from 'cors' + +export const app = express() + +app.use(express.json()) + +app.use(cors()) + +app.listen(3003, () => { + console.log("Server is running in http://localhost:3003"); +}); \ No newline at end of file diff --git a/src/data/BaseDatabase.ts b/src/data/BaseDatabase.ts new file mode 100644 index 0000000..2e06216 --- /dev/null +++ b/src/data/BaseDatabase.ts @@ -0,0 +1,21 @@ +import knex from 'knex' +import dotenv from "dotenv" + +dotenv.config() + +export abstract class BaseDatabase { + + protected static connection = knex({ + client: "mysql", + connection: { + host: process.env.DB_HOST, + port: 3306, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_DATABASE, + multipleStatements: true + } + }) +} + + diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..76b9bea --- /dev/null +++ b/src/index.ts @@ -0,0 +1 @@ +import { app } from "./app"; \ No newline at end of file diff --git a/src/services/IdGenerator.ts b/src/services/IdGenerator.ts new file mode 100644 index 0000000..2260a0d --- /dev/null +++ b/src/services/IdGenerator.ts @@ -0,0 +1,6 @@ +import { v4 } from "uuid"; + +export class IdGenerator { + + public generateId = () => v4() +} \ No newline at end of file diff --git a/src/services/TokenGenerator.ts b/src/services/TokenGenerator.ts new file mode 100644 index 0000000..e69de29 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4cc66d5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + "outDir": "./build" /* Redirect output structure to the directory. */, + "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, + "strict": true /* Enable all strict type-checking options. */, + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} \ No newline at end of file From 94b077ce196c228f71e468219e77ab2fbc22577d Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Thu, 9 Feb 2023 14:46:46 -0300 Subject: [PATCH 02/53] =?UTF-8?q?config=20faltando=20configura=C3=A7=C3=B5?= =?UTF-8?q?es,=20agora=20adicionadas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.json | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 4cc66d5..b36b619 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,14 @@ { "compilerOptions": { - "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, - "outDir": "./build" /* Redirect output structure to the directory. */, - "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - "strict": true /* Enable all strict type-checking options. */, - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "target": "es6", + "module": "commonjs", + "outDir": "./build", + "rootDir": "./src", + "removeComments": true, + "strict": true, + "noImplicitAny": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true } } \ No newline at end of file From 1b5ec219cb7ef7e8be21d9a28eab6913a69e04ea Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 12:17:08 -0300 Subject: [PATCH 03/53] inicio create user data --- src/data/UserDatabase.ts | 17 +++++++++++++++++ src/model/userDTO.ts | 6 ++++++ 2 files changed, 23 insertions(+) create mode 100644 src/data/UserDatabase.ts create mode 100644 src/model/userDTO.ts diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts new file mode 100644 index 0000000..a056ee6 --- /dev/null +++ b/src/data/UserDatabase.ts @@ -0,0 +1,17 @@ +import { InputUserDTO } from "../model/userDTO"; +import { BaseDatabase } from "./BaseDatabase"; + +export class UserDatabase extends BaseDatabase { + private static TABLE_NAME= "cookenu_users" + + create = async ({id,name,email,password}:InputUserDTO):Promise=>{ + try{ + await UserDatabase.connection + .insert({id,name,email,password}) + .into(UserDatabase.TABLE_NAME) + + }catch(error:any){ + + } + } +} \ No newline at end of file diff --git a/src/model/userDTO.ts b/src/model/userDTO.ts new file mode 100644 index 0000000..0fa86e1 --- /dev/null +++ b/src/model/userDTO.ts @@ -0,0 +1,6 @@ +export interface InputUserDTO{ + id: string; + name: string; + email: string; + password: string +} \ No newline at end of file From a5b01e4cc601342eaaa0e73c80f5fc4de98a2c68 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 12:18:01 -0300 Subject: [PATCH 04/53] feat: custom error --- src/error/CustomError.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/error/CustomError.ts diff --git a/src/error/CustomError.ts b/src/error/CustomError.ts new file mode 100644 index 0000000..17d3b06 --- /dev/null +++ b/src/error/CustomError.ts @@ -0,0 +1,5 @@ +export class CustomError extends Error { + constructor(statusCode: number, message: string){ + super(message) + } +} \ No newline at end of file From ea16b269fe3837a5f96729d2a0c07c5c0829c507 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 12:19:39 -0300 Subject: [PATCH 05/53] feat: Token generator --- src/data/UserDatabase.ts | 3 ++- src/services/TokenGenerator.ts | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index a056ee6..69ededc 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -1,3 +1,4 @@ +import { CustomError } from "../error/CustomError"; import { InputUserDTO } from "../model/userDTO"; import { BaseDatabase } from "./BaseDatabase"; @@ -11,7 +12,7 @@ export class UserDatabase extends BaseDatabase { .into(UserDatabase.TABLE_NAME) }catch(error:any){ - + throw new CustomError(400, error.message); } } } \ No newline at end of file diff --git a/src/services/TokenGenerator.ts b/src/services/TokenGenerator.ts index e69de29..24440e9 100644 --- a/src/services/TokenGenerator.ts +++ b/src/services/TokenGenerator.ts @@ -0,0 +1,22 @@ +import * as jwt from 'jsonwebtoken' + +export class TokenGenerator { + + public generateToken = ({id, role}:AuthenticationData) => { + const token = jwt.sign( + { id, role }, + process.env.JWT_KEY as string, + { expiresIn: "4h" } + ) + return token + } + + public tokenData = (token: string): AuthenticationData => { + const payload = jwt.verify( + token, + process.env.JWT_KEY as string + ) as jwt.JwtPayload + + return {id: payload.id as string, role: payload.role as string} + } +} \ No newline at end of file From 408fe36ce09ba58463581633e5382bfcfb95a518 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 12:31:42 -0300 Subject: [PATCH 06/53] feat: user bussines, interface rename --- queries.sql | 7 +++++++ src/business/UserBusiness.ts | 21 +++++++++++++++++++++ src/data/UserDatabase.ts | 6 +++--- src/model/userDTO.ts | 15 +++++++++++++-- src/services/TokenGenerator.ts | 1 + 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 src/business/UserBusiness.ts diff --git a/queries.sql b/queries.sql index e69de29..389cce8 100644 --- a/queries.sql +++ b/queries.sql @@ -0,0 +1,7 @@ +-- Active: 1674084192186@@35.226.146.116@3306@jbl-4416152-caroline-martins +CREATE TABLE IF NOT EXISTS Cookenu_users( + id VARCHAR(255) PRIMARY KEY, + name VARCHAR(255) NOT NULL, + email VARCHAR(64) NOT NULL, + password VARCHAR(64) NOT NULL +); diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts new file mode 100644 index 0000000..1fe2a00 --- /dev/null +++ b/src/business/UserBusiness.ts @@ -0,0 +1,21 @@ +import { UserDatabase } from "../data/UserDatabase"; +import { CustomError } from "../error/CustomError"; +import { IdGenerator } from "../services/IdGenerator"; +import { TokenGenerator } from "../services/TokenGenerator"; + +export class UserBusiness{ + idGenerator = new IdGenerator(); + tokenGenerator = new TokenGenerator(); + userDatabase = new UserDatabase(); + + public createUser = async ()=>{ + try{ + + + + }catch(error:any){ + throw new CustomError(400, error.message); + } + + } +} \ No newline at end of file diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index 69ededc..36dc2bb 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -1,11 +1,11 @@ import { CustomError } from "../error/CustomError"; -import { InputUserDTO } from "../model/userDTO"; +import { UserDTO } from "../model/userDTO"; import { BaseDatabase } from "./BaseDatabase"; export class UserDatabase extends BaseDatabase { - private static TABLE_NAME= "cookenu_users" + private static TABLE_NAME= "Cookenu_users" - create = async ({id,name,email,password}:InputUserDTO):Promise=>{ + create = async ({id,name,email,password}:UserDTO):Promise=>{ try{ await UserDatabase.connection .insert({id,name,email,password}) diff --git a/src/model/userDTO.ts b/src/model/userDTO.ts index 0fa86e1..575511a 100644 --- a/src/model/userDTO.ts +++ b/src/model/userDTO.ts @@ -1,6 +1,17 @@ -export interface InputUserDTO{ +export interface UserDTO{ id: string; name: string; email: string; password: string -} \ No newline at end of file +} + +export interface InputUserDTO{ + name: string; + email: string; + password: string +} + +export interface AuthenticationData { + id: string; + role: string + } \ No newline at end of file diff --git a/src/services/TokenGenerator.ts b/src/services/TokenGenerator.ts index 24440e9..a979c55 100644 --- a/src/services/TokenGenerator.ts +++ b/src/services/TokenGenerator.ts @@ -1,4 +1,5 @@ import * as jwt from 'jsonwebtoken' +import { AuthenticationData } from '../model/userDTO' export class TokenGenerator { From 9795cc9044e5dc0a2b47bcec2d35ec33fc82275f Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 13:06:49 -0300 Subject: [PATCH 07/53] FEAT:criar usuario gerando token --- src/app.ts | 17 ++++++++----- src/business/UserBusiness.ts | 41 ++++++++++++++++++++++++++------ src/controller/UserController.ts | 28 ++++++++++++++++++++++ src/index.ts | 7 +++++- src/model/userDTO.ts | 14 +++++------ src/routes/userRouter.ts | 9 +++++++ src/services/TokenGenerator.ts | 6 ++--- 7 files changed, 98 insertions(+), 24 deletions(-) create mode 100644 src/controller/UserController.ts create mode 100644 src/routes/userRouter.ts diff --git a/src/app.ts b/src/app.ts index 60b17cd..334e131 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,13 +1,18 @@ -import express from "express" - +import express from 'express' import cors from 'cors' +import { AddressInfo } from "net"; export const app = express() app.use(express.json()) - app.use(cors()) -app.listen(3003, () => { - console.log("Server is running in http://localhost:3003"); -}); \ No newline at end of file + +const server = app.listen(process.env.PORT || 3003, () => { + if (server) { + const address = server.address() as AddressInfo; + console.log(`Server is running in http://localhost:${address.port}`); + } else { + console.error("failure upon starting server"); + } +}) \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 1fe2a00..29e2423 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -1,19 +1,46 @@ import { UserDatabase } from "../data/UserDatabase"; import { CustomError } from "../error/CustomError"; +import { InputUserDTO, UserDTO } from "../model/userDTO"; import { IdGenerator } from "../services/IdGenerator"; import { TokenGenerator } from "../services/TokenGenerator"; -export class UserBusiness{ - idGenerator = new IdGenerator(); - tokenGenerator = new TokenGenerator(); - userDatabase = new UserDatabase(); +const idGenerator = new IdGenerator(); +const tokenGenerator = new TokenGenerator(); +const userDatabase = new UserDatabase(); +export class UserBusiness { - public createUser = async ()=>{ - try{ + public signup = async ({ name, email, password }: InputUserDTO) => { + try { + if (!name || !email || !password) { + throw new CustomError(400,'Fill in the fields "name", "email" and "password"'); + } + if(name.length > 3){ + throw new CustomError(400,'Very short name'); + } + if(password.length > 6){ + throw new CustomError(400,'Fill in the fields "name", "email" and "password"'); + } + if (!email.includes("@")) { + throw new CustomError(400, "Invalid email address"); + } + + const id = idGenerator.generateId() + + const newUser:UserDTO = { + id, + name, + email, + password + } + + await userDatabase.create(newUser) + + const token = tokenGenerator.generateToken({id:id}) + return (token) - }catch(error:any){ + } catch (error: any) { throw new CustomError(400, error.message); } diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts new file mode 100644 index 0000000..c06a5ef --- /dev/null +++ b/src/controller/UserController.ts @@ -0,0 +1,28 @@ +import { Request, Response } from "express"; +import { UserBusiness } from "../business/UserBusiness"; +import { CustomError } from "../error/CustomError"; +import { InputUserDTO} from "../model/userDTO"; + + +const userBusiness = new UserBusiness() + +export class UserController { + public signup = async (req: Request, res: Response) => { + try { + const { name, email, password } = req.body + + const insert: InputUserDTO = { + name, + email, + password + } + + const token = await userBusiness.signup(insert) + + res.status(201).send({ message: "Usuário criado!", token }); + + } catch (error: any) { + throw new CustomError(400, error.message); + } + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 76b9bea..42f2118 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,6 @@ -import { app } from "./app"; \ No newline at end of file +import { app } from "./app"; +import { userRouter } from "./routes/userRouter"; + + +// ENDPOINT CRIAR USUARIO +app.use("", userRouter) \ No newline at end of file diff --git a/src/model/userDTO.ts b/src/model/userDTO.ts index 575511a..cafb497 100644 --- a/src/model/userDTO.ts +++ b/src/model/userDTO.ts @@ -1,17 +1,17 @@ export interface UserDTO{ - id: string; - name: string; - email: string; + id: string, + name: string, + email: string, password: string } export interface InputUserDTO{ - name: string; - email: string; + name: string, + email: string, password: string } export interface AuthenticationData { - id: string; - role: string + id: string, + } \ No newline at end of file diff --git a/src/routes/userRouter.ts b/src/routes/userRouter.ts new file mode 100644 index 0000000..4b6f469 --- /dev/null +++ b/src/routes/userRouter.ts @@ -0,0 +1,9 @@ +import express from "express"; +import { UserController } from "../controller/UserController"; + +export const userRouter = express.Router() +const userController = new UserController() + + +// ENDPOINT CRIAR USUARIO +userRouter.post("signup", userController.signup) \ No newline at end of file diff --git a/src/services/TokenGenerator.ts b/src/services/TokenGenerator.ts index a979c55..9b58074 100644 --- a/src/services/TokenGenerator.ts +++ b/src/services/TokenGenerator.ts @@ -3,9 +3,9 @@ import { AuthenticationData } from '../model/userDTO' export class TokenGenerator { - public generateToken = ({id, role}:AuthenticationData) => { + public generateToken = ({id}:AuthenticationData) => { const token = jwt.sign( - { id, role }, + { id }, process.env.JWT_KEY as string, { expiresIn: "4h" } ) @@ -18,6 +18,6 @@ export class TokenGenerator { process.env.JWT_KEY as string ) as jwt.JwtPayload - return {id: payload.id as string, role: payload.role as string} + return {id: payload.id as string} } } \ No newline at end of file From 65d587312a0bb22cad59ed07b54faddc708203cf Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 13:38:34 -0300 Subject: [PATCH 08/53] FEAT:criar usuario funcionando e testado, gerando token e password criptografado --- request.rest | 8 ++++++++ src/business/UserBusiness.ts | 11 ++++++++--- src/controller/UserController.ts | 4 ++-- src/data/UserDatabase.ts | 8 ++++++-- src/routes/userRouter.ts | 2 +- src/services/HashGenerator.ts | 17 +++++++++++++++++ 6 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 request.rest create mode 100644 src/services/HashGenerator.ts diff --git a/request.rest b/request.rest new file mode 100644 index 0000000..3d65a01 --- /dev/null +++ b/request.rest @@ -0,0 +1,8 @@ +POST http://localhost:3003/signup +Content-Type: application/json + +{ + "name":"Bananinha teste", + "email":"bananinha@teste.com", + "password":"123456" +} \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 29e2423..c4f9524 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -1,12 +1,14 @@ import { UserDatabase } from "../data/UserDatabase"; import { CustomError } from "../error/CustomError"; import { InputUserDTO, UserDTO } from "../model/userDTO"; +import { HashGenerator } from "../services/HashGenerator"; import { IdGenerator } from "../services/IdGenerator"; import { TokenGenerator } from "../services/TokenGenerator"; const idGenerator = new IdGenerator(); const tokenGenerator = new TokenGenerator(); const userDatabase = new UserDatabase(); +const hashGenerator = new HashGenerator(); export class UserBusiness { public signup = async ({ name, email, password }: InputUserDTO) => { @@ -14,7 +16,7 @@ export class UserBusiness { if (!name || !email || !password) { throw new CustomError(400,'Fill in the fields "name", "email" and "password"'); } - if(name.length > 3){ + if(name.length < 3){ throw new CustomError(400,'Very short name'); } @@ -27,16 +29,19 @@ export class UserBusiness { const id = idGenerator.generateId() + const passwordHash = await hashGenerator.generateHash(password) + const newUser:UserDTO = { id, name, email, - password + password: passwordHash } await userDatabase.create(newUser) - const token = tokenGenerator.generateToken({id:id}) + const token = tokenGenerator.generateToken({id}) + console.log(id); return (token) diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index c06a5ef..bfddcb2 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -10,7 +10,7 @@ export class UserController { public signup = async (req: Request, res: Response) => { try { const { name, email, password } = req.body - + const insert: InputUserDTO = { name, email, @@ -18,7 +18,7 @@ export class UserController { } const token = await userBusiness.signup(insert) - + res.status(201).send({ message: "Usuário criado!", token }); } catch (error: any) { diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index 36dc2bb..043b7d8 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -8,8 +8,12 @@ export class UserDatabase extends BaseDatabase { create = async ({id,name,email,password}:UserDTO):Promise=>{ try{ await UserDatabase.connection - .insert({id,name,email,password}) - .into(UserDatabase.TABLE_NAME) + .insert({ + id, + name, + email, + password + }).into(UserDatabase.TABLE_NAME) }catch(error:any){ throw new CustomError(400, error.message); diff --git a/src/routes/userRouter.ts b/src/routes/userRouter.ts index 4b6f469..e6679b2 100644 --- a/src/routes/userRouter.ts +++ b/src/routes/userRouter.ts @@ -6,4 +6,4 @@ const userController = new UserController() // ENDPOINT CRIAR USUARIO -userRouter.post("signup", userController.signup) \ No newline at end of file +userRouter.post("/signup", userController.signup) \ No newline at end of file diff --git a/src/services/HashGenerator.ts b/src/services/HashGenerator.ts new file mode 100644 index 0000000..4f27734 --- /dev/null +++ b/src/services/HashGenerator.ts @@ -0,0 +1,17 @@ +import * as bcrypt from "bcryptjs"; + +export class HashGenerator{ + generateHash = async(plainTest: string):Promise =>{ + const cost:number = Number(process.env.BCRYPT_COST) + const salt:string = await bcrypt.genSalt(cost) + const hash:string = await bcrypt.hash(plainTest, salt) + + return(hash) + } + + compareHash = async(plainTest: string, hashTest: string):Promise=>{ + const result = await bcrypt.compare(plainTest, hashTest) + + return (result) + } +} \ No newline at end of file From 9fde40724dab4b256bbb18976ab6e286bb249d5e Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 13:44:54 -0300 Subject: [PATCH 09/53] FEAT:criar usuario funcionando e testado, gerando token e password criptografado --- request.rest | 6 +++--- src/business/UserBusiness.ts | 7 +++---- src/controller/UserController.ts | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/request.rest b/request.rest index 3d65a01..c343858 100644 --- a/request.rest +++ b/request.rest @@ -2,7 +2,7 @@ POST http://localhost:3003/signup Content-Type: application/json { - "name":"Bananinha teste", - "email":"bananinha@teste.com", - "password":"123456" + "name":"Camila Prado", + "email":"camila@testando", + "password":"1234567" } \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index c4f9524..31a465b 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -20,8 +20,8 @@ export class UserBusiness { throw new CustomError(400,'Very short name'); } - if(password.length > 6){ - throw new CustomError(400,'Fill in the fields "name", "email" and "password"'); + if(password.length <= 6){ + throw new CustomError(400,'Invalid password'); } if (!email.includes("@")) { throw new CustomError(400, "Invalid email address"); @@ -41,8 +41,7 @@ export class UserBusiness { await userDatabase.create(newUser) const token = tokenGenerator.generateToken({id}) - console.log(id); - + return (token) } catch (error: any) { diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index bfddcb2..21e58e1 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -19,10 +19,10 @@ export class UserController { const token = await userBusiness.signup(insert) - res.status(201).send({ message: "Usuário criado!", token }); + res.status(201).send(`access_token: ${token} `); } catch (error: any) { - throw new CustomError(400, error.message); + res.status(400).send(error.message); } } } \ No newline at end of file From 4e92ee4c2c02ba0ab8493caa73e1954fe2496393 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 10 Feb 2023 13:52:58 -0300 Subject: [PATCH 10/53] FEAT:tabela com email unico --- queries.sql | 3 ++- request.rest | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/queries.sql b/queries.sql index 389cce8..575a89b 100644 --- a/queries.sql +++ b/queries.sql @@ -2,6 +2,7 @@ CREATE TABLE IF NOT EXISTS Cookenu_users( id VARCHAR(255) PRIMARY KEY, name VARCHAR(255) NOT NULL, - email VARCHAR(64) NOT NULL, + email VARCHAR(64) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL ); + diff --git a/request.rest b/request.rest index c343858..c257afa 100644 --- a/request.rest +++ b/request.rest @@ -2,7 +2,7 @@ POST http://localhost:3003/signup Content-Type: application/json { - "name":"Camila Prado", + "name":"Carmem lucia", "email":"camila@testando", "password":"1234567" } \ No newline at end of file From d0562fe23c229da4b390f89d0ec415fed1ef32b1 Mon Sep 17 00:00:00 2001 From: Bianca Paccola Date: Tue, 14 Feb 2023 12:10:00 -0300 Subject: [PATCH 11/53] endpoint de fazer login com hash e token --- request.rest | 18 +++++++++++++--- src/business/UserBusiness.ts | 36 +++++++++++++++++++++++++++++++- src/controller/UserController.ts | 12 +++++++++++ src/data/UserDatabase.ts | 13 ++++++++++++ src/error/UserErrors.ts | 31 +++++++++++++++++++++++++++ src/model/userDTO.ts | 5 +++++ src/routes/userRouter.ts | 5 ++++- 7 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 src/error/UserErrors.ts diff --git a/request.rest b/request.rest index c257afa..f22e22b 100644 --- a/request.rest +++ b/request.rest @@ -1,8 +1,20 @@ +// Signup - Criar cadastro de usuário POST http://localhost:3003/signup Content-Type: application/json { - "name":"Carmem lucia", - "email":"camila@testando", - "password":"1234567" + "name":"Bianca Paccola", + "email":"bianca@email.com", + "password":"123abc#" +} + +### + +// Login +POST http://localhost:3003/login +Content-Type: application/json + +{ + "email": "bianca@email.com", + "password": "123abc#" } \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 31a465b..73ae570 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -1,6 +1,7 @@ import { UserDatabase } from "../data/UserDatabase"; import { CustomError } from "../error/CustomError"; -import { InputUserDTO, UserDTO } from "../model/userDTO"; +import { UserIncompleteData, UserIncorrectPassword, UserInvalidEmail, UserInvalidPassword, UserNotFound } from "../error/UserErrors"; +import { InputUserDTO, UserDTO, userLoginDTO } from "../model/userDTO"; import { HashGenerator } from "../services/HashGenerator"; import { IdGenerator } from "../services/IdGenerator"; import { TokenGenerator } from "../services/TokenGenerator"; @@ -49,4 +50,37 @@ export class UserBusiness { } } + + public async login ({email, password}:userLoginDTO ) { + try { + if(!email || !password) { + throw new UserIncompleteData() + } + if (!email.includes("@" )) { + throw new UserInvalidEmail() + } + if (password.length <= 6) { + throw new UserInvalidPassword() + } + + const user = await userDatabase.findByEmail(email) + + if(!user) { + throw new UserNotFound() + } + + const comparePassword: boolean = await hashGenerator.compareHash(password, user.password) + + if (!comparePassword) { + throw new UserIncorrectPassword() + } + + const token = await tokenGenerator.generateToken({id: user.id}) + + return token; + + } catch (error:any) { + throw new CustomError(400, error.message); + } + } } \ No newline at end of file diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index 21e58e1..822b3a9 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -25,4 +25,16 @@ export class UserController { res.status(400).send(error.message); } } + + public async login (req: Request, res: Response) { + try { + const {email, password} = req.body + const token = await userBusiness.login({email, password}) + + res.status(200).send({token: token}) + + } catch (error:any) { + res.status(400).send(error.message); + } + } } \ No newline at end of file diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index 043b7d8..7886e4e 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -19,4 +19,17 @@ export class UserDatabase extends BaseDatabase { throw new CustomError(400, error.message); } } + + public async findByEmail (email: string) { + try { + const user = await UserDatabase.connection + .select('*') + .where({email}) + .into(UserDatabase.TABLE_NAME) + + return user[0]; + } catch (error:any) { + throw new CustomError(400, error.message || error.sqlMessage); + } + } } \ No newline at end of file diff --git a/src/error/UserErrors.ts b/src/error/UserErrors.ts new file mode 100644 index 0000000..2f9d51e --- /dev/null +++ b/src/error/UserErrors.ts @@ -0,0 +1,31 @@ +import { CustomError } from "./CustomError"; + +export class UserIncompleteData extends CustomError { + constructor () { + super(422, 'Fill in the fields: "email" and "password" ') + } +} + +export class UserInvalidEmail extends CustomError { + constructor() { + super(422, "Invalid Email") + } +} + +export class UserInvalidPassword extends CustomError { + constructor() { + super(422, "Password must contain at least 7 characters.") + } +} + +export class UserNotFound extends CustomError { + constructor() { + super(404, "User not found!") + } +} + +export class UserIncorrectPassword extends CustomError { + constructor() { + super(401, "Unauthorized: Incorrect password.") + } +} \ No newline at end of file diff --git a/src/model/userDTO.ts b/src/model/userDTO.ts index cafb497..c72f740 100644 --- a/src/model/userDTO.ts +++ b/src/model/userDTO.ts @@ -11,6 +11,11 @@ export interface InputUserDTO{ password: string } +export interface userLoginDTO { + email: string, + password: string +} + export interface AuthenticationData { id: string, diff --git a/src/routes/userRouter.ts b/src/routes/userRouter.ts index e6679b2..2d5cc3a 100644 --- a/src/routes/userRouter.ts +++ b/src/routes/userRouter.ts @@ -6,4 +6,7 @@ const userController = new UserController() // ENDPOINT CRIAR USUARIO -userRouter.post("/signup", userController.signup) \ No newline at end of file +userRouter.post("/signup", userController.signup) + +//ENDPOINT FAZER LOGIN +userRouter.post("/login", userController.login) \ No newline at end of file From 35304755ae1a68f49b2a6d6c4760ef9554a2333b Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 12:43:18 -0300 Subject: [PATCH 12/53] create table recipes --- queries.sql | 8 ++++++++ request.rest | 4 ++-- src/business/UserBusiness.ts | 5 +++++ src/data/UserDatabase.ts | 12 ++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/queries.sql b/queries.sql index 575a89b..88d5aec 100644 --- a/queries.sql +++ b/queries.sql @@ -6,3 +6,11 @@ CREATE TABLE IF NOT EXISTS Cookenu_users( password VARCHAR(64) NOT NULL ); +CREATE TABLE IF NOT EXISTS Cookenu_recipe( + id VARCHAR(255) PRIMARY KEY, + title VARCHAR(255) NOT NULL, + description TEXT NOT NULL, + creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + id_author VARCHAR(255) NOT NULL, + FOREIGN KEY (id_author) REFERENCES Cookenu_users (id) +); \ No newline at end of file diff --git a/request.rest b/request.rest index c257afa..5e46798 100644 --- a/request.rest +++ b/request.rest @@ -2,7 +2,7 @@ POST http://localhost:3003/signup Content-Type: application/json { - "name":"Carmem lucia", - "email":"camila@testando", + "name":"Carla", + "email":"carla@gmail.com", "password":"1234567" } \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 31a465b..15c2049 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -26,6 +26,11 @@ export class UserBusiness { if (!email.includes("@")) { throw new CustomError(400, "Invalid email address"); } + // const verificationEmail = await userDatabase.getAll(email) + + // if(verificationEmail){ + // throw new CustomError(400, "Already have this email"); + // } const id = idGenerator.generateId() diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index 043b7d8..e0f5bfe 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -19,4 +19,16 @@ export class UserDatabase extends BaseDatabase { throw new CustomError(400, error.message); } } + + getAll = async(email:string)=>{ + try{ + const result = await UserDatabase.connection.raw(` + SELECT email FROM ${UserDatabase.TABLE_NAME} WHERE email=${email} + `) + return (result) + + }catch(error:any){ + throw new CustomError(400, error.message); + } + } } \ No newline at end of file From f8fd6a5fc8cb9c1c250d2951a2d97e2e76e1e29e Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 12:48:57 -0300 Subject: [PATCH 13/53] erros data base --- src/data/RecipeDatabase.ts | 15 +++++++++++++++ src/data/UserDatabase.ts | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/data/RecipeDatabase.ts diff --git a/src/data/RecipeDatabase.ts b/src/data/RecipeDatabase.ts new file mode 100644 index 0000000..c5e10e3 --- /dev/null +++ b/src/data/RecipeDatabase.ts @@ -0,0 +1,15 @@ +import { CustomError } from "../error/CustomError"; +import { BaseDatabase } from "./BaseDatabase"; + +export class RecipeDatabase extends BaseDatabase{ + private static TABLE_NAME: string = "Cookenu_recipe" + + create=async()=>{ + try{ + + + }catch(error:any){ + throw new CustomError(400, error.message || error.sqlMessage); + } + } +} \ No newline at end of file diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index e0f5bfe..db06b61 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -16,7 +16,7 @@ export class UserDatabase extends BaseDatabase { }).into(UserDatabase.TABLE_NAME) }catch(error:any){ - throw new CustomError(400, error.message); + throw new CustomError(400, error.message || error.sqlMessage); } } @@ -28,7 +28,7 @@ export class UserDatabase extends BaseDatabase { return (result) }catch(error:any){ - throw new CustomError(400, error.message); + throw new CustomError(400, error.message || error.sqlMessage); } } } \ No newline at end of file From 150b00143ea4607f3255f57ffd8ef82520e81a93 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 12:53:48 -0300 Subject: [PATCH 14/53] inicio create recipe --- src/data/RecipeDatabase.ts | 10 +++++++++- src/model/recipeDTO.ts | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/model/recipeDTO.ts diff --git a/src/data/RecipeDatabase.ts b/src/data/RecipeDatabase.ts index c5e10e3..4c24af1 100644 --- a/src/data/RecipeDatabase.ts +++ b/src/data/RecipeDatabase.ts @@ -1,12 +1,20 @@ import { CustomError } from "../error/CustomError"; +import { RecipeDTO } from "../model/recipeDTO"; import { BaseDatabase } from "./BaseDatabase"; export class RecipeDatabase extends BaseDatabase{ private static TABLE_NAME: string = "Cookenu_recipe" - create=async()=>{ + create=async({id,title,description,idAuthor}:RecipeDTO)=>{ try{ + await RecipeDatabase.connection.insert({ + id, + title, + description, + id_author:idAuthor + }) + }catch(error:any){ throw new CustomError(400, error.message || error.sqlMessage); diff --git a/src/model/recipeDTO.ts b/src/model/recipeDTO.ts new file mode 100644 index 0000000..1ad3bf9 --- /dev/null +++ b/src/model/recipeDTO.ts @@ -0,0 +1,6 @@ +export interface RecipeDTO{ + id:String, + title:String, + description:String, + idAuthor:String +} From 1fbe88d37b1198cc6a52ac803bb5090c84c774e9 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 12:54:29 -0300 Subject: [PATCH 15/53] inicio create recipe --- src/data/RecipeDatabase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/RecipeDatabase.ts b/src/data/RecipeDatabase.ts index 4c24af1..e83862a 100644 --- a/src/data/RecipeDatabase.ts +++ b/src/data/RecipeDatabase.ts @@ -13,7 +13,7 @@ export class RecipeDatabase extends BaseDatabase{ title, description, id_author:idAuthor - }) + }).into(RecipeDatabase.TABLE_NAME) }catch(error:any){ From 390da8e9da2a89d4b5796b88d194ca62dd156d96 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 13:21:03 -0300 Subject: [PATCH 16/53] CREATE RECIPE BUSINESS --- src/business/RecipeBusiness.ts | 37 ++++++++++++++++++++++++++++++++++ src/model/recipeDTO.ts | 14 +++++++++---- 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/business/RecipeBusiness.ts diff --git a/src/business/RecipeBusiness.ts b/src/business/RecipeBusiness.ts new file mode 100644 index 0000000..1a49a0f --- /dev/null +++ b/src/business/RecipeBusiness.ts @@ -0,0 +1,37 @@ +import { RecipeDatabase } from "../data/RecipeDatabase"; +import { CustomError } from "../error/CustomError"; +import { InputRecipeDTO } from "../model/recipeDTO"; +import { IdGenerator } from "../services/IdGenerator"; +import { TokenGenerator } from "../services/TokenGenerator"; + +const tokenGenerator = new TokenGenerator(); +const idGenerator = new IdGenerator(); +const recipeDatabase = new RecipeDatabase(); + +export class RecipeBusiness { + + createRecipe = async (input: InputRecipeDTO) => { + try { + + const { title, description, idAuthor } = input + + if (!title || !description) { + throw new CustomError(400, 'Fill in the fields "title" and "description"'); + } + + const idUser = tokenGenerator.tokenData(idAuthor) + + const id = idGenerator.generateId() + + await recipeDatabase.create({ + id: id, + title: title, + description: description, + idAuthor: idUser.id + }) + + } catch (error: any) { + throw new CustomError(400, error.message); + } + } +} \ No newline at end of file diff --git a/src/model/recipeDTO.ts b/src/model/recipeDTO.ts index 1ad3bf9..40119fe 100644 --- a/src/model/recipeDTO.ts +++ b/src/model/recipeDTO.ts @@ -1,6 +1,12 @@ export interface RecipeDTO{ - id:String, - title:String, - description:String, - idAuthor:String + id:string, + title:string, + description:string, + idAuthor:string +} + +export interface InputRecipeDTO{ + title:string, + description:string, + idAuthor: string } From df4f2f94c1497d04fed73195ca05e75abf61af1e Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 17:05:35 -0300 Subject: [PATCH 17/53] create recipe controller --- src/controller/RecipeController.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/controller/RecipeController.ts diff --git a/src/controller/RecipeController.ts b/src/controller/RecipeController.ts new file mode 100644 index 0000000..9347a21 --- /dev/null +++ b/src/controller/RecipeController.ts @@ -0,0 +1,29 @@ +import { Request, Response } from "express"; +import { RecipeBusiness } from "../business/RecipeBusiness"; + +const recipeBusiness = new RecipeBusiness(); + +export class RecipeController { + + createRecipe = async (req: Request, res: Response) => { + + try { + + const idAuthor = req.headers.authorization as string + const title = req.body.title as string + const description = req.body.description as string + + const create = { + title: title, + description: description, + idAuthor: idAuthor + } + + await recipeBusiness.createRecipe(create) + + res.status(201).send({ message: "Recipe created successfully!" }) + } catch (error: any) { + res.status(400).send(error.message); + } + } +} \ No newline at end of file From c3ddec2693a8e3ce42ce7be91a4b77b4d81237ef Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 17:08:24 -0300 Subject: [PATCH 18/53] router recipe --- src/index.ts | 8 +++++++- src/routes/recipeRouter.ts | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/routes/recipeRouter.ts diff --git a/src/index.ts b/src/index.ts index 42f2118..dd4179d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,12 @@ import { app } from "./app"; +import { recipeRouter } from "./routes/recipeRouter"; import { userRouter } from "./routes/userRouter"; // ENDPOINT CRIAR USUARIO -app.use("", userRouter) \ No newline at end of file +app.use("", userRouter) + + + +// ENDPOINT CRIAR RECEITA +app.use("", recipeRouter) \ No newline at end of file diff --git a/src/routes/recipeRouter.ts b/src/routes/recipeRouter.ts new file mode 100644 index 0000000..416b835 --- /dev/null +++ b/src/routes/recipeRouter.ts @@ -0,0 +1,9 @@ +import express from "express"; +import { RecipeController } from "../controller/RecipeController"; + +export const recipeRouter = express.Router() +const recipeController = new RecipeController() + + +// ENDPOINT CRIAR RECEITA +recipeRouter.post("/recipe", recipeController.createRecipe) \ No newline at end of file From d3e4bce72cf219733dcd47fbbe12ce893d207044 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 19:11:00 -0300 Subject: [PATCH 19/53] redme inicio --- README.md | 26 +++++++++++++++++++++++++- src/index.ts | 1 - 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b32459a..a2bd9eb 100644 --- a/README.md +++ b/README.md @@ -1 +1,25 @@ -# Cookenu \ No newline at end of file +

Cookenu 🍱

+ +Enunciado Projeto:
+Esse produto nada mais é do que uma rede social, na qual os usuários podem dividir informações relevantes sobre comidas e receitas que tenham experimentado. Ela possui todas as funcionalidades mais comuns em redes sociais: + +

Funcionalidades:

+✅ Cadastrar pessoas usuária;
+✅ Login;
+⬛ Informações do próprio perfil;
+✅ Criar receitas;
+⬛ Seguir usuários;
+⬛ Feed
+ +--- + +

🛠Ferramentas:

+- Typescript;
+- Node.js;
+- MySQL;
+- Express;
+- Uuid;
+- JsonWebToken;
+- Knex;
+ +--- diff --git a/src/index.ts b/src/index.ts index dd4179d..356dcdf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,5 @@ import { userRouter } from "./routes/userRouter"; app.use("", userRouter) - // ENDPOINT CRIAR RECEITA app.use("", recipeRouter) \ No newline at end of file From 292bd36132e708c8f8d9f98d95bfe1f3b19fbbf0 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Tue, 14 Feb 2023 19:14:15 -0300 Subject: [PATCH 20/53] request --- request.rest | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/request.rest b/request.rest index 9c7ba56..1932580 100644 --- a/request.rest +++ b/request.rest @@ -16,7 +16,18 @@ POST http://localhost:3003/login Content-Type: application/json { - "email": "bianca@email.com", - "password": "123abc#" + "email": "camila@testando", + "password": "1234567" + +} + +### +POST http://localhost:3003/recipe +Content-Type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEtNDYyMC1iZGVkLWNjODliZTQyNWQ2NSIsImlhdCI6MTY3NjQxMjc5OCwiZXhwIjoxNjc2NDI3MTk4fQ.8tEMuwDXX7Q2770l30RY4lyIZK2BF4XwI1jXS6f0YDE + +{ + "title": "Bolo de banana", + "description": "banana aveia canela acucar" } \ No newline at end of file From 2651b8820134d8f0f7b660c5da3dedf518234a4e Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Wed, 15 Feb 2023 12:08:22 -0300 Subject: [PATCH 21/53] feat: inicio seguidores --- queries.sql | 8 ++++++++ request.rest | 6 ++++-- src/data/FollowDatabase.ts | 5 +++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/data/FollowDatabase.ts diff --git a/queries.sql b/queries.sql index 88d5aec..c1bf7da 100644 --- a/queries.sql +++ b/queries.sql @@ -13,4 +13,12 @@ CREATE TABLE IF NOT EXISTS Cookenu_recipe( creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, id_author VARCHAR(255) NOT NULL, FOREIGN KEY (id_author) REFERENCES Cookenu_users (id) +); + +CREATE Table IF NOT EXISTS Cookenu_follow( + id VARCHAR(255) PRIMARY KEY, + user_id VARCHAR(255) NOT NULL, + follow_id VARCHAR(255) NOT NULL, + FOREIGN KEY (user_id) REFERENCES Cookenu_users (id), + FOREIGN KEY (follow_id) REFERENCES Cookenu_users (id) ); \ No newline at end of file diff --git a/request.rest b/request.rest index 1932580..bf44932 100644 --- a/request.rest +++ b/request.rest @@ -20,7 +20,7 @@ Content-Type: application/json "password": "1234567" } - +// Criar receitas ### POST http://localhost:3003/recipe Content-Type: application/json @@ -30,4 +30,6 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEt "title": "Bolo de banana", "description": "banana aveia canela acucar" -} \ No newline at end of file +} + +### \ No newline at end of file diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts new file mode 100644 index 0000000..0735678 --- /dev/null +++ b/src/data/FollowDatabase.ts @@ -0,0 +1,5 @@ +import { BaseDatabase } from "./BaseDatabase"; + +export class FollowDatabase extends BaseDatabase { + private static TABLE_NAME: string = "Cookenu_follow" +} \ No newline at end of file From 363c39e226e8be17c76901c5468d0260fc0c3ebc Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Wed, 15 Feb 2023 12:19:25 -0300 Subject: [PATCH 22/53] feat: inicio seguidores --- src/data/FollowDatabase.ts | 15 +++++++++++++++ src/model/followDTO.ts | 5 +++++ 2 files changed, 20 insertions(+) create mode 100644 src/model/followDTO.ts diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index 0735678..077b58f 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -1,5 +1,20 @@ +import { CustomError } from "../error/CustomError"; +import { FollowDTO } from "../model/followDTO"; import { BaseDatabase } from "./BaseDatabase"; export class FollowDatabase extends BaseDatabase { private static TABLE_NAME: string = "Cookenu_follow" + + create = async ({ id, userId, followId }: FollowDTO) => { + try { + await FollowDatabase.connection.insert({ + id: id, + user_id: userId, + follow_id: followId + }).into(FollowDatabase.TABLE_NAME) + + } catch (error: any) { + throw new CustomError(400, error.message || error.sqlMessage); + } + } } \ No newline at end of file diff --git a/src/model/followDTO.ts b/src/model/followDTO.ts new file mode 100644 index 0000000..8e8d497 --- /dev/null +++ b/src/model/followDTO.ts @@ -0,0 +1,5 @@ +export interface FollowDTO{ + id: string; + userId: string; + followId: string; +} \ No newline at end of file From 2738fab8741a29fdd71a93d2c28c9dc52b2689e2 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Wed, 15 Feb 2023 12:40:22 -0300 Subject: [PATCH 23/53] feat: business, controller seguidores --- src/business/FollowBusiness.ts | 35 ++++++++++++++++++++++++++++++ src/controller/FollowController.ts | 26 ++++++++++++++++++++++ src/model/followDTO.ts | 5 +++++ 3 files changed, 66 insertions(+) create mode 100644 src/business/FollowBusiness.ts create mode 100644 src/controller/FollowController.ts diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts new file mode 100644 index 0000000..26219c7 --- /dev/null +++ b/src/business/FollowBusiness.ts @@ -0,0 +1,35 @@ +import { FollowDatabase } from "../data/FollowDatabase"; +import { CustomError } from "../error/CustomError"; +import { InputFollowDTO } from "../model/followDTO"; +import { IdGenerator } from "../services/IdGenerator"; +import { TokenGenerator } from "../services/TokenGenerator"; + +const tokenGenerator = new TokenGenerator(); +const idGenerator = new IdGenerator(); +const followDatabase = new FollowDatabase(); + +export class FollowBusiness { + + createFollow = async (input: InputFollowDTO): Promise => { + try { + const { userId, followId } = input + + if (!followId) { + throw new CustomError(400, 'Fill in the fields "followId"'); + } + + const idUserToken = tokenGenerator.tokenData(userId) + + const idFollow = idGenerator.generateId() + + await followDatabase.create({ + id: idFollow, + userId: idUserToken.id, + followId: followId + }) + + } catch (error: any) { + throw new CustomError(400, error.message); + } + } +} \ No newline at end of file diff --git a/src/controller/FollowController.ts b/src/controller/FollowController.ts new file mode 100644 index 0000000..bb25f73 --- /dev/null +++ b/src/controller/FollowController.ts @@ -0,0 +1,26 @@ +import { Request, Response } from "express"; +import { FollowBusiness } from "../business/FollowBusiness"; +import { InputFollowDTO } from "../model/followDTO"; + +const followBusiness = new FollowBusiness(); + +export class FollwController { + createFollw = async (req: Request, res: Response): Promise => { + try { + + const userId = req.headers.authorization as string; + const idFollow = req.body.idFollow + + const create:InputFollowDTO = { + userId:userId, + followId:idFollow + } + await followBusiness.createFollow(create) + + res.status(201).send({ message: "Follow created successfully!" }) + + } catch (error: any) { + res.status(400).send(error.message); + } + } +} \ No newline at end of file diff --git a/src/model/followDTO.ts b/src/model/followDTO.ts index 8e8d497..3be0873 100644 --- a/src/model/followDTO.ts +++ b/src/model/followDTO.ts @@ -2,4 +2,9 @@ export interface FollowDTO{ id: string; userId: string; followId: string; +} + +export interface InputFollowDTO{ + userId: string; + followId: string; } \ No newline at end of file From 8807ee0d80fadcdd9735fc834651865af8f942b1 Mon Sep 17 00:00:00 2001 From: Bianca Paccola Date: Wed, 15 Feb 2023 12:46:13 -0300 Subject: [PATCH 24/53] =?UTF-8?q?endpoint=20de=20mudar=20a=20senha:=20mand?= =?UTF-8?q?a=20o=20email=20pelo=20body,=20a=20pr=C3=B3pria=20aplica=C3=A7?= =?UTF-8?q?=C3=A3o=20faz=20uma=20senha=20aleat=C3=B3ria,=20altera=20no=20b?= =?UTF-8?q?anco=20de=20dados=20e=20envia=20a=20nova=20senha=20para=20o=20e?= =?UTF-8?q?mail=20do=20usu=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 44 +++++++++++++++++++++++++++++++- package-lock.json | 33 ++++++++++++++++++++++++ package.json | 2 ++ request.rest | 18 ++++++++++--- src/business/UserBusiness.ts | 31 ++++++++++++++++++++-- src/controller/UserController.ts | 12 ++++++++- src/data/UserDatabase.ts | 13 +++++++++- src/error/UserErrors.ts | 9 ++++++- src/routes/userRouter.ts | 5 +++- src/services/Nodemailer.ts | 30 ++++++++++++++++++++++ src/utils/passwordGenerate.ts | 3 +++ 11 files changed, 190 insertions(+), 10 deletions(-) create mode 100644 src/services/Nodemailer.ts create mode 100644 src/utils/passwordGenerate.ts diff --git a/README.md b/README.md index a2bd9eb..5ab4d5b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div --- -

🛠Ferramentas:

+

🛠 Ferramentas:

- Typescript;
- Node.js;
- MySQL;
@@ -21,5 +21,47 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div - Uuid;
- JsonWebToken;
- Knex;
+- Bcrypt;
--- + +

⚙️ Instruções para rodar o projeto:

+ +> O arquivo *requests.rest*, presente na pasta raiz do projeto, contém todos os endpoints com url do deploy disponível online (Render) + +Caso queira rodar o projeto localmente, as instruções são: + +``` +git clone https://github.com/future4code/Barros-labook3.git + +cd Barros-labook3 -> para entrar na pasta raiz do projeto + +npm install -> para instalar as dependências do projeto + +criar um arquivo .env com as informações do seus banco de dados + +npm run migrations -> para criar as tabelas no seu banco de dados + +npm run dev -> para rodar o servidor +Instruções para preencher o arquivo dotenv: +``` + +criar um arquivo .env na pasta raiz com as seguintes variáveis: + +``` + DB_HOST: , + DB_USER: , + DB_PASSWORD: , + DB_DATABASE: , +``` + +Preencher as variáveis com as informações do seu banco de dados. + +Ainda no .env, preencher também as variáveis: + + + JWT_KEY: , (palavra passe) + BCRYPT_COST: , (cost da lib Bcrypt, geralmente 12) + NODEMAILER_USER :, (email do qual vai enviar a redefinição de senha) + NODEMAILER_PASS :, (senha do email acima) + diff --git a/package-lock.json b/package-lock.json index 5d2f7ba..579a047 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "jsonwebtoken": "^9.0.0", "knex": "^2.4.2", "mysql": "^2.18.1", + "nodemailer": "^6.9.1", "typescript": "^4.9.5", "uuid": "^9.0.0" }, @@ -25,6 +26,7 @@ "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.1", "@types/knex": "^0.16.1", + "@types/nodemailer": "^6.4.7", "@types/uuid": "^9.0.0", "cors": "^2.8.5", "ts-node-dev": "^2.0.0" @@ -178,6 +180,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==" }, + "node_modules/@types/nodemailer": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.7.tgz", + "integrity": "sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -1136,6 +1147,14 @@ "node": ">= 0.6" } }, + "node_modules/nodemailer": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.1.tgz", + "integrity": "sha512-qHw7dOiU5UKNnQpXktdgQ1d3OFgRAekuvbJLcdG5dnEo/GtcTHRYM7+UfJARdOFU9WUQO8OiIamgWPmiSFHYAA==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1905,6 +1924,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==" }, + "@types/nodemailer": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.7.tgz", + "integrity": "sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -2631,6 +2659,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "nodemailer": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.1.tgz", + "integrity": "sha512-qHw7dOiU5UKNnQpXktdgQ1d3OFgRAekuvbJLcdG5dnEo/GtcTHRYM7+UfJARdOFU9WUQO8OiIamgWPmiSFHYAA==" + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", diff --git a/package.json b/package.json index 0226d9f..dc74a6e 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "jsonwebtoken": "^9.0.0", "knex": "^2.4.2", "mysql": "^2.18.1", + "nodemailer": "^6.9.1", "typescript": "^4.9.5", "uuid": "^9.0.0" }, @@ -36,6 +37,7 @@ "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.1", "@types/knex": "^0.16.1", + "@types/nodemailer": "^6.4.7", "@types/uuid": "^9.0.0", "cors": "^2.8.5", "ts-node-dev": "^2.0.0" diff --git a/request.rest b/request.rest index 1932580..66e281d 100644 --- a/request.rest +++ b/request.rest @@ -5,7 +5,7 @@ Content-Type: application/json { "name":"Bianca Paccola", - "email":"bianca@email.com", + "email":"bianca.paccola@gmail.com", "password":"123abc#" } @@ -16,12 +16,14 @@ POST http://localhost:3003/login Content-Type: application/json { - "email": "camila@testando", - "password": "1234567" + "email": "bianca.paccola@gmail.com", + "password": "w5glbr6" } ### + +// Criar receita POST http://localhost:3003/recipe Content-Type: application/json Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEtNDYyMC1iZGVkLWNjODliZTQyNWQ2NSIsImlhdCI6MTY3NjQxMjc5OCwiZXhwIjoxNjc2NDI3MTk4fQ.8tEMuwDXX7Q2770l30RY4lyIZK2BF4XwI1jXS6f0YDE @@ -30,4 +32,14 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEt "title": "Bolo de banana", "description": "banana aveia canela acucar" +} + +### + +// Esqueci a senha +PUT http://localhost:3003/forgot-password +Content-Type: application/json + +{ + "email": "bianca.paccola@gmail.com" } \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 04fb617..0dfec81 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -1,10 +1,12 @@ import { UserDatabase } from "../data/UserDatabase"; import { CustomError } from "../error/CustomError"; -import { UserIncompleteData, UserIncorrectPassword, UserInvalidEmail, UserInvalidPassword, UserNotFound } from "../error/UserErrors"; +import { UserMissingEmail, UserIncompleteData, UserIncorrectPassword, UserInvalidEmail, UserInvalidPassword, UserNotFound } from "../error/UserErrors"; import { InputUserDTO, UserDTO, userLoginDTO } from "../model/userDTO"; import { HashGenerator } from "../services/HashGenerator"; import { IdGenerator } from "../services/IdGenerator"; import { TokenGenerator } from "../services/TokenGenerator"; +import { passwordGenerate } from "../utils/passwordGenerate"; +import sendNodemailer from "../services/Nodemailer" const idGenerator = new IdGenerator(); const tokenGenerator = new TokenGenerator(); @@ -56,7 +58,7 @@ export class UserBusiness { } - public async login ({email, password}:userLoginDTO ) { + public async login ({email, password}:userLoginDTO ):Promise { try { if(!email || !password) { throw new UserIncompleteData() @@ -88,4 +90,29 @@ export class UserBusiness { throw new CustomError(400, error.message); } } + + public async forgotPassword (email: string): Promise { + try { + if(!email) { + throw new UserMissingEmail() + } + + if(!email.includes('@')) { + throw new UserInvalidEmail() + } + + const user = await userDatabase.findByEmail(email); + if (!user) { + throw new UserNotFound; + } + + const newPassword = passwordGenerate().toString() + const passwordHash = await hashGenerator.generateHash(newPassword) + await userDatabase.changePassword(user.id, passwordHash); + await sendNodemailer(email, newPassword) + + } catch (error:any) { + throw new CustomError(400, error.message); + } + } } \ No newline at end of file diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index 822b3a9..ee87e1f 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -26,7 +26,7 @@ export class UserController { } } - public async login (req: Request, res: Response) { + public async login (req: Request, res: Response): Promise { try { const {email, password} = req.body const token = await userBusiness.login({email, password}) @@ -37,4 +37,14 @@ export class UserController { res.status(400).send(error.message); } } + + public async forgotPassword (req: Request, res: Response):Promise { + try { + const email: string = req.body.email + await userBusiness.forgotPassword(email) + res.status(200).send({message: "A new password has been sent to the email."}) + } catch (error:any) { + res.status(400).send(error.message); + } + } } \ No newline at end of file diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index a254163..685e0e2 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -32,7 +32,7 @@ export class UserDatabase extends BaseDatabase { } } - public async findByEmail (email: string) { + public async findByEmail (email: string):Promise { try { const user = await UserDatabase.connection .select('*') @@ -44,4 +44,15 @@ export class UserDatabase extends BaseDatabase { throw new CustomError(400, error.message || error.sqlMessage); } } + + public async changePassword (id:string, newPassword:string) { + try { + await UserDatabase.connection + .where({id}) + .update({password: newPassword}) + .into(UserDatabase.TABLE_NAME) + } catch (error:any) { + throw new CustomError(400, error.message || error.sqlMessage); + } + } } \ No newline at end of file diff --git a/src/error/UserErrors.ts b/src/error/UserErrors.ts index 2f9d51e..013b84c 100644 --- a/src/error/UserErrors.ts +++ b/src/error/UserErrors.ts @@ -6,6 +6,13 @@ export class UserIncompleteData extends CustomError { } } +export class UserMissingEmail extends CustomError { + constructor() { + super(422, "You must send the email") + } +} + + export class UserInvalidEmail extends CustomError { constructor() { super(422, "Invalid Email") @@ -28,4 +35,4 @@ export class UserIncorrectPassword extends CustomError { constructor() { super(401, "Unauthorized: Incorrect password.") } -} \ No newline at end of file +} diff --git a/src/routes/userRouter.ts b/src/routes/userRouter.ts index 2d5cc3a..0f2d70e 100644 --- a/src/routes/userRouter.ts +++ b/src/routes/userRouter.ts @@ -9,4 +9,7 @@ const userController = new UserController() userRouter.post("/signup", userController.signup) //ENDPOINT FAZER LOGIN -userRouter.post("/login", userController.login) \ No newline at end of file +userRouter.post("/login", userController.login) + +//ENDPOINT PARA ENVIAR UMA SENHA NOVA POR EMAIL - ESQUECI MINHA SENHA +userRouter.put("/forgot-password", userController.forgotPassword) \ No newline at end of file diff --git a/src/services/Nodemailer.ts b/src/services/Nodemailer.ts new file mode 100644 index 0000000..5c9ad37 --- /dev/null +++ b/src/services/Nodemailer.ts @@ -0,0 +1,30 @@ +import dotenv from 'dotenv'; +import nodemailer from 'nodemailer' + +dotenv.config(); + +const transporter = nodemailer.createTransport({ + host: 'smtp.gmail.com', + port: 587, + secure: false, + auth: { + user: process.env.NODEMAILER_USER, + pass: process.env.NODEMAILER_PASS, + }, + tls: { + ciphers: "SSLv3", + rejectUnauthorized: false, + }, +}); + +async function sendNodemailer (email: string, password: string) { + const mailSend = await transporter.sendMail({ + from: process.env.NODEMAILER_USER, + to: email, + subject: "Redefinição de senha", + text: `Sua nova senha é: ${password}` + }) + return mailSend; +} + +export default sendNodemailer; \ No newline at end of file diff --git a/src/utils/passwordGenerate.ts b/src/utils/passwordGenerate.ts new file mode 100644 index 0000000..3355a60 --- /dev/null +++ b/src/utils/passwordGenerate.ts @@ -0,0 +1,3 @@ +export function passwordGenerate() { + return Math.random().toString(36).slice(-7); +} \ No newline at end of file From 1e1385f71c197dd76e5ac042ed16250f8d76cb1c Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Wed, 15 Feb 2023 13:33:00 -0300 Subject: [PATCH 25/53] =?UTF-8?q?feat:=20endpoitn=20create=20follow,=20sem?= =?UTF-8?q?=20verifica=C3=A7=C3=B5es=20de=20erros?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- queries.sql | 11 ++++++----- request.rest | 9 ++++++++- src/business/FollowBusiness.ts | 3 ++- src/controller/FollowController.ts | 10 ++++++---- src/data/FollowDatabase.ts | 4 +++- src/index.ts | 6 +++++- src/routes/followRouter.ts | 10 ++++++++++ 7 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 src/routes/followRouter.ts diff --git a/queries.sql b/queries.sql index c1bf7da..3e0f5e9 100644 --- a/queries.sql +++ b/queries.sql @@ -17,8 +17,9 @@ CREATE TABLE IF NOT EXISTS Cookenu_recipe( CREATE Table IF NOT EXISTS Cookenu_follow( id VARCHAR(255) PRIMARY KEY, - user_id VARCHAR(255) NOT NULL, - follow_id VARCHAR(255) NOT NULL, - FOREIGN KEY (user_id) REFERENCES Cookenu_users (id), - FOREIGN KEY (follow_id) REFERENCES Cookenu_users (id) -); \ No newline at end of file + user_id VARCHAR(255), + follow_id VARCHAR(255) , + FOREIGN KEY (user_id) REFERENCES Cookenu_users(id), + FOREIGN KEY (follow_id) REFERENCES Cookenu_users(id) +); + diff --git a/request.rest b/request.rest index bf44932..02efd15 100644 --- a/request.rest +++ b/request.rest @@ -32,4 +32,11 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEt } -### \ No newline at end of file +### +POST http://localhost:3003/follow +Content-Type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEtNDYyMC1iZGVkLWNjODliZTQyNWQ2NSIsImlhdCI6MTY3NjQ3NjAxMCwiZXhwIjoxNjc2NDkwNDEwfQ.Uc9kuilNia3F2tRgeEVZZCRyzkSKeG8vRbLJHZ8O1yU + +{ + "followId": "c8ff9401-dd13-44f2-9c36-ddbf173006a3" +} \ No newline at end of file diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts index 26219c7..341708b 100644 --- a/src/business/FollowBusiness.ts +++ b/src/business/FollowBusiness.ts @@ -19,7 +19,8 @@ export class FollowBusiness { } const idUserToken = tokenGenerator.tokenData(userId) - + // console.log(idUserToken.id); + const idFollow = idGenerator.generateId() await followDatabase.create({ diff --git a/src/controller/FollowController.ts b/src/controller/FollowController.ts index bb25f73..261b38d 100644 --- a/src/controller/FollowController.ts +++ b/src/controller/FollowController.ts @@ -4,17 +4,19 @@ import { InputFollowDTO } from "../model/followDTO"; const followBusiness = new FollowBusiness(); -export class FollwController { - createFollw = async (req: Request, res: Response): Promise => { +export class FollowController { + createFollow = async (req: Request, res: Response): Promise => { try { const userId = req.headers.authorization as string; - const idFollow = req.body.idFollow + const followId = req.body.followId const create:InputFollowDTO = { userId:userId, - followId:idFollow + followId:followId } + // console.log(create); + await followBusiness.createFollow(create) res.status(201).send({ message: "Follow created successfully!" }) diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index 077b58f..c187740 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -5,8 +5,10 @@ import { BaseDatabase } from "./BaseDatabase"; export class FollowDatabase extends BaseDatabase { private static TABLE_NAME: string = "Cookenu_follow" - create = async ({ id, userId, followId }: FollowDTO) => { + create = async (input: FollowDTO):Promise => { try { + const {id, userId, followId} = input + await FollowDatabase.connection.insert({ id: id, user_id: userId, diff --git a/src/index.ts b/src/index.ts index 356dcdf..4b0381b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import { app } from "./app"; +import { followRouter } from "./routes/followRouter"; import { recipeRouter } from "./routes/recipeRouter"; import { userRouter } from "./routes/userRouter"; @@ -8,4 +9,7 @@ app.use("", userRouter) // ENDPOINT CRIAR RECEITA -app.use("", recipeRouter) \ No newline at end of file +app.use("", recipeRouter) + +//ENDPOINT CRIAR SEGUIR +app.use("",followRouter) \ No newline at end of file diff --git a/src/routes/followRouter.ts b/src/routes/followRouter.ts new file mode 100644 index 0000000..d378e4a --- /dev/null +++ b/src/routes/followRouter.ts @@ -0,0 +1,10 @@ +import express from "express"; +import { FollowController } from "../controller/FollowController"; + + +export const followRouter = express.Router() +const followController = new FollowController() + + +// ENDPOINT CRIAR RECEITA +followRouter.post("/follow", followController.createFollow) \ No newline at end of file From 00c38bbe2bb9de02f7c9343d856db883140a4ba2 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Wed, 15 Feb 2023 14:09:53 -0300 Subject: [PATCH 26/53] =?UTF-8?q?feat:=20verifica=C3=A7=C3=A3o=20se=20ja?= =?UTF-8?q?=20existe=20curtidA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- request.rest | 8 +++---- src/business/FollowBusiness.ts | 38 ++++++++++++++++++++++++---------- src/data/FollowDatabase.ts | 25 +++++++++++++++++++--- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/request.rest b/request.rest index 02efd15..36d32de 100644 --- a/request.rest +++ b/request.rest @@ -16,8 +16,8 @@ POST http://localhost:3003/login Content-Type: application/json { - "email": "camila@testando", - "password": "1234567" + "email": "bianca@email.com", + "password": "123abc#" } // Criar receitas @@ -35,8 +35,8 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEt ### POST http://localhost:3003/follow Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEtNDYyMC1iZGVkLWNjODliZTQyNWQ2NSIsImlhdCI6MTY3NjQ3NjAxMCwiZXhwIjoxNjc2NDkwNDEwfQ.Uc9kuilNia3F2tRgeEVZZCRyzkSKeG8vRbLJHZ8O1yU +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjBiYTc5NWM5LTBlNGYtNGNkYi04ZTY1LTA2YzJiNDUxZWIxMSIsImlhdCI6MTY3NjQ3OTUwOCwiZXhwIjoxNjc2NDkzOTA4fQ._js7FKv4PMYsP3Jv7HzeLUdxLdgB1Wkj7JMf6aNSRx4 { - "followId": "c8ff9401-dd13-44f2-9c36-ddbf173006a3" + "followId":"72f25832-3249-44d3-bb14-5de2ec7da0d2" } \ No newline at end of file diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts index 341708b..2136c35 100644 --- a/src/business/FollowBusiness.ts +++ b/src/business/FollowBusiness.ts @@ -1,6 +1,6 @@ import { FollowDatabase } from "../data/FollowDatabase"; import { CustomError } from "../error/CustomError"; -import { InputFollowDTO } from "../model/followDTO"; +import { FollowDTO, InputFollowDTO } from "../model/followDTO"; import { IdGenerator } from "../services/IdGenerator"; import { TokenGenerator } from "../services/TokenGenerator"; @@ -13,24 +13,40 @@ export class FollowBusiness { createFollow = async (input: InputFollowDTO): Promise => { try { const { userId, followId } = input - if (!followId) { throw new CustomError(400, 'Fill in the fields "followId"'); } - const idUserToken = tokenGenerator.tokenData(userId) - // console.log(idUserToken.id); - + const idFollow = idGenerator.generateId() - await followDatabase.create({ - id: idFollow, - userId: idUserToken.id, - followId: followId - }) + const verificationUserId = await followDatabase.getAll({ userId: idUserToken.id, followId: followId }) + + if (verificationUserId === undefined) { + + const insertFollow: FollowDTO = { + id: idFollow, + userId: idUserToken.id, + followId: followId + } + + await followDatabase.create(insertFollow) + }else{ + throw new CustomError(400, "Follow already exists"); + } } catch (error: any) { throw new CustomError(400, error.message); } } -} \ No newline at end of file +} + + + + + // await followDatabase.create({ + // id: idFollow, + // userId: idUserToken.id, + // followId: followId + // }) + diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index c187740..d1dcec4 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -1,13 +1,13 @@ import { CustomError } from "../error/CustomError"; -import { FollowDTO } from "../model/followDTO"; +import { FollowDTO, InputFollowDTO } from "../model/followDTO"; import { BaseDatabase } from "./BaseDatabase"; export class FollowDatabase extends BaseDatabase { private static TABLE_NAME: string = "Cookenu_follow" - create = async (input: FollowDTO):Promise => { + create = async (input: FollowDTO): Promise => { try { - const {id, userId, followId} = input + const { id, userId, followId } = input await FollowDatabase.connection.insert({ id: id, @@ -19,4 +19,23 @@ export class FollowDatabase extends BaseDatabase { throw new CustomError(400, error.message || error.sqlMessage); } } + + getAll = async ({ userId, followId }: InputFollowDTO) => { + try { + + const result = await FollowDatabase.connection() + .select("*") + .from(FollowDatabase.TABLE_NAME) + .where({ + user_id: userId, + follow_id:followId + }) + + console.log(result[0]); + return (result[0]) + + } catch (error: any) { + throw new CustomError(400, error.message || error.sqlMessage); + } + } } \ No newline at end of file From 5cdb5c5e96f1a591e0f41b17dd40667123443b0a Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Wed, 15 Feb 2023 14:14:01 -0300 Subject: [PATCH 27/53] =?UTF-8?q?modificando=20situa=C3=A7=C3=A3o=20do=20e?= =?UTF-8?q?ndpoint=20no=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2bd9eb..b076adb 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div ✅ Login;
⬛ Informações do próprio perfil;
✅ Criar receitas;
-⬛ Seguir usuários;
+✅ Seguir usuários;
⬛ Feed
--- From 00960ec448a0420e72f60a43b4fe584670fae450 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Wed, 15 Feb 2023 17:08:34 -0300 Subject: [PATCH 28/53] ajustes --- src/business/FollowBusiness.ts | 3 +++ src/business/UserBusiness.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts index 2136c35..73de3c3 100644 --- a/src/business/FollowBusiness.ts +++ b/src/business/FollowBusiness.ts @@ -16,6 +16,9 @@ export class FollowBusiness { if (!followId) { throw new CustomError(400, 'Fill in the fields "followId"'); } + if(followId === undefined){ + throw new CustomError(400, 'Fill in the fields "followId"'); + } const idUserToken = tokenGenerator.tokenData(userId) const idFollow = idGenerator.generateId() diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 04fb617..60716f2 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -64,7 +64,7 @@ export class UserBusiness { if (!email.includes("@" )) { throw new UserInvalidEmail() } - if (password.length <= 6) { + if (password.length <= 5) { throw new UserInvalidPassword() } From dd502f39953b5565259208623c7586015c934442 Mon Sep 17 00:00:00 2001 From: MartinsCaroline <102299433+CarolineMartins09@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:33:45 -0300 Subject: [PATCH 29/53] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 5ab4d5b..2ffe55a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div ✅ Login;
⬛ Informações do próprio perfil;
✅ Criar receitas;
-⬛ Seguir usuários;
+✅ Seguir usuários;
⬛ Feed
--- @@ -34,8 +34,6 @@ Caso queira rodar o projeto localmente, as instruções são: ``` git clone https://github.com/future4code/Barros-labook3.git -cd Barros-labook3 -> para entrar na pasta raiz do projeto - npm install -> para instalar as dependências do projeto criar um arquivo .env com as informações do seus banco de dados From 9e9e3ee8b9340fae9339e1880666d76427aa2e08 Mon Sep 17 00:00:00 2001 From: MartinsCaroline <102299433+CarolineMartins09@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:37:37 -0300 Subject: [PATCH 30/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2ffe55a..b0726df 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Enunciado Projeto:
Esse produto nada mais é do que uma rede social, na qual os usuários podem dividir informações relevantes sobre comidas e receitas que tenham experimentado. Ela possui todas as funcionalidades mais comuns em redes sociais: -

Funcionalidades:

+

💻 Funcionalidades:

✅ Cadastrar pessoas usuária;
✅ Login;
⬛ Informações do próprio perfil;
From d105a9b09769fc96808e760d29658f781571a388 Mon Sep 17 00:00:00 2001 From: Bianca Paccola Date: Wed, 15 Feb 2023 17:47:57 -0300 Subject: [PATCH 31/53] arrumando link do readme --- README.md | 4 ++-- src/error/UserErrors.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b0726df..ede43c0 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,13 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div Caso queira rodar o projeto localmente, as instruções são: ``` -git clone https://github.com/future4code/Barros-labook3.git +git clone https://github.com/future4code/Barros-cookenu9.git npm install -> para instalar as dependências do projeto criar um arquivo .env com as informações do seus banco de dados -npm run migrations -> para criar as tabelas no seu banco de dados +executar as queries do arquivo queries.sql para criar as tabelas npm run dev -> para rodar o servidor Instruções para preencher o arquivo dotenv: diff --git a/src/error/UserErrors.ts b/src/error/UserErrors.ts index 013b84c..f793dec 100644 --- a/src/error/UserErrors.ts +++ b/src/error/UserErrors.ts @@ -21,7 +21,7 @@ export class UserInvalidEmail extends CustomError { export class UserInvalidPassword extends CustomError { constructor() { - super(422, "Password must contain at least 7 characters.") + super(422, "Password must contain at least 6 characters.") } } From d89706ae3fc2f2c8a166f1cb81ad804ece3e2eae Mon Sep 17 00:00:00 2001 From: MartinsCaroline <102299433+CarolineMartins09@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:59:24 -0300 Subject: [PATCH 32/53] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b0726df..b31c5f6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div ⬛ Informações do próprio perfil;
✅ Criar receitas;
✅ Seguir usuários;
-⬛ Feed
+⬛ Alimentação
+✅ Esqueceu senha;
--- From 45776c7343f585bc54cb27d1abba4d3410f7c87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:40:26 -0300 Subject: [PATCH 33/53] feat:get all users --- request.rest | 5 +++++ src/business/UserBusiness.ts | 9 +++++++++ src/controller/UserController.ts | 10 ++++++++++ src/data/UserDatabase.ts | 8 ++++---- src/routes/userRouter.ts | 5 ++++- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/request.rest b/request.rest index 66e281d..7358c53 100644 --- a/request.rest +++ b/request.rest @@ -10,6 +10,11 @@ Content-Type: application/json } ### +// Retorna todos os usuários cadastrados no banco de dados +GET http://localhost:3003/all + +### + // Login POST http://localhost:3003/login diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 0dfec81..fae3856 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -115,4 +115,13 @@ export class UserBusiness { throw new CustomError(400, error.message); } } + + getAll = async() => { + try { + return await userDatabase.getAll() + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + } + + } } \ No newline at end of file diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index ee87e1f..aae570a 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -47,4 +47,14 @@ export class UserController { res.status(400).send(error.message); } } + + getAll = async(req:Request, res:Response) => { + try { + let result = await userBusiness.getAll() + res.status(200).send(result) + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + + } + } } \ No newline at end of file diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index 685e0e2..2d01d34 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -20,11 +20,11 @@ export class UserDatabase extends BaseDatabase { } } - getAll = async(email:string)=>{ + getAll = async()=>{ try{ - const result = await UserDatabase.connection.raw(` - SELECT email FROM ${UserDatabase.TABLE_NAME} WHERE email=${email} - `) + const result = await UserDatabase.connection + .select() + .from(UserDatabase.TABLE_NAME) return (result) }catch(error:any){ diff --git a/src/routes/userRouter.ts b/src/routes/userRouter.ts index 0f2d70e..6ad7309 100644 --- a/src/routes/userRouter.ts +++ b/src/routes/userRouter.ts @@ -12,4 +12,7 @@ userRouter.post("/signup", userController.signup) userRouter.post("/login", userController.login) //ENDPOINT PARA ENVIAR UMA SENHA NOVA POR EMAIL - ESQUECI MINHA SENHA -userRouter.put("/forgot-password", userController.forgotPassword) \ No newline at end of file +userRouter.put("/forgot-password", userController.forgotPassword) + +//ENDPOINT PARA RETORNAR TODOS OS USUÁRIOS +userRouter.get("/all", userController.getAll) \ No newline at end of file From e7a6183aee10f3db6ee0f6e250c8af5ea8e32727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Wed, 15 Feb 2023 22:21:41 -0300 Subject: [PATCH 34/53] feat:pegar dados pelo token de login --- request.rest | 8 +++++++- src/business/UserBusiness.ts | 20 +++++++++++++++++++- src/controller/UserController.ts | 10 ++++++++++ src/data/UserDatabase.ts | 21 ++++++++++++++++++++- src/routes/userRouter.ts | 4 +++- 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/request.rest b/request.rest index 7358c53..4680ea2 100644 --- a/request.rest +++ b/request.rest @@ -47,4 +47,10 @@ Content-Type: application/json { "email": "bianca.paccola@gmail.com" -} \ No newline at end of file +} + +### + +GET http://localhost:3003/user +Content-Type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMDMwMSwiZXhwIjoxNjc2NTI0NzAxfQ.YGwjMffJ363AxdlU7TtPH1k7uHtLbQaI_dGIV15Oxhg \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index fae3856..74c5b9f 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -1,7 +1,7 @@ import { UserDatabase } from "../data/UserDatabase"; import { CustomError } from "../error/CustomError"; import { UserMissingEmail, UserIncompleteData, UserIncorrectPassword, UserInvalidEmail, UserInvalidPassword, UserNotFound } from "../error/UserErrors"; -import { InputUserDTO, UserDTO, userLoginDTO } from "../model/userDTO"; +import { AuthenticationData, InputUserDTO, UserDTO, userLoginDTO } from "../model/userDTO"; import { HashGenerator } from "../services/HashGenerator"; import { IdGenerator } from "../services/IdGenerator"; import { TokenGenerator } from "../services/TokenGenerator"; @@ -124,4 +124,22 @@ export class UserBusiness { } } + + getById = async(token:string) => { + try { + if (!token) { + throw new Error("Missing authorization"); + } + let id:AuthenticationData = tokenGenerator.tokenData(token) + let userId:any = await userDatabase.checkIfExists(id.id) + userId=JSON.parse(JSON.stringify(userId)) + + if (userId[0].id !== id.id) { + throw new CustomError(400, "Token is invalid"); + } + return await userDatabase.getById(id.id) + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + } + } } \ No newline at end of file diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index aae570a..8a7961d 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -57,4 +57,14 @@ export class UserController { } } + + getById = async(req:Request, res:Response) => { + try { + let token = req.headers.authorization as string + let result = await userBusiness.getById(token) + res.status(200).send(result) + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + } + } } \ No newline at end of file diff --git a/src/data/UserDatabase.ts b/src/data/UserDatabase.ts index 2d01d34..3fe813d 100644 --- a/src/data/UserDatabase.ts +++ b/src/data/UserDatabase.ts @@ -23,7 +23,7 @@ export class UserDatabase extends BaseDatabase { getAll = async()=>{ try{ const result = await UserDatabase.connection - .select() + .select('id', 'name') .from(UserDatabase.TABLE_NAME) return (result) @@ -32,6 +32,18 @@ export class UserDatabase extends BaseDatabase { } } + getById = async(id:string) => { + try { + const result = await UserDatabase.connection + .select() + .where({id}) + .from(UserDatabase.TABLE_NAME) + return result + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + } + } + public async findByEmail (email: string):Promise { try { const user = await UserDatabase.connection @@ -55,4 +67,11 @@ export class UserDatabase extends BaseDatabase { throw new CustomError(400, error.message || error.sqlMessage); } } + checkIfExists = async (id:string):Promise => { + let result:UserDTO = await BaseDatabase.connection + .select() + .where({id}) + .from(UserDatabase.TABLE_NAME) + return result + } } \ No newline at end of file diff --git a/src/routes/userRouter.ts b/src/routes/userRouter.ts index 6ad7309..74b5fc5 100644 --- a/src/routes/userRouter.ts +++ b/src/routes/userRouter.ts @@ -15,4 +15,6 @@ userRouter.post("/login", userController.login) userRouter.put("/forgot-password", userController.forgotPassword) //ENDPOINT PARA RETORNAR TODOS OS USUÁRIOS -userRouter.get("/all", userController.getAll) \ No newline at end of file +userRouter.get("/all", userController.getAll) + +userRouter.get("/user", userController.getById) \ No newline at end of file From 83ad6b557da98507194014f79adea36af6559147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Wed, 15 Feb 2023 23:29:02 -0300 Subject: [PATCH 35/53] =?UTF-8?q?feat:=20pegar=20todas=20as=20receitas=20d?= =?UTF-8?q?e=20um=20usu=C3=A1rio=20especifico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- request.rest | 14 ++++++++++---- src/business/RecipeBusiness.ts | 14 ++++++++++++++ src/controller/RecipeController.ts | 10 ++++++++++ src/data/RecipeDatabase.ts | 12 ++++++++++++ src/routes/recipeRouter.ts | 4 +++- 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/request.rest b/request.rest index 4680ea2..8d7fcb4 100644 --- a/request.rest +++ b/request.rest @@ -31,11 +31,11 @@ Content-Type: application/json // Criar receita POST http://localhost:3003/recipe Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMyNWExNThiLTE1NzEtNDYyMC1iZGVkLWNjODliZTQyNWQ2NSIsImlhdCI6MTY3NjQxMjc5OCwiZXhwIjoxNjc2NDI3MTk4fQ.8tEMuwDXX7Q2770l30RY4lyIZK2BF4XwI1jXS6f0YDE +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMzU2MywiZXhwIjoxNjc2NTI3OTYzfQ.57tIymx6FtxvsuuheQHmfh4mK-WDHI1cUU2sfR0_2gM { - "title": "Bolo de banana", - "description": "banana aveia canela acucar" + "title": "Brigadeiro", + "description": "Misture uma colher de manteiga com uma caixa de leite condensado, quatro colheres de achocolatado e misture até desgrudar da panela" } @@ -53,4 +53,10 @@ Content-Type: application/json GET http://localhost:3003/user Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMDMwMSwiZXhwIjoxNjc2NTI0NzAxfQ.YGwjMffJ363AxdlU7TtPH1k7uHtLbQaI_dGIV15Oxhg \ No newline at end of file +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMDMwMSwiZXhwIjoxNjc2NTI0NzAxfQ.YGwjMffJ363AxdlU7TtPH1k7uHtLbQaI_dGIV15Oxhg + +### + +GET http://localhost:3003/all-recipes +Content-Type: application/json +Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMzU2MywiZXhwIjoxNjc2NTI3OTYzfQ.57tIymx6FtxvsuuheQHmfh4mK-WDHI1cUU2sfR0_2gM \ No newline at end of file diff --git a/src/business/RecipeBusiness.ts b/src/business/RecipeBusiness.ts index 1a49a0f..bdbfe33 100644 --- a/src/business/RecipeBusiness.ts +++ b/src/business/RecipeBusiness.ts @@ -1,6 +1,7 @@ import { RecipeDatabase } from "../data/RecipeDatabase"; import { CustomError } from "../error/CustomError"; import { InputRecipeDTO } from "../model/recipeDTO"; +import { AuthenticationData } from "../model/userDTO"; import { IdGenerator } from "../services/IdGenerator"; import { TokenGenerator } from "../services/TokenGenerator"; @@ -34,4 +35,17 @@ export class RecipeBusiness { throw new CustomError(400, error.message); } } + + getRecipes = async(token:string) => { + try { + if (!token) { + throw new Error("Missing authorization"); + } + let id:AuthenticationData = tokenGenerator.tokenData(token) + return await recipeDatabase.getRecipes(id.id) + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + + } + } } \ No newline at end of file diff --git a/src/controller/RecipeController.ts b/src/controller/RecipeController.ts index 9347a21..a85d378 100644 --- a/src/controller/RecipeController.ts +++ b/src/controller/RecipeController.ts @@ -26,4 +26,14 @@ export class RecipeController { res.status(400).send(error.message); } } + + getRecipes = async(req:Request, res:Response) => { + try { + let token = req.headers.authorization as string + let result = await recipeBusiness.getRecipes(token) + res.status(200).send(result) + }catch(error:any){ + throw new Error(error.message || error.sqlMessage); + } + } } \ No newline at end of file diff --git a/src/data/RecipeDatabase.ts b/src/data/RecipeDatabase.ts index e83862a..c37e6bf 100644 --- a/src/data/RecipeDatabase.ts +++ b/src/data/RecipeDatabase.ts @@ -20,4 +20,16 @@ export class RecipeDatabase extends BaseDatabase{ throw new CustomError(400, error.message || error.sqlMessage); } } + getRecipes = async(id:string) => { + try { + let result = await RecipeDatabase.connection + .select() + .where('id_author', id) + .from(RecipeDatabase.TABLE_NAME) + return result + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + + } + } } \ No newline at end of file diff --git a/src/routes/recipeRouter.ts b/src/routes/recipeRouter.ts index 416b835..e6a0e90 100644 --- a/src/routes/recipeRouter.ts +++ b/src/routes/recipeRouter.ts @@ -6,4 +6,6 @@ const recipeController = new RecipeController() // ENDPOINT CRIAR RECEITA -recipeRouter.post("/recipe", recipeController.createRecipe) \ No newline at end of file +recipeRouter.post("/recipe", recipeController.createRecipe) + +recipeRouter.get("/all-recipes", recipeController.getRecipes) \ No newline at end of file From f0b481611ea8e3035d0f3ca14786b7e1c4cefe2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Thu, 16 Feb 2023 15:17:08 -0300 Subject: [PATCH 36/53] feat:Pegar a tabela de seguidores --- request.rest | 21 ++++++++++++++++----- src/business/FollowBusiness.ts | 13 ++++++++++++- src/controller/FollowController.ts | 9 +++++++++ src/data/FollowDatabase.ts | 13 ++++++++++++- src/routes/followRouter.ts | 4 +++- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/request.rest b/request.rest index 03a6a97..4420351 100644 --- a/request.rest +++ b/request.rest @@ -21,8 +21,8 @@ POST http://localhost:3003/login Content-Type: application/json { - "email": "bianca.paccola@gmail.com", - "password": "w5glbr6" + "email": "lbsouza@gmail.com", + "password": "teste_cript" } // Criar receitas ### @@ -40,12 +40,14 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUt ### +// Recupera os dados de um seguidor com autorização. POST http://localhost:3003/follow Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjBiYTc5NWM5LTBlNGYtNGNkYi04ZTY1LTA2YzJiNDUxZWIxMSIsImlhdCI6MTY3NjQ3OTUwOCwiZXhwIjoxNjc2NDkzOTA4fQ._js7FKv4PMYsP3Jv7HzeLUdxLdgB1Wkj7JMf6aNSRx4 +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjUxOTEyNCwiZXhwIjoxNjc2NTMzNTI0fQ.ipKOXoOoLRaCw5VN_-nDrpKNXek82D7emTD3CwQ9G4Q { - "followId":"72f25832-3249-44d3-bb14-5de2ec7da0d2" + "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" + } @@ -62,12 +64,21 @@ Content-Type: application/json ### +// Recupera dados confidenciais de um usuário com a autorização concedida pelo token. GET http://localhost:3003/user Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMDMwMSwiZXhwIjoxNjc2NTI0NzAxfQ.YGwjMffJ363AxdlU7TtPH1k7uHtLbQaI_dGIV15Oxhg +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU3MDU2NywiZXhwIjoxNjc2NTg0OTY3fQ.X7xCSF2HirlWg6Z87ItONyTqClGvvuY-yZ1ZW0Sj9Xw ### +// Obtenha as receitas de um usuário específico utilizando o seu token de acesso. GET http://localhost:3003/all-recipes Content-Type: application/json Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMzU2MywiZXhwIjoxNjc2NTI3OTYzfQ.57tIymx6FtxvsuuheQHmfh4mK-WDHI1cUU2sfR0_2gM + + +### + +// Recuperar a lista de relações entre quem segue e quem é seguido. +GET http://localhost:3003/all-followers +Content-Type: application/json \ No newline at end of file diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts index 73de3c3..e9422bf 100644 --- a/src/business/FollowBusiness.ts +++ b/src/business/FollowBusiness.ts @@ -23,7 +23,7 @@ export class FollowBusiness { const idFollow = idGenerator.generateId() - const verificationUserId = await followDatabase.getAll({ userId: idUserToken.id, followId: followId }) + const verificationUserId = await followDatabase.getById({ userId: idUserToken.id, followId: followId }) if (verificationUserId === undefined) { @@ -42,6 +42,17 @@ export class FollowBusiness { throw new CustomError(400, error.message); } } + getAll = async () => { + try { + let result:FollowDTO[] = await followDatabase.getAll() + if (result.length <= 0) { + throw new CustomError(404, "No followers yet"); + } + return result + } catch (error) { + + } + } } diff --git a/src/controller/FollowController.ts b/src/controller/FollowController.ts index 261b38d..430675b 100644 --- a/src/controller/FollowController.ts +++ b/src/controller/FollowController.ts @@ -25,4 +25,13 @@ export class FollowController { res.status(400).send(error.message); } } + getAll = async(req:Request, res:Response) => { + try { + let result = await followBusiness.getAll() + res.status(200).send(result) + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + + } + } } \ No newline at end of file diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index d1dcec4..a4757aa 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -20,7 +20,7 @@ export class FollowDatabase extends BaseDatabase { } } - getAll = async ({ userId, followId }: InputFollowDTO) => { + getById = async ({ userId, followId }: InputFollowDTO) => { try { const result = await FollowDatabase.connection() @@ -38,4 +38,15 @@ export class FollowDatabase extends BaseDatabase { throw new CustomError(400, error.message || error.sqlMessage); } } + getAll = async():Promise => { + try { + let result:FollowDTO[] = await FollowDatabase.connection + .select() + .from(FollowDatabase.TABLE_NAME) + return result + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + + } + } } \ No newline at end of file diff --git a/src/routes/followRouter.ts b/src/routes/followRouter.ts index d378e4a..e892cd7 100644 --- a/src/routes/followRouter.ts +++ b/src/routes/followRouter.ts @@ -7,4 +7,6 @@ const followController = new FollowController() // ENDPOINT CRIAR RECEITA -followRouter.post("/follow", followController.createFollow) \ No newline at end of file +followRouter.post("/follow", followController.createFollow) + +followRouter.get("/all-followers", followController.getAll) \ No newline at end of file From d8bc8aa6b61182bf69c601738c56a93269b126fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Thu, 16 Feb 2023 19:14:46 -0300 Subject: [PATCH 37/53] =?UTF-8?q?Adicionar=20feed=20de=20determinado=20usu?= =?UTF-8?q?=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- request.rest | 23 ++++++++++++---------- src/business/FeedBusiness.ts | 33 ++++++++++++++++++++++++++++++++ src/controller/FeedController.ts | 19 ++++++++++++++++++ src/data/FeedDatabase.ts | 20 +++++++++++++++++++ src/index.ts | 7 ++++++- src/routes/feedRouter.ts | 7 +++++++ 6 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 src/business/FeedBusiness.ts create mode 100644 src/controller/FeedController.ts create mode 100644 src/data/FeedDatabase.ts create mode 100644 src/routes/feedRouter.ts diff --git a/request.rest b/request.rest index 4420351..55b4b58 100644 --- a/request.rest +++ b/request.rest @@ -40,15 +40,13 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUt ### -// Recupera os dados de um seguidor com autorização. +// Retorna os dados de um seguidor com autorização. POST http://localhost:3003/follow Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjUxOTEyNCwiZXhwIjoxNjc2NTMzNTI0fQ.ipKOXoOoLRaCw5VN_-nDrpKNXek82D7emTD3CwQ9G4Q +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU4NDA5MCwiZXhwIjoxNjc2NTk4NDkwfQ.HX4UKBaHhfOsnEr16sAsnNE--2Od3ef_BpfZmSCIOI8 { - "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" - - + "followId":"72f25832-3249-44d3-bb14-5de2ec7da0d2" } @@ -64,11 +62,10 @@ Content-Type: application/json ### -// Recupera dados confidenciais de um usuário com a autorização concedida pelo token. +// Retorna dados confidenciais de um usuário com a autorização concedida pelo token. GET http://localhost:3003/user Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU3MDU2NywiZXhwIjoxNjc2NTg0OTY3fQ.X7xCSF2HirlWg6Z87ItONyTqClGvvuY-yZ1ZW0Sj9Xw - +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU4NDA5MCwiZXhwIjoxNjc2NTk4NDkwfQ.HX4UKBaHhfOsnEr16sAsnNE--2Od3ef_BpfZmSCIOI8 ### // Obtenha as receitas de um usuário específico utilizando o seu token de acesso. @@ -79,6 +76,12 @@ Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtN ### -// Recuperar a lista de relações entre quem segue e quem é seguido. +// Retornar a lista de relações entre quem segue e quem é seguido. GET http://localhost:3003/all-followers -Content-Type: application/json \ No newline at end of file +Content-Type: application/json + +### + +GET http://localhost:3003/my-feed +Content-Type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU4NDA5MCwiZXhwIjoxNjc2NTk4NDkwfQ.HX4UKBaHhfOsnEr16sAsnNE--2Od3ef_BpfZmSCIOI8 \ No newline at end of file diff --git a/src/business/FeedBusiness.ts b/src/business/FeedBusiness.ts new file mode 100644 index 0000000..0b4dcd0 --- /dev/null +++ b/src/business/FeedBusiness.ts @@ -0,0 +1,33 @@ +import { FeedDatabase } from "../data/FeedDatabase"; +import { FollowDatabase } from "../data/FollowDatabase"; +import { FollowDTO } from "../model/followDTO"; +import { TokenGenerator } from "../services/TokenGenerator" + +const feedDatabase = new FeedDatabase() +const tokenGenerator = new TokenGenerator(); +const followDatabase = new FollowDatabase() +export class FeedBusiness { + + getFeed = async(token:string) => { + try { + let followers = [] + const tokenData = tokenGenerator.tokenData(token) + + let allFollowers:any = await followDatabase.getAll() + allFollowers=JSON.parse(JSON.stringify(allFollowers)) + + for (let index = 0; index < allFollowers.length; index++) { + const element = allFollowers[index]; + if (element.user_id === tokenData.id) { + followers.push(element.follow_id) + } + + } + + return await feedDatabase.getFeed(followers) + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + + } + } +} \ No newline at end of file diff --git a/src/controller/FeedController.ts b/src/controller/FeedController.ts new file mode 100644 index 0000000..f27c243 --- /dev/null +++ b/src/controller/FeedController.ts @@ -0,0 +1,19 @@ +import { Request, Response } from "express"; +import { FeedBusiness } from "../business/FeedBusiness"; + + +const feedBusiness = new FeedBusiness() +export class FeedController { + getFeed = async(req:Request, res:Response) => { + try { + let token = req.headers.authorization as string + let result = await feedBusiness.getFeed(token) + + + res.status(200).send(result) + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + + } + } +} \ No newline at end of file diff --git a/src/data/FeedDatabase.ts b/src/data/FeedDatabase.ts new file mode 100644 index 0000000..5e6cae5 --- /dev/null +++ b/src/data/FeedDatabase.ts @@ -0,0 +1,20 @@ +import { RecipeDTO } from "../model/recipeDTO"; +import { BaseDatabase } from "./BaseDatabase"; + + +export class FeedDatabase extends BaseDatabase { + private static TABLE_NAME: string = "Cookenu_recipe" + + getFeed = async(id:string[]) => { + try { + let result:RecipeDTO[] = await FeedDatabase.connection + .select() + .whereIn('id_author', id) + .from(FeedDatabase.TABLE_NAME) + + return result + } catch (error:any) { + throw new Error(error.message || error.sqlMessage); + } + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4b0381b..3f7390a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import { app } from "./app"; +import { feedRouter } from "./routes/feedRouter"; import { followRouter } from "./routes/followRouter"; import { recipeRouter } from "./routes/recipeRouter"; import { userRouter } from "./routes/userRouter"; @@ -12,4 +13,8 @@ app.use("", userRouter) app.use("", recipeRouter) //ENDPOINT CRIAR SEGUIR -app.use("",followRouter) \ No newline at end of file +app.use("",followRouter) + +//ENDPOINT FEED + +app.use("", feedRouter) \ No newline at end of file diff --git a/src/routes/feedRouter.ts b/src/routes/feedRouter.ts new file mode 100644 index 0000000..2f0e587 --- /dev/null +++ b/src/routes/feedRouter.ts @@ -0,0 +1,7 @@ +import express from "express"; +import { FeedController } from "../controller/FeedController"; + +export const feedRouter = express.Router() +const feedController = new FeedController() + +feedRouter.get("/my-feed", feedController.getFeed) \ No newline at end of file From 23b94a1acf92ebd9ca8379bbe7ae5c8dd69ad03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Thu, 16 Feb 2023 20:27:32 -0300 Subject: [PATCH 38/53] fix: request --- request.rest | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/request.rest b/request.rest index 55b4b58..4579748 100644 --- a/request.rest +++ b/request.rest @@ -21,8 +21,8 @@ POST http://localhost:3003/login Content-Type: application/json { - "email": "lbsouza@gmail.com", - "password": "teste_cript" + "email": "bianca.paccola@gmail.com", + "password": "w5glbr6" } // Criar receitas ### @@ -35,7 +35,6 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUt { "title": "Brigadeiro", "description": "Misture uma colher de manteiga com uma caixa de leite condensado, quatro colheres de achocolatado e misture até desgrudar da panela" - } ### @@ -43,7 +42,7 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUt // Retorna os dados de um seguidor com autorização. POST http://localhost:3003/follow Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU4NDA5MCwiZXhwIjoxNjc2NTk4NDkwfQ.HX4UKBaHhfOsnEr16sAsnNE--2Od3ef_BpfZmSCIOI8 +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjU4OTkwMSwiZXhwIjoxNjc2NjA0MzAxfQ.ByBArZVRpdjDoO1Ul3vvpCwOP5um09NPwO5Adar0Cew { "followId":"72f25832-3249-44d3-bb14-5de2ec7da0d2" @@ -84,4 +83,4 @@ Content-Type: application/json GET http://localhost:3003/my-feed Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU4NDA5MCwiZXhwIjoxNjc2NTk4NDkwfQ.HX4UKBaHhfOsnEr16sAsnNE--2Od3ef_BpfZmSCIOI8 \ No newline at end of file +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjU4OTkwMSwiZXhwIjoxNjc2NjA0MzAxfQ.ByBArZVRpdjDoO1Ul3vvpCwOP5um09NPwO5Adar0Cew \ No newline at end of file From de41b512112d0e3512957e49f775a01c2a96ff9c Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 17 Feb 2023 12:50:34 -0300 Subject: [PATCH 39/53] =?UTF-8?q?identa=C3=A7=C3=A3o=20dos=20arquivos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/business/FeedBusiness.ts | 16 +++--- src/business/FollowBusiness.ts | 22 +++------ src/business/RecipeBusiness.ts | 8 +-- src/business/UserBusiness.ts | 79 ++++++++++++++---------------- src/controller/FeedController.ts | 9 ++-- src/controller/FollowController.ts | 17 +++---- src/controller/RecipeController.ts | 4 +- src/controller/UserController.ts | 41 ++++++++-------- src/data/FeedDatabase.ts | 14 +++--- src/data/FollowDatabase.ts | 20 ++++---- src/data/RecipeDatabase.ts | 22 ++++----- src/error/UserErrors.ts | 4 +- src/model/followDTO.ts | 4 +- src/model/recipeDTO.ts | 16 +++--- src/model/userDTO.ts | 6 +-- src/services/HashGenerator.ts | 14 +++--- src/services/TokenGenerator.ts | 8 +-- 17 files changed, 143 insertions(+), 161 deletions(-) diff --git a/src/business/FeedBusiness.ts b/src/business/FeedBusiness.ts index 0b4dcd0..155f661 100644 --- a/src/business/FeedBusiness.ts +++ b/src/business/FeedBusiness.ts @@ -8,26 +8,26 @@ const tokenGenerator = new TokenGenerator(); const followDatabase = new FollowDatabase() export class FeedBusiness { - getFeed = async(token:string) => { + getFeed = async (token: string) => { try { let followers = [] const tokenData = tokenGenerator.tokenData(token) - - let allFollowers:any = await followDatabase.getAll() - allFollowers=JSON.parse(JSON.stringify(allFollowers)) + + let allFollowers: any = await followDatabase.getAll() + allFollowers = JSON.parse(JSON.stringify(allFollowers)) for (let index = 0; index < allFollowers.length; index++) { - const element = allFollowers[index]; + const element = allFollowers[index]; if (element.user_id === tokenData.id) { followers.push(element.follow_id) } - + } return await feedDatabase.getFeed(followers) - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); - + } } } \ No newline at end of file diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts index e9422bf..979bb2d 100644 --- a/src/business/FollowBusiness.ts +++ b/src/business/FollowBusiness.ts @@ -16,7 +16,7 @@ export class FollowBusiness { if (!followId) { throw new CustomError(400, 'Fill in the fields "followId"'); } - if(followId === undefined){ + if (followId === undefined) { throw new CustomError(400, 'Fill in the fields "followId"'); } const idUserToken = tokenGenerator.tokenData(userId) @@ -26,15 +26,15 @@ export class FollowBusiness { const verificationUserId = await followDatabase.getById({ userId: idUserToken.id, followId: followId }) if (verificationUserId === undefined) { - + const insertFollow: FollowDTO = { id: idFollow, userId: idUserToken.id, followId: followId } - + await followDatabase.create(insertFollow) - }else{ + } else { throw new CustomError(400, "Follow already exists"); } @@ -44,23 +44,13 @@ export class FollowBusiness { } getAll = async () => { try { - let result:FollowDTO[] = await followDatabase.getAll() + let result: FollowDTO[] = await followDatabase.getAll() if (result.length <= 0) { throw new CustomError(404, "No followers yet"); } return result } catch (error) { - + } } } - - - - - // await followDatabase.create({ - // id: idFollow, - // userId: idUserToken.id, - // followId: followId - // }) - diff --git a/src/business/RecipeBusiness.ts b/src/business/RecipeBusiness.ts index bdbfe33..3ee3db3 100644 --- a/src/business/RecipeBusiness.ts +++ b/src/business/RecipeBusiness.ts @@ -36,16 +36,16 @@ export class RecipeBusiness { } } - getRecipes = async(token:string) => { + getRecipes = async (token: string) => { try { if (!token) { throw new Error("Missing authorization"); } - let id:AuthenticationData = tokenGenerator.tokenData(token) + let id: AuthenticationData = tokenGenerator.tokenData(token) return await recipeDatabase.getRecipes(id.id) - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); - + } } } \ No newline at end of file diff --git a/src/business/UserBusiness.ts b/src/business/UserBusiness.ts index 70f0acd..f4f1db9 100644 --- a/src/business/UserBusiness.ts +++ b/src/business/UserBusiness.ts @@ -17,29 +17,24 @@ export class UserBusiness { public signup = async ({ name, email, password }: InputUserDTO) => { try { if (!name || !email || !password) { - throw new CustomError(400,'Fill in the fields "name", "email" and "password"'); + throw new CustomError(400, 'Fill in the fields "name", "email" and "password"'); } - if(name.length < 3){ - throw new CustomError(400,'Very short name'); + if (name.length < 3) { + throw new CustomError(400, 'Very short name'); } - if(password.length <= 6){ - throw new CustomError(400,'Invalid password'); + if (password.length <= 6) { + throw new CustomError(400, 'Invalid password'); } if (!email.includes("@")) { throw new CustomError(400, "Invalid email address"); } - // const verificationEmail = await userDatabase.getAll(email) - // if(verificationEmail){ - // throw new CustomError(400, "Already have this email"); - // } - - const id = idGenerator.generateId() + const id = idGenerator.generateId() const passwordHash = await hashGenerator.generateHash(password) - const newUser:UserDTO = { + const newUser: UserDTO = { id, name, email, @@ -48,7 +43,7 @@ export class UserBusiness { await userDatabase.create(newUser) - const token = tokenGenerator.generateToken({id}) + const token = tokenGenerator.generateToken({ id }) return (token) @@ -58,12 +53,12 @@ export class UserBusiness { } - public async login ({email, password}:userLoginDTO ):Promise { + public async login({ email, password }: userLoginDTO): Promise { try { - if(!email || !password) { + if (!email || !password) { throw new UserIncompleteData() } - if (!email.includes("@" )) { + if (!email.includes("@")) { throw new UserInvalidEmail() } if (password.length <= 5) { @@ -72,7 +67,7 @@ export class UserBusiness { const user = await userDatabase.findByEmail(email) - if(!user) { + if (!user) { throw new UserNotFound() } @@ -82,63 +77,63 @@ export class UserBusiness { throw new UserIncorrectPassword() } - const token = await tokenGenerator.generateToken({id: user.id}) - + const token = await tokenGenerator.generateToken({ id: user.id }) + return token; - } catch (error:any) { + } catch (error: any) { throw new CustomError(400, error.message); } } - public async forgotPassword (email: string): Promise { + public async forgotPassword(email: string): Promise { try { - if(!email) { + if (!email) { throw new UserMissingEmail() } - if(!email.includes('@')) { + if (!email.includes('@')) { throw new UserInvalidEmail() } - const user = await userDatabase.findByEmail(email); - if (!user) { - throw new UserNotFound; - } - - const newPassword = passwordGenerate().toString() - const passwordHash = await hashGenerator.generateHash(newPassword) - await userDatabase.changePassword(user.id, passwordHash); - await sendNodemailer(email, newPassword) - - } catch (error:any) { + const user = await userDatabase.findByEmail(email); + if (!user) { + throw new UserNotFound; + } + + const newPassword = passwordGenerate().toString() + const passwordHash = await hashGenerator.generateHash(newPassword) + await userDatabase.changePassword(user.id, passwordHash); + await sendNodemailer(email, newPassword) + + } catch (error: any) { throw new CustomError(400, error.message); } } - getAll = async() => { + getAll = async () => { try { return await userDatabase.getAll() - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); } } - getById = async(token:string) => { + getById = async (token: string) => { try { if (!token) { throw new Error("Missing authorization"); } - let id:AuthenticationData = tokenGenerator.tokenData(token) - let userId:any = await userDatabase.checkIfExists(id.id) - userId=JSON.parse(JSON.stringify(userId)) - + let id: AuthenticationData = tokenGenerator.tokenData(token) + let userId: any = await userDatabase.checkIfExists(id.id) + userId = JSON.parse(JSON.stringify(userId)) + if (userId[0].id !== id.id) { throw new CustomError(400, "Token is invalid"); } return await userDatabase.getById(id.id) - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); } } diff --git a/src/controller/FeedController.ts b/src/controller/FeedController.ts index f27c243..e8d43a4 100644 --- a/src/controller/FeedController.ts +++ b/src/controller/FeedController.ts @@ -4,16 +4,15 @@ import { FeedBusiness } from "../business/FeedBusiness"; const feedBusiness = new FeedBusiness() export class FeedController { - getFeed = async(req:Request, res:Response) => { + getFeed = async (req: Request, res: Response) => { try { let token = req.headers.authorization as string let result = await feedBusiness.getFeed(token) - - + res.status(200).send(result) - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); - + } } } \ No newline at end of file diff --git a/src/controller/FollowController.ts b/src/controller/FollowController.ts index 430675b..ed35ed8 100644 --- a/src/controller/FollowController.ts +++ b/src/controller/FollowController.ts @@ -9,14 +9,13 @@ export class FollowController { try { const userId = req.headers.authorization as string; - const followId = req.body.followId + const followId = req.body.followId - const create:InputFollowDTO = { - userId:userId, - followId:followId + const create: InputFollowDTO = { + userId: userId, + followId: followId } - // console.log(create); - + await followBusiness.createFollow(create) res.status(201).send({ message: "Follow created successfully!" }) @@ -25,13 +24,13 @@ export class FollowController { res.status(400).send(error.message); } } - getAll = async(req:Request, res:Response) => { + getAll = async (req: Request, res: Response) => { try { let result = await followBusiness.getAll() res.status(200).send(result) - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); - + } } } \ No newline at end of file diff --git a/src/controller/RecipeController.ts b/src/controller/RecipeController.ts index a85d378..616cfb3 100644 --- a/src/controller/RecipeController.ts +++ b/src/controller/RecipeController.ts @@ -27,12 +27,12 @@ export class RecipeController { } } - getRecipes = async(req:Request, res:Response) => { + getRecipes = async (req: Request, res: Response) => { try { let token = req.headers.authorization as string let result = await recipeBusiness.getRecipes(token) res.status(200).send(result) - }catch(error:any){ + } catch (error: any) { throw new Error(error.message || error.sqlMessage); } } diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index 8a7961d..41a72cd 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -1,7 +1,6 @@ import { Request, Response } from "express"; import { UserBusiness } from "../business/UserBusiness"; -import { CustomError } from "../error/CustomError"; -import { InputUserDTO} from "../model/userDTO"; +import { InputUserDTO } from "../model/userDTO"; const userBusiness = new UserBusiness() @@ -10,7 +9,7 @@ export class UserController { public signup = async (req: Request, res: Response) => { try { const { name, email, password } = req.body - + const insert: InputUserDTO = { name, email, @@ -18,7 +17,7 @@ export class UserController { } const token = await userBusiness.signup(insert) - + res.status(201).send(`access_token: ${token} `); } catch (error: any) { @@ -26,44 +25,44 @@ export class UserController { } } - public async login (req: Request, res: Response): Promise { + public async login(req: Request, res: Response): Promise { try { - const {email, password} = req.body - const token = await userBusiness.login({email, password}) + const { email, password } = req.body + const token = await userBusiness.login({ email, password }) - res.status(200).send({token: token}) + res.status(200).send({ token: token }) - } catch (error:any) { - res.status(400).send(error.message); + } catch (error: any) { + res.status(400).send(error.message); } } - public async forgotPassword (req: Request, res: Response):Promise { + public async forgotPassword(req: Request, res: Response): Promise { try { const email: string = req.body.email await userBusiness.forgotPassword(email) - res.status(200).send({message: "A new password has been sent to the email."}) - } catch (error:any) { - res.status(400).send(error.message); + res.status(200).send({ message: "A new password has been sent to the email." }) + } catch (error: any) { + res.status(400).send(error.message); } } - getAll = async(req:Request, res:Response) => { + getAll = async (req: Request, res: Response) => { try { let result = await userBusiness.getAll() res.status(200).send(result) - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); - + } } - - getById = async(req:Request, res:Response) => { + + getById = async (req: Request, res: Response) => { try { - let token = req.headers.authorization as string + let token = req.headers.authorization as string let result = await userBusiness.getById(token) res.status(200).send(result) - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); } } diff --git a/src/data/FeedDatabase.ts b/src/data/FeedDatabase.ts index 5e6cae5..9aaffc9 100644 --- a/src/data/FeedDatabase.ts +++ b/src/data/FeedDatabase.ts @@ -5,16 +5,16 @@ import { BaseDatabase } from "./BaseDatabase"; export class FeedDatabase extends BaseDatabase { private static TABLE_NAME: string = "Cookenu_recipe" - getFeed = async(id:string[]) => { + getFeed = async (id: string[]) => { try { - let result:RecipeDTO[] = await FeedDatabase.connection - .select() - .whereIn('id_author', id) - .from(FeedDatabase.TABLE_NAME) + let result: RecipeDTO[] = await FeedDatabase.connection + .select() + .whereIn('id_author', id) + .from(FeedDatabase.TABLE_NAME) return result - } catch (error:any) { - throw new Error(error.message || error.sqlMessage); + } catch (error: any) { + throw new Error(error.message || error.sqlMessage); } } } \ No newline at end of file diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index a4757aa..1ce3294 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -27,26 +27,26 @@ export class FollowDatabase extends BaseDatabase { .select("*") .from(FollowDatabase.TABLE_NAME) .where({ - user_id: userId, - follow_id:followId + user_id: userId, + follow_id: followId }) - - console.log(result[0]); + + console.log(result[0]); return (result[0]) } catch (error: any) { throw new CustomError(400, error.message || error.sqlMessage); } } - getAll = async():Promise => { + getAll = async (): Promise => { try { - let result:FollowDTO[] = await FollowDatabase.connection - .select() - .from(FollowDatabase.TABLE_NAME) + let result: FollowDTO[] = await FollowDatabase.connection + .select() + .from(FollowDatabase.TABLE_NAME) return result - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); - + } } } \ No newline at end of file diff --git a/src/data/RecipeDatabase.ts b/src/data/RecipeDatabase.ts index c37e6bf..2ad3009 100644 --- a/src/data/RecipeDatabase.ts +++ b/src/data/RecipeDatabase.ts @@ -2,34 +2,34 @@ import { CustomError } from "../error/CustomError"; import { RecipeDTO } from "../model/recipeDTO"; import { BaseDatabase } from "./BaseDatabase"; -export class RecipeDatabase extends BaseDatabase{ +export class RecipeDatabase extends BaseDatabase { private static TABLE_NAME: string = "Cookenu_recipe" - create=async({id,title,description,idAuthor}:RecipeDTO)=>{ - try{ + create = async ({ id, title, description, idAuthor }: RecipeDTO) => { + try { await RecipeDatabase.connection.insert({ id, title, description, - id_author:idAuthor + id_author: idAuthor }).into(RecipeDatabase.TABLE_NAME) - }catch(error:any){ + } catch (error: any) { throw new CustomError(400, error.message || error.sqlMessage); } } - getRecipes = async(id:string) => { + getRecipes = async (id: string) => { try { let result = await RecipeDatabase.connection - .select() - .where('id_author', id) - .from(RecipeDatabase.TABLE_NAME) + .select() + .where('id_author', id) + .from(RecipeDatabase.TABLE_NAME) return result - } catch (error:any) { + } catch (error: any) { throw new Error(error.message || error.sqlMessage); - + } } } \ No newline at end of file diff --git a/src/error/UserErrors.ts b/src/error/UserErrors.ts index f793dec..7fa04a1 100644 --- a/src/error/UserErrors.ts +++ b/src/error/UserErrors.ts @@ -1,10 +1,10 @@ import { CustomError } from "./CustomError"; export class UserIncompleteData extends CustomError { - constructor () { + constructor() { super(422, 'Fill in the fields: "email" and "password" ') } -} +} export class UserMissingEmail extends CustomError { constructor() { diff --git a/src/model/followDTO.ts b/src/model/followDTO.ts index 3be0873..c0143ad 100644 --- a/src/model/followDTO.ts +++ b/src/model/followDTO.ts @@ -1,10 +1,10 @@ -export interface FollowDTO{ +export interface FollowDTO { id: string; userId: string; followId: string; } -export interface InputFollowDTO{ +export interface InputFollowDTO { userId: string; followId: string; } \ No newline at end of file diff --git a/src/model/recipeDTO.ts b/src/model/recipeDTO.ts index 40119fe..708f919 100644 --- a/src/model/recipeDTO.ts +++ b/src/model/recipeDTO.ts @@ -1,12 +1,12 @@ -export interface RecipeDTO{ - id:string, - title:string, - description:string, - idAuthor:string +export interface RecipeDTO { + id: string, + title: string, + description: string, + idAuthor: string } -export interface InputRecipeDTO{ - title:string, - description:string, +export interface InputRecipeDTO { + title: string, + description: string, idAuthor: string } diff --git a/src/model/userDTO.ts b/src/model/userDTO.ts index c72f740..e3b0417 100644 --- a/src/model/userDTO.ts +++ b/src/model/userDTO.ts @@ -1,11 +1,11 @@ -export interface UserDTO{ +export interface UserDTO { id: string, name: string, email: string, password: string } -export interface InputUserDTO{ +export interface InputUserDTO { name: string, email: string, password: string @@ -19,4 +19,4 @@ export interface userLoginDTO { export interface AuthenticationData { id: string, - } \ No newline at end of file +} \ No newline at end of file diff --git a/src/services/HashGenerator.ts b/src/services/HashGenerator.ts index 4f27734..6e955ff 100644 --- a/src/services/HashGenerator.ts +++ b/src/services/HashGenerator.ts @@ -1,15 +1,15 @@ import * as bcrypt from "bcryptjs"; -export class HashGenerator{ - generateHash = async(plainTest: string):Promise =>{ - const cost:number = Number(process.env.BCRYPT_COST) - const salt:string = await bcrypt.genSalt(cost) - const hash:string = await bcrypt.hash(plainTest, salt) +export class HashGenerator { + generateHash = async (plainTest: string): Promise => { + const cost: number = Number(process.env.BCRYPT_COST) + const salt: string = await bcrypt.genSalt(cost) + const hash: string = await bcrypt.hash(plainTest, salt) - return(hash) + return (hash) } - compareHash = async(plainTest: string, hashTest: string):Promise=>{ + compareHash = async (plainTest: string, hashTest: string): Promise => { const result = await bcrypt.compare(plainTest, hashTest) return (result) diff --git a/src/services/TokenGenerator.ts b/src/services/TokenGenerator.ts index 9b58074..e407233 100644 --- a/src/services/TokenGenerator.ts +++ b/src/services/TokenGenerator.ts @@ -3,13 +3,13 @@ import { AuthenticationData } from '../model/userDTO' export class TokenGenerator { - public generateToken = ({id}:AuthenticationData) => { + public generateToken = ({ id }: AuthenticationData) => { const token = jwt.sign( { id }, process.env.JWT_KEY as string, { expiresIn: "4h" } - ) - return token + ) + return token } public tokenData = (token: string): AuthenticationData => { @@ -18,6 +18,6 @@ export class TokenGenerator { process.env.JWT_KEY as string ) as jwt.JwtPayload - return {id: payload.id as string} + return { id: payload.id as string } } } \ No newline at end of file From 5d6ef5ff322ce56cc3f138d203bf958c21454464 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 17 Feb 2023 13:10:52 -0300 Subject: [PATCH 40/53] inicio descurtir --- README.md | 7 ++++--- request.rest | 26 +++++++++++++------------- src/data/FollowDatabase.ts | 10 ++++++++++ 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 69f486b..52baa11 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,15 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div

💻 Funcionalidades:

✅ Cadastrar pessoas usuária;
✅ Login;
-⬛ Informações do próprio perfil;
+✅ Informações do próprio perfil;
✅ Criar receitas;
✅ Seguir usuários;
- -⬛ Feed
+✅ Feed (vizualiza somente receitas de amigos);
⬛ Alimentação
✅ Esqueceu senha;
+Extra para facilitar testes: +✅ Buscar todos usuários (Ps: precisa saber a senha para logar com ele pois estão criptografadas.);
--- diff --git a/request.rest b/request.rest index 4579748..5f8eaa2 100644 --- a/request.rest +++ b/request.rest @@ -4,9 +4,9 @@ Content-Type: application/json { - "name":"Bianca Paccola", - "email":"bianca.paccola@gmail.com", - "password":"123abc#" + "name":"Lorenzo Martins", + "email":"carolinemartins1109@gmail.com", + "password":"1234567" } ### @@ -21,8 +21,8 @@ POST http://localhost:3003/login Content-Type: application/json { - "email": "bianca.paccola@gmail.com", - "password": "w5glbr6" + "email": "carolinemartins1109@gmail.com", + "password": "1234567" } // Criar receitas ### @@ -30,11 +30,11 @@ Content-Type: application/json // Criar receita POST http://localhost:3003/recipe Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMzU2MywiZXhwIjoxNjc2NTI3OTYzfQ.57tIymx6FtxvsuuheQHmfh4mK-WDHI1cUU2sfR0_2gM +Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk { - "title": "Brigadeiro", - "description": "Misture uma colher de manteiga com uma caixa de leite condensado, quatro colheres de achocolatado e misture até desgrudar da panela" + "title": "Bolo de cenoura ", + "description": "Em um liquidificador, adicione a cenoura, os ovos e o óleo, depois misture." } ### @@ -42,10 +42,10 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUt // Retorna os dados de um seguidor com autorização. POST http://localhost:3003/follow Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjU4OTkwMSwiZXhwIjoxNjc2NjA0MzAxfQ.ByBArZVRpdjDoO1Ul3vvpCwOP5um09NPwO5Adar0Cew +Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk { - "followId":"72f25832-3249-44d3-bb14-5de2ec7da0d2" + "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" } @@ -64,13 +64,13 @@ Content-Type: application/json // Retorna dados confidenciais de um usuário com a autorização concedida pelo token. GET http://localhost:3003/user Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjA0MmVlMGIwLTM1NDEtNDlmYy05MTg2LTQ4M2UxMmRjNGM2NyIsImlhdCI6MTY3NjU4NDA5MCwiZXhwIjoxNjc2NTk4NDkwfQ.HX4UKBaHhfOsnEr16sAsnNE--2Od3ef_BpfZmSCIOI8 +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk ### // Obtenha as receitas de um usuário específico utilizando o seu token de acesso. GET http://localhost:3003/all-recipes Content-Type: application/json -Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjUxMzU2MywiZXhwIjoxNjc2NTI3OTYzfQ.57tIymx6FtxvsuuheQHmfh4mK-WDHI1cUU2sfR0_2gM +Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk ### @@ -83,4 +83,4 @@ Content-Type: application/json GET http://localhost:3003/my-feed Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5ZDQyZTcwLWQ5NWUtNDdhYy1hOGY4LTFmMTBlYWUyMmY4ZiIsImlhdCI6MTY3NjU4OTkwMSwiZXhwIjoxNjc2NjA0MzAxfQ.ByBArZVRpdjDoO1Ul3vvpCwOP5um09NPwO5Adar0Cew \ No newline at end of file +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk \ No newline at end of file diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index 1ce3294..e202947 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -49,4 +49,14 @@ export class FollowDatabase extends BaseDatabase { } } + + delete = async()=>{ + try{ + + + + }catch(error:any){ + throw new CustomError(400, error.message || error.sqlMessage); + } + } } \ No newline at end of file From 9dc5d825e324bb021813472e522c1437b66ad1f5 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 17 Feb 2023 13:24:56 -0300 Subject: [PATCH 41/53] inicio descurtir --- src/data/FollowDatabase.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index e202947..5a9afaf 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -50,12 +50,15 @@ export class FollowDatabase extends BaseDatabase { } } - delete = async()=>{ - try{ - + delete = async ({ userId, followId }: InputFollowDTO) => { + try { + await FollowDatabase.connection() + .delete() + .from(FollowDatabase.TABLE_NAME) + .where({ user_id: userId, follow_id: followId }) - }catch(error:any){ + } catch (error: any) { throw new CustomError(400, error.message || error.sqlMessage); } } From c60325b4c739d954dc5941a885a870da329093f9 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 17 Feb 2023 14:46:30 -0300 Subject: [PATCH 42/53] deletar curtida --- request.rest | 20 +++++++++++++++----- src/business/FollowBusiness.ts | 28 +++++++++++++++++++++++++++- src/controller/FollowController.ts | 16 +++++++++++++++- src/data/FollowDatabase.ts | 23 ++++++++++++++++++++--- src/index.ts | 2 ++ src/routes/followRouter.ts | 4 +++- 6 files changed, 82 insertions(+), 11 deletions(-) diff --git a/request.rest b/request.rest index 5f8eaa2..04f865c 100644 --- a/request.rest +++ b/request.rest @@ -22,7 +22,7 @@ Content-Type: application/json { "email": "carolinemartins1109@gmail.com", - "password": "1234567" + "password": "fkqzpcb" } // Criar receitas ### @@ -39,10 +39,10 @@ Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtN ### -// Retorna os dados de um seguidor com autorização. +// curtir POST http://localhost:3003/follow Content-Type: application/json -Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk +Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY1MzI3NywiZXhwIjoxNjc2NjY3Njc3fQ.tFh6P9lgS00R0_k6ybqRfC_UYXzBff8Bi9AiAumvyeQ { "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" @@ -55,7 +55,7 @@ PUT http://localhost:3003/forgot-password Content-Type: application/json { - "email": "bianca.paccola@gmail.com" + "email": "carolinemartins1109@gmail.com" } @@ -83,4 +83,14 @@ Content-Type: application/json GET http://localhost:3003/my-feed Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk \ No newline at end of file +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk + +### +// DESCURTIR USUARIO +DELETE http://localhost:3003/user/unfollow +Content-Type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY1MzI3NywiZXhwIjoxNjc2NjY3Njc3fQ.tFh6P9lgS00R0_k6ybqRfC_UYXzBff8Bi9AiAumvyeQ + +{ + "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" +} \ No newline at end of file diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts index 979bb2d..dcfbf8b 100644 --- a/src/business/FollowBusiness.ts +++ b/src/business/FollowBusiness.ts @@ -49,8 +49,34 @@ export class FollowBusiness { throw new CustomError(404, "No followers yet"); } return result - } catch (error) { + } catch (error:any) { + throw new CustomError(400, error.message); + } + } + + deleteFollow=async({userId,followId}:InputFollowDTO)=>{ + try{ + + if (!userId ) { + throw new CustomError(400, "invalid! userId"); + } + if (!followId) { + throw new CustomError(400, "invalid! followId"); + } + const idUserToken = tokenGenerator.tokenData(userId) + + const verificationUserId = await followDatabase.getFollow({userId:idUserToken.id, followId}) +// console.log(verificationUserId); + + if (verificationUserId === undefined) { + throw new CustomError(400, "Follow not exists"); + } else { + await followDatabase.delete({userId:idUserToken.id, followId}) + } + + }catch(error:any){ + throw new CustomError(400, error.message); } } } diff --git a/src/controller/FollowController.ts b/src/controller/FollowController.ts index ed35ed8..e2ac254 100644 --- a/src/controller/FollowController.ts +++ b/src/controller/FollowController.ts @@ -29,8 +29,22 @@ export class FollowController { let result = await followBusiness.getAll() res.status(200).send(result) } catch (error: any) { - throw new Error(error.message || error.sqlMessage); + res.status(400).send(error.message); + + } + } + deleteFollow = async (req: Request, res: Response) => { + try { + const userId = req.headers.authorization as string; + const followId = req.body.followId + + await followBusiness.deleteFollow({userId,followId}) + + res.status(200).send("Unfollowed successfully!") + + } catch (error: any) { + res.status(400).send(error.message); } } } \ No newline at end of file diff --git a/src/data/FollowDatabase.ts b/src/data/FollowDatabase.ts index 5a9afaf..672b657 100644 --- a/src/data/FollowDatabase.ts +++ b/src/data/FollowDatabase.ts @@ -31,7 +31,6 @@ export class FollowDatabase extends BaseDatabase { follow_id: followId }) - console.log(result[0]); return (result[0]) } catch (error: any) { @@ -50,9 +49,27 @@ export class FollowDatabase extends BaseDatabase { } } - delete = async ({ userId, followId }: InputFollowDTO) => { + getFollow =async({userId, followId}:InputFollowDTO)=>{ + try{ + + const result = await FollowDatabase.connection() + .select("*") + .from(FollowDatabase.TABLE_NAME) + .where({ + user_id: userId, + follow_id: followId + }) + + return (result[0]) + + }catch(error: any){ + throw new CustomError(400, error.message || error.sqlMessage); + } + } + + delete = async ({userId, followId}:InputFollowDTO) => { try { - await FollowDatabase.connection() + const result= await FollowDatabase.connection() .delete() .from(FollowDatabase.TABLE_NAME) .where({ user_id: userId, follow_id: followId }) diff --git a/src/index.ts b/src/index.ts index 3f7390a..ef7b2ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,6 +15,8 @@ app.use("", recipeRouter) //ENDPOINT CRIAR SEGUIR app.use("",followRouter) +app.use("/user", followRouter) + //ENDPOINT FEED app.use("", feedRouter) \ No newline at end of file diff --git a/src/routes/followRouter.ts b/src/routes/followRouter.ts index e892cd7..2c9bb99 100644 --- a/src/routes/followRouter.ts +++ b/src/routes/followRouter.ts @@ -9,4 +9,6 @@ const followController = new FollowController() // ENDPOINT CRIAR RECEITA followRouter.post("/follow", followController.createFollow) -followRouter.get("/all-followers", followController.getAll) \ No newline at end of file +followRouter.get("/all-followers", followController.getAll) + +followRouter.delete("/unfollow", followController.deleteFollow) \ No newline at end of file From cc2d418f58ae95deed235527a72e16ed82b2b53e Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 17 Feb 2023 14:47:30 -0300 Subject: [PATCH 43/53] deletar curtida readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 52baa11..dd8802e 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,8 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div ✅ Informações do próprio perfil;
✅ Criar receitas;
✅ Seguir usuários;
+✅ Deixar de seguir usuários;
✅ Feed (vizualiza somente receitas de amigos);
- -⬛ Alimentação
✅ Esqueceu senha;
Extra para facilitar testes: ✅ Buscar todos usuários (Ps: precisa saber a senha para logar com ele pois estão criptografadas.);
From a631178351a8138ec4a5c86a6c731cc560ac7bec Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Sat, 18 Feb 2023 17:19:53 -0300 Subject: [PATCH 44/53] readme --- README.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dd8802e..5b1d0a1 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,22 @@ Extra para facilitar testes: ---

🛠 Ferramentas:

-- Typescript;
-- Node.js;
-- MySQL;
-- Express;
-- Uuid;
-- JsonWebToken;
-- Knex;
-- Bcrypt;
+- Typescript
+- Node.js
+- MySQL
+- Express
+- Uuid
+- JsonWebToken
+- Knex
+- Bcrypt
+ +--- + +

✒️ Pessoas Desenvolvedoras do Projeto

+ +| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) | +| :---: | :---: | :---: | +
--- From 2ea06a94a0687b1a61d3ce64a61b352fd26abeae Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Sat, 18 Feb 2023 17:22:15 -0300 Subject: [PATCH 45/53] readme --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 5b1d0a1..4965f5e 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,19 @@ Extra para facilitar testes: --- +

🐱‍🚀 Documentação Postam:

+ +[---Documentação---]() + + +--- + +

🔗 Link Render:

+ +[---LINK AQUI---]() + +--- +

⚙️ Instruções para rodar o projeto:

> O arquivo *requests.rest*, presente na pasta raiz do projeto, contém todos os endpoints com url do deploy disponível online (Render) From 0bcec25487a73d94c972793416186d98a4528289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Wed, 22 Feb 2023 15:54:05 -0300 Subject: [PATCH 46/53] fix: retornar mensagem caso o feed esteja vazio --- request.rest | 7 ++++--- src/business/FeedBusiness.ts | 8 +++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/request.rest b/request.rest index 04f865c..aa29076 100644 --- a/request.rest +++ b/request.rest @@ -42,7 +42,7 @@ Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtN // curtir POST http://localhost:3003/follow Content-Type: application/json -Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY1MzI3NywiZXhwIjoxNjc2NjY3Njc3fQ.tFh6P9lgS00R0_k6ybqRfC_UYXzBff8Bi9AiAumvyeQ +Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5MTA5NSwiZXhwIjoxNjc3MTA1NDk1fQ.KwP6Fy5ly2KOssygS7Chs6_UrZC0JTsw5XTlhcq_jSw { "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" @@ -81,15 +81,16 @@ Content-Type: application/json ### +// Retorna uma lista contendo as receitas das pessoas que o usuário segue. GET http://localhost:3003/my-feed Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5MTA5NSwiZXhwIjoxNjc3MTA1NDk1fQ.KwP6Fy5ly2KOssygS7Chs6_UrZC0JTsw5XTlhcq_jSw ### // DESCURTIR USUARIO DELETE http://localhost:3003/user/unfollow Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY1MzI3NywiZXhwIjoxNjc2NjY3Njc3fQ.tFh6P9lgS00R0_k6ybqRfC_UYXzBff8Bi9AiAumvyeQ +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5MTA5NSwiZXhwIjoxNjc3MTA1NDk1fQ.KwP6Fy5ly2KOssygS7Chs6_UrZC0JTsw5XTlhcq_jSw { "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" diff --git a/src/business/FeedBusiness.ts b/src/business/FeedBusiness.ts index 155f661..d0531af 100644 --- a/src/business/FeedBusiness.ts +++ b/src/business/FeedBusiness.ts @@ -24,7 +24,13 @@ export class FeedBusiness { } - return await feedDatabase.getFeed(followers) + let result = await feedDatabase.getFeed(followers) + if (result.length <= 0) { + return ("Feed is empty."); + } else { + return ({recipes: result}) + } + } catch (error: any) { throw new Error(error.message || error.sqlMessage); From 2351be1fa84e4885d9ab625562fc4cc685748587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Barros?= <69652623+FluffyThread@users.noreply.github.com> Date: Thu, 23 Feb 2023 12:32:37 -0300 Subject: [PATCH 47/53] =?UTF-8?q?fix:criar=20entidades=20e=20ajuste=20de?= =?UTF-8?q?=20gram=C3=A1tica=20nas=20respostas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- request.rest | 30 +++++++++++++++--------------- src/business/FollowBusiness.ts | 6 +++--- src/controller/FollowController.ts | 2 +- src/controller/UserController.ts | 2 +- src/index.ts | 10 +++++----- src/routes/recipeRouter.ts | 2 +- src/routes/userRouter.ts | 2 +- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/request.rest b/request.rest index aa29076..9376faf 100644 --- a/request.rest +++ b/request.rest @@ -1,5 +1,5 @@ // Signup - Criar cadastro de usuário -POST http://localhost:3003/signup +POST http://localhost:3003/user/signup Content-Type: application/json { @@ -11,13 +11,13 @@ Content-Type: application/json ### // Retorna todos os usuários cadastrados no banco de dados -GET http://localhost:3003/all +GET http://localhost:3003/user/all ### // Login -POST http://localhost:3003/login +POST http://localhost:3003/user/login Content-Type: application/json { @@ -28,7 +28,7 @@ Content-Type: application/json ### // Criar receita -POST http://localhost:3003/recipe +POST http://localhost:3003/recipe/create-recipe Content-Type: application/json Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk @@ -40,9 +40,9 @@ Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtN ### // curtir -POST http://localhost:3003/follow +POST http://localhost:3003/followers/follow Content-Type: application/json -Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5MTA5NSwiZXhwIjoxNjc3MTA1NDk1fQ.KwP6Fy5ly2KOssygS7Chs6_UrZC0JTsw5XTlhcq_jSw +Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5NjE4NSwiZXhwIjoxNjc3MTEwNTg1fQ.Ttlsrcal_0oqAlY1sf_IQszs-PcRKLn3IIyDbWXYvYM { "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" @@ -51,7 +51,7 @@ Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtN ### // Esqueci a senha -PUT http://localhost:3003/forgot-password +PUT http://localhost:3003/user/forgot-password Content-Type: application/json { @@ -62,13 +62,13 @@ Content-Type: application/json ### // Retorna dados confidenciais de um usuário com a autorização concedida pelo token. -GET http://localhost:3003/user +GET http://localhost:3003/user/get-user Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5MjM1MSwiZXhwIjoxNjc3MTA2NzUxfQ.lwVlwl9D_YhlFNMtQKeZUtd_hCecGHw2fMLTJeMsl5c ### // Obtenha as receitas de um usuário específico utilizando o seu token de acesso. -GET http://localhost:3003/all-recipes +GET http://localhost:3003/recipe/all-recipes Content-Type: application/json Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NjY0OTM3OSwiZXhwIjoxNjc2NjYzNzc5fQ.Ju-5GH29AnTIyg5R33I6xGFBRpCqOwIXN0NkCoEJqqk @@ -76,21 +76,21 @@ Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtN ### // Retornar a lista de relações entre quem segue e quem é seguido. -GET http://localhost:3003/all-followers +GET http://localhost:3003/followers/all-followers Content-Type: application/json ### // Retorna uma lista contendo as receitas das pessoas que o usuário segue. -GET http://localhost:3003/my-feed +GET http://localhost:3003/feed/my-feed Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5MTA5NSwiZXhwIjoxNjc3MTA1NDk1fQ.KwP6Fy5ly2KOssygS7Chs6_UrZC0JTsw5XTlhcq_jSw +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5NjE4NSwiZXhwIjoxNjc3MTEwNTg1fQ.Ttlsrcal_0oqAlY1sf_IQszs-PcRKLn3IIyDbWXYvYM ### // DESCURTIR USUARIO -DELETE http://localhost:3003/user/unfollow +DELETE http://localhost:3003/followers/unfollow Content-Type: application/json -Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzA5MTA5NSwiZXhwIjoxNjc3MTA1NDk1fQ.KwP6Fy5ly2KOssygS7Chs6_UrZC0JTsw5XTlhcq_jSw +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImRjZGM4MzcwLWJmNTEtNGRlYy04ODYzLTY0MGIxYmU0Zjc5MSIsImlhdCI6MTY3NzE2NTE4NywiZXhwIjoxNjc3MTc5NTg3fQ.usDKrf9KkkvN_kgDF0mlhJ7PUlp7vXK_CxNn-edbIqg { "followId":"99d42e70-d95e-47ac-a8f8-1f10eae22f8f" diff --git a/src/business/FollowBusiness.ts b/src/business/FollowBusiness.ts index dcfbf8b..27dad5f 100644 --- a/src/business/FollowBusiness.ts +++ b/src/business/FollowBusiness.ts @@ -35,7 +35,7 @@ export class FollowBusiness { await followDatabase.create(insertFollow) } else { - throw new CustomError(400, "Follow already exists"); + throw new CustomError(400, "User is already following this person."); } } catch (error: any) { @@ -67,10 +67,10 @@ export class FollowBusiness { const idUserToken = tokenGenerator.tokenData(userId) const verificationUserId = await followDatabase.getFollow({userId:idUserToken.id, followId}) -// console.log(verificationUserId); + if (verificationUserId === undefined) { - throw new CustomError(400, "Follow not exists"); + throw new CustomError(400, "Is not possible to delete a relation that do not exists."); } else { await followDatabase.delete({userId:idUserToken.id, followId}) } diff --git a/src/controller/FollowController.ts b/src/controller/FollowController.ts index e2ac254..aa2c601 100644 --- a/src/controller/FollowController.ts +++ b/src/controller/FollowController.ts @@ -18,7 +18,7 @@ export class FollowController { await followBusiness.createFollow(create) - res.status(201).send({ message: "Follow created successfully!" }) + res.status(201).send({ message: "The user is now a follower!" }) } catch (error: any) { res.status(400).send(error.message); diff --git a/src/controller/UserController.ts b/src/controller/UserController.ts index 41a72cd..b1027bb 100644 --- a/src/controller/UserController.ts +++ b/src/controller/UserController.ts @@ -18,7 +18,7 @@ export class UserController { const token = await userBusiness.signup(insert) - res.status(201).send(`access_token: ${token} `); + res.status(201).send(`"access_token": "${token}" `); } catch (error: any) { res.status(400).send(error.message); diff --git a/src/index.ts b/src/index.ts index ef7b2ec..117d9c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,17 +6,17 @@ import { userRouter } from "./routes/userRouter"; // ENDPOINT CRIAR USUARIO -app.use("", userRouter) +app.use("/user", userRouter) // ENDPOINT CRIAR RECEITA -app.use("", recipeRouter) +app.use("/recipe", recipeRouter) //ENDPOINT CRIAR SEGUIR -app.use("",followRouter) +app.use("/followers",followRouter) + -app.use("/user", followRouter) //ENDPOINT FEED -app.use("", feedRouter) \ No newline at end of file +app.use("/feed", feedRouter) \ No newline at end of file diff --git a/src/routes/recipeRouter.ts b/src/routes/recipeRouter.ts index e6a0e90..652ef82 100644 --- a/src/routes/recipeRouter.ts +++ b/src/routes/recipeRouter.ts @@ -6,6 +6,6 @@ const recipeController = new RecipeController() // ENDPOINT CRIAR RECEITA -recipeRouter.post("/recipe", recipeController.createRecipe) +recipeRouter.post("/create-recipe", recipeController.createRecipe) recipeRouter.get("/all-recipes", recipeController.getRecipes) \ No newline at end of file diff --git a/src/routes/userRouter.ts b/src/routes/userRouter.ts index 74b5fc5..dbe2dd1 100644 --- a/src/routes/userRouter.ts +++ b/src/routes/userRouter.ts @@ -17,4 +17,4 @@ userRouter.put("/forgot-password", userController.forgotPassword) //ENDPOINT PARA RETORNAR TODOS OS USUÁRIOS userRouter.get("/all", userController.getAll) -userRouter.get("/user", userController.getById) \ No newline at end of file +userRouter.get("/get-user", userController.getById) \ No newline at end of file From cf0b556e5233956069a4ca9e93b4e585d2283f3d Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 24 Feb 2023 18:43:27 -0300 Subject: [PATCH 48/53] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4965f5e..313c70c 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Extra para facilitar testes:

🐱‍🚀 Documentação Postam:

-[---Documentação---]() +[---Documentação---](https://documenter.getpostman.com/view/22367197/2s93CLtZrF) --- From c893b03761e4c7607d9d307055fa3db37188498d Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 24 Feb 2023 18:58:34 -0300 Subject: [PATCH 49/53] reamde --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 313c70c..580d20e 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Extra para facilitar testes:

🔗 Link Render:

-[---LINK AQUI---]() +[---LINK AQUI---](https://barros-cookenu-grupo9.onrender.com) --- From c46067139f0d3ae6efbbac3ca48bd47648ad3b32 Mon Sep 17 00:00:00 2001 From: MartinsCaroline <102299433+CarolineMartins09@users.noreply.github.com> Date: Fri, 24 Feb 2023 19:01:04 -0300 Subject: [PATCH 50/53] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 580d20e..19c5dbf 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Esse produto nada mais é do que uma rede social, na qual os usuários podem div ✅ Deixar de seguir usuários;
✅ Feed (vizualiza somente receitas de amigos);
✅ Esqueceu senha;
-Extra para facilitar testes: +Extra para facilitar testes:
✅ Buscar todos usuários (Ps: precisa saber a senha para logar com ele pois estão criptografadas.);
@@ -32,7 +32,7 @@ Extra para facilitar testes:

✒️ Pessoas Desenvolvedoras do Projeto

-| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) | +| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) | | :---: | :---: | :---: |
From 44c4fd240703cb0c68667ddb2835f155282a8793 Mon Sep 17 00:00:00 2001 From: MartinsCaroline <102299433+CarolineMartins09@users.noreply.github.com> Date: Fri, 24 Feb 2023 19:03:02 -0300 Subject: [PATCH 51/53] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 19c5dbf..a36a037 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Extra para facilitar testes:

✒️ Pessoas Desenvolvedoras do Projeto

-| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) | +| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) https://avatars.githubusercontent.com/u/69652623?v=4 | :---: | :---: | :---: |
From 856321ea38233e02beb6c80ccc38659e363199ff Mon Sep 17 00:00:00 2001 From: MartinsCaroline <102299433+CarolineMartins09@users.noreply.github.com> Date: Fri, 24 Feb 2023 19:04:34 -0300 Subject: [PATCH 52/53] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a36a037..56f310c 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,7 @@ Extra para facilitar testes:

✒️ Pessoas Desenvolvedoras do Projeto

-| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) https://avatars.githubusercontent.com/u/69652623?v=4 -| :---: | :---: | :---: | +| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread)
--- From 696ba26e71926185e6680d1270c9455eca626ef5 Mon Sep 17 00:00:00 2001 From: carolinemartins Date: Fri, 24 Feb 2023 19:06:35 -0300 Subject: [PATCH 53/53] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 580d20e..7b6a768 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Extra para facilitar testes:

✒️ Pessoas Desenvolvedoras do Projeto

-| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) | +| [
Bianca Paccola](https://github.com/BiancaPaccola) | [
Caroline Martins](https://github.com/CarolineMartins09) | [
Lê Barros](https://github.com/FluffyThread) | | :---: | :---: | :---: |