diff --git a/.delete.txt b/.delete.txt new file mode 100644 index 0000000..df7e0b5 --- /dev/null +++ b/.delete.txt @@ -0,0 +1,87 @@ +DROP TABLE IF EXISTS `recibo`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `recibo` ( + `id_recibo` int(11) NOT NULL AUTO_INCREMENT, + `folio_recibo` varchar(45) NOT NULL, + `monto` decimal(10,2) NOT NULL, + `fecha_recibo` date NOT NULL, + `fecha_registro` timestamp NOT NULL DEFAULT current_timestamp(), + `id_cuenta` int(9) unsigned zerofill NOT NULL, + `id_usuario` int(11) NOT NULL, + PRIMARY KEY (`id_recibo`), + KEY `fk_Credito_Alumno` (`id_cuenta`), + KEY `fk_Credito_Usuario1` (`id_usuario`), + CONSTRAINT `fk_Credito_Alumno` FOREIGN KEY (`id_cuenta`) REFERENCES `alumno` (`id_cuenta`) ON UPDATE CASCADE, + CONSTRAINT `fk_Credito_Usuario1` FOREIGN KEY (`id_usuario`) REFERENCES `usuario` (`id_usuario`) ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=120607 DEFAULT CHARSET=utf8mb3 COMMENT='Capturar todos los recibos que el alumno entregue'; +/*!40101 SET character_set_client = @saved_cs_client */; + +DROP TABLE IF EXISTS `carrera`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `carrera` ( + `id_carrera` int(11) NOT NULL, + `carrera` varchar(100) NOT NULL, + PRIMARY KEY (`id_carrera`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; +/*!40101 SET character_set_client = @saved_cs_client */; + + +DROP TABLE IF EXISTS `perfil`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `perfil` ( + `id_perfil` int(11) NOT NULL AUTO_INCREMENT, + `perfil` varchar(45) NOT NULL, + PRIMARY KEY (`id_perfil`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb3; +/*!40101 SET character_set_client = @saved_cs_client */; + +DROP TABLE IF EXISTS `detalle_servicio`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `detalle_servicio` ( + `id_detalle_servicio` int(11) NOT NULL AUTO_INCREMENT, + `monto` decimal(10,2) NOT NULL, + `numero_hojas` int(11) NOT NULL DEFAULT 0, + `fecha_operacion` timestamp NOT NULL DEFAULT current_timestamp(), + `id_cuenta` int(9) unsigned zerofill NOT NULL, + `id_servicio` int(11) NOT NULL, + `id_usuario` int(11) NOT NULL, + `id_periodo` int(11) DEFAULT NULL, + PRIMARY KEY (`id_detalle_servicio`), + KEY `index_DetalleIngresoEgreso_Servicio1` (`id_servicio`), + KEY `index_DetalleIngresoEgreso_Alumno1` (`id_cuenta`), + KEY `fk_DetalleServicio_usuario1` (`id_usuario`), + KEY `fk_detalle_servicio_periodo1` (`id_periodo`), + CONSTRAINT `fk_DetalleIngresoEgreso_Alumno1` FOREIGN KEY (`id_cuenta`) REFERENCES `alumno` (`id_cuenta`) ON UPDATE CASCADE, + CONSTRAINT `fk_DetalleIngresoEgreso_Servicio1` FOREIGN KEY (`id_servicio`) REFERENCES `servicio` (`id_servicio`) ON UPDATE CASCADE, + CONSTRAINT `fk_DetalleServicio_usuario1` FOREIGN KEY (`id_usuario`) REFERENCES `usuario` (`id_usuario`) ON UPDATE CASCADE, + CONSTRAINT `fk_detalle_servicio_periodo1` FOREIGN KEY (`id_periodo`) REFERENCES `periodo` (`id_periodo`) ON UPDATE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=167097 DEFAULT CHARSET=utf8mb3; +/*!40101 SET character_set_client = @saved_cs_client */; + + +DROP TABLE IF EXISTS `periodo`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `periodo` ( + `id_periodo` int(11) NOT NULL AUTO_INCREMENT, + `semestre` char(6) NOT NULL, + `fecha_inicio_servicio` date NOT NULL, + `fecha_fin_servicio` date NOT NULL, + `activo` bit(1) NOT NULL DEFAULT b'1' COMMENT 'cuando se cree un periodo nuevo todos los anteriores deben de quedar en 0, y el ultimo en 1.', + PRIMARY KEY (`id_periodo`) +) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb3; +/*!40101 SET character_set_client = @saved_cs_client */; + +DROP TABLE IF EXISTS `servicio`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `servicio` ( + `id_servicio` int(11) NOT NULL AUTO_INCREMENT, + `servicio` varchar(45) NOT NULL, + PRIMARY KEY (`id_servicio`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb3; +/*!40101 SET character_set_client = @saved_cs_client */; diff --git a/.gitignore b/.gitignore index 4b56acf..8e640ab 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,6 @@ pids # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +.delete.txt +.delete \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f0868c5..988623f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,16 @@ "@nestjs/common": "^11.0.1", "@nestjs/config": "^4.0.2", "@nestjs/core": "^11.0.1", + "@nestjs/jwt": "^11.0.0", "@nestjs/mapped-types": "*", + "@nestjs/passport": "^11.0.5", "@nestjs/platform-express": "^11.0.1", "@nestjs/typeorm": "^11.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.2", "mysql2": "^3.14.4", + "passport": "^0.7.0", + "passport-jwt": "^4.0.1", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", "typeorm": "^0.3.26" @@ -31,6 +35,7 @@ "@types/express": "^5.0.0", "@types/jest": "^30.0.0", "@types/node": "^22.18.1", + "@types/passport-jwt": "^4.0.1", "@types/supertest": "^6.0.2", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", @@ -2387,6 +2392,19 @@ } } }, + "node_modules/@nestjs/jwt": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.0.tgz", + "integrity": "sha512-v7YRsW3Xi8HNTsO+jeHSEEqelX37TVWgwt+BcxtkG/OfXJEOs6GZdbdza200d6KqId1pJQZ6UPj1F0M6E+mxaA==", + "license": "MIT", + "dependencies": { + "@types/jsonwebtoken": "9.0.7", + "jsonwebtoken": "9.0.2" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" + } + }, "node_modules/@nestjs/mapped-types": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", @@ -2407,6 +2425,16 @@ } } }, + "node_modules/@nestjs/passport": { + "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.6", "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.6.tgz", @@ -2861,6 +2889,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", + "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/methods": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", @@ -2879,12 +2916,43 @@ "version": "22.18.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.1.tgz", "integrity": "sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==", - "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, + "node_modules/@types/passport": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.17.tgz", + "integrity": "sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/passport-jwt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/passport-jwt/-/passport-jwt-4.0.1.tgz", + "integrity": "sha512-Y0Ykz6nWP4jpxgEUYq8NoVZeCQPo1ZndJLfapI249g1jHChvRfZRO/LS3tqu26YgAS/laI1qx98sYGz0IalRXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jsonwebtoken": "*", + "@types/passport-strategy": "*" + } + }, + "node_modules/@types/passport-strategy": { + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz", + "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@types/passport": "*" + } + }, "node_modules/@types/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", @@ -4241,6 +4309,12 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -4997,6 +5071,15 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -7432,6 +7515,49 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -7530,6 +7656,42 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7544,6 +7706,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -8258,6 +8426,42 @@ "node": ">= 0.8" } }, + "node_modules/passport": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", + "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", + "license": "MIT", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, + "node_modules/passport-jwt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.1.tgz", + "integrity": "sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ==", + "license": "MIT", + "dependencies": { + "jsonwebtoken": "^9.0.0", + "passport-strategy": "^1.0.0" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8333,6 +8537,11 @@ "node": ">=8" } }, + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -8877,7 +9086,6 @@ "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -10322,7 +10530,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "devOptional": true, "license": "MIT" }, "node_modules/universalify": { @@ -10426,6 +10633,15 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/uuid": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", diff --git a/package.json b/package.json index a6ba4ff..87b6d4c 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,16 @@ "@nestjs/common": "^11.0.1", "@nestjs/config": "^4.0.2", "@nestjs/core": "^11.0.1", + "@nestjs/jwt": "^11.0.0", "@nestjs/mapped-types": "*", + "@nestjs/passport": "^11.0.5", "@nestjs/platform-express": "^11.0.1", "@nestjs/typeorm": "^11.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.2", "mysql2": "^3.14.4", + "passport": "^0.7.0", + "passport-jwt": "^4.0.1", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", "typeorm": "^0.3.26" @@ -42,6 +46,7 @@ "@types/express": "^5.0.0", "@types/jest": "^30.0.0", "@types/node": "^22.18.1", + "@types/passport-jwt": "^4.0.1", "@types/supertest": "^6.0.2", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", diff --git a/src/Operations/dto/operations.dto.ts b/src/Operations/dto/operations.dto.ts new file mode 100644 index 0000000..2703fa4 --- /dev/null +++ b/src/Operations/dto/operations.dto.ts @@ -0,0 +1,18 @@ +import { IsInt, IsNotEmpty, Min } from "class-validator"; + +export class chargePrintDto { + + @IsInt() + @IsNotEmpty() + @Min(1) + monto:number + + @IsInt() + @Min(1) + @IsNotEmpty() + numero_hojas: number; + + @IsInt() + @IsNotEmpty() + id_cuenta: number; +} diff --git a/src/Operations/operations.controller.ts b/src/Operations/operations.controller.ts new file mode 100644 index 0000000..2b18dca --- /dev/null +++ b/src/Operations/operations.controller.ts @@ -0,0 +1,12 @@ +import { Body, Controller, Post } from "@nestjs/common"; +import { OperationsService } from "./operations.services"; + +@Controller('operations') +export class OperationsController{ + constructor(private readonly operationsService:OperationsService){} + + @Post() + async Login(@Body() data) { + return this.operationsService.chargePrint(data,data.userid); + } +} \ No newline at end of file diff --git a/src/Operations/operations.module.ts b/src/Operations/operations.module.ts new file mode 100644 index 0000000..84e1ba9 --- /dev/null +++ b/src/Operations/operations.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Student } from 'src/alumno/entities/student.entity'; +import { DetalleServicio } from 'src/detalle_servicio/entities/detalle_servicio.entity'; +import { OperationsController } from './operations.controller'; +import { OperationsService } from './operations.services'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Student, DetalleServicio]), // entidades que usarán las transacciones + ], + controllers: [OperationsController], + providers: [OperationsService], +}) +export class OperationsModule {} diff --git a/src/Operations/operations.services.ts b/src/Operations/operations.services.ts new file mode 100644 index 0000000..e609e3d --- /dev/null +++ b/src/Operations/operations.services.ts @@ -0,0 +1,54 @@ +import { BadRequestException, Injectable } from '@nestjs/common'; +import { StudentService } from 'src/alumno/student.service'; +import { DetalleServicioService } from 'src/detalle_servicio/detalle_servicio.service'; +import { DataSource } from 'typeorm'; +import { chargePrintDto } from './dto/operations.dto'; +import { CreateDetalleServicioDto } from 'src/detalle_servicio/dto/create-detalle_servicio.dto'; + +@Injectable() +export class OperationsService { + constructor( + private readonly dataSource: DataSource, + private readonly studentService: StudentService, + private readonly detalleServicioService: DetalleServicioService, + ) {} + + async chargePrint(data: chargePrintDto, userId: number) { + const { monto, id_cuenta } = data; + + const queryRunner = this.dataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + + try { + const credit = await this.studentService.GetCredit(id_cuenta); + + if (credit < monto) { + throw new BadRequestException('Crédito insuficiente'); + } + + const detalleData: CreateDetalleServicioDto = { + ...data, + id_servicio: 1, + id_usuario: userId, + fecha_operacion: new Date(), + }; + + await this.detalleServicioService.Create(detalleData, queryRunner.manager); + + await this.studentService.UpdateCredit( + id_cuenta, + monto, + queryRunner.manager, + ); + + await queryRunner.commitTransaction(); + return { message: 'correct' }; + } catch (error) { + await queryRunner.rollbackTransaction(); + return { message: 'error', error: error.message }; + } finally { + await queryRunner.release(); + } + } +} diff --git a/src/alumno/dto/create-student.dto.ts b/src/alumno/dto/create-student.dto.ts new file mode 100644 index 0000000..c26edfd --- /dev/null +++ b/src/alumno/dto/create-student.dto.ts @@ -0,0 +1,23 @@ + +import { IsEmail, IsNotEmpty, IsNumber, IsString } from 'class-validator'; + +export class CreateStudentDto { + @IsNotEmpty() + @IsNumber() + id_cuenta: number; + + @IsNotEmpty() + @IsString() + nombre: string; + + @IsString() + fecha_nacimiento: string; + + @IsNotEmpty() + @IsNumber() + id_carrera: number; + + @IsEmail() + @IsString() + correo: string; +} diff --git a/src/student/dto/update-student.dto.ts b/src/alumno/dto/update-student.dto.ts similarity index 100% rename from src/student/dto/update-student.dto.ts rename to src/alumno/dto/update-student.dto.ts diff --git a/src/alumno/entities/student.entity.ts b/src/alumno/entities/student.entity.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/alumno/student.controller.ts b/src/alumno/student.controller.ts new file mode 100644 index 0000000..d064281 --- /dev/null +++ b/src/alumno/student.controller.ts @@ -0,0 +1,30 @@ +import { + Controller, + Get, + Post, + Body, + Param, +} from '@nestjs/common'; +import { StudentService } from './student.service'; +import { CreateStudentDto } from './dto/create-student.dto'; +import { Student } from './entities/student.entity'; + +@Controller('student') +export class StudentController { + constructor(private readonly studentService: StudentService) {} + + @Post() + async create(@Body() createStudentDto: CreateStudentDto): Promise { + return this.studentService.create(createStudentDto); + } + + @Get() + async findAll(): Promise { + return this.studentService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: number) { + return this.studentService.findOne(+id); + } +} diff --git a/src/student/student.module.ts b/src/alumno/student.module.ts similarity index 100% rename from src/student/student.module.ts rename to src/alumno/student.module.ts diff --git a/src/alumno/student.service.ts b/src/alumno/student.service.ts new file mode 100644 index 0000000..236d15d --- /dev/null +++ b/src/alumno/student.service.ts @@ -0,0 +1,52 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { CreateStudentDto } from './dto/create-student.dto'; +import { UpdateStudentDto } from './dto/update-student.dto'; +import { Student } from './entities/student.entity'; +import { EntityManager, Repository } from 'typeorm'; +import { InjectRepository } from '@nestjs/typeorm'; + +@Injectable() +export class StudentService { + constructor( + @InjectRepository(Student) + private readonly studentRepository: Repository, + ) {} + + async create(createStudentDto: CreateStudentDto): Promise { + const student = this.studentRepository.create(createStudentDto); + return await this.studentRepository.save(student); + } + + findAll(): Promise { + return this.studentRepository.find({ skip: 5000, take: 50 }); + } + + async findOne(id_cuenta: number): Promise { + const student = await this.studentRepository.findOne({ + where: { id_cuenta }, + }); + if (!student) { + throw new NotFoundException(`Student with ID ${id_cuenta} not found`); + } + return student; + } + + async GetCredit(id_cuenta: number): Promise { + const student = await this.findOne(id_cuenta); + return student.credito; + } + + async UpdateCredit( + id_cuenta: number, + credit: number, + manager: EntityManager, + ) { + const repo = manager.getRepository(Student); + return await repo + .createQueryBuilder() + .update() + .set({ credito: () => `credito - ${credit}` }) + .where({ id_cuenta }) + .execute(); + } +} diff --git a/src/app.module.ts b/src/app.module.ts index facbc4a..11f7867 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -3,11 +3,16 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { StudentModule } from './student/student.module'; +import { StudentModule } from './alumno/student.module'; import { UserModule } from './user/user.module'; -import { User } from './user/entities/user.entity'; -import { Student } from './student/entities/student.entity'; -import { TicketModule } from './ticket/ticket.module'; +import { Perfil, User } from './user/entities/user.entity'; +import { DetalleServicioModule } from './detalle_servicio/detalle_servicio.module'; +import { PeriodoModule } from './periodo/periodo.module'; +import { ServicioModule } from './servicio/servicio.module'; +import { Student } from './alumno/entities/student.entity'; +import { DetalleServicio } from './detalle_servicio/entities/detalle_servicio.entity'; +import { Periodo } from './periodo/entities/periodo.entity'; +import { Servicio } from './servicio/entities/servicio.entity'; @Module({ imports: [ @@ -24,13 +29,16 @@ import { TicketModule } from './ticket/ticket.module'; username: configService.get('DB_USER'), password: configService.get('DB_PASSWORD'), database: configService.get('DB_NAME'), - entities: [User, Student], - synchronize: false, + entities: [User, Student, DetalleServicio, Periodo, Servicio, Perfil], + synchronize: false, //Never change to true in production! }), }), UserModule, StudentModule, - TicketModule, + DetalleServicioModule, + PeriodoModule, + ServicioModule, + StudentModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/detalle_servicio/detalle_servicio.controller.ts b/src/detalle_servicio/detalle_servicio.controller.ts new file mode 100644 index 0000000..b804907 --- /dev/null +++ b/src/detalle_servicio/detalle_servicio.controller.ts @@ -0,0 +1,9 @@ +import { Controller } from '@nestjs/common'; +import { DetalleServicioService } from './detalle_servicio.service'; + + +@Controller('detalle-servicio') +export class DetalleServicioController { + constructor(private readonly detalleServicioService: DetalleServicioService) {} + +} diff --git a/src/detalle_servicio/detalle_servicio.module.ts b/src/detalle_servicio/detalle_servicio.module.ts new file mode 100644 index 0000000..392fb3c --- /dev/null +++ b/src/detalle_servicio/detalle_servicio.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { DetalleServicioService } from './detalle_servicio.service'; +import { DetalleServicioController } from './detalle_servicio.controller'; + +@Module({ + controllers: [DetalleServicioController], + providers: [DetalleServicioService], +}) +export class DetalleServicioModule {} diff --git a/src/detalle_servicio/detalle_servicio.service.ts b/src/detalle_servicio/detalle_servicio.service.ts new file mode 100644 index 0000000..ea6b477 --- /dev/null +++ b/src/detalle_servicio/detalle_servicio.service.ts @@ -0,0 +1,13 @@ +import { Injectable } from '@nestjs/common'; +import { DetalleServicio } from './entities/detalle_servicio.entity'; +import { EntityManager } from 'typeorm'; +import { CreateDetalleServicioDto } from './dto/create-detalle_servicio.dto'; + +@Injectable() +export class DetalleServicioService { + async Create(data: CreateDetalleServicioDto, manager: EntityManager) { + const repo = manager.getRepository(DetalleServicio); + const details = repo.create(data); + return await repo.save(details); + } +} diff --git a/src/detalle_servicio/dto/create-detalle_servicio.dto.ts b/src/detalle_servicio/dto/create-detalle_servicio.dto.ts new file mode 100644 index 0000000..9dc2a64 --- /dev/null +++ b/src/detalle_servicio/dto/create-detalle_servicio.dto.ts @@ -0,0 +1,32 @@ +import { Type } from 'class-transformer'; +import { IsDate, IsIn, IsInt, IsNotEmpty, IsOptional, Min } from 'class-validator'; + +export class CreateDetalleServicioDto { + + @IsInt() + @IsNotEmpty() + @Min(1) + monto:number + + @IsInt() + @Min(1) + @IsNotEmpty() + numero_hojas: number; + + @IsOptional() + @Type(() => Date) + @IsDate() + fecha_operacion?: Date; + + @IsInt() + @IsNotEmpty() + id_cuenta: number; + + @IsInt() + @IsNotEmpty() + id_servicio: number; + + @IsInt() + @IsNotEmpty() + id_usuario: number; +} diff --git a/src/detalle_servicio/dto/update-detalle_servicio.dto.ts b/src/detalle_servicio/dto/update-detalle_servicio.dto.ts new file mode 100644 index 0000000..d50fec8 --- /dev/null +++ b/src/detalle_servicio/dto/update-detalle_servicio.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateDetalleServicioDto } from './create-detalle_servicio.dto'; + +export class UpdateDetalleServicioDto extends PartialType(CreateDetalleServicioDto) {} diff --git a/src/detalle_servicio/entities/detalle_servicio.entity.ts b/src/detalle_servicio/entities/detalle_servicio.entity.ts new file mode 100644 index 0000000..e6691f3 --- /dev/null +++ b/src/detalle_servicio/entities/detalle_servicio.entity.ts @@ -0,0 +1,42 @@ +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity({ name: 'detalle_servicio' }) +export class DetalleServicio { + @PrimaryGeneratedColumn({ + name: 'id_detalle_servicio', + type: 'int', + unsigned: true, + }) + id_detalle_servicio: number; + + @Column('decimal', { + name: 'monto', + precision: 10, + scale: 2, + nullable: false, + }) + monto: number; + + @Column({ name: 'numero_hojas', type: 'int', nullable: false, default: 0 }) + numero_hojas: number; + + @Column({ + name: 'fecha_operacion', + type: 'timestamp', + default: () => 'CURRENT_TIMESTAMP', + nullable: false, + }) + fecha_operacion: Date; + + @Column({ name: 'id_cuenta', type: 'int', nullable: false }) + id_cuenta: number; + + @Column({ name: 'id_servicio', type: 'int', nullable: false }) + id_servicio: number; + + @Column({ name: 'id_usuario', type: 'int', nullable: false }) + id_usuario: number; + + @Column({ name: 'id_perido', type: 'int', default: null }) + id_periodo: number; +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 27f66be..be77c31 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +1,20 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; async function bootstrap() { const app = await NestFactory.create(AppModule); + const configService = app.get(ConfigService); + app.useGlobalPipes(new ValidationPipe()); - app.enableCors(); + + app.enableCors( + { + origin: configService.get('Front_URL'), + } +); + await app.listen(process.env.PORT ?? 3000); } bootstrap(); diff --git a/src/periodo/dto/create-periodo.dto.ts b/src/periodo/dto/create-periodo.dto.ts new file mode 100644 index 0000000..ea24c49 --- /dev/null +++ b/src/periodo/dto/create-periodo.dto.ts @@ -0,0 +1,23 @@ +import { + IsString, + Length, + IsDateString, + IsOptional, + IsBoolean, +} from 'class-validator'; + +export class CreatePeriodoDto { + @IsString() + @Length(6, 6) + semestre: string; + + @IsDateString() + fecha_inicio_servicio: string; + + @IsDateString() + fecha_fin_servicio: string; + + @IsOptional() + @IsBoolean() + activo?: boolean; +} diff --git a/src/periodo/dto/periodo.dto.ts b/src/periodo/dto/periodo.dto.ts new file mode 100644 index 0000000..b91e65e --- /dev/null +++ b/src/periodo/dto/periodo.dto.ts @@ -0,0 +1,7 @@ +export class PeriodoDto { + id_periodo: number; + semestre: string; + fecha_inicio_servicio: Date; + fecha_fin_servicio: Date; + activo: boolean; +} diff --git a/src/periodo/dto/update-periodo.dto.ts b/src/periodo/dto/update-periodo.dto.ts new file mode 100644 index 0000000..994f395 --- /dev/null +++ b/src/periodo/dto/update-periodo.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreatePeriodoDto } from './create-periodo.dto'; + +export class UpdatePeriodoDto extends PartialType(CreatePeriodoDto) {} diff --git a/src/periodo/entities/periodo.entity.ts b/src/periodo/entities/periodo.entity.ts new file mode 100644 index 0000000..3218596 --- /dev/null +++ b/src/periodo/entities/periodo.entity.ts @@ -0,0 +1,23 @@ +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity({ name: 'periodo' }) +export class Periodo { + @PrimaryGeneratedColumn({ name: 'id_periodo', type: 'int' }) + id_periodo: number; + + @Column({ type: 'char', length: 6, nullable: false }) + semestre: string; + + @Column({ name: 'fecha_inicio_servicio', type: 'date', nullable: false }) + fecha_inicio_servicio: Date; + + @Column({ name: 'fecha_fin_servicio', type: 'date', nullable: false }) + fecha_fin_servicio: Date; + + @Column({ + type: 'bit', + width: 1, + default: () => "b'1'", + }) + activo: boolean; +} diff --git a/src/periodo/periodo.controller.ts b/src/periodo/periodo.controller.ts new file mode 100644 index 0000000..c6a72c6 --- /dev/null +++ b/src/periodo/periodo.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { PeriodoService } from './periodo.service'; +import { CreatePeriodoDto } from './dto/create-periodo.dto'; +import { UpdatePeriodoDto } from './dto/update-periodo.dto'; + +@Controller('periodo') +export class PeriodoController { + constructor(private readonly periodoService: PeriodoService) {} + + @Post() + create(@Body() createPeriodoDto: CreatePeriodoDto) { + return this.periodoService.create(createPeriodoDto); + } + + @Get() + findAll() { + return this.periodoService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.periodoService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updatePeriodoDto: UpdatePeriodoDto) { + return this.periodoService.update(+id, updatePeriodoDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.periodoService.remove(+id); + } +} diff --git a/src/periodo/periodo.module.ts b/src/periodo/periodo.module.ts new file mode 100644 index 0000000..8834bac --- /dev/null +++ b/src/periodo/periodo.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { PeriodoService } from './periodo.service'; +import { PeriodoController } from './periodo.controller'; + +@Module({ + controllers: [PeriodoController], + providers: [PeriodoService], +}) +export class PeriodoModule {} diff --git a/src/periodo/periodo.service.ts b/src/periodo/periodo.service.ts new file mode 100644 index 0000000..b808232 --- /dev/null +++ b/src/periodo/periodo.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@nestjs/common'; +import { CreatePeriodoDto } from './dto/create-periodo.dto'; +import { UpdatePeriodoDto } from './dto/update-periodo.dto'; + +@Injectable() +export class PeriodoService { + create(createPeriodoDto: CreatePeriodoDto) { + return 'This action adds a new periodo'; + } + + findAll() { + return `This action returns all periodo`; + } + + findOne(id: number) { + return `This action returns a #${id} periodo`; + } + + update(id: number, updatePeriodoDto: UpdatePeriodoDto) { + return `This action updates a #${id} periodo`; + } + + remove(id: number) { + return `This action removes a #${id} periodo`; + } +} diff --git a/src/servicio/dto/create-servicio.dto.ts b/src/servicio/dto/create-servicio.dto.ts new file mode 100644 index 0000000..d130367 --- /dev/null +++ b/src/servicio/dto/create-servicio.dto.ts @@ -0,0 +1,7 @@ +import { IsString, MaxLength } from 'class-validator'; + +export class CreateServicioDto { + @IsString() + @MaxLength(45) + servicio: string; +} diff --git a/src/servicio/dto/servicio.dto.ts b/src/servicio/dto/servicio.dto.ts new file mode 100644 index 0000000..4d68631 --- /dev/null +++ b/src/servicio/dto/servicio.dto.ts @@ -0,0 +1,4 @@ +export class ServicioDto { + id_servicio: number; + servicio: string; +} diff --git a/src/servicio/dto/update-servicio.dto.ts b/src/servicio/dto/update-servicio.dto.ts new file mode 100644 index 0000000..c830b2d --- /dev/null +++ b/src/servicio/dto/update-servicio.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateServicioDto } from './create-servicio.dto'; + +export class UpdateServicioDto extends PartialType(CreateServicioDto) {} diff --git a/src/servicio/entities/servicio.entity.ts b/src/servicio/entities/servicio.entity.ts new file mode 100644 index 0000000..bc1d060 --- /dev/null +++ b/src/servicio/entities/servicio.entity.ts @@ -0,0 +1,10 @@ +import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; + +@Entity({ name: 'servicio' }) +export class Servicio { + @PrimaryGeneratedColumn({ name: 'id_servicio', type: 'int' }) + id_servicio: number; + + @Column({ type: 'varchar', length: 45, nullable: false }) + servicio: string; +} diff --git a/src/servicio/servicio.controller.ts b/src/servicio/servicio.controller.ts new file mode 100644 index 0000000..3bed5e5 --- /dev/null +++ b/src/servicio/servicio.controller.ts @@ -0,0 +1,35 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { ServicioService } from './servicio.service'; +import { CreateServicioDto } from './dto/create-servicio.dto'; +import { UpdateServicioDto } from './dto/update-servicio.dto'; + +@Controller('servicio') +export class ServicioController { + constructor(private readonly servicioService: ServicioService) {} + + @Post() + create(@Body() createServicioDto: CreateServicioDto) { + return this.servicioService.create(createServicioDto); + } + + @Get() + findAll() { + return this.servicioService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.servicioService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateServicioDto: UpdateServicioDto) { + return this.servicioService.update(+id, updateServicioDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.servicioService.remove(+id); + } +} +//IO \ No newline at end of file diff --git a/src/servicio/servicio.module.ts b/src/servicio/servicio.module.ts new file mode 100644 index 0000000..7c691f3 --- /dev/null +++ b/src/servicio/servicio.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { ServicioService } from './servicio.service'; +import { ServicioController } from './servicio.controller'; + +@Module({ + controllers: [ServicioController], + providers: [ServicioService], +}) +export class ServicioModule {} diff --git a/src/servicio/servicio.service.ts b/src/servicio/servicio.service.ts new file mode 100644 index 0000000..7d7bd27 --- /dev/null +++ b/src/servicio/servicio.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@nestjs/common'; +import { CreateServicioDto } from './dto/create-servicio.dto'; +import { UpdateServicioDto } from './dto/update-servicio.dto'; + +@Injectable() +export class ServicioService { + create(createServicioDto: CreateServicioDto) { + return 'This action adds a new servicio'; + } + + findAll() { + return `This action returns all servicio`; + } + + findOne(id: number) { + return `This action returns a #${id} servicio`; + } + + update(id: number, updateServicioDto: UpdateServicioDto) { + return `This action updates a #${id} servicio`; + } + + remove(id: number) { + return `This action removes a #${id} servicio`; + } +} diff --git a/src/student/dto/create-student.dto.ts b/src/student/dto/create-student.dto.ts deleted file mode 100644 index b8fcadd..0000000 --- a/src/student/dto/create-student.dto.ts +++ /dev/null @@ -1 +0,0 @@ -export class CreateStudentDto {} diff --git a/src/student/dto/student.dto.ts b/src/student/dto/student.dto.ts deleted file mode 100644 index 0abde95..0000000 --- a/src/student/dto/student.dto.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IsNumber, IsString } from 'class-validator'; - -export class studentDto { - @IsNumber() - id_cuenta: number; -} diff --git a/src/student/entities/student.entity.ts b/src/student/entities/student.entity.ts deleted file mode 100644 index a375e94..0000000 --- a/src/student/entities/student.entity.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; - -@Entity({ name: 'alumno' }) -export class Student { - @PrimaryGeneratedColumn({ name: 'id_cuenta', type: 'int', unsigned: true }) - id_cuenta: number; - - @Column({ name: 'nombre', type: 'varchar', length: 300, nullable: false }) - nombre: string; - - @Column({ - name: 'fecha_nacimiento', - type: 'varchar', - length: 8, - nullable: true, - }) - fecha_nacimiento: string | null; - - @Column({ name: 'correo', type: 'varchar', length: 100, nullable: true }) - correo: string | null; - - @Column({ - name: 'credito', - type: 'decimal', - precision: 10, - scale: 2, - default: 0.0, - }) - credito: string; - - @Column({ - name: 'fecha_actualizacion_credito', - type: 'timestamp', - default: () => 'CURRENT_TIMESTAMP', - onUpdate: 'CURRENT_TIMESTAMP', - }) - fecha_actualizacion_credito: Date; - - @Column({ - name: 'vigente', - type: 'enum', - enum: ['si', 'no'], - default: 'si', - }) - vigente: 'si' | 'no'; - - @Column({ name: 'id_periodo', type: 'int', nullable: true }) - id_periodo: number | null; - - @Column({ name: 'fecha_registro', type: 'datetime', nullable: false }) - fecha_registro: Date; - - @Column({ name: 'id_carrera', type: 'int', nullable: false }) - id_carrera: number; - - @Column({ name: 'generacion', type: 'int', width: 4, nullable: true }) - generacion: number | null; -} diff --git a/src/student/student.controller.ts b/src/student/student.controller.ts deleted file mode 100644 index 4e2d1e9..0000000 --- a/src/student/student.controller.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - Controller, - Get, - Post, - Body, - Patch, - Param, - Delete, -} from '@nestjs/common'; -import { StudentService } from './student.service'; -import { CreateStudentDto } from './dto/create-student.dto'; -import { UpdateStudentDto } from './dto/update-student.dto'; -import { studentDto } from './dto/student.dto'; - -@Controller('student') -export class StudentController { - constructor(private readonly studentService: StudentService) {} - - @Post() - create(@Body() data: studentDto) { - return this.studentService.findOne(data); - } -} diff --git a/src/student/student.service.ts b/src/student/student.service.ts deleted file mode 100644 index 1c862f9..0000000 --- a/src/student/student.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { CreateStudentDto } from './dto/create-student.dto'; -import { UpdateStudentDto } from './dto/update-student.dto'; -import { studentDto } from './dto/student.dto'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Student } from './entities/student.entity'; -import { Repository } from 'typeorm'; - -@Injectable() -export class StudentService { - constructor( - @InjectRepository(Student) - private studenRepository: Repository, - ) {} - findOne(data: studentDto) { - const { id_cuenta } = data; - return this.studenRepository.findOne({ where: { id_cuenta } }); - } -} diff --git a/src/user/jwt.strategy.ts b/src/user/jwt.strategy.ts new file mode 100644 index 0000000..ba6d3ae --- /dev/null +++ b/src/user/jwt.strategy.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@nestjs/common'; +import { PassportStrategy } from '@nestjs/passport'; +import { ExtractJwt, Strategy } from 'passport-jwt'; +import { UserService } from './user.service'; +import { ConfigService } from '@nestjs/config'; + +@Injectable() +export class JwtStrategy extends PassportStrategy(Strategy) { + constructor(private configService: ConfigService) { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + ignoreExpiration: false, + secretOrKey: configService.get('JWT_SECRET')!, + }); + } + + async validate(payload: any) { + return { userId: payload.id, username: payload.usuario }; + } +} diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index 2c733ad..37bab3d 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -1,15 +1,30 @@ -import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { + Controller, + Get, + Post, + Body, + UseGuards, + Request, + Res, +} from '@nestjs/common'; +import type { Response } from 'express'; import { UserService } from './user.service'; import { CreateUserDto } from './dto/create-user.dto'; -import { UpdateUserDto } from './dto/update-user.dto'; +import { AuthGuard } from '@nestjs/passport'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @Post() - Login(@Body() user: CreateUserDto) { - return this.userService.Login(user); + async Login(@Body() data: CreateUserDto, @Res() res: Response) { + return this.userService.Login(data, res); + } + + @UseGuards(AuthGuard('jwt')) + @Get('/validate-token') + getProfile(@Request() req) { + return req.user; } - } +//IO diff --git a/src/user/user.module.ts b/src/user/user.module.ts index 55bce57..ecbeb79 100644 --- a/src/user/user.module.ts +++ b/src/user/user.module.ts @@ -3,13 +3,29 @@ import { UserService } from './user.service'; import { UserController } from './user.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from './entities/user.entity'; +import { ConfigService } from '@nestjs/config'; +import { JwtModule } from '@nestjs/jwt'; +import { PassportModule } from '@nestjs/passport'; +import { JwtStrategy } from './jwt.strategy'; @Module({ - imports:[ - TypeOrmModule.forFeature([User]) + imports: [ + TypeOrmModule.forFeature([User]), + PassportModule.register({ defaultStrategy: 'jwt' }), + JwtModule.registerAsync({ + inject: [ConfigService], + useFactory: async (configService: ConfigService) => { + return { + global: true, + secret: configService.get('JWT_SECRET'), + signOptions: { expiresIn: '1h' }, + }; + }, + + }), ], controllers: [UserController], - providers: [UserService], + providers: [UserService,JwtStrategy], exports: [UserService], }) -export class UserModule {} +export class UserModule { } diff --git a/src/user/user.service.ts b/src/user/user.service.ts index 0c22671..c65627c 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -1,14 +1,10 @@ -import { - Injectable, - Logger, - NotFoundException, - UnauthorizedException, -} from '@nestjs/common'; +import { Injectable, NotFoundException } from '@nestjs/common'; +import { Response } from 'express'; import { CreateUserDto } from './dto/create-user.dto'; -import { UpdateUserDto } from './dto/update-user.dto'; import { InjectRepository } from '@nestjs/typeorm'; import { User } from './entities/user.entity'; import { Repository } from 'typeorm'; +import { JwtService } from '@nestjs/jwt'; @Injectable() export class UserService { @@ -32,6 +28,7 @@ export class UserService { } async Login(data: CreateUserDto) { - return await this.findOneByNameandPassword(data); + const user = await this.findOneByNameandPassword(data); + return user; } }