utn-cli 2.0.89 → 2.0.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/backend/servicios/Nucleo/Miscelaneas.js +88 -21
- package/templates/backend/servicios/Nucleo/ReportePDF.js +19 -0
- package/templates/backend/servicios/Servicio1.js +0 -1
- package/templates/frontend/src/app/Paginas/gestion-tabla-XYZ/gestion-tabla-XYZ.component.ts +12 -0
- package/templates/frontend/src/index.html +1 -0
package/package.json
CHANGED
|
@@ -461,6 +461,68 @@ class Miscelaneo {
|
|
|
461
461
|
return;
|
|
462
462
|
}
|
|
463
463
|
|
|
464
|
+
async AutenticarConGoogle(Solicitud) {
|
|
465
|
+
const { OAuth2Client } = require('google-auth-library');
|
|
466
|
+
const jwt = require('jsonwebtoken');
|
|
467
|
+
const clientId = await this.googleClientId();
|
|
468
|
+
const client = new OAuth2Client(clientId);
|
|
469
|
+
const ConexionSigu = await crearObjetoConexionSIGU();
|
|
470
|
+
const LastUser = await this.generarLastUser(Solicitud);
|
|
471
|
+
|
|
472
|
+
try {
|
|
473
|
+
const ticket = await client.verifyIdToken({
|
|
474
|
+
idToken: Solicitud.body.token,
|
|
475
|
+
audience: clientId,
|
|
476
|
+
});
|
|
477
|
+
const payload = ticket.getPayload();
|
|
478
|
+
const email = payload['email'];
|
|
479
|
+
|
|
480
|
+
const resultadosEmail = await ConexionSigu.query("SELECT `Identificador` FROM `SIGU`.`SIGU_CorreosPersona` WHERE `CorreoElectronico` = ? AND `Principal` = TRUE LIMIT 1", [email]);
|
|
481
|
+
|
|
482
|
+
if (resultadosEmail[0].length === 0) {
|
|
483
|
+
console.log("El correo de Google", email, "no está registrado como principal en SIGU");
|
|
484
|
+
return { error: "Su cuenta de Google no está vinculada a ningún usuario de SIGU." };
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const Identificador = resultadosEmail[0][0]['Identificador'];
|
|
488
|
+
const resultadosUsuario = await ConexionSigu.query("SELECT `Identificacion` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` = ? AND `Activo` = TRUE", [Identificador]);
|
|
489
|
+
|
|
490
|
+
if (resultadosUsuario[0].length === 0) {
|
|
491
|
+
return { error: "El usuario asociado a esta cuenta no está activo." };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const Identificacion = resultadosUsuario[0][0]['Identificacion'];
|
|
495
|
+
|
|
496
|
+
// Generar Token
|
|
497
|
+
const Token = await jwt.sign({ Identificador: Identificador, uid: Identificador }, await this.palabraSecretaParaTokens(), { expiresIn: '2h' });
|
|
498
|
+
await ConexionSigu.query("INSERT INTO `SIGU`.`SIGU_Sesiones` VALUES (?, ?, ?, NOW(4), ?) ON DUPLICATE KEY UPDATE `Token` = ?, `LastUser` = ?", [Identificador, Solicitud.headers.host.trim(), Token, LastUser, Token, LastUser]);
|
|
499
|
+
await ConexionSigu.query("DELETE FROM `SIGU`.`SIGU_SesionesFallidas` WHERE `Identificador` = ?", [Identificador]);
|
|
500
|
+
|
|
501
|
+
// OBTENER IP DEL USUARIO
|
|
502
|
+
const ipUsuario = (Solicitud.headers['x-forwarded-for'] || '').split(',').shift() || Solicitud.socket?.remoteAddress || Solicitud.connection?.remoteAddress || '-';
|
|
503
|
+
|
|
504
|
+
// SI LA IP YA EXISTE CONTINUA
|
|
505
|
+
await ConexionSigu.query("\
|
|
506
|
+
INSERT INTO `SIGU`.`SIGU_DireccionesUsadasPorLosUsuarios` \
|
|
507
|
+
(`DireccionUsadaPorElUsuario`, `Identificador`, `LastUpdate`, `LastUser`) \
|
|
508
|
+
VALUES (?, ?, NOW(4), ?) \
|
|
509
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4), `LastUser` = ?;", [
|
|
510
|
+
ipUsuario,
|
|
511
|
+
Identificador,
|
|
512
|
+
LastUser,
|
|
513
|
+
LastUser
|
|
514
|
+
]);
|
|
515
|
+
|
|
516
|
+
return { Token, Dominio: ((process.env.ENV || 'local') === 'production' ? '.sigu.utn.ac.cr' : '.181.193.85.44.nip.io') };
|
|
517
|
+
|
|
518
|
+
} catch (error) {
|
|
519
|
+
console.error("Error en AutenticarConGoogle:", error);
|
|
520
|
+
return { error: "Error al autenticar con Google" };
|
|
521
|
+
} finally {
|
|
522
|
+
if (ConexionSigu) await ConexionSigu.end();
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
464
526
|
async Autenticar(Solicitud) {
|
|
465
527
|
const crypto = require('crypto');
|
|
466
528
|
const bcrypt = require('bcryptjs');
|
|
@@ -696,7 +758,7 @@ class Miscelaneo {
|
|
|
696
758
|
`a`.`Tipo`, IF(`a`.`Icono` <> '', CONCAT('https://storage.sigu.utn.ac.cr/images/cards/', `a`.`Icono`), '') AS `Icono`, `a`.`Color`, `a`.`Correo`,\
|
|
697
759
|
`a`.`Version`, `a`.`FechaDePublicacion`, `a`.`AcuerdoDeNivelDeServicio`, `a`.`DiccionarioDeDatos`, `a`.`Repositorios`,\
|
|
698
760
|
`a`.`EnlaceDelVideo`,`a`.`EnlaceDelManual`\
|
|
699
|
-
, `a`.`Estado`, REGEXP_SUBSTR(`a`.`Repositorios`, '[^,]*front[^,]*') AS `Frontend`\
|
|
761
|
+
, `a`.`Estado`, REGEXP_SUBSTR(SUBSTRING_INDEX(`a`.`Repositorios`, '/', -1), '[^,]*front[^,]*') AS `Frontend`\
|
|
700
762
|
FROM `SIGU`.`SIGU_ModulosV2` `a`\
|
|
701
763
|
WHERE `a`.`Nombre` = ?", [this.NombreCanonicoDelModulo]);
|
|
702
764
|
return Modulos.map((linea) => {
|
|
@@ -890,10 +952,10 @@ class Miscelaneo {
|
|
|
890
952
|
const Version = this.Version + "$$" + this.versionDelNucleo().split(' ')[0];
|
|
891
953
|
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_ModulosV2` VALUES\
|
|
892
954
|
(?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(4), ?, 'DiccionarioDeDatos'\
|
|
893
|
-
, ?, '-', '-', 'Activo', NOW(4), USER()) ON DUPLICATE KEY UPDATE `Version` = ?"
|
|
955
|
+
, ?, '-', '-', 'Activo', NOW(4), USER()) ON DUPLICATE KEY UPDATE `Version` = ?, `Repositorios` = ?"
|
|
894
956
|
, [this.NombreCanonicoDelModulo, this.MenuPadre, this.DescripcionDelModulo, this.DetalleDelModulo
|
|
895
957
|
, this.TipoDeCard, this.IconoDelModulo, this.ColorDelModulo, this.CorreoParaReportes, Version, this.versionDelNucleo().split(' ')[0], this.Repositorios
|
|
896
|
-
, Version]);
|
|
958
|
+
, Version, this.Repositorios]);
|
|
897
959
|
await ejecutarConsultaSIGU("SELECT IFNULL(MAX(`PermisoId`), 0) + 1 INTO @`SiguientePermisoId` FROM `SIGU`.`SIGU_PermisosV2`;\
|
|
898
960
|
INSERT INTO `SIGU`.`SIGU_PermisosV2` VALUES\
|
|
899
961
|
(@`SiguientePermisoId`, ?, ?, ?, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUser` = USER(), `Nombre` = ?, `Descripcion` = ?;"
|
|
@@ -1192,7 +1254,7 @@ class Miscelaneo {
|
|
|
1192
1254
|
}
|
|
1193
1255
|
|
|
1194
1256
|
versionDelNucleo() {
|
|
1195
|
-
return "
|
|
1257
|
+
return "VERSION_DEL_NUCLEO" + " " + this.NombreCanonicoDelModulo;
|
|
1196
1258
|
}
|
|
1197
1259
|
|
|
1198
1260
|
async destinatarioDeInformesDeError() {
|
|
@@ -1257,49 +1319,54 @@ class Miscelaneo {
|
|
|
1257
1319
|
console.log(error);
|
|
1258
1320
|
return;
|
|
1259
1321
|
}
|
|
1260
|
-
return ejecutarConsultaSIGU("SELECT `a`.`Identificador`, `a`.`Identificacion`\
|
|
1322
|
+
return await ejecutarConsultaSIGU("SELECT `a`.`Identificador`, `a`.`Identificacion`\
|
|
1261
1323
|
, `a`.`Nombre`, `a`.`PrimerApellido`, `a`.`SegundoApellido`\
|
|
1262
1324
|
, (SELECT GROUP_CONCAT(`b`.`CuentaIBAN`) FROM `SIGU`.`SIGU_CuentasBancariasPersonas` `b` WHERE `b`.`Estado` = TRUE AND `a`.`Identificador` = `b`.`Identificador`) AS `CuentasIBAN`\
|
|
1263
1325
|
FROM `SIGU`.`SIGU_Personas` `a` WHERE `a`.`Identificador` = ?"
|
|
1264
1326
|
, [Resultado.uid]);
|
|
1265
1327
|
}
|
|
1266
1328
|
|
|
1267
|
-
obtenerDatosDeLaPersonaPorIdentificacion(Identificacion) {
|
|
1268
|
-
return ejecutarConsultaSIGU("SELECT `a`.`Identificador`, `a`.`Identificacion`\
|
|
1329
|
+
async obtenerDatosDeLaPersonaPorIdentificacion(Identificacion) {
|
|
1330
|
+
return await ejecutarConsultaSIGU("SELECT `a`.`Identificador`, `a`.`Identificacion`\
|
|
1269
1331
|
, `a`.`Nombre`, `a`.`PrimerApellido`, `a`.`SegundoApellido`\
|
|
1270
1332
|
, (SELECT GROUP_CONCAT(`b`.`CuentaIBAN`) FROM `SIGU`.`SIGU_CuentasBancariasPersonas` `b` WHERE `b`.`Estado` = TRUE AND `a`.`Identificador` = `b`.`Identificador`) AS `CuentasIBAN`\
|
|
1271
1333
|
FROM `SIGU`.`SIGU_Personas` `a` WHERE `a`.`Identificacion` = ?"
|
|
1272
1334
|
, [Identificacion]);
|
|
1273
1335
|
}
|
|
1274
1336
|
|
|
1275
|
-
obtenerEstudiantes() {
|
|
1276
|
-
return ejecutarConsultaSIGU("SELECT `Identificador`, `Identificacion`, `Nombre`, `PrimerApellido`,\
|
|
1337
|
+
async obtenerEstudiantes() {
|
|
1338
|
+
return await ejecutarConsultaSIGU("SELECT `Identificador`, `Identificacion`, `Nombre`, `PrimerApellido`,\
|
|
1277
1339
|
`SegundoApellido` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` IN\
|
|
1278
1340
|
(SELECT `Identificador` FROM `SIGU`.`SIGU_RolesPersonas` WHERE `PerfilGeneralId` = 1 /*El perfil 1 parece ser para Estudiantes*/)");
|
|
1279
1341
|
}
|
|
1280
1342
|
|
|
1281
|
-
obtenerBeneficios() {
|
|
1282
|
-
return ejecutarConsultaSIGU("SELECT `BeneficioId`, `Beneficio`, `Estado` FROM `SIGU`.`SIGU_Beneficios`");
|
|
1343
|
+
async obtenerBeneficios() {
|
|
1344
|
+
return await ejecutarConsultaSIGU("SELECT `BeneficioId`, `Beneficio`, `Estado` FROM `SIGU`.`SIGU_Beneficios`");
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
async obtenerIdentificacion(Identificador) {
|
|
1348
|
+
return await ejecutarConsultaSIGU("SELECT `Identificacion` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` = ?", [Identificador]);
|
|
1283
1349
|
}
|
|
1284
1350
|
|
|
1285
|
-
|
|
1286
|
-
return ejecutarConsultaSIGU("SELECT `
|
|
1351
|
+
async obtenerPeriodos() {
|
|
1352
|
+
return await ejecutarConsultaSIGU("SELECT `PeriodoId`, `CodigoPeriodo`, `Anio`, `Periodo`, `FechaInicio`, `FechaFinal`, `Tipo`, `Estado` FROM `SIGU`.`SIGU_Periodos` ORDER BY `Anio` DESC, `CodigoPeriodo` DESC");
|
|
1287
1353
|
}
|
|
1288
1354
|
|
|
1289
|
-
|
|
1290
|
-
return ejecutarConsultaSIGU("SELECT
|
|
1355
|
+
async obtenerAnios() {
|
|
1356
|
+
return await ejecutarConsultaSIGU("SELECT DISTINCT `Anio` FROM `SIGU`.`SIGU_Periodos`");
|
|
1291
1357
|
}
|
|
1292
1358
|
|
|
1293
|
-
|
|
1294
|
-
return ejecutarConsultaSIGU("SELECT
|
|
1359
|
+
async obtenerSedes() {
|
|
1360
|
+
return await ejecutarConsultaSIGU("SELECT `SedesId`, `CodigoAvatar`, `Descripcion`, `Siglas` FROM `SIGU`.`SIGU_Sedes` ORDER BY `Descripcion`");
|
|
1295
1361
|
}
|
|
1296
1362
|
|
|
1297
|
-
|
|
1298
|
-
return ejecutarConsultaSIGU("SELECT `
|
|
1363
|
+
async obtenerRecintos() {
|
|
1364
|
+
return await ejecutarConsultaSIGU("SELECT `a`.`RecintoId`, CONCAT(`b`.`Descripcion`, '/', `a`.`Recinto`) AS `Recinto` FROM `SIGU`.`SIGU_Recintos` `a` LEFT JOIN `SIGU`.`SIGU_Sedes` `b` ON (`a`.`SedeId` = `b`.`SedesId`) ORDER BY `Recinto`");
|
|
1299
1365
|
}
|
|
1300
1366
|
|
|
1301
|
-
|
|
1302
|
-
|
|
1367
|
+
async googleClientId() {
|
|
1368
|
+
const clientId = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'Google-ClientId'");
|
|
1369
|
+
return clientId[0]?.['Valor'] || '';
|
|
1303
1370
|
}
|
|
1304
1371
|
|
|
1305
1372
|
async palabraSecretaParaTokens() {
|
|
@@ -377,6 +377,23 @@ class ReportePDF {
|
|
|
377
377
|
// Como el texto de la izquierda tiene 2 líneas, alineamos la paginación un poco más abajo para que quede centrado
|
|
378
378
|
doc.text(paginacion, centerX + 15, footerY + 14, { width: (pageWidth / 2) - margin - 15, align: 'right' });
|
|
379
379
|
|
|
380
|
+
// Si el documento tiene firmas y estamos en la última página, agregar la leyenda de seguridad
|
|
381
|
+
if (doc._tieneFirmas && i === range.start + range.count - 1) {
|
|
382
|
+
const leyenda = "Documento firmado electrónicamente con firma digital interna de la Universidad Técnica Nacional. Incluye un código de verificación único validable en el sistema SIGU. Cualquier modificación invalida su autenticidad.";
|
|
383
|
+
doc.fillColor("black").fontSize(6).font(this.config.fuenteBase);
|
|
384
|
+
|
|
385
|
+
// Calculamos la posición Y para que esté inmediatamente por encima de la línea del footer (footerY)
|
|
386
|
+
// Estimamos un alto aproximado dependiendo de cuantas líneas abarque el texto,
|
|
387
|
+
// pdfkit calculará la altura si usamos heightOfString, pero podemos darle un espacio fijo.
|
|
388
|
+
const alturaLeyenda = doc.heightOfString(leyenda, { width: pageWidth - 2 * margin, align: 'center' });
|
|
389
|
+
const yPosLeyenda = footerY - alturaLeyenda - 5;
|
|
390
|
+
|
|
391
|
+
doc.text(leyenda, margin, yPosLeyenda, {
|
|
392
|
+
width: pageWidth - 2 * margin,
|
|
393
|
+
align: 'center'
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
380
397
|
// Restaurar el margen inferior original
|
|
381
398
|
doc.page.margins.bottom = bottomMargin;
|
|
382
399
|
}
|
|
@@ -682,6 +699,8 @@ class ReportePDF {
|
|
|
682
699
|
generarFirmas(doc, firmas) {
|
|
683
700
|
if (!firmas || !Array.isArray(firmas) || firmas.length === 0) return;
|
|
684
701
|
|
|
702
|
+
doc._tieneFirmas = true; // Marcar el documento como firmado para el pie de página
|
|
703
|
+
|
|
685
704
|
const margin = this.config.margin;
|
|
686
705
|
const pageWidth = doc.page.width;
|
|
687
706
|
const availableWidth = pageWidth - 2 * margin;
|
|
@@ -86,7 +86,6 @@ class Servicio1 {
|
|
|
86
86
|
// Resultados = await ejecutarConsultaSIGU(SELECTBase + " SELECT * FROM Datos WHERE " + WHERE + ORDERBY + " LIMIT ? OFFSET ?", [parseInt(Parametros.PaginadorTamanio), parseInt(Parametros.PaginadorIndice)]);
|
|
87
87
|
// return { Registros: Resultados, TotalDeRegistros: Total[0]['Total'] };
|
|
88
88
|
// }
|
|
89
|
-
// const ss = "";
|
|
90
89
|
// }
|
|
91
90
|
// // Predeterminadamente se retornan los datos paginados pero sin filtrar
|
|
92
91
|
// // Los símbolos &&&& se usan como valor predeterminado
|
|
@@ -172,6 +172,18 @@ export class GestionTablaXYZComponent {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
obtenerDatosParaPoblarLaTabla() {
|
|
175
|
+
// let Filtrado = undefined
|
|
176
|
+
// if (this.PaginarResultados) {
|
|
177
|
+
// if (this.PaginadorTamanio === 0) {
|
|
178
|
+
// const pageSize = localStorage.getItem('pageSize');
|
|
179
|
+
// if (pageSize) {
|
|
180
|
+
// this.PaginadorTamanio = parseInt(pageSize);
|
|
181
|
+
// }
|
|
182
|
+
// }
|
|
183
|
+
// Filtrado = `/${this.PaginadorAccion}/${this.PaginadorIndice}/${this.PaginadorTamanio}/${this.PaginadorFiltro}/${this.PaginadorColumnaParaFiltrar}/${this.PaginadorColumnasParaFiltrar}/${this.ColumnaParaOrdenar}/${this.TipoDeOrden}`;
|
|
184
|
+
// } else {
|
|
185
|
+
// Filtrado = `/TablaSinFiltro/-/-/-/-/-/-/-`;
|
|
186
|
+
// }
|
|
175
187
|
this.http.get(`${this.datosGlobalesService.ObtenerURL()}XYZ/listar`).subscribe({
|
|
176
188
|
next: (datos: any) => {
|
|
177
189
|
if (datos.error) {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
|
18
18
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
|
19
19
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
|
20
|
+
<script src="https://accounts.google.com/gsi/client" async defer></script>
|
|
20
21
|
</head>
|
|
21
22
|
|
|
22
23
|
<body>
|