Se agregó el inicio de sesion de google
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
database:
|
||||
image: mariadb:latest
|
||||
container_name: carga_db
|
||||
restart: always
|
||||
environment:
|
||||
- MARIADB_ROOT_PASSWORD=root
|
||||
- MARIADB_DATABASE=carga_test
|
||||
- MARIADB_USER=miusuario
|
||||
- MARIADB_PASSWORD=root
|
||||
env_file:
|
||||
- ../.env
|
||||
ports:
|
||||
|
||||
Generated
+313
-122
@@ -27,10 +27,11 @@
|
||||
"mysql2": "^3.14.1",
|
||||
"nodemailer": "^7.0.3",
|
||||
"passport": "^0.7.0",
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"typeorm": "^0.3.24"
|
||||
"typeorm": "^0.3.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
@@ -913,19 +914,30 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/plugin-kit": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz",
|
||||
"integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==",
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
|
||||
"integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@eslint/core": "^0.14.0",
|
||||
"@eslint/core": "^0.15.2",
|
||||
"levn": "^0.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
|
||||
"version": "0.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
|
||||
"integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fast-csv/format": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz",
|
||||
@@ -1081,14 +1093,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@inquirer/core": {
|
||||
"version": "10.1.13",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.13.tgz",
|
||||
"integrity": "sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==",
|
||||
"version": "10.1.15",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.15.tgz",
|
||||
"integrity": "sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@inquirer/figures": "^1.0.12",
|
||||
"@inquirer/type": "^3.0.7",
|
||||
"@inquirer/figures": "^1.0.13",
|
||||
"@inquirer/type": "^3.0.8",
|
||||
"ansi-escapes": "^4.3.2",
|
||||
"cli-width": "^4.1.0",
|
||||
"mute-stream": "^2.0.0",
|
||||
@@ -1109,15 +1120,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@inquirer/editor": {
|
||||
"version": "4.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.13.tgz",
|
||||
"integrity": "sha512-WbicD9SUQt/K8O5Vyk9iC2ojq5RHoCLK6itpp2fHsWe44VxxcA9z3GTWlvjSTGmMQpZr+lbVmrxdHcumJoLbMA==",
|
||||
"version": "4.2.17",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.17.tgz",
|
||||
"integrity": "sha512-r6bQLsyPSzbWrZZ9ufoWL+CztkSatnJ6uSxqd6N+o41EZC51sQeWOzI6s5jLb+xxTWxl7PlUppqm8/sow241gg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@inquirer/core": "^10.1.13",
|
||||
"@inquirer/type": "^3.0.7",
|
||||
"external-editor": "^3.1.0"
|
||||
"@inquirer/core": "^10.1.15",
|
||||
"@inquirer/external-editor": "^1.0.1",
|
||||
"@inquirer/type": "^3.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -1154,12 +1164,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@inquirer/figures": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.12.tgz",
|
||||
"integrity": "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==",
|
||||
"node_modules/@inquirer/external-editor": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.1.tgz",
|
||||
"integrity": "sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chardet": "^2.1.0",
|
||||
"iconv-lite": "^0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": ">=18"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@inquirer/figures": {
|
||||
"version": "1.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz",
|
||||
"integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
@@ -1334,11 +1364,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@inquirer/type": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.7.tgz",
|
||||
"integrity": "sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz",
|
||||
"integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -2632,21 +2661,19 @@
|
||||
"version": "11.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz",
|
||||
"integrity": "sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
||||
"passport": "^0.5.0 || ^0.6.0 || ^0.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/platform-express": {
|
||||
"version": "11.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.3.tgz",
|
||||
"integrity": "sha512-hEDNMlaPiBO72fxxX/CuRQL3MEhKRc/sIYGVoXjrnw6hTxZdezvvM6A95UaLsYknfmcZZa/CdG1SMBZOu9agHQ==",
|
||||
"license": "MIT",
|
||||
"version": "11.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.6.tgz",
|
||||
"integrity": "sha512-HErwPmKnk+loTq8qzu1up+k7FC6Kqa8x6lJ4cDw77KnTxLzsCaPt+jBvOq6UfICmfqcqCCf3dKXg+aObQp+kIQ==",
|
||||
"dependencies": {
|
||||
"cors": "2.8.5",
|
||||
"express": "5.1.0",
|
||||
"multer": "2.0.1",
|
||||
"multer": "2.0.2",
|
||||
"path-to-regexp": "8.2.0",
|
||||
"tslib": "2.8.1"
|
||||
},
|
||||
@@ -2835,7 +2862,6 @@
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-11.0.0.tgz",
|
||||
"integrity": "sha512-SOeUQl70Lb2OfhGkvnh4KXWlsd+zA08RuuQgT7kKbzivngxzSo1Oc7Usu5VxCxACQC9wc2l9esOHILSJeK7rJA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
||||
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
||||
@@ -5124,6 +5150,20 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/available-typed-arrays": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
||||
"dependencies": {
|
||||
"possible-typed-array-names": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/aws-ssl-profiles": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
|
||||
@@ -5300,6 +5340,14 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64url": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
|
||||
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bcrypt": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz",
|
||||
@@ -5598,6 +5646,23 @@
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.0",
|
||||
"es-define-property": "^1.0.0",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
@@ -5708,11 +5773,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/chardet": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz",
|
||||
"integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
@@ -6312,6 +6376,22 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -6902,15 +6982,6 @@
|
||||
"node": ">=8.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/exceljs/node_modules/tmp": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
|
||||
"integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/exceljs/node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
@@ -7058,34 +7129,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/external-editor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chardet": "^0.7.0",
|
||||
"iconv-lite": "^0.4.24",
|
||||
"tmp": "^0.0.33"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/external-editor/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==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-csv": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz",
|
||||
@@ -7390,6 +7433,20 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
||||
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
|
||||
"dependencies": {
|
||||
"is-callable": "^1.2.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
@@ -7435,11 +7492,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
|
||||
"integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
@@ -7836,6 +7892,17 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
@@ -7852,7 +7919,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
@@ -8077,6 +8143,17 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-callable": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||
@@ -8190,6 +8267,20 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-typed-array": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
|
||||
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
|
||||
"dependencies": {
|
||||
"which-typed-array": "^1.1.16"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-unicode-supported": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||
@@ -9793,10 +9884,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/multer": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.1.tgz",
|
||||
"integrity": "sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==",
|
||||
"license": "MIT",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz",
|
||||
"integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==",
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^1.6.0",
|
||||
@@ -10022,6 +10112,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/oauth": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.2.tgz",
|
||||
"integrity": "sha512-JtFnB+8nxDEXgNyniwz573xxbKSOu3R8D40xQKqcjwJ2CDkYqUDI53o6IuzDJBx60Z8VKCm271+t8iFjakrl8Q=="
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@@ -10145,16 +10240,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/p-cancelable": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
|
||||
@@ -10278,6 +10363,17 @@
|
||||
"url": "https://github.com/sponsors/jaredhanson"
|
||||
}
|
||||
},
|
||||
"node_modules/passport-google-oauth20": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
|
||||
"integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==",
|
||||
"dependencies": {
|
||||
"passport-oauth2": "1.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/passport-jwt": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.1.tgz",
|
||||
@@ -10288,6 +10384,25 @@
|
||||
"passport-strategy": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/passport-oauth2": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.8.0.tgz",
|
||||
"integrity": "sha512-cjsQbOrXIDE4P8nNb3FQRCCmJJ/utnFKEz2NX209f7KOHPoX18gF7gBzBbLLsj2/je4KrgiwLLGjf0lm9rtTBA==",
|
||||
"dependencies": {
|
||||
"base64url": "3.x.x",
|
||||
"oauth": "0.10.x",
|
||||
"passport-strategy": "1.x.x",
|
||||
"uid2": "0.0.x",
|
||||
"utils-merge": "1.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jaredhanson"
|
||||
}
|
||||
},
|
||||
"node_modules/passport-strategy": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
||||
@@ -10522,6 +10637,14 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/possible-typed-array-names": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
||||
"integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
@@ -11208,6 +11331,22 @@
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
@@ -11221,16 +11360,22 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/sha.js": {
|
||||
"version": "2.4.11",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
|
||||
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
|
||||
"license": "(MIT AND BSD-3-Clause)",
|
||||
"version": "2.4.12",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
|
||||
"integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
"inherits": "^2.0.4",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"to-buffer": "^1.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"sha.js": "bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
@@ -12052,16 +12197,11 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"os-tmpdir": "~1.0.2"
|
||||
},
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
|
||||
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/tmpl": {
|
||||
@@ -12071,6 +12211,24 @@
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/to-buffer": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz",
|
||||
"integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==",
|
||||
"dependencies": {
|
||||
"isarray": "^2.0.5",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"typed-array-buffer": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/to-buffer/node_modules/isarray": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@@ -12367,6 +12525,19 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-array-buffer": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
||||
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.3",
|
||||
"es-errors": "^1.3.0",
|
||||
"is-typed-array": "^1.1.14"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
@@ -12374,10 +12545,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typeorm": {
|
||||
"version": "0.3.24",
|
||||
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.24.tgz",
|
||||
"integrity": "sha512-4IrHG7A0tY8l5gEGXfW56VOMfUVWEkWlH/h5wmcyZ+V8oCiLj7iTPp0lEjMEZVrxEkGSdP9ErgTKHKXQApl/oA==",
|
||||
"license": "MIT",
|
||||
"version": "0.3.26",
|
||||
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.26.tgz",
|
||||
"integrity": "sha512-o2RrBNn3lczx1qv4j+JliVMmtkPSqEGpG0UuZkt9tCfWkoXKu8MZnjvp2GjWPll1SehwemQw6xrbVRhmOglj8Q==",
|
||||
"dependencies": {
|
||||
"@sqltools/formatter": "^1.2.5",
|
||||
"ansis": "^3.17.0",
|
||||
@@ -12407,9 +12577,8 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@google-cloud/spanner": "^5.18.0 || ^6.0.0 || ^7.0.0",
|
||||
"@sap/hana-client": "^2.12.25",
|
||||
"better-sqlite3": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
|
||||
"hdb-pool": "^0.1.6",
|
||||
"@sap/hana-client": "^2.14.22",
|
||||
"better-sqlite3": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0",
|
||||
"ioredis": "^5.0.4",
|
||||
"mongodb": "^5.8.0 || ^6.0.0",
|
||||
"mssql": "^9.1.1 || ^10.0.1 || ^11.0.1",
|
||||
@@ -12418,7 +12587,7 @@
|
||||
"pg": "^8.5.1",
|
||||
"pg-native": "^3.0.0",
|
||||
"pg-query-stream": "^4.0.0",
|
||||
"redis": "^3.1.1 || ^4.0.0",
|
||||
"redis": "^3.1.1 || ^4.0.0 || ^5.0.14",
|
||||
"reflect-metadata": "^0.1.14 || ^0.2.0",
|
||||
"sql.js": "^1.4.0",
|
||||
"sqlite3": "^5.0.3",
|
||||
@@ -12435,9 +12604,6 @@
|
||||
"better-sqlite3": {
|
||||
"optional": true
|
||||
},
|
||||
"hdb-pool": {
|
||||
"optional": true
|
||||
},
|
||||
"ioredis": {
|
||||
"optional": true
|
||||
},
|
||||
@@ -12633,6 +12799,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/uid2": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz",
|
||||
"integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA=="
|
||||
},
|
||||
"node_modules/uint8array-extras": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz",
|
||||
@@ -13100,6 +13271,26 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.19",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
|
||||
"integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.7",
|
||||
"call-bind": "^1.0.8",
|
||||
"call-bound": "^1.0.4",
|
||||
"for-each": "^0.3.5",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
|
||||
|
||||
+2
-1
@@ -38,10 +38,11 @@
|
||||
"mysql2": "^3.14.1",
|
||||
"nodemailer": "^7.0.3",
|
||||
"passport": "^0.7.0",
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"typeorm": "^0.3.24"
|
||||
"typeorm": "^0.3.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { AuthDocumentation } from './auth.documentation';
|
||||
import { Controller, Post, Body, UseGuards, Request, Get } from '@nestjs/common';
|
||||
import { Controller, Post, Body, UseGuards, Request, Get, Req, Res } from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { SetPasswordDto } from './dto/createPassword.dto';
|
||||
import { Response } from 'express';
|
||||
import { WhiteDto } from './dto/whiteList.dto';
|
||||
|
||||
@Controller()
|
||||
export class AuthController {
|
||||
@@ -34,6 +37,8 @@ export class AuthController {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +48,73 @@ export class AuthController {
|
||||
return this.authService.register(dto);
|
||||
}
|
||||
|
||||
@Post('white-list')
|
||||
@AuthDocumentation.white()
|
||||
async newRegister(@Body() dto:WhiteDto){
|
||||
|
||||
return this.authService.white(dto)
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Inicio de sesión con GOOGLE
|
||||
|
||||
@Get('google')
|
||||
@UseGuards(AuthGuard('google'))
|
||||
async googleLogin() {
|
||||
return { msg: 'Redirigiendo a Google' };
|
||||
}
|
||||
|
||||
// Callback de Google
|
||||
// @Get('google/callback')
|
||||
// @UseGuards(AuthGuard('google'))
|
||||
// async googleCallback(@Req() req) {
|
||||
// const user = req.user;
|
||||
|
||||
// if (user.needsPassword) {
|
||||
// return {
|
||||
// status: 'NEEDS_PASSWORD',
|
||||
// email: user.correo,
|
||||
// message: 'El usuario debe crear una contraseña antes de continuar',
|
||||
// };
|
||||
// }
|
||||
|
||||
// return this.authService.login(user); // genera JWT
|
||||
// }
|
||||
|
||||
// auth.controller.ts
|
||||
@Get('google/callback')
|
||||
@UseGuards(AuthGuard('google'))
|
||||
async googleCallback(@Req() req, @Res() res: Response) {
|
||||
const user = req.user;
|
||||
|
||||
if (user.needsPassword) {
|
||||
|
||||
return res.redirect(
|
||||
`${process.env.FRONTEND_URL}/password?email=${user.correo}`,
|
||||
);
|
||||
}
|
||||
|
||||
const jwt = await this.authService.login(user);
|
||||
|
||||
|
||||
return res.redirect(
|
||||
`${process.env.FRONTEND_URL}/oauth-callback?token=${jwt.access_token}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//Inicio de sesión con GOOGLE
|
||||
|
||||
//Set-contraseña
|
||||
// auth.controller.ts
|
||||
|
||||
|
||||
@Post('set-password')
|
||||
async setPassword(@Body() dto: SetPasswordDto) {
|
||||
return this.authService.setPassword(dto);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -101,4 +101,40 @@ export class AuthDocumentation {
|
||||
);
|
||||
}
|
||||
|
||||
static white() {
|
||||
return applyDecorators(
|
||||
ApiTags('Auth'),
|
||||
ApiOperation({
|
||||
summary: 'Registrar usuario',
|
||||
description: 'Crea un nuevo usuario con correo y origen para una white list.'
|
||||
}),
|
||||
ApiConsumes('application/json'),
|
||||
ApiBody({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
email: { type: 'string', format: 'email', example: 'nuevo@dominio.com' },
|
||||
origen: { type: 'string', example: 'RED', description: 'Origen del usuario' }
|
||||
|
||||
}
|
||||
}
|
||||
}),
|
||||
ApiResponse({
|
||||
status: 201,
|
||||
description: 'Usuario creado correctamente',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id_usuario: { type: 'number', example: 1 },
|
||||
correo: { type: 'string', example: 'nuevo@dominio.com' },
|
||||
origen: { type: 'string', example: 'RED' }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}),
|
||||
ApiResponse({ status: 409, description: 'El correo ya está registrado.' }),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { AuthController } from './auth.controller';
|
||||
import { JwtStrategy } from './jwt.strategy';
|
||||
import { Origen, UsuariosDelSistema } from '../entities/entities';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { GoogleStrategy } from './google.strategy';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -22,7 +23,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
}),
|
||||
}),
|
||||
],
|
||||
providers: [AuthService, JwtStrategy],
|
||||
providers: [AuthService, JwtStrategy, GoogleStrategy],
|
||||
controllers: [AuthController],
|
||||
})
|
||||
export class AuthModule { }
|
||||
|
||||
@@ -6,6 +6,8 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Origen, UsuariosDelSistema } from '../entities/entities';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
import { SetPasswordDto } from './dto/createPassword.dto';
|
||||
import { WhiteDto } from './dto/whiteList.dto';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
@@ -75,4 +77,92 @@ export class AuthService {
|
||||
const { contraseña, ...result } = saved;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
async white(dto: WhiteDto) {
|
||||
// 1) Verificar duplicado
|
||||
const exists = await this.userRepo.findOne({ where: { correo: dto.email } });
|
||||
if (exists) {
|
||||
throw new ConflictException('El correo ya está registrado');
|
||||
}
|
||||
|
||||
|
||||
|
||||
let origen = await this.origenRepo.findOne({ where: { origen: dto.origen } });
|
||||
|
||||
if (!origen) {
|
||||
origen = this.origenRepo.create({ origen: dto.origen });
|
||||
origen = await this.origenRepo.save(origen);
|
||||
}
|
||||
|
||||
|
||||
// 3) Crear entidad Usuario
|
||||
const user = this.userRepo.create({
|
||||
correo: dto.email,
|
||||
origen: origen,
|
||||
|
||||
});
|
||||
|
||||
// 4) Guardar en BD
|
||||
const saved = await this.userRepo.save(user);
|
||||
|
||||
// 5) Devolver sin contraseña
|
||||
const { contraseña, ...result } = saved;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
async validateGoogleUser(email: string) {
|
||||
const user = await this.userRepo.findOne({ where: { correo: email }, relations: ['origen'] });
|
||||
|
||||
if (!user) {
|
||||
// No permitir crear cuenta
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!user.contraseña) {
|
||||
// Usuario existe pero nunca puso contraseña → permitirle definirla
|
||||
return {
|
||||
...user,
|
||||
needsPassword: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Usuario con contraseña → login normal
|
||||
return user;
|
||||
}
|
||||
|
||||
//Poner contraseñas
|
||||
// auth.service.ts
|
||||
async setPassword(dto: SetPasswordDto) {
|
||||
const user = await this.userRepo.findOne({
|
||||
where: { correo: dto.email },
|
||||
relations: ['origen'],
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new UnauthorizedException('Usuario no encontrado');
|
||||
}
|
||||
|
||||
if (user.contraseña) {
|
||||
throw new ConflictException('Este usuario ya tiene contraseña');
|
||||
}
|
||||
|
||||
// Hash contraseña nueva
|
||||
const hash = await bcrypt.hash(dto.password, 10);
|
||||
|
||||
user.contraseña = hash;
|
||||
const updated = await this.userRepo.save(user);
|
||||
|
||||
// Retornar con JWT inmediato (login automático)
|
||||
const payload = { sub: updated.id_usuario, email: updated.correo, tipo: updated.origen.origen };
|
||||
|
||||
return {
|
||||
access_token: this.jwtService.sign(payload),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// dto/set-password.dto.ts
|
||||
import { IsEmail, IsNotEmpty, MinLength } from 'class-validator';
|
||||
|
||||
export class SetPasswordDto {
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@MinLength(6)
|
||||
password: string;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { IsEmail, IsString, MinLength, MaxLength, IsOptional, IsNumber } from 'class-validator';
|
||||
|
||||
export class WhiteDto {
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@IsString()
|
||||
@MaxLength(60)
|
||||
origen: string;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// google.strategy.ts
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { Strategy, VerifyCallback } from 'passport-google-oauth20';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
@Injectable()
|
||||
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
|
||||
constructor(
|
||||
private readonly authService: AuthService,
|
||||
private readonly config: ConfigService,
|
||||
) {
|
||||
super({
|
||||
clientID: config.get<string>('GOOGLE_CLIENT_ID'),
|
||||
clientSecret: config.get<string>('GOOGLE_CLIENT_SECRET'),
|
||||
callbackURL: config.get<string>('GOOGLE_CALLBACK_URL'),
|
||||
scope: ['email', 'profile'],
|
||||
});
|
||||
}
|
||||
|
||||
async validate(
|
||||
accessToken: string,
|
||||
refreshToken: string,
|
||||
profile: any,
|
||||
done: VerifyCallback,
|
||||
): Promise<any> {
|
||||
const { emails } = profile;
|
||||
const email = emails[0].value;
|
||||
|
||||
const user = await this.authService.validateGoogleUser(email);
|
||||
|
||||
if (!user) {
|
||||
throw new UnauthorizedException('Usuario no registrado en el sistema');
|
||||
}
|
||||
|
||||
done(null, user);
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ export class TipoUsuario {
|
||||
@PrimaryGeneratedColumn({ name: 'id_tipo_usuario', type: 'int' })
|
||||
id_tipo_usuario: number;
|
||||
|
||||
@Column({ name: 'tipo_usuario', type: 'varchar', length: 20 })
|
||||
@Column({ name: 'tipo_usuario', type: 'varchar', length: 30 })
|
||||
tipo_usuario: string;
|
||||
|
||||
@OneToMany(() => UsuarioTipoUsuario, utu => utu.tipoUsuario)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// src/excel/excel.controller.ts
|
||||
import { Controller, Post, Get, UseGuards, Request, Res, UploadedFile, UseInterceptors, HttpStatus, Param, ParseIntPipe, Body, BadRequestException } from '@nestjs/common';
|
||||
import { Controller, Post, Get, UseGuards, Request, Res, UploadedFile, UseInterceptors, HttpStatus, Param, ParseIntPipe, Body, BadRequestException, Delete } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
@@ -69,6 +69,7 @@ export class ExcelController {
|
||||
@ExcelDocumentation.loadExcel()
|
||||
async loadExcel(@Request() req, @UploadedFile() file: Express.Multer.File) {
|
||||
const origen = req.user.origen; // ahora sí existe
|
||||
|
||||
if (origen != 'LOAD') {
|
||||
await this.movimientoService.log(
|
||||
origen,
|
||||
@@ -78,6 +79,7 @@ export class ExcelController {
|
||||
throw new Error('Origen no permitido para carga.');
|
||||
}
|
||||
try {
|
||||
|
||||
const result = await this.excelService.loadFile(file.buffer);
|
||||
//Actualizar el estado de los movimientos
|
||||
if (!result) {
|
||||
@@ -120,6 +122,24 @@ export class ExcelController {
|
||||
});
|
||||
|
||||
await this.excelService.enviarCargaMasiva();
|
||||
|
||||
|
||||
await this.excelService.enviarInforme('AT',"Carga de datos en Servicios PCpuma",
|
||||
`Se ha hecho una carga en el sistema \n ${result.conteoTiposAt}`
|
||||
)
|
||||
|
||||
await this.excelService.enviarInforme('RED',"Carga de datos en Servicios PCpuma",
|
||||
`Se ha hecho una carga en el sistema \n ${result.conteoTiposRed}`
|
||||
)
|
||||
|
||||
await this.excelService.enviarInforme('SOLICITA',"Carga de datos en Servicios PCpuma",
|
||||
`Se ha hecho una carga en el sistema \n ${result.conteoTiposCorreo}`
|
||||
)
|
||||
|
||||
await this.excelService.enviarInforme('CORREO',"Carga de datos en Servicios PCpuma",
|
||||
`Se ha hecho una carga en el sistema \n ${result.conteoTiposCorreo}`
|
||||
)
|
||||
|
||||
|
||||
|
||||
return result
|
||||
@@ -300,6 +320,11 @@ export class ExcelController {
|
||||
|
||||
}
|
||||
|
||||
// @Delete()
|
||||
// async borrar(){
|
||||
// return await this.excelService.borrarUsers()
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+242
-166
@@ -198,178 +198,244 @@ export class ExcelService {
|
||||
* Valida y luego persiste usuarios y relaciones básicas
|
||||
*/
|
||||
async loadFile(buffer: Buffer) {
|
||||
const file = await this.parseFile(buffer);
|
||||
const status = this.validateRows(file);
|
||||
const errs = status.errors;
|
||||
const rows = status.rowsGood;
|
||||
const file = await this.parseFile(buffer);
|
||||
const status = this.validateRows(file);
|
||||
const errs = status.errors;
|
||||
const rows = status.rowsGood;
|
||||
|
||||
if (rows.length === 0) {
|
||||
throw new BadRequestException('No se encontraron filas válidas para cargar. ' + errs);
|
||||
}
|
||||
if (rows.length === 0) {
|
||||
throw new BadRequestException(
|
||||
'No se encontraron filas válidas para cargar. ' + errs,
|
||||
);
|
||||
}
|
||||
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
const conteoTiposRed: Record<string, number> = {};
|
||||
const conteoTiposAt: Record<string, number> = {};
|
||||
const conteoTiposSolicita: Record<string, number> = {};
|
||||
const conteoTiposCorreo: Record<string, number> = {};
|
||||
|
||||
try {
|
||||
const movimiento = await this.movimientoService.logger(
|
||||
queryRunner,
|
||||
'LOAD',
|
||||
'LOADING',
|
||||
undefined,
|
||||
'CARGA MASIVA DE USUARIOS'
|
||||
);
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
let contador = 0;
|
||||
try {
|
||||
const movimiento = await this.movimientoService.logger(
|
||||
queryRunner,
|
||||
'LOAD',
|
||||
'LOADING',
|
||||
undefined,
|
||||
'CARGA MASIVA DE USUARIOS',
|
||||
);
|
||||
|
||||
for (const r of rows) {
|
||||
// 🔹 1. Pre-cargar cuentas/rfc ya existentes
|
||||
const cuentas = rows.map((r) => r.cuenta).filter(Boolean);
|
||||
const rfcs = rows.map((r) => r.rfc).filter(Boolean);
|
||||
|
||||
const whereCond: Array<{ num_cuenta?: string; rfc?: string }> = [{ num_cuenta: r.cuenta }];
|
||||
if (r.rfc) {
|
||||
whereCond.push({ rfc: r.rfc });
|
||||
}
|
||||
const existentes = await queryRunner.manager.find(Usuario, {
|
||||
where: [{ num_cuenta: In(cuentas) }, { rfc: In(rfcs) }],
|
||||
select: ['num_cuenta', 'rfc'],
|
||||
});
|
||||
|
||||
const userExists = await queryRunner.manager.findOne(Usuario, {
|
||||
where: whereCond,
|
||||
});
|
||||
const setCuentas = new Set(existentes.map((u) => u.num_cuenta));
|
||||
const setRfcs = new Set(existentes.map((u) => u.rfc));
|
||||
|
||||
// 🔹 2. Pre-cargar catálogos
|
||||
const generosUnicos = [...new Set(rows.map((r) => r.sexo).filter(Boolean))];
|
||||
const carrerasUnicasClave = [
|
||||
...new Set(rows.map((r) => r.clave).filter(Boolean)),
|
||||
];
|
||||
const carrerasUnicasNombre = [
|
||||
...new Set(rows.map((r) => r.nomCarr).filter(Boolean)),
|
||||
];
|
||||
const tiposUnicos = [...new Set(rows.map((r) => r.tipo?.trim()).filter(Boolean))];
|
||||
|
||||
const [generosExist, carrerasExist, tiposExist] = await Promise.all([
|
||||
queryRunner.manager.find(Genero, { where: { genero: In(generosUnicos) } }),
|
||||
queryRunner.manager.find(Carrera, {
|
||||
where: [{ clave: In(carrerasUnicasClave) }, { carrera: In(carrerasUnicasNombre) }],
|
||||
}),
|
||||
queryRunner.manager.find(TipoUsuario, {
|
||||
where: { tipo_usuario: In(tiposUnicos) },
|
||||
}),
|
||||
]);
|
||||
|
||||
if (userExists) {
|
||||
errs.push(`Cuenta ${r.cuenta} ya existe, se omite.`);
|
||||
contador++;
|
||||
continue;
|
||||
}
|
||||
const mapGenero = new Map(generosExist.map((g) => [g.genero, g]));
|
||||
const mapCarreraClave = new Map(carrerasExist.map((c) => [c.clave, c]));
|
||||
const mapCarreraNom = new Map(carrerasExist.map((c) => [c.carrera, c]));
|
||||
const mapTipo = new Map(tiposExist.map((t) => [t.tipo_usuario, t]));
|
||||
|
||||
if (!r.tipo || !r.nombres || !r.apellidopa || !r.apellidoma) {
|
||||
errs.push(`Fila con cuenta ${r.cuenta} tiene campos faltantes.`);
|
||||
contador++;
|
||||
continue;
|
||||
}
|
||||
// 🔹 3. Arreglos para inserciones masivas
|
||||
const usuarios: Usuario[] = [];
|
||||
const carrerasUsuario: CarreraUsuario[] = [];
|
||||
const usuariosTipos: UsuarioTipoUsuario[] = [];
|
||||
const serviciosActivos: ServActivos[] = [];
|
||||
|
||||
let genero = await queryRunner.manager.findOne(Genero, { where: { genero: r.sexo } });
|
||||
if (!genero) {
|
||||
genero = queryRunner.manager.create(Genero, { genero: r.sexo });
|
||||
await queryRunner.manager.save(genero);
|
||||
}
|
||||
let contador = 0;
|
||||
|
||||
let carrera
|
||||
if (r.clave || r.nomCarr) {
|
||||
if (!r.clave) {
|
||||
carrera = await queryRunner.manager.findOne(Carrera, { where: { carrera: r.nomCarr } });
|
||||
|
||||
|
||||
} else if (!r.nomCarr) {
|
||||
|
||||
carrera = await queryRunner.manager.findOne(Carrera, { where: { clave: r.clave } });
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!carrera) {
|
||||
carrera = queryRunner.manager.create(Carrera, {
|
||||
clave: r.clave ?? "",
|
||||
carrera: r.nomCarr.slice(0, 100),
|
||||
});
|
||||
|
||||
await queryRunner.manager.save(carrera);
|
||||
}
|
||||
|
||||
} else {
|
||||
carrera = null;
|
||||
}
|
||||
|
||||
let tipo = await queryRunner.manager.findOne(TipoUsuario, {
|
||||
where: { tipo_usuario: r.tipo.trim() },
|
||||
});
|
||||
if (!tipo) {
|
||||
tipo = queryRunner.manager.create(TipoUsuario, { tipo_usuario: r.tipo.trim() });
|
||||
await queryRunner.manager.save(tipo);
|
||||
}
|
||||
|
||||
const generacion = /^[0-9]{4}$/.test(r.gen?.toString().trim())
|
||||
? parseInt(r.gen.toString().trim(), 10)
|
||||
: null;
|
||||
|
||||
const usuario = queryRunner.manager.create(Usuario, {
|
||||
num_cuenta: r.cuenta,
|
||||
nombre: r.nombres,
|
||||
a_paterno: r.apellidopa,
|
||||
a_materno: r.apellidoma,
|
||||
rfc: r.rfc,
|
||||
fecha_nacimiento: r.fechnac,
|
||||
generacion,
|
||||
genero,
|
||||
movimiento,
|
||||
});
|
||||
const user = await queryRunner.manager.save(usuario);
|
||||
|
||||
if (carrera) {
|
||||
const carreraUsuario = queryRunner.manager.create(CarreraUsuario, {
|
||||
usuario: user,
|
||||
carrera,
|
||||
});
|
||||
await queryRunner.manager.save(carreraUsuario);
|
||||
}
|
||||
|
||||
const usuarioTipo = queryRunner.manager.create(UsuarioTipoUsuario, {
|
||||
usuario: user,
|
||||
tipoUsuario: tipo,
|
||||
});
|
||||
await queryRunner.manager.save(usuarioTipo);
|
||||
|
||||
const servData = {
|
||||
usuario: user,
|
||||
RedStatus: 'Inactivo',
|
||||
ATStatus: 'Inactivo',
|
||||
CorreoStatus: 'Inactivo',
|
||||
PrestamosStatus: 'Inactivo',
|
||||
};
|
||||
|
||||
switch (r.tipo.trim()) {
|
||||
case 'Diplomado':
|
||||
Object.assign(servData, { Correo: true });
|
||||
break;
|
||||
case 'Extra Largo':
|
||||
Object.assign(servData, { Correo: true, Prestamos: true });
|
||||
break;
|
||||
case 'Servicio Social':
|
||||
Object.assign(servData, { Correo: true, AT: true, Red: true });
|
||||
break;
|
||||
case 'Idiomas R (UNAM)':
|
||||
case 'Idiomas Sabatino':
|
||||
Object.assign(servData, { Correo: true, Red: true });
|
||||
break;
|
||||
case 'Reinscrito':
|
||||
case 'Posgrado':
|
||||
case 'Intercambio UNAM':
|
||||
case 'Movilidad':
|
||||
case 'Ampliación de Conocimiento':
|
||||
case 'Licenciatura':
|
||||
case 'Profesor':
|
||||
Object.assign(servData, { Correo: true, AT: true, Red: true, Prestamos: true });
|
||||
break;
|
||||
case 'Trabajadores':
|
||||
Object.assign(servData, { Red: true });
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
const serv = queryRunner.manager.create(ServActivos, servData);
|
||||
await queryRunner.manager.save(serv);
|
||||
for (const r of rows) {
|
||||
if (setCuentas.has(r.cuenta) || (r.rfc && setRfcs.has(r.rfc))) {
|
||||
errs.push(`Cuenta ${r.cuenta} ya existe, se omite.`);
|
||||
contador++;
|
||||
continue;
|
||||
}
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
return { inserted: rows.length - contador, id_movimiento: movimiento.id_mov, errors: errs };
|
||||
} catch (err) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
throw err;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
if (!r.tipo || !r.nombres || !r.apellidopa || !r.apellidoma) {
|
||||
errs.push(`Fila con cuenta ${r.cuenta} tiene campos faltantes.`);
|
||||
contador++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Genero
|
||||
let genero = mapGenero.get(r.sexo);
|
||||
if (!genero) {
|
||||
genero = queryRunner.manager.create(Genero, { genero: r.sexo });
|
||||
mapGenero.set(r.sexo, genero);
|
||||
}
|
||||
|
||||
// Carrera
|
||||
let carrera: Carrera|undefined;
|
||||
if (r.clave && mapCarreraClave.has(r.clave)) {
|
||||
carrera = mapCarreraClave.get(r.clave);
|
||||
} else if (r.nomCarr && mapCarreraNom.has(r.nomCarr)) {
|
||||
carrera = mapCarreraNom.get(r.nomCarr);
|
||||
} else if (r.clave || r.nomCarr) {
|
||||
carrera = queryRunner.manager.create(Carrera, {
|
||||
clave: r.clave ?? '',
|
||||
carrera: r.nomCarr?.slice(0, 100) ?? '',
|
||||
});
|
||||
mapCarreraClave.set(carrera.clave, carrera);
|
||||
mapCarreraNom.set(carrera.carrera, carrera);
|
||||
}
|
||||
|
||||
// Tipo
|
||||
let tipo = mapTipo.get(r.tipo.trim());
|
||||
if (!tipo) {
|
||||
tipo = queryRunner.manager.create(TipoUsuario, {
|
||||
tipo_usuario: r.tipo.trim(),
|
||||
});
|
||||
mapTipo.set(r.tipo.trim(), tipo);
|
||||
}
|
||||
|
||||
const generacion =
|
||||
/^[0-9]{4}$/.test(r.gen?.toString().trim()) ?
|
||||
parseInt(r.gen.toString().trim(), 10) : null;
|
||||
|
||||
const usuario = queryRunner.manager.create(Usuario, {
|
||||
num_cuenta: r.cuenta,
|
||||
nombre: r.nombres,
|
||||
a_paterno: r.apellidopa,
|
||||
a_materno: r.apellidoma,
|
||||
rfc: r.rfc,
|
||||
fecha_nacimiento: r.fechnac,
|
||||
generacion,
|
||||
genero,
|
||||
movimiento,
|
||||
});
|
||||
|
||||
usuarios.push(usuario);
|
||||
|
||||
if (carrera) {
|
||||
const carreraUsuario = queryRunner.manager.create(CarreraUsuario, {
|
||||
usuario,
|
||||
carrera,
|
||||
});
|
||||
carrerasUsuario.push(carreraUsuario);
|
||||
}
|
||||
|
||||
usuariosTipos.push(
|
||||
queryRunner.manager.create(UsuarioTipoUsuario, {
|
||||
usuario,
|
||||
tipoUsuario: tipo,
|
||||
}),
|
||||
);
|
||||
|
||||
// Servicios activos
|
||||
const servData: Partial<ServActivos> = {
|
||||
usuario,
|
||||
RedStatus: 'Inactivo',
|
||||
ATStatus: 'Inactivo',
|
||||
CorreoStatus: 'Inactivo',
|
||||
PrestamosStatus: 'Inactivo',
|
||||
};
|
||||
|
||||
switch (r.tipo.trim()) {
|
||||
case 'Diplomado':
|
||||
Object.assign(servData, { Correo: true });
|
||||
conteoTiposCorreo[r.tipo] = (conteoTiposCorreo[r.tipo] ?? 0) + 1;
|
||||
break;
|
||||
case 'Extra Largo':
|
||||
Object.assign(servData, { Correo: true, Prestamos: true });
|
||||
conteoTiposCorreo[r.tipo] = (conteoTiposCorreo[r.tipo] ?? 0) + 1;
|
||||
conteoTiposSolicita[r.tipo] = (conteoTiposSolicita[r.tipo] ?? 0) + 1;
|
||||
break;
|
||||
case 'Servicio Social':
|
||||
Object.assign(servData, { Correo: true, AT: true, Red: true });
|
||||
conteoTiposCorreo[r.tipo] = (conteoTiposCorreo[r.tipo] ?? 0) + 1;
|
||||
conteoTiposAt[r.tipo] = (conteoTiposAt[r.tipo] ?? 0) + 1;
|
||||
conteoTiposRed[r.tipo] = (conteoTiposRed[r.tipo] ?? 0) + 1;
|
||||
break;
|
||||
case 'Idiomas R (UNAM)':
|
||||
case 'Idiomas Sabatino':
|
||||
Object.assign(servData, { Correo: true, Red: true });
|
||||
conteoTiposCorreo[r.tipo] = (conteoTiposCorreo[r.tipo] ?? 0) + 1;
|
||||
conteoTiposRed[r.tipo] = (conteoTiposRed[r.tipo] ?? 0) + 1;
|
||||
break;
|
||||
case 'Reinscrito':
|
||||
case 'Posgrado':
|
||||
case 'Intercambio UNAM':
|
||||
case 'Movilidad':
|
||||
case 'Ampliación de Conocimiento':
|
||||
case 'Licenciatura':
|
||||
case 'Profesor':
|
||||
Object.assign(servData, {
|
||||
Correo: true,
|
||||
AT: true,
|
||||
Red: true,
|
||||
Prestamos: true,
|
||||
});
|
||||
conteoTiposCorreo[r.tipo] = (conteoTiposCorreo[r.tipo] ?? 0) + 1;
|
||||
conteoTiposRed[r.tipo] = (conteoTiposRed[r.tipo] ?? 0) + 1;
|
||||
conteoTiposAt[r.tipo] = (conteoTiposAt[r.tipo] ?? 0) + 1;
|
||||
conteoTiposSolicita[r.tipo] = (conteoTiposSolicita[r.tipo] ?? 0) + 1;
|
||||
break;
|
||||
case 'Trabajadores':
|
||||
Object.assign(servData, { Red: true });
|
||||
conteoTiposRed[r.tipo] = (conteoTiposRed[r.tipo] ?? 0) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
serviciosActivos.push(queryRunner.manager.create(ServActivos, servData));
|
||||
}
|
||||
|
||||
// 🔹 4. Guardar en batch
|
||||
await queryRunner.manager.save([...mapGenero.values()]);
|
||||
await queryRunner.manager.save([...mapCarreraClave.values()]);
|
||||
await queryRunner.manager.save([...mapTipo.values()]);
|
||||
|
||||
await queryRunner.manager.save(usuarios);
|
||||
await queryRunner.manager.save(carrerasUsuario);
|
||||
await queryRunner.manager.save(usuariosTipos);
|
||||
await queryRunner.manager.save(serviciosActivos);
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
return {
|
||||
inserted: rows.length - contador,
|
||||
id_movimiento: movimiento.id_mov,
|
||||
errors: errs,
|
||||
conteoTiposAt,
|
||||
conteoTiposCorreo,
|
||||
conteoTiposRed,
|
||||
conteoTiposSolicita,
|
||||
};
|
||||
} catch (err) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
throw err;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -571,13 +637,10 @@ export class ExcelService {
|
||||
},
|
||||
servActivo: {
|
||||
RedStatus: 'Inactivo',
|
||||
Red: true, // solo los que tienen el servicio de red activo
|
||||
Red: true, // solo los que tienen el servicio de red
|
||||
}
|
||||
},
|
||||
relations: [
|
||||
'genero',
|
||||
'carreraUsuarios', // relación intermedia
|
||||
'carreraUsuarios.carrera', // carrera asociada a través de la intermedia
|
||||
'usuarioTipos',
|
||||
'usuarioTipos.tipoUsuario',
|
||||
],
|
||||
@@ -737,7 +800,7 @@ export class ExcelService {
|
||||
throw new BadRequestException('No se encontraron usuarios para enviar correo');
|
||||
}
|
||||
|
||||
// Aquí puedes enviar el correo usando MailService
|
||||
// Aquí puedes enviar el correo usnado MailService
|
||||
await this.mailService.sendMail({
|
||||
to: usuarios_red.correo ?? '',
|
||||
subject: 'Carga de Usuarios',
|
||||
@@ -756,12 +819,7 @@ export class ExcelService {
|
||||
text: 'Se ha realizado una carga de usuarios en el sistema.',
|
||||
html: '',
|
||||
});
|
||||
await this.mailService.sendMail({
|
||||
to: usuarios_solicita.correo ?? '',
|
||||
subject: 'Carga de Usuarios',
|
||||
text: 'Se ha realizado una carga de usuarios en el sistema.',
|
||||
html: '',
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -770,6 +828,24 @@ export class ExcelService {
|
||||
|
||||
|
||||
|
||||
async enviarInforme(origen:string, subject:string ,text:string, html:string = "" ):Promise<void>{
|
||||
const user = await this.usuariosDelSistemaRepo.find({where:{origen:{origen}}})
|
||||
|
||||
user.forEach(async(u)=>{
|
||||
await this.mailService.sendMail({
|
||||
to: u.correo ?? '',
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import * as crypto from "crypto";
|
||||
|
||||
// Hacer que esté disponible como global
|
||||
(global as any).crypto = crypto;
|
||||
|
||||
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { GlobalExceptionFilter } from './helpers/exception.filter';
|
||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
app.enableCors({ exposedHeaders: ['Content-Disposition'] });
|
||||
|
||||
@@ -460,11 +460,19 @@ export class UsuariosService {
|
||||
}
|
||||
}
|
||||
|
||||
let carrera = await queryRunner.manager.findOne(Carrera, { where: { carrera: usuario.carrera } });
|
||||
if (!carrera) {
|
||||
const nuevaCarrera = queryRunner.manager.create(Carrera, { carrera: usuario.carrera, clave: usuario.clave_carrera });
|
||||
carrera = await queryRunner.manager.save(nuevaCarrera);
|
||||
let carrera;
|
||||
if(usuario.carrera!=undefined){
|
||||
carrera = await queryRunner.manager.findOne(Carrera, { where: { carrera: usuario.carrera } });
|
||||
}else{
|
||||
carrera= await queryRunner.manager.findOne(Carrera, {where:{carrera: ""}})
|
||||
if(!carrera){
|
||||
const nuevaCarrera = queryRunner.manager.create(Carrera, { carrera: "", clave: "" });
|
||||
carrera = await queryRunner.manager.save(nuevaCarrera);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const nuevo = queryRunner.manager.create(Usuario, {
|
||||
@@ -480,6 +488,8 @@ export class UsuariosService {
|
||||
contraseña: usuario.contraseña ?? null, // Asegúrate de manejar la contraseña adecuadamente
|
||||
});
|
||||
|
||||
console.log(nuevo)
|
||||
|
||||
const savedUser = await queryRunner.manager.save(nuevo);
|
||||
|
||||
const userCarrera = queryRunner.manager.create(CarreraUsuario, { carrera, usuario: savedUser });
|
||||
@@ -622,6 +632,8 @@ export class UsuariosService {
|
||||
console.log(savedUser)
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
|
||||
|
||||
return { saved: savedUser, movId: mov.id_mov };
|
||||
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user