Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5322aefcdb | |||
| 53bd76c78d | |||
| bf22d644b4 | |||
| b952de694b | |||
| 604f09893a | |||
| 1e4e7f2d65 | |||
| a8794eee14 | |||
| 71b65ad5a5 | |||
| 672a5e82fd | |||
| 376e75c5ee | |||
| 61ffbc195b | |||
| 28aba967b1 | |||
| 41be2b547e | |||
| 76eb6523e7 | |||
| 896631ef5e | |||
| cc39055581 | |||
| e52a90b725 | |||
| 10c415cdd4 | |||
| 39c37faafc | |||
| 63f3f7f443 | |||
| 81dfbe4910 | |||
| f8df1e2504 | |||
| f419ff1703 | |||
| 70882772c8 | |||
| b814bdd53e | |||
| 2307169453 | |||
| 9fcb69acd5 | |||
| 867f055de9 | |||
| ebbf6a53f5 | |||
| f569081092 | |||
| 6f8cff7c2d | |||
| 3c67e8e61c | |||
| 9c2d104868 | |||
| 82394b05a2 | |||
| 3be07318ea | |||
| 97fd5b27eb | |||
| 208715a6e1 | |||
| 3e3925c063 | |||
| 90ddb52370 | |||
| 8738d65382 | |||
| fb04abfb06 | |||
| a210ac3d66 | |||
| a7175979c3 | |||
| 788c6f2a0a | |||
| dd6ff0d87c | |||
| 87fae370be | |||
| e72bbbc8fe | |||
| 2bcacc5362 | |||
| 45368ff981 | |||
| 8a03c17c65 | |||
| bd9adfe7d0 | |||
| 6227b1aa89 | |||
| 7ca922dc61 | |||
| 17bdd137e3 | |||
| 148760cc04 | |||
| 2cc767612d | |||
| 38b7066ac0 | |||
| 30a4b0270a |
@@ -54,3 +54,5 @@ pids
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
imagenes
|
||||
|
||||
Generated
+588
-2
@@ -9,13 +9,14 @@
|
||||
"version": "0.0.1",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^10.0.0",
|
||||
"@nestjs/common": "^10.3.9",
|
||||
"@nestjs/config": "^3.2.2",
|
||||
"@nestjs/core": "^10.0.0",
|
||||
"@nestjs/jwt": "^10.2.0",
|
||||
"@nestjs/mapped-types": "*",
|
||||
"@nestjs/passport": "^10.0.3",
|
||||
"@nestjs/platform-express": "^10.0.0",
|
||||
"@nestjs/platform-express": "^10.3.9",
|
||||
"@nestjs/serve-static": "^4.0.2",
|
||||
"@nestjs/typeorm": "^10.0.2",
|
||||
"bcrypt": "^5.1.1",
|
||||
"bcryptjs": "^2.4.3",
|
||||
@@ -27,6 +28,7 @@
|
||||
"passport-jwt": "^4.0.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"sharp": "^0.33.4",
|
||||
"typeorm": "^0.3.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -36,6 +38,7 @@
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/node": "^20.14.2",
|
||||
"@types/passport-jwt": "^4.0.1",
|
||||
"@types/supertest": "^6.0.0",
|
||||
@@ -859,6 +862,16 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz",
|
||||
"integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
@@ -1014,6 +1027,456 @@
|
||||
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-arm64": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz",
|
||||
"integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.26",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-arm64": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-x64": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.26",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-x64": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-arm64": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz",
|
||||
"integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"macos": ">=11",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-x64": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz",
|
||||
"integrity": "sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"macos": ">=10.13",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz",
|
||||
"integrity": "sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.28",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm64": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz",
|
||||
"integrity": "sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.26",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-s390x": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz",
|
||||
"integrity": "sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.28",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-x64": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz",
|
||||
"integrity": "sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.26",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz",
|
||||
"integrity": "sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"musl": ">=1.2.2",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz",
|
||||
"integrity": "sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"musl": ">=1.2.2",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz",
|
||||
"integrity": "sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.28",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm64": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz",
|
||||
"integrity": "sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.26",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm64": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-s390x": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz",
|
||||
"integrity": "sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.31",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-s390x": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-x64": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"glibc": ">=2.26",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-x64": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-arm64": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz",
|
||||
"integrity": "sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"musl": ">=1.2.2",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-x64": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"musl": ">=1.2.2",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-wasm32": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz",
|
||||
"integrity": "sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/runtime": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-ia32": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz",
|
||||
"integrity": "sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-x64": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz",
|
||||
"integrity": "sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
|
||||
"npm": ">=9.6.5",
|
||||
"pnpm": ">=7.1.0",
|
||||
"yarn": ">=3.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
@@ -1865,6 +2328,7 @@
|
||||
"version": "10.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.9.tgz",
|
||||
"integrity": "sha512-JAQONPagMa+sy/fcIqh/Hn3rkYQ9pQM51vXCFNOM5ujefxUVqn3gwFRMN8Y1+MxdUHipV+8daEj2jEm0IqJzOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"iterare": "1.2.1",
|
||||
"tslib": "2.6.2",
|
||||
@@ -1988,6 +2452,7 @@
|
||||
"version": "10.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.9.tgz",
|
||||
"integrity": "sha512-si/UzobP6YUtYtCT1cSyQYHHzU3yseqYT6l7OHSMVvfG1+TqxaAqI6nmrix02LO+l1YntHRXEs3p+v9a7EfrSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"body-parser": "1.20.2",
|
||||
"cors": "2.8.5",
|
||||
@@ -2026,6 +2491,39 @@
|
||||
"integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@nestjs/serve-static": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/serve-static/-/serve-static-4.0.2.tgz",
|
||||
"integrity": "sha512-cT0vdWN5ar7jDI2NKbhf4LcwJzU4vS5sVpMkVrHuyLcltbrz6JdGi1TfIMMatP2pNiq5Ie/uUdPSFDVaZX/URQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-to-regexp": "0.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fastify/static": "^6.5.0 || ^7.0.0",
|
||||
"@nestjs/common": "^9.0.0 || ^10.0.0",
|
||||
"@nestjs/core": "^9.0.0 || ^10.0.0",
|
||||
"express": "^4.18.1",
|
||||
"fastify": "^4.7.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@fastify/static": {
|
||||
"optional": true
|
||||
},
|
||||
"express": {
|
||||
"optional": true
|
||||
},
|
||||
"fastify": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/serve-static/node_modules/path-to-regexp": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.2.5.tgz",
|
||||
"integrity": "sha512-l6qtdDPIkmAmzEO6egquYDfqQGPMRNGjYtrU13HAXb3YSRrt7HSb1sJY0pKp6o2bAa86tSB6iwaW2JbthPKr7Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@nestjs/testing": {
|
||||
"version": "10.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.9.tgz",
|
||||
@@ -2392,6 +2890,16 @@
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/multer": {
|
||||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz",
|
||||
"integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
|
||||
@@ -3827,6 +4335,19 @@
|
||||
"integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1",
|
||||
"color-string": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@@ -3843,6 +4364,16 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/color-string": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
||||
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/color-support": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||
@@ -8356,6 +8887,46 @@
|
||||
"sha.js": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/sharp": {
|
||||
"version": "0.33.4",
|
||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz",
|
||||
"integrity": "sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"color": "^4.2.3",
|
||||
"detect-libc": "^2.0.3",
|
||||
"semver": "^7.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"libvips": ">=8.15.2",
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "0.33.4",
|
||||
"@img/sharp-darwin-x64": "0.33.4",
|
||||
"@img/sharp-libvips-darwin-arm64": "1.0.2",
|
||||
"@img/sharp-libvips-darwin-x64": "1.0.2",
|
||||
"@img/sharp-libvips-linux-arm": "1.0.2",
|
||||
"@img/sharp-libvips-linux-arm64": "1.0.2",
|
||||
"@img/sharp-libvips-linux-s390x": "1.0.2",
|
||||
"@img/sharp-libvips-linux-x64": "1.0.2",
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.0.2",
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.0.2",
|
||||
"@img/sharp-linux-arm": "0.33.4",
|
||||
"@img/sharp-linux-arm64": "0.33.4",
|
||||
"@img/sharp-linux-s390x": "0.33.4",
|
||||
"@img/sharp-linux-x64": "0.33.4",
|
||||
"@img/sharp-linuxmusl-arm64": "0.33.4",
|
||||
"@img/sharp-linuxmusl-x64": "0.33.4",
|
||||
"@img/sharp-wasm32": "0.33.4",
|
||||
"@img/sharp-win32-ia32": "0.33.4",
|
||||
"@img/sharp-win32-x64": "0.33.4"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@@ -8463,6 +9034,21 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-swizzle/node_modules/is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sisteransi": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||
|
||||
+5
-2
@@ -20,13 +20,14 @@
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^10.0.0",
|
||||
"@nestjs/common": "^10.3.9",
|
||||
"@nestjs/config": "^3.2.2",
|
||||
"@nestjs/core": "^10.0.0",
|
||||
"@nestjs/jwt": "^10.2.0",
|
||||
"@nestjs/mapped-types": "*",
|
||||
"@nestjs/passport": "^10.0.3",
|
||||
"@nestjs/platform-express": "^10.0.0",
|
||||
"@nestjs/platform-express": "^10.3.9",
|
||||
"@nestjs/serve-static": "^4.0.2",
|
||||
"@nestjs/typeorm": "^10.0.2",
|
||||
"bcrypt": "^5.1.1",
|
||||
"bcryptjs": "^2.4.3",
|
||||
@@ -38,6 +39,7 @@
|
||||
"passport-jwt": "^4.0.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"sharp": "^0.33.4",
|
||||
"typeorm": "^0.3.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -47,6 +49,7 @@
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/node": "^20.14.2",
|
||||
"@types/passport-jwt": "^4.0.1",
|
||||
"@types/supertest": "^6.0.0",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { IsBoolean, IsInt, IsNotEmpty, IsNumber, IsString, IsOptional, Length} from "class-validator";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsBoolean, IsInt, IsNotEmpty, IsNumber, IsString, IsOptional, Length, ValidateNested} from "class-validator";
|
||||
|
||||
export class profesorDto{
|
||||
|
||||
@IsInt()
|
||||
id_profesor: number;
|
||||
|
||||
@IsInt()
|
||||
@IsNotEmpty()
|
||||
@@ -81,16 +85,24 @@ export class profesorDto{
|
||||
@IsOptional()
|
||||
mostrar: boolean;
|
||||
|
||||
proyectosAcademicos: ProyectoDto[];
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => ProyectosAcademicos)
|
||||
proyectosAcademicos: ProyectosAcademicos[];
|
||||
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => DatosAcademicos)
|
||||
datosAcademicos: DatosAcademicos[];
|
||||
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => LineasInvestigacion)
|
||||
lineasInvestigacion: LineasInvestigacion[];
|
||||
}
|
||||
|
||||
export class ProyectoDto {
|
||||
export class ProyectosAcademicos {
|
||||
|
||||
@IsOptional()
|
||||
@Length(0, 500)
|
||||
proyecto: string;
|
||||
proyecto_html: string;
|
||||
}
|
||||
|
||||
export class DatosAcademicos{
|
||||
@@ -108,5 +120,10 @@ export class LineasInvestigacion{
|
||||
|
||||
@IsOptional()
|
||||
@Length(0,300)
|
||||
lineas_inv: string;
|
||||
lineas_inv_html: string;
|
||||
}
|
||||
|
||||
export class UpdateProfesorImageDto {
|
||||
@IsString()
|
||||
fotografia: string;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
PrimaryColumn,
|
||||
Column,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
@@ -14,12 +14,12 @@ import { LineasInvestigacion } from '../../lineas_investigacion/entities/lineas_
|
||||
import { ProyectosAcademicos } from '../../proyectos_academicos/entities/proyectos_academicos.entity';
|
||||
import { User } from 'src/users/entities/user.entity';
|
||||
|
||||
@Entity()
|
||||
@Entity({ name: 'profesor' })
|
||||
export class Profesor {
|
||||
@PrimaryGeneratedColumn()
|
||||
@PrimaryColumn({ type: 'int', nullable: false })
|
||||
id_profesor: number;
|
||||
|
||||
@Column({ type: 'int',nullable: false })
|
||||
@Column({ type: 'int', nullable: false })
|
||||
id_usuario: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 10, nullable: true })
|
||||
@@ -86,28 +86,28 @@ export class Profesor {
|
||||
fecha_actualizacion: Date;
|
||||
|
||||
@ManyToOne(() => Edificio, edificio => edificio.profesores)
|
||||
@JoinColumn({ name: 'id_edificio' })
|
||||
@JoinColumn({ name: 'id_edificio', referencedColumnName: 'id_edificio', foreignKeyConstraintName: 'FK_edificio_fk' })
|
||||
edificio: Edificio;
|
||||
|
||||
@ManyToOne(() => Adscripcion, adscripcion => adscripcion.profesores)
|
||||
@JoinColumn({ name: 'id_adscripcion' })
|
||||
@JoinColumn({ name: 'id_adscripcion', referencedColumnName: 'id_adscripcion', foreignKeyConstraintName: 'FK_adscripcion_fk' })
|
||||
adscripcion: Adscripcion;
|
||||
|
||||
@ManyToOne(() => Categoria, categoria => categoria.profesores)
|
||||
@JoinColumn({ name: 'id_categoria' })
|
||||
@JoinColumn({ name: 'id_categoria', referencedColumnName: 'id_categoria', foreignKeyConstraintName: 'FK_categoria_fk' })
|
||||
categoria: Categoria;
|
||||
|
||||
@ManyToOne(() => User, user => user.profesores)
|
||||
@JoinColumn({ name: 'id_usuario' })
|
||||
@JoinColumn({ name: 'id_usuario', referencedColumnName: 'id_usuario', foreignKeyConstraintName: 'FK_usuario_fk' })
|
||||
user: User;
|
||||
|
||||
@OneToMany(() => DatosAcademicos, datosAcademicos => datosAcademicos.profesor)
|
||||
@OneToMany(() => DatosAcademicos, datosAcademicos => datosAcademicos.profesor,{ cascade: true })
|
||||
datosAcademicos: DatosAcademicos[];
|
||||
|
||||
@OneToMany(() => LineasInvestigacion, linea => linea.profesor)
|
||||
@OneToMany(() => LineasInvestigacion, linea => linea.profesor,{ cascade: true })
|
||||
lineasInvestigacion: LineasInvestigacion[];
|
||||
|
||||
@OneToMany(() => ProyectosAcademicos, proyecto => proyecto.profesor)
|
||||
@OneToMany(() => ProyectosAcademicos, proyecto => proyecto.profesor,{ cascade: true })
|
||||
proyectosAcademicos: ProyectosAcademicos[];
|
||||
|
||||
}
|
||||
|
||||
@@ -1,53 +1,96 @@
|
||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Query,UseGuards } from '@nestjs/common';
|
||||
import { ProfesorService } from './profesor.service';
|
||||
import { profesorDto } from './dto/profesorDto.dto';
|
||||
import {Roles} from '../permissions/roles.decorator'
|
||||
import {RolesGuard} from '../permissions/roles.guard'
|
||||
import {Role} from '../permissions/role.enum'
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpException,
|
||||
Logger,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards
|
||||
} from "@nestjs/common";
|
||||
import { ProfesorService } from "./profesor.service";
|
||||
import { profesorDto, UpdateProfesorImageDto } from "./dto/profesorDto.dto";
|
||||
import { Roles } from "../permissions/roles.decorator";
|
||||
import { RolesGuard } from "../permissions/roles.guard";
|
||||
import { Role } from "../permissions/role.enum";
|
||||
import { Profesor } from "./entities/profesor.entity";
|
||||
|
||||
@Controller('profesor')
|
||||
@Controller("profesor")
|
||||
@UseGuards(RolesGuard)
|
||||
export class ProfesorController {
|
||||
constructor(private profesorService: ProfesorService) {}
|
||||
constructor(private profesorService: ProfesorService) {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Roles(Role.Responsable,Role.Admin)
|
||||
@Roles(Role.Responsable, Role.Admin)
|
||||
async register(@Body() data: profesorDto) {
|
||||
Logger.debug("register profesor");
|
||||
return this.profesorService.register(data);
|
||||
}
|
||||
|
||||
@Put(':id_profesor/image')
|
||||
async updateImage(
|
||||
@Param('id_profesor') id_profesor: number,
|
||||
@Body() updateProfesorImageDto: UpdateProfesorImageDto,
|
||||
): Promise<Profesor> {
|
||||
const { fotografia } = updateProfesorImageDto;
|
||||
|
||||
const profesor = await this.profesorService.findOne(id_profesor);
|
||||
|
||||
if (!profesor) {
|
||||
throw new HttpException('Profesor not found', 404);
|
||||
}
|
||||
|
||||
profesor.fotografia = fotografia;
|
||||
|
||||
return this.profesorService.update(profesor);
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug("findAllProfesors");
|
||||
return this.profesorService.findAll();
|
||||
}
|
||||
|
||||
@Get('page')
|
||||
findAllPaginated(@Query('page') page: number = 1, @Query('limit') limit: number = 10, @Query() filters: any) {
|
||||
page = page < 1 ? 1 : page;
|
||||
limit = limit > 10 || limit < 1 ? 10 : limit;
|
||||
@Get("page")
|
||||
findAllPaginated(@Query("page") page: number = 1, @Query("limit") limit: number = 10, @Query() filters: any) {
|
||||
try {
|
||||
Logger.debug("Page Profesors");
|
||||
page = page < 1 ? 1 : page;
|
||||
limit = limit > 10 || limit < 1 ? 10 : limit;
|
||||
return this.profesorService.findAllPaginated(page, limit, filters);
|
||||
} catch (err) {
|
||||
Logger.error("profesor controller ", err.error);
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.profesorService.findAllPaginated(page, limit, filters);
|
||||
}
|
||||
|
||||
@Put(':id_profesor')
|
||||
@Roles(Role.Responsable,Role.Admin)
|
||||
async modify(@Param('id_profesor', ParseIntPipe) id_profesor: number, @Body() data: profesorDto) {
|
||||
@Put(":id_profesor")
|
||||
@Roles(Role.Responsable, Role.Admin)
|
||||
async modify(@Param("id_profesor", ParseIntPipe) id_profesor: number, @Body() data: profesorDto) {
|
||||
Logger.debug("put Profesors by id");
|
||||
|
||||
return this.profesorService.modify(id_profesor, data);
|
||||
}
|
||||
|
||||
@Delete(':id_profesor')
|
||||
@Roles(Role.Responsable,Role.Admin)
|
||||
async remove(@Param('id_profesor', ParseIntPipe) id_profesor: number) {
|
||||
@Delete(":id_profesor")
|
||||
@Roles(Role.Responsable, Role.Admin)
|
||||
async remove(@Param("id_profesor", ParseIntPipe) id_profesor: number) {
|
||||
Logger.debug("delete Profesors by id");
|
||||
|
||||
return this.profesorService.remove(id_profesor);
|
||||
}
|
||||
|
||||
@Get(':id_profesor')
|
||||
async profile(@Param('id_profesor', ParseIntPipe) id_profesor: number) {
|
||||
@Get(":id_profesor")
|
||||
async profile(@Param("id_profesor", ParseIntPipe) id_profesor: number) {
|
||||
Logger.debug("get Profesors by id");
|
||||
|
||||
return this.profesorService.profile(id_profesor);
|
||||
}
|
||||
|
||||
@Post('filter')
|
||||
async filter(@Body() data: profesorDto) {
|
||||
return this.profesorService.filter(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,24 +7,25 @@ import { DatosAcademicosModule } from '../datos_academicos/datos_academicos.modu
|
||||
import { LineasInvestigacionModule } from '../lineas_investigacion/lineas_investigacion.module';
|
||||
import { ProyectosAcademicosModule } from '../proyectos_academicos/proyectos_academicos.module';
|
||||
import { ProyectosAcademicos } from 'src/proyectos_academicos/entities/proyectos_academicos.entity';
|
||||
import { DatosAcademicos, LineasInvestigacion } from './dto/profesorDto.dto';
|
||||
import { ProyectosAcademicosService } from 'src/proyectos_academicos/proyectos_academicos.service';
|
||||
import { DatosAcademicosService } from 'src/datos_academicos/datos_academicos.service';
|
||||
import { LineasInvestigacionService } from 'src/lineas_investigacion/lineas_investigacion.service';
|
||||
import { DatosAcademicos } from 'src/datos_academicos/entities/datos_academicos.entity'
|
||||
import { LineasInvestigacion } from 'src/lineas_investigacion/entities/lineas_investigacion.entity'
|
||||
|
||||
import { JwtModule } from '@nestjs/jwt';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Profesor,
|
||||
ProyectosAcademicos,
|
||||
DatosAcademicos,
|
||||
LineasInvestigacion]),
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([
|
||||
Profesor,
|
||||
ProyectosAcademicos,
|
||||
DatosAcademicos,
|
||||
LineasInvestigacion
|
||||
]),
|
||||
DatosAcademicosModule,
|
||||
LineasInvestigacionModule,
|
||||
ProyectosAcademicosModule,
|
||||
JwtModule,
|
||||
],
|
||||
providers: [ProfesorService,
|
||||
ProyectosAcademicosService,
|
||||
DatosAcademicosService,
|
||||
LineasInvestigacionService,],
|
||||
providers: [ProfesorService],
|
||||
controllers: [ProfesorController],
|
||||
})
|
||||
export class ProfesorModule {}
|
||||
|
||||
+119
-105
@@ -1,83 +1,107 @@
|
||||
import { HttpException, Injectable } from '@nestjs/common';
|
||||
import { Profesor } from './entities/profesor.entity';
|
||||
import { DatosAcademicosService } from '../datos_academicos/datos_academicos.service';
|
||||
import { LineasInvestigacionService } from '../lineas_investigacion/lineas_investigacion.service';
|
||||
import { ProyectosAcademicosService } from '../proyectos_academicos/proyectos_academicos.service';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { profesorDto } from './dto/profesorDto.dto';
|
||||
import { ProyectosAcademicos } from '../proyectos_academicos/entities/proyectos_academicos.entity';
|
||||
import { DatosAcademicos } from '../datos_academicos/entities/datos_academicos.entity'
|
||||
import { LineasInvestigacion } from '../lineas_investigacion/entities/lineas_investigacion.entity'
|
||||
import { HttpException, Injectable, Logger } from "@nestjs/common";
|
||||
import { Profesor } from "./entities/profesor.entity";
|
||||
import { DatosAcademicosService } from "../datos_academicos/datos_academicos.service";
|
||||
import { LineasInvestigacionService } from "../lineas_investigacion/lineas_investigacion.service";
|
||||
import { ProyectosAcademicosService } from "../proyectos_academicos/proyectos_academicos.service";
|
||||
import { InjectRepository } from "@nestjs/typeorm";
|
||||
import { Repository } from "typeorm";
|
||||
import { profesorDto } from "./dto/profesorDto.dto";
|
||||
import { ProyectosAcademicos } from "../proyectos_academicos/entities/proyectos_academicos.entity";
|
||||
import { DatosAcademicos } from "../datos_academicos/entities/datos_academicos.entity";
|
||||
import { LineasInvestigacion } from "../lineas_investigacion/entities/lineas_investigacion.entity";
|
||||
|
||||
@Injectable()
|
||||
export class ProfesorService {
|
||||
constructor(
|
||||
@InjectRepository(Profesor) private profesorRepository: Repository<Profesor>,
|
||||
private datosAcademicosService: DatosAcademicosService,
|
||||
private lineasInvestigacionService: LineasInvestigacionService,
|
||||
private proyectosAcademicosService: ProyectosAcademicosService,
|
||||
@InjectRepository(ProyectosAcademicos)
|
||||
private readonly proyectosAcademicosRepository: Repository<ProyectosAcademicos>,
|
||||
@InjectRepository(Profesor)
|
||||
private readonly profesorRepository: Repository<Profesor>,
|
||||
private readonly datosAcademicosService: DatosAcademicosService,
|
||||
private readonly lineasInvestigacionService: LineasInvestigacionService,
|
||||
private readonly proyectosAcademicosService: ProyectosAcademicosService,
|
||||
@InjectRepository(DatosAcademicos)
|
||||
private readonly datosAcademicosRepository: Repository<DatosAcademicos>,
|
||||
@InjectRepository(LineasInvestigacion)
|
||||
private readonly lineasInvestigacionRepository: Repository<LineasInvestigacion>,
|
||||
) {}
|
||||
@InjectRepository(ProyectosAcademicos)
|
||||
private readonly proyectosAcademicosRepository: Repository<ProyectosAcademicos>
|
||||
) {
|
||||
}
|
||||
|
||||
async findOne(id_profesor: number): Promise<Profesor | undefined> {
|
||||
return this.profesorRepository.findOne({ where: { id_profesor } });
|
||||
}
|
||||
|
||||
async update(profesor: Profesor): Promise<Profesor> {
|
||||
return this.profesorRepository.save(profesor);
|
||||
}
|
||||
|
||||
private async findAvailableId(): Promise<number> {
|
||||
let id = 1;
|
||||
let exists = true;
|
||||
|
||||
while (exists) {
|
||||
if (!await this.profesorRepository.findOne({ where: { id_profesor: id } })) {
|
||||
Logger.debug(`id_profesor = ${id}`);
|
||||
exists = false;
|
||||
return id;
|
||||
}
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
//register teacher
|
||||
async register(data: profesorDto) {
|
||||
const {num_trabajador,rfc,proyectosAcademicos, datosAcademicos, lineasInvestigacion } = data;
|
||||
async register(data: profesorDto): Promise<Profesor | undefined> {
|
||||
const { num_trabajador, rfc, proyectosAcademicos, datosAcademicos, lineasInvestigacion } = data;
|
||||
|
||||
const existrfc = await this.profesorRepository.findOne({where:{rfc}});
|
||||
if(existrfc){
|
||||
throw new HttpException('rfc already exist', 403);
|
||||
if (await this.profesorRepository.findOne({ where: { rfc } })) {
|
||||
throw new HttpException("rfc already exist", 403);
|
||||
}
|
||||
|
||||
const existnumber = await this.profesorRepository.findOne({where:{num_trabajador}});
|
||||
if(existnumber){
|
||||
throw new HttpException('number of worker already exist', 403);
|
||||
if (await this.profesorRepository.findOne({ where: { num_trabajador } })) {
|
||||
throw new HttpException("number of worker already exist", 403);
|
||||
}
|
||||
|
||||
const newProfesor = this.profesorRepository.create(data);
|
||||
const savedProfesor = await this.profesorRepository.save(newProfesor);
|
||||
const availableId = await this.findAvailableId();
|
||||
data.id_profesor = availableId;
|
||||
|
||||
const savedProfesor = await this.profesorRepository.save(data);
|
||||
|
||||
if (proyectosAcademicos && proyectosAcademicos.length > 0) {
|
||||
const proyectos = proyectosAcademicos.map(proyecto => {
|
||||
const newProyecto = this.proyectosAcademicosRepository.create({
|
||||
...proyecto,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor,
|
||||
id_profesor: savedProfesor.id_profesor
|
||||
});
|
||||
return newProyecto;
|
||||
});
|
||||
await this.proyectosAcademicosRepository.save(proyectos);
|
||||
}
|
||||
|
||||
if (datosAcademicos && datosAcademicos.length > 0) {
|
||||
const datos = datosAcademicos.map(dato => {
|
||||
const newDato = this.datosAcademicosRepository.create({
|
||||
...dato,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor,
|
||||
});
|
||||
return newDato;
|
||||
});
|
||||
await this.datosAcademicosRepository.save(datos);
|
||||
}
|
||||
|
||||
if (lineasInvestigacion && lineasInvestigacion.length > 0) {
|
||||
const lineas = lineasInvestigacion.map(linea => {
|
||||
const newLinea = this.lineasInvestigacionRepository.create({
|
||||
...linea,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor,
|
||||
id_profesor: savedProfesor.id_profesor
|
||||
});
|
||||
return newLinea;
|
||||
});
|
||||
await this.lineasInvestigacionRepository.save(lineas);
|
||||
}
|
||||
|
||||
if (datosAcademicos && datosAcademicos.length > 0) {
|
||||
const datos = datosAcademicos.map(datosAcademicos => {
|
||||
const newDato = this.datosAcademicosRepository.create({
|
||||
...datosAcademicos,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor
|
||||
});
|
||||
return newDato;
|
||||
});
|
||||
await this.datosAcademicosRepository.save(datos);
|
||||
}
|
||||
|
||||
return savedProfesor;
|
||||
}
|
||||
|
||||
@@ -85,8 +109,8 @@ export class ProfesorService {
|
||||
async findAll(): Promise<Profesor[]> {
|
||||
return this.profesorRepository.find({
|
||||
order: {
|
||||
nombre: 'ASC',
|
||||
},
|
||||
nombre: "ASC"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,11 +118,12 @@ export class ProfesorService {
|
||||
async modify(id_profesor: number, data: profesorDto) {
|
||||
const profesor = await this.profesorRepository.findOne({ where: { id_profesor } });
|
||||
if (!profesor) {
|
||||
throw new HttpException('Profesor not found', 404);
|
||||
throw new HttpException("Profesor not found", 404);
|
||||
}
|
||||
|
||||
const { proyectosAcademicos, datosAcademicos, lineasInvestigacion, ...profesorData } = data;
|
||||
Object.assign(profesor, profesorData);
|
||||
|
||||
const savedProfesor = await this.profesorRepository.save(profesor);
|
||||
|
||||
if (proyectosAcademicos) {
|
||||
@@ -107,135 +132,124 @@ export class ProfesorService {
|
||||
const newProyecto = this.proyectosAcademicosRepository.create({
|
||||
...proyecto,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor,
|
||||
id_profesor: savedProfesor.id_profesor
|
||||
});
|
||||
return newProyecto;
|
||||
});
|
||||
await this.proyectosAcademicosRepository.save(proyectos);
|
||||
}
|
||||
|
||||
if (datosAcademicos) {
|
||||
await this.datosAcademicosRepository.delete({ profesor: { id_profesor } });
|
||||
const datos = datosAcademicos.map(dato => {
|
||||
const newDato = this.datosAcademicosRepository.create({
|
||||
...dato,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor,
|
||||
});
|
||||
return newDato;
|
||||
});
|
||||
await this.datosAcademicosRepository.save(datos);
|
||||
}
|
||||
|
||||
if (lineasInvestigacion) {
|
||||
await this.lineasInvestigacionRepository.delete({ profesor: { id_profesor } });
|
||||
const lineas = lineasInvestigacion.map(linea => {
|
||||
const newLinea = this.lineasInvestigacionRepository.create({
|
||||
...linea,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor,
|
||||
id_profesor: savedProfesor.id_profesor
|
||||
});
|
||||
return newLinea;
|
||||
});
|
||||
await this.lineasInvestigacionRepository.save(lineas);
|
||||
}
|
||||
|
||||
if (datosAcademicos) {
|
||||
await this.datosAcademicosRepository.delete({ profesor: { id_profesor } });
|
||||
const datos = datosAcademicos.map(datosAcademicos => {
|
||||
const newDato = this.datosAcademicosRepository.create({
|
||||
...datosAcademicos,
|
||||
profesor: savedProfesor,
|
||||
id_profesor: savedProfesor.id_profesor
|
||||
});
|
||||
return newDato;
|
||||
});
|
||||
await this.datosAcademicosRepository.save(datos);
|
||||
}
|
||||
|
||||
return savedProfesor;
|
||||
}
|
||||
|
||||
//remove teacher
|
||||
async remove(id_profesor: number) {
|
||||
const profesor = await this.profesorRepository.findOne({ where: { id_profesor }, relations: ['datosAcademicos'] });
|
||||
const profesor = await this.profesorRepository.findOne({ where: { id_profesor }, relations: ["datosAcademicos"] });
|
||||
if (!profesor) {
|
||||
throw new HttpException('Profesor not found', 404);
|
||||
throw new HttpException("Profesor not found", 404);
|
||||
}
|
||||
|
||||
// Delete related records in datos_academicos
|
||||
await this.datosAcademicosService.removeByProfesorId(id_profesor);
|
||||
await this.lineasInvestigacionService.removeByProfesorId(id_profesor);
|
||||
await this.proyectosAcademicosService.removeByProfesorId(id_profesor);
|
||||
|
||||
await this.profesorRepository.remove(profesor);
|
||||
return { message: 'Profesor removed successfully' };
|
||||
return { message: "Profesor removed successfully" };
|
||||
}
|
||||
|
||||
//brings teachers by id
|
||||
async profile(id_profesor: number) {
|
||||
const profesor = await this.profesorRepository.findOne({
|
||||
where: { id_profesor },
|
||||
relations: ['proyectosAcademicos', 'datosAcademicos', 'lineasInvestigacion'],
|
||||
relations: ["proyectosAcademicos", "datosAcademicos", "lineasInvestigacion"]
|
||||
});
|
||||
|
||||
|
||||
if (!profesor) {
|
||||
throw new HttpException('Profesor not found', 404);
|
||||
throw new HttpException("Profesor not found", 404);
|
||||
}
|
||||
|
||||
return profesor;
|
||||
}
|
||||
|
||||
//brings teachers by filter
|
||||
async filter(filterDto: profesorDto): Promise<Profesor[]> {
|
||||
const query = this.profesorRepository.createQueryBuilder('profesor');
|
||||
|
||||
if (filterDto.nombre) {
|
||||
query.andWhere('profesor.nombre like :nombre', { nombre: `%${filterDto.nombre}%` });
|
||||
}
|
||||
|
||||
if (filterDto.id_categoria !== undefined) {
|
||||
query.andWhere('profesor.id_categoria = :id_categoria', { id_categoria: filterDto.id_categoria });
|
||||
}
|
||||
|
||||
if (filterDto.extension) {
|
||||
query.andWhere('profesor.extension like :extension', { extension: `%${filterDto.extension}%` });
|
||||
}
|
||||
|
||||
if (filterDto.id_adscripcion !== undefined) {
|
||||
query.andWhere('profesor.id_adscripcion = :id_adscripcion', { id_adscripcion: filterDto.id_adscripcion });
|
||||
}
|
||||
|
||||
if (filterDto.id_edificio !== undefined) {
|
||||
query.andWhere('profesor.id_edificio = :id_edificio', { id_edificio: filterDto.id_edificio });
|
||||
}
|
||||
|
||||
if (filterDto.activo !== undefined) {
|
||||
query.andWhere('profesor.activo = :activo', { activo: filterDto.activo });
|
||||
}
|
||||
|
||||
return query.getMany();
|
||||
}
|
||||
|
||||
async findAllPaginated(
|
||||
page: number,
|
||||
limit: number,
|
||||
filters: any
|
||||
): Promise<{ profesores: Profesor[], total: number, totalPages: number }> {
|
||||
const query = this.profesorRepository.createQueryBuilder('profesor')
|
||||
const query = this.profesorRepository.createQueryBuilder("profesor");
|
||||
|
||||
if (filters.nombre) {
|
||||
query.andWhere('profesor.nombre LIKE :nombre', { nombre: `%${filters.nombre}%` });
|
||||
Logger.debug('fiter by name');
|
||||
|
||||
query.andWhere("profesor.nombre LIKE :nombre", { nombre: `%${filters.nombre}%` });
|
||||
}
|
||||
|
||||
if (filters.adscripcion) {
|
||||
query.andWhere('profesor.adscripcion = :adscripcion', { adscripcion: filters.adscripcion });
|
||||
Logger.debug("fiter by adscription");
|
||||
|
||||
query.andWhere("profesor.adscripcion = :adscripcion", { adscripcion: filters.adscripcion });
|
||||
}
|
||||
|
||||
if (filters.categoria) {
|
||||
query.andWhere('profesor.categoria = :categoria', { categoria: filters.categoria });
|
||||
Logger.debug("fiter by category");
|
||||
|
||||
query.andWhere("profesor.categoria = :categoria", { categoria: filters.categoria });
|
||||
}
|
||||
|
||||
if (filters.edificio) {
|
||||
query.andWhere('profesor.edificio = :edificio', { edificio: filters.edificio });
|
||||
Logger.debug("fiter by building");
|
||||
|
||||
query.andWhere("profesor.edificio = :edificio", { edificio: filters.edificio });
|
||||
}
|
||||
|
||||
if (typeof filters.activo !== "undefined") {
|
||||
Logger.debug("fiter by is active");
|
||||
|
||||
query.andWhere("profesor.activo = :activo", { activo: filters.activo });
|
||||
} else {
|
||||
query.orderBy("profesor.activo", "DESC");
|
||||
}
|
||||
|
||||
query.addOrderBy("profesor.nombre", "ASC");
|
||||
|
||||
const [profesores, total] = await query
|
||||
.skip((page - 1) * limit)
|
||||
.take(limit)
|
||||
.orderBy('profesor.nombre', 'ASC')
|
||||
.getManyAndCount();
|
||||
|
||||
const totalPages = Math.ceil(total / limit);
|
||||
|
||||
return { profesores, total, totalPages };
|
||||
}
|
||||
|
||||
|
||||
|
||||
async updateImageURL(id_profesor: number, imageUrl: string): Promise<void> {
|
||||
await this.profesorRepository.update(id_profesor, { fotografia: imageUrl });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { Controller, Get, Logger } from '@nestjs/common';
|
||||
import { AdscripcionService } from './adscripcion.service';
|
||||
|
||||
@Controller('adscripcion')
|
||||
@@ -7,6 +7,7 @@ export class AdscripcionController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all adscripcion');
|
||||
return this.adscripcionService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Entity, PrimaryColumn, Column, OneToMany } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Entity({ name: 'adscripcion' })
|
||||
export class Adscripcion {
|
||||
@PrimaryColumn({ type: 'int', nullable: false })
|
||||
id_adscripcion: number;
|
||||
|
||||
+20
-9
@@ -1,5 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||
import { join } from 'path';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
@@ -15,12 +17,13 @@ import { ProyectosAcademicos } from './proyectos_academicos/entities/proyectos_a
|
||||
import { TipoUsuario } from './tipo_usuario/entities/tipo_usuario.entity';
|
||||
import { ProfesorModule } from './Profesor/profesor.module';
|
||||
import { Profesor } from './Profesor/entities/profesor.entity';
|
||||
|
||||
import { AdscripcionController } from "./adscripcion/adscripcion.controller";
|
||||
import { AdscripcionService } from "./adscripcion/adscripcion.service";
|
||||
import { AdscripcionModule } from "./adscripcion/adscripcion.module";
|
||||
import { EdificioModule } from "./edificio/edificio.module";
|
||||
import { CategoriaModule } from "./categoria/categoria.module";
|
||||
import { AdscripcionModule } from './adscripcion/adscripcion.module';
|
||||
import { EdificioModule } from './edificio/edificio.module';
|
||||
import { CategoriaModule } from './categoria/categoria.module';
|
||||
import { DatosAcademicosModule } from './datos_academicos/datos_academicos.module';
|
||||
import { LineasInvestigacionModule } from './lineas_investigacion/lineas_investigacion.module';
|
||||
import { ProyectosAcademicosModule } from './proyectos_academicos/proyectos_academicos.module';
|
||||
import { ImagenModule } from './images/images.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -34,7 +37,7 @@ import { CategoriaModule } from "./categoria/categoria.module";
|
||||
imports: [ConfigModule, AuthModule, UsersModule],
|
||||
inject: [ConfigService],
|
||||
useFactory: async (configService: ConfigService) => ({
|
||||
type: 'mariadb',
|
||||
type: 'mysql',
|
||||
host: configService.get('DB_HOST'),
|
||||
port: configService.get('DB_PORT'),
|
||||
username: configService.get('DB_USER'),
|
||||
@@ -45,8 +48,8 @@ import { CategoriaModule } from "./categoria/categoria.module";
|
||||
User,
|
||||
Adscripcion,
|
||||
Categoria,
|
||||
DatosAcademicos,
|
||||
Edificio,
|
||||
DatosAcademicos,
|
||||
LineasInvestigacion,
|
||||
ProyectosAcademicos,
|
||||
TipoUsuario,
|
||||
@@ -54,7 +57,15 @@ import { CategoriaModule } from "./categoria/categoria.module";
|
||||
synchronize: true,
|
||||
}),
|
||||
}),
|
||||
ProfesorModule, AdscripcionModule, EdificioModule, CategoriaModule
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, '..', 'imagenes'),
|
||||
serveRoot: '/imagenes',
|
||||
}),
|
||||
ImagenModule,
|
||||
ProfesorModule,
|
||||
AdscripcionModule,
|
||||
EdificioModule,
|
||||
CategoriaModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common';
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
getHello(): string {
|
||||
console.log("it's ok ")
|
||||
console.log("it's ok IO")
|
||||
|
||||
return "hei verden";
|
||||
}
|
||||
|
||||
+60
-27
@@ -9,59 +9,92 @@ import {
|
||||
Put,
|
||||
Request,
|
||||
UseGuards,
|
||||
Delete
|
||||
Delete,
|
||||
ParseIntPipe,
|
||||
Query,
|
||||
Logger,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import { AuthGuard } from './auth.guard';
|
||||
import { AuthService } from './auth.service';
|
||||
import { registerDto } from './dto/registerDto.dto';
|
||||
import {Roles} from '../permissions/roles.decorator'
|
||||
import {RolesGuard} from '../permissions/roles.guard'
|
||||
import {Role} from '../permissions/role.enum'
|
||||
|
||||
import { Roles } from '../permissions/roles.decorator';
|
||||
import { RolesGuard } from '../permissions/roles.guard';
|
||||
import { Role } from '../permissions/role.enum';
|
||||
|
||||
@Controller('auth')
|
||||
//@UseGuards(RolesGuard)
|
||||
@UseGuards(RolesGuard)
|
||||
export class AuthController {
|
||||
constructor(private authService: AuthService) {}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('login')
|
||||
async signIn(@Body() data: registerDto) {
|
||||
return this.authService.signIn(data);
|
||||
Logger.debug('signIn');
|
||||
const { rememberMe } = data;
|
||||
return this.authService.signIn(data, rememberMe);
|
||||
}
|
||||
|
||||
//@UseGuards()
|
||||
@Post("register")
|
||||
//@Roles(Role.Admin)
|
||||
async register(@Body() data: registerDto){
|
||||
return this.authService.register(data)
|
||||
@Post('register')
|
||||
@Roles(Role.Admin)
|
||||
async register(@Body() data: registerDto) {
|
||||
Logger.debug('register user');
|
||||
return this.authService.register(data);
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all users');
|
||||
return this.authService.findAll();
|
||||
}
|
||||
|
||||
@Get('page')
|
||||
findAllPaginated(
|
||||
@Query('page') page: number = 1,
|
||||
@Query('limit') limit: number = 10,
|
||||
@Query() filters: any,
|
||||
) {
|
||||
Logger.debug('find all users max 10');
|
||||
page = page < 1 ? 1 : page;
|
||||
limit = limit > 10 || limit < 1 ? 10 : limit;
|
||||
|
||||
return this.authService.findAllPaginated(page, limit, filters);
|
||||
}
|
||||
|
||||
@Get(':id_usuario')
|
||||
async profile(@Param('id_usuario', ParseIntPipe) id_usuario: number) {
|
||||
Logger.debug('find one user');
|
||||
return this.authService.profile(id_usuario);
|
||||
}
|
||||
|
||||
//@UseGuards(AuthGuard)
|
||||
@Get('profile')
|
||||
async getProfile(@Request() req) {
|
||||
return req.user;
|
||||
@Put(':id_usuario')
|
||||
@Roles(Role.Admin)
|
||||
async update(
|
||||
@Param('id_usuario') id_usuario: number,
|
||||
@Body() data: registerDto,
|
||||
@Req() req: any
|
||||
) {
|
||||
const authHeader = req.headers['authorization'];
|
||||
const [, token] = authHeader.split(' ');
|
||||
|
||||
return this.authService.update(id_usuario, data, token);
|
||||
}
|
||||
|
||||
//@UseGuards(AuthGuard)
|
||||
@Put('Modificacion/:id')
|
||||
//@Roles(Role.Admin)
|
||||
async update(@Param('id') userId: number, @Body() data: registerDto) {
|
||||
return this.authService.update(userId, data);
|
||||
}
|
||||
|
||||
//@UseGuards(AuthGuard)
|
||||
@Delete('Borrado/:id')
|
||||
//@Roles(Role.Admin)
|
||||
async remove(@Param('id') id: number) {
|
||||
await this.authService.remove(id);
|
||||
@Delete(':id_usuario')
|
||||
@Roles(Role.Admin)
|
||||
async remove(@Param('id_usuario') id_usuario: number) {
|
||||
Logger.debug('delete user');
|
||||
await this.authService.remove(id_usuario);
|
||||
return { message: 'User successfully deleted' };
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post('validate')
|
||||
async validateToken(@Body('token') token: string) {
|
||||
Logger.debug('validate user');
|
||||
return this.authService.validateToken(token);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { UsersModule } from '../users/users.module';
|
||||
@@ -17,7 +16,7 @@ import { User } from 'src/users/entities/user.entity';
|
||||
return{
|
||||
global: true,
|
||||
secret: configService.get('JWT_SECRET'),
|
||||
signOptions: { expiresIn: "1h"},
|
||||
signOptions: { expiresIn: "7h"},
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
+95
-14
@@ -2,6 +2,7 @@ import {
|
||||
HttpException,
|
||||
Inject,
|
||||
Injectable,
|
||||
Logger,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { UsersService } from '../users/users.service';
|
||||
@@ -25,7 +26,7 @@ export class AuthService {
|
||||
|
||||
//register users
|
||||
async register(data: registerDto) {
|
||||
const { usuario, contraseña} = data;
|
||||
const { usuario, contraseña } = data;
|
||||
|
||||
if (await this.usersService.findOne(usuario)) {
|
||||
throw new HttpException('User already exist', 403);
|
||||
@@ -38,7 +39,7 @@ export class AuthService {
|
||||
}
|
||||
|
||||
//singin
|
||||
async signIn(data: registerDto) {
|
||||
async signIn(data: registerDto, rememberMe: boolean) {
|
||||
const { usuario, contraseña } = data;
|
||||
const user = await this.usersService.findOne(usuario);
|
||||
if (!user) {
|
||||
@@ -55,33 +56,55 @@ export class AuthService {
|
||||
usuario: user.usuario,
|
||||
id_tipo_usuario: user.id_tipo_usuario,
|
||||
};
|
||||
const token = this.jwtService.sign(payload);
|
||||
|
||||
const token = this.jwtService.sign(payload, {
|
||||
expiresIn: rememberMe ? '31d' : '7h',
|
||||
});
|
||||
|
||||
const expirationTime = rememberMe ? 31 * 24 * 3600 * 1000 : 7 * 3600 * 1000;
|
||||
|
||||
await this.usersService.updateTokenAndDates(
|
||||
user.id_usuario,
|
||||
token,
|
||||
new Date(),
|
||||
new Date(Date.now() + 3600 * 1000),
|
||||
new Date(Date.now() + expirationTime),
|
||||
);
|
||||
|
||||
return { token: token };
|
||||
return { token };
|
||||
}
|
||||
|
||||
//update user
|
||||
async update(userId, data:registerDto) {
|
||||
async update(
|
||||
id_usuario: number,
|
||||
data: registerDto,
|
||||
token: string,
|
||||
): Promise<any> {
|
||||
const { contraseña, id_tipo_usuario } = data;
|
||||
|
||||
const{contraseña}=data;
|
||||
const tokenUserId = this.getTokenUserId(token);
|
||||
|
||||
if(contraseña){
|
||||
const hashedpassword = await hash(contraseña, 10);
|
||||
data = {...data,contraseña:hashedpassword};
|
||||
if (tokenUserId == id_usuario && id_tipo_usuario !== undefined) {
|
||||
Logger.debug('Cannot modify id_tipo_usuario')
|
||||
delete data.id_tipo_usuario;
|
||||
}
|
||||
|
||||
return await this.userRepository.update(userId, data);
|
||||
const user = await this.userRepository.findOne({ where: { id_usuario } });
|
||||
if (!user) {
|
||||
throw new HttpException('User not found', 404);
|
||||
}
|
||||
|
||||
if (contraseña) {
|
||||
const hashedpassword = await hash(contraseña, 10);
|
||||
data = { ...data, contraseña: hashedpassword };
|
||||
} else {
|
||||
data = { ...data, contraseña: user.contraseña };
|
||||
}
|
||||
|
||||
return await this.userRepository.update(id_usuario, data);
|
||||
}
|
||||
|
||||
async remove(userId: number): Promise<void> {
|
||||
await this.userRepository.delete(userId);
|
||||
async remove(id_usuario: number): Promise<void> {
|
||||
await this.userRepository.delete(id_usuario);
|
||||
}
|
||||
|
||||
//validate tojen of users
|
||||
@@ -103,9 +126,67 @@ export class AuthService {
|
||||
throw new UnauthorizedException('Token has expired');
|
||||
}
|
||||
|
||||
return user;
|
||||
return;
|
||||
} catch (error) {
|
||||
throw new UnauthorizedException('validation token failed');
|
||||
}
|
||||
}
|
||||
|
||||
async findAll(): Promise<User[]> {
|
||||
return this.userRepository.find();
|
||||
}
|
||||
|
||||
async findAllPaginated(
|
||||
page: number,
|
||||
limit: number,
|
||||
filters: any,
|
||||
): Promise<{ usuarios: User[]; total: number; totalPages: number }> {
|
||||
const query = this.userRepository.createQueryBuilder('usuario');
|
||||
|
||||
if (filters.nombre) {
|
||||
Logger.debug('fiter by name user');
|
||||
query.andWhere('usuario.nombre LIKE :nombre', {
|
||||
nombre: `%${filters.nombre}%`,
|
||||
});
|
||||
}
|
||||
|
||||
if (filters.id_tipo_usuario) {
|
||||
Logger.debug('fiter by id user');
|
||||
query.andWhere('usuario.id_tipo_usuario = :id_tipo_usuario', {
|
||||
id_tipo_usuario: filters.id_tipo_usuario,
|
||||
});
|
||||
}
|
||||
|
||||
const [usuarios, total] = await query
|
||||
.skip((page - 1) * limit)
|
||||
.take(limit)
|
||||
.orderBy('usuario.nombre', 'ASC')
|
||||
.getManyAndCount();
|
||||
|
||||
const totalPages = Math.ceil(total / limit);
|
||||
|
||||
return { usuarios, total, totalPages };
|
||||
}
|
||||
|
||||
async profile(id_usuario: number) {
|
||||
const user = await this.userRepository.findOne({
|
||||
where: { id_usuario },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
Logger.debug('user not found');
|
||||
throw new HttpException('user not found', 404);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
getTokenUserId(token: string): number {
|
||||
try {
|
||||
const decoded = this.jwtService.verify(token);
|
||||
return decoded['id_usuario'];
|
||||
} catch (error) {
|
||||
throw new UnauthorizedException('Invalid token');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {IsString, IsNotEmpty,IsNumber } from "class-validator";
|
||||
import {IsString, IsNotEmpty,IsNumber, IsBoolean, IsOptional } from "class-validator";
|
||||
|
||||
export class registerDto{
|
||||
|
||||
@@ -22,4 +22,8 @@ export class registerDto{
|
||||
@IsNotEmpty()
|
||||
correo: string;
|
||||
|
||||
}
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
rememberMe: boolean;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { Controller, Get, Logger } from '@nestjs/common';
|
||||
import { CategoriaService } from './categoria.service';
|
||||
|
||||
@Controller('categoria')
|
||||
@@ -7,6 +7,7 @@ export class CategoriaController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all categoria');
|
||||
return this.categoriaService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Entity, PrimaryColumn, Column, OneToMany } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Entity({ name: 'categoria' })
|
||||
export class Categoria {
|
||||
@PrimaryColumn({ type: 'int', nullable: false })
|
||||
id_categoria: number;
|
||||
@@ -10,4 +10,4 @@ export class Categoria {
|
||||
|
||||
@OneToMany(() => Categoria, (categoria) => categoria.profesores)
|
||||
profesores: Categoria[];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DatosAcademicosController } from './datos_academicos.controller';
|
||||
|
||||
describe('DatosAcademicosController', () => {
|
||||
let controller: DatosAcademicosController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [DatosAcademicosController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<DatosAcademicosController>(DatosAcademicosController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,12 +1,15 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { Controller, Get, Logger } from '@nestjs/common';
|
||||
import { DatosAcademicosService } from './datos_academicos.service';
|
||||
|
||||
@Controller('datos-academicos')
|
||||
export class DatosAcademicosController {
|
||||
constructor(private readonly datosAcademicosService: DatosAcademicosService) {}
|
||||
constructor(
|
||||
private readonly datosAcademicosService: DatosAcademicosService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all datos academicos');
|
||||
return this.datosAcademicosService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { DatosAcademicos } from './entities/datos_academicos.entity';
|
||||
import { DatosAcademicosService } from './datos_academicos.service';
|
||||
import { DatosAcademicosController } from './datos_academicos.controller';
|
||||
import { DatosAcademicos } from './entities/datos_academicos.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([DatosAcademicos])],
|
||||
providers: [DatosAcademicosService],
|
||||
controllers: [DatosAcademicosController],
|
||||
exports: [DatosAcademicosService],
|
||||
})
|
||||
export class DatosAcademicosModule {}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DatosAcademicosService } from './datos_academicos.service';
|
||||
|
||||
describe('DatosAcademicosService', () => {
|
||||
let service: DatosAcademicosService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [DatosAcademicosService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<DatosAcademicosService>(DatosAcademicosService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,6 @@ export class DatosAcademicosService {
|
||||
private readonly datosAcademicosRepository: Repository<DatosAcademicos>,
|
||||
) {}
|
||||
|
||||
// Add methods to manage DatosAcademicos entities as needed
|
||||
async removeByProfesorId(id_profesor: number): Promise<void> {
|
||||
await this.datosAcademicosRepository.delete({ profesor: { id_profesor } });
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@ export class DatosAcademicos {
|
||||
grados_obtenidos: string;
|
||||
|
||||
@ManyToOne(() => Profesor, (profesor) => profesor.datosAcademicos)
|
||||
@JoinColumn({ name: 'id_profesor' })
|
||||
@JoinColumn({ name: 'id_profesor', referencedColumnName: 'id_profesor', foreignKeyConstraintName: 'FK_datos_academicos' })
|
||||
profesor: Profesor;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { Controller, Get, Logger } from '@nestjs/common';
|
||||
import { EdificioService } from './edificio.service';
|
||||
|
||||
@Controller('edificio')
|
||||
@@ -7,6 +7,7 @@ export class EdificioController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all edificio');
|
||||
return this.edificioService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Entity, PrimaryColumn, Column, OneToMany } from 'typeorm';
|
||||
import { Entity, PrimaryColumn, Column, OneToMany} from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@Entity({ name: 'edificio' })
|
||||
export class Edificio {
|
||||
@PrimaryColumn({ type: 'int', nullable: false })
|
||||
id_edificio: number;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Controller, Post, Body, Put, Logger } from '@nestjs/common';
|
||||
import { ImagenService } from './images.service';
|
||||
|
||||
@Controller('imagen')
|
||||
export class ImagenController {
|
||||
constructor(private readonly imagenService: ImagenService) {}
|
||||
|
||||
@Post()
|
||||
async upload(@Body() body) {
|
||||
Logger.debug('upload image');
|
||||
const { fotografia, nombre } = body;
|
||||
|
||||
const imageUrl = await this.imagenService.saveImage(fotografia, nombre);
|
||||
|
||||
return { message: 'Image uploaded successfully', imageUrl };
|
||||
}
|
||||
|
||||
@Put()
|
||||
async modify(@Body() body) {
|
||||
Logger.debug('modify image');
|
||||
const { fotografia, nombre } = body;
|
||||
|
||||
const imageUrl = await this.imagenService.modify(fotografia, nombre);
|
||||
|
||||
return { message: 'Image uploaded successfully', imageUrl };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ImagenController } from './images.controller';
|
||||
import { ImagenService } from './images.service';
|
||||
|
||||
@Module({
|
||||
controllers: [ImagenController],
|
||||
providers: [ImagenService],
|
||||
})
|
||||
export class ImagenModule {}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import { Injectable, BadRequestException, Logger } from '@nestjs/common';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
@Injectable()
|
||||
export class ImagenService {
|
||||
async saveImage(fotografia: string, id: string): Promise<string> {
|
||||
if (!fotografia) {
|
||||
throw new BadRequestException('No image provided');
|
||||
}
|
||||
|
||||
// Extract the image extension
|
||||
const matches = fotografia.match(/^data:image\/([a-zA-Z]+);base64,/);
|
||||
if (!matches) {
|
||||
throw new BadRequestException('Invalid image format');
|
||||
}
|
||||
const ext = matches[1];
|
||||
|
||||
// Decode base64 string and save the image
|
||||
const buffer = Buffer.from(fotografia.split(',')[1], 'base64');
|
||||
const imageName = `${id}.${ext}`;
|
||||
|
||||
// Save image to the 'imagenes' directory in the root of the project
|
||||
const imagePath = path.join(process.cwd(), 'imagenes', imageName);
|
||||
|
||||
// Ensure the directory exists
|
||||
const dirPath = path.join(process.cwd(), 'imagenes');
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(imagePath, buffer);
|
||||
|
||||
return imageName;
|
||||
}
|
||||
|
||||
async deleteImage(id: string): Promise<void> {
|
||||
Logger.debug('delete image');
|
||||
const imageDir = path.join(process.cwd(), 'imagenes');
|
||||
const imagePath = path.join(imageDir, id);
|
||||
|
||||
const extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'avif'];
|
||||
|
||||
let fileFound = false;
|
||||
for (const ext of extensions) {
|
||||
const fullImagePath = `${imagePath}.${ext}`;
|
||||
if (fs.existsSync(fullImagePath)) {
|
||||
fs.unlinkSync(fullImagePath);
|
||||
fileFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileFound) {
|
||||
console.log('Image not found, but continuing to save the new image.');
|
||||
}
|
||||
}
|
||||
|
||||
async modify(fotografia: string, id: string): Promise<string> {
|
||||
if (!fotografia) {
|
||||
throw new BadRequestException('No image provided');
|
||||
}
|
||||
|
||||
await this.deleteImage(id);
|
||||
|
||||
// Extract the image extension
|
||||
const matches = fotografia.match(/^data:image\/([a-zA-Z]+);base64,/);
|
||||
if (!matches) {
|
||||
throw new BadRequestException('Invalid image format');
|
||||
}
|
||||
const ext = matches[1];
|
||||
|
||||
// Decode base64 string and save the image
|
||||
const buffer = Buffer.from(fotografia.split(',')[1], 'base64');
|
||||
const imageName = `${id}.${ext}`;
|
||||
|
||||
// Save image to the 'imagenes' directory in the root of the project
|
||||
const imagePath = path.join(process.cwd(), 'imagenes', imageName);
|
||||
|
||||
// Ensure the directory exists
|
||||
const dirPath = path.join(process.cwd(), 'imagenes');
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(imagePath, buffer);
|
||||
|
||||
return imageName;
|
||||
}
|
||||
}
|
||||
@@ -10,13 +10,10 @@ export class LineasInvestigacion {
|
||||
@Column({ type: 'int', nullable: false })
|
||||
id_profesor: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 300, nullable: true })
|
||||
lineas_inv: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 350, nullable: true })
|
||||
lineas_inv_html: string;
|
||||
|
||||
@ManyToOne(() => Profesor, profesor => profesor.lineasInvestigacion)
|
||||
@JoinColumn({ name: 'id_profesor' })
|
||||
@ManyToOne(() => Profesor, profesor => profesor.lineasInvestigacion)
|
||||
@JoinColumn({ name: 'id_profesor', referencedColumnName: 'id_profesor', foreignKeyConstraintName: 'FK_lineas_investigacion' })
|
||||
profesor: Profesor;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { LineasInvestigacionController } from './lineas_investigacion.controller';
|
||||
|
||||
describe('LineasInvestigacionController', () => {
|
||||
let controller: LineasInvestigacionController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [LineasInvestigacionController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<LineasInvestigacionController>(LineasInvestigacionController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import { Controller, Get, Logger } from '@nestjs/common';
|
||||
import { LineasInvestigacionService } from './lineas_investigacion.service';
|
||||
|
||||
@Controller('lineas-investigacion')
|
||||
@@ -7,6 +7,7 @@ export class LineasInvestigacionController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all lineas de investigacion');
|
||||
return this.lineasInvestigacionService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { LineasInvestigacionService } from './lineas_investigacion.service';
|
||||
|
||||
describe('LineasInvestigacionService', () => {
|
||||
let service: LineasInvestigacionService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [LineasInvestigacionService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<LineasInvestigacionService>(LineasInvestigacionService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,6 @@ export class LineasInvestigacionService {
|
||||
private readonly lineasInvestigacionRepository: Repository<LineasInvestigacion>,
|
||||
) {}
|
||||
|
||||
// Add methods to manage LineasInvestigacion entities as needed
|
||||
async removeByProfesorId(id_profesor: number): Promise<void> {
|
||||
await this.lineasInvestigacionRepository.delete({ profesor: { id_profesor } });
|
||||
}
|
||||
|
||||
+12
-1
@@ -1,9 +1,20 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import * as path from 'path';
|
||||
import * as bodyParser from 'body-parser';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
||||
app.enableCors();
|
||||
|
||||
app.use(bodyParser.json({ limit: '1mb' }));
|
||||
app.use(bodyParser.urlencoded({ limit: '1mb', extended: true }));
|
||||
|
||||
app.useStaticAssets(path.join(__dirname, '..', 'imagenes'), {
|
||||
prefix: '/imagenes/',
|
||||
});
|
||||
|
||||
await app.listen(3000);
|
||||
}
|
||||
bootstrap();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export enum Role {
|
||||
Admin = '1',
|
||||
Responsable = '2',
|
||||
Admin = 1,
|
||||
Responsable = 2,
|
||||
}
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common';
|
||||
import {
|
||||
Injectable,
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
UnauthorizedException,
|
||||
Logger,
|
||||
} from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { Role } from './role.enum';
|
||||
import { ROLES_KEY } from './roles.decorator';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class RolesGuard implements CanActivate {
|
||||
constructor(private reflector: Reflector, private jwtService: JwtService) {}
|
||||
constructor(
|
||||
private reflector: Reflector,
|
||||
private jwtService: JwtService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
Logger.debug('verify roles');
|
||||
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
]);
|
||||
|
||||
if (!requiredRoles) {
|
||||
return true; // Si no hay roles requeridos, se permite el acceso
|
||||
return true;
|
||||
}
|
||||
|
||||
const request = context.switchToHttp().getRequest();
|
||||
@@ -25,23 +37,27 @@ export class RolesGuard implements CanActivate {
|
||||
throw new UnauthorizedException('No authorization header provided');
|
||||
}
|
||||
|
||||
const [, token] = authHeader.split(' ');
|
||||
const [, token] = authHeader.split(' ');
|
||||
if (!token) {
|
||||
throw new UnauthorizedException('No token provided');
|
||||
}
|
||||
|
||||
let userPayload;
|
||||
try {
|
||||
userPayload = this.jwtService.verify(token);
|
||||
const userPayload = await this.jwtService.verifyAsync(token, {
|
||||
secret: this.configService.get<string>('JWT_SECRET'),
|
||||
});
|
||||
|
||||
const userRole: Role = userPayload.id_tipo_usuario;
|
||||
const userId: number = userPayload.id_usuario;
|
||||
|
||||
const paramId = parseInt(request.params.id_usuario, 10);
|
||||
if (requiredRoles.includes(userRole) || userId === paramId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
throw new UnauthorizedException('Invalid token');
|
||||
}
|
||||
|
||||
const userRoles: Role[] = userPayload.id_tipo_usuario;
|
||||
if (!userRoles) {
|
||||
return false; // Si el token no contiene roles, se niega el acceso
|
||||
}
|
||||
|
||||
return requiredRoles.some(role => userRoles.includes(role));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,10 @@ export class ProyectosAcademicos {
|
||||
@Column({ type: 'int', nullable: false })
|
||||
id_profesor: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 500, nullable: true })
|
||||
proyecto: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 700, nullable: true })
|
||||
proyecto_html: string;
|
||||
|
||||
@ManyToOne(() => Profesor, profesor => profesor.proyectosAcademicos)
|
||||
@JoinColumn({ name: 'id_profesor' })
|
||||
@JoinColumn({ name: 'id_profesor', referencedColumnName: 'id_profesor', foreignKeyConstraintName: 'FK_proyectos_academicos' })
|
||||
profesor: Profesor;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ProyectosAcademicosController } from './proyectos_academicos.controller';
|
||||
|
||||
describe('ProyectosAcademicosController', () => {
|
||||
let controller: ProyectosAcademicosController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [ProyectosAcademicosController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<ProyectosAcademicosController>(ProyectosAcademicosController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller,Get } from '@nestjs/common';
|
||||
import { Controller,Get, Logger } from '@nestjs/common';
|
||||
import { ProyectosAcademicosService } from './proyectos_academicos.service';
|
||||
|
||||
@Controller('proyectos-academicos')
|
||||
@@ -7,6 +7,7 @@ export class ProyectosAcademicosController {
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
Logger.debug('find all proyectos academicos');
|
||||
return this.proyectosAcademicosService.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ProyectosAcademicosService } from './proyectos_academicos.service';
|
||||
|
||||
describe('ProyectosAcademicosService', () => {
|
||||
let service: ProyectosAcademicosService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [ProyectosAcademicosService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<ProyectosAcademicosService>(ProyectosAcademicosService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,6 @@ export class ProyectosAcademicosService {
|
||||
private readonly proyectosAcademicosRepository: Repository<ProyectosAcademicos>,
|
||||
) {}
|
||||
|
||||
// Add methods to manage ProyectosAcademicos entities as needed
|
||||
async removeByProfesorId(id_profesor: number): Promise<void> {
|
||||
await this.proyectosAcademicosRepository.delete({ profesor: { id_profesor } });
|
||||
}
|
||||
|
||||
@@ -4,17 +4,21 @@ export class UserDto{
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
usuario: string;
|
||||
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
nombre: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
contraseña: string;
|
||||
|
||||
@IsNumber()
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
id_tipo_usuario:number;
|
||||
id_tipo_usuario:string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
correo: string;
|
||||
|
||||
|
||||
}
|
||||
@@ -33,9 +33,9 @@ export class User {
|
||||
lastlog: Date;
|
||||
|
||||
@ManyToOne(() => TipoUsuario, tipoUsuario => tipoUsuario.users)
|
||||
@JoinColumn({ name: 'id_tipo_usuario' })
|
||||
@JoinColumn({ name: 'id_tipo_usuario', referencedColumnName: 'id_tipo_usuario', foreignKeyConstraintName: 'FK_tipo_usuario' })
|
||||
tipoUsuario: TipoUsuario;
|
||||
|
||||
@OneToMany(() => Profesor, profesor => profesor.user)
|
||||
profesores: Profesor[];
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { User } from './entities/user.entity';
|
||||
@@ -14,12 +14,14 @@ export class UsersService {
|
||||
async findOne(usuario: string): Promise<User | undefined> {
|
||||
return this.users.findOne({ where: { usuario } });
|
||||
}
|
||||
|
||||
async updateTokenAndDates(
|
||||
id: number,
|
||||
token: string,
|
||||
lastLogin: Date,
|
||||
jwtExpiry: Date,
|
||||
): Promise<void> {
|
||||
Logger.debug('update token and date user');
|
||||
await this.users.update(id, {
|
||||
jwt: token,
|
||||
lastlog: lastLogin,
|
||||
|
||||
Reference in New Issue
Block a user