utn-cli 2.1.18 → 2.1.20
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/commands/backend.js +64 -40
- package/package.json +1 -1
- package/templates/backend/InformacionDelModulo.json +0 -4
- package/templates/backend/servicios/Nucleo/InformacionDelModulo.js +96 -0
- package/templates/backend/servicios/Nucleo/Miscelaneas.js +2451 -92
- package/templates/backend/servicios/InformacionDelModulo.js +0 -193
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/Archivos.js +0 -329
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/Autenticacion.js +0 -388
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/InicializacionDelModulo.js +0 -254
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/Modulos.js +0 -261
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/Notificaciones.js +0 -82
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/Personas.js +0 -93
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/Reportes.js +0 -370
- package/templates/backend/servicios/Nucleo/MiscelaneasMixins/TareasProgramadas.js +0 -105
|
@@ -1,81 +1,87 @@
|
|
|
1
1
|
const { ejecutarConsulta, ejecutarConsultaSIGU, crearObjetoConexionSIGU } = require('./db.js');
|
|
2
2
|
const ManejadorDeErrores = require('./ManejadorDeErrores.js');
|
|
3
|
-
const InformacionDelModulo = require('
|
|
4
|
-
|
|
5
|
-
const MixinAutenticacion = require('./MiscelaneasMixins/Autenticacion.js');
|
|
6
|
-
const MixinNotificaciones = require('./MiscelaneasMixins/Notificaciones.js');
|
|
7
|
-
const MixinTareasProgramadas = require('./MiscelaneasMixins/TareasProgramadas.js');
|
|
8
|
-
const MixinPersonas = require('./MiscelaneasMixins/Personas.js');
|
|
9
|
-
const MixinArchivos = require('./MiscelaneasMixins/Archivos.js');
|
|
10
|
-
const MixinModulos = require('./MiscelaneasMixins/Modulos.js');
|
|
11
|
-
const MixinInicializacion = require('./MiscelaneasMixins/InicializacionDelModulo.js');
|
|
12
|
-
const MixinReportes = require('./MiscelaneasMixins/Reportes.js');
|
|
3
|
+
const InformacionDelModulo = require('./InformacionDelModulo.js');
|
|
4
|
+
const { envioDeCorreo } = require('./EnvioDeCorreos.js');
|
|
13
5
|
|
|
14
6
|
class Miscelaneo {
|
|
15
7
|
|
|
16
8
|
constructor() {
|
|
17
|
-
this.NombreDelModulo = InformacionDelModulo.getNombreDelModulo();
|
|
9
|
+
// this.NombreDelModulo = InformacionDelModulo.getNombreDelModulo();
|
|
18
10
|
this.DescripcionDelModulo = InformacionDelModulo.getDescripcionDelModulo();
|
|
19
11
|
this.DetalleDelModulo = InformacionDelModulo.getDetalleDelModulo();
|
|
20
12
|
this.NombreCanonicoDelModulo = InformacionDelModulo.getNombreCanonicoDelModulo();
|
|
21
13
|
this.TipoDeCard = InformacionDelModulo.getTipoDeCard();
|
|
22
|
-
this.NombreDelRol = this.NombreCanonicoDelModulo + ' - ' + InformacionDelModulo.getNombreDelRol();
|
|
14
|
+
// this.NombreDelRol = this.NombreCanonicoDelModulo + ' - ' + InformacionDelModulo.getNombreDelRol();
|
|
23
15
|
this.NombreDelRepositorioDeLaBaseDeDatos = InformacionDelModulo.getNombreDelRepositorioDeLaBaseDeDatos();
|
|
24
16
|
this.NombreDelRepositorioDelBackend = InformacionDelModulo.getNombreDelRepositorioDelBackend();
|
|
25
17
|
this.NombreDelRepositorioDelFrontend = InformacionDelModulo.getNombreDelRepositorioDelFrontend();
|
|
26
18
|
this.UrlDelGrupo = InformacionDelModulo.getUrlDelGrupo();
|
|
27
19
|
this.Repositorios = this.UrlDelGrupo + '/' + this.NombreDelRepositorioDeLaBaseDeDatos + ',' + this.UrlDelGrupo + '/' + this.NombreDelRepositorioDelBackend
|
|
28
20
|
+ ',' + this.UrlDelGrupo + '/' + this.NombreDelRepositorioDelFrontend;
|
|
29
|
-
this.NombreDelPermiso = this.NombreCanonicoDelModulo + ' - ' + InformacionDelModulo.getNombreDelPermiso();
|
|
21
|
+
// this.NombreDelPermiso = this.NombreCanonicoDelModulo + ' - ' + InformacionDelModulo.getNombreDelPermiso();
|
|
30
22
|
this.NombreDelPermisoV2 = InformacionDelModulo.getNombreDelPermiso();
|
|
31
23
|
this.DescripcionDelPermiso = InformacionDelModulo.getDescripcionDelPermiso();
|
|
32
24
|
this.MenuPadre = InformacionDelModulo.getMenuPadre();
|
|
33
25
|
this.BackEndsQueConsumeEsteModulo = InformacionDelModulo.getBackEndsQueConsumeEsteModulo();
|
|
34
|
-
this.PerfilGeneral = InformacionDelModulo.getPerfilGeneral();
|
|
26
|
+
// this.PerfilGeneral = InformacionDelModulo.getPerfilGeneral();
|
|
35
27
|
this.UsuariosConAccesoInicial = InformacionDelModulo.getUsuariosConAccesoInicial();
|
|
36
28
|
this.IconoDelModulo = this.NombreCanonicoDelModulo + '.svg';
|
|
37
|
-
this.ColorDelModulo = InformacionDelModulo.getColorDelModulo();
|
|
29
|
+
// this.ColorDelModulo = InformacionDelModulo.getColorDelModulo();
|
|
38
30
|
this.CorreoParaReportes = InformacionDelModulo.getCorreoParaReportes();
|
|
39
31
|
this.Version = InformacionDelModulo.getVersion();
|
|
40
32
|
|
|
33
|
+
// Declaración de variables
|
|
34
|
+
// A estas variables no es necesario darles un valor inicial
|
|
41
35
|
this.UUID = 'UUID';
|
|
42
36
|
this.Enlace = undefined;
|
|
43
|
-
this.RolId = 0;
|
|
44
|
-
this.PermisoId = 0;
|
|
37
|
+
// this.RolId = 0;
|
|
38
|
+
// this.PermisoId = 0;
|
|
45
39
|
this.EnlaceDePortal = undefined;
|
|
46
40
|
this.EnlaceDePerfil = undefined;
|
|
47
41
|
this.EnlaceDeAcceso = undefined;
|
|
48
|
-
}
|
|
42
|
+
};
|
|
49
43
|
|
|
50
44
|
async PasosDeFlujoDeAprobacion(Identificador, PasoActual, Accion, Metadatos, Justificacion, LastUser) {
|
|
51
45
|
const DatosARetornar = {};
|
|
46
|
+
|
|
47
|
+
// Determina si la acción es una improbación para manejar el flujo de forma diferente
|
|
52
48
|
const EsImprobacion = Accion === 'Improbacion';
|
|
49
|
+
|
|
50
|
+
// Obtiene el ID del flujo de aprobación configurado para este módulo
|
|
53
51
|
const idDelFlujoDeAprobacion = await this.idDelFlujoDeAprobacion();
|
|
54
52
|
|
|
53
|
+
// Consulta cuál es el último paso del flujo, para saber si el detalle queda completamente aprobado
|
|
55
54
|
const PasoMaximo = await ejecutarConsultaSIGU("SELECT MAX(`NumeroDePaso`) \
|
|
56
55
|
AS `PasoMaximo` FROM `SIGU`.`SIGU_FlujosDeAprobacionPasos` WHERE \
|
|
57
56
|
`FlujoDeAprobacionId` = ?"
|
|
58
57
|
, [idDelFlujoDeAprobacion]);
|
|
59
58
|
|
|
59
|
+
// En improbación el flujo retrocede, por lo que el paso siguiente se resuelve después;
|
|
60
|
+
// en aprobación simplemente avanza al siguiente paso
|
|
60
61
|
let PasoSiguiente = EsImprobacion ? PasoActual : PasoActual + 1;
|
|
61
62
|
|
|
63
|
+
// Verifica que el usuario tenga permiso para actuar en el paso correspondiente
|
|
62
64
|
const TienePermiso = await ejecutarConsultaSIGU("SELECT `NumeroDePasoPorImprobacion` FROM `SIGU`.`SIGU_FlujosDeAprobacionPasos` \
|
|
63
65
|
WHERE `NumeroDePaso`=? AND (`Identificadores` LIKE '%?%' OR `Identificadores`='Persona usuaria')",
|
|
64
66
|
[PasoSiguiente, Number(Identificador)]);
|
|
65
67
|
|
|
68
|
+
// Si el usuario no aparece como firmante autorizado del paso, se corta la ejecución
|
|
66
69
|
if (TienePermiso.length == 0) {
|
|
67
70
|
DatosARetornar.Mensaje = 'No tiene permisos para firmar este detalle';
|
|
68
71
|
DatosARetornar.error = true;
|
|
69
72
|
return DatosARetornar;
|
|
70
73
|
}
|
|
71
74
|
|
|
75
|
+
// Registra el movimiento en el historial del flujo de aprobación
|
|
72
76
|
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_FlujosDeAprobacionMovimientos` VALUES (?, ?, ?, ?, ?, ?, NOW(4), ?)"
|
|
73
77
|
, [idDelFlujoDeAprobacion, PasoActual
|
|
74
78
|
, Identificador, Accion
|
|
75
79
|
, Justificacion, JSON.stringify(Metadatos), LastUser]);
|
|
76
80
|
|
|
81
|
+
// En improbación, el paso destino viene definido en la configuración del flujo (retroceso configurado)
|
|
77
82
|
PasoSiguiente = EsImprobacion ? TienePermiso[0].NumeroDePasoPorImprobacion : PasoSiguiente;
|
|
78
83
|
|
|
84
|
+
// Indica al llamador si el detalle alcanzó el último paso y debe cambiar su estado global
|
|
79
85
|
DatosARetornar.CambiarEstado = PasoSiguiente === PasoMaximo[0].PasoMaximo;
|
|
80
86
|
DatosARetornar.Mensaje = EsImprobacion ? 'Detalle firmado como no aprobado' : 'Detalle firmado correctamente';
|
|
81
87
|
DatosARetornar.PasoSiguiente = PasoSiguiente;
|
|
@@ -110,7 +116,7 @@ class Miscelaneo {
|
|
|
110
116
|
JSON_VALUE(Solicitud, '$.originalUrl') AS URL,
|
|
111
117
|
IFNULL(JSON_VALUE(Solicitud, '$.country'), 'Costa Rica') AS Pais,
|
|
112
118
|
SUBSTRING_INDEX(JSON_VALUE(Solicitud, '$.headers.authorization'), ' ', -1) AS Token,
|
|
113
|
-
CASE
|
|
119
|
+
CASE
|
|
114
120
|
WHEN JSON_VALUE(Solicitud, '$.userAgent') LIKE '%Mobile%' THEN 'Móvil'
|
|
115
121
|
WHEN JSON_VALUE(Solicitud, '$.userAgent') LIKE '%Android%' AND JSON_VALUE(Solicitud, '$.userAgent') NOT LIKE '%Mobile%' THEN 'Tablet'
|
|
116
122
|
WHEN JSON_VALUE(Solicitud, '$.userAgent') LIKE '%iPad%' THEN 'Tablet'
|
|
@@ -129,6 +135,11 @@ class Miscelaneo {
|
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
|
|
138
|
+
async cerrarSesionPorToken(Token) {
|
|
139
|
+
await ejecutarConsultaSIGU("DELETE FROM `SIGU`.`SIGU_Sesiones` WHERE `Token` = ?", [Token]);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
132
143
|
async UsuariosActuales() {
|
|
133
144
|
const ConexionSigu = await crearObjetoConexionSIGU();
|
|
134
145
|
const Actuales = await ConexionSigu.query("SELECT COUNT(DISTINCT `Identificador`) AS `Total` FROM `SIGU`.`SIGU_Sesiones` WHERE `LastUpdate` >= NOW() - INTERVAL 2 HOUR");
|
|
@@ -137,103 +148,2451 @@ class Miscelaneo {
|
|
|
137
148
|
return {
|
|
138
149
|
UsuariosActuales: Actuales[0][0]['Total'],
|
|
139
150
|
UsuariosActivos: Activos[0][0]['Total']
|
|
140
|
-
}
|
|
151
|
+
}
|
|
141
152
|
}
|
|
142
153
|
|
|
143
|
-
async
|
|
154
|
+
async generarFirmaHTML(Identificador, FechaDeLaFirma) {
|
|
155
|
+
const ReporteHTML = require('./ReporteHTML.js');
|
|
156
|
+
return await ReporteHTML.generarFirmaHTML(Identificador, FechaDeLaFirma);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
GenerarReporteHTMLRegistrosVerticales(ElementosParaLaTabla, ParametrosExcluidos = [], ParametrosExtra = [], MostrarEncabezado = true) {
|
|
160
|
+
const ReporteHTML = require('./ReporteHTML.js');
|
|
161
|
+
return ReporteHTML.GenerarReporteHTMLRegistrosVerticales(ElementosParaLaTabla, ParametrosExcluidos, ParametrosExtra, MostrarEncabezado);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
GenerarReporteHTMLEncabezado(InformacionDeLaDerecha, titulares, marcaDeAgua = '') {
|
|
165
|
+
const ReporteHTML = require('./ReporteHTML.js');
|
|
166
|
+
return ReporteHTML.GenerarReporteHTMLEncabezado(InformacionDeLaDerecha, titulares, marcaDeAgua);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
GenerarReporteHTMLFecha() {
|
|
170
|
+
const ReporteHTML = require('./ReporteHTML.js');
|
|
171
|
+
return ReporteHTML.GenerarReporteHTMLFecha();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
GenerarReporteHTMLTablas(ElementosParaLaTabla, ParametrosExcluidos = [], ParametrosExtra = []) {
|
|
175
|
+
const ReporteHTML = require('./ReporteHTML.js');
|
|
176
|
+
return ReporteHTML.GenerarReporteHTMLTablas(ElementosParaLaTabla, ParametrosExcluidos, ParametrosExtra);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
GenerarReporteHTMLPie() {
|
|
180
|
+
const ReporteHTML = require('./ReporteHTML.js');
|
|
181
|
+
return ReporteHTML.GenerarReporteHTMLPie();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
obtenerNombreLaBaseDeDatos() {
|
|
185
|
+
return this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async RegistrarPermisoExtra(Permiso, Descripcion) {
|
|
189
|
+
await ejecutarConsultaSIGU("SELECT IFNULL(MAX(`PermisoExtraId`), 0) + 1 INTO @`SiguientePermisoId` FROM `SIGU`.`SIGU_PermisosExtraV2`;\
|
|
190
|
+
INSERT INTO `SIGU`.`SIGU_PermisosExtraV2` VALUES\
|
|
191
|
+
(@`SiguientePermisoId`, ?, ?, ?, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUser` = USER(), `Nombre` = ?, `Descripcion` = ?;"
|
|
192
|
+
, [Permiso, this.NombreCanonicoDelModulo, Descripcion, Permiso, Descripcion]);
|
|
193
|
+
|
|
194
|
+
// Asginación inicial de permisos
|
|
195
|
+
if (this.UsuariosConAccesoInicial.length > 0) {
|
|
196
|
+
const PermisoExtraIdValor = await this.PermisoExtraId(Permiso);
|
|
197
|
+
this.UsuariosConAccesoInicial.forEach(async (dato) => {
|
|
198
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_PermisosExtraPersonasV2` VALUES (?,\
|
|
199
|
+
(SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = ?), NOW(4), USER())\
|
|
200
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
201
|
+
, [PermisoExtraIdValor, dato]);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async PermisoExtraId(Permiso) {
|
|
207
|
+
const PermisoExtraId = await ejecutarConsultaSIGU("SELECT `PermisoExtraId` FROM `SIGU`.`SIGU_PermisosExtraV2` \
|
|
208
|
+
WHERE `Nombre` = ? AND `Modulo` = ?"
|
|
209
|
+
, [Permiso, this.NombreCanonicoDelModulo]);
|
|
210
|
+
return PermisoExtraId[0]['PermisoExtraId'];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
obtenerNombreCanonicoDelModulo() {
|
|
214
|
+
return this.NombreCanonicoDelModulo;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
obtenerVersionDelModulo() {
|
|
218
|
+
return this.Version;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async convertirTextoEnArchivoLocal(Texto, Token, NombreDelArchivo, Etiquetas) {
|
|
222
|
+
let EnlaceDelBack = 'http';
|
|
223
|
+
EnlaceDelBack = EnlaceDelBack + ((process.env.ENV || 'local') === 'production' ? 's' : '');
|
|
224
|
+
EnlaceDelBack = EnlaceDelBack + '://';
|
|
225
|
+
EnlaceDelBack = EnlaceDelBack + (['desarrollo', 'calidad', 'pruebas', 'production'].includes(process.env.ENV) ? this.NombreDelRepositorioDelBackend : 'localhost');
|
|
226
|
+
EnlaceDelBack = EnlaceDelBack + '/misc/cargarArchivo/' + Etiquetas;
|
|
227
|
+
// let EnlaceDelBack = `${Solicitud.protocol}://${Solicitud.get('host')}` + '/misc/cargarArchivo/' + Etiquetas;
|
|
144
228
|
const Encabezados = {
|
|
145
|
-
'
|
|
146
|
-
'Authorization': 'Bearer ' + await this.getUUID(),
|
|
229
|
+
'Authorization': Token,
|
|
147
230
|
'Referrer': this.NombreDelRepositorioDelBackend,
|
|
148
|
-
'Origin':
|
|
231
|
+
'Origin': EnlaceDelBack
|
|
149
232
|
};
|
|
150
|
-
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
233
|
+
const blob = new Blob([Texto], { type: 'text/plain' });
|
|
234
|
+
const formData = new FormData();
|
|
235
|
+
formData.append('archivo', blob, NombreDelArchivo);
|
|
236
|
+
try {
|
|
237
|
+
const response = await fetch(EnlaceDelBack, {
|
|
238
|
+
method: 'POST',
|
|
239
|
+
headers: Encabezados,
|
|
240
|
+
body: formData,
|
|
241
|
+
redirect: 'error'
|
|
242
|
+
});
|
|
243
|
+
if (!response.ok) {
|
|
244
|
+
const errorTexto = await response.text();
|
|
245
|
+
throw new Error(`Error del servidor (${response.status}): ${errorTexto}`);
|
|
246
|
+
}
|
|
247
|
+
return await response.json();
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error(error.message);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async RegistrarElServicio(Servicio, Tarjetas = null) {
|
|
254
|
+
const archivo = this._archivoFuenteActual;
|
|
255
|
+
try {
|
|
256
|
+
await ejecutarConsultaSIGU("REPLACE INTO `SIGU`.`SIGU_ModulosV2Secciones` (`Modulo`, `Descripcion`) VALUES (?, ?)"
|
|
257
|
+
, [this.NombreCanonicoDelModulo, Servicio]);
|
|
258
|
+
console.log(`Servicio ${Servicio} registrado correctamente`);
|
|
259
|
+
} catch (error) {
|
|
260
|
+
console.error(error.message);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (!Tarjetas) return;
|
|
264
|
+
|
|
265
|
+
const listaTarjetas = Array.isArray(Tarjetas) ? Tarjetas : [Tarjetas];
|
|
266
|
+
|
|
267
|
+
for (const tarjeta of listaTarjetas) {
|
|
268
|
+
try {
|
|
269
|
+
const titulo = tarjeta['Título'];
|
|
270
|
+
const existentes = await ejecutarConsultaSIGU(
|
|
271
|
+
`SELECT CAST(JSON_VALUE(\`Datos\`, '$."Posición"') AS UNSIGNED) AS Posicion, JSON_VALUE(\`Datos\`, '$."Título"') AS Titulo, JSON_VALUE(\`Datos\`, '$."Descripción"') AS Descripcion FROM \`SIGU\`.\`SIGU_ModulosV2Tarjetas\` WHERE \`Modulo\` = ? AND JSON_VALUE(\`Datos\`, '$."Título"') = ?`,
|
|
272
|
+
[this.NombreCanonicoDelModulo, titulo]
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
let datosFinales;
|
|
276
|
+
if (existentes.length > 0) {
|
|
277
|
+
datosFinales = { ...tarjeta, 'Posición': existentes[0].Posicion, 'Título': existentes[0].Titulo, 'Descripción': existentes[0].Descripcion, 'Archivo': archivo };
|
|
278
|
+
await ejecutarConsultaSIGU(
|
|
279
|
+
`UPDATE \`SIGU\`.\`SIGU_ModulosV2Tarjetas\` SET \`Datos\` = ?, \`LastUser\` = 'Sistema' WHERE \`Modulo\` = ? AND JSON_VALUE(\`Datos\`, '$."Título"') = ?`,
|
|
280
|
+
[JSON.stringify(datosFinales), this.NombreCanonicoDelModulo, titulo]
|
|
281
|
+
);
|
|
282
|
+
} else {
|
|
283
|
+
let posicion = tarjeta['Posición'];
|
|
284
|
+
if (posicion === undefined) {
|
|
285
|
+
const [{ NuevaPosicion }] = await ejecutarConsultaSIGU(
|
|
286
|
+
`SELECT COALESCE(MAX(CAST(JSON_VALUE(\`Datos\`, '$."Posición"') AS UNSIGNED)), 0) + 10 AS NuevaPosicion FROM \`SIGU\`.\`SIGU_ModulosV2Tarjetas\` WHERE \`Modulo\` = ?`,
|
|
287
|
+
[this.NombreCanonicoDelModulo]
|
|
288
|
+
);
|
|
289
|
+
posicion = NuevaPosicion;
|
|
290
|
+
}
|
|
291
|
+
datosFinales = { ...tarjeta, 'Posición': posicion, 'Archivo': archivo };
|
|
292
|
+
await ejecutarConsultaSIGU(
|
|
293
|
+
`INSERT INTO \`SIGU\`.\`SIGU_ModulosV2Tarjetas\` (\`Modulo\`, \`Datos\`, \`LastUser\`) VALUES (?, ?, 'Sistema')`,
|
|
294
|
+
[this.NombreCanonicoDelModulo, JSON.stringify(datosFinales)]
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
console.log(`Tarjeta "${titulo}" registrada correctamente`);
|
|
298
|
+
} catch (error) {
|
|
299
|
+
console.error(`Error al registrar tarjeta "${tarjeta['Título']}":`, error.message);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
_archivoFuenteActual = null;
|
|
305
|
+
_archivoCache = new Map();
|
|
306
|
+
|
|
307
|
+
_buscarArchivoRecursivo(dir, nombre) {
|
|
308
|
+
if (this._archivoCache.has(nombre)) return this._archivoCache.get(nombre);
|
|
309
|
+
const fs = require('fs');
|
|
310
|
+
const path = require('path');
|
|
311
|
+
const buscar = (directorio) => {
|
|
312
|
+
for (const entrada of fs.readdirSync(directorio, { withFileTypes: true })) {
|
|
313
|
+
const ruta = path.join(directorio, entrada.name);
|
|
314
|
+
if (entrada.isDirectory()) {
|
|
315
|
+
const resultado = buscar(ruta);
|
|
316
|
+
if (resultado) return resultado;
|
|
317
|
+
} else if (entrada.name === nombre) {
|
|
318
|
+
return ruta;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
155
322
|
};
|
|
156
|
-
|
|
157
|
-
|
|
323
|
+
const resultado = buscar(dir);
|
|
324
|
+
this._archivoCache.set(nombre, resultado);
|
|
325
|
+
return resultado;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async DatosParaReporteCSV() {
|
|
329
|
+
return this.convertirACSV(await this.DatosParaGraficoDeBarras());
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async DatosParaGraficoDeBarras() {
|
|
333
|
+
return await ejecutarConsultaSIGU("SELECT MONTHNAME(`FechaNacimiento`) AS `EjeHorizontal`, `Sexo` AS `Etiqueta`, COUNT(*) AS `Total` FROM `SIGU`.`SIGU_Personas` WHERE MONTH(`FechaNacimiento`) > 0 AND `Sexo` <> '' GROUP BY MONTHNAME(`FechaNacimiento`), `Sexo` ORDER BY MONTH(`FechaNacimiento`)");
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
async DatosParaGraficoDePie() {
|
|
337
|
+
return await ejecutarConsultaSIGU("SELECT `Tipo` AS `Etiqueta`, COUNT(*) AS `Total` FROM `SIGU`.`SIGU_ModulosV2` GROUP BY `Tipo`");
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
JSONAHTML(input, title = 'Reporte') {
|
|
341
|
+
// intentar parsear si es string JSON
|
|
342
|
+
let obj = input;
|
|
343
|
+
if (typeof input === 'string') {
|
|
344
|
+
try { obj = JSON.parse(input); }
|
|
345
|
+
catch (e) { /* no es JSON, lo tratamos como texto primitivo */ }
|
|
158
346
|
}
|
|
159
|
-
|
|
160
|
-
|
|
347
|
+
|
|
348
|
+
const escapeHtml = (s) =>
|
|
349
|
+
String(s)
|
|
350
|
+
.replace(/&/g, '&')
|
|
351
|
+
.replace(/</g, '<')
|
|
352
|
+
.replace(/>/g, '>')
|
|
353
|
+
.replace(/"/g, '"')
|
|
354
|
+
.replace(/'/g, ''');
|
|
355
|
+
|
|
356
|
+
const isPrimitive = v => v === null || v === undefined || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean';
|
|
357
|
+
|
|
358
|
+
const seen = new WeakSet();
|
|
359
|
+
|
|
360
|
+
function renderValue(v) {
|
|
361
|
+
if (v === null || v === undefined || v === '') return '—';
|
|
362
|
+
if (isPrimitive(v)) return escapeHtml(String(v));
|
|
363
|
+
if (Array.isArray(v)) return renderArray(v);
|
|
364
|
+
return renderObject(v);
|
|
161
365
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
366
|
+
|
|
367
|
+
function renderObject(o) {
|
|
368
|
+
if (seen.has(o)) return '<em>(referencia circular)</em>';
|
|
369
|
+
seen.add(o);
|
|
370
|
+
|
|
371
|
+
// si es objeto vacío
|
|
372
|
+
const keys = Object.keys(o);
|
|
373
|
+
if (keys.length === 0) {
|
|
374
|
+
seen.delete(o);
|
|
375
|
+
return '—';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// construir filas key / value
|
|
379
|
+
let rows = '';
|
|
380
|
+
for (const k of keys) {
|
|
381
|
+
rows += `
|
|
382
|
+
<tr>
|
|
383
|
+
<th>${escapeHtml(k)}</th>
|
|
384
|
+
<td>${renderValue(o[k])}</td>
|
|
385
|
+
</tr>
|
|
386
|
+
`;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
seen.delete(o);
|
|
390
|
+
return `<table border='1'><tbody>${rows}</tbody></table>`;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function renderArray(arr) {
|
|
394
|
+
if (arr.length === 0) return '—';
|
|
395
|
+
|
|
396
|
+
// si todos son primitivos => lista simple
|
|
397
|
+
if (arr.every(isPrimitive)) {
|
|
398
|
+
return `<div>${arr.map(x => `<span>${escapeHtml(String(x))}</span>`).join(' ')}</div>`;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// si todos son objetos => tabla con columnas (union de keys)
|
|
402
|
+
if (arr.every(it => typeof it === 'object' && it !== null && !Array.isArray(it))) {
|
|
403
|
+
const columns = Array.from(new Set(arr.flatMap(item => Object.keys(item))));
|
|
404
|
+
const header = columns.map(c => `<th>${escapeHtml(c)}</th>`).join('');
|
|
405
|
+
const body = arr.map(item => {
|
|
406
|
+
const cells = columns.map(c => `<td>${item.hasOwnProperty(c) ? renderValue(item[c]) : ''}</td>`).join('');
|
|
407
|
+
return `<tr>${cells}</tr>`;
|
|
408
|
+
}).join('');
|
|
409
|
+
return `<table border='1'><thead><tr>${header}</tr></thead><tbody>${body}</tbody></table>`;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// mezcla de tipos: render por ítem
|
|
413
|
+
return `<div>${arr.map(it => `<div>${renderValue(it)}</div>`).join('')}</div>`;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// construir contenido (una sección por clave del primer nivel)
|
|
417
|
+
let content = '';
|
|
418
|
+
if (typeof obj === 'object' && obj !== null && !Array.isArray(obj)) {
|
|
419
|
+
const topKeys = Object.keys(obj);
|
|
420
|
+
for (const k of topKeys) {
|
|
421
|
+
content += `
|
|
422
|
+
<section>
|
|
423
|
+
<h2>${escapeHtml(k)}</h2>
|
|
424
|
+
<div>${renderValue(obj[k])}</div>
|
|
425
|
+
</section>
|
|
426
|
+
`;
|
|
427
|
+
}
|
|
428
|
+
} else {
|
|
429
|
+
// si el input fue un array o primitivo
|
|
430
|
+
content = `<section><div>${renderValue(obj)}</div></section>`;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// template HTML + CSS
|
|
434
|
+
return `<h1>${escapeHtml(title)}</h1>${content}`;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async generarLastUser(Solicitud) {
|
|
438
|
+
const Resultado = await this.obtenerDatosDelUsuario(Solicitud.headers.authorization);
|
|
439
|
+
// try {
|
|
440
|
+
// Resultado = await this.obtenerDatosDelUsuario(Solicitud.headers.authorization);
|
|
441
|
+
// if (!Resultado) {
|
|
442
|
+
// throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
443
|
+
// }
|
|
444
|
+
// } catch (error) {
|
|
445
|
+
// console.log(error);
|
|
446
|
+
// }
|
|
447
|
+
let LastUser = '';
|
|
448
|
+
if (Resultado) {
|
|
449
|
+
LastUser = Resultado.Identificador;
|
|
450
|
+
}
|
|
451
|
+
LastUser = LastUser + '@' + Solicitud.headers.host.trim()
|
|
452
|
+
+ '@' + Solicitud.headers["user-agent"].trim()
|
|
453
|
+
+ '@' + (Solicitud.ip || Solicitud.headers['x-forwarded-for'] || Solicitud.socket.remoteAddress);
|
|
454
|
+
return LastUser;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
async validarAccesoDelOrigen(Solicitud) {
|
|
458
|
+
if (this.NombresParalocalhost().includes(process.env.HOST) && (typeof process.env.DB_HOST_SIGU === "undefined")) {
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
const Resultado = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_RepositoriosAccesos`\
|
|
462
|
+
WHERE `RepositorioDestino` = ? AND `RepositorioOrigen` = ?"
|
|
463
|
+
, [this.NombreDelRepositorioDelBackend, this.NombreDelRepositorioDelFrontend]);
|
|
464
|
+
if (Resultado[0]['Total'] === 1) {
|
|
465
|
+
return true;
|
|
466
|
+
} else {
|
|
467
|
+
console.error('validarAccesoDelOrigen:', Solicitud.headers.origin, 'intentó consumir a:', this.NombreDelRepositorioDelBackend);
|
|
468
|
+
const Mensaje = "Error de validarAccesoDelOrigen por fallo de autorización.";
|
|
469
|
+
const solicitudCompleta = {
|
|
470
|
+
metodo: Solicitud.method,
|
|
471
|
+
url: Solicitud.originalUrl,
|
|
472
|
+
ip: Solicitud.ip,
|
|
473
|
+
headers: Solicitud.headers,
|
|
474
|
+
query: Solicitud.query,
|
|
475
|
+
params: Solicitud.params,
|
|
476
|
+
body: Solicitud.body,
|
|
477
|
+
};
|
|
478
|
+
const contenidoHTML = `
|
|
479
|
+
<h2>Solicitud HTTP completa</h2>
|
|
480
|
+
<p><strong>Método:</strong> ${solicitudCompleta.metodo}</p>
|
|
481
|
+
<p><strong>URL:</strong> ${solicitudCompleta.url}</p>
|
|
482
|
+
<p><strong>IP:</strong> ${solicitudCompleta.ip}</p>
|
|
483
|
+
<h3>Headers:</h3>
|
|
484
|
+
<pre>${JSON.stringify(solicitudCompleta.headers, null, 2)}</pre>
|
|
485
|
+
<h3>Query:</h3>
|
|
486
|
+
<pre>${JSON.stringify(solicitudCompleta.query, null, 2)}</pre>
|
|
487
|
+
<h3>Params:</h3>
|
|
488
|
+
<pre>${JSON.stringify(solicitudCompleta.params, null, 2)}</pre>
|
|
489
|
+
<h3>Body:</h3>
|
|
490
|
+
<pre>${JSON.stringify(solicitudCompleta.body, null, 2)}</pre>
|
|
491
|
+
`;
|
|
492
|
+
envioDeCorreo(process.env.DESTINATARIODEINFORMESDEERROR, Mensaje, contenidoHTML);
|
|
493
|
+
}
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
getNombreDelRepositorioDelBackend() {
|
|
498
|
+
return this.NombreDelRepositorioDelBackend;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
async ejecucionCadaXMinutos(callback, intervaloMinutos) {
|
|
502
|
+
while (true) {
|
|
503
|
+
try {
|
|
504
|
+
await this.crearTareaProgramada(callback);
|
|
505
|
+
break;
|
|
506
|
+
} catch (error) {
|
|
507
|
+
console.error('Error al ejecutar crearTareaProgramada:', error);
|
|
508
|
+
console.log('Reintentando en 5 segundos...');
|
|
509
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
const intervaloMilisegundos = intervaloMinutos * 60 * 1000;
|
|
513
|
+
while (true) {
|
|
514
|
+
const inicio = Date.now();
|
|
515
|
+
try {
|
|
516
|
+
await callback();
|
|
517
|
+
} catch (error) {
|
|
518
|
+
console.error(`Error en la función "${callback.name}":`, error?.message || error);
|
|
519
|
+
}
|
|
520
|
+
const duracion = Date.now() - inicio;
|
|
521
|
+
const tiempoRestante = intervaloMilisegundos - duracion;
|
|
522
|
+
if (tiempoRestante > 0) {
|
|
523
|
+
await new Promise(resolve => setTimeout(resolve, tiempoRestante));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async restablecimientoDeClave(Solicitud) {
|
|
529
|
+
let Clave = await ejecutarConsultaSIGU("SELECT MD5(NOW(4)) AS `Dato`");
|
|
530
|
+
Clave = Clave[0]['Dato'];
|
|
531
|
+
console.log("El usuario: " + Solicitud.body.Identificacion + " ha solicitado restablecer su clave de acceso.");
|
|
532
|
+
const CorreoElectronico = await ejecutarConsultaSIGU("SELECT `CorreoElectronico`, `Identificador` FROM `SIGU`.`SIGU_CorreosPersona` WHERE `Identificador` = (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = ?) AND `Principal` = TRUE LIMIT 1"
|
|
533
|
+
, [Solicitud.body.Identificacion]);
|
|
534
|
+
const LastUser = Solicitud.body.Identificacion
|
|
535
|
+
+ '@' + Solicitud.headers.host.trim()
|
|
536
|
+
+ '@' + Solicitud.headers["user-agent"].trim()
|
|
537
|
+
+ '@' + (Solicitud.ip || Solicitud.headers['x-forwarded-for'] || Solicitud.socket.remoteAddress);
|
|
538
|
+
await ejecutarConsultaSIGU("REPLACE INTO `SIGU`.`SIGU_ClavesTemporalesDeLasPersonas` VALUES (?, ?, NOW(4), ?)"
|
|
539
|
+
, [CorreoElectronico[0]['Identificador'], Clave, LastUser]);
|
|
540
|
+
const SolicitudTextual = JSON.stringify({
|
|
541
|
+
timestamp: new Date().toISOString(),
|
|
542
|
+
httpVersion: Solicitud.httpVersion,
|
|
543
|
+
method: Solicitud.method,
|
|
544
|
+
protocol: Solicitud.protocol,
|
|
545
|
+
secure: Solicitud.secure,
|
|
546
|
+
ip: Solicitud.ip,
|
|
547
|
+
ips: Solicitud.ips,
|
|
548
|
+
hostname: Solicitud.hostname,
|
|
549
|
+
originalUrl: Solicitud.originalUrl,
|
|
550
|
+
baseUrl: Solicitud.baseUrl,
|
|
551
|
+
path: Solicitud.path,
|
|
552
|
+
url: Solicitud.url,
|
|
553
|
+
headers: Solicitud.headers,
|
|
554
|
+
query: Solicitud.query,
|
|
555
|
+
params: Solicitud.params,
|
|
556
|
+
body: Solicitud.body,
|
|
557
|
+
cookies: Solicitud.cookies,
|
|
558
|
+
signedCookies: Solicitud.signedCookies,
|
|
559
|
+
userAgent: Solicitud.get('User-Agent'),
|
|
560
|
+
authUser: Solicitud.user ?? null,
|
|
561
|
+
});
|
|
562
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_SolicitudesDeRestablecimientoDeClave` VALUES (?, ?, ?, NOW(4), ?)"
|
|
563
|
+
, [CorreoElectronico[0]['Identificador'], Solicitud.body.Identificacion
|
|
564
|
+
, SolicitudTextual, LastUser]);
|
|
565
|
+
await envioDeCorreo(CorreoElectronico[0]['CorreoElectronico'], "Solicitud de restablecimiento de clave",
|
|
566
|
+
"<p>Estimada persona usuaria,<br /><br />"
|
|
567
|
+
+ "Se ha realizado una solicitud de cambio de clave para su cuenta de acceso a SIGU.</p>"
|
|
568
|
+
+ "<p>Para continuar con el cambio por favor presione "
|
|
569
|
+
+ "<a href='" + this.EnlaceDeAcceso + "/?Identificacion=" + Solicitud.body.Identificacion + "'>aquí</a>"
|
|
570
|
+
+ " de lo contrario omita este mensaje.</p>"
|
|
571
|
+
+ "<p>Su nueva clave es: " + Clave + " y se le invita a cambiarla lo antes posible haciendo uso del sistema.</p>"
|
|
572
|
+
+ "<p>La vigencia de la clave generada es de 10 minutos, luego de eso se eliminará la solicitud.</p>"
|
|
573
|
+
+ "<p>Si usted no solicitó el cambio de contraseña por favor omita este correo.</p>");
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
async AutenticarConGoogle(Solicitud) {
|
|
578
|
+
const { OAuth2Client } = require('google-auth-library');
|
|
579
|
+
const jwt = require('jsonwebtoken');
|
|
580
|
+
const clientId = await this.googleClientId();
|
|
581
|
+
const client = new OAuth2Client(clientId);
|
|
582
|
+
const ConexionSigu = await crearObjetoConexionSIGU();
|
|
583
|
+
const LastUser = await this.generarLastUser(Solicitud);
|
|
584
|
+
|
|
167
585
|
try {
|
|
168
|
-
|
|
169
|
-
|
|
586
|
+
const ticket = await client.verifyIdToken({
|
|
587
|
+
idToken: Solicitud.body.token,
|
|
588
|
+
audience: clientId,
|
|
589
|
+
});
|
|
590
|
+
const payload = ticket.getPayload();
|
|
591
|
+
const email = payload['email'];
|
|
592
|
+
|
|
593
|
+
const resultadosEmail = await ConexionSigu.query("SELECT `Identificador` FROM `SIGU`.`SIGU_CorreosPersona` WHERE `CorreoElectronico` = ? AND `Principal` = TRUE LIMIT 1", [email]);
|
|
594
|
+
|
|
595
|
+
if (resultadosEmail[0].length === 0) {
|
|
596
|
+
console.log("El correo de Google", email, "no está registrado como principal en SIGU");
|
|
597
|
+
return { error: "Su cuenta de Google no está vinculada a ningún usuario de SIGU." };
|
|
170
598
|
}
|
|
171
|
-
|
|
172
|
-
|
|
599
|
+
|
|
600
|
+
const Identificador = resultadosEmail[0][0]['Identificador'];
|
|
601
|
+
const resultadosUsuario = await ConexionSigu.query("SELECT `Identificacion` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` = ? AND `Activo` = TRUE", [Identificador]);
|
|
602
|
+
|
|
603
|
+
if (resultadosUsuario[0].length === 0) {
|
|
604
|
+
return { error: "El usuario asociado a esta cuenta no está activo." };
|
|
173
605
|
}
|
|
174
|
-
|
|
175
|
-
|
|
606
|
+
|
|
607
|
+
const Identificacion = resultadosUsuario[0][0]['Identificacion'];
|
|
608
|
+
|
|
609
|
+
// Generar Token
|
|
610
|
+
const Token = await jwt.sign({ Identificador: Identificador, uid: Identificador }, await this.palabraSecretaParaTokens(), { expiresIn: '2h' });
|
|
611
|
+
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]);
|
|
612
|
+
await ConexionSigu.query("DELETE FROM `SIGU`.`SIGU_SesionesFallidas` WHERE `Identificador` = ?", [Identificador]);
|
|
613
|
+
|
|
614
|
+
// OBTENER IP DEL USUARIO
|
|
615
|
+
const ipUsuario = (Solicitud.headers['x-forwarded-for'] || '').split(',').shift() || Solicitud.socket?.remoteAddress || Solicitud.connection?.remoteAddress || '-';
|
|
616
|
+
|
|
617
|
+
// SI LA IP YA EXISTE CONTINUA
|
|
618
|
+
await ConexionSigu.query("\
|
|
619
|
+
INSERT INTO `SIGU`.`SIGU_DireccionesUsadasPorLosUsuarios` \
|
|
620
|
+
(`DireccionUsadaPorElUsuario`, `Identificador`, `LastUpdate`, `LastUser`) \
|
|
621
|
+
VALUES (?, ?, NOW(4), ?) \
|
|
622
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4), `LastUser` = ?;", [
|
|
623
|
+
ipUsuario,
|
|
624
|
+
Identificador,
|
|
625
|
+
LastUser,
|
|
626
|
+
LastUser
|
|
627
|
+
]);
|
|
628
|
+
|
|
629
|
+
return { Token, Dominio: ((process.env.ENV || 'local') === 'production' ? '.sigu.utn.ac.cr' : '.181.193.85.44.nip.io') };
|
|
630
|
+
|
|
631
|
+
} catch (error) {
|
|
632
|
+
console.error("Error en AutenticarConGoogle:", error);
|
|
633
|
+
return { error: "Error al autenticar con Google" };
|
|
634
|
+
} finally {
|
|
635
|
+
if (ConexionSigu) await ConexionSigu.end();
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
async Autenticar(Solicitud) {
|
|
640
|
+
const crypto = require('crypto');
|
|
641
|
+
const bcrypt = require('bcryptjs');
|
|
642
|
+
const jwt = require('jsonwebtoken');
|
|
643
|
+
const LastUser = await this.generarLastUser(Solicitud);
|
|
644
|
+
const ConexionSigu = await crearObjetoConexionSIGU();
|
|
645
|
+
|
|
646
|
+
try {
|
|
647
|
+
const resultados = await ConexionSigu.query("SELECT `Identificador`, `Clave` FROM `SIGU`.`SIGU_Personas` WHERE `Activo` = TRUE AND `Identificacion` = ?", [Solicitud.body.Identificacion]);
|
|
648
|
+
const Identificador = resultados[0][0]['Identificador'];
|
|
649
|
+
const Resultado = await bcrypt.compare(crypto.createHash('md5').update(Solicitud.body.Clave).digest("hex"), resultados[0][0]['Clave']);
|
|
650
|
+
|
|
651
|
+
if (Resultado) {
|
|
652
|
+
console.log("La clave brindada para el usuario", Solicitud.body.Identificacion, "coincide");
|
|
653
|
+
const Token = await jwt.sign({ Identificador: Identificador, uid: Identificador }, await this.palabraSecretaParaTokens(), { expiresIn: '2h' });
|
|
654
|
+
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]);
|
|
655
|
+
await ConexionSigu.query("DELETE FROM `SIGU`.`SIGU_SesionesFallidas` WHERE `Identificador` = ?", [Identificador]);
|
|
656
|
+
const permisos = await ConexionSigu.query("\
|
|
657
|
+
WITH RECURSIVE`ModulosJerarquia` AS( \
|
|
658
|
+
SELECT`Nombre`, `Padre` \
|
|
659
|
+
FROM`SIGU`.`SIGU_ModulosV2` \
|
|
660
|
+
WHERE`Nombre` COLLATE utf8mb4_spanish_ci IN(\
|
|
661
|
+
SELECT`Modulo` \
|
|
662
|
+
FROM`SIGU`.`SIGU_PermisosV2` \
|
|
663
|
+
WHERE`Nombre` LIKE '%Público%' \
|
|
664
|
+
) \
|
|
665
|
+
UNION ALL \
|
|
666
|
+
SELECT`m`.`Nombre`, `m`.`Padre` \
|
|
667
|
+
FROM`SIGU`.`SIGU_ModulosV2` `m` \
|
|
668
|
+
INNER JOIN`ModulosJerarquia` `mj` \
|
|
669
|
+
ON`mj`.`Padre` COLLATE utf8mb4_spanish_ci = \
|
|
670
|
+
`m`.`Nombre` COLLATE utf8mb4_spanish_ci \
|
|
671
|
+
) \
|
|
672
|
+
SELECT DISTINCT \
|
|
673
|
+
`p`.`PermisoId` \
|
|
674
|
+
FROM`ModulosJerarquia` `mj` \
|
|
675
|
+
JOIN`SIGU`.`SIGU_PermisosV2` `p` \
|
|
676
|
+
ON`p`.`Modulo` COLLATE utf8mb4_spanish_ci = \
|
|
677
|
+
`mj`.`Nombre` COLLATE utf8mb4_spanish_ci; \
|
|
678
|
+
");
|
|
679
|
+
|
|
680
|
+
for (const permiso of permisos[0]) {
|
|
681
|
+
await ConexionSigu.query(" \
|
|
682
|
+
INSERT INTO `SIGU`.`SIGU_PermisosPersonasV2` \
|
|
683
|
+
(`PermisoId`, `Identificador`, `LastUpdate`, `LastUser`) \
|
|
684
|
+
VALUES (?, ?, NOW(4), USER()) \
|
|
685
|
+
ON DUPLICATE KEY UPDATE \
|
|
686
|
+
`LastUser` = USER(), \
|
|
687
|
+
`LastUpdate` = NOW(4);", [permiso.PermisoId, Identificador]);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// OBTENER IP DEL USUARIO
|
|
691
|
+
const ipUsuario = (Solicitud.headers['x-forwarded-for'] || '').split(',').shift() || Solicitud.socket?.remoteAddress || Solicitud.connection?.remoteAddress || '-';
|
|
692
|
+
|
|
693
|
+
// VERIFICAR SI LA IP YA EXISTE
|
|
694
|
+
const ipExiste = await ConexionSigu.query("\
|
|
695
|
+
SELECT COUNT(*) AS Total \
|
|
696
|
+
FROM `SIGU`.`SIGU_DireccionesUsadasPorLosUsuarios` \
|
|
697
|
+
WHERE `Identificador` = ? AND `DireccionUsadaPorElUsuario` = ?", [Identificador, ipUsuario]);
|
|
698
|
+
|
|
699
|
+
// Verificar si la fecha de cambio supera los 2 meses
|
|
700
|
+
const fechaUltimoCambio = await ConexionSigu.query(
|
|
701
|
+
"SELECT LastUpdate \
|
|
702
|
+
FROM `SIGU`.`SIGU_FechaDelUltimoCambioDeClave` \
|
|
703
|
+
WHERE `Identificador` = ?",
|
|
704
|
+
[Identificador]
|
|
705
|
+
);
|
|
706
|
+
let fechaBD = fechaUltimoCambio?.[0]?.[0]?.LastUpdate;
|
|
707
|
+
const fechaUltimo = new Date(fechaBD);
|
|
708
|
+
const fechaActual = new Date();
|
|
709
|
+
const diferenciaMs = fechaActual - fechaUltimo;
|
|
710
|
+
const diasPasados = diferenciaMs / (1000 * 60 * 60 * 24);
|
|
711
|
+
if (!fechaBD || diasPasados >= 60) {
|
|
712
|
+
await ConexionSigu.query(
|
|
713
|
+
"UPDATE`SIGU_Personas` \
|
|
714
|
+
SET`Clave` = '' \
|
|
715
|
+
where`Identificador` = ? ;",
|
|
716
|
+
[Identificador]
|
|
717
|
+
);
|
|
718
|
+
return { RequiereCambioContraseña: true };
|
|
719
|
+
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (ipExiste[0][0].Total === 0) {
|
|
723
|
+
// GENERAR CODIGO 2FA
|
|
724
|
+
let Codigo2FA = await ConexionSigu.query("SELECT UUID() AS `Dato`");
|
|
725
|
+
Codigo2FA = Codigo2FA[0][0].Dato;
|
|
726
|
+
|
|
727
|
+
// GUARDAR CODIGO 2FA
|
|
728
|
+
await ConexionSigu.query(" \
|
|
729
|
+
REPLACE INTO `SIGU`.`SIGU_CodigosDe2FAParaLosUsuarios` \
|
|
730
|
+
VALUES (?, ?, NOW(4), ?)", [
|
|
731
|
+
Identificador,
|
|
732
|
+
Codigo2FA,
|
|
733
|
+
LastUser
|
|
734
|
+
]);
|
|
735
|
+
|
|
736
|
+
// OBTENER CORREO
|
|
737
|
+
const CorreoElectronico = await ConexionSigu.query(
|
|
738
|
+
"SELECT `CorreoElectronico` \
|
|
739
|
+
FROM `SIGU`.`SIGU_CorreosPersona` \
|
|
740
|
+
WHERE `Identificador` = ? \
|
|
741
|
+
AND `Principal` = TRUE"
|
|
742
|
+
, [Identificador]);
|
|
743
|
+
// ENVIAR CORREO
|
|
744
|
+
await envioDeCorreo(
|
|
745
|
+
CorreoElectronico[0][0].CorreoElectronico,
|
|
746
|
+
"Código de verificación 2FA",
|
|
747
|
+
"<p>Hemos recibido su solicitud de acceso para 2FA.</p>" +
|
|
748
|
+
"<p>Para continuar con el proceso, por favor utilice el siguiente código único de verificación:</p>" +
|
|
749
|
+
"<p>" + Codigo2FA + "</p>" +
|
|
750
|
+
"<p>Si usted no inició este proceso, puede ignorar este mensaje.</p>"
|
|
751
|
+
);
|
|
752
|
+
return { Requiere2FA: true };
|
|
753
|
+
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// SI LA IP YA EXISTE CONTINUA
|
|
757
|
+
await ConexionSigu.query("\
|
|
758
|
+
INSERT INTO `SIGU`.`SIGU_DireccionesUsadasPorLosUsuarios` \
|
|
759
|
+
(`DireccionUsadaPorElUsuario`, `Identificador`, `LastUpdate`, `LastUser`) \
|
|
760
|
+
VALUES (?, ?, NOW(4), ?) \
|
|
761
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4), `LastUser` = ?;", [
|
|
762
|
+
ipUsuario,
|
|
763
|
+
Identificador,
|
|
764
|
+
LastUser,
|
|
765
|
+
LastUser
|
|
766
|
+
]);
|
|
767
|
+
return { Token, Dominio: ((process.env.ENV || 'local') === 'production' ? '.sigu.utn.ac.cr' : '.svc.cluster.local') };
|
|
768
|
+
|
|
769
|
+
} else {
|
|
770
|
+
console.log("La clave brindada para el usuario", Solicitud.body.Identificacion, "no conincide");
|
|
771
|
+
const Resultados2 = await ConexionSigu.query("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_ClavesTemporalesDeLasPersonas` WHERE `Identificador` = ? AND `Clave` = ?", [Identificador, Solicitud.body.Clave]);
|
|
772
|
+
if (Resultados2[0][0]['Total'] > 0) {
|
|
773
|
+
console.log("La clave brindada para el usuario", Solicitud.body.Identificacion, "no conincide, pero coincide la clave temporal");
|
|
774
|
+
await ConexionSigu.query("UPDATE `SIGU`.`SIGU_Personas` SET `Clave` = ?, `LastUpdate` = NOW(4), `LastUser` = ? WHERE `Identificacion` = ?"
|
|
775
|
+
, [await bcrypt.hash(require('crypto').createHash('md5').update(Solicitud.body.Clave).digest("hex"), 10), LastUser, Solicitud.body.Identificacion]);
|
|
776
|
+
await ConexionSigu.query("REPLACE INTO `SIGU`.`SIGU_FechaDelUltimoCambioDeClave` VALUES (?, NOW(), ?);", [Identificador, LastUser]);
|
|
777
|
+
await ConexionSigu.query("DELETE FROM `SIGU`.`SIGU_ClavesTemporalesDeLasPersonas`WHERE `Identificador` = ?", [Identificador]);
|
|
778
|
+
return await this.Autenticar(Solicitud);
|
|
779
|
+
|
|
780
|
+
} else {
|
|
781
|
+
await ConexionSigu.query("INSERT INTO `SIGU`.`SIGU_SesionesFallidas` VALUES (?, ?, NOW(4))"
|
|
782
|
+
, [Identificador, Solicitud.headers.host.trim()]);
|
|
783
|
+
}
|
|
176
784
|
}
|
|
177
|
-
return await Respuesta.json();
|
|
178
785
|
} catch (error) {
|
|
179
|
-
console.
|
|
180
|
-
|
|
181
|
-
|
|
786
|
+
console.log(error);
|
|
787
|
+
return;
|
|
788
|
+
} finally {
|
|
789
|
+
if (ConexionSigu) await ConexionSigu.end();
|
|
182
790
|
}
|
|
791
|
+
return;
|
|
183
792
|
}
|
|
184
793
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
794
|
+
async Verificar2FA(Solicitud) {
|
|
795
|
+
const jwt = require('jsonwebtoken');
|
|
796
|
+
const ConexionSigu = await crearObjetoConexionSIGU();
|
|
797
|
+
const LastUser = await this.generarLastUser(Solicitud);
|
|
798
|
+
try {
|
|
799
|
+
const { Identificacion, Codigo } = Solicitud.body;
|
|
800
|
+
const resultados = await ConexionSigu.query(
|
|
801
|
+
"SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Activo` = TRUE AND `Identificacion` = ?", [Identificacion]);
|
|
802
|
+
|
|
803
|
+
if (!resultados[0].length) {
|
|
804
|
+
return { error: "Usuario no encontrado" };
|
|
805
|
+
}
|
|
806
|
+
const Identificador = resultados[0][0]['Identificador'];
|
|
807
|
+
// Validar código 2FA
|
|
808
|
+
const codigoValido = await ConexionSigu.query(" \
|
|
809
|
+
SELECT COUNT(*) AS Total \
|
|
810
|
+
FROM `SIGU`.`SIGU_CodigosDe2FAParaLosUsuarios` \
|
|
811
|
+
WHERE `Identificador` = ? \
|
|
812
|
+
AND `CodigoDe2FAParaElUsuario` = ?", [Identificador, Codigo]);
|
|
813
|
+
|
|
814
|
+
if (codigoValido[0][0].Total === 0) {
|
|
815
|
+
// Eliminar código usado cuando falle
|
|
816
|
+
await ConexionSigu.query(" \
|
|
817
|
+
DELETE FROM `SIGU`.`SIGU_CodigosDe2FAParaLosUsuarios` \
|
|
818
|
+
WHERE `Identificador` = ? ", [Identificador]);
|
|
819
|
+
return { error: "Código inválido" };
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// Eliminar código usado
|
|
823
|
+
await ConexionSigu.query(" \
|
|
824
|
+
DELETE FROM `SIGU`.`SIGU_CodigosDe2FAParaLosUsuarios` WHERE `Identificador` = ?", [Identificador]);
|
|
825
|
+
|
|
826
|
+
// Obtener IP del usuario
|
|
827
|
+
const ipUsuario = (Solicitud.headers['x-forwarded-for'] || '').split(',').shift() || Solicitud.socket?.remoteAddress || Solicitud.connection?.remoteAddress || '-';
|
|
828
|
+
|
|
829
|
+
// Guardar IP autorizada
|
|
830
|
+
await ConexionSigu.query(" \
|
|
831
|
+
INSERT INTO `SIGU`.`SIGU_DireccionesUsadasPorLosUsuarios` (`DireccionUsadaPorElUsuario`, `Identificador`, `LastUpdate`, `LastUser`) \
|
|
832
|
+
VALUES (?, ?, NOW(4), ?) \
|
|
833
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4), `LastUser` = ?;", [
|
|
834
|
+
ipUsuario,
|
|
835
|
+
Identificador,
|
|
836
|
+
LastUser,
|
|
837
|
+
LastUser
|
|
838
|
+
]);
|
|
839
|
+
|
|
840
|
+
// Generar token
|
|
841
|
+
const Token = await jwt.sign(
|
|
842
|
+
{ Identificador: Identificador, uid: Identificador },
|
|
843
|
+
await this.palabraSecretaParaTokens(),
|
|
844
|
+
{ expiresIn: '2h' }
|
|
845
|
+
);
|
|
846
|
+
|
|
847
|
+
// Registrar sesión
|
|
848
|
+
await ConexionSigu.query("INSERT INTO `SIGU`.`SIGU_Sesiones` VALUES (?, ?, ?, NOW(4), ?) ON DUPLICATE KEY UPDATE `Token` = ?, `LastUser` = ?"
|
|
849
|
+
, [Identificador, Solicitud.headers.host.trim(), Token, LastUser, Token, LastUser]);
|
|
850
|
+
return {
|
|
851
|
+
Token,
|
|
852
|
+
Dominio: ((process.env.ENV || 'local') === 'production' ? '.sigu.utn.ac.cr' : '-')
|
|
853
|
+
};
|
|
854
|
+
} catch (error) {
|
|
855
|
+
console.log(error);
|
|
856
|
+
return { error: "Error verificando 2FA" };
|
|
857
|
+
} finally {
|
|
858
|
+
if (ConexionSigu) await ConexionSigu.end();
|
|
859
|
+
}
|
|
214
860
|
}
|
|
215
861
|
|
|
216
|
-
|
|
217
|
-
|
|
862
|
+
async ListadoDePaisesParaCrearCuenta() {
|
|
863
|
+
const Resultado = await ejecutarConsultaSIGU("SELECT REPLACE(MID(`COLUMN_TYPE`, 6, CHAR_LENGTH(`COLUMN_TYPE`) - 6), \"'\", '') AS `Datos` FROM `information_schema`.`COLUMNS`\
|
|
864
|
+
WHERE `TABLE_SCHEMA` = 'SIGU' AND `TABLE_NAME` = 'SIGU_Personas' AND\
|
|
865
|
+
`COLUMN_NAME` = 'Pais'");
|
|
866
|
+
return Resultado[0]['Datos'].split(',').sort();
|
|
218
867
|
}
|
|
219
868
|
|
|
220
|
-
|
|
221
|
-
|
|
869
|
+
async obtenerDetalleDelModulo() {
|
|
870
|
+
const Modulos = await ejecutarConsultaSIGU("SELECT `a`.`Nombre`, `a`.`Padre`, `a`.`Descripcion`, `a`.`Detalle`,\
|
|
871
|
+
`a`.`Tipo`, IF(`a`.`Icono` <> '', CONCAT('https://storage.sigu.utn.ac.cr/images/cards/', `a`.`Icono`), '') AS `Icono`, `a`.`Color`, `a`.`Correo`,\
|
|
872
|
+
`a`.`Version`, `a`.`FechaDePublicacion`, `a`.`AcuerdoDeNivelDeServicio`, `a`.`DiccionarioDeDatos`, `a`.`Repositorios`,\
|
|
873
|
+
`a`.`EnlaceDelVideo`,`a`.`EnlaceDelManual`\
|
|
874
|
+
, `a`.`Estado`, REGEXP_SUBSTR(SUBSTRING_INDEX(`a`.`Repositorios`, '/', -1), '[^,]*front[^,]*') AS `Frontend`\
|
|
875
|
+
FROM `SIGU`.`SIGU_ModulosV2` `a`\
|
|
876
|
+
WHERE `a`.`Nombre` = ?", [this.NombreCanonicoDelModulo]);
|
|
877
|
+
return Modulos.map((linea) => {
|
|
878
|
+
linea.Enlace = this.generarEnlace(linea.Frontend);
|
|
879
|
+
return linea;
|
|
880
|
+
});
|
|
222
881
|
}
|
|
223
882
|
|
|
224
|
-
|
|
225
|
-
|
|
883
|
+
async registrarVistaDelManual(Token) {
|
|
884
|
+
const { uid } = await this.obtenerDatosDelUsuario(Token);
|
|
885
|
+
await ejecutarConsulta(
|
|
886
|
+
"INSERT INTO `DatosMiscelaneos` (`DatoMiscelaneo`, `Datos`, `LastUser`) VALUES ('VistasDelManual', JSON_OBJECT('Total', 1), ?) ON DUPLICATE KEY UPDATE `Datos` = JSON_SET(`Datos`, '$.Total', CAST(JSON_VALUE(`Datos`, '$.Total') AS UNSIGNED) + 1), `LastUser` = ?",
|
|
887
|
+
[uid, uid]
|
|
888
|
+
);
|
|
226
889
|
}
|
|
227
890
|
|
|
228
|
-
|
|
891
|
+
async obtenerMensajesModulares() {
|
|
892
|
+
return await ejecutarConsultaSIGU("SELECT `MensajeModularId`, `Titulo`, `Texto`, `FechaYHoraDeInicio`, `FechaYHoraDeFinalizacion` FROM `SIGU`.`SIGU_MensajesModulares` WHERE NOW(4) BETWEEN `FechaYHoraDeInicio` AND `FechaYHoraDeFinalizacion` AND `Modulo` = ?"
|
|
893
|
+
, [this.NombreCanonicoDelModulo]);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
async obtenerMensajesInstitucionales() {
|
|
897
|
+
return await ejecutarConsultaSIGU("SELECT `MensajeInstitucionalId`, `Titulo`, `Texto`, `FechaYHoraDeInicio`, `FechaYHoraDeFinalizacion` FROM `SIGU`.`SIGU_MensajesInstitucionales` WHERE NOW(4) BETWEEN `FechaYHoraDeInicio` AND `FechaYHoraDeFinalizacion`");
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
async obtenerConsentimientoInformado(Modulo = undefined) {
|
|
901
|
+
if (Modulo === undefined) {
|
|
902
|
+
Modulo = this.NombreCanonicoDelModulo;
|
|
903
|
+
}
|
|
904
|
+
let Datos = await ejecutarConsultaSIGU("SELECT `ConsentimientoInformadoId`, `Titulo`, `Texto`, `TextoDeAceptacion` FROM `SIGU`.`SIGU_ConsentimientosInformadosV2`\
|
|
905
|
+
WHERE `Estado` = 'Activo' AND `Modulo` = ? AND `Titulo` <> 'Versión del módulo'", [Modulo]);
|
|
906
|
+
if (Datos.length === 0) {
|
|
907
|
+
Datos = await ejecutarConsultaSIGU("SELECT `ConsentimientoInformadoId`, `Titulo`, `Texto`, `TextoDeAceptacion` FROM `SIGU`.`SIGU_ConsentimientosInformadosV2`\
|
|
908
|
+
WHERE `Estado` = 'Activo' AND `Modulo` = ? AND `Titulo` <> 'Versión del módulo'", [this.NombreCanonicoDelModulo]);
|
|
909
|
+
}
|
|
910
|
+
return Datos[0];
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
async creacionDeConsetimientoInformado(Titulo, Texto, TextoDeAceptacion) {
|
|
914
|
+
return await ejecutarConsultaSIGU("UPDATE `SIGU`.`SIGU_ConsentimientosInformadosV2` SET `Estado` = 'Inactivo' WHERE\
|
|
915
|
+
`Modulo` = ? AND `Titulo` <> 'Versión del módulo'; \
|
|
916
|
+
SELECT MAX(`ConsentimientoInformadoId`) + 1 INTO @`NuevoId` FROM `SIGU`.`SIGU_ConsentimientosInformadosV2`; \
|
|
917
|
+
INSERT INTO `SIGU`.`SIGU_ConsentimientosInformadosV2` VALUES\
|
|
918
|
+
(@`NuevoId`, ?, ?, ?, 'Activo', ?, NOW(), USER())\
|
|
919
|
+
ON DUPLICATE KEY UPDATE `Estado` = 'Activo';"
|
|
920
|
+
, [this.NombreCanonicoDelModulo, Titulo, Texto, TextoDeAceptacion, this.NombreCanonicoDelModulo]);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
obtenerCorreoParaReportes() {
|
|
924
|
+
return this.CorreoParaReportes;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
async iniciarSesion() {
|
|
928
|
+
return this.EnlaceDeAcceso;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
async obtenerModulos(Token, Padre, ModulosFavoritos) {
|
|
932
|
+
let Resultado = undefined;
|
|
933
|
+
try {
|
|
934
|
+
Resultado = await this.obtenerDatosDelUsuario(Token);
|
|
935
|
+
if (!Resultado) {
|
|
936
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
937
|
+
}
|
|
938
|
+
} catch (error) {
|
|
939
|
+
console.log(error);
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
const Permisos = await ejecutarConsultaSIGU("SELECT `PermisoId` FROM `SIGU`.`SIGU_PermisosPersonasV2` WHERE `Identificador` = ?"
|
|
943
|
+
, [Resultado.Identificador]);
|
|
944
|
+
const Modulos = await ejecutarConsultaSIGU("SELECT `a`.`Nombre`, `a`.`Padre`, `a`.`Descripcion`, `a`.`Detalle`,\
|
|
945
|
+
`a`.`Tipo`, IF(`a`.`Icono` <> '', CONCAT('https://storage.sigu.utn.ac.cr/images/cards/', `a`.`Icono`), '') AS `Icono`, `a`.`Color`, `a`.`Correo`,\
|
|
946
|
+
`a`.`Version`, `a`.`FechaDePublicacion`, `a`.`AcuerdoDeNivelDeServicio`, `a`.`DiccionarioDeDatos`, `a`.`Repositorios`,\
|
|
947
|
+
`a`.`EnlaceDelVideo`,`a`.`EnlaceDelManual`\
|
|
948
|
+
, `a`.`Estado`, REGEXP_SUBSTR(SUBSTRING_INDEX(`a`.`Repositorios`, '/', -1), '[^,]*front[^,]*') AS `Frontend`\
|
|
949
|
+
, `c`.`Etiqueta`, `c`.`ColorDeLaEtiqueta`\
|
|
950
|
+
, (SELECT COUNT(*) FROM `SIGU`.`SIGU_ModulosV2` `h`\
|
|
951
|
+
JOIN `SIGU`.`SIGU_PermisosV2` `hp` ON (`h`.`Nombre` = `hp`.`Modulo`)\
|
|
952
|
+
WHERE `h`.`Estado` = 'Activo' AND `h`.`Padre` = `a`.`Nombre` AND `hp`.`PermisoId` IN (?)) AS `CantidadDeHijos`\
|
|
953
|
+
FROM `SIGU`.`SIGU_ModulosV2` `a`\
|
|
954
|
+
JOIN `SIGU`.`SIGU_PermisosV2` `b` ON (`a`.`Nombre` = `b`.`Modulo`)\
|
|
955
|
+
LEFT JOIN `SIGU`.`SIGU_ModulosV2InformacionExtra` `c` ON (`a`.`Nombre` = `c`.`Modulo`)\
|
|
956
|
+
WHERE `a`.`Estado` = 'Activo' AND `a`.`Padre` = ? AND `b`.`PermisoId` IN (?)\
|
|
957
|
+
ORDER BY FIELD(a.Nombre, " + ModulosFavoritos + ") DESC, a.Nombre", [Permisos.map(p => p.PermisoId), Padre, Permisos.map(p => p.PermisoId)]);
|
|
958
|
+
return Modulos.map((linea) => {
|
|
959
|
+
linea.Enlace = this.generarEnlace(linea.Frontend);
|
|
960
|
+
return linea;
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
async crearNotificacion(IdentificadorDelUsuario, IdentificadorDelDestinatario, Mensaje) {
|
|
965
|
+
return await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_NotificacionesV2` VALUES (?, ?, 'Sin leer', NOW(4), NOW(4), ?)"
|
|
966
|
+
, [IdentificadorDelDestinatario, Mensaje, IdentificadorDelUsuario]);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
async actualizarNotificacion(Token, FechaYHoraDeCreacion) {
|
|
970
|
+
let Resultado = undefined;
|
|
971
|
+
try {
|
|
972
|
+
Resultado = await this.obtenerDatosDelUsuario(Token);
|
|
973
|
+
if (!Resultado) {
|
|
974
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
975
|
+
}
|
|
976
|
+
} catch (error) {
|
|
977
|
+
console.log(error);
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
return await ejecutarConsultaSIGU("UPDATE `SIGU`.`SIGU_NotificacionesV2` SET `Estado` = 'Leída' WHERE `Identificador` = ? AND `FechaYHoraDeCreacion` = ?"
|
|
981
|
+
, [Resultado.Identificador, FechaYHoraDeCreacion]);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
async obtenerNotificaciones(Token) {
|
|
985
|
+
let Resultado = undefined;
|
|
986
|
+
try {
|
|
987
|
+
Resultado = await this.obtenerDatosDelUsuario(Token);
|
|
988
|
+
if (!Resultado) {
|
|
989
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
990
|
+
}
|
|
991
|
+
} catch (error) {
|
|
992
|
+
console.log(error);
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
return await ejecutarConsultaSIGU("SELECT `Notificacion` AS `valor`, CONCAT(`FechaYHoraDeCreacion`) AS `llave`, false AS `tachado` FROM `SIGU`.`SIGU_NotificacionesV2` WHERE `Identificador` = ? AND `Estado` = 'Sin leer' ORDER BY `FechaYHoraDeCreacion` DESC LIMIT 10", [Resultado.Identificador]);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
async reporteDeIncidencia(Solicitud, Datos) {
|
|
999
|
+
const DatosDelArchivo = await this.cargarArchivo(Solicitud, Datos);
|
|
1000
|
+
await envioDeCorreo('msavatar@utn.ac.cr', "Reporte de incidencia",
|
|
1001
|
+
"<p><b>Sistema: </b>" + this.NombreCanonicoDelModulo + "</p><br />"
|
|
1002
|
+
+ "<p><b>Asunto: </b>Reporte de incidencia</p><br />"
|
|
1003
|
+
+ "<p><b>Detalle de la incidencia: </b>" + Datos.detalle + "</p><br />"
|
|
1004
|
+
+ "<p><b>Resultado esperado: </b>" + Datos.resultado + "</p><br />"
|
|
1005
|
+
+ "<p><b>Información de contacto: </b>" + Datos.concato + "</p><br />"
|
|
1006
|
+
+ "<p><b>Información del usuario: </b>" + await this.obtenerDatosDelUsuario(Solicitud.headers.authorization) + "</p><br />"
|
|
1007
|
+
, [DatosDelArchivo.rutaDeArchivo]);
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
async reporteDeSugerencia(Solicitud, Datos) {
|
|
1012
|
+
// const DatosDelArchivo = await this.cargarArchivo(Solicitud, Datos);
|
|
1013
|
+
await envioDeCorreo('msavatar@utn.ac.cr', "Reporte de sugerencia",
|
|
1014
|
+
"<p><b>Sistema: </b>" + this.NombreCanonicoDelModulo + "</p><br />"
|
|
1015
|
+
+ "<p><b>Asunto: </b>Reporte de sugerencia</p><br />"
|
|
1016
|
+
+ "<p><b>Detalle de la sugerencia: </b>" + Datos.detalle + "</p><br />"
|
|
1017
|
+
+ "<p><b>Información del usuario: </b>" + await this.obtenerDatosDelUsuario(Solicitud.headers.authorization) + "</p><br />");
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
async cerrarSesion(Token) {
|
|
1022
|
+
let Resultado = undefined;
|
|
1023
|
+
try {
|
|
1024
|
+
Resultado = await this.obtenerDatosDelUsuario(Token);
|
|
1025
|
+
if (!Resultado) {
|
|
1026
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1027
|
+
}
|
|
1028
|
+
} catch (error) {
|
|
1029
|
+
console.log(error);
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
await ejecutarConsultaSIGU("DELETE FROM `SIGU`.`SIGU_Sesiones` WHERE `Token` = ?", [Token.split(" ")[1]]);
|
|
1033
|
+
return this.EnlaceDeAcceso;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
async permisosDelModuloV2(NombreCanonicoDelModulo) {
|
|
1037
|
+
return await ejecutarConsultaSIGU("\
|
|
1038
|
+
WITH RECURSIVE `Jerarquia` AS (\
|
|
1039
|
+
SELECT\
|
|
1040
|
+
`m`.`Padre`,\
|
|
1041
|
+
`m`.`Nombre` AS `Modulo`,\
|
|
1042
|
+
`p`.`PermisoId`,\
|
|
1043
|
+
`p`.`Nombre` AS `Permiso`\
|
|
1044
|
+
FROM `SIGU`.`SIGU_ModulosV2` `m`\
|
|
1045
|
+
JOIN `SIGU`.`SIGU_PermisosV2` `p` ON `p`.`Modulo` = `m`.`Nombre`\
|
|
1046
|
+
WHERE `m`.`Nombre` = ?\
|
|
1047
|
+
UNION ALL\
|
|
1048
|
+
SELECT \
|
|
1049
|
+
`m`.`Padre`,\
|
|
1050
|
+
`m`.`Nombre` AS `Modulo`,\
|
|
1051
|
+
`p`.`PermisoId`,\
|
|
1052
|
+
`p`.`Nombre` AS `Permiso`\
|
|
1053
|
+
FROM `SIGU`.`SIGU_ModulosV2` `m`\
|
|
1054
|
+
JOIN `SIGU`.`SIGU_PermisosV2` `p` ON `p`.`Modulo` = `m`.`Nombre`\
|
|
1055
|
+
JOIN `Jerarquia` `j` ON `j`.`Padre` = `m`.`Nombre`\
|
|
1056
|
+
)\
|
|
1057
|
+
SELECT DISTINCT * FROM `Jerarquia`"
|
|
1058
|
+
, [NombreCanonicoDelModulo]
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
async modulosV2() {
|
|
1063
|
+
return await ejecutarConsultaSIGU("SELECT `Nombre`, `Padre`, `Descripcion`, `Detalle`, `Tipo`, `Icono`, `Color`, `Correo`, `Version`, `FechaDePublicacion`, `AcuerdoDeNivelDeServicio`, `DiccionarioDeDatos`, `Repositorios`, `EnlaceDelVideo`, `EnlaceDelManual`, `Estado` FROM `SIGU`.`SIGU_ModulosV2`");
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
async permisoIdV2() {
|
|
1067
|
+
const Datos = await ejecutarConsultaSIGU("SELECT `PermisoId` FROM `SIGU`.`SIGU_PermisosV2` WHERE `Nombre` = ? AND `Modulo` = ?", [this.NombreDelPermisoV2, this.NombreCanonicoDelModulo]);
|
|
1068
|
+
return Datos[0]['PermisoId'];
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
async permisoIdDelPadreV2() {
|
|
1072
|
+
const Datos = await ejecutarConsultaSIGU("SELECT `PermisoId` FROM `SIGU`.`SIGU_PermisosV2` WHERE `Modulo` = ?"
|
|
1073
|
+
, [this.MenuPadre]);
|
|
1074
|
+
return Datos[0]['PermisoId'];
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
async registroDelModuloEnSIGUV2() {
|
|
1078
|
+
const Version = this.Version + "$$" + this.versionDelNucleo().split(' ')[0];
|
|
1079
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_ModulosV2` VALUES\
|
|
1080
|
+
(?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(4), ?, 'DiccionarioDeDatos'\
|
|
1081
|
+
, ?, '-', '-', 'Activo', NOW(4), USER()) ON DUPLICATE KEY UPDATE `Version` = ?, `Repositorios` = ?"
|
|
1082
|
+
, [this.NombreCanonicoDelModulo, 'DGTI', this.DescripcionDelModulo, this.DetalleDelModulo
|
|
1083
|
+
, this.TipoDeCard, this.IconoDelModulo, '#FFFFFF', this.CorreoParaReportes, Version, this.versionDelNucleo().split(' ')[0], this.Repositorios
|
|
1084
|
+
, Version, this.Repositorios]);
|
|
1085
|
+
await ejecutarConsultaSIGU("SELECT IFNULL(MAX(`PermisoId`), 0) + 1 INTO @`SiguientePermisoId` FROM `SIGU`.`SIGU_PermisosV2`;\
|
|
1086
|
+
INSERT INTO `SIGU`.`SIGU_PermisosV2` VALUES\
|
|
1087
|
+
(@`SiguientePermisoId`, ?, ?, ?, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUser` = USER(), `Nombre` = ?, `Descripcion` = ?;"
|
|
1088
|
+
, [this.NombreDelPermisoV2, this.NombreCanonicoDelModulo, this.DescripcionDelPermiso, this.NombreDelPermisoV2, this.DescripcionDelPermiso]);
|
|
1089
|
+
|
|
1090
|
+
// Creación de Flujo de aprobaciones predeterminado del módulo
|
|
1091
|
+
await ejecutarConsultaSIGU("SELECT COALESCE(MAX(`FlujoDeAprobacionId`), 0) + 1 INTO @`Consecutivo` FROM `SIGU`.`SIGU_FlujosDeAprobacion`;\
|
|
1092
|
+
INSERT INTO `SIGU`.`SIGU_FlujosDeAprobacion` VALUES (@`Consecutivo`, ?, CONCAT('Flujo de aprobación predeterminado para:', ' ', ?), TRUE, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4);"
|
|
1093
|
+
, [this.NombreCanonicoDelModulo, this.NombreCanonicoDelModulo]);
|
|
1094
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_FlujosDeAprobacionPasos` VALUES (\
|
|
1095
|
+
(SELECT `FlujoDeAprobacionId` FROM `SIGU`.`SIGU_FlujosDeAprobacion` WHERE `NombreCanonico` = ?)\
|
|
1096
|
+
, 0, 'Sin aprobaciones realizadas', (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = '111050570'), 0, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1097
|
+
, [this.NombreCanonicoDelModulo]);
|
|
1098
|
+
|
|
1099
|
+
// Asignación del permiso a dvillalobos
|
|
1100
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_PermisosPersonasV2` VALUES (?,\
|
|
1101
|
+
(SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = '111050570'), NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUser` = USER()"
|
|
1102
|
+
, [await this.permisoIdV2()]);
|
|
1103
|
+
|
|
1104
|
+
// Asginación inicial de permisos
|
|
1105
|
+
if (this.UsuariosConAccesoInicial.length > 0) {
|
|
1106
|
+
const permisoId = await this.permisoIdV2();
|
|
1107
|
+
const permisoIdDelPadre = await this.permisoIdDelPadreV2();
|
|
1108
|
+
this.UsuariosConAccesoInicial.forEach(async (dato) => {
|
|
1109
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_PermisosPersonasV2` VALUES (?,\
|
|
1110
|
+
(SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = ?), NOW(4), USER())\
|
|
1111
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1112
|
+
, [permisoIdDelPadre, dato]);
|
|
1113
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_PermisosPersonasV2` VALUES (?,\
|
|
1114
|
+
(SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = ?), NOW(4), USER())\
|
|
1115
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1116
|
+
, [permisoId, dato]);
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// Validación de que sólo el front especificado pueda consumir este backend
|
|
1121
|
+
const uuidTemporal = await ejecutarConsultaSIGU("SELECT UUID() AS `UUID`");
|
|
1122
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Repositorios` VALUES (?, ?) ON DUPLICATE KEY UPDATE `Identificador` = ?"
|
|
1123
|
+
, [this.NombreDelRepositorioDelFrontend, uuidTemporal[0]['UUID'], uuidTemporal[0]['UUID']]);
|
|
1124
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_RepositoriosAccesos` VALUES (?, ?)\
|
|
1125
|
+
ON DUPLICATE KEY UPDATE `RepositorioDestino` = ?,`RepositorioOrigen` = ?"
|
|
1126
|
+
, [this.NombreDelRepositorioDelBackend, this.NombreDelRepositorioDelFrontend, this.NombreDelRepositorioDelBackend, this.NombreDelRepositorioDelFrontend]);
|
|
1127
|
+
|
|
1128
|
+
// Impresión de la información de registro
|
|
1129
|
+
console.log(new Date());
|
|
1130
|
+
console.log(`Módulo registrado correctamente en SIGU. Módulo: ${this.NombreCanonicoDelModulo}`);
|
|
1131
|
+
console.log(`Identificador del flujo de aprobación: ${await this.idDelFlujoDeAprobacion()}`);
|
|
1132
|
+
console.log(`Enlace del módulo: ${this.Enlace}`);
|
|
1133
|
+
console.log(`Permisos: ${JSON.stringify(await this.permisosDelModuloV2(this.NombreCanonicoDelModulo))}`);
|
|
1134
|
+
this.creacionDeldirectorioParaElAlmacenamientoDeArchivos();
|
|
1135
|
+
console.log(`Versión del núcleo: ${this.versionDelNucleo()}`);
|
|
1136
|
+
|
|
1137
|
+
// // Creación de variables de entorno
|
|
1138
|
+
// process.env.SERVIDORSMTP = await this.servidorSMTP();
|
|
1139
|
+
// process.env.USUARIOSMTP = await this.usuarioSMTP();
|
|
1140
|
+
// process.env.PUERTOSMTP = await this.puertoSMTP();
|
|
1141
|
+
// process.env.CLAVESMTP = await this.claveSMTP();
|
|
1142
|
+
// process.env.DESTINATARIODEINFORMESDEERROR = await this.destinatarioDeInformesDeError();
|
|
1143
|
+
// process.env.NOMBRECANONICODELMODULO = this.NombreCanonicoDelModulo;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
generarUUID() {
|
|
1147
|
+
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11)
|
|
1148
|
+
.replace(/[018]/g, c =>
|
|
1149
|
+
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
async obtenerPersonasFuncionarias() {
|
|
1154
|
+
return await ejecutarConsultaSIGU("SELECT `Identificador`, `Identificacion`, `Nombre`, `PrimerApellido`,\
|
|
1155
|
+
`SegundoApellido` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` IN\
|
|
1156
|
+
(SELECT `Identificador` FROM `SIGU`.`EstructuraOrganizacional_Instancias`) ORDER BY `Nombre`, `PrimerApellido`,\
|
|
1157
|
+
`SegundoApellido`");
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// async rolPermisoIdDelMenuPadre() {
|
|
1161
|
+
// const rolPermisoIdDelMenuPadre = await ejecutarConsultaSIGU("SELECT `RolPermisoId` FROM `SIGU`.`SIGU_RolesPermisos` WHERE\
|
|
1162
|
+
// `PermisoId` = (SELECT `PermisoId` FROM `SIGU`.`SIGU_Menu` WHERE `Nombre` = ?)", [this.MenuPadre]);
|
|
1163
|
+
// return rolPermisoIdDelMenuPadre[0]['RolPermisoId'];
|
|
1164
|
+
// }
|
|
1165
|
+
|
|
1166
|
+
async getUUID() {
|
|
1167
|
+
const Identificador = await ejecutarConsultaSIGU("SELECT `Identificador` FROM `SIGU`.`SIGU_Repositorios` WHERE `Repositorio` = ?", [this.NombreDelRepositorioDelBackend]);
|
|
1168
|
+
return Identificador[0]['Identificador'];
|
|
1169
|
+
}
|
|
229
1170
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
1171
|
+
// async perfilGeneralId() {
|
|
1172
|
+
// const PerfilGeneralId = await ejecutarConsultaSIGU("SELECT `PerfilGeneralId` FROM `SIGU`.`SIGU_PerfilesGenerales` WHERE `Perfil` = ?", [this.PerfilGeneral]);
|
|
1173
|
+
// return PerfilGeneralId[0]['PerfilGeneralId'];
|
|
1174
|
+
// }
|
|
1175
|
+
|
|
1176
|
+
// async rolIdDelModulo() {
|
|
1177
|
+
// const RolId = await ejecutarConsultaSIGU("SELECT `RolId` FROM `SIGU`.`SIGU_Roles` WHERE `Descripcion` = ?", [this.NombreDelRol]);
|
|
1178
|
+
// return RolId[0]['RolId'];
|
|
1179
|
+
// }
|
|
1180
|
+
|
|
1181
|
+
// async permisoIdDelModulo() {
|
|
1182
|
+
// const PermisoId = await ejecutarConsultaSIGU("SELECT `PermisoId` FROM `SIGU`.`SIGU_Permisos` WHERE `Nombre` = ?", [this.NombreDelPermiso]);
|
|
1183
|
+
// return PermisoId[0]['PermisoId'];
|
|
1184
|
+
// }
|
|
1185
|
+
|
|
1186
|
+
// async rolPermisoIdDelModulo() {
|
|
1187
|
+
// this.RolId = await this.rolIdDelModulo();
|
|
1188
|
+
// this.PermisoId = await this.permisoIdDelModulo();
|
|
1189
|
+
// const RolPermisoId = await ejecutarConsultaSIGU("SELECT `RolPermisoId` FROM `SIGU`.`SIGU_RolesPermisos` WHERE `RolId` = ? AND `PermisoId` = ?"
|
|
1190
|
+
// , [this.RolId, this.PermisoId]);
|
|
1191
|
+
// return RolPermisoId[0]['RolPermisoId'];
|
|
1192
|
+
// }
|
|
1193
|
+
|
|
1194
|
+
// async idDelMenuPadre() {
|
|
1195
|
+
// const IdDelMenuPadre = await ejecutarConsultaSIGU("SELECT `MenuId` FROM `SIGU`.`SIGU_Menu` WHERE `Nombre` = ?", [this.MenuPadre]);
|
|
1196
|
+
// return IdDelMenuPadre[0]['MenuId'];
|
|
1197
|
+
// }
|
|
1198
|
+
|
|
1199
|
+
// async idDelMenuDelModulo() {
|
|
1200
|
+
// const IdDelMenuDelModulo = await ejecutarConsultaSIGU("SELECT `MenuId` FROM `SIGU`.`SIGU_Menu` WHERE `Nombre` = ?", [this.NombreCanonicoDelModulo]);
|
|
1201
|
+
// return IdDelMenuDelModulo[0]['MenuId'];
|
|
1202
|
+
// }
|
|
1203
|
+
|
|
1204
|
+
generarEnlace(Modulo) {
|
|
1205
|
+
return ((process.env.ENV || 'local') === 'production' ? 'https' : 'http')
|
|
1206
|
+
+ '://' + Modulo
|
|
1207
|
+
+ ((process.env.ENV || 'local') === 'production' ? '' : '-' + (process.env.ENV || 'local'))
|
|
1208
|
+
+ ((process.env.ENV || 'local') === 'production' ? '.sigu.utn.ac.cr' : '-');
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
async registroDelModuloEnSIGU() {
|
|
1212
|
+
|
|
1213
|
+
// Creación del enlace
|
|
1214
|
+
this.Enlace = this.generarEnlace(this.NombreDelRepositorioDelFrontend);
|
|
1215
|
+
|
|
1216
|
+
// Creación del enlace a portal
|
|
1217
|
+
this.EnlaceDePortal = this.generarEnlace('portalv2-frontend');
|
|
1218
|
+
|
|
1219
|
+
// Creación del enlace a perfil
|
|
1220
|
+
this.EnlaceDePerfil = this.generarEnlace('perfilv2-frontend');
|
|
1221
|
+
|
|
1222
|
+
// Creación del enlace a acceso
|
|
1223
|
+
this.EnlaceDeAcceso = this.generarEnlace('accesov2-frontend');
|
|
1224
|
+
|
|
1225
|
+
// // Creación del Rol
|
|
1226
|
+
// const RolId = await ejecutarConsultaSIGU("SELECT (MAX(`RolId`) + 1) AS `RolId` FROM `SIGU`.`SIGU_Roles` WHERE `RolId` < 1000");
|
|
1227
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Roles` VALUES (?, ?, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)", [RolId[0]['RolId'], this.NombreDelRol]);
|
|
1228
|
+
// this.RolId = await this.rolIdDelModulo();
|
|
1229
|
+
|
|
1230
|
+
// // Creación del Módulo
|
|
1231
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Modulos` VALUES (?, ?, ?, ?, ?, 1, ?, ?\
|
|
1232
|
+
// , (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = '111050570')\
|
|
1233
|
+
// , (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = '111050570')\
|
|
1234
|
+
// , (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = '111050570')\
|
|
1235
|
+
// , ?, '1.0.0', NOW(4), 'ANS', '/', ?, '1', NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1236
|
+
// , [this.NombreDelModulo, this.DescripcionDelModulo, this.NombreCanonicoDelModulo, this.TipoDeCard, this.IconoDelModulo
|
|
1237
|
+
// , this.ColorDelModulo, this.RolId, this.CorreoParaReportes, this.Repositorios]);
|
|
1238
|
+
|
|
1239
|
+
// // Creación del Permiso
|
|
1240
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Permisos` VALUES (NULL, ?, ?, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1241
|
+
// , [this.NombreDelPermiso, this.DescripcionDelPermiso]);
|
|
1242
|
+
// this.PermisoId = await this.permisoIdDelModulo();
|
|
1243
|
+
|
|
1244
|
+
// // Creación del Rol-Permiso
|
|
1245
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_RolesPermisos` VALUES (NULL, ?, ?, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1246
|
+
// , [this.RolId, this.PermisoId]);
|
|
1247
|
+
// this.RolPermisoId = await this.rolPermisoIdDelModulo();
|
|
1248
|
+
|
|
1249
|
+
// // Asignación del permiso a dvillalobos
|
|
1250
|
+
// const perfilGeneralId = await this.perfilGeneralId();
|
|
1251
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_RolesPersonas` VALUES (?, ?,\
|
|
1252
|
+
// (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = '111050570'), NOW(4), USER())\
|
|
1253
|
+
// ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1254
|
+
// , [this.RolPermisoId, perfilGeneralId]);
|
|
1255
|
+
|
|
1256
|
+
// // Creación de los menús
|
|
1257
|
+
// this.IdDelMenuPadre = await this.idDelMenuPadre();
|
|
1258
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Menu` VALUES (NULL, ?, ?, ?, 'Módulo', 'opciones', ?\
|
|
1259
|
+
// , ?, ?, 0, 1, NOW(4), USER()) ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1260
|
+
// , [this.PermisoId, this.NombreCanonicoDelModulo, this.DescripcionDelModulo, this.NombreCanonicoDelModulo, this.Enlace, this.IdDelMenuPadre]);
|
|
1261
|
+
// this.IdDelMenuDelModulo = await this.idDelMenuDelModulo();
|
|
1262
|
+
|
|
1263
|
+
// let IdDelMenuAreas = await ejecutarConsultaSIGU("SELECT `MenuId` FROM `SIGU`.`SIGU_Menu` WHERE `Nombre` = 'Menú principal de áreas'\
|
|
1264
|
+
// AND `Padre` = ?", [this.IdDelMenuDelModulo]);
|
|
1265
|
+
// if (IdDelMenuAreas.length === 0) {
|
|
1266
|
+
// IdDelMenuAreas = await ejecutarConsultaSIGU("SELECT MAX(`MenuId`) + 1 AS `MenuId` FROM `SIGU`.`SIGU_Menu`");
|
|
1267
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Menu` VALUES (?, ?, 'Menú principal de áreas', 'Regreso al menú principal de áreas', 'Opción Menú', 'inicio'\
|
|
1268
|
+
// , NULL, '/modulos', ?, 0, 1, NOW(4), USER())"
|
|
1269
|
+
// , [IdDelMenuAreas[0]['MenuId'], this.PermisoId, this.IdDelMenuDelModulo]);
|
|
1270
|
+
// }
|
|
1271
|
+
|
|
1272
|
+
// let IdDelMenuRegreso1 = await ejecutarConsultaSIGU("SELECT `MenuId` FROM `SIGU`.`SIGU_Menu` WHERE `Nombre` = CONCAT('Regreso a ', ?)\
|
|
1273
|
+
// AND `Padre` = ?", [this.MenuPadre, this.IdDelMenuDelModulo]);
|
|
1274
|
+
// if (IdDelMenuRegreso1.length === 0) {
|
|
1275
|
+
// IdDelMenuRegreso1 = await ejecutarConsultaSIGU("SELECT MAX(`MenuId`) + 1 AS `MenuId` FROM `SIGU`.`SIGU_Menu`");
|
|
1276
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Menu` VALUES (?, ?, CONCAT('Regreso a ', ?), CONCAT('Regreso a ', ?), 'Opción Menú', 'opciones'\
|
|
1277
|
+
// , NULL, CONCAT('/modulos/', ?), ?, 0, 1, NOW(4), USER())"
|
|
1278
|
+
// , [IdDelMenuRegreso1[0]['MenuId'], this.PermisoId, this.MenuPadre, this.MenuPadre, this.IdDelMenuPadre, this.IdDelMenuDelModulo]);
|
|
1279
|
+
// }
|
|
1280
|
+
|
|
1281
|
+
// let IdDelMenuRegreso2 = await ejecutarConsultaSIGU("SELECT `MenuId` FROM `SIGU`.`SIGU_Menu` WHERE `Nombre` = CONCAT('Regreso a ', ?)\
|
|
1282
|
+
// AND `Padre` = ?", [this.NombreCanonicoDelModulo, this.IdDelMenuDelModulo]);
|
|
1283
|
+
// if (IdDelMenuRegreso2.length === 0) {
|
|
1284
|
+
// IdDelMenuRegreso2 = await ejecutarConsultaSIGU("SELECT MAX(`MenuId`) + 1 AS `MenuId` FROM `SIGU`.`SIGU_Menu`");
|
|
1285
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Menu` VALUES (?, ?, CONCAT('Regreso a ', ?), CONCAT('Regreso a ', ?), 'Opción Menú', 'menus'\
|
|
1286
|
+
// , NULL, CONCAT('/enlace/', ?, '/', ?), ?, 0, 1, NOW(4), USER())"
|
|
1287
|
+
// , [IdDelMenuRegreso2[0]['MenuId'], this.PermisoId, this.NombreCanonicoDelModulo, this.NombreCanonicoDelModulo
|
|
1288
|
+
// , this.IdDelMenuDelModulo, Buffer.from(this.Enlace.split('//')[1]).toString('base64'), this.IdDelMenuDelModulo]);
|
|
1289
|
+
// }
|
|
1290
|
+
|
|
1291
|
+
// Creación del UUID del módulo
|
|
1292
|
+
const uuidTemporal = await ejecutarConsultaSIGU("SELECT UUID() AS `UUID`");
|
|
1293
|
+
this.UUID = uuidTemporal[0]['UUID'];
|
|
1294
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Repositorios` VALUES (?, ?) ON DUPLICATE KEY UPDATE `Identificador` = ?"
|
|
1295
|
+
, [this.NombreDelRepositorioDelBackend, this.UUID, this.UUID]);
|
|
1296
|
+
process.env.UUID = this.UUID;
|
|
1297
|
+
if (this.BackEndsQueConsumeEsteModulo.length > 0) {
|
|
1298
|
+
this.BackEndsQueConsumeEsteModulo.forEach(async (dato) => {
|
|
1299
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_RepositoriosAccesos` VALUES (?, ?)\
|
|
1300
|
+
ON DUPLICATE KEY UPDATE `RepositorioDestino` = ?,`RepositorioOrigen` = ?"
|
|
1301
|
+
, [dato, this.NombreDelRepositorioDelBackend, dato, this.NombreDelRepositorioDelBackend]);
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
// // Asginación inicial de permisos
|
|
1306
|
+
// if (this.UsuariosConAccesoInicial.length > 0) {
|
|
1307
|
+
// const rolPermisoIdDelPadre = await this.rolPermisoIdDelMenuPadre();
|
|
1308
|
+
// this.UsuariosConAccesoInicial.forEach(async (dato) => {
|
|
1309
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_RolesPersonas` VALUES (?, ?,\
|
|
1310
|
+
// (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = ?), NOW(4), USER())\
|
|
1311
|
+
// ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1312
|
+
// , [this.RolPermisoId, perfilGeneralId, dato]);
|
|
1313
|
+
// await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_RolesPersonas` VALUES (?, ?,\
|
|
1314
|
+
// (SELECT `Identificador` FROM `SIGU`.`SIGU_Personas` WHERE `Identificacion` = ?), NOW(4), USER())\
|
|
1315
|
+
// ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4)"
|
|
1316
|
+
// , [rolPermisoIdDelPadre, perfilGeneralId, dato]);
|
|
1317
|
+
// });
|
|
1318
|
+
// }
|
|
1319
|
+
|
|
1320
|
+
// // Impresión de la información de registro
|
|
1321
|
+
// console.log(new Date());
|
|
1322
|
+
// console.log(`Módulo registrado correctamente en SIGU. Módulo: ${this.NombreCanonicoDelModulo}`);
|
|
1323
|
+
// console.log(`Identificador de rol a utilizar (RolId): ${this.RolId}`);
|
|
1324
|
+
// console.log(`Identificador de permiso a utilizar (PermisoId): ${this.PermisoId}`);
|
|
1325
|
+
// console.log(`Identificador de Rol-Permiso a utilizar (RolPermisoId): ${this.RolPermisoId}`);
|
|
1326
|
+
// console.log(`Identificador del menú padre (MenuId del padre): ${this.IdDelMenuPadre}`);
|
|
1327
|
+
// console.log(`Identificador del menú (MenuId del módulo): ${this.IdDelMenuDelModulo}`);
|
|
1328
|
+
// // console.log(`Identificador del flujo de aprobación: ${await this.idDelFlujoDeAprobacion()}`);
|
|
1329
|
+
// console.log(`Enlace del módulo: ${this.Enlace}`);
|
|
1330
|
+
// this.creacionDeldirectorioParaElAlmacenamientoDeArchivos();
|
|
1331
|
+
// console.log(`Versión del núcleo: ${this.versionDelNucleo()}`);
|
|
1332
|
+
|
|
1333
|
+
// Creación de variables de entorno
|
|
1334
|
+
process.env.SERVIDORSMTP = await this.servidorSMTP();
|
|
1335
|
+
process.env.USUARIOSMTP = await this.usuarioSMTP();
|
|
1336
|
+
process.env.PUERTOSMTP = await this.puertoSMTP();
|
|
1337
|
+
process.env.CLAVESMTP = await this.claveSMTP();
|
|
1338
|
+
process.env.DESTINATARIODEINFORMESDEERROR = await this.destinatarioDeInformesDeError();
|
|
1339
|
+
process.env.NOMBRECANONICODELMODULO = this.NombreCanonicoDelModulo;
|
|
1340
|
+
|
|
1341
|
+
await InformacionDelModulo.cargarDesdeBD();
|
|
1342
|
+
this.DescripcionDelModulo = InformacionDelModulo.getDescripcionDelModulo();
|
|
1343
|
+
this.DetalleDelModulo = InformacionDelModulo.getDetalleDelModulo();
|
|
1344
|
+
this.TipoDeCard = InformacionDelModulo.getTipoDeCard();
|
|
1345
|
+
this.NombreDelPermisoV2 = InformacionDelModulo.getNombreDelPermiso();
|
|
1346
|
+
this.DescripcionDelPermiso = InformacionDelModulo.getDescripcionDelPermiso();
|
|
1347
|
+
this.MenuPadre = InformacionDelModulo.getMenuPadre();
|
|
1348
|
+
this.CorreoParaReportes = InformacionDelModulo.getCorreoParaReportes();
|
|
1349
|
+
this.Version = InformacionDelModulo.getVersion();
|
|
1350
|
+
|
|
1351
|
+
await this.registroDelModuloEnSIGUV2();
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
enlaceDelFrontend() {
|
|
1355
|
+
return this.Enlace;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
async idDelFlujoDeAprobacion() {
|
|
1359
|
+
const Resultado = await ejecutarConsultaSIGU("SELECT `FlujoDeAprobacionId` FROM `SIGU`.`SIGU_FlujosDeAprobacion` WHERE `NombreCanonico` = ?"
|
|
1360
|
+
, [this.NombreCanonicoDelModulo]);
|
|
1361
|
+
return Resultado[0]['FlujoDeAprobacionId'];
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
fechaConFormato() {
|
|
1365
|
+
const ahora = new Date(Date.now());
|
|
1366
|
+
const anio = ahora.getFullYear();
|
|
1367
|
+
const mes = String(ahora.getMonth() + 1).padStart(2, '0');
|
|
1368
|
+
const dia = String(ahora.getDate()).padStart(2, '0');
|
|
1369
|
+
const hora = String(ahora.getHours()).padStart(2, '0');
|
|
1370
|
+
const minutos = String(ahora.getMinutes()).padStart(2, '0');
|
|
1371
|
+
const segundos = String(ahora.getSeconds()).padStart(2, '0');
|
|
1372
|
+
return `${anio}${mes}${dia}${hora}${minutos}${segundos}`;
|
|
1373
|
+
}
|
|
1374
|
+
creacionDeldirectorioParaElAlmacenamientoDeArchivos() {
|
|
1375
|
+
const fs = require('fs');
|
|
1376
|
+
try {
|
|
1377
|
+
if (!fs.existsSync(this.directorioParaElAlmacenamientoDeArchivos())) {
|
|
1378
|
+
fs.mkdirSync(this.directorioParaElAlmacenamientoDeArchivos(), { recursive: true });
|
|
1379
|
+
console.log(`El directorio '${this.directorioParaElAlmacenamientoDeArchivos()}' ha sido creado.`);
|
|
1380
|
+
} else {
|
|
1381
|
+
console.log(`El directorio '${this.directorioParaElAlmacenamientoDeArchivos()}' ya existe.`);
|
|
1382
|
+
}
|
|
1383
|
+
} catch (error) {
|
|
1384
|
+
console.error(`Se presentó el siguiente problema al interactuar con el sistema de archivos: ${error}`);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
directorioParaElAlmacenamientoDeArchivos() {
|
|
1389
|
+
return '/var/storage/public/' + this.NombreCanonicoDelModulo;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
versionDelNucleo() {
|
|
1393
|
+
return "VERSION_DEL_NUCLEO" + " " + this.NombreCanonicoDelModulo;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
async destinatarioDeInformesDeError() {
|
|
1397
|
+
const destinatarioDeInformesDeError = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'DestinatarioDeInformesDeError'");
|
|
1398
|
+
if (destinatarioDeInformesDeError.length > 0) {
|
|
1399
|
+
return destinatarioDeInformesDeError[0]['Valor'];
|
|
1400
|
+
} else {
|
|
1401
|
+
return '';
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
async claveSMTP() {
|
|
1406
|
+
const claveSMTP = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'ClaveSMTP'");
|
|
1407
|
+
if (claveSMTP.length > 0) {
|
|
1408
|
+
return claveSMTP[0]['Valor'];
|
|
1409
|
+
} else {
|
|
1410
|
+
return '';
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
async puertoSMTP() {
|
|
1415
|
+
const puertoSMTP = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'PuertoSMTP'");
|
|
1416
|
+
if (puertoSMTP.length > 0) {
|
|
1417
|
+
return puertoSMTP[0]['Valor'];
|
|
1418
|
+
} else {
|
|
1419
|
+
return '';
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
async usuarioSMTP() {
|
|
1424
|
+
const usuarioSMTP = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'UsuarioSMTP'");
|
|
1425
|
+
if (usuarioSMTP.length > 0) {
|
|
1426
|
+
return usuarioSMTP[0]['Valor'];
|
|
1427
|
+
} else {
|
|
1428
|
+
return '';
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
async servidorSMTP() {
|
|
1433
|
+
const servidorSMTP = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'ServidorSMTP'");
|
|
1434
|
+
if (servidorSMTP.length > 0) {
|
|
1435
|
+
return servidorSMTP[0]['Valor'];
|
|
1436
|
+
} else {
|
|
1437
|
+
return '';
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
almacenarCuentaIBAN(Cuerpo) {
|
|
1442
|
+
return ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_CuentasBancariasPersonas` VALUES (NULL, ?, ?, TRUE, NOW(4), ?)\
|
|
1443
|
+
ON DUPLICATE KEY UPDATE `LastUpdate` = NOW(4), `LastUser` = ?"
|
|
1444
|
+
, [Cuerpo.Identificador, Cuerpo.IBAN, Cuerpo.LastUser, Cuerpo.LastUser]);
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
async obtenerDatosDeLaPersona(Token) {
|
|
1448
|
+
let Resultado = undefined;
|
|
1449
|
+
try {
|
|
1450
|
+
Resultado = await this.obtenerDatosDelUsuario(Token);
|
|
1451
|
+
if (!Resultado) {
|
|
1452
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1453
|
+
}
|
|
1454
|
+
} catch (error) {
|
|
1455
|
+
console.log(error);
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
return await ejecutarConsultaSIGU("SELECT `a`.`Identificador`, `a`.`Identificacion`\
|
|
1459
|
+
, `a`.`Nombre`, `a`.`PrimerApellido`, `a`.`SegundoApellido`\
|
|
1460
|
+
, (SELECT GROUP_CONCAT(`b`.`CuentaIBAN`) FROM `SIGU`.`SIGU_CuentasBancariasPersonas` `b` WHERE `b`.`Estado` = TRUE AND `a`.`Identificador` = `b`.`Identificador`) AS `CuentasIBAN`\
|
|
1461
|
+
FROM `SIGU`.`SIGU_Personas` `a` WHERE `a`.`Identificador` = ?"
|
|
1462
|
+
, [Resultado.Identificador]);
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
async obtenerDatosDeLaPersonaPorIdentificacion(Identificacion) {
|
|
1466
|
+
return await ejecutarConsultaSIGU("SELECT `a`.`Identificador`, `a`.`Identificacion`\
|
|
1467
|
+
, `a`.`Nombre`, `a`.`PrimerApellido`, `a`.`SegundoApellido`\
|
|
1468
|
+
, (SELECT GROUP_CONCAT(`b`.`CuentaIBAN`) FROM `SIGU`.`SIGU_CuentasBancariasPersonas` `b` WHERE `b`.`Estado` = TRUE AND `a`.`Identificador` = `b`.`Identificador`) AS `CuentasIBAN`\
|
|
1469
|
+
FROM `SIGU`.`SIGU_Personas` `a` WHERE `a`.`Identificacion` = ?"
|
|
1470
|
+
, [Identificacion]);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
async obtenerEstudiantes() {
|
|
1474
|
+
return await ejecutarConsultaSIGU("SELECT `Identificador`, `Identificacion`, `Nombre`, `PrimerApellido`,\
|
|
1475
|
+
`SegundoApellido` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` IN\
|
|
1476
|
+
(SELECT `Identificador` FROM `SIGU`.`SIGU_RolesPersonas` WHERE `PerfilGeneralId` = 1 /*El perfil 1 parece ser para Estudiantes*/)");
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
async obtenerBeneficios() {
|
|
1480
|
+
return await ejecutarConsultaSIGU("SELECT `BeneficioId`, `Beneficio`, `Estado` FROM `SIGU`.`SIGU_Beneficios`");
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
async obtenerIdentificacion(Identificador) {
|
|
1484
|
+
return await ejecutarConsultaSIGU("SELECT `Identificacion` FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` = ?", [Identificador]);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
async obtenerPeriodos() {
|
|
1488
|
+
return await ejecutarConsultaSIGU("SELECT `PeriodoId`, `CodigoPeriodo`, `Anio`, `Periodo`, `FechaInicio`, `FechaFinal`, `Tipo`, `Estado` FROM `SIGU`.`SIGU_Periodos` ORDER BY `Anio` DESC, `CodigoPeriodo` DESC");
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
async obtenerAnios() {
|
|
1492
|
+
return await ejecutarConsultaSIGU("SELECT DISTINCT `Anio` FROM `SIGU`.`SIGU_Periodos`");
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
async obtenerSedes() {
|
|
1496
|
+
return await ejecutarConsultaSIGU("SELECT `SedesId`, `CodigoAvatar`, `Descripcion`, `Siglas` FROM `SIGU`.`SIGU_Sedes` ORDER BY `Descripcion`");
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
async obtenerRecintos() {
|
|
1500
|
+
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`");
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
async googleClientId() {
|
|
1504
|
+
const clientId = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'Google-ClientId'");
|
|
1505
|
+
return clientId[0]?.['Valor'] || '';
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
async palabraSecretaParaTokens() {
|
|
1509
|
+
const palabraSecreta = await ejecutarConsultaSIGU("SELECT `Valor` FROM `SIGU`.`SIGU_VariablesDeSistema` WHERE `Nombre` = 'PalabraSecretaParaLaCreacionDeTokens'");
|
|
1510
|
+
return palabraSecreta[0]['Valor'];
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
comparacionDeCadenas(cadena1, cadena2) {
|
|
1514
|
+
const cadenaA = String(cadena1);
|
|
1515
|
+
let cadenaB = String(cadena2);
|
|
1516
|
+
const tamanioDeCadelaA = cadenaA.length;
|
|
1517
|
+
let resultado = 0;
|
|
1518
|
+
|
|
1519
|
+
if (tamanioDeCadelaA !== cadenaB.length) {
|
|
1520
|
+
cadenaB = cadenaA;
|
|
1521
|
+
resultado = 1;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
for (let contador = 0; contador < tamanioDeCadelaA; contador++) {
|
|
1525
|
+
resultado |= (cadenaA.charCodeAt(contador) ^ cadenaB.charCodeAt(contador));
|
|
1526
|
+
}
|
|
1527
|
+
return resultado === 0;
|
|
1528
|
+
};
|
|
1529
|
+
|
|
1530
|
+
async obtenerDatosDelUsuario(encabezadoDeAutorizacion) {
|
|
1531
|
+
const jwt = require('jsonwebtoken');
|
|
1532
|
+
// Obtención del token
|
|
1533
|
+
let token = undefined;
|
|
1534
|
+
try {
|
|
1535
|
+
token = encabezadoDeAutorizacion.split(" ")[1];
|
|
1536
|
+
if (!token) {
|
|
1537
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorEncabezadoDeAutorizacion(), ManejadorDeErrores.obtenerNumeroDeLinea(), encabezadoDeAutorizacion);
|
|
1538
|
+
}
|
|
1539
|
+
} catch (error) {
|
|
1540
|
+
console.error(error);
|
|
1541
|
+
return false;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
// Verificación del token
|
|
1545
|
+
let Resultado = undefined;
|
|
1546
|
+
try {
|
|
1547
|
+
Resultado = await jwt.verify(token, await this.palabraSecretaParaTokens());
|
|
1548
|
+
if (!Resultado) {
|
|
1549
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea(), encabezadoDeAutorizacion);
|
|
1550
|
+
}
|
|
1551
|
+
Resultado.token = token;
|
|
1552
|
+
const DatosDeLaPersona = await ejecutarConsultaSIGU("SELECT `Identificacion`, `Nombre`, `PrimerApellido`,\
|
|
1553
|
+
`SegundoApellido`, CONCAT(`FechaNacimiento`) AS `FechaDeNacimiento`\
|
|
1554
|
+
FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` = ?", [Resultado.Identificador]);
|
|
1555
|
+
Resultado.Identificacion = DatosDeLaPersona[0]['Identificacion'];
|
|
1556
|
+
Resultado.Nombre = DatosDeLaPersona[0]['Nombre'];
|
|
1557
|
+
Resultado.PrimerApellido = DatosDeLaPersona[0]['PrimerApellido'];
|
|
1558
|
+
Resultado.SegundoApellido = DatosDeLaPersona[0]['SegundoApellido'];
|
|
1559
|
+
Resultado.FechaDeNacimiento = DatosDeLaPersona[0]['FechaDeNacimiento'];
|
|
1560
|
+
return Resultado;
|
|
1561
|
+
} catch (error) {
|
|
1562
|
+
console.error(error);
|
|
1563
|
+
return false;
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
async validarTokenV2(encabezadoDeAutorizacion, permisoExtraId = undefined) {
|
|
1568
|
+
let Resultado = undefined;
|
|
1569
|
+
try {
|
|
1570
|
+
Resultado = await this.obtenerDatosDelUsuario(encabezadoDeAutorizacion);
|
|
1571
|
+
} catch (error) {
|
|
1572
|
+
console.error(error);
|
|
1573
|
+
}
|
|
1574
|
+
// Validación del token para el usuario y authorización
|
|
1575
|
+
if (Resultado) {
|
|
1576
|
+
try {
|
|
1577
|
+
// Validación del token en la sesión
|
|
1578
|
+
const tokenAlmacenado = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_Sesiones`\
|
|
1579
|
+
WHERE `Identificador` = ? AND `Token` = ?", [Resultado.Identificador, Resultado.token]);
|
|
1580
|
+
if (tokenAlmacenado[0]['Total'] >= 1) {
|
|
1581
|
+
// Validación de permisos
|
|
1582
|
+
const rolPermisoId = await this.permisoIdV2();
|
|
1583
|
+
const permisos = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_PermisosPersonasV2`\
|
|
1584
|
+
WHERE `PermisoId` = ? AND `Identificador` = ?", [rolPermisoId, Resultado.Identificador]);
|
|
1585
|
+
if (permisos[0]['Total'] === 1) {
|
|
1586
|
+
if (permisoExtraId) {
|
|
1587
|
+
const ValidacionPermisoExtra = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_PermisosExtraPersonasV2`\
|
|
1588
|
+
WHERE `PermisoExtraId` = ? AND `Identificador` = ?", [permisoExtraId, Resultado.Identificador]);
|
|
1589
|
+
if (ValidacionPermisoExtra[0]['Total'] === 1) {
|
|
1590
|
+
return true;
|
|
1591
|
+
}
|
|
1592
|
+
} else {
|
|
1593
|
+
return true;
|
|
1594
|
+
}
|
|
1595
|
+
} else {
|
|
1596
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorPermisosInsuficientes(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1597
|
+
}
|
|
1598
|
+
} else {
|
|
1599
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorTokenInvalido(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1600
|
+
}
|
|
1601
|
+
} catch (error) {
|
|
1602
|
+
console.error(error);
|
|
1603
|
+
return false;
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
return false;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
async validarToken(encabezadoDeAutorizacion) {
|
|
1610
|
+
return await this.validarTokenV2(encabezadoDeAutorizacion);
|
|
1611
|
+
// const Resultado = undefined;
|
|
1612
|
+
// try {
|
|
1613
|
+
// Resultado = await this.obtenerDatosDelUsuario(encabezadoDeAutorizacion);
|
|
1614
|
+
// } catch (error) {
|
|
1615
|
+
// console.error(error);
|
|
1616
|
+
// }
|
|
1617
|
+
// // Validación del token para el usuario y authorización
|
|
1618
|
+
// if (Resultado) {
|
|
1619
|
+
// try {
|
|
1620
|
+
// // Validación del token en la sesión
|
|
1621
|
+
// const tokenAlmacenado = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_Sesiones`\
|
|
1622
|
+
// WHERE `Identificador` = ? AND `Token` = ?", [Resultado.Identificador, Resultado.token]);
|
|
1623
|
+
// if (tokenAlmacenado[0]['Total'] >= 1) { // Se compara con >= para preveer multisesiones
|
|
1624
|
+
// // Validación de permisos
|
|
1625
|
+
// const perfilGeneralId = await this.perfilGeneralId();
|
|
1626
|
+
// const rolPermisoId = await this.rolPermisoIdDelModulo();
|
|
1627
|
+
// const permisos = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_RolesPersonas`\
|
|
1628
|
+
// WHERE `RolPermisoId` = ? AND `Identificador` = ? AND `PerfilGeneralId` = ?", [rolPermisoId, Resultado.Identificador, perfilGeneralId]);
|
|
1629
|
+
// if (permisos[0]['Total'] === 1) {
|
|
1630
|
+
// return true;
|
|
1631
|
+
// } else {
|
|
1632
|
+
// throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorPermisosInsuficientes(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1633
|
+
// }
|
|
1634
|
+
// } else {
|
|
1635
|
+
// throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorTokenInvalido(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1636
|
+
// }
|
|
1637
|
+
// } catch (error) {
|
|
1638
|
+
// console.error(error);
|
|
1639
|
+
// return false;
|
|
1640
|
+
// }
|
|
1641
|
+
// }
|
|
1642
|
+
// return false;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
convertirACSV(ArregloDeJSON) {
|
|
1646
|
+
if (!ArregloDeJSON || ArregloDeJSON.length === 0) return '';
|
|
1647
|
+
const intentarParsearJSON = (valor) => {
|
|
1648
|
+
if (typeof valor === 'object' && valor !== null && !Array.isArray(valor)) return valor;
|
|
1649
|
+
if (typeof valor === 'string' && valor.trim().startsWith('{')) {
|
|
1650
|
+
try {
|
|
1651
|
+
const objeto = JSON.parse(valor);
|
|
1652
|
+
if (typeof objeto === 'object' && objeto !== null && !Array.isArray(objeto)) return objeto;
|
|
1653
|
+
} catch (e) { }
|
|
1654
|
+
}
|
|
1655
|
+
return null;
|
|
1656
|
+
};
|
|
1657
|
+
const columnasOriginales = Object.keys(ArregloDeJSON[0]);
|
|
1658
|
+
const mapaColumnasJSON = {};
|
|
1659
|
+
columnasOriginales.forEach(col => {
|
|
1660
|
+
const todasLasLlaves = new Set();
|
|
1661
|
+
let esJSON = false;
|
|
1662
|
+
ArregloDeJSON.forEach(fila => {
|
|
1663
|
+
const obj = intentarParsearJSON(fila[col]);
|
|
1664
|
+
if (obj) {
|
|
1665
|
+
esJSON = true;
|
|
1666
|
+
Object.keys(obj).forEach(k => todasLasLlaves.add(k));
|
|
1667
|
+
}
|
|
1668
|
+
});
|
|
1669
|
+
if (esJSON) mapaColumnasJSON[col] = Array.from(todasLasLlaves);
|
|
1670
|
+
});
|
|
1671
|
+
|
|
1672
|
+
const encabezadosFinales = [];
|
|
1673
|
+
columnasOriginales.forEach(col => {
|
|
1674
|
+
if (mapaColumnasJSON[col]) {
|
|
1675
|
+
mapaColumnasJSON[col].forEach(llave => encabezadosFinales.push(`${col}_${llave}`));
|
|
1676
|
+
} else {
|
|
1677
|
+
encabezadosFinales.push(col);
|
|
1678
|
+
}
|
|
1679
|
+
});
|
|
1680
|
+
|
|
1681
|
+
const filasCSV = ArregloDeJSON.map(fila => {
|
|
1682
|
+
const valoresFila = [];
|
|
1683
|
+
columnasOriginales.forEach(col => {
|
|
1684
|
+
if (mapaColumnasJSON[col]) {
|
|
1685
|
+
const obj = intentarParsearJSON(fila[col]) || {};
|
|
1686
|
+
mapaColumnasJSON[col].forEach(llave => {
|
|
1687
|
+
let valor = obj[llave];
|
|
1688
|
+
if (valor === undefined || valor === null || valor === 'null') valor = '';
|
|
1689
|
+
valoresFila.push(JSON.stringify(String(valor)).replace(/,/g, ' '));
|
|
1690
|
+
});
|
|
1691
|
+
} else {
|
|
1692
|
+
let valor = fila[col];
|
|
1693
|
+
if (valor === null || valor === 'null') valor = '';
|
|
1694
|
+
valoresFila.push(JSON.stringify(String(valor)).replace(/,/g, ' '));
|
|
1695
|
+
}
|
|
1696
|
+
});
|
|
1697
|
+
return valoresFila.join(',');
|
|
1698
|
+
});
|
|
1699
|
+
return [encabezadosFinales.join(','), ...filasCSV].join('\n');
|
|
1700
|
+
};
|
|
1701
|
+
|
|
1702
|
+
convertirACSVConDetalle(ArregloDeJSON, ColumnaConDetalle) {
|
|
1703
|
+
if (!ArregloDeJSON || ArregloDeJSON.length === 0) return '';
|
|
1704
|
+
const ejemploConDetalle = ArregloDeJSON.find(e => Array.isArray(e[ColumnaConDetalle]) && e[ColumnaConDetalle].length > 0);
|
|
1705
|
+
const camposDetalle = ejemploConDetalle ? Object.keys(ejemploConDetalle[ColumnaConDetalle][0]) : [];
|
|
1706
|
+
const columnasBase = Object.keys(ArregloDeJSON[0]).filter(key => key !== ColumnaConDetalle);
|
|
1707
|
+
const encabezados = [...columnasBase, ...camposDetalle];
|
|
1708
|
+
const filas = ArregloDeJSON.flatMap(fila => {
|
|
1709
|
+
const detalles = Array.isArray(fila[ColumnaConDetalle]) ? fila[ColumnaConDetalle] : [];
|
|
1710
|
+
if (detalles.length === 0) {
|
|
1711
|
+
return [
|
|
1712
|
+
encabezados.map(col => {
|
|
1713
|
+
const valor = fila[col];
|
|
1714
|
+
return formatearValor(valor);
|
|
1715
|
+
}).join(',')
|
|
1716
|
+
];
|
|
1717
|
+
}
|
|
1718
|
+
return detalles.map(detalle => {
|
|
1719
|
+
return encabezados.map(col => {
|
|
1720
|
+
if (camposDetalle.includes(col)) {
|
|
1721
|
+
return formatearValor(detalle[col]);
|
|
1722
|
+
} else {
|
|
1723
|
+
return formatearValor(fila[col]);
|
|
1724
|
+
}
|
|
1725
|
+
}).join(',');
|
|
1726
|
+
});
|
|
1727
|
+
});
|
|
1728
|
+
return [encabezados.join(','), ...filas].join('\n');
|
|
1729
|
+
function formatearValor(valor) {
|
|
1730
|
+
if (valor === null || valor === 'null' || typeof valor === 'undefined') {
|
|
1731
|
+
return '""';
|
|
1732
|
+
}
|
|
1733
|
+
return `"${String(valor).replace(/"/g, '""')}"`; // Escapa comillas
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
async validarIdentificadorAPI(Encabezados) {
|
|
1738
|
+
// Obtención del UUID del repositorio
|
|
1739
|
+
let Identificador = undefined;
|
|
1740
|
+
try {
|
|
1741
|
+
Identificador = Encabezados.authorization.split(" ")[1];
|
|
1742
|
+
if (!Identificador) {
|
|
1743
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorEncabezadoDeAutorizacion(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1744
|
+
}
|
|
1745
|
+
} catch (error) {
|
|
1746
|
+
console.error(error);
|
|
1747
|
+
return false;
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
// Obtención del Repositorio
|
|
1751
|
+
let Repositorio = undefined;
|
|
1752
|
+
try {
|
|
1753
|
+
Repositorio = Encabezados.referrer;
|
|
1754
|
+
if (!Repositorio) {
|
|
1755
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorRepositorioOrigen(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1756
|
+
}
|
|
1757
|
+
} catch (error) {
|
|
1758
|
+
console.error(error);
|
|
1759
|
+
return false;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
// Comprobar el UUID y el repositorio
|
|
1763
|
+
let ComprobacionDeRepositorio = undefined;
|
|
1764
|
+
try {
|
|
1765
|
+
ComprobacionDeRepositorio = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_Repositorios`\
|
|
1766
|
+
WHERE `Repositorio` = ? AND `Identificador` = ?", [Repositorio, Identificador]);
|
|
1767
|
+
if (ComprobacionDeRepositorio[0]['Total'] === 0) {
|
|
1768
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorRepositorioOrigen(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1769
|
+
} else {
|
|
1770
|
+
// Comprobar si el repositorio origen tiene derecho a consumir el repositorio destino
|
|
1771
|
+
let ComprobacionDeAcceso = undefined;
|
|
1772
|
+
try {
|
|
1773
|
+
ComprobacionDeAcceso = await ejecutarConsultaSIGU("SELECT COUNT(*) AS `Total` FROM `SIGU`.`SIGU_RepositoriosAccesos`\
|
|
1774
|
+
WHERE `RepositorioDestino` = ? AND `RepositorioOrigen` = ?", [this.NombreDelRepositorioDelBackend, Repositorio]);
|
|
1775
|
+
if (ComprobacionDeAcceso[0]['Total'] === 1) {
|
|
1776
|
+
return true;
|
|
1777
|
+
} else {
|
|
1778
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorPermisosInsuficientes(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1779
|
+
}
|
|
1780
|
+
} catch (error) {
|
|
1781
|
+
console.error(error);
|
|
1782
|
+
return false;
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
} catch (error) {
|
|
1786
|
+
console.error(error);
|
|
1787
|
+
return false;
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
async validarUsuarioYContrasenia(Cuerpo) {
|
|
1792
|
+
// Esta función no es para autenticación, se parte del hecho de que la clave y el usario dada son correctos.
|
|
1793
|
+
// Esta función se usa para que APIs de entidades externas debidamente documentadas consuman nuestros servicios.
|
|
1794
|
+
// Si la clave no coincide, el usuario se bloquea.
|
|
1795
|
+
const crypto = require('crypto');
|
|
1796
|
+
const bcrypt = require('bcryptjs');
|
|
1797
|
+
const resultados = await ejecutarConsultaSIGU("SELECT `Clave` FROM `SIGU`.`SIGU_Personas` WHERE `Activo` = TRUE AND `Identificacion` = ?"
|
|
1798
|
+
, [Cuerpo.body.Identificacion]);
|
|
1799
|
+
if (resultados.length != 1) {
|
|
1800
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorAccesoAAPI("El usuario " + Cuerpo.body.Identificacion + " no existe"), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1801
|
+
}
|
|
1802
|
+
const Resultado = await bcrypt.compare(crypto.createHash('md5').update(Cuerpo.body.Clave).digest("hex"), resultados[0]['Clave']);
|
|
1803
|
+
if (!Resultado) {
|
|
1804
|
+
const Mensaje = "Desactivación del usario: " + Cuerpo.body.Identificacion + " por fallo de autenticación.";
|
|
1805
|
+
console.log(Mensaje);
|
|
1806
|
+
const solicitudCompleta = {
|
|
1807
|
+
metodo: Cuerpo.method,
|
|
1808
|
+
url: Cuerpo.originalUrl,
|
|
1809
|
+
ip: Cuerpo.ip,
|
|
1810
|
+
headers: Cuerpo.headers,
|
|
1811
|
+
query: Cuerpo.query,
|
|
1812
|
+
params: Cuerpo.params,
|
|
1813
|
+
body: Cuerpo.body,
|
|
1814
|
+
};
|
|
1815
|
+
const contenidoHTML = `
|
|
1816
|
+
<h2>Solicitud HTTP completa</h2>
|
|
1817
|
+
<p><strong>Método:</strong> ${solicitudCompleta.metodo}</p>
|
|
1818
|
+
<p><strong>URL:</strong> ${solicitudCompleta.url}</p>
|
|
1819
|
+
<p><strong>IP:</strong> ${solicitudCompleta.ip}</p>
|
|
1820
|
+
<h3>Headers:</h3>
|
|
1821
|
+
<pre>${JSON.stringify(solicitudCompleta.headers, null, 2)}</pre>
|
|
1822
|
+
<h3>Query:</h3>
|
|
1823
|
+
<pre>${JSON.stringify(solicitudCompleta.query, null, 2)}</pre>
|
|
1824
|
+
<h3>Params:</h3>
|
|
1825
|
+
<pre>${JSON.stringify(solicitudCompleta.params, null, 2)}</pre>
|
|
1826
|
+
<h3>Body:</h3>
|
|
1827
|
+
<pre>${JSON.stringify(solicitudCompleta.body, null, 2)}</pre>
|
|
1828
|
+
`;
|
|
1829
|
+
envioDeCorreo(process.env.DESTINATARIODEINFORMESDEERROR, Mensaje, contenidoHTML);
|
|
1830
|
+
await ejecutarConsultaSIGU("UPDATE `SIGU`.`SIGU_Personas` SET `Activo` = FALSE WHERE `Identificacion` = ?"
|
|
1831
|
+
, [Cuerpo.body.Identificacion]);
|
|
1832
|
+
}
|
|
1833
|
+
return Resultado;
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
async consumirBackend(URL, Cuerpo = undefined, Tipo = undefined) {
|
|
1837
|
+
const Encabezados = {
|
|
1838
|
+
'Content-Type': 'application/json',
|
|
1839
|
+
'Authorization': 'Bearer ' + await this.getUUID(),
|
|
1840
|
+
'Referrer': this.NombreDelRepositorioDelBackend,
|
|
1841
|
+
'Origin': this.Enlace
|
|
1842
|
+
};
|
|
1843
|
+
let Respuesta = undefined;
|
|
1844
|
+
const Opciones = {
|
|
1845
|
+
method: Cuerpo ? "POST" : "GET",
|
|
1846
|
+
headers: Encabezados,
|
|
1847
|
+
redirect: 'error'
|
|
1848
|
+
};
|
|
1849
|
+
if (Tipo === 'stream') {
|
|
1850
|
+
Opciones.responseType = 'stream';
|
|
1851
|
+
}
|
|
1852
|
+
if (Cuerpo) {
|
|
1853
|
+
Opciones.body = JSON.stringify(Cuerpo);
|
|
1854
|
+
}
|
|
1855
|
+
const ListaDeDominiosPermitidos = [
|
|
1856
|
+
"sigu.utn.ac.cr",
|
|
1857
|
+
"localhost",
|
|
1858
|
+
"svc.cluster.local"
|
|
1859
|
+
];
|
|
1860
|
+
try {
|
|
1861
|
+
if (ListaDeDominiosPermitidos.some(dominio => URL.includes(dominio))) {
|
|
1862
|
+
Respuesta = await fetch(URL, Opciones);
|
|
1863
|
+
}
|
|
1864
|
+
if (!Respuesta.ok) {
|
|
1865
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorAccesoAAPI(Respuesta.error), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1866
|
+
}
|
|
1867
|
+
if (Tipo === 'stream') {
|
|
1868
|
+
return await Respuesta;
|
|
1869
|
+
}
|
|
1870
|
+
return await Respuesta.json();
|
|
1871
|
+
} catch (error) {
|
|
1872
|
+
console.error(error);
|
|
1873
|
+
console.error(Respuesta);
|
|
1874
|
+
throw new ManejadorDeErrores(error.message, ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1877
|
+
|
|
1878
|
+
async almacenarArchivoEnDisco(Solicitud, UId) {
|
|
1879
|
+
const fs = require('fs');
|
|
1880
|
+
const trozos = [];
|
|
1881
|
+
let tamanioTotal = 0;
|
|
1882
|
+
let informacionDelArchivo = {};
|
|
1883
|
+
|
|
1884
|
+
await new Promise((resolve, reject) => {
|
|
1885
|
+
Solicitud.on('data', (trozo) => {
|
|
1886
|
+
trozos.push(trozo);
|
|
1887
|
+
tamanioTotal += trozo.length;
|
|
1888
|
+
});
|
|
1889
|
+
|
|
1890
|
+
Solicitud.on('end', resolve);
|
|
1891
|
+
Solicitud.on('error', reject);
|
|
1892
|
+
});
|
|
1893
|
+
|
|
1894
|
+
try {
|
|
1895
|
+
const buffer = Buffer.concat(trozos);
|
|
1896
|
+
const limite = Solicitud.headers['content-type'].split('; ')[1].split('=')[1];
|
|
1897
|
+
const limiteDelimitador = `--${limite}`;
|
|
1898
|
+
const partes = buffer.toString('latin1').split(limiteDelimitador).filter(Boolean);
|
|
1899
|
+
|
|
1900
|
+
for (const parte of partes) {
|
|
1901
|
+
if (parte.includes('filename=')) {
|
|
1902
|
+
const [headers, ...contentParts] = parte.split('\r\n\r\n');
|
|
1903
|
+
const contenidoBinario = Buffer.from(contentParts.join('\r\n\r\n'), 'latin1');
|
|
1904
|
+
const nombreDeArchivoMatch = headers.match(/filename="([^"]+)"/);
|
|
1905
|
+
const tipoDeContenidoMatch = headers.match(/Content-Type: ([^\r\n]+)/);
|
|
1906
|
+
|
|
1907
|
+
if (nombreDeArchivoMatch) {
|
|
1908
|
+
const nombreDeArchivo = Buffer.from(nombreDeArchivoMatch[1], 'latin1').toString('utf8');
|
|
1909
|
+
const tipoDeContenido = tipoDeContenidoMatch ? tipoDeContenidoMatch[1] : 'application/octet-stream';
|
|
1910
|
+
const rutaDeArchivo = `${this.directorioParaElAlmacenamientoDeArchivos()}/${UId}-${this.fechaConFormato()}-${nombreDeArchivo}`;
|
|
1911
|
+
|
|
1912
|
+
fs.writeFileSync(rutaDeArchivo, contenidoBinario);
|
|
1913
|
+
|
|
1914
|
+
informacionDelArchivo = {
|
|
1915
|
+
nombreDeArchivo,
|
|
1916
|
+
tipoDeContenido,
|
|
1917
|
+
tamanioTotal,
|
|
1918
|
+
rutaDeArchivo,
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
} catch (error) {
|
|
1924
|
+
console.error('Error al guardar el archivo:', error);
|
|
1925
|
+
throw new ManejadorDeErrores(error.message, ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
1926
|
+
}
|
|
1927
|
+
return informacionDelArchivo;
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
async cargarArchivo(Solicitud, Etiquetas) {
|
|
1931
|
+
const Partes = Etiquetas.split('--');
|
|
1932
|
+
Etiquetas = Partes.slice(0, -1).join("--");
|
|
1933
|
+
let Resultado = undefined;
|
|
1934
|
+
try {
|
|
1935
|
+
Resultado = await this.obtenerDatosDelUsuario(Solicitud.headers.authorization);
|
|
1936
|
+
} catch (error) {
|
|
1937
|
+
console.error(error);
|
|
1938
|
+
}
|
|
1939
|
+
// Validación del token para el usuario y authorización
|
|
1940
|
+
if (Resultado) {
|
|
1941
|
+
const informacionDelArchivo = await this.almacenarArchivoEnDisco(Solicitud, Resultado['uid']);
|
|
1942
|
+
const Respuesta = await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Adjuntos` (`AdjuntosId`, `Identificador`, `Modulo`, `Seccion`, `Nombre`,\
|
|
1943
|
+
`NombreOriginal`, `Ruta`, `Tipo`, `Tamanio`, `Etiqueta`, `LastUpdate`, `LastUser`)\
|
|
1944
|
+
VALUES (NULL, ?, ?, 'No aplica', ?, ?, ?, ?, ?, ?, NOW(4), ?)"
|
|
1945
|
+
, [Resultado['uid'], this.NombreCanonicoDelModulo, informacionDelArchivo.nombreDeArchivo, informacionDelArchivo.nombreDeArchivo
|
|
1946
|
+
, informacionDelArchivo.rutaDeArchivo, informacionDelArchivo.tipoDeContenido, informacionDelArchivo.tamanioTotal
|
|
1947
|
+
, Etiquetas, Resultado['uid']]);
|
|
1948
|
+
informacionDelArchivo.insertId = Respuesta.insertId;
|
|
1949
|
+
informacionDelArchivo.Etiquetas = Etiquetas;
|
|
1950
|
+
await ejecutarConsulta("INSERT INTO `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
1951
|
+
VALUES (?, ?, ?, ?, ?, NOW(4), ?)"
|
|
1952
|
+
, [Respuesta.insertId, Resultado.Identificador, informacionDelArchivo.rutaDeArchivo, informacionDelArchivo.nombreDeArchivo
|
|
1953
|
+
, Etiquetas, Resultado.Identificador]);
|
|
1954
|
+
return informacionDelArchivo;
|
|
1955
|
+
}
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
archivoCSVAJSON(rutaArchivo) {
|
|
1960
|
+
const fs = require('fs');
|
|
1961
|
+
const path = require('path');
|
|
1962
|
+
return new Promise((resolve, reject) => {
|
|
1963
|
+
fs.readFile(path.resolve(rutaArchivo), 'utf8', (err, data) => {
|
|
1964
|
+
if (err) {
|
|
1965
|
+
return reject(err);
|
|
1966
|
+
}
|
|
1967
|
+
try {
|
|
1968
|
+
const lineas = data.trim().split('\n'); // Dividir en líneas
|
|
1969
|
+
const encabezados = lineas[0].split(','); // Extraer encabezados de la primera línea
|
|
1970
|
+
const resultados = lineas.slice(1).map((linea) => {
|
|
1971
|
+
const valores = linea.split(','); // Dividir cada línea en valores
|
|
1972
|
+
const objeto = {};
|
|
1973
|
+
encabezados.forEach((encabezado, index) => {
|
|
1974
|
+
objeto[encabezado.trim()] = valores[index]?.trim(); // Crear clave-valor
|
|
1975
|
+
});
|
|
1976
|
+
return objeto;
|
|
1977
|
+
});
|
|
1978
|
+
resolve(resultados);
|
|
1979
|
+
} catch (error) {
|
|
1980
|
+
reject(error);
|
|
1981
|
+
}
|
|
1982
|
+
});
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
jsonATabla(Datos) {
|
|
1987
|
+
if (!Array.isArray(Datos) || Datos.length === 0) {
|
|
1988
|
+
return 'El arreglo está vacío o no es válido.';
|
|
1989
|
+
}
|
|
1990
|
+
const columnas = Object.keys(Datos[0]);
|
|
1991
|
+
const anchos = columnas.map(columna => {
|
|
1992
|
+
return Math.max(
|
|
1993
|
+
columna.length,
|
|
1994
|
+
...Datos.map(row => (row[columna] ? row[columna].toString().length : 0))
|
|
1995
|
+
);
|
|
1996
|
+
});
|
|
1997
|
+
const formatearFila = (fila) => '| ' + fila.map((valor, index) => (valor || '').toString().padEnd(anchos[index])).join(' | ') + ' |';
|
|
1998
|
+
const separador = '+-' + anchos.map(ancho => '-'.repeat(ancho)).join('-+-') + '-+';
|
|
1999
|
+
const encabezado = formatearFila(columnas);
|
|
2000
|
+
const filas = Datos.map(row => formatearFila(columnas.map(col => row[col] || '')));
|
|
2001
|
+
return [separador, encabezado, separador, ...filas, separador].join('\n');
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
// async agregarCodigoQR(doc, url, opciones = {}) {
|
|
2005
|
+
// const { x = 0, y = 0, size = 100 } = opciones;
|
|
2006
|
+
|
|
2007
|
+
|
|
2008
|
+
|
|
2009
|
+
// const urlQR = `https://qrcode.tec-it.com/API/QRCode?data=${encodeURIComponent(url)}&backcolor=%23ffffff&size=small&quietzone=1&errorcorrection=H`;
|
|
2010
|
+
// doc.image(urlQR, x, y, { width: size, height: size });
|
|
2011
|
+
// }
|
|
2012
|
+
|
|
2013
|
+
agregarMarcaDeAgua(doc, texto = 'Borrador', opciones = {}) {
|
|
2014
|
+
const {
|
|
2015
|
+
color = '#CCCCCC',
|
|
2016
|
+
opacity = 0.3,
|
|
2017
|
+
} = opciones;
|
|
2018
|
+
|
|
2019
|
+
const { width, height } = doc.page; // Tamaño de la página
|
|
2020
|
+
|
|
2021
|
+
doc.save(); // Guardar el estado original de la página
|
|
2022
|
+
|
|
2023
|
+
// Calcular la posición y el ángulo de la marca de agua
|
|
2024
|
+
doc
|
|
2025
|
+
.font('Times-Roman', 220)
|
|
2026
|
+
.fillColor(color)
|
|
2027
|
+
.opacity(opacity)
|
|
2028
|
+
.rotate(-55, { origin: [width / 2, height / 2] }) // Rotar el texto en diagonal
|
|
2029
|
+
.text(
|
|
2030
|
+
texto,
|
|
2031
|
+
-width * 0.2, // Ajustar el desplazamiento horizontal
|
|
2032
|
+
height * 0.4, // Ajustar el desplazamiento vertical
|
|
2033
|
+
{
|
|
2034
|
+
align: 'center',
|
|
2035
|
+
valign: 'center',
|
|
2036
|
+
width: width * 1.5, // Asegurar que el texto abarca toda la diagonal
|
|
2037
|
+
}
|
|
2038
|
+
);
|
|
2039
|
+
|
|
2040
|
+
doc.restore(); // Restaurar el estado original de la página
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
async generarObjetoInfoDeUnReportePDF() {
|
|
2044
|
+
|
|
2045
|
+
// Título: UTN-1-1-2024
|
|
2046
|
+
// Autor: Apellido Apellido Nombre + cédula del funcionario
|
|
2047
|
+
// Asunto: Boleta de Vacaciones
|
|
2048
|
+
// Palabras Clave: Hash documento: asfsadffsdafsdfafggef4455
|
|
2049
|
+
|
|
2050
|
+
// Agregarle al doc un QR con el enlace a SIGU y códiigo de verificación
|
|
2051
|
+
|
|
2052
|
+
const UUID = await ejecutarConsulta("SELECT UUID() AS `Dato`");
|
|
2053
|
+
const PalabrasClave = {
|
|
2054
|
+
"Módulo": this.NombreCanonicoDelModulo,
|
|
2055
|
+
"UUID": UUID[0]['Dato']
|
|
2056
|
+
};
|
|
2057
|
+
return {
|
|
2058
|
+
Title: 'Nombre del reporte, como por ejemplo: Boleta de Vacaciones',
|
|
2059
|
+
Author: 'Universidad Técnica Nacional',
|
|
2060
|
+
Subject: 'Reporte PDF',
|
|
2061
|
+
Keywords: JSON.stringify(PalabrasClave),
|
|
2062
|
+
Creator: 'SIGU',
|
|
2063
|
+
Producer: 'SIGU'
|
|
2064
|
+
};
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
agregarTablaElegante(doc, datos, opciones = {}) {
|
|
2068
|
+
const { x = 50, y = 50, columnWidth = 100, rowHeight = 20, headerHeight = 25, fontSize = 10 } = opciones;
|
|
2069
|
+
|
|
2070
|
+
// Configuración de fuentes
|
|
2071
|
+
doc.fontSize(fontSize);
|
|
2072
|
+
|
|
2073
|
+
// Obtener las claves del primer objeto como encabezados
|
|
2074
|
+
const encabezados = Object.keys(datos[0]);
|
|
2075
|
+
|
|
2076
|
+
// Dibujar los encabezados
|
|
2077
|
+
encabezados.forEach((encabezado, i) => {
|
|
2078
|
+
const posX = x + i * columnWidth;
|
|
2079
|
+
doc
|
|
2080
|
+
.rect(posX, y, columnWidth, headerHeight)
|
|
2081
|
+
.fillAndStroke('#d3d3d3', '#000')
|
|
2082
|
+
.fillColor('#000')
|
|
2083
|
+
.text(encabezado, posX + 5, y + 5, { width: columnWidth - 10, align: 'left' });
|
|
2084
|
+
});
|
|
2085
|
+
|
|
2086
|
+
// Dibujar las filas
|
|
2087
|
+
datos.forEach((fila, filaIndex) => {
|
|
2088
|
+
const filaY = y + headerHeight + filaIndex * rowHeight;
|
|
2089
|
+
encabezados.forEach((columna, colIndex) => {
|
|
2090
|
+
const posX = x + colIndex * columnWidth;
|
|
2091
|
+
const texto = fila[columna] !== undefined ? fila[columna].toString() : '';
|
|
2092
|
+
doc
|
|
2093
|
+
.rect(posX, filaY, columnWidth, rowHeight)
|
|
2094
|
+
.stroke()
|
|
2095
|
+
.fillColor('#000')
|
|
2096
|
+
.text(texto, posX + 5, filaY + 5, { width: columnWidth - 10, align: 'left' });
|
|
2097
|
+
});
|
|
2098
|
+
});
|
|
2099
|
+
|
|
2100
|
+
return doc;
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
async reportePDFDeEjemplo(Respuesta) {
|
|
2104
|
+
|
|
2105
|
+
Respuesta.setHeader('Content-Type', 'application/pdf');
|
|
2106
|
+
Respuesta.setHeader('Content-Disposition', 'inline; filename="reporte.pdf"');
|
|
2107
|
+
const PDFDocument = require('pdfkit');
|
|
2108
|
+
|
|
2109
|
+
const opciones = {
|
|
2110
|
+
font: 'Courier',
|
|
2111
|
+
size: 'LETTER',
|
|
2112
|
+
info: await this.generarObjetoInfoDeUnReportePDF()
|
|
2113
|
+
};
|
|
2114
|
+
var doc = new PDFDocument(opciones);
|
|
2115
|
+
doc.pipe(Respuesta);
|
|
2116
|
+
|
|
2117
|
+
this.agregarMarcaDeAgua(doc, 'Borrador', {
|
|
2118
|
+
fontSize: 80,
|
|
2119
|
+
opacity: 0.2,
|
|
2120
|
+
color: '#FF0000',
|
|
2121
|
+
});
|
|
2122
|
+
|
|
2123
|
+
doc.fontSize(25).text('Here is some vector graphics...', 100, 80);
|
|
2124
|
+
|
|
2125
|
+
doc.save()
|
|
2126
|
+
.moveTo(100, 150)
|
|
2127
|
+
.lineTo(100, 250)
|
|
2128
|
+
.lineTo(200, 250)
|
|
2129
|
+
.fill('#FF3300');
|
|
2130
|
+
|
|
2131
|
+
doc.circle(280, 200, 50).fill('#6600FF');
|
|
2132
|
+
|
|
2133
|
+
doc.scale(0.6)
|
|
2134
|
+
.translate(470, 130)
|
|
2135
|
+
.path('M 250,75 L 323,301 131,161 369,161 177,301 z')
|
|
2136
|
+
.fill('red', 'even-odd')
|
|
2137
|
+
.restore();
|
|
2138
|
+
|
|
2139
|
+
doc.text('And here is some wrapped text...', 100, 300)
|
|
2140
|
+
.font('Times-Roman', 13)
|
|
2141
|
+
.moveDown()
|
|
2142
|
+
.text("lorem", {
|
|
2143
|
+
width: 412,
|
|
2144
|
+
align: 'justify',
|
|
2145
|
+
indent: 30,
|
|
2146
|
+
columns: 2,
|
|
2147
|
+
height: 300,
|
|
2148
|
+
ellipsis: true
|
|
2149
|
+
});
|
|
2150
|
+
|
|
2151
|
+
// Datos de ejemplo
|
|
2152
|
+
const datos = [
|
|
2153
|
+
{ Nombre: 'Juan', Edad: 28, Ciudad: 'San José', LugarDeTrabajo: 'UTN' },
|
|
2154
|
+
{ Nombre: 'Ana', Edad: 34 },
|
|
2155
|
+
{ Nombre: 'Luis', Edad: 25, Ciudad: 'Alajuela' },
|
|
2156
|
+
];
|
|
2157
|
+
this.agregarTablaElegante(doc, datos, { x: 0, y: 400, columnWidth: 150, fontSize: 12 });
|
|
2158
|
+
// await this.agregarCodigoQR(doc, 'https://www.utn.ac.cr', { x: doc.page.width - 150, y: doc.page.height - 150, size: 100 });
|
|
2159
|
+
doc.end();
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
async verificarToken(Token) {
|
|
2163
|
+
let Resultado = undefined;
|
|
2164
|
+
try {
|
|
2165
|
+
Resultado = await this.obtenerDatosDelUsuario(`Bearer ${Token}`);
|
|
2166
|
+
} catch (error) {
|
|
2167
|
+
console.error(error);
|
|
2168
|
+
}
|
|
2169
|
+
return Resultado;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
async crearTareaProgramada(Tarea) {
|
|
2173
|
+
const os = require('node:os');
|
|
2174
|
+
return await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_ModulosTareasProgramadas` VALUES\
|
|
2175
|
+
(?, ?, 'Ejecutada', NOW(4), ?) ON DUPLICATE KEY UPDATE `NombreDelEquipo` = ?"
|
|
2176
|
+
, [this.NombreDelRepositorioDelBackend, Tarea.name, os.hostname(), os.hostname()]);
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
async pseudoEjecutarTareaProgramada(Tarea) {
|
|
2180
|
+
const os = require('node:os');
|
|
2181
|
+
const Resultado = await ejecutarConsultaSIGU("UPDATE `SIGU`.`SIGU_ModulosTareasProgramadas` SET `Estado` = 'Procesando'\
|
|
2182
|
+
, `NombreDelEquipo` = ?, `FechaYHoraDeLaUltimaEjecucion` = NOW(4)\
|
|
2183
|
+
WHERE `Repositorio` = ? AND `TareaProgramada` = ? AND `Estado` IN ('Ejecutada', 'Cancelada', 'Fallida')"
|
|
2184
|
+
, [os.hostname(), this.NombreDelRepositorioDelBackend, Tarea]);
|
|
2185
|
+
return Resultado['affectedRows'];
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
async finalizarTareaProgramada(Tarea) {
|
|
2189
|
+
const os = require('node:os');
|
|
2190
|
+
const Resultado = await ejecutarConsultaSIGU("UPDATE `SIGU`.`SIGU_ModulosTareasProgramadas` SET `Estado` = 'Ejecutada'\
|
|
2191
|
+
, `NombreDelEquipo` = ?, `FechaYHoraDeLaUltimaEjecucion` = NOW(4)\
|
|
2192
|
+
WHERE `Repositorio` = ? AND `TareaProgramada` = ? AND `Estado` IN ('Procesando')"
|
|
2193
|
+
, [os.hostname(), this.NombreDelRepositorioDelBackend, Tarea]);
|
|
2194
|
+
return Resultado['affectedRows'];
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
async ejecutarEnHoraEspecifica(hora, minuto, segundo, callback) {
|
|
2198
|
+
while (true) {
|
|
2199
|
+
try {
|
|
2200
|
+
await this.crearTareaProgramada(callback);
|
|
2201
|
+
break;
|
|
2202
|
+
} catch (error) {
|
|
2203
|
+
console.error('Error al ejecutar crearTareaProgramada:', error);
|
|
2204
|
+
console.log('Reintentando en 5 segundos...');
|
|
2205
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
function programarEjecucion() {
|
|
2210
|
+
const ahora = new Date();
|
|
2211
|
+
const proximaEjecucion = new Date(ahora);
|
|
2212
|
+
proximaEjecucion.setHours(hora, minuto, segundo, 0);
|
|
2213
|
+
let tiempoEspera = proximaEjecucion - ahora;
|
|
2214
|
+
if (tiempoEspera < 0) {
|
|
2215
|
+
proximaEjecucion.setDate(proximaEjecucion.getDate() + 1);
|
|
2216
|
+
tiempoEspera = proximaEjecucion - ahora;
|
|
2217
|
+
}
|
|
2218
|
+
console.log(`Se ha programado a '${callback.name}' para ejecución a las ${proximaEjecucion.toLocaleTimeString()}`);
|
|
2219
|
+
|
|
2220
|
+
setTimeout(() => {
|
|
2221
|
+
callback();
|
|
2222
|
+
programarEjecucion();
|
|
2223
|
+
}, tiempoEspera);
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
programarEjecucion();
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
NombresParalocalhost() {
|
|
2230
|
+
return ["localhost", "::", "127.0.0.1", "::1"];
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
async crearToken(Identificador) {
|
|
2234
|
+
let Token = undefined;
|
|
2235
|
+
if (this.NombresParalocalhost().includes(process.env.HOST) && (typeof process.env.DB_HOST_SIGU === "undefined")) {
|
|
2236
|
+
const jwt = require('jsonwebtoken');
|
|
2237
|
+
Token = await jwt.sign({ uid: Identificador, Identificador }, await this.palabraSecretaParaTokens(), { expiresIn: '10h' });
|
|
2238
|
+
await ejecutarConsultaSIGU("DELETE FROM `SIGU`.`SIGU_Sesiones` WHERE `Identificador` = ?", [Identificador]);
|
|
2239
|
+
await ejecutarConsultaSIGU("INSERT INTO `SIGU`.`SIGU_Sesiones` VALUES (?, 'Backend', ?, NOW(4), USER())", [Identificador, Token]);
|
|
2240
|
+
}
|
|
2241
|
+
const fs = require('fs');
|
|
2242
|
+
const ExpresionRegular = new RegExp(/[A-Za-z0-9_-]{30,}\.[A-Za-z0-9_-]{30,}\.[A-Za-z0-9_-]{30,}/, 'g');
|
|
2243
|
+
// index.rest
|
|
2244
|
+
let ArchivoREST = process.cwd() + '/index.rest';
|
|
2245
|
+
let contenido = fs.readFileSync(ArchivoREST, 'utf-8');
|
|
2246
|
+
let contenidoActualizado = contenido.replace(ExpresionRegular, Token);
|
|
2247
|
+
fs.writeFileSync(ArchivoREST, contenidoActualizado);
|
|
2248
|
+
// Módulo.rest
|
|
2249
|
+
ArchivoREST = process.cwd() + '/' + this.NombreCanonicoDelModulo + '.rest';
|
|
2250
|
+
contenido = fs.readFileSync(ArchivoREST, 'utf-8');
|
|
2251
|
+
contenidoActualizado = contenido.replace(ExpresionRegular, Token);
|
|
2252
|
+
fs.writeFileSync(ArchivoREST, contenidoActualizado);
|
|
2253
|
+
// datos-globales.service.ts
|
|
2254
|
+
try {
|
|
2255
|
+
const CWD = process.cwd();
|
|
2256
|
+
process.chdir('..');
|
|
2257
|
+
ArchivoREST = process.cwd() + '/' + this.NombreDelRepositorioDelFrontend + '/src/app/datos-globales.service.ts';
|
|
2258
|
+
process.chdir(CWD);
|
|
2259
|
+
contenido = fs.readFileSync(ArchivoREST, 'utf-8');
|
|
2260
|
+
contenidoActualizado = contenido.replace(ExpresionRegular, Token);
|
|
2261
|
+
fs.writeFileSync(ArchivoREST, contenidoActualizado);
|
|
2262
|
+
} catch (error) {
|
|
2263
|
+
console.warn("No fue posible actualizar el archivo datos-globales.service.ts del front: ", error);
|
|
2264
|
+
}
|
|
2265
|
+
return Token;
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
async listarArchivos(Datos) {
|
|
2269
|
+
const Partes = Datos.Etiquetas.split('--');
|
|
2270
|
+
const Etiquetas = Partes.slice(0, -1).join("--");
|
|
2271
|
+
const partes = Datos.Etiquetas.split('--');
|
|
2272
|
+
const ultimaParte = partes[partes.length - 1].split('=')[1];
|
|
2273
|
+
if (ultimaParte === 'Usuario') {
|
|
2274
|
+
let Resultado = undefined;
|
|
2275
|
+
try {
|
|
2276
|
+
Resultado = await this.obtenerDatosDelUsuario(Datos.Token);
|
|
2277
|
+
if (!Resultado) {
|
|
2278
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
2279
|
+
}
|
|
2280
|
+
} catch (error) {
|
|
2281
|
+
console.log(error);
|
|
2282
|
+
return;
|
|
2283
|
+
}
|
|
2284
|
+
return await ejecutarConsulta("SELECT `ArchivoId`, `Identificador`, `Ruta`, CONCAT(`Nombre`, ' (', DATE_FORMAT(`LastUpdate`, '%Y-%M-%d %H:%i'), ')') AS `Nombre`, `Etiquetas`\
|
|
2285
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2286
|
+
WHERE `Identificador` = ? AND `Etiquetas` = ?"
|
|
2287
|
+
, [Resultado.Identificador, Etiquetas]);
|
|
2288
|
+
}
|
|
2289
|
+
if (ultimaParte === 'Servicio') {
|
|
2290
|
+
return await ejecutarConsulta("SELECT `ArchivoId`, `Identificador`, `Ruta`, CONCAT(`Nombre`, ' (', DATE_FORMAT(`LastUpdate`, '%Y-%M-%d %H:%i'), ')') AS `Nombre`, `Etiquetas`\
|
|
2291
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2292
|
+
WHERE `Etiquetas` = ?"
|
|
2293
|
+
, [Etiquetas]);
|
|
2294
|
+
}
|
|
2295
|
+
if (ultimaParte === 'Proceso') {
|
|
2296
|
+
return await ejecutarConsulta("SELECT `ArchivoId`, `Identificador`, `Ruta`, CONCAT(`Nombre`, ' (', DATE_FORMAT(`LastUpdate`, '%Y-%M-%d %H:%i'), ')') AS `Nombre`, `Etiquetas`\
|
|
2297
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2298
|
+
WHERE `Etiquetas` = ?"
|
|
2299
|
+
, [Etiquetas]);
|
|
2300
|
+
}
|
|
2301
|
+
if (typeof ultimaParte === "number") {
|
|
2302
|
+
if (this.validarTokenV2(Datos.Token, ultimaParte)) {
|
|
2303
|
+
return await ejecutarConsulta("SELECT `ArchivoId`, `Identificador`, `Ruta`, CONCAT(`Nombre`, ' (', DATE_FORMAT(`LastUpdate`, '%Y-%M-%d %H:%i'), ')') AS `Nombre`, `Etiquetas`\
|
|
2304
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2305
|
+
WHERE `Etiquetas` = ?"
|
|
2306
|
+
, [Etiquetas]);
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
async listarArchivosExterno(Datos) {
|
|
2312
|
+
const Partes = Datos.Etiquetas.split('--');
|
|
2313
|
+
const Etiquetas = Partes.slice(0, -1).join("--");
|
|
2314
|
+
const partes = Datos.Etiquetas.split('--');
|
|
2315
|
+
const ultimaParte = partes[partes.length - 1].split('=')[1];
|
|
2316
|
+
let Resultado = undefined;
|
|
2317
|
+
try {
|
|
2318
|
+
Resultado = await this.obtenerDatosDelUsuario(Datos.Token);
|
|
2319
|
+
if (!Resultado) {
|
|
2320
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
2321
|
+
}
|
|
2322
|
+
} catch (error) {
|
|
2323
|
+
console.log(error);
|
|
2324
|
+
return;
|
|
2325
|
+
}
|
|
2326
|
+
return await ejecutarConsulta("SELECT `ArchivoId`, `Identificador`, `Ruta`, CONCAT(`Nombre`, ' (', DATE_FORMAT(`LastUpdate`, '%Y-%M-%d %H:%i'), ')') AS `Nombre`, `Etiquetas`\
|
|
2327
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2328
|
+
WHERE `Identificador` = ?"
|
|
2329
|
+
, [Etiquetas]);
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
async borrarArchivo(Datos) {
|
|
2333
|
+
let Resultado = undefined;
|
|
2334
|
+
try {
|
|
2335
|
+
Resultado = await this.obtenerDatosDelUsuario(Datos.Token);
|
|
2336
|
+
if (!Resultado) {
|
|
2337
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
2338
|
+
}
|
|
2339
|
+
} catch (error) {
|
|
2340
|
+
console.log(error);
|
|
2341
|
+
return;
|
|
2342
|
+
}
|
|
2343
|
+
const fs = require('fs');
|
|
2344
|
+
const Archivo = await ejecutarConsulta("SELECT `Ruta`\
|
|
2345
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2346
|
+
WHERE `Identificador` = ? AND `ArchivoId` = ?"
|
|
2347
|
+
, [Resultado.Identificador, Datos.ArchivoId]);
|
|
2348
|
+
fs.unlinkSync(Archivo[0]['Ruta']);
|
|
2349
|
+
await ejecutarConsulta("DELETE FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2350
|
+
WHERE `Identificador` = ? AND `ArchivoId` = ?"
|
|
2351
|
+
, [Resultado.Identificador, Datos.ArchivoId]);
|
|
2352
|
+
await ejecutarConsultaSIGU("DELETE FROM `SIGU`.`SIGU_Adjuntos`\
|
|
2353
|
+
WHERE `Identificador` = ? AND `AdjuntosId` = ?"
|
|
2354
|
+
, [Resultado.Identificador, Datos.ArchivoId]);
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
async descargarArchivo(Respuesta, Datos) {
|
|
2359
|
+
let RutaDelArchivo = undefined;
|
|
2360
|
+
const ArchivoId = Datos.ArchivoId.split('--')[0];
|
|
2361
|
+
const partes = Datos.ArchivoId.split('--');
|
|
2362
|
+
const ultimaParte = partes[partes.length - 1].split('=')[1];
|
|
2363
|
+
if (ultimaParte === 'Usuario') {
|
|
2364
|
+
let Resultado = undefined;
|
|
2365
|
+
try {
|
|
2366
|
+
Resultado = await this.obtenerDatosDelUsuario(Datos.Token);
|
|
2367
|
+
if (!Resultado) {
|
|
2368
|
+
throw new ManejadorDeErrores(ManejadorDeErrores.mensajeDeErrorVerificacionDeToken(), ManejadorDeErrores.obtenerNumeroDeLinea());
|
|
2369
|
+
}
|
|
2370
|
+
} catch (error) {
|
|
2371
|
+
console.log(error);
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
RutaDelArchivo = await ejecutarConsulta("SELECT `Ruta`\
|
|
2375
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2376
|
+
WHERE `Identificador` = ? AND `ArchivoId` = ?"
|
|
2377
|
+
, [Resultado.Identificador, ArchivoId]);
|
|
2378
|
+
}
|
|
2379
|
+
if (ultimaParte === 'Servicio') {
|
|
2380
|
+
RutaDelArchivo = await ejecutarConsulta("SELECT `Ruta`\
|
|
2381
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2382
|
+
WHERE `ArchivoId` = ?"
|
|
2383
|
+
, [ArchivoId]);
|
|
2384
|
+
}
|
|
2385
|
+
if (ultimaParte === 'Proceso') {
|
|
2386
|
+
RutaDelArchivo = await ejecutarConsulta("SELECT `Ruta`\
|
|
2387
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2388
|
+
WHERE `ArchivoId` = ?"
|
|
2389
|
+
, [ArchivoId]);
|
|
2390
|
+
}
|
|
2391
|
+
if (typeof ultimaParte === "number") {
|
|
2392
|
+
if (this.validarTokenV2(Datos.Token, ultimaParte)) {
|
|
2393
|
+
RutaDelArchivo = await ejecutarConsulta("SELECT `Ruta`\
|
|
2394
|
+
FROM `" + this.NombreDelRepositorioDeLaBaseDeDatos.slice(0, -3) + "`.`Archivos`\
|
|
2395
|
+
WHERE `ArchivoId` = ?"
|
|
2396
|
+
, [ArchivoId]);
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
Respuesta.download(RutaDelArchivo[0]['Ruta']);
|
|
2400
|
+
return;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
async configurarFrontend(Token = undefined) {
|
|
2404
|
+
let NombreUsuario = '';
|
|
2405
|
+
if (Token) {
|
|
2406
|
+
try {
|
|
2407
|
+
const datosUsuario = await this.obtenerDatosDelUsuario(Token);
|
|
2408
|
+
if (datosUsuario) {
|
|
2409
|
+
NombreUsuario = `${datosUsuario.Nombre || ''} ${datosUsuario.PrimerApellido || ''} ${datosUsuario.SegundoApellido || ''}`.trim();
|
|
2410
|
+
}
|
|
2411
|
+
} catch (e) {
|
|
2412
|
+
console.error('Error obteniendo datos de usuario para frontend:', e);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
return {
|
|
2416
|
+
"Modulo": this.NombreCanonicoDelModulo,
|
|
2417
|
+
"Titulo": this.DescripcionDelModulo,
|
|
2418
|
+
"Version": this.Version + "$$" + this.versionDelNucleo().split(' ')[0],
|
|
2419
|
+
"Descripcion": this.DescripcionDelModulo,
|
|
2420
|
+
"Detalle": this.DetalleDelModulo,
|
|
2421
|
+
"NombreUsuario": NombreUsuario
|
|
2422
|
+
};
|
|
2423
|
+
// if (this.NombresParalocalhost().includes(process.env.HOST) && (typeof process.env.DB_HOST_SIGU === "undefined")) {
|
|
2424
|
+
// try {
|
|
2425
|
+
// const fs = require('fs');
|
|
2426
|
+
// const Archivo;
|
|
2427
|
+
// const CWD = process.cwd();
|
|
2428
|
+
// let contenido;
|
|
2429
|
+
// let contenidoActualizado;
|
|
2430
|
+
// // contenedor-principal.component.html
|
|
2431
|
+
// process.chdir('..');
|
|
2432
|
+
// Archivo = process.cwd() + '/' + this.NombreDelRepositorioDelFrontend + '/src/app/Paginas/contenedor-principal/contenedor-principal.component.html';
|
|
2433
|
+
// contenido = fs.readFileSync(Archivo, 'utf-8');
|
|
2434
|
+
// contenidoActualizado = contenido.replace('DESCRIPCION_DEL_PROYECTO', this.DescripcionDelModulo);
|
|
2435
|
+
// fs.writeFileSync(Archivo, contenidoActualizado);
|
|
2436
|
+
// contenido = fs.readFileSync(Archivo, 'utf-8');
|
|
2437
|
+
// contenidoActualizado = contenido.replace('DETALLE_DEL_PROYECTO', this.DetalleDelModulo);
|
|
2438
|
+
// fs.writeFileSync(Archivo, contenidoActualizado);
|
|
2439
|
+
// process.chdir(CWD);
|
|
2440
|
+
|
|
2441
|
+
// // contenedor-componentes.component.html
|
|
2442
|
+
// process.chdir('..');
|
|
2443
|
+
// Archivo = process.cwd() + '/' + this.NombreDelRepositorioDelFrontend + '/src/app/Paginas/Nucleo/contenedor-componentes/contenedor-componentes.component.html';
|
|
2444
|
+
// contenido = fs.readFileSync(Archivo, 'utf-8');
|
|
2445
|
+
// contenidoActualizado = contenido.replace('NOMBRE_DEL_PROYECTO', this.NombreDelModulo);
|
|
2446
|
+
// fs.writeFileSync(Archivo, contenidoActualizado);
|
|
2447
|
+
// contenido = fs.readFileSync(Archivo, 'utf-8');
|
|
2448
|
+
// contenidoActualizado = contenido.replace('MODULO', this.NombreCanonicoDelModulo);
|
|
2449
|
+
// fs.writeFileSync(Archivo, contenidoActualizado);
|
|
2450
|
+
// contenido = fs.readFileSync(Archivo, 'utf-8');
|
|
2451
|
+
// contenidoActualizado = contenido.replace('VERSION', '1.0.0');
|
|
2452
|
+
// fs.writeFileSync(Archivo, contenidoActualizado);
|
|
2453
|
+
// process.chdir(CWD);
|
|
2454
|
+
|
|
2455
|
+
// } catch (error) {
|
|
2456
|
+
// console.warn("No fue posible actualizar el archivo contenedor-principal.component.html del front: ", error);
|
|
2457
|
+
// }
|
|
2458
|
+
// }
|
|
2459
|
+
// return;
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
async DatosPersonalesDeUnaPersona(Identificador) {
|
|
2463
|
+
const Resultado = {};
|
|
2464
|
+
const DatosDeLaPersona = await ejecutarConsultaSIGU("SELECT `Identificacion`, `Nombre`, `PrimerApellido`,\
|
|
2465
|
+
`SegundoApellido`, (SELECT `CorreoElectronico` FROM `SIGU`.`SIGU_CorreosPersona` WHERE `Identificador` = ? AND `Principal` = TRUE) AS `CorreoElectronicoPrincipal`\
|
|
2466
|
+
FROM `SIGU`.`SIGU_Personas` WHERE `Identificador` = ?", [Identificador, Identificador]);
|
|
2467
|
+
Resultado.Identificador = Identificador;
|
|
2468
|
+
Resultado.Identificacion = DatosDeLaPersona[0]['Identificacion'];
|
|
2469
|
+
Resultado.Nombre = DatosDeLaPersona[0]['Nombre'];
|
|
2470
|
+
Resultado.PrimerApellido = DatosDeLaPersona[0]['PrimerApellido'];
|
|
2471
|
+
Resultado.SegundoApellido = DatosDeLaPersona[0]['SegundoApellido'];
|
|
2472
|
+
Resultado.CorreoElectronicoPrincipal = DatosDeLaPersona[0]['CorreoElectronicoPrincipal'];
|
|
2473
|
+
return Resultado;
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
async ejecucionDiferida(callback) {
|
|
2477
|
+
const stackLines = new Error().stack.split('\n');
|
|
2478
|
+
const lineaCaller = stackLines[2] ?? '';
|
|
2479
|
+
const match = lineaCaller.match(/\((.+?):\d+:\d+\)/) ?? lineaCaller.match(/at (.+?):\d+:\d+/);
|
|
2480
|
+
const archivo = match ? require('path').basename(match[1]) : null;
|
|
2481
|
+
|
|
2482
|
+
while (true) {
|
|
2483
|
+
try {
|
|
2484
|
+
this._archivoFuenteActual = archivo;
|
|
2485
|
+
await callback();
|
|
2486
|
+
break;
|
|
2487
|
+
} catch (error) {
|
|
2488
|
+
console.error(`Error en la función "${callback.name}": `, error.message);
|
|
2489
|
+
console.log('Reintentando en 5 segundos...');
|
|
2490
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
this._archivoFuenteActual = null;
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2496
|
+
// async obtenerEnlaceDelModuloPadre() {
|
|
2497
|
+
// const Ruta = await ejecutarConsultaSIGU("SELECT CONCAT('modulos/', `MenuId`) AS `Ruta` FROM `SIGU`.`SIGU_Menu`\
|
|
2498
|
+
// WHERE `MenuId` = (SELECT `Padre` FROM `SIGU`.`SIGU_Menu` WHERE `Nombre` = ?)"
|
|
2499
|
+
// , [this.NombreCanonicoDelModulo]);
|
|
2500
|
+
// return await this.obtenerEnlaceDePortal() + "/" + Ruta[0]['Ruta'];
|
|
2501
|
+
// }
|
|
2502
|
+
|
|
2503
|
+
async obtenerEnlaceDePortal() {
|
|
2504
|
+
return this.EnlaceDePortal;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
async obtenerEnlaceDePerfil() {
|
|
2508
|
+
return this.EnlaceDePerfil;
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
async obtenerTarjetas() {
|
|
2512
|
+
const resultados = await ejecutarConsultaSIGU(
|
|
2513
|
+
"SELECT `Datos` FROM `SIGU`.`SIGU_ModulosV2Tarjetas` WHERE `Modulo` = ? AND JSON_EXTRACT(`Datos`, '$.Activa') = TRUE",
|
|
2514
|
+
[this.NombreCanonicoDelModulo]
|
|
2515
|
+
);
|
|
2516
|
+
return resultados.map(fila => typeof fila.Datos === 'string' ? JSON.parse(fila.Datos) : fila.Datos);
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
async inicializar(solicitud) {
|
|
2520
|
+
const ConsentimientoInformado = require('./ConsentimientoInformado.js');
|
|
2521
|
+
const LastUser = await this.generarLastUser(solicitud);
|
|
2522
|
+
const [configuracion, detalleDelModulo, notificaciones, mensajesModulares, consentimiento] = await Promise.all([
|
|
2523
|
+
this.configurarFrontend(solicitud.headers.authorization),
|
|
2524
|
+
this.obtenerDetalleDelModulo(),
|
|
2525
|
+
this.obtenerNotificaciones(solicitud.headers.authorization),
|
|
2526
|
+
this.obtenerMensajesModulares(),
|
|
2527
|
+
ConsentimientoInformado.ConsentimientoInformado({ LastUser })
|
|
2528
|
+
]);
|
|
2529
|
+
return {
|
|
2530
|
+
TienePermiso: true,
|
|
2531
|
+
...configuracion,
|
|
2532
|
+
Descripcion: detalleDelModulo[0]?.Descripcion ?? configuracion.Descripcion,
|
|
2533
|
+
Detalle: detalleDelModulo[0]?.Detalle ?? configuracion.Detalle,
|
|
2534
|
+
EnlaceDelManual: detalleDelModulo[0]?.EnlaceDelManual ?? '-',
|
|
2535
|
+
EnlaceDelVideo: detalleDelModulo[0]?.EnlaceDelVideo ?? '-',
|
|
2536
|
+
Notificaciones: notificaciones,
|
|
2537
|
+
MensajesModulares: mensajesModulares,
|
|
2538
|
+
Consentimiento: consentimiento
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
async obtenerTarjetasDelContenedor(token) {
|
|
2543
|
+
const ConfiguracionDeTarjetas = require('./ConfiguracionDeTarjetas.js');
|
|
2544
|
+
const path = require('path');
|
|
2545
|
+
const serviciosDir = path.join(__dirname, '..');
|
|
2546
|
+
|
|
2547
|
+
const usuario = await this.obtenerDatosDelUsuario(token);
|
|
2548
|
+
const [tarjetas, configuracion] = await Promise.all([
|
|
2549
|
+
this.obtenerTarjetas(),
|
|
2550
|
+
ConfiguracionDeTarjetas.obtener({ Identificador: usuario.uid })
|
|
2551
|
+
]);
|
|
2552
|
+
|
|
2553
|
+
const datosDeServicio = await Promise.all(
|
|
2554
|
+
tarjetas
|
|
2555
|
+
.filter(t => t.Archivo)
|
|
2556
|
+
.map(async t => {
|
|
2557
|
+
try {
|
|
2558
|
+
const rutaArchivo = this._buscarArchivoRecursivo(serviciosDir, t.Archivo);
|
|
2559
|
+
if (!rutaArchivo) return null;
|
|
2560
|
+
const servicio = require(rutaArchivo);
|
|
2561
|
+
const [cantidades, tienePermisoExtra] = await Promise.all([
|
|
2562
|
+
typeof servicio.Cantidades === 'function' ? servicio.Cantidades(token) : null,
|
|
2563
|
+
typeof servicio.PermisoExtra === 'function' ? servicio.PermisoExtra(token) : null
|
|
2564
|
+
]);
|
|
2565
|
+
return [t['Título'], { cantidades, tienePermisoExtra }];
|
|
2566
|
+
} catch { return null; }
|
|
2567
|
+
})
|
|
2568
|
+
);
|
|
2569
|
+
|
|
2570
|
+
const datosPorTitulo = Object.fromEntries(datosDeServicio.filter(Boolean));
|
|
2571
|
+
|
|
2572
|
+
const titulosAExcluir = new Set(
|
|
2573
|
+
Object.entries(datosPorTitulo)
|
|
2574
|
+
.filter(([, { cantidades }]) => cantidades && !(cantidades.cantidadMaxima > 0))
|
|
2575
|
+
.map(([titulo]) => titulo)
|
|
2576
|
+
);
|
|
2577
|
+
|
|
2578
|
+
return tarjetas
|
|
2579
|
+
.filter(t => !t.RequierePermisoExtra || datosPorTitulo[t['Título']]?.tienePermisoExtra)
|
|
2580
|
+
.filter(t => !titulosAExcluir.has(t['Título']))
|
|
2581
|
+
.map(t => {
|
|
2582
|
+
const config = configuracion.find(c => c.Titulo === t['Título']);
|
|
2583
|
+
if (config) {
|
|
2584
|
+
t['Posición'] = config.Posicion;
|
|
2585
|
+
if (config.ColorDeBorde) t.ColorDeBorde = config.ColorDeBorde;
|
|
2586
|
+
}
|
|
2587
|
+
const datos = datosPorTitulo[t['Título']];
|
|
2588
|
+
if (datos?.cantidades) {
|
|
2589
|
+
t['Cantidad'] = datos.cantidades.cantidad;
|
|
2590
|
+
t['CantidadMaxima'] = datos.cantidades.cantidadMaxima;
|
|
2591
|
+
}
|
|
2592
|
+
return t;
|
|
2593
|
+
})
|
|
2594
|
+
.sort((a, b) => a['Posición'] - b['Posición']);
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
238
2597
|
|
|
239
2598
|
module.exports = new Miscelaneo();
|