From aada9d8299b0a9f287a16fce3aa9434d61885e80 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 22 Apr 2024 18:39:55 -0400 Subject: [PATCH 01/27] patch: orden de archivos de test * Se ordenan archivos de pruebas wip: trabajo en arreglar el login de academia --- .pnp.cjs | 43 +++++++++++++++ package.json | 1 + src/academia/services/auth.service.ts | 4 +- test/auth.test.ts | 56 ++++++++++++++++++++ test/{endpoints.test.ts => carreras.test.ts} | 51 +----------------- yarn.lock | 36 +++++++++++++ 6 files changed, 140 insertions(+), 51 deletions(-) create mode 100644 test/auth.test.ts rename test/{endpoints.test.ts => carreras.test.ts} (58%) diff --git a/.pnp.cjs b/.pnp.cjs index 02675f8..b22bb07 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -33,6 +33,7 @@ const RAW_RUNTIME_STATE = ["@types/jsonwebtoken", "npm:9.0.6"],\ ["@types/morgan", "npm:1.9.9"],\ ["@types/random-useragent", "npm:0.3.3"],\ + ["@types/supertest", "npm:6.0.2"],\ ["atob", "npm:2.1.2"],\ ["axios", "npm:1.6.7"],\ ["body-parser", "npm:1.20.2"],\ @@ -4255,6 +4256,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@types/cookiejar", [\ + ["npm:2.1.5", {\ + "packageLocation": "./.yarn/cache/@types-cookiejar-npm-2.1.5-f36531e52d-04d5990e87.zip/node_modules/@types/cookiejar/",\ + "packageDependencies": [\ + ["@types/cookiejar", "npm:2.1.5"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@types/cors", [\ ["npm:2.8.13", {\ "packageLocation": "./.yarn/cache/@types-cors-npm-2.8.13-4b8ac1068f-7ef197ea19.zip/node_modules/@types/cors/",\ @@ -4427,6 +4437,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@types/methods", [\ + ["npm:1.1.4", {\ + "packageLocation": "./.yarn/cache/@types-methods-npm-1.1.4-8565dc8af4-ad2a717848.zip/node_modules/@types/methods/",\ + "packageDependencies": [\ + ["@types/methods", "npm:1.1.4"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@types/mime", [\ ["npm:1.3.2", {\ "packageLocation": "./.yarn/cache/@types-mime-npm-1.3.2-ea71878ab3-0493368244.zip/node_modules/@types/mime/",\ @@ -4550,6 +4569,29 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@types/superagent", [\ + ["npm:8.1.6", {\ + "packageLocation": "./.yarn/cache/@types-superagent-npm-8.1.6-263a072803-d21913bfe6.zip/node_modules/@types/superagent/",\ + "packageDependencies": [\ + ["@types/superagent", "npm:8.1.6"],\ + ["@types/cookiejar", "npm:2.1.5"],\ + ["@types/methods", "npm:1.1.4"],\ + ["@types/node", "npm:20.4.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@types/supertest", [\ + ["npm:6.0.2", {\ + "packageLocation": "./.yarn/cache/@types-supertest-npm-6.0.2-1f239669e4-4b67fb2d1b.zip/node_modules/@types/supertest/",\ + "packageDependencies": [\ + ["@types/supertest", "npm:6.0.2"],\ + ["@types/methods", "npm:1.1.4"],\ + ["@types/superagent", "npm:8.1.6"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@types/triple-beam", [\ ["npm:1.3.2", {\ "packageLocation": "./.yarn/cache/@types-triple-beam-npm-1.3.2-e1699700a8-dd7b4a563f.zip/node_modules/@types/triple-beam/",\ @@ -10284,6 +10326,7 @@ const RAW_RUNTIME_STATE = ["@types/jsonwebtoken", "npm:9.0.6"],\ ["@types/morgan", "npm:1.9.9"],\ ["@types/random-useragent", "npm:0.3.3"],\ + ["@types/supertest", "npm:6.0.2"],\ ["atob", "npm:2.1.2"],\ ["axios", "npm:1.6.7"],\ ["body-parser", "npm:1.20.2"],\ diff --git a/package.json b/package.json index b98e319..63a1e00 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@types/jest": "^29.5.12", "@types/jsonwebtoken": "^9.0.6", "@types/random-useragent": "^0.3.3", + "@types/supertest": "^6.0.2", "cross-env": "^7.0.3", "jest": "^29.7.0", "nodemon": "^3.1.0", diff --git a/src/academia/services/auth.service.ts b/src/academia/services/auth.service.ts index 3d57d04..cf13a00 100644 --- a/src/academia/services/auth.service.ts +++ b/src/academia/services/auth.service.ts @@ -7,7 +7,7 @@ import { KeycloakUserService } from "../../keycloak/services/user.service"; export class AcademiaUserService { public static async loginAndGetCookies(correo: string, contrasenia: string): Promise { - const academiaIssuer = await Issuer.discover(`${process.env.SSO_UTEM_URL}/auth/realms/utem`) + const academiaIssuer = await Issuer.discover(`${process.env.SSO_UTEM_URL}/auth/realms/prod`) const client = new academiaIssuer.Client({ // Genera un link cliente para el flujo de autorización. client_id: 'academiaClient', client_secret: process.env.ACADEMIA_CLIENT_SECRET, @@ -38,7 +38,7 @@ export class AcademiaUserService { message: 'Error al obtener el token de autorización de academia.', uri: oauthUri, loginResponse: loginResponse.headers.location, - error, + error: error.response?.data || error.response || error, } throw err } diff --git a/test/auth.test.ts b/test/auth.test.ts new file mode 100644 index 0000000..f74897f --- /dev/null +++ b/test/auth.test.ts @@ -0,0 +1,56 @@ +import {describe, expect} from '@jest/globals'; +import request from 'supertest'; +import {server} from '../src/app'; + +const correo = process.env.USER_EMAIL || ""; +const contrasenia = process.env.USER_PASSWORD || ""; + +describe('Prueba de Inicio de Sesión', () => { + it('Inicio de Sesión con @utem.cl', async () => { + const res = await request(server.app) + .post('/v1/auth') + .send({ + correo: correo, + contrasenia: contrasenia + }) + expect(res.statusCode).toEqual(200) + expect(res.body).toHaveProperty('token') + }, 25000) + + it('Inicio de sesión sin @utem.cl', async () => { + const res = await request(server.app) + .post('/v1/auth') + .send({ + correo: correo.replace("@utem.cl", ""), + contrasenia: contrasenia + }) + expect(res.statusCode).toEqual(200) + expect(res.body).toHaveProperty('token') + }, 25000) + + it('Correo Incorrecto', async () => { + const res = await request(server.app) + .post('/v1/auth') + .send({ + correo: "a" + correo, + contrasenia: contrasenia + }) + expect(res.statusCode).toEqual(403) + }) + + it('Contraseña Incorrecta', async () => { + const res = await request(server.app) + .post('/v1/auth') + .send({ + correo: correo, + contrasenia: contrasenia + "a" + }) + expect(res.statusCode).toEqual(403) + }) +}); + + +afterAll(done => { + server.close(); + done(); +}) diff --git a/test/endpoints.test.ts b/test/carreras.test.ts similarity index 58% rename from test/endpoints.test.ts rename to test/carreras.test.ts index 055209a..b225968 100644 --- a/test/endpoints.test.ts +++ b/test/carreras.test.ts @@ -2,57 +2,11 @@ import {describe, expect} from '@jest/globals'; import request from 'supertest'; import {server} from '../src/app'; -let api; - const correo = process.env.USER_EMAIL || ""; const contrasenia = process.env.USER_PASSWORD || ""; -describe('POST /auth', () => { - it('login successful with @utem.cl', async () => { - const res = await request(server.app) - .post('/v1/auth') - .send({ - correo: correo, - contrasenia: contrasenia - }) - expect(res.statusCode).toEqual(200) - expect(res.body).toHaveProperty('token') - }, 25000) - - it('login successful without @utem.cl', async () => { - const res = await request(server.app) - .post('/v1/auth') - .send({ - correo: correo.replace("@utem.cl", ""), - contrasenia: contrasenia - }) - expect(res.statusCode).toEqual(200) - expect(res.body).toHaveProperty('token') - }, 25000) - - it('wrong email', async () => { - const res = await request(server.app) - .post('/v1/auth') - .send({ - correo: "a" + correo, - contrasenia: contrasenia - }) - expect(res.statusCode).toEqual(403) - }) - - it('wrong password', async () => { - const res = await request(server.app) - .post('/v1/auth') - .send({ - correo: correo, - contrasenia: contrasenia + "a" - }) - expect(res.statusCode).toEqual(403) - }) -}); - -describe('SIGA flow', () => { - it('login successful', async () => { +describe('Prueba de Carreras', () => { + it('Solicitud de Carreras y Notas', async () => { let res = await request(server.app) .post('/v1/auth') .send({ @@ -98,7 +52,6 @@ describe('SIGA flow', () => { }, 60000) }); - afterAll(done => { server.close(); done(); diff --git a/yarn.lock b/yarn.lock index 972b3c4..d996b6e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2582,6 +2582,13 @@ __metadata: languageName: node linkType: hard +"@types/cookiejar@npm:^2.1.5": + version: 2.1.5 + resolution: "@types/cookiejar@npm:2.1.5" + checksum: 10/04d5990e87b6387532d15a87d9ec9b2eb783039291193863751dcfd7fc723a3b3aa30ce4c06b03975cba58632e933772f1ff031af23eaa3ac7f94e71afa6e073 + languageName: node + linkType: hard + "@types/cors@npm:^2.8.5": version: 2.8.13 resolution: "@types/cors@npm:2.8.13" @@ -2736,6 +2743,13 @@ __metadata: languageName: node linkType: hard +"@types/methods@npm:^1.1.4": + version: 1.1.4 + resolution: "@types/methods@npm:1.1.4" + checksum: 10/ad2a7178486f2fd167750f3eb920ab032a947ff2e26f55c86670a6038632d790b46f52e5b6ead5823f1e53fc68028f1e9ddd15cfead7903e04517c88debd72b1 + languageName: node + linkType: hard + "@types/mime@npm:*": version: 3.0.1 resolution: "@types/mime@npm:3.0.1" @@ -2839,6 +2853,27 @@ __metadata: languageName: node linkType: hard +"@types/superagent@npm:^8.1.0": + version: 8.1.6 + resolution: "@types/superagent@npm:8.1.6" + dependencies: + "@types/cookiejar": "npm:^2.1.5" + "@types/methods": "npm:^1.1.4" + "@types/node": "npm:*" + checksum: 10/d21913bfe62b33ed214fc6895229a7f1aaea4adc5e42f915028443ab25c1c2cd4c8e7d624a2032dbd6a7f709ff7d0d63fe3a82856d8b7bc9751f17ab6ed7aec7 + languageName: node + linkType: hard + +"@types/supertest@npm:^6.0.2": + version: 6.0.2 + resolution: "@types/supertest@npm:6.0.2" + dependencies: + "@types/methods": "npm:^1.1.4" + "@types/superagent": "npm:^8.1.0" + checksum: 10/4b67fb2d1bfbb7ff0a7dfaaf190cdf2e0014522615fb2dc53c214bdac95b4ee42696dd1df13332c90a7765cc52934c9cc0c428bf0f9e8189167aef01042e7448 + languageName: node + linkType: hard + "@types/triple-beam@npm:^1.3.2": version: 1.3.2 resolution: "@types/triple-beam@npm:1.3.2" @@ -7856,6 +7891,7 @@ __metadata: "@types/jsonwebtoken": "npm:^9.0.6" "@types/morgan": "npm:^1.9.9" "@types/random-useragent": "npm:^0.3.3" + "@types/supertest": "npm:^6.0.2" atob: "npm:^2.1.2" axios: "npm:^1.6.7" body-parser: "npm:^1.20.2" From b610dd561def1cd80ce6fd3e2cc74aaa4ad55857 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 22 Apr 2024 23:04:29 -0400 Subject: [PATCH 02/27] =?UTF-8?q?patch:=20reparado=20login=20y=20reducido?= =?UTF-8?q?=20c=C3=B3digo=20*=20Se=20reduce=20c=C3=B3digo=20al=20autentica?= =?UTF-8?q?r=20con=20siga.=20*=20Se=20agrega=20la=20variable=20de=20entorn?= =?UTF-8?q?o=20de=20sso=20realm=20*=20Se=20mejora=20el=20modelo=20de=20coo?= =?UTF-8?q?kie?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> --- .env.example | 4 ++- src/academia/services/auth.service.ts | 2 +- src/infrastructure/models/cookie.model.ts | 43 +++++++++++++++++++++-- src/siga-api/services/auth.service.ts | 32 ++++------------- 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/.env.example b/.env.example index 6134b6f..336159a 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,10 @@ PORT=3000 LOG_LEVEL=info -UTEM_URL="https://www.utem.cl" SSO_UTEM_URL="https://sso.utem.cl" +ACADEMIA_SSO_REALM="prod" + +UTEM_URL="https://www.utem.cl" MI_UTEM_URL="https://mi.utem.cl" PASAPORTE_UTEM_URL="https://pasaporte.utem.cl" ACADEMIA_UTEM_URL="https://academia.utem.cl" diff --git a/src/academia/services/auth.service.ts b/src/academia/services/auth.service.ts index cf13a00..8239318 100644 --- a/src/academia/services/auth.service.ts +++ b/src/academia/services/auth.service.ts @@ -7,7 +7,7 @@ import { KeycloakUserService } from "../../keycloak/services/user.service"; export class AcademiaUserService { public static async loginAndGetCookies(correo: string, contrasenia: string): Promise { - const academiaIssuer = await Issuer.discover(`${process.env.SSO_UTEM_URL}/auth/realms/prod`) + const academiaIssuer = await Issuer.discover(`${process.env.SSO_UTEM_URL}/auth/realms/${process.env.ACADEMIA_SSO_REALM}`) const client = new academiaIssuer.Client({ // Genera un link cliente para el flujo de autorización. client_id: 'academiaClient', client_secret: process.env.ACADEMIA_CLIENT_SECRET, diff --git a/src/infrastructure/models/cookie.model.ts b/src/infrastructure/models/cookie.model.ts index aaf1527..78743c3 100644 --- a/src/infrastructure/models/cookie.model.ts +++ b/src/infrastructure/models/cookie.model.ts @@ -16,6 +16,45 @@ export default class Cookie { this.raw = `${name}=${value}`; } + static from(name: string, value: string) { + return new Cookie(name, value); + } + + withExpires(expires: Date | string) { + this.expires = expires; + return this; + } + + withMaxAge(maxAge: number) { + this.maxAge = maxAge; + return this; + } + + withPath(path: string) { + this.path = path; + return this; + } + + withDomain(domain: string) { + this.domain = domain; + return this; + } + + withSecure() { + this.secure = true; + return this; + } + + withHttpOnly() { + this.httpOnly = true; + return this; + } + + withSameSite(sameSite: 'Strict' | 'Lax' | 'None') { + this.sameSite = sameSite; + return this; + } + static parse(cookieString: string): Cookie { const cookieParts = cookieString.split(';'); const [name, value] = cookieParts.shift()?.split('=') ?? ['', '']; @@ -68,7 +107,7 @@ export default class Cookie { return newCookies } - static header(cookies: Cookie[]) { - return cookies.map(it => it.raw).join(';') + static header(cookies: Cookie | Cookie[]) { + return Array.isArray(cookies) ? cookies.map(it => it.raw).join(';') : this.header([cookies]); } } diff --git a/src/siga-api/services/auth.service.ts b/src/siga-api/services/auth.service.ts index 91b4145..6b8a148 100644 --- a/src/siga-api/services/auth.service.ts +++ b/src/siga-api/services/auth.service.ts @@ -2,37 +2,16 @@ import axios from "axios"; import Usuario from "../../core/models/usuario.model"; import GenericError from "../../infrastructure/models/error.model"; import {HashUtils} from "../../infrastructure/utils/hash.utils"; +import Cookie from "../../infrastructure/models/cookie.model"; export class SigaApiAuthService { public static async loginAndGetToken(correo: string, contrasenia: string): Promise { try { - const form = new FormData; - form.set('username', correo); - form.set('password', contrasenia); - const res = await axios.post(`${process.env.SIGA_API_URL}/autenticacion/login/`, form, { - headers: { - "Content-Type": "application/x-www-form-urlencoded", - Host: "siga.utem.cl", - }, - }); - - return res.data.response.token; + const response = await this.loginAndGetProfile(correo, contrasenia); + return response.token; } catch (err) { - if (err.response?.status === 401) { - console.debug({ - message: "Credenciales incorrectas", - response: err?.response?.data, - error: err, - }) - const error = GenericError.CREDENCIALES_INCORRECTAS - error.internalCode = 1.1 - error.metadata = { - uid: HashUtils.md5(correo), - statusCode: err.response?.status, - statusText: err.response?.statusText, - response: err.response?.data, - } - throw error + if(err.internalCode === 1.2) { + err.internalCode = 1.1 } throw err @@ -48,6 +27,7 @@ export class SigaApiAuthService { headers: { "Content-Type": "application/x-www-form-urlencoded", Host: "siga.utem.cl", + Cookie: Cookie.header(Cookie.from('SIGA', 'siga').withPath('/')), }, }); From d7afc0df56be46fdd8152a9145fe56b07f23dbf1 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:06:51 -0400 Subject: [PATCH 03/27] patch: arreglado tests, ahora se ejecutan sin problemas --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 63a1e00..34afda0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "", "main": "src/app.ts", "scripts": { - "test": "jest", + "test": "PORT=0 jest", "start": "ts-node src/app.ts", "start-dev": "nodemon src/app.ts" }, From 9f4040338510a8c36bc5e3109a26e7b7a32175bf Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 29 Apr 2024 22:20:44 -0400 Subject: [PATCH 04/27] =?UTF-8?q?patch:=20arreglos=20a=20la=20beca=20de=20?= =?UTF-8?q?alimentaci=C3=B3n=20y=20agregado=20test=20de=20Academia.UTEM=20?= =?UTF-8?q?*=20Se=20agrega=20variable=20faltante=20al=20.env=20*=20Se=20me?= =?UTF-8?q?jora=20y=20arregla=20login=20de=20academia=20*=20Se=20mejora=20?= =?UTF-8?q?y=20arregla=20la=20beca=20de=20alimentaci=C3=B3n=20(ahora=20es?= =?UTF-8?q?=20solo=20un=20m=C3=A9todo)=20*=20Se=20agrega=20test=20de=20Aca?= =?UTF-8?q?demia.UTEM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> --- .env.example | 2 +- src/academia/services/auth.service.ts | 4 +- .../services/beca-alimentacion.service.ts | 21 +++++- .../beca-alimentacion.controller.ts | 18 +---- src/core/routes/beca-alimentacion.routes.ts | 6 -- test/academia.test.ts | 74 +++++++++++++++++++ 6 files changed, 99 insertions(+), 26 deletions(-) create mode 100644 test/academia.test.ts diff --git a/.env.example b/.env.example index 336159a..e109410 100644 --- a/.env.example +++ b/.env.example @@ -2,7 +2,7 @@ PORT=3000 LOG_LEVEL=info SSO_UTEM_URL="https://sso.utem.cl" -ACADEMIA_SSO_REALM="prod" +ACADEMIA_SSO_REALM=prod UTEM_URL="https://www.utem.cl" MI_UTEM_URL="https://mi.utem.cl" diff --git a/src/academia/services/auth.service.ts b/src/academia/services/auth.service.ts index 8239318..4f58921 100644 --- a/src/academia/services/auth.service.ts +++ b/src/academia/services/auth.service.ts @@ -7,7 +7,7 @@ import { KeycloakUserService } from "../../keycloak/services/user.service"; export class AcademiaUserService { public static async loginAndGetCookies(correo: string, contrasenia: string): Promise { - const academiaIssuer = await Issuer.discover(`${process.env.SSO_UTEM_URL}/auth/realms/${process.env.ACADEMIA_SSO_REALM}`) + const academiaIssuer = await Issuer.discover(`${process.env.SSO_UTEM_URL}/auth/realms/${process.env.ACADEMIA_SSO_REALM || 'prod'}`) const client = new academiaIssuer.Client({ // Genera un link cliente para el flujo de autorización. client_id: 'academiaClient', client_secret: process.env.ACADEMIA_CLIENT_SECRET, @@ -26,7 +26,7 @@ export class AcademiaUserService { const urlParams = new URLSearchParams(loginResponse.headers.location.split('/sso#')[1]) // Obtiene los parámetros de la url de redirección let tokenSet; try { - await client.grant({ // Obtiene el token de autorización + tokenSet = await client.grant({ // Obtiene el token de autorización grant_type: 'authorization_code', code: urlParams.get('code'), redirect_uri: `${process.env.ACADEMIA_UTEM_URL}/sso`, diff --git a/src/academia/services/beca-alimentacion.service.ts b/src/academia/services/beca-alimentacion.service.ts index 5ca2f19..e9c646b 100644 --- a/src/academia/services/beca-alimentacion.service.ts +++ b/src/academia/services/beca-alimentacion.service.ts @@ -5,6 +5,7 @@ import axios from "axios"; import * as cheerio from 'cheerio'; import CodigoBecaAlimentacion from "../../core/models/codigo-beca-alimentacion.model"; import {dayjs} from "../../app"; +import * as fs from "node:fs"; export class BecaAlimentacionService { @@ -17,7 +18,7 @@ export class BecaAlimentacionService { }, }) - if(becaAlimentacionResponse.data.includes('Actualmente, no posees la beca de alimentación UTEM, cualquier consulta, dirígete a bienestar estudiantil de tu sede.')) { + if(!BecaAlimentacionService.tieneBeca(becaAlimentacionResponse)) { throw GenericError.SIN_BECA_ALIMENTACION } @@ -35,7 +36,17 @@ export class BecaAlimentacionService { } catch(_){} }) - console.debug({ codigos }) + const alerta = ($('div[class*="alert alert-danger col-sm-10 col-sm-offset-1"]')?.text() || '').replaceAll('\n', '').trim() + if(alerta.toLowerCase().includes('ya tienes generado el cupón de alimentación para el día')) { + const partes = alerta.split('el código es:') + if(partes.length == 2) { + codigos.push({ + codigo: partes[1].trim(), + validoPara: dayjs().tz('America/Santiago').toISOString(), + estado: 'DESCONOCIDO' + }) + } + } return codigos } @@ -50,7 +61,7 @@ export class BecaAlimentacionService { }, }) - if(becaAlimentacionResponse.data.includes('Actualmente, no posees la beca de alimentación UTEM, cualquier consulta, dirígete a bienestar estudiantil de tu sede.')) { + if(!BecaAlimentacionService.tieneBeca(becaAlimentacionResponse)) { throw GenericError.SIN_BECA_ALIMENTACION } @@ -80,4 +91,8 @@ export class BecaAlimentacionService { const codigos = await BecaAlimentacionService.obtenerCodigoAlimentacion(cookies) return codigos.filter(it => dayjs(it.validoPara).tz('America/Santiago').isSameOrAfter(desde, 'day') && dayjs(it.validoPara).tz('America/Santiago').isSameOrBefore(hasta, 'day')) } + + private static tieneBeca(response) { + return !response.data.toLowerCase().includes('actualmente, no posees la beca de alimentación utem, cualquier consulta, dirígete a bienestar estudiantil de tu sede.') + } } diff --git a/src/core/controllers/beca-alimentacion.controller.ts b/src/core/controllers/beca-alimentacion.controller.ts index 2633e40..3f7b703 100644 --- a/src/core/controllers/beca-alimentacion.controller.ts +++ b/src/core/controllers/beca-alimentacion.controller.ts @@ -5,17 +5,6 @@ import {dayjs} from "../../app"; import GenericError from "../../infrastructure/models/error.model"; export class BecaAlimentacionController { - public static async getCodigoBecaAlimentacion(req: Request, res: Response, next: NextFunction): Promise { - try { - const cookies = res.locals.loggedInUser.academiaCookies; - - const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.obtenerCodigoAlimentacion(cookies) - - res.status(200).json(codigos); - } catch (error) { - next(error); - } - } public static async solicitarCodigoBecaAlimentacion(req: Request, res: Response, next: NextFunction): Promise { try { @@ -34,8 +23,9 @@ export class BecaAlimentacionController { const ahora = dayjs().tz('America/Santiago') // Hoy a las 00:00 const cookies = res.locals.loggedInUser.academiaCookies; - const desde = (dayjs(req.body.desde, 'YYYY-MM-DD').tz('America/Santiago') || ahora).startOf('day'); - const hasta = (dayjs(req.body.hasta, 'YYYY-MM-DD').tz('America/Santiago') || ahora).endOf('day'); + const desde = (req.body.desde ? dayjs(req.body.desde, 'YYYY-MM-DD').tz('America/Santiago') : ahora).startOf('day'); + let hasta = (req.body.hasta ? dayjs(req.body.hasta, 'YYYY-MM-DD').tz('America/Santiago') : ahora).endOf('day'); + hasta.isBefore(desde) && (hasta = desde.endOf('day')); // Si es desde sabado hasta domingo lanzar error if (dayjs(desde).tz('America/Santiago').day() === 6 && dayjs(hasta).tz('America/Santiago').day() === 0) { @@ -55,7 +45,7 @@ export class BecaAlimentacionController { return next(error) } - const codigos = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desde.toISOString(), hasta.toISOString()) + const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desde.toISOString(), hasta.toISOString()) res.status(200).json(codigos); } catch (error) { diff --git a/src/core/routes/beca-alimentacion.routes.ts b/src/core/routes/beca-alimentacion.routes.ts index bc12dd4..e7e2f09 100644 --- a/src/core/routes/beca-alimentacion.routes.ts +++ b/src/core/routes/beca-alimentacion.routes.ts @@ -4,12 +4,6 @@ import {AcademiaCredentialsMiddleware} from "../../infrastructure/middlewares/cr const router: Router = Router(); -router.get( - "/beca-alimentacion", - AcademiaCredentialsMiddleware.isLoggedIn, - BecaAlimentacionController.getCodigoBecaAlimentacion -); - router.post( "/beca-alimentacion", AcademiaCredentialsMiddleware.isLoggedIn, diff --git a/test/academia.test.ts b/test/academia.test.ts new file mode 100644 index 0000000..6775bdf --- /dev/null +++ b/test/academia.test.ts @@ -0,0 +1,74 @@ +import {describe, expect} from '@jest/globals'; +import request from 'supertest'; +import {server} from '../src/app'; +import dayjs from "dayjs"; + +const correo = process.env.USER_EMAIL || ""; +const contrasenia = process.env.USER_PASSWORD || ""; + +describe('Prueba de Academia', () => { + it('Solicitud de Beca de Alimentación (Día Especifico)', async () => { + let res = await request(server.app) + .post('/v1/auth') + .send({ + correo: correo, + contrasenia: contrasenia + }) + expect(res.statusCode).toEqual(200) + + const token = res.body.token; + + // Obtiene el viernes de esta semana o la próxima si ya pasó el viernes + const currentOrNextFriday = dayjs().day() > 5 ? dayjs().add(1, 'week').day(5) : dayjs().day(5); + res = await request(server.app) + .post('/v1/beca-alimentacion') + .set('Authorization', `Bearer ${token}`) + .send({ + desde: currentOrNextFriday.format('YYYY-MM-DD'), + }) + + expect(res.statusCode).toEqual(200) + + // Solo ver en (abril a junio) o (septiembre a diciembre), ya que dentro de esas fechas es más probable tener la beca activa. + const currentMonth = new Date().getMonth(); + if ((currentMonth === 3 || currentMonth === 5) || (currentMonth >= 8 && currentMonth <= 11)) { + expect(res.body.length).toBeGreaterThan(0) + } + }, 60000) + + it('Solicitud de Beca de Alimentación (Toda la Semana)', async () => { + + let res = await request(server.app) + .post('/v1/auth') + .send({ + correo: correo, + contrasenia: contrasenia + }) + expect(res.statusCode).toEqual(200) + + const token = res.body.token; + + res = await request(server.app) + .post('/v1/beca-alimentacion') + .set('Authorization', `Bearer ${token}`) + .send({ + desde: dayjs().format('YYYY-MM-DD'), + hasta: dayjs().add(6, 'day').format('YYYY-MM-DD'), + }) + + expect(res.statusCode).toEqual(200) + + // Solo ver en (abril a junio) o (septiembre a diciembre), ya que dentro de esas fechas es más probable tener la beca activa. + const currentMonth = new Date().getMonth(); + if ((currentMonth === 3 || currentMonth === 5) || (currentMonth >= 8 && currentMonth <= 11)) { + expect(res.body.length).toBeGreaterThan(0) + // Esperar que contenga algun codigo que contenga la vigenca de la beca + expect((res.body || []).find(it => dayjs(it.validoPara).isBetween(dayjs().format('YYYY-MM-DD'), dayjs().add(6, 'day').format('YYYY-MM-DD')))).toBeTruthy() + } + }); +}); + +afterAll(done => { + server.close(); + done(); +}) From fdd9141a43ab93490bef28a39cf6d07edffc314b Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Thu, 2 May 2024 18:36:33 -0400 Subject: [PATCH 05/27] patch: agregado tipo de respuesta --- src/mi-utem/services/auth.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mi-utem/services/auth.service.ts b/src/mi-utem/services/auth.service.ts index f441a3b..fa881d6 100644 --- a/src/mi-utem/services/auth.service.ts +++ b/src/mi-utem/services/auth.service.ts @@ -7,8 +7,8 @@ import { KeycloakUserService } from "../../keycloak/services/user.service"; export class MiUtemAuthService { public static async loginAndGetCookies(correo: string, contrasenia: string): Promise { - const pasaporteCookies = await MiUtemAuthService.loginPasaporte(correo, contrasenia) - if (pasaporteCookies) { + const pasaporteCookies: Cookie[] | undefined = await MiUtemAuthService.loginPasaporte(correo, contrasenia) + if ((pasaporteCookies?.length || 0) > 0) { return pasaporteCookies } From ea3fd26c2f695a62bbdf82cf5787d3924f974146 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Thu, 2 May 2024 18:48:23 -0400 Subject: [PATCH 06/27] patch: agregado reino del sso a los tests --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index df0f563..07498e1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,6 +38,7 @@ jobs: MI_UTEM_URL: ${{ vars.MI_UTEM_URL || 'https://mi.utem.cl' }} PASAPORTE_UTEM_URL: ${{ vars.PASAPORTE_UTEM_URL || 'https://pasaporte.utem.cl' }} ACADEMIA_UTEM_URL: ${{ vars.ACADEMIA_UTEM_URL || 'https://academia.utem.cl' }} + ACADEMIA_SSO_REALM: ${{ vars.ACADEMIA_SSO_REALM || 'prod' }} SIGA_API_URL: ${{ vars.SIGA_API_URL || 'https://siga.utem.cl/servicios' }} FCM_SERVER_KEY: ${{ secrets.FCM_SERVER_KEY }} From affe6f0a134be9aa8fcf0391e26dd571ac7fb701 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 08:41:17 -0400 Subject: [PATCH 07/27] =?UTF-8?q?patch:=20mejorado=20workflow=20de=20yarn?= =?UTF-8?q?=20*=20Se=20actualiza=20a=20setup-node=20v4=20*=20Se=20agrega?= =?UTF-8?q?=20cach=C3=A9=20de=20yarn=20*=20Se=20mejoran=20los=20nombres=20?= =?UTF-8?q?de=20las=20acciones?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tests.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 07498e1..59f356e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,20 +17,20 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [18, 20] steps: - uses: actions/checkout@v2 - name: 'Setup Node.js' - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - - name: 'Install yarn' - run: npm install -g yarn - - name: 'yarn install and test' + cache: 'yarn' + - name: 'Yarn Install' + run: yarn install + - name: 'Test' run: | echo "${{ secrets.FIREBASE_ADMINSDK_PROJECT_ID }}" - yarn yarn test env: UTEM_URL: ${{ vars.UTEM_URL || 'https://www.utem.cl' }} From 8a06a0e02d4ffbc1042a6e5a4fa83dd43434a8ad Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 08:43:31 -0400 Subject: [PATCH 08/27] patch: se elimina comando echo --- .github/workflows/tests.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 59f356e..7ffc1b4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,10 +28,8 @@ jobs: cache: 'yarn' - name: 'Yarn Install' run: yarn install - - name: 'Test' - run: | - echo "${{ secrets.FIREBASE_ADMINSDK_PROJECT_ID }}" - yarn test + - name: 'Yarn Test' + run: yarn test env: UTEM_URL: ${{ vars.UTEM_URL || 'https://www.utem.cl' }} SSO_UTEM_URL: ${{ vars.SSO_UTEM_URL || 'https://sso.utem.cl' }} From 1021918aca1df9d1c733ec02fbe75374aff1043c Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 09:14:27 -0400 Subject: [PATCH 09/27] patch: instalado y actualizado sentry --- .github/workflows/tests.yml | 2 + .pnp.cjs | 154 +++++++++++++++++- package.json | 6 +- src/core/controllers/asignatura.controller.ts | 12 +- src/core/controllers/noticia.controller.ts | 7 +- src/infrastructure/server/server.ts | 34 ++-- yarn.lock | 148 ++++++++++++++++- 7 files changed, 321 insertions(+), 42 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7ffc1b4..24f2254 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,6 +31,8 @@ jobs: - name: 'Yarn Test' run: yarn test env: + NODE_ENV: test + SENTRY_URL: ${{ secrets.SENTRY_URL }} UTEM_URL: ${{ vars.UTEM_URL || 'https://www.utem.cl' }} SSO_UTEM_URL: ${{ vars.SSO_UTEM_URL || 'https://sso.utem.cl' }} MI_UTEM_URL: ${{ vars.MI_UTEM_URL || 'https://mi.utem.cl' }} diff --git a/.pnp.cjs b/.pnp.cjs index b22bb07..8bfc487 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -27,8 +27,12 @@ const RAW_RUNTIME_STATE = "packageLocation": "./",\ "packageDependencies": [\ ["@jest/globals", "npm:29.7.0"],\ - ["@sentry/node", "npm:7.103.0"],\ + ["@sentry/node", "npm:7.113.0"],\ + ["@sentry/profiling-node", "npm:7.113.0"],\ ["@sentry/tracing", "npm:7.103.0"],\ + ["@sentry/types", "npm:7.113.0"],\ + ["@types/body-parser", "npm:1.19.5"],\ + ["@types/express", "npm:4.17.21"],\ ["@types/jest", "npm:29.5.12"],\ ["@types/jsonwebtoken", "npm:9.0.6"],\ ["@types/morgan", "npm:1.9.9"],\ @@ -4061,6 +4065,16 @@ const RAW_RUNTIME_STATE = ["@sentry/utils", "npm:7.103.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:7.113.0", {\ + "packageLocation": "./.yarn/cache/@sentry-internal-tracing-npm-7.113.0-3b7498c229-9be626ef56.zip/node_modules/@sentry-internal/tracing/",\ + "packageDependencies": [\ + ["@sentry-internal/tracing", "npm:7.113.0"],\ + ["@sentry/core", "npm:7.113.0"],\ + ["@sentry/types", "npm:7.113.0"],\ + ["@sentry/utils", "npm:7.113.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@sentry/core", [\ @@ -4072,17 +4086,52 @@ const RAW_RUNTIME_STATE = ["@sentry/utils", "npm:7.103.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:7.113.0", {\ + "packageLocation": "./.yarn/cache/@sentry-core-npm-7.113.0-dd00989c55-70bd3f34fb.zip/node_modules/@sentry/core/",\ + "packageDependencies": [\ + ["@sentry/core", "npm:7.113.0"],\ + ["@sentry/types", "npm:7.113.0"],\ + ["@sentry/utils", "npm:7.113.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@sentry/integrations", [\ + ["npm:7.113.0", {\ + "packageLocation": "./.yarn/cache/@sentry-integrations-npm-7.113.0-b4815751ec-a3ce0c40c7.zip/node_modules/@sentry/integrations/",\ + "packageDependencies": [\ + ["@sentry/integrations", "npm:7.113.0"],\ + ["@sentry/core", "npm:7.113.0"],\ + ["@sentry/types", "npm:7.113.0"],\ + ["@sentry/utils", "npm:7.113.0"],\ + ["localforage", "npm:1.10.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@sentry/node", [\ - ["npm:7.103.0", {\ - "packageLocation": "./.yarn/cache/@sentry-node-npm-7.103.0-d8ba54633b-81c74e3772.zip/node_modules/@sentry/node/",\ + ["npm:7.113.0", {\ + "packageLocation": "./.yarn/cache/@sentry-node-npm-7.113.0-f70a9d318d-93d012bb9e.zip/node_modules/@sentry/node/",\ "packageDependencies": [\ - ["@sentry/node", "npm:7.103.0"],\ - ["@sentry-internal/tracing", "npm:7.103.0"],\ - ["@sentry/core", "npm:7.103.0"],\ - ["@sentry/types", "npm:7.103.0"],\ - ["@sentry/utils", "npm:7.103.0"]\ + ["@sentry/node", "npm:7.113.0"],\ + ["@sentry-internal/tracing", "npm:7.113.0"],\ + ["@sentry/core", "npm:7.113.0"],\ + ["@sentry/integrations", "npm:7.113.0"],\ + ["@sentry/types", "npm:7.113.0"],\ + ["@sentry/utils", "npm:7.113.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@sentry/profiling-node", [\ + ["npm:7.113.0", {\ + "packageLocation": "./.yarn/unplugged/@sentry-profiling-node-npm-7.113.0-cff9e2a686/node_modules/@sentry/profiling-node/",\ + "packageDependencies": [\ + ["@sentry/profiling-node", "npm:7.113.0"],\ + ["detect-libc", "npm:2.0.3"],\ + ["node-abi", "npm:3.62.0"],\ + ["node-gyp", "npm:9.4.0"]\ ],\ "linkType": "HARD"\ }]\ @@ -4104,6 +4153,13 @@ const RAW_RUNTIME_STATE = ["@sentry/types", "npm:7.103.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:7.113.0", {\ + "packageLocation": "./.yarn/cache/@sentry-types-npm-7.113.0-b862b61cdf-a6a2c453d3.zip/node_modules/@sentry/types/",\ + "packageDependencies": [\ + ["@sentry/types", "npm:7.113.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@sentry/utils", [\ @@ -4114,6 +4170,14 @@ const RAW_RUNTIME_STATE = ["@sentry/types", "npm:7.103.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:7.113.0", {\ + "packageLocation": "./.yarn/cache/@sentry-utils-npm-7.113.0-8dcabb246a-e18054d298.zip/node_modules/@sentry/utils/",\ + "packageDependencies": [\ + ["@sentry/utils", "npm:7.113.0"],\ + ["@sentry/types", "npm:7.113.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@sinclair/typebox", [\ @@ -4244,6 +4308,15 @@ const RAW_RUNTIME_STATE = ["@types/node", "npm:20.4.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:1.19.5", {\ + "packageLocation": "./.yarn/cache/@types-body-parser-npm-1.19.5-97fb106976-1e251118c4.zip/node_modules/@types/body-parser/",\ + "packageDependencies": [\ + ["@types/body-parser", "npm:1.19.5"],\ + ["@types/connect", "npm:3.4.35"],\ + ["@types/node", "npm:20.4.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["@types/connect", [\ @@ -4287,6 +4360,17 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ + ["npm:4.17.21", {\ + "packageLocation": "./.yarn/cache/@types-express-npm-4.17.21-be92a0245e-7a6d26cf6f.zip/node_modules/@types/express/",\ + "packageDependencies": [\ + ["@types/express", "npm:4.17.21"],\ + ["@types/body-parser", "npm:1.19.2"],\ + ["@types/express-serve-static-core", "npm:4.17.35"],\ + ["@types/qs", "npm:6.9.7"],\ + ["@types/serve-static", "npm:1.15.2"]\ + ],\ + "linkType": "HARD"\ + }],\ ["npm:4.17.3", {\ "packageLocation": "./.yarn/cache/@types-express-npm-4.17.3-ac3232298a-9895c322dc.zip/node_modules/@types/express/",\ "packageDependencies": [\ @@ -6753,6 +6837,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["detect-libc", [\ + ["npm:2.0.3", {\ + "packageLocation": "./.yarn/cache/detect-libc-npm-2.0.3-2ddae34945-b4ea018d62.zip/node_modules/detect-libc/",\ + "packageDependencies": [\ + ["detect-libc", "npm:2.0.3"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["detect-newline", [\ ["npm:3.1.0", {\ "packageLocation": "./.yarn/cache/detect-newline-npm-3.1.0-6d33fa8d37-ae6cd429c4.zip/node_modules/detect-newline/",\ @@ -8471,6 +8564,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["immediate", [\ + ["npm:3.0.6", {\ + "packageLocation": "./.yarn/cache/immediate-npm-3.0.6-c27588a2d3-f9b3486477.zip/node_modules/immediate/",\ + "packageDependencies": [\ + ["immediate", "npm:3.0.6"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["import-fresh", [\ ["npm:3.3.0", {\ "packageLocation": "./.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip/node_modules/import-fresh/",\ @@ -9854,6 +9956,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["lie", [\ + ["npm:3.1.1", {\ + "packageLocation": "./.yarn/cache/lie-npm-3.1.1-91350720d9-c2c7d9dcc3.zip/node_modules/lie/",\ + "packageDependencies": [\ + ["lie", "npm:3.1.1"],\ + ["immediate", "npm:3.0.6"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["lilconfig", [\ ["npm:2.1.0", {\ "packageLocation": "./.yarn/cache/lilconfig-npm-2.1.0-a179261924-b1314a2e55.zip/node_modules/lilconfig/",\ @@ -9891,6 +10003,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["localforage", [\ + ["npm:1.10.0", {\ + "packageLocation": "./.yarn/cache/localforage-npm-1.10.0-cf9ea9a436-d5c44be3a0.zip/node_modules/localforage/",\ + "packageDependencies": [\ + ["localforage", "npm:1.10.0"],\ + ["lie", "npm:3.1.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["locate-path", [\ ["npm:5.0.0", {\ "packageLocation": "./.yarn/cache/locate-path-npm-5.0.0-46580c43e4-83e51725e6.zip/node_modules/locate-path/",\ @@ -10320,8 +10442,12 @@ const RAW_RUNTIME_STATE = "packageDependencies": [\ ["mi-utem-api", "workspace:."],\ ["@jest/globals", "npm:29.7.0"],\ - ["@sentry/node", "npm:7.103.0"],\ + ["@sentry/node", "npm:7.113.0"],\ + ["@sentry/profiling-node", "npm:7.113.0"],\ ["@sentry/tracing", "npm:7.103.0"],\ + ["@sentry/types", "npm:7.113.0"],\ + ["@types/body-parser", "npm:1.19.5"],\ + ["@types/express", "npm:4.17.21"],\ ["@types/jest", "npm:29.5.12"],\ ["@types/jsonwebtoken", "npm:9.0.6"],\ ["@types/morgan", "npm:1.9.9"],\ @@ -10784,6 +10910,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["node-abi", [\ + ["npm:3.62.0", {\ + "packageLocation": "./.yarn/cache/node-abi-npm-3.62.0-e3e1be9ac7-4cb9d4e6d3.zip/node_modules/node-abi/",\ + "packageDependencies": [\ + ["node-abi", "npm:3.62.0"],\ + ["semver", "npm:7.5.3"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["node-cache", [\ ["npm:5.1.2", {\ "packageLocation": "./.yarn/cache/node-cache-npm-5.1.2-f65482660d-6ac71a9e65.zip/node_modules/node-cache/",\ diff --git a/package.json b/package.json index 34afda0..09f92ea 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "author": "", "license": "ISC", "dependencies": { - "@sentry/node": "^7.103.0", + "@sentry/node": "^7.113.0", + "@sentry/profiling-node": "^7.113.0", "@sentry/tracing": "^7.103.0", "@types/morgan": "^1.9.9", "atob": "^2.1.2", @@ -49,6 +50,9 @@ }, "devDependencies": { "@jest/globals": "^29.7.0", + "@sentry/types": "^7.113.0", + "@types/body-parser": "^1.19.5", + "@types/express": "^4.17.21", "@types/jest": "^29.5.12", "@types/jsonwebtoken": "^9.0.6", "@types/random-useragent": "^0.3.3", diff --git a/src/core/controllers/asignatura.controller.ts b/src/core/controllers/asignatura.controller.ts index db3a798..c17f421 100644 --- a/src/core/controllers/asignatura.controller.ts +++ b/src/core/controllers/asignatura.controller.ts @@ -64,12 +64,12 @@ export class AsignaturaController { const codigo: string = req.params.codigoId; - const asignatura: SeccionAsignatura = - await MiUtemAsignaturaService.getDetalleAsignatura( - cookies, - codigo, - req.query.tipoHora || 'TEORIA', // Por defecto vemos la teoría - ); + const tipoHora = `${req.query.tipoHora || 'TEORIA'}` + const asignatura: SeccionAsignatura = await MiUtemAsignaturaService.getDetalleAsignatura( + cookies, + codigo, + tipoHora, // Por defecto vemos la teoría + ); res.status(200).json(asignatura); } catch (error) { diff --git a/src/core/controllers/noticia.controller.ts b/src/core/controllers/noticia.controller.ts index dc89703..39a77b7 100644 --- a/src/core/controllers/noticia.controller.ts +++ b/src/core/controllers/noticia.controller.ts @@ -10,22 +10,23 @@ export class NoticiaController { query.desde = query.desde || dayjs().subtract(6, 'month').format('YYYY-MM-DD') // Por defecto desde hace 6 meses query.hasta = query.hasta || dayjs().format('YYYY-MM-DD') // Por defecto hasta hoy // Valida que el formato de fecha sea 'YYYY-MM-DD' - const desdeDayjs = dayjs(query.desde, 'YYYY-MM-DD').tz('America/Santiago').startOf('day') + const desdeDayjs = dayjs(`${query.desde}`, 'YYYY-MM-DD').tz('America/Santiago').startOf('day') if (query.desde && !desdeDayjs.isValid()) { const error = GenericError.FORMATO_FECHA_INVALIDO error.internalCode = 18.1 return next(error) } - const hastaDayjs = dayjs(query.hasta, 'YYYY-MM-DD').tz('America/Santiago').endOf('day') + const hastaDayjs = dayjs(`${query.hasta}`, 'YYYY-MM-DD').tz('America/Santiago').endOf('day') if (query.hasta && !hastaDayjs.isValid()) { const error = GenericError.FORMATO_FECHA_INVALIDO error.internalCode = 18.2 return next(error) } + const porPagina: number = parseInt(`${query.porPagina || 10}`); const noticias = await UtemNoticiasService.getNoticias( - query.por_pagina || 10, + porPagina, desdeDayjs.toISOString(), hastaDayjs.toISOString() ); diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index 8788f70..622f6b8 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -1,5 +1,4 @@ import * as Sentry from "@sentry/node"; -import * as Tracing from "@sentry/tracing"; import bodyParser from "body-parser"; import express, { NextFunction, Request, Response } from "express"; import { readFileSync } from "fs"; @@ -11,9 +10,11 @@ import CoreRouter from "../../core/routes/index.routes"; import GenericError from "../models/error.model"; import GenericLogger from "../utils/logger.utils"; import {HashUtils} from "../utils/hash.utils"; +import {nodeProfilingIntegration} from "@sentry/profiling-node"; +import * as process from "node:process"; -const winstonMorgarWriter = new stream.Writable(); -winstonMorgarWriter._write = function (chunk, encoding, done) { +const winstonMorganWriter = new stream.Writable(); +winstonMorganWriter._write = function (chunk, encoding, done) { GenericLogger.log({ level: "http", message: chunk.toString(), @@ -30,14 +31,20 @@ export default class Server { public constructor(port: number) { this.port = port; this.app = express(); - Sentry.init({ - dsn: process.env.SENTRY_URL, - integrations: [ - new Sentry.Integrations.Http({tracing: true}), - new Tracing.Integrations.Express({app: this.app}), - ], - tracesSampleRate: 1.0, - }); + if(process.env.SENTRY_URL) { + Sentry.init({ + dsn: process.env.SENTRY_URL, + integrations: [ + // enable HTTP calls tracing + new Sentry.Integrations.Http({ tracing: true }), + // enable Express.js middleware tracing + new Sentry.Integrations.Express({ app: this.app }), + nodeProfilingIntegration(), + ], + tracesSampleRate: 1.0, + profilesSampleRate: 1.0, + }); + } this.config(); this.listen(); @@ -51,7 +58,7 @@ export default class Server { this.app.use( morgan("short", { - stream: winstonMorgarWriter, + stream: winstonMorganWriter, }) ); @@ -67,7 +74,6 @@ export default class Server { this.app.use("/v1", CoreRouter); this.app.use(Sentry.Handlers.errorHandler()); - this.app.use(function onError( err: any, req: Request, @@ -79,7 +85,7 @@ export default class Server { message: err.stack, }); if (err instanceof GenericError) { - let uid; + let uid: string; try { uid = HashUtils.md5(req.body.correo || '') } catch { diff --git a/yarn.lock b/yarn.lock index d996b6e..d221503 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2415,6 +2415,17 @@ __metadata: languageName: node linkType: hard +"@sentry-internal/tracing@npm:7.113.0": + version: 7.113.0 + resolution: "@sentry-internal/tracing@npm:7.113.0" + dependencies: + "@sentry/core": "npm:7.113.0" + "@sentry/types": "npm:7.113.0" + "@sentry/utils": "npm:7.113.0" + checksum: 10/9be626ef56a4fda8f9c39a66565ca161851cd1aa6acd1c6153cfd28d26c79958c48c928af0a8cb8a3df2e320495c7b638fb386edd882e58c7b72a3b4d5c3cf25 + languageName: node + linkType: hard + "@sentry/core@npm:7.103.0": version: 7.103.0 resolution: "@sentry/core@npm:7.103.0" @@ -2425,15 +2436,51 @@ __metadata: languageName: node linkType: hard -"@sentry/node@npm:^7.103.0": - version: 7.103.0 - resolution: "@sentry/node@npm:7.103.0" +"@sentry/core@npm:7.113.0": + version: 7.113.0 + resolution: "@sentry/core@npm:7.113.0" dependencies: - "@sentry-internal/tracing": "npm:7.103.0" - "@sentry/core": "npm:7.103.0" - "@sentry/types": "npm:7.103.0" - "@sentry/utils": "npm:7.103.0" - checksum: 10/81c74e377296df20be16aba1f4874665ceff771a7ff5833c52c7ff21585cfc90b32fbfc9eac80d0ac9780e10e6aae68238ce4d07216e1d94f273afe28566dd6a + "@sentry/types": "npm:7.113.0" + "@sentry/utils": "npm:7.113.0" + checksum: 10/70bd3f34fba44b597a37aee45aa7af5086b2ff9434d2314dfaaed4310be07a55df313e853923a0fa728ee714198ba73d053b1088e50dc93d60e4b2eae7b50e91 + languageName: node + linkType: hard + +"@sentry/integrations@npm:7.113.0": + version: 7.113.0 + resolution: "@sentry/integrations@npm:7.113.0" + dependencies: + "@sentry/core": "npm:7.113.0" + "@sentry/types": "npm:7.113.0" + "@sentry/utils": "npm:7.113.0" + localforage: "npm:^1.8.1" + checksum: 10/a3ce0c40c7806322d759be9c6a633793a43d0230f216682812ac06f03e4c1d90a991e851615f4e0f787ffdfc6fe60ce731814c0d28931d09a4e2aaf1ee9d92f9 + languageName: node + linkType: hard + +"@sentry/node@npm:^7.113.0": + version: 7.113.0 + resolution: "@sentry/node@npm:7.113.0" + dependencies: + "@sentry-internal/tracing": "npm:7.113.0" + "@sentry/core": "npm:7.113.0" + "@sentry/integrations": "npm:7.113.0" + "@sentry/types": "npm:7.113.0" + "@sentry/utils": "npm:7.113.0" + checksum: 10/93d012bb9e5a19c140e90c9d0a20c2a3a20928a36a69a3878cf8d757b18ef349967e556f91224f3c6acfe96cf89c4b3c345e1b569357709665afaaa4c048e5d5 + languageName: node + linkType: hard + +"@sentry/profiling-node@npm:^7.113.0": + version: 7.113.0 + resolution: "@sentry/profiling-node@npm:7.113.0" + dependencies: + detect-libc: "npm:^2.0.2" + node-abi: "npm:^3.61.0" + node-gyp: "npm:latest" + bin: + sentry-prune-profiler-binaries: scripts/prune-profiler-binaries.js + checksum: 10/5b759f2f7d377a6663734049e204630cd55f86fb2f6b2017251e4195ccf03abcc1f8e3ef49f82ad3ecda43c1c78bb3c09666ec8b44efa0b143f234a268d6a069 languageName: node linkType: hard @@ -2453,6 +2500,13 @@ __metadata: languageName: node linkType: hard +"@sentry/types@npm:7.113.0, @sentry/types@npm:^7.113.0": + version: 7.113.0 + resolution: "@sentry/types@npm:7.113.0" + checksum: 10/a6a2c453d38b7a2ddaf1b75063077c547e4a3398d5a2e3dd0d505b9bb122caa0334e3126be000d549fab2037ba32fd72ef20771633fe7f802afcb5adbc5fbbf5 + languageName: node + linkType: hard + "@sentry/utils@npm:7.103.0": version: 7.103.0 resolution: "@sentry/utils@npm:7.103.0" @@ -2462,6 +2516,15 @@ __metadata: languageName: node linkType: hard +"@sentry/utils@npm:7.113.0": + version: 7.113.0 + resolution: "@sentry/utils@npm:7.113.0" + dependencies: + "@sentry/types": "npm:7.113.0" + checksum: 10/e18054d298497d9f63561b478f4b8e80d188cbf2c26cabacea6a15c9bbcfe03c8f0c9ee0a809c410cba2e5f621c89ea3bfa0efc88ea482019573fe4a6843ea90 + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.27.8": version: 0.27.8 resolution: "@sinclair/typebox@npm:0.27.8" @@ -2573,6 +2636,16 @@ __metadata: languageName: node linkType: hard +"@types/body-parser@npm:^1.19.5": + version: 1.19.5 + resolution: "@types/body-parser@npm:1.19.5" + dependencies: + "@types/connect": "npm:*" + "@types/node": "npm:*" + checksum: 10/1e251118c4b2f61029cc43b0dc028495f2d1957fe8ee49a707fb940f86a9bd2f9754230805598278fe99958b49e9b7e66eec8ef6a50ab5c1f6b93e1ba2aaba82 + languageName: node + linkType: hard + "@types/connect@npm:*": version: 3.4.35 resolution: "@types/connect@npm:3.4.35" @@ -2633,6 +2706,18 @@ __metadata: languageName: node linkType: hard +"@types/express@npm:^4.17.21": + version: 4.17.21 + resolution: "@types/express@npm:4.17.21" + dependencies: + "@types/body-parser": "npm:*" + "@types/express-serve-static-core": "npm:^4.17.33" + "@types/qs": "npm:*" + "@types/serve-static": "npm:*" + checksum: 10/7a6d26cf6f43d3151caf4fec66ea11c9d23166e4f3102edfe45a94170654a54ea08cf3103d26b3928d7ebcc24162c90488e33986b7e3a5f8941225edd5eb18c7 + languageName: node + linkType: hard + "@types/glob@npm:*": version: 8.1.0 resolution: "@types/glob@npm:8.1.0" @@ -4705,6 +4790,13 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^2.0.2": + version: 2.0.3 + resolution: "detect-libc@npm:2.0.3" + checksum: 10/b4ea018d623e077bd395f168a9e81db77370dde36a5b01d067f2ad7989924a81d31cb547ff764acb2aa25d50bb7fdde0b0a93bec02212b0cb430621623246d39 + languageName: node + linkType: hard + "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -6258,6 +6350,13 @@ __metadata: languageName: node linkType: hard +"immediate@npm:~3.0.5": + version: 3.0.6 + resolution: "immediate@npm:3.0.6" + checksum: 10/f9b3486477555997657f70318cc8d3416159f208bec4cca3ff3442fd266bc23f50f0c9bd8547e1371a6b5e82b821ec9a7044a4f7b944798b25aa3cc6d5e63e62 + languageName: node + linkType: hard + "import-fresh@npm:^3.2.1": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" @@ -7487,6 +7586,15 @@ __metadata: languageName: node linkType: hard +"lie@npm:3.1.1": + version: 3.1.1 + resolution: "lie@npm:3.1.1" + dependencies: + immediate: "npm:~3.0.5" + checksum: 10/c2c7d9dcc3a9aae641f41cde4e2e2cd571e4426b1f5915862781d77776672dcbca43461e16f4d382c9a300825c15e1a4923f1def3a5568d97577e077a3cecb44 + languageName: node + linkType: hard + "lilconfig@npm:^2.0.5": version: 2.1.0 resolution: "lilconfig@npm:2.1.0" @@ -7517,6 +7625,15 @@ __metadata: languageName: node linkType: hard +"localforage@npm:^1.8.1": + version: 1.10.0 + resolution: "localforage@npm:1.10.0" + dependencies: + lie: "npm:3.1.1" + checksum: 10/d5c44be3a09169b013a3ebe252e678aaeb6938ffe72e9e12c199fd4307c1ec9d1a057ac2dfdfbb1379dfeec467a34ad0fc3ecd27489a2c43a154fb72b2822542 + languageName: node + linkType: hard + "locate-path@npm:^5.0.0": version: 5.0.0 resolution: "locate-path@npm:5.0.0" @@ -7885,8 +8002,12 @@ __metadata: resolution: "mi-utem-api@workspace:." dependencies: "@jest/globals": "npm:^29.7.0" - "@sentry/node": "npm:^7.103.0" + "@sentry/node": "npm:^7.113.0" + "@sentry/profiling-node": "npm:^7.113.0" "@sentry/tracing": "npm:^7.103.0" + "@sentry/types": "npm:^7.113.0" + "@types/body-parser": "npm:^1.19.5" + "@types/express": "npm:^4.17.21" "@types/jest": "npm:^29.5.12" "@types/jsonwebtoken": "npm:^9.0.6" "@types/morgan": "npm:^1.9.9" @@ -8322,6 +8443,15 @@ __metadata: languageName: node linkType: hard +"node-abi@npm:^3.61.0": + version: 3.62.0 + resolution: "node-abi@npm:3.62.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10/4cb9d4e6d3501bd9868230187f9f1638d777d1d2ca357389a2d411675889ee44375acbeae973b9c501fca723c9657d84684856787988a6327187f5f1e9ab6aee + languageName: node + linkType: hard + "node-cache@npm:^5.1.2": version: 5.1.2 resolution: "node-cache@npm:5.1.2" From ed6b30078f65131b52242ef223e24d80462b49ec Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 10:26:25 -0400 Subject: [PATCH 10/27] =?UTF-8?q?patch:=20se=20extrae=20el=20m=C3=A9todo?= =?UTF-8?q?=20para=20iniciar=20sentry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infrastructure/server/server.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index 622f6b8..e3cbd25 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -31,23 +31,27 @@ export default class Server { public constructor(port: number) { this.port = port; this.app = express(); - if(process.env.SENTRY_URL) { + this.initSentry(); + + this.config(); + this.listen(); + } + + private initSentry() { + if (process.env.SENTRY_URL) { Sentry.init({ dsn: process.env.SENTRY_URL, integrations: [ // enable HTTP calls tracing - new Sentry.Integrations.Http({ tracing: true }), + new Sentry.Integrations.Http({tracing: true}), // enable Express.js middleware tracing - new Sentry.Integrations.Express({ app: this.app }), + new Sentry.Integrations.Express({app: this.app}), nodeProfilingIntegration(), ], tracesSampleRate: 1.0, profilesSampleRate: 1.0, }); } - - this.config(); - this.listen(); } private config(): void { From 7bd0e742785921000981facced7ffabe263d7075 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 11:54:56 -0400 Subject: [PATCH 11/27] =?UTF-8?q?patch:=20optimizaci=C3=B3n=20de=20codigo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infrastructure/utils/credentials.utils.ts | 95 ++++++------------- 1 file changed, 29 insertions(+), 66 deletions(-) diff --git a/src/infrastructure/utils/credentials.utils.ts b/src/infrastructure/utils/credentials.utils.ts index 3654f1d..cf6a08b 100644 --- a/src/infrastructure/utils/credentials.utils.ts +++ b/src/infrastructure/utils/credentials.utils.ts @@ -16,52 +16,40 @@ export default class CredentialsUtils { return expirationDate < now; } - public static getMiUtemToken(authToken: string): string | undefined { + public static getMiUtemCookies(authToken: string): Cookie[] { const authTokenComponents = authToken.split("|"); if (authTokenComponents.length < 3) { - return; + return []; } const miUtemToken = authTokenComponents[0]; if (!CredentialsUtils.isBase64(miUtemToken)) { - return; - } - return miUtemToken; - } - - public static getMiUtemCookies(authToken: string): Cookie[] { - const token = CredentialsUtils.getMiUtemToken(authToken) - if (!token || token.length === 0) { - return []; - } - let data: string[] = atob(token).split("|"); // Formato: expira|cookie1|cookie2|cookie3... - data = data.filter(it => it && it.length > 0); - if (data.length <= 1) { // Valida el formato return []; } - if (CredentialsUtils.isCookieExpired(token)) { // Valida que no haya expirado - return []; - } - - - return data.slice(1).map(it => Cookie.parse(atob(it))); + return CredentialsUtils.parseCookiesFromToken(miUtemToken); } - public static getAcademiaToken(authToken: string): string | undefined { - const authTokenComponents = authToken.split("|"); + public static getAcademiaCookies(authToken: string): Cookie[] { + const authTokenComponents = authToken.split("|"); // Separa el token en sus partes if (authTokenComponents.length < 3) { - return; + console.error({ + authToken: 'Token no tiene las partes necesarias', + }) + return []; } - const academiaToken = authTokenComponents[2]; + const academiaToken = authTokenComponents[2]; // Obtiene el token de academia if (!CredentialsUtils.isBase64(academiaToken)) { - return; + console.error({ + academiaToken: 'Token de academia no es base64', + }) + return []; } - return academiaToken; + + return CredentialsUtils.parseCookiesFromToken(academiaToken); } - public static getAcademiaCookies(authToken: string): Cookie[] { - const token = CredentialsUtils.getAcademiaToken(authToken); + private static parseCookiesFromToken(token: string): Cookie[] { if (!token || token.length === 0) { return []; } @@ -80,17 +68,19 @@ export default class CredentialsUtils { } public static getSigaUser(sigaBearerToken: string): Usuario | null { - if (sigaBearerToken != null) { - const sigaPayload: any = jwt.decode(sigaBearerToken); - - return { - nombres: sigaPayload.given_name, - apellidos: sigaPayload.family_name, - nombreCompleto: sigaPayload.name, - correoUtem: sigaPayload.email, - username: sigaPayload.preferred_username, - }; + if (sigaBearerToken == null) { + return null } + + const sigaPayload: any = jwt.decode(sigaBearerToken); + + return { + nombres: sigaPayload.given_name, + apellidos: sigaPayload.family_name, + nombreCompleto: sigaPayload.name, + correoUtem: sigaPayload.email, + username: sigaPayload.preferred_username, + }; } public static async isMiUTEMTokenExpired(token: string): Promise { @@ -167,33 +157,6 @@ export default class CredentialsUtils { return `${miutemToken}|${sigaBearerToken}|${academiaToken}`; } - public static get emptyCookies(): object { - return [ - { - name: "sessionid", - value: "", - domain: "mi.utem.cl", - path: "/", - expires: -1, - httpOnly: true, - secure: false, - session: true, - sameSite: "Lax", - }, - { - name: "csrftoken", - value: "", - domain: "mi.utem.cl", - path: "/", - expires: -1, - httpOnly: false, - secure: false, - session: false, - sameSite: "Lax", - }, - ]; - } - private static isBase64(str: string): boolean { try { return btoa(atob(str)) == str; From 1684b462523018cea941fc54d19106c2fbfff014 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 12:14:39 -0400 Subject: [PATCH 12/27] =?UTF-8?q?patch:=20actualizado=20workflow=20y=20mej?= =?UTF-8?q?oras=20de=20c=C3=B3digo=20*=20Se=20actualiza=20version=20de=20a?= =?UTF-8?q?ctions/checkout=20*=20Mejorada=20lectura=20de=20c=C3=B3digo=20e?= =?UTF-8?q?n=20logger.utils.ts=20*=20Se=20agregan=20"migas"=20de=20sentry?= =?UTF-8?q?=20al=20recibir=20errores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tests.yml | 7 ++----- src/infrastructure/server/server.ts | 20 ++++++++++++++------ src/infrastructure/utils/logger.utils.ts | 8 +------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 24f2254..ddffff7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,7 +1,4 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs - -name: Node Tests +name: Node Test on: push: @@ -20,7 +17,7 @@ jobs: node-version: [18, 20] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: 'Setup Node.js' uses: actions/setup-node@v4 with: diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index e3cbd25..0ea9223 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -84,10 +84,6 @@ export default class Server { res: Response, next: NextFunction ) { - GenericLogger.log({ - level: "error", - message: err.stack, - }); if (err instanceof GenericError) { let uid: string; try { @@ -103,10 +99,21 @@ export default class Server { } } - console.error({ + Sentry.addBreadcrumb({ + category: 'error', message: 'Obtuvimos un error de tipo "GenericError" en el servidor', - error: err, + level: 'error', + data: { + error: err, + uid, + } }) + + + GenericLogger.log({ + level: "error", + message: err.stack, + }); res.statusCode = err.statusCode; res.json({ codigoHttp: err.statusCode ? err.statusCode : 500, @@ -115,6 +122,7 @@ export default class Server { error: err.message, }); } else { + Sentry.captureException(err); res.statusCode = 500; res.json({ codigoHttp: 500, diff --git a/src/infrastructure/utils/logger.utils.ts b/src/infrastructure/utils/logger.utils.ts index 579ea0b..c3c580f 100644 --- a/src/infrastructure/utils/logger.utils.ts +++ b/src/infrastructure/utils/logger.utils.ts @@ -45,13 +45,7 @@ export default class GenericLogger { ], }); - public static log({ - level = "info", - message = "", - }: { - level?: string; - message?: string; - }) { + public static log({ level = "info", message = "" }: { level?: string; message?: string; }) { this.logger.log({level, message}); } } From 2f167800e19ef05e855fda4bb3d5961b036e3c32 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 12:32:39 -0400 Subject: [PATCH 13/27] patch: arreglado sentry no recibe errores --- src/infrastructure/server/server.ts | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index 0ea9223..3eda062 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -85,10 +85,12 @@ export default class Server { next: NextFunction ) { if (err instanceof GenericError) { - let uid: string; + let uid: string = ''; try { - uid = HashUtils.md5(req.body.correo || '') - } catch { + uid = req.body.correo ? HashUtils.md5(req.body.correo) : '' + } catch {} + + if(uid.length == 0) { uid = `desconocido:${Math.random().toString(36).substring(7)}` } @@ -99,6 +101,13 @@ export default class Server { } } + Sentry.setUser({ id: uid, email: req.body.correo || '' }) + Sentry.addBreadcrumb({ + type: 'stacktrace', + category: 'stacktrace', + level: 'error', + message: err.stack, + }) Sentry.addBreadcrumb({ category: 'error', message: 'Obtuvimos un error de tipo "GenericError" en el servidor', @@ -110,17 +119,19 @@ export default class Server { }) - GenericLogger.log({ - level: "error", - message: err.stack, - }); + GenericLogger.log({ level: "error", message: err.stack }); res.statusCode = err.statusCode; - res.json({ + const error = { codigoHttp: err.statusCode ? err.statusCode : 500, mensaje: err.publicMessage ? err.publicMessage : "Error inesperado", codigoInterno: err.internalCode ? err.internalCode : 0, error: err.message, - }); + } + res.json(error); + Sentry.captureException({ + ...error, + error: err, + }) } else { Sentry.captureException(err); res.statusCode = 500; From be1810d1c60fcb0c6f5ff97baaf38309ceaa0071 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 12:33:54 -0400 Subject: [PATCH 14/27] =?UTF-8?q?patch:=20mejoras=20en=20recepci=C3=B3n=20?= =?UTF-8?q?de=20errores=20de=20sentry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infrastructure/server/server.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index 3eda062..6c85652 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -102,12 +102,6 @@ export default class Server { } Sentry.setUser({ id: uid, email: req.body.correo || '' }) - Sentry.addBreadcrumb({ - type: 'stacktrace', - category: 'stacktrace', - level: 'error', - message: err.stack, - }) Sentry.addBreadcrumb({ category: 'error', message: 'Obtuvimos un error de tipo "GenericError" en el servidor', @@ -121,19 +115,13 @@ export default class Server { GenericLogger.log({ level: "error", message: err.stack }); res.statusCode = err.statusCode; - const error = { + res.json({ codigoHttp: err.statusCode ? err.statusCode : 500, mensaje: err.publicMessage ? err.publicMessage : "Error inesperado", codigoInterno: err.internalCode ? err.internalCode : 0, error: err.message, - } - res.json(error); - Sentry.captureException({ - ...error, - error: err, - }) + }); } else { - Sentry.captureException(err); res.statusCode = 500; res.json({ codigoHttp: 500, @@ -142,6 +130,7 @@ export default class Server { error: err.toString(), }); } + Sentry.captureException(err); }); } From fed3972962555d839f85b66536e51b4e3de4df9b Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 18:22:53 -0400 Subject: [PATCH 15/27] =?UTF-8?q?patch:=20agregado=20identificaci=C3=B3n?= =?UTF-8?q?=20de=20usuario=20mediante=20siga=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infrastructure/server/server.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index 6c85652..9dea89d 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -12,6 +12,7 @@ import GenericLogger from "../utils/logger.utils"; import {HashUtils} from "../utils/hash.utils"; import {nodeProfilingIntegration} from "@sentry/profiling-node"; import * as process from "node:process"; +import CredentialsUtils from "../utils/credentials.utils"; const winstonMorganWriter = new stream.Writable(); winstonMorganWriter._write = function (chunk, encoding, done) { @@ -90,6 +91,19 @@ export default class Server { uid = req.body.correo ? HashUtils.md5(req.body.correo) : '' } catch {} + if(uid.length == 0) { + if(req.headers['authorization']) { + // Get siga token + const sigaToken = CredentialsUtils.getSigaToken(req.headers['authorization'] as string) + if(sigaToken?.length > 0) { + const sigaProfile = CredentialsUtils.getSigaUser(sigaToken); + try { + uid = sigaProfile.correoUtem ? HashUtils.md5(sigaProfile.correoUtem) : ''; + } catch {} + } + } + } + if(uid.length == 0) { uid = `desconocido:${Math.random().toString(36).substring(7)}` } From 255336b676ac559d5fa63b27b4ba960784951442 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Fri, 3 May 2024 18:28:22 -0400 Subject: [PATCH 16/27] =?UTF-8?q?patch:=20agregado=20m=C3=A1s=20datos=20de?= =?UTF-8?q?=20usuario=20para=20sentry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infrastructure/server/server.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index 9dea89d..0241e4e 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -86,43 +86,48 @@ export default class Server { next: NextFunction ) { if (err instanceof GenericError) { - let uid: string = ''; + let user = { + uid: '', + email: '', + } try { - uid = req.body.correo ? HashUtils.md5(req.body.correo) : '' + user.uid = req.body.correo ? HashUtils.md5(req.body.correo) : '' + user.email = req.body.correo || '' } catch {} - if(uid.length == 0) { + if(user.uid.length == 0) { if(req.headers['authorization']) { // Get siga token const sigaToken = CredentialsUtils.getSigaToken(req.headers['authorization'] as string) if(sigaToken?.length > 0) { const sigaProfile = CredentialsUtils.getSigaUser(sigaToken); try { - uid = sigaProfile.correoUtem ? HashUtils.md5(sigaProfile.correoUtem) : ''; + user.uid = sigaProfile.correoUtem ? HashUtils.md5(sigaProfile.correoUtem) : ''; + user.email = sigaProfile.correoUtem } catch {} } } } - if(uid.length == 0) { - uid = `desconocido:${Math.random().toString(36).substring(7)}` + if(user.uid.length == 0) { + user.uid = `desconocido:${Math.random().toString(36).substring(7)}` } if(((err.metadata || {})['uid'] || '') == '') { err.metadata = { ...err.metadata, - uid, + uid: user.uid, } } - Sentry.setUser({ id: uid, email: req.body.correo || '' }) + Sentry.setUser({ id: user.uid, email: user.email, ip_address: req.ip }) Sentry.addBreadcrumb({ category: 'error', message: 'Obtuvimos un error de tipo "GenericError" en el servidor', level: 'error', data: { error: err, - uid, + uid: user.uid, } }) From cacd4e0d6f12427acb06a071ce3bb88c524130ad Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Sat, 4 May 2024 10:07:45 -0400 Subject: [PATCH 17/27] patch: actualizado y mejorado cliente de openid --- .pnp.cjs | 29 ++++++++++++++++++--------- package.json | 3 ++- src/academia/services/auth.service.ts | 4 ++-- yarn.lock | 28 +++++++++++++++++--------- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/.pnp.cjs b/.pnp.cjs index 8bfc487..6cd52d6 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -38,6 +38,7 @@ const RAW_RUNTIME_STATE = ["@types/morgan", "npm:1.9.9"],\ ["@types/random-useragent", "npm:0.3.3"],\ ["@types/supertest", "npm:6.0.2"],\ + ["@types/uuid", "npm:9.0.8"],\ ["atob", "npm:2.1.2"],\ ["axios", "npm:1.6.7"],\ ["body-parser", "npm:1.20.2"],\ @@ -60,7 +61,7 @@ const RAW_RUNTIME_STATE = ["node-cache", "npm:5.1.2"],\ ["node-html", "npm:1.0.0-beta.63"],\ ["nodemon", "npm:3.1.0"],\ - ["openid-client", "npm:5.6.4"],\ + ["openid-client", "npm:5.6.5"],\ ["pdf-parse", "npm:1.1.1"],\ ["qs", "npm:6.11.2"],\ ["random-useragent", "npm:0.5.0"],\ @@ -4685,6 +4686,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@types/uuid", [\ + ["npm:9.0.8", {\ + "packageLocation": "./.yarn/cache/@types-uuid-npm-9.0.8-3eeeaa5abb-b8c60b7ba8.zip/node_modules/@types/uuid/",\ + "packageDependencies": [\ + ["@types/uuid", "npm:9.0.8"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@types/yargs", [\ ["npm:17.0.24", {\ "packageLocation": "./.yarn/cache/@types-yargs-npm-17.0.24-b034cf1d8b-03d9a985cb.zip/node_modules/@types/yargs/",\ @@ -9615,10 +9625,10 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ - ["npm:4.15.4", {\ - "packageLocation": "./.yarn/cache/jose-npm-4.15.4-c518ec3da8-20fa941597.zip/node_modules/jose/",\ + ["npm:4.15.5", {\ + "packageLocation": "./.yarn/cache/jose-npm-4.15.5-15e487a3a1-17944fcc0d.zip/node_modules/jose/",\ "packageDependencies": [\ - ["jose", "npm:4.15.4"]\ + ["jose", "npm:4.15.5"]\ ],\ "linkType": "HARD"\ }]\ @@ -10453,6 +10463,7 @@ const RAW_RUNTIME_STATE = ["@types/morgan", "npm:1.9.9"],\ ["@types/random-useragent", "npm:0.3.3"],\ ["@types/supertest", "npm:6.0.2"],\ + ["@types/uuid", "npm:9.0.8"],\ ["atob", "npm:2.1.2"],\ ["axios", "npm:1.6.7"],\ ["body-parser", "npm:1.20.2"],\ @@ -10475,7 +10486,7 @@ const RAW_RUNTIME_STATE = ["node-cache", "npm:5.1.2"],\ ["node-html", "npm:1.0.0-beta.63"],\ ["nodemon", "npm:3.1.0"],\ - ["openid-client", "npm:5.6.4"],\ + ["openid-client", "npm:5.6.5"],\ ["pdf-parse", "npm:1.1.1"],\ ["qs", "npm:6.11.2"],\ ["random-useragent", "npm:0.5.0"],\ @@ -11286,11 +11297,11 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["openid-client", [\ - ["npm:5.6.4", {\ - "packageLocation": "./.yarn/cache/openid-client-npm-5.6.4-9b740f7bb0-ab9b1ec59b.zip/node_modules/openid-client/",\ + ["npm:5.6.5", {\ + "packageLocation": "./.yarn/cache/openid-client-npm-5.6.5-5d3d2c2d1d-e843f39b3e.zip/node_modules/openid-client/",\ "packageDependencies": [\ - ["openid-client", "npm:5.6.4"],\ - ["jose", "npm:4.15.4"],\ + ["openid-client", "npm:5.6.5"],\ + ["jose", "npm:4.15.5"],\ ["lru-cache", "npm:6.0.0"],\ ["object-hash", "npm:2.2.0"],\ ["oidc-token-hash", "npm:5.0.3"]\ diff --git a/package.json b/package.json index 09f92ea..4c7ddae 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "morgan": "^1.10.0", "node-cache": "^5.1.2", "node-html": "^1.0.0-beta.63", - "openid-client": "^5.6.4", + "openid-client": "^5.6.5", "pdf-parse": "^1.1.1", "qs": "^6.11.2", "random-useragent": "^0.5.0", @@ -57,6 +57,7 @@ "@types/jsonwebtoken": "^9.0.6", "@types/random-useragent": "^0.3.3", "@types/supertest": "^6.0.2", + "@types/uuid": "^9.0.8", "cross-env": "^7.0.3", "jest": "^29.7.0", "nodemon": "^3.1.0", diff --git a/src/academia/services/auth.service.ts b/src/academia/services/auth.service.ts index 4f58921..872ae25 100644 --- a/src/academia/services/auth.service.ts +++ b/src/academia/services/auth.service.ts @@ -11,12 +11,12 @@ export class AcademiaUserService { const client = new academiaIssuer.Client({ // Genera un link cliente para el flujo de autorización. client_id: 'academiaClient', client_secret: process.env.ACADEMIA_CLIENT_SECRET, + redirect_uris: [`${process.env.ACADEMIA_UTEM_URL}/sso`], + response_types: ['code'], }); let oauthUri = client.authorizationUrl({ // Genera el link de autorización sso - redirect_uri: `${process.env.ACADEMIA_UTEM_URL}/sso`, scope: 'openid', - response_type: 'code', response_mode: 'fragment', nonce: uuid(), state: uuid(), diff --git a/yarn.lock b/yarn.lock index d221503..8a9e401 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2966,6 +2966,13 @@ __metadata: languageName: node linkType: hard +"@types/uuid@npm:^9.0.8": + version: 9.0.8 + resolution: "@types/uuid@npm:9.0.8" + checksum: 10/b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 + languageName: node + linkType: hard + "@types/yargs-parser@npm:*": version: 21.0.0 resolution: "@types/yargs-parser@npm:21.0.0" @@ -7265,10 +7272,10 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.15.4": - version: 4.15.4 - resolution: "jose@npm:4.15.4" - checksum: 10/20fa941597150dffc7af3f41d994500cc3e71cd650b755243dbd80d91cf26c1053f95b78af588f05cfc4371e492a67c5c7a48f689b8605145a8fe28b484d725b +"jose@npm:^4.15.5": + version: 4.15.5 + resolution: "jose@npm:4.15.5" + checksum: 10/17944fcc0d9afa07387eef23127c30ecfcc77eafddc4b4f1a349a8eee0536bee9b08ecd745406eaa0af65d531f738b94d2467976479cbfe8b3b60f8fc8082b8d languageName: node linkType: hard @@ -8013,6 +8020,7 @@ __metadata: "@types/morgan": "npm:^1.9.9" "@types/random-useragent": "npm:^0.3.3" "@types/supertest": "npm:^6.0.2" + "@types/uuid": "npm:^9.0.8" atob: "npm:^2.1.2" axios: "npm:^1.6.7" body-parser: "npm:^1.20.2" @@ -8035,7 +8043,7 @@ __metadata: node-cache: "npm:^5.1.2" node-html: "npm:^1.0.0-beta.63" nodemon: "npm:^3.1.0" - openid-client: "npm:^5.6.4" + openid-client: "npm:^5.6.5" pdf-parse: "npm:^1.1.1" qs: "npm:^6.11.2" random-useragent: "npm:^0.5.0" @@ -8778,15 +8786,15 @@ __metadata: languageName: node linkType: hard -"openid-client@npm:^5.6.4": - version: 5.6.4 - resolution: "openid-client@npm:5.6.4" +"openid-client@npm:^5.6.5": + version: 5.6.5 + resolution: "openid-client@npm:5.6.5" dependencies: - jose: "npm:^4.15.4" + jose: "npm:^4.15.5" lru-cache: "npm:^6.0.0" object-hash: "npm:^2.2.0" oidc-token-hash: "npm:^5.0.3" - checksum: 10/ab9b1ec59be68f13b10c4e4eb1979e204d211701b139c2363e58faeb4bb0b67e26782fd2080d7488bb3e7e2ebc3c2aac43cff7284c3da3723cfe4f9b29852c24 + checksum: 10/e843f39b3eac07d9a415d8524745d722df0298708e58ac4e13b2642a34b2211591d2c9a58d6f4e29826b678856965454bcfa5148a030c7eef53178ceff48d8ee languageName: node linkType: hard From 9843a7f04e07c6d00d1e262640cb844ab614df56 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Sat, 4 May 2024 11:56:54 -0400 Subject: [PATCH 18/27] patch: arreglado login academia --- src/academia/services/auth.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/academia/services/auth.service.ts b/src/academia/services/auth.service.ts index 872ae25..be7b917 100644 --- a/src/academia/services/auth.service.ts +++ b/src/academia/services/auth.service.ts @@ -11,7 +11,7 @@ export class AcademiaUserService { const client = new academiaIssuer.Client({ // Genera un link cliente para el flujo de autorización. client_id: 'academiaClient', client_secret: process.env.ACADEMIA_CLIENT_SECRET, - redirect_uris: [`${process.env.ACADEMIA_UTEM_URL}/sso`], + redirect_uris: [`${process.env.ACADEMIA_UTEM_URL}/sso`.trim()], response_types: ['code'], }); @@ -29,7 +29,7 @@ export class AcademiaUserService { tokenSet = await client.grant({ // Obtiene el token de autorización grant_type: 'authorization_code', code: urlParams.get('code'), - redirect_uri: `${process.env.ACADEMIA_UTEM_URL}/sso`, + redirect_uri: `${process.env.ACADEMIA_UTEM_URL}/sso`.trim(), }) } catch (error) { let err = GenericError.ACADEMIA_EXPIRO From c062adb7a94b68507d21b2654483cc25804cdc06 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Sat, 4 May 2024 12:34:48 -0400 Subject: [PATCH 19/27] patch: se agrega timezone a algunas condiciones --- src/core/controllers/beca-alimentacion.controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/controllers/beca-alimentacion.controller.ts b/src/core/controllers/beca-alimentacion.controller.ts index 3f7b703..055d149 100644 --- a/src/core/controllers/beca-alimentacion.controller.ts +++ b/src/core/controllers/beca-alimentacion.controller.ts @@ -33,13 +33,13 @@ export class BecaAlimentacionController { } // Verifica si es entre hoy a las 00:00 y 40 días después - if (!dayjs(desde).isSameOrAfter(ahora.startOf('day'))) { // Si no esta hoy o después + if (!dayjs(desde).tz('America/Santiago').isSameOrAfter(ahora.startOf('day'))) { // Si no esta hoy o después const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.1 return next(error) } - if (!dayjs(ahora).isSameOrBefore(dayjs().tz('America/Santiago').endOf('year'))) { // Si no está entre fin de año o antes + if (!dayjs(ahora).tz('America/Santiago').isSameOrBefore(dayjs().tz('America/Santiago').endOf('year'))) { // Si no está entre fin de año o antes const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.2 return next(error) From 9c6b8902346f9a5cd3ffc6dd988e8361e2f7c2fd Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 6 May 2024 10:41:35 -0400 Subject: [PATCH 20/27] =?UTF-8?q?patch:=20arreglos=20a=20la=20beca=20de=20?= =?UTF-8?q?alimentaci=C3=B3n=20y=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infrastructure/server/server.ts | 19 ++++++++----------- test/academia.test.ts | 6 +++--- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/infrastructure/server/server.ts b/src/infrastructure/server/server.ts index 0241e4e..8e88ff2 100644 --- a/src/infrastructure/server/server.ts +++ b/src/infrastructure/server/server.ts @@ -95,17 +95,14 @@ export default class Server { user.email = req.body.correo || '' } catch {} - if(user.uid.length == 0) { - if(req.headers['authorization']) { - // Get siga token - const sigaToken = CredentialsUtils.getSigaToken(req.headers['authorization'] as string) - if(sigaToken?.length > 0) { - const sigaProfile = CredentialsUtils.getSigaUser(sigaToken); - try { - user.uid = sigaProfile.correoUtem ? HashUtils.md5(sigaProfile.correoUtem) : ''; - user.email = sigaProfile.correoUtem - } catch {} - } + if(user.uid.length == 0 && req.headers['authorization']) { // Agrega datos para identificar al usuario de la token de siga + const sigaToken = CredentialsUtils.getSigaToken(req.headers['authorization'] as string) + if(sigaToken?.length > 0) { + const sigaProfile = CredentialsUtils.getSigaUser(sigaToken); + try { + user.uid = sigaProfile.correoUtem ? HashUtils.md5(sigaProfile.correoUtem) : ''; + user.email = sigaProfile.correoUtem + } catch {} } } diff --git a/test/academia.test.ts b/test/academia.test.ts index 6775bdf..c210cda 100644 --- a/test/academia.test.ts +++ b/test/academia.test.ts @@ -52,8 +52,8 @@ describe('Prueba de Academia', () => { .post('/v1/beca-alimentacion') .set('Authorization', `Bearer ${token}`) .send({ - desde: dayjs().format('YYYY-MM-DD'), - hasta: dayjs().add(6, 'day').format('YYYY-MM-DD'), + desde: dayjs().tz('America/Santiago').format('YYYY-MM-DD'), + hasta: dayjs().tz('America/Santiago').add(6, 'day').format('YYYY-MM-DD'), }) expect(res.statusCode).toEqual(200) @@ -63,7 +63,7 @@ describe('Prueba de Academia', () => { if ((currentMonth === 3 || currentMonth === 5) || (currentMonth >= 8 && currentMonth <= 11)) { expect(res.body.length).toBeGreaterThan(0) // Esperar que contenga algun codigo que contenga la vigenca de la beca - expect((res.body || []).find(it => dayjs(it.validoPara).isBetween(dayjs().format('YYYY-MM-DD'), dayjs().add(6, 'day').format('YYYY-MM-DD')))).toBeTruthy() + expect((res.body || []).find(it => dayjs(it.validoPara).tz('America/Santiago').isBetween(dayjs().tz('America/Santiago').format('YYYY-MM-DD'), dayjs().tz('America/Santiago').add(6, 'day').format('YYYY-MM-DD')))).toBeTruthy() } }); }); From e95621cb96f864193671aeafabdf6d5a57b0f2ae Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 6 May 2024 10:48:39 -0400 Subject: [PATCH 21/27] =?UTF-8?q?patch:=20reparado=20condicionales=20de=20?= =?UTF-8?q?beca=20de=20alimentaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beca-alimentacion.controller.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/controllers/beca-alimentacion.controller.ts b/src/core/controllers/beca-alimentacion.controller.ts index 055d149..1a1fac5 100644 --- a/src/core/controllers/beca-alimentacion.controller.ts +++ b/src/core/controllers/beca-alimentacion.controller.ts @@ -20,32 +20,32 @@ export class BecaAlimentacionController { return next(error) } - const ahora = dayjs().tz('America/Santiago') // Hoy a las 00:00 + const ahora = dayjs().tz('America/Santiago') const cookies = res.locals.loggedInUser.academiaCookies; - const desde = (req.body.desde ? dayjs(req.body.desde, 'YYYY-MM-DD').tz('America/Santiago') : ahora).startOf('day'); - let hasta = (req.body.hasta ? dayjs(req.body.hasta, 'YYYY-MM-DD').tz('America/Santiago') : ahora).endOf('day'); - hasta.isBefore(desde) && (hasta = desde.endOf('day')); + const desdeInicioCodigo = ((req.body.desde ? dayjs(req.body.desde, 'YYYY-MM-DD').tz('America/Santiago') : ahora).startOf('day')); + let hastaDiaCodigo = (req.body.hasta ? dayjs(req.body.hasta, 'YYYY-MM-DD').tz('America/Santiago') : ahora).endOf('day'); + hastaDiaCodigo.isBefore(desdeInicioCodigo) && (hastaDiaCodigo = desdeInicioCodigo.endOf('day')); - // Si es desde sabado hasta domingo lanzar error - if (dayjs(desde).tz('America/Santiago').day() === 6 && dayjs(hasta).tz('America/Santiago').day() === 0) { - return next(GenericError.FUERA_DE_HORARIO_BECA_ALIMENTACION) // Si es sabado o domingo, no se puede generar codigo. + // Si es desde Sábado hasta domingo lanzar error + if (desdeInicioCodigo.day() === 6 && hastaDiaCodigo.day() === 0) { + return next(GenericError.FUERA_DE_HORARIO_BECA_ALIMENTACION) // Si es Sábado o domingo, no se puede generar código. } - // Verifica si es entre hoy a las 00:00 y 40 días después - if (!dayjs(desde).tz('America/Santiago').isSameOrAfter(ahora.startOf('day'))) { // Si no esta hoy o después + // Verifica si es entre hoy a las 00:00 y ahora + if (!ahora.isSameOrAfter(desdeInicioCodigo)) { // Si no esta hoy o después const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.1 return next(error) } - if (!dayjs(ahora).tz('America/Santiago').isSameOrBefore(dayjs().tz('America/Santiago').endOf('year'))) { // Si no está entre fin de año o antes + if (!ahora.isSameOrBefore(dayjs().tz('America/Santiago').endOf('year'))) { // Si no está entre fin de año o antes const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.2 return next(error) } - const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desde.toISOString(), hasta.toISOString()) + const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desdeInicioCodigo.toISOString(), hastaDiaCodigo.toISOString()) res.status(200).json(codigos); } catch (error) { From 9c5a1951e12e82611f962d3ad3faa65fbbe8a996 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 6 May 2024 15:11:30 -0400 Subject: [PATCH 22/27] =?UTF-8?q?patch:=20arreglos=20a=20la=20beca=20de=20?= =?UTF-8?q?alimentaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/controllers/beca-alimentacion.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/controllers/beca-alimentacion.controller.ts b/src/core/controllers/beca-alimentacion.controller.ts index 1a1fac5..e657453 100644 --- a/src/core/controllers/beca-alimentacion.controller.ts +++ b/src/core/controllers/beca-alimentacion.controller.ts @@ -33,7 +33,7 @@ export class BecaAlimentacionController { } // Verifica si es entre hoy a las 00:00 y ahora - if (!ahora.isSameOrAfter(desdeInicioCodigo)) { // Si no esta hoy o después + if (!desdeInicioCodigo.isSameOrAfter(ahora.startOf('day'))) { // Si no esta hoy o después const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.1 return next(error) From ec020f253167bb69c2e2d5f3a5fefff09be96092 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 6 May 2024 15:18:53 -0400 Subject: [PATCH 23/27] patch: agregado datos de metadata para logging de error --- .../beca-alimentacion.controller.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/core/controllers/beca-alimentacion.controller.ts b/src/core/controllers/beca-alimentacion.controller.ts index e657453..e7ad43d 100644 --- a/src/core/controllers/beca-alimentacion.controller.ts +++ b/src/core/controllers/beca-alimentacion.controller.ts @@ -8,34 +8,39 @@ export class BecaAlimentacionController { public static async solicitarCodigoBecaAlimentacion(req: Request, res: Response, next: NextFunction): Promise { try { - if (req.body.desde && !dayjs(req.body.desde, 'YYYY-MM-DD').tz('America/Santiago').isValid()) { + const desde: string | undefined = req.body.desde; + if (desde && !dayjs(desde, 'YYYY-MM-DD').tz('America/Santiago').isValid()) { const error = GenericError.FORMATO_FECHA_INVALIDO error.internalCode = 18.1 return next(error) } - if (req.body.hasta && !dayjs(req.body.hasta, 'YYYY-MM-DD').tz('America/Santiago').isValid()) { + const hasta: string | undefined = req.body.hasta; + if (hasta && !dayjs(hasta, 'YYYY-MM-DD').tz('America/Santiago').isValid()) { const error = GenericError.FORMATO_FECHA_INVALIDO error.internalCode = 18.2 return next(error) } const ahora = dayjs().tz('America/Santiago') - - const cookies = res.locals.loggedInUser.academiaCookies; - const desdeInicioCodigo = ((req.body.desde ? dayjs(req.body.desde, 'YYYY-MM-DD').tz('America/Santiago') : ahora).startOf('day')); - let hastaDiaCodigo = (req.body.hasta ? dayjs(req.body.hasta, 'YYYY-MM-DD').tz('America/Santiago') : ahora).endOf('day'); - hastaDiaCodigo.isBefore(desdeInicioCodigo) && (hastaDiaCodigo = desdeInicioCodigo.endOf('day')); + const desdeDayJS = ((desde ? dayjs(desde, 'YYYY-MM-DD').tz('America/Santiago') : ahora).startOf('day')); + let hastaDayJS = (hasta ? dayjs(hasta, 'YYYY-MM-DD').tz('America/Santiago') : ahora).endOf('day'); + hastaDayJS.isBefore(desdeDayJS) && (hastaDayJS = desdeDayJS.endOf('day')); // Si es desde Sábado hasta domingo lanzar error - if (desdeInicioCodigo.day() === 6 && hastaDiaCodigo.day() === 0) { + if (desdeDayJS.day() === 6 && hastaDayJS.day() === 0) { return next(GenericError.FUERA_DE_HORARIO_BECA_ALIMENTACION) // Si es Sábado o domingo, no se puede generar código. } - // Verifica si es entre hoy a las 00:00 y ahora - if (!desdeInicioCodigo.isSameOrAfter(ahora.startOf('day'))) { // Si no esta hoy o después + if (!desdeDayJS.isSameOrAfter(ahora.startOf('day'))) { // Si no esta hoy o después const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.1 + error.metadata = { + ...error.metadata, + desde: desdeDayJS.toISOString(), + ahora: ahora.startOf('day').toISOString(), + sameOrAfter: desdeDayJS.isSameOrAfter(ahora.startOf('day')) + } return next(error) } @@ -45,7 +50,8 @@ export class BecaAlimentacionController { return next(error) } - const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desdeInicioCodigo.toISOString(), hastaDiaCodigo.toISOString()) + const cookies = res.locals.loggedInUser.academiaCookies; + const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desdeDayJS.toISOString(), hastaDayJS.toISOString()) res.status(200).json(codigos); } catch (error) { From 2e3263defc64f63df4f264fccc04a3ba390a69ca Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 6 May 2024 15:42:25 -0400 Subject: [PATCH 24/27] =?UTF-8?q?patch:=20agregado=20m=C3=A1s=20tests=20y?= =?UTF-8?q?=20reparados=20errores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beca-alimentacion.controller.ts | 44 +++++++++------- test/academia.test.ts | 50 ++++++++++++++++++- 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/core/controllers/beca-alimentacion.controller.ts b/src/core/controllers/beca-alimentacion.controller.ts index e7ad43d..33e29d6 100644 --- a/src/core/controllers/beca-alimentacion.controller.ts +++ b/src/core/controllers/beca-alimentacion.controller.ts @@ -8,50 +8,56 @@ export class BecaAlimentacionController { public static async solicitarCodigoBecaAlimentacion(req: Request, res: Response, next: NextFunction): Promise { try { - const desde: string | undefined = req.body.desde; - if (desde && !dayjs(desde, 'YYYY-MM-DD').tz('America/Santiago').isValid()) { + const ahora = dayjs().tz('America/Santiago') + const desde = dayjs(req.body.desde || ahora.format('YYYY-MM-DD'), 'YYYY-MM-DD', true).tz('America/Santiago').startOf('day'); + if (!desde.isValid()) { const error = GenericError.FORMATO_FECHA_INVALIDO error.internalCode = 18.1 + error.publicMessage = `La fecha de inicio '${req.body.desde}' es inválida. Debe ser en formato YYYY-MM-DD.` return next(error) } - const hasta: string | undefined = req.body.hasta; - if (hasta && !dayjs(hasta, 'YYYY-MM-DD').tz('America/Santiago').isValid()) { + let hasta = dayjs(req.body.hasta || ahora.format('YYYY-MM-DD'), 'YYYY-MM-DD', true).tz('America/Santiago').endOf('day'); + hasta.isBefore(desde) && (hasta = desde.endOf('day')); + if (!hasta.isValid()) { const error = GenericError.FORMATO_FECHA_INVALIDO error.internalCode = 18.2 + error.publicMessage = `La fecha de término '${req.body.hasta}' es inválida. Debe ser en formato YYYY-MM-DD.` return next(error) } - const ahora = dayjs().tz('America/Santiago') - const desdeDayJS = ((desde ? dayjs(desde, 'YYYY-MM-DD').tz('America/Santiago') : ahora).startOf('day')); - let hastaDayJS = (hasta ? dayjs(hasta, 'YYYY-MM-DD').tz('America/Santiago') : ahora).endOf('day'); - hastaDayJS.isBefore(desdeDayJS) && (hastaDayJS = desdeDayJS.endOf('day')); - // Si es desde Sábado hasta domingo lanzar error - if (desdeDayJS.day() === 6 && hastaDayJS.day() === 0) { - return next(GenericError.FUERA_DE_HORARIO_BECA_ALIMENTACION) // Si es Sábado o domingo, no se puede generar código. + if (desde.day() === 6 && hasta.day() === 0) { + const error = GenericError.FUERA_DE_HORARIO_BECA_ALIMENTACION + error.publicMessage = 'No se puede generar código de beca de alimentación para fines de semana.' + return next(error) // Si es Sábado o domingo, no se puede generar código. } - if (!desdeDayJS.isSameOrAfter(ahora.startOf('day'))) { // Si no esta hoy o después + // Si desde no es ahora o después + if (!desde.isSameOrAfter(ahora.startOf('day'))) { const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.1 - error.metadata = { - ...error.metadata, - desde: desdeDayJS.toISOString(), - ahora: ahora.startOf('day').toISOString(), - sameOrAfter: desdeDayJS.isSameOrAfter(ahora.startOf('day')) - } + error.publicMessage = 'La fecha de inicio debe ser hoy o después.' + return next(error) + } + + if(!hasta.isAfter(desde)) { + const error = GenericError.FECHA_FUERA_DE_RANGO + error.internalCode = 19.3 + error.publicMessage = 'La fecha de término debe ser después de la fecha de inicio.' return next(error) } + // Si ahora no es antes de fin de año if (!ahora.isSameOrBefore(dayjs().tz('America/Santiago').endOf('year'))) { // Si no está entre fin de año o antes const error = GenericError.FECHA_FUERA_DE_RANGO error.internalCode = 19.2 + error.publicMessage = 'La fecha de inicio debe ser antes de fin de año.' return next(error) } const cookies = res.locals.loggedInUser.academiaCookies; - const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desdeDayJS.toISOString(), hastaDayJS.toISOString()) + const codigos: CodigoBecaAlimentacion[] = await BecaAlimentacionService.generarCodigoAlimentacion(cookies, desde.toISOString(), hasta.toISOString()) res.status(200).json(codigos); } catch (error) { diff --git a/test/academia.test.ts b/test/academia.test.ts index c210cda..a8fbbc4 100644 --- a/test/academia.test.ts +++ b/test/academia.test.ts @@ -7,7 +7,7 @@ const correo = process.env.USER_EMAIL || ""; const contrasenia = process.env.USER_PASSWORD || ""; describe('Prueba de Academia', () => { - it('Solicitud de Beca de Alimentación (Día Especifico)', async () => { + test('Solicitud de Beca de Alimentación (Día Especifico)', async () => { let res = await request(server.app) .post('/v1/auth') .send({ @@ -36,7 +36,7 @@ describe('Prueba de Academia', () => { } }, 60000) - it('Solicitud de Beca de Alimentación (Toda la Semana)', async () => { + test('Solicitud de Beca de Alimentación (Toda la Semana)', async () => { let res = await request(server.app) .post('/v1/auth') @@ -66,6 +66,52 @@ describe('Prueba de Academia', () => { expect((res.body || []).find(it => dayjs(it.validoPara).tz('America/Santiago').isBetween(dayjs().tz('America/Santiago').format('YYYY-MM-DD'), dayjs().tz('America/Santiago').add(6, 'day').format('YYYY-MM-DD')))).toBeTruthy() } }); + + test('Solicitud de Beca de Alimentación (Desde Fecha Pasada)', async () => { + + let res = await request(server.app) + .post('/v1/auth') + .send({ + correo: correo, + contrasenia: contrasenia + }) + expect(res.statusCode).toEqual(200) + + const token = res.body.token; + + res = await request(server.app) + .post('/v1/beca-alimentacion') + .set('Authorization', `Bearer ${token}`) + .send({ + desde: dayjs().tz('America/Santiago').subtract(1, 'day').format('YYYY-MM-DD'), + hasta: dayjs().tz('America/Santiago').add(6, 'day').format('YYYY-MM-DD'), + }) + + expect(res.statusCode).toEqual(400) + }); + + test('Solicitud de Beca de Alimentación (Hasta Fecha Pasada a Desde)', async () => { + + let res = await request(server.app) + .post('/v1/auth') + .send({ + correo: correo, + contrasenia: contrasenia + }) + expect(res.statusCode).toEqual(200) + + const token = res.body.token; + + res = await request(server.app) + .post('/v1/beca-alimentacion') + .set('Authorization', `Bearer ${token}`) + .send({ + desde: dayjs().tz('America/Santiago').format('YYYY-MM-DD'), + hasta: dayjs().tz('America/Santiago').subtract(3, 'day').format('YYYY-MM-DD'), + }) + + expect(res.statusCode).toEqual(200) // Aunque la fecha de término sea antes de la fecha de inicio, se generará el codigo para hoy + }); }); afterAll(done => { From b1582b4d62316a380a54dcf03f957a7fa3972484 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 6 May 2024 15:46:54 -0400 Subject: [PATCH 25/27] patch: se agrega time zone --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ddffff7..d414283 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,6 +10,8 @@ jobs: build: name: Tests environment: api-mi-utem + env: + TZ: America/Santiago runs-on: ubuntu-latest strategy: From 05b055e55a9af5a86f288a175483a5407512b005 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Mon, 6 May 2024 15:50:13 -0400 Subject: [PATCH 26/27] patch: se agregan timeouts a los tests --- test/academia.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/academia.test.ts b/test/academia.test.ts index a8fbbc4..cac6e46 100644 --- a/test/academia.test.ts +++ b/test/academia.test.ts @@ -65,7 +65,7 @@ describe('Prueba de Academia', () => { // Esperar que contenga algun codigo que contenga la vigenca de la beca expect((res.body || []).find(it => dayjs(it.validoPara).tz('America/Santiago').isBetween(dayjs().tz('America/Santiago').format('YYYY-MM-DD'), dayjs().tz('America/Santiago').add(6, 'day').format('YYYY-MM-DD')))).toBeTruthy() } - }); + }, 60000); test('Solicitud de Beca de Alimentación (Desde Fecha Pasada)', async () => { @@ -88,7 +88,7 @@ describe('Prueba de Academia', () => { }) expect(res.statusCode).toEqual(400) - }); + }, 60000); test('Solicitud de Beca de Alimentación (Hasta Fecha Pasada a Desde)', async () => { @@ -111,7 +111,7 @@ describe('Prueba de Academia', () => { }) expect(res.statusCode).toEqual(200) // Aunque la fecha de término sea antes de la fecha de inicio, se generará el codigo para hoy - }); + }, 60000); }); afterAll(done => { From eaf4d5f44dac3ec341e3348b5e2637d941644bf2 Mon Sep 17 00:00:00 2001 From: Francisco Solis <30329003+Im-Fran@users.noreply.github.com> Date: Sat, 18 May 2024 11:00:00 -0400 Subject: [PATCH 27/27] patch: orden de clases y archivos * Se elimina la carpeta 'infrastructure' a favor de la carpeta 'core' * Se mueven los modelos de 'infrastructure' a 'core/models/internal' * Se mueven algunos modelos a sus respectivos dominios * Arreglos varios --- .../models/codigo-beca-alimentacion.model.ts | 0 src/academia/services/auth.service.ts | 4 +-- .../services/beca-alimentacion.service.ts | 6 ++-- src/app.ts | 2 +- src/core/controllers/asignatura.controller.ts | 11 ++---- src/core/controllers/auth.controller.ts | 10 +++--- .../beca-alimentacion.controller.ts | 4 +-- src/core/controllers/carrera.controller.ts | 2 +- .../controllers/notificacion.controller.ts | 4 +-- src/core/controllers/permiso.controller.ts | 4 +-- src/core/controllers/usuario.controller.ts | 4 +-- .../academia-credentials.middleware.ts | 4 +-- .../credentials/credentials.middleware.ts | 2 +- .../miutem-credentials.middleware.ts | 4 +-- .../siga-credentials.middleware.ts | 4 +-- .../models/internal}/cookie.model.ts | 0 .../models/internal}/error.model.ts | 0 src/core/routes/asignatura.routes.ts | 4 +-- src/core/routes/beca-alimentacion.routes.ts | 2 +- src/core/routes/carrera.routes.ts | 2 +- src/core/routes/horario.routes.ts | 2 +- src/core/routes/permiso.routes.ts | 2 +- src/core/routes/usuario.routes.ts | 2 +- src/{infrastructure/server => core}/server.ts | 10 +++--- .../utils/credentials.utils.ts | 4 +-- .../utils/fcm.utils.ts | 0 .../utils/files.utils.ts | 0 .../utils/hash.utils.ts | 0 .../utils/logger.utils.ts | 0 src/keycloak/services/user.service.ts | 4 +-- src/{core => mi-utem}/models/permiso.model.ts | 0 .../models/semestre.model.ts | 2 +- src/mi-utem/services/asignatura.service.ts | 28 ++------------- src/mi-utem/services/auth.service.ts | 4 +-- src/mi-utem/services/carrera.service.ts | 35 ------------------- src/mi-utem/services/horario.service.ts | 4 +-- src/mi-utem/services/nota.service.ts | 4 +-- src/mi-utem/services/permiso.service.ts | 6 ++-- src/mi-utem/services/user.service.ts | 4 +-- .../models/carrera.model.ts | 0 src/siga-api/services/asignatura.service.ts | 11 ++---- src/siga-api/services/auth.service.ts | 6 ++-- src/siga-api/services/carrera.service.ts | 2 +- 43 files changed, 67 insertions(+), 136 deletions(-) rename src/{core => academia}/models/codigo-beca-alimentacion.model.ts (100%) rename src/{infrastructure => core}/middlewares/credentials/academia-credentials.middleware.ts (87%) rename src/{infrastructure => core}/middlewares/credentials/credentials.middleware.ts (94%) rename src/{infrastructure => core}/middlewares/credentials/miutem-credentials.middleware.ts (91%) rename src/{infrastructure => core}/middlewares/credentials/siga-credentials.middleware.ts (91%) rename src/{infrastructure/models => core/models/internal}/cookie.model.ts (100%) rename src/{infrastructure/models => core/models/internal}/error.model.ts (100%) rename src/{infrastructure/server => core}/server.ts (95%) rename src/{infrastructure => core}/utils/credentials.utils.ts (98%) rename src/{infrastructure => core}/utils/fcm.utils.ts (100%) rename src/{infrastructure => core}/utils/files.utils.ts (100%) rename src/{infrastructure => core}/utils/hash.utils.ts (100%) rename src/{infrastructure => core}/utils/logger.utils.ts (100%) rename src/{core => mi-utem}/models/permiso.model.ts (100%) rename src/{core => mi-utem}/models/semestre.model.ts (59%) delete mode 100644 src/mi-utem/services/carrera.service.ts rename src/{core => siga-api}/models/carrera.model.ts (100%) diff --git a/src/core/models/codigo-beca-alimentacion.model.ts b/src/academia/models/codigo-beca-alimentacion.model.ts similarity index 100% rename from src/core/models/codigo-beca-alimentacion.model.ts rename to src/academia/models/codigo-beca-alimentacion.model.ts diff --git a/src/academia/services/auth.service.ts b/src/academia/services/auth.service.ts index be7b917..ff40492 100644 --- a/src/academia/services/auth.service.ts +++ b/src/academia/services/auth.service.ts @@ -1,8 +1,8 @@ import axios from "axios"; import { Issuer } from "openid-client"; import { v4 as uuid } from 'uuid'; -import Cookie from "../../infrastructure/models/cookie.model"; -import GenericError from "../../infrastructure/models/error.model"; +import Cookie from "../../core/models/internal/cookie.model"; +import GenericError from "../../core/models/internal/error.model"; import { KeycloakUserService } from "../../keycloak/services/user.service"; export class AcademiaUserService { diff --git a/src/academia/services/beca-alimentacion.service.ts b/src/academia/services/beca-alimentacion.service.ts index e9c646b..c5cd637 100644 --- a/src/academia/services/beca-alimentacion.service.ts +++ b/src/academia/services/beca-alimentacion.service.ts @@ -1,9 +1,9 @@ -import Cookie from "../../infrastructure/models/cookie.model"; +import Cookie from "../../core/models/internal/cookie.model"; import {AcademiaUserService} from "./auth.service"; -import GenericError from "../../infrastructure/models/error.model"; +import GenericError from "../../core/models/internal/error.model"; import axios from "axios"; import * as cheerio from 'cheerio'; -import CodigoBecaAlimentacion from "../../core/models/codigo-beca-alimentacion.model"; +import CodigoBecaAlimentacion from "../models/codigo-beca-alimentacion.model"; import {dayjs} from "../../app"; import * as fs from "node:fs"; diff --git a/src/app.ts b/src/app.ts index e6c64c8..12568f9 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,5 @@ import * as firebaseAdmin from "firebase-admin"; -import Server from "./infrastructure/server/server"; +import Server from "./core/server"; import dayjs from 'dayjs' import 'dayjs/locale/es' diff --git a/src/core/controllers/asignatura.controller.ts b/src/core/controllers/asignatura.controller.ts index c17f421..d64937f 100644 --- a/src/core/controllers/asignatura.controller.ts +++ b/src/core/controllers/asignatura.controller.ts @@ -1,8 +1,8 @@ import {NextFunction, Request, Response} from "express"; import {SigaApiAsignaturaService} from "../../siga-api/services/asignatura.service"; import SeccionAsignatura from "../models/seccion-asignatura.model"; -import Semestre from "../models/semestre.model"; -import Cookie from "../../infrastructure/models/cookie.model"; +import Semestre from "../../mi-utem/models/semestre.model"; +import Cookie from "../models/internal/cookie.model"; import {MiUtemNotaService} from "../../mi-utem/services/nota.service"; import {MiUtemAsignaturaService} from "../../mi-utem/services/asignatura.service"; @@ -27,12 +27,7 @@ export class AsignaturaController { const carreraId: string = req.params.carreraId; const seccionId: string = req.params.seccionId; - const asignatura: SeccionAsignatura = - await SigaApiAsignaturaService.getNotasAsignatura( - sigaToken, - carreraId, - seccionId - ); + const asignatura: SeccionAsignatura = await SigaApiAsignaturaService.getNotasAsignatura(sigaToken, carreraId, seccionId); res.status(200).json(asignatura); } catch (error) { diff --git a/src/core/controllers/auth.controller.ts b/src/core/controllers/auth.controller.ts index 1e8badb..7d263d3 100644 --- a/src/core/controllers/auth.controller.ts +++ b/src/core/controllers/auth.controller.ts @@ -1,15 +1,15 @@ import { NextFunction, Request, Response } from "express"; import { AcademiaUserService } from "../../academia/services/auth.service"; -import { CredentialsMiddleware } from "../../infrastructure/middlewares/credentials/credentials.middleware"; -import Cookie from "../../infrastructure/models/cookie.model"; -import GenericError from "../../infrastructure/models/error.model"; -import CredentialsUtils from "../../infrastructure/utils/credentials.utils"; +import { CredentialsMiddleware } from "../middlewares/credentials/credentials.middleware"; +import Cookie from "../models/internal/cookie.model"; +import GenericError from "../models/internal/error.model"; +import CredentialsUtils from "../utils/credentials.utils"; import { MiUtemAuthService } from "../../mi-utem/services/auth.service"; import { MiUtemUserService } from "../../mi-utem/services/user.service"; import { SigaApiAuthService } from "../../siga-api/services/auth.service"; import Usuario from "../models/usuario.model"; import {cache} from "../../app"; -import {HashUtils} from "../../infrastructure/utils/hash.utils"; +import {HashUtils} from "../utils/hash.utils"; export class AuthController { public static async login(req: Request, res: Response, next: NextFunction): Promise { diff --git a/src/core/controllers/beca-alimentacion.controller.ts b/src/core/controllers/beca-alimentacion.controller.ts index 33e29d6..70bcfe7 100644 --- a/src/core/controllers/beca-alimentacion.controller.ts +++ b/src/core/controllers/beca-alimentacion.controller.ts @@ -1,8 +1,8 @@ import {NextFunction, Request, Response} from "express"; import {BecaAlimentacionService} from "../../academia/services/beca-alimentacion.service"; -import CodigoBecaAlimentacion from "../models/codigo-beca-alimentacion.model"; +import CodigoBecaAlimentacion from "../../academia/models/codigo-beca-alimentacion.model"; import {dayjs} from "../../app"; -import GenericError from "../../infrastructure/models/error.model"; +import GenericError from "../models/internal/error.model"; export class BecaAlimentacionController { diff --git a/src/core/controllers/carrera.controller.ts b/src/core/controllers/carrera.controller.ts index a6e4ce7..809fb2c 100644 --- a/src/core/controllers/carrera.controller.ts +++ b/src/core/controllers/carrera.controller.ts @@ -1,6 +1,6 @@ import {NextFunction, Request, Response} from "express"; import {SigaApiCarreraService} from "../../siga-api/services/carrera.service"; -import Carrera from "../models/carrera.model"; +import Carrera from "../../siga-api/models/carrera.model"; export class CarreraController { public static async getAll(req: Request, res: Response, next: NextFunction): Promise { diff --git a/src/core/controllers/notificacion.controller.ts b/src/core/controllers/notificacion.controller.ts index 8e2f8e3..b9aa840 100644 --- a/src/core/controllers/notificacion.controller.ts +++ b/src/core/controllers/notificacion.controller.ts @@ -6,8 +6,8 @@ import { Firestore, getFirestore, } from "firebase-admin/firestore"; -import GenericError from "../../infrastructure/models/error.model"; -import FcmUtils from "../../infrastructure/utils/fcm.utils"; +import GenericError from "../models/internal/error.model"; +import FcmUtils from "../utils/fcm.utils"; import Usuario from "../models/usuario.model"; export class NotificacionController { diff --git a/src/core/controllers/permiso.controller.ts b/src/core/controllers/permiso.controller.ts index 05851c4..8b28a68 100644 --- a/src/core/controllers/permiso.controller.ts +++ b/src/core/controllers/permiso.controller.ts @@ -1,7 +1,7 @@ import {NextFunction, Request, Response} from "express"; import {MiUtemPermisoService} from "../../mi-utem/services/permiso.service"; -import Permiso from "../models/permiso.model"; -import Cookie from "../../infrastructure/models/cookie.model"; +import Permiso from "../../mi-utem/models/permiso.model"; +import Cookie from "../models/internal/cookie.model"; export class PermisoController { public static async getAll(req: Request, res: Response, next: NextFunction): Promise { diff --git a/src/core/controllers/usuario.controller.ts b/src/core/controllers/usuario.controller.ts index 450cb0e..ceafe5d 100644 --- a/src/core/controllers/usuario.controller.ts +++ b/src/core/controllers/usuario.controller.ts @@ -1,9 +1,9 @@ import {NextFunction, Request, Response} from "express"; -import GenericError from "../../infrastructure/models/error.model"; +import GenericError from "../models/internal/error.model"; import {MiUtemAuthService} from "../../mi-utem/services/auth.service"; import {MiUtemUserService} from "../../mi-utem/services/user.service"; import {PasaportePasswordService} from "../../pasaporte/services/password.service"; -import Cookie from "../../infrastructure/models/cookie.model"; +import Cookie from "../models/internal/cookie.model"; export class UsuarioController { public static async resetPassword(req: Request, res: Response, next: NextFunction): Promise { diff --git a/src/infrastructure/middlewares/credentials/academia-credentials.middleware.ts b/src/core/middlewares/credentials/academia-credentials.middleware.ts similarity index 87% rename from src/infrastructure/middlewares/credentials/academia-credentials.middleware.ts rename to src/core/middlewares/credentials/academia-credentials.middleware.ts index 457a966..ffa6c21 100644 --- a/src/infrastructure/middlewares/credentials/academia-credentials.middleware.ts +++ b/src/core/middlewares/credentials/academia-credentials.middleware.ts @@ -1,6 +1,6 @@ import { NextFunction, Request, Response } from "express"; -import Cookie from "../../models/cookie.model"; -import GenericError from "../../models/error.model"; +import Cookie from "../../models/internal/cookie.model"; +import GenericError from "../../models/internal/error.model"; import CredentialsUtils from "../../utils/credentials.utils"; import { CredentialsMiddleware } from "./credentials.middleware"; diff --git a/src/infrastructure/middlewares/credentials/credentials.middleware.ts b/src/core/middlewares/credentials/credentials.middleware.ts similarity index 94% rename from src/infrastructure/middlewares/credentials/credentials.middleware.ts rename to src/core/middlewares/credentials/credentials.middleware.ts index 0c47343..633cdb1 100644 --- a/src/infrastructure/middlewares/credentials/credentials.middleware.ts +++ b/src/core/middlewares/credentials/credentials.middleware.ts @@ -1,5 +1,5 @@ import { Request } from "express"; -import GenericError from "../../models/error.model"; +import GenericError from "../../models/internal/error.model"; /** * Esta clase representa la base de los middleware 'Credentials', permitiendo una validación de token. diff --git a/src/infrastructure/middlewares/credentials/miutem-credentials.middleware.ts b/src/core/middlewares/credentials/miutem-credentials.middleware.ts similarity index 91% rename from src/infrastructure/middlewares/credentials/miutem-credentials.middleware.ts rename to src/core/middlewares/credentials/miutem-credentials.middleware.ts index 7eaf2a0..bd6c13a 100644 --- a/src/infrastructure/middlewares/credentials/miutem-credentials.middleware.ts +++ b/src/core/middlewares/credentials/miutem-credentials.middleware.ts @@ -1,7 +1,7 @@ import { NextFunction, Request, Response } from "express"; import { MiUtemAuthService } from "../../../mi-utem/services/auth.service"; -import Cookie from "../../models/cookie.model"; -import GenericError from "../../models/error.model"; +import Cookie from "../../models/internal/cookie.model"; +import GenericError from "../../models/internal/error.model"; import CredentialsUtils from "../../utils/credentials.utils"; import { CredentialsMiddleware } from "./credentials.middleware"; diff --git a/src/infrastructure/middlewares/credentials/siga-credentials.middleware.ts b/src/core/middlewares/credentials/siga-credentials.middleware.ts similarity index 91% rename from src/infrastructure/middlewares/credentials/siga-credentials.middleware.ts rename to src/core/middlewares/credentials/siga-credentials.middleware.ts index d9c72f6..bf92e50 100644 --- a/src/infrastructure/middlewares/credentials/siga-credentials.middleware.ts +++ b/src/core/middlewares/credentials/siga-credentials.middleware.ts @@ -1,7 +1,7 @@ import { NextFunction, Request, Response } from "express"; import jwt from "jsonwebtoken"; -import Usuario from "../../../core/models/usuario.model"; -import GenericError from "../../models/error.model"; +import Usuario from "../../models/usuario.model"; +import GenericError from "../../models/internal/error.model"; import CredentialsUtils from "../../utils/credentials.utils"; import { CredentialsMiddleware } from "./credentials.middleware"; diff --git a/src/infrastructure/models/cookie.model.ts b/src/core/models/internal/cookie.model.ts similarity index 100% rename from src/infrastructure/models/cookie.model.ts rename to src/core/models/internal/cookie.model.ts diff --git a/src/infrastructure/models/error.model.ts b/src/core/models/internal/error.model.ts similarity index 100% rename from src/infrastructure/models/error.model.ts rename to src/core/models/internal/error.model.ts diff --git a/src/core/routes/asignatura.routes.ts b/src/core/routes/asignatura.routes.ts index 4c4e968..e61712e 100644 --- a/src/core/routes/asignatura.routes.ts +++ b/src/core/routes/asignatura.routes.ts @@ -1,8 +1,8 @@ import { Router } from "express"; import { AsignaturaController } from "../controllers/asignatura.controller"; import { NotificacionController } from "../controllers/notificacion.controller"; -import {SigaCredentialsMiddleware} from "../../infrastructure/middlewares/credentials/siga-credentials.middleware"; -import {MiUTEMCredentialsMiddleware} from "../../infrastructure/middlewares/credentials/miutem-credentials.middleware"; +import {SigaCredentialsMiddleware} from "../middlewares/credentials/siga-credentials.middleware"; +import {MiUTEMCredentialsMiddleware} from "../middlewares/credentials/miutem-credentials.middleware"; const router: Router = Router(); diff --git a/src/core/routes/beca-alimentacion.routes.ts b/src/core/routes/beca-alimentacion.routes.ts index e7e2f09..415e1e9 100644 --- a/src/core/routes/beca-alimentacion.routes.ts +++ b/src/core/routes/beca-alimentacion.routes.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import {BecaAlimentacionController} from "../controllers/beca-alimentacion.controller"; -import {AcademiaCredentialsMiddleware} from "../../infrastructure/middlewares/credentials/academia-credentials.middleware"; +import {AcademiaCredentialsMiddleware} from "../middlewares/credentials/academia-credentials.middleware"; const router: Router = Router(); diff --git a/src/core/routes/carrera.routes.ts b/src/core/routes/carrera.routes.ts index f1327ab..6c973f9 100644 --- a/src/core/routes/carrera.routes.ts +++ b/src/core/routes/carrera.routes.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { CarreraController } from "../controllers/carrera.controller"; -import {SigaCredentialsMiddleware} from "../../infrastructure/middlewares/credentials/siga-credentials.middleware"; +import {SigaCredentialsMiddleware} from "../middlewares/credentials/siga-credentials.middleware"; const router: Router = Router(); diff --git a/src/core/routes/horario.routes.ts b/src/core/routes/horario.routes.ts index 9756852..26ae0af 100644 --- a/src/core/routes/horario.routes.ts +++ b/src/core/routes/horario.routes.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { HorarioController } from "../controllers/horario.controller"; -import {SigaCredentialsMiddleware} from "../../infrastructure/middlewares/credentials/siga-credentials.middleware"; +import {SigaCredentialsMiddleware} from "../middlewares/credentials/siga-credentials.middleware"; const router: Router = Router(); diff --git a/src/core/routes/permiso.routes.ts b/src/core/routes/permiso.routes.ts index 05b4b1a..6282efd 100644 --- a/src/core/routes/permiso.routes.ts +++ b/src/core/routes/permiso.routes.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { PermisoController } from "../controllers/permiso.controller"; -import {MiUTEMCredentialsMiddleware} from "../../infrastructure/middlewares/credentials/miutem-credentials.middleware"; +import {MiUTEMCredentialsMiddleware} from "../middlewares/credentials/miutem-credentials.middleware"; const router: Router = Router(); diff --git a/src/core/routes/usuario.routes.ts b/src/core/routes/usuario.routes.ts index d11a63d..c02bc5d 100644 --- a/src/core/routes/usuario.routes.ts +++ b/src/core/routes/usuario.routes.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { UsuarioController } from "../controllers/usuario.controller"; -import {MiUTEMCredentialsMiddleware} from "../../infrastructure/middlewares/credentials/miutem-credentials.middleware"; +import {MiUTEMCredentialsMiddleware} from "../middlewares/credentials/miutem-credentials.middleware"; const router: Router = Router(); diff --git a/src/infrastructure/server/server.ts b/src/core/server.ts similarity index 95% rename from src/infrastructure/server/server.ts rename to src/core/server.ts index 8e88ff2..49e2fb2 100644 --- a/src/infrastructure/server/server.ts +++ b/src/core/server.ts @@ -6,13 +6,13 @@ import http from "http"; import https from "https"; import morgan from "morgan"; import stream from "stream"; -import CoreRouter from "../../core/routes/index.routes"; -import GenericError from "../models/error.model"; -import GenericLogger from "../utils/logger.utils"; -import {HashUtils} from "../utils/hash.utils"; +import CoreRouter from "./routes/index.routes"; +import GenericError from "./models/internal/error.model"; +import GenericLogger from "./utils/logger.utils"; +import {HashUtils} from "./utils/hash.utils"; import {nodeProfilingIntegration} from "@sentry/profiling-node"; import * as process from "node:process"; -import CredentialsUtils from "../utils/credentials.utils"; +import CredentialsUtils from "./utils/credentials.utils"; const winstonMorganWriter = new stream.Writable(); winstonMorganWriter._write = function (chunk, encoding, done) { diff --git a/src/infrastructure/utils/credentials.utils.ts b/src/core/utils/credentials.utils.ts similarity index 98% rename from src/infrastructure/utils/credentials.utils.ts rename to src/core/utils/credentials.utils.ts index cf6a08b..d6d6cdd 100644 --- a/src/infrastructure/utils/credentials.utils.ts +++ b/src/core/utils/credentials.utils.ts @@ -1,6 +1,6 @@ import jwt from "jsonwebtoken"; -import Usuario from "../../core/models/usuario.model"; -import Cookie from "../models/cookie.model"; +import Usuario from "../models/usuario.model"; +import Cookie from "../models/internal/cookie.model"; import axios from "axios"; export default class CredentialsUtils { diff --git a/src/infrastructure/utils/fcm.utils.ts b/src/core/utils/fcm.utils.ts similarity index 100% rename from src/infrastructure/utils/fcm.utils.ts rename to src/core/utils/fcm.utils.ts diff --git a/src/infrastructure/utils/files.utils.ts b/src/core/utils/files.utils.ts similarity index 100% rename from src/infrastructure/utils/files.utils.ts rename to src/core/utils/files.utils.ts diff --git a/src/infrastructure/utils/hash.utils.ts b/src/core/utils/hash.utils.ts similarity index 100% rename from src/infrastructure/utils/hash.utils.ts rename to src/core/utils/hash.utils.ts diff --git a/src/infrastructure/utils/logger.utils.ts b/src/core/utils/logger.utils.ts similarity index 100% rename from src/infrastructure/utils/logger.utils.ts rename to src/core/utils/logger.utils.ts diff --git a/src/keycloak/services/user.service.ts b/src/keycloak/services/user.service.ts index b1463aa..1507284 100644 --- a/src/keycloak/services/user.service.ts +++ b/src/keycloak/services/user.service.ts @@ -1,7 +1,7 @@ -import GenericError from "../../infrastructure/models/error.model"; +import GenericError from "../../core/models/internal/error.model"; import * as cheerio from 'cheerio' import axios, {AxiosResponse} from "axios"; -import Cookie from "../../infrastructure/models/cookie.model"; +import Cookie from "../../core/models/internal/cookie.model"; export class KeycloakUserService { public static async loginSSO({oauthUri, correo, contrasenia}: { diff --git a/src/core/models/permiso.model.ts b/src/mi-utem/models/permiso.model.ts similarity index 100% rename from src/core/models/permiso.model.ts rename to src/mi-utem/models/permiso.model.ts diff --git a/src/core/models/semestre.model.ts b/src/mi-utem/models/semestre.model.ts similarity index 59% rename from src/core/models/semestre.model.ts rename to src/mi-utem/models/semestre.model.ts index 6f9b664..6e63445 100644 --- a/src/core/models/semestre.model.ts +++ b/src/mi-utem/models/semestre.model.ts @@ -1,4 +1,4 @@ -import SeccionAsignatura from "./seccion-asignatura.model"; +import SeccionAsignatura from "../../core/models/seccion-asignatura.model"; export default interface Semestre { id?: string; diff --git a/src/mi-utem/services/asignatura.service.ts b/src/mi-utem/services/asignatura.service.ts index c2781ba..89b8394 100644 --- a/src/mi-utem/services/asignatura.service.ts +++ b/src/mi-utem/services/asignatura.service.ts @@ -1,34 +1,12 @@ import SeccionAsignatura from "../../core/models/seccion-asignatura.model"; import Usuario from "../../core/models/usuario.model"; -import GenericError from "../../infrastructure/models/error.model"; -import Cookie from "../../infrastructure/models/cookie.model"; +import GenericError from "../../core/models/internal/error.model"; +import Cookie from "../../core/models/internal/cookie.model"; import {MiUtemAuthService} from "./auth.service"; import axios from "axios"; import * as cheerio from "cheerio"; export class MiUtemAsignaturaService { - public static async getAsignaturas(cookies: Cookie[]): Promise { - await MiUtemAuthService.cookiesValidas(cookies); - - const page = await axios.get(process.env.MI_UTEM_URL, { - headers: { - Cookie: Cookie.header(cookies), - } - }) - - const $ = cheerio.load(page.data); - const asignaturas: SeccionAsignatura[] = []; - - $('.card-utem #table_mdl_titulo tbody tr.no-border').each((_, el) => { - asignaturas.push({ - codigo: $(el).find('td:nth-child(1) > span').text().split(' - ')[0].trim(), - nombre: $(el).find('td:nth-child(1) > span').text().split(' - ')[1].trim(), - tipoHora: $(el).find('td:nth-child(2)').text().trim(), - }) - }); - - return asignaturas; - } /** * Obtiene el detalle de una asignatura del usuario @@ -93,7 +71,7 @@ export class MiUtemAsignaturaService { const estudiantes: Usuario[] = []; $detalleAsignatura('#table-estudiantes > tbody > tr').each((_, el) => { const nombre = $detalleAsignatura(el).find('td:nth-child(2)').text().trim(); - let nombreCompleto, nombres, apellidos: string + let nombreCompleto: string, nombres: string, apellidos: string if(nombre.includes(',')) { nombres = nombre.split(',')[1].trim(); apellidos = nombre.split(',')[0].trim(); diff --git a/src/mi-utem/services/auth.service.ts b/src/mi-utem/services/auth.service.ts index fa881d6..dd6ab5e 100644 --- a/src/mi-utem/services/auth.service.ts +++ b/src/mi-utem/services/auth.service.ts @@ -1,7 +1,7 @@ import axios from "axios"; import * as cheerio from 'cheerio'; -import Cookie from "../../infrastructure/models/cookie.model"; -import GenericError from "../../infrastructure/models/error.model"; +import Cookie from "../../core/models/internal/cookie.model"; +import GenericError from "../../core/models/internal/error.model"; import { KeycloakUserService } from "../../keycloak/services/user.service"; export class MiUtemAuthService { diff --git a/src/mi-utem/services/carrera.service.ts b/src/mi-utem/services/carrera.service.ts deleted file mode 100644 index 77e5c72..0000000 --- a/src/mi-utem/services/carrera.service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import Carrera from "../../core/models/carrera.model"; -import Cookie from "../../infrastructure/models/cookie.model"; -import {MiUtemAuthService} from "./auth.service"; -import axios from "axios"; -import * as cheerio from "cheerio"; - -export class MiUtemCarreraService { - public static async getCarreras(cookies: Cookie[]): Promise { - await MiUtemAuthService.cookiesValidas(cookies) - const mallaRequest = await axios.get(`${process.env.MI_UTEM_URL}/academicos/mi-malla`, { - headers: { - Cookie: Cookie.header(cookies), - }, - }) - const $ = cheerio.load(mallaRequest.data) - - const carreras: Carrera[] = []; - const carrerasCollapsableElement = $('#avance-malla > #accordion > div.collapse') - $('#avance-malla > #accordion > div.div-card-avance').each((i, carreraCardElement) => { - const datosCarrera = $(carreraCardElement).find('div > div > span.card-avance-left').text().split(' - ') - const codigo = (datosCarrera[0] || '').trim() - const nombre = (datosCarrera[1] || '').trim() - const estado = $(carreraCardElement).find('div > div > span.card-avance-right').text().replace('Estado : ', '').trim() - - carreras.push({ - codigo, - nombre, - estado, - plan: $(carrerasCollapsableElement[i]).find('div > div:nth-child(1) > div > table > tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), - }) - }) - - return carreras - } -} diff --git a/src/mi-utem/services/horario.service.ts b/src/mi-utem/services/horario.service.ts index aabfc3b..5168a1e 100644 --- a/src/mi-utem/services/horario.service.ts +++ b/src/mi-utem/services/horario.service.ts @@ -1,7 +1,7 @@ import Horario from "../../core/models/horario.model"; -import GenericError from "../../infrastructure/models/error.model"; +import GenericError from "../../core/models/internal/error.model"; import {MiUtemAuthService} from "./auth.service"; -import Cookie from "../../infrastructure/models/cookie.model"; +import Cookie from "../../core/models/internal/cookie.model"; import axios from "axios"; import * as cheerio from "cheerio"; diff --git a/src/mi-utem/services/nota.service.ts b/src/mi-utem/services/nota.service.ts index f84103a..46721e8 100644 --- a/src/mi-utem/services/nota.service.ts +++ b/src/mi-utem/services/nota.service.ts @@ -1,7 +1,7 @@ import Evaluacion from "../../core/models/evaluacion.model"; import SeccionAsignatura from "../../core/models/seccion-asignatura.model"; -import Semestre from "../../core/models/semestre.model"; -import Cookie from "../../infrastructure/models/cookie.model"; +import Semestre from "../models/semestre.model"; +import Cookie from "../../core/models/internal/cookie.model"; import {MiUtemAuthService} from "./auth.service"; import axios from "axios"; import * as cheerio from "cheerio"; diff --git a/src/mi-utem/services/permiso.service.ts b/src/mi-utem/services/permiso.service.ts index cc88841..f6286f1 100644 --- a/src/mi-utem/services/permiso.service.ts +++ b/src/mi-utem/services/permiso.service.ts @@ -2,9 +2,9 @@ import axios, {AxiosResponse} from "axios"; import FormData from "form-data"; import moment from "moment"; import pdf from "pdf-parse"; -import Permiso from "../../core/models/permiso.model"; -import GenericError from "../../infrastructure/models/error.model"; -import Cookie from "../../infrastructure/models/cookie.model"; +import Permiso from "../models/permiso.model"; +import GenericError from "../../core/models/internal/error.model"; +import Cookie from "../../core/models/internal/cookie.model"; import {MiUtemAuthService} from "./auth.service"; export class MiUtemPermisoService { diff --git a/src/mi-utem/services/user.service.ts b/src/mi-utem/services/user.service.ts index 7da5541..af85d01 100644 --- a/src/mi-utem/services/user.service.ts +++ b/src/mi-utem/services/user.service.ts @@ -2,8 +2,8 @@ import axios, { AxiosResponse } from "axios"; import * as cheerio from 'cheerio'; import FormData from "form-data"; import Usuario from "../../core/models/usuario.model"; -import Cookie from "../../infrastructure/models/cookie.model"; -import FilesUtils from "../../infrastructure/utils/files.utils"; +import Cookie from "../../core/models/internal/cookie.model"; +import FilesUtils from "../../core/utils/files.utils"; import { MiUtemAuthService } from "./auth.service"; export class MiUtemUserService { diff --git a/src/core/models/carrera.model.ts b/src/siga-api/models/carrera.model.ts similarity index 100% rename from src/core/models/carrera.model.ts rename to src/siga-api/models/carrera.model.ts diff --git a/src/siga-api/services/asignatura.service.ts b/src/siga-api/services/asignatura.service.ts index 94f0985..ef71d64 100644 --- a/src/siga-api/services/asignatura.service.ts +++ b/src/siga-api/services/asignatura.service.ts @@ -4,10 +4,7 @@ import Evaluacion from "../../core/models/evaluacion.model"; import SeccionAsignatura from "../../core/models/seccion-asignatura.model"; export class SigaApiAsignaturaService { - public static async getAsignaturas( - token: string, - carreraId: string - ): Promise { + public static async getAsignaturas(token: string, carreraId: string): Promise { const uri: string = "/estudiante/asignaturas/"; const url: string = `${process.env.SIGA_API_URL}${uri}`; @@ -45,11 +42,7 @@ export class SigaApiAsignaturaService { return asignaturas; } - public static async getNotasAsignatura( - token: string, - carreraId: string, - asignaturaId: string - ): Promise { + public static async getNotasAsignatura(token: string, carreraId: string, asignaturaId: string): Promise { const uri: string = "/estudiante/asignaturas/notas/"; const url: string = `${process.env.SIGA_API_URL}${uri}`; diff --git a/src/siga-api/services/auth.service.ts b/src/siga-api/services/auth.service.ts index 6b8a148..d4419af 100644 --- a/src/siga-api/services/auth.service.ts +++ b/src/siga-api/services/auth.service.ts @@ -1,8 +1,8 @@ import axios from "axios"; import Usuario from "../../core/models/usuario.model"; -import GenericError from "../../infrastructure/models/error.model"; -import {HashUtils} from "../../infrastructure/utils/hash.utils"; -import Cookie from "../../infrastructure/models/cookie.model"; +import GenericError from "../../core/models/internal/error.model"; +import {HashUtils} from "../../core/utils/hash.utils"; +import Cookie from "../../core/models/internal/cookie.model"; export class SigaApiAuthService { public static async loginAndGetToken(correo: string, contrasenia: string): Promise { diff --git a/src/siga-api/services/carrera.service.ts b/src/siga-api/services/carrera.service.ts index 1f3e56e..5602a62 100644 --- a/src/siga-api/services/carrera.service.ts +++ b/src/siga-api/services/carrera.service.ts @@ -1,6 +1,6 @@ import axios, {AxiosResponse} from "axios"; import qs from "qs"; -import Carrera from "../../core/models/carrera.model"; +import Carrera from "../models/carrera.model"; export class SigaApiCarreraService { public static async getCarreras(token: string): Promise {