fpavon-ee-shared 1.0.0

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.
Files changed (117) hide show
  1. package/dependency-injection/dependency-injection.ts +56 -0
  2. package/digitalSignature/application/digitalSignature.useCase.ts +171 -0
  3. package/digitalSignature/domain/PDFArrayCustom.ts +60 -0
  4. package/digitalSignature/domain/SignPDF.ts +112 -0
  5. package/digitalSignature/infrastructure/routes/digitalSignature.routes.ts +3 -0
  6. package/digitalSignature/infrastructure/template/marco.pdf +0 -0
  7. package/dist/dependency-injection/dependency-injection.js +46 -0
  8. package/dist/digitalSignature/application/digitalSignature.useCase.js +180 -0
  9. package/dist/digitalSignature/domain/PDFArrayCustom.js +59 -0
  10. package/dist/digitalSignature/domain/SignPDF.js +100 -0
  11. package/dist/digitalSignature/infrastructure/routes/digitalSignature.routes.js +1 -0
  12. package/dist/documentos/application/documentos.useCase.js +49 -0
  13. package/dist/documentos/application/streamConversor.js +14 -0
  14. package/dist/documentos/domain/documento.class.js +60 -0
  15. package/dist/documentos/domain/documento.interface.js +2 -0
  16. package/dist/documentos/domain/documento.repository.js +2 -0
  17. package/dist/documentos/domain/documentoFTP.js +11 -0
  18. package/dist/documentos/domain/value-object/uuid.js +21 -0
  19. package/dist/documentos/infrastructure/repository/documentos.ftp.repository.js +172 -0
  20. package/dist/estados/application/flujos.useCase.js +21 -0
  21. package/dist/estados/domain/estado.class.js +150 -0
  22. package/dist/estados/domain/flujos.repository.js +2 -0
  23. package/dist/estados/infrastructure/controller/flujos.controller.js +34 -0
  24. package/dist/estados/infrastructure/repositories/flujos.sql.repository.js +36 -0
  25. package/dist/estados/infrastructure/routes/flujo.route.js +50 -0
  26. package/dist/expediente-electronico/application/expediente-electronico.useCase.js +171 -0
  27. package/dist/expediente-electronico/domain/expediente-electronico.class.js +190 -0
  28. package/dist/expediente-electronico/domain/expediente-electronico.interface.js +2 -0
  29. package/dist/expediente-electronico/domain/expediente-electronico.repository.js +2 -0
  30. package/dist/expediente-electronico/domain/value-object/limited-string.class.js +19 -0
  31. package/dist/expediente-electronico/domain/value-object/notas.class.js +41 -0
  32. package/dist/expediente-electronico/infrastructure/controller/expediente-electronico.controller.js +306 -0
  33. package/dist/expediente-electronico/infrastructure/repositories/expediente-electronico.sql.repository.js +775 -0
  34. package/dist/expediente-electronico/infrastructure/routes/expediente-electronico.route.js +46 -0
  35. package/dist/infrastructure/bd/connection.sql.js +64 -0
  36. package/dist/infrastructure/bd/pagination.sql.js +15 -0
  37. package/dist/infrastructure/docs/swagger.js +37 -0
  38. package/dist/infrastructure/fileServer/fileServer.basic-ftp.js +220 -0
  39. package/dist/infrastructure/fileServer/fileServer.connection.js +94 -0
  40. package/dist/infrastructure/middlewares/middleware.apikey.js +15 -0
  41. package/dist/infrastructure/middlewares/middleware.auth.js +372 -0
  42. package/dist/infrastructure/middlewares/middleware.deslogueo.js +1 -0
  43. package/dist/infrastructure/middlewares/middleware.validarCampos.js +15 -0
  44. package/dist/infrastructure/middlewares/middleware.validarRol.js +19 -0
  45. package/dist/infrastructure/middlewares/validarNivel.js +37 -0
  46. package/dist/infrastructure/server/httpsServer.class.js +59 -0
  47. package/dist/infrastructure/server/server.class.js +54 -0
  48. package/dist/infrastructure/socket/socketIO.js +23 -0
  49. package/dist/infrastructure/stream-handler/stream-handler.js +137 -0
  50. package/dist/notificaciones/domain/datosNotificacion.class.js +11 -0
  51. package/dist/notificaciones/domain/datosNotificacion.interface.js +2 -0
  52. package/dist/notificaciones/domain/notificacion.class.js +19 -0
  53. package/dist/notificaciones/domain/notificacion.interface.js +2 -0
  54. package/dist/notificaciones/domain/notificacion.repository.js +2 -0
  55. package/dist/notificaciones/infrastructure/notificacion.controller.js +31 -0
  56. package/dist/usuarios/application/usuarios.useCase.js +22 -0
  57. package/dist/usuarios/domain/usuario.class.js +24 -0
  58. package/dist/usuarios/domain/usuario.interface.js +2 -0
  59. package/dist/usuarios/domain/usuarios.repository.js +2 -0
  60. package/dist/usuarios/infrastructure/controller/usuarios.controller.js +28 -0
  61. package/dist/usuarios/infrastructure/repository/usuarios.sql.repository.js +17 -0
  62. package/dist/usuarios/infrastructure/routes/usuarios.routes.js +19 -0
  63. package/documentos/application/documentos.useCase.ts +41 -0
  64. package/documentos/domain/documento.class.ts +101 -0
  65. package/documentos/domain/documento.interface.ts +9 -0
  66. package/documentos/domain/documento.repository.ts +12 -0
  67. package/documentos/domain/documentoFTP.ts +17 -0
  68. package/documentos/domain/value-object/uuid.ts +23 -0
  69. package/documentos/infrastructure/repository/documentos.ftp.repository.ts +169 -0
  70. package/estados/application/flujos.useCase.ts +13 -0
  71. package/estados/domain/estado.class.ts +213 -0
  72. package/estados/domain/flujos.repository.ts +8 -0
  73. package/estados/infrastructure/controller/flujos.controller.ts +21 -0
  74. package/estados/infrastructure/repositories/flujos.sql.repository.ts +29 -0
  75. package/estados/infrastructure/routes/flujo.route.ts +56 -0
  76. package/expediente-electronico/application/expediente-electronico.useCase.ts +154 -0
  77. package/expediente-electronico/domain/expediente-electronico.class.ts +223 -0
  78. package/expediente-electronico/domain/expediente-electronico.interface.ts +19 -0
  79. package/expediente-electronico/domain/expediente-electronico.repository.ts +22 -0
  80. package/expediente-electronico/domain/value-object/limited-string.class.ts +19 -0
  81. package/expediente-electronico/domain/value-object/notas.class.ts +51 -0
  82. package/expediente-electronico/infrastructure/controller/expediente-electronico.controller.ts +308 -0
  83. package/expediente-electronico/infrastructure/repositories/expediente-electronico.sql.repository.ts +799 -0
  84. package/expediente-electronico/infrastructure/routes/expediente-electronico.route.ts +64 -0
  85. package/infrastructure/bd/connection.sql.ts +49 -0
  86. package/infrastructure/bd/pagination.sql.ts +11 -0
  87. package/infrastructure/docs/swagger.ts +38 -0
  88. package/infrastructure/fileServer/fileServer.basic-ftp.ts +196 -0
  89. package/infrastructure/fileServer/fileServer.connection.ts +78 -0
  90. package/infrastructure/middlewares/middleware.apikey.ts +17 -0
  91. package/infrastructure/middlewares/middleware.auth.ts +409 -0
  92. package/infrastructure/middlewares/middleware.deslogueo.ts +0 -0
  93. package/infrastructure/middlewares/middleware.validarCampos.ts +15 -0
  94. package/infrastructure/middlewares/middleware.validarRol.ts +15 -0
  95. package/infrastructure/middlewares/validarNivel.ts +37 -0
  96. package/infrastructure/server/httpsServer.class.ts +69 -0
  97. package/infrastructure/server/server.class.ts +66 -0
  98. package/infrastructure/socket/socketIO.ts +22 -0
  99. package/infrastructure/stream-handler/stream-handler.ts +161 -0
  100. package/jest.config.js +8 -0
  101. package/notificaciones/domain/datosNotificacion.class.ts +13 -0
  102. package/notificaciones/domain/datosNotificacion.interface.ts +5 -0
  103. package/notificaciones/domain/notificacion.class.ts +23 -0
  104. package/notificaciones/domain/notificacion.interface.ts +15 -0
  105. package/notificaciones/domain/notificacion.repository.ts +8 -0
  106. package/notificaciones/infrastructure/notificacion.controller.ts +16 -0
  107. package/package.json +42 -0
  108. package/script.js +135 -0
  109. package/test/expediente-electronico/domain/expediente-electronico.class.test.ts +186 -0
  110. package/tsconfig.json +73 -0
  111. package/usuarios/application/usuarios.useCase.ts +12 -0
  112. package/usuarios/domain/usuario.class.ts +40 -0
  113. package/usuarios/domain/usuario.interface.ts +18 -0
  114. package/usuarios/domain/usuarios.repository.ts +3 -0
  115. package/usuarios/infrastructure/controller/usuarios.controller.ts +19 -0
  116. package/usuarios/infrastructure/repository/usuarios.sql.repository.ts +19 -0
  117. package/usuarios/infrastructure/routes/usuarios.routes.ts +20 -0
@@ -0,0 +1,56 @@
1
+ import { ContainerBuilder } from 'node-dependency-injection';
2
+ import { ExpedienteElectronicoSqlRepository } from '../expediente-electronico/infrastructure/repositories/expediente-electronico.sql.repository';
3
+ import { ExpedienteElectronicoUseCase } from '../expediente-electronico/application/expediente-electronico.useCase';
4
+ import { ExpedienteElectronicoController } from '../expediente-electronico/infrastructure/controller/expediente-electronico.controller';
5
+ import { DocumentosUseCase } from '../documentos/application/documentos.useCase';
6
+ import { NotificacionController } from '../notificaciones/infrastructure/notificacion.controller';
7
+ import { FlujosController } from '../estados/infrastructure/controller/flujos.controller';
8
+ import { FlujosUseCase } from '../estados/application/flujos.useCase';
9
+ import { FlujosRepository } from '../estados/infrastructure/repositories/flujos.sql.repository';
10
+ import { DocumentosFTPRepository } from '../documentos/infrastructure/repository/documentos.ftp.repository';
11
+ import { FtpConnection } from '../infrastructure/fileServer/fileServer.basic-ftp';
12
+
13
+
14
+ let container = new ContainerBuilder();
15
+
16
+ /**
17
+ * Notificaciones
18
+ */
19
+ container.register('EE.Notificaciones.infrastructure.NotificacionesController', NotificacionController);
20
+ const notificacionCtrl = container.get('EE.Notificaciones.infrastructure.NotificacionesController');
21
+
22
+ /**
23
+ * Flujos
24
+ */
25
+ container.register('EE.Flujos.infrastructure.FlujosRepository', FlujosRepository);
26
+ const flujosRepo = container.get('EE.Flujos.infrastructure.FlujosRepository');
27
+ container.register('EE.Flujos.application.FlujosUseCase', FlujosUseCase).addArgument(flujosRepo);
28
+ const flujosUseCase = container.get('EE.Flujos.application.FlujosUseCase');
29
+ container.register('EE.Flujos.infrastructure.FlujosController', FlujosController).addArgument(flujosUseCase);
30
+ const flujosController = container.get('EE.Flujos.infrastructure.FlujosController');
31
+
32
+
33
+ container.register('EE.FTPConnection', FtpConnection);
34
+ const ftp = container.get('EE.FTPConnection');
35
+
36
+ /**
37
+ * Documentos
38
+ */
39
+ container.register('EE.Documentos.infrastructure.DocumentosRepository', DocumentosFTPRepository).addArgument(ftp);
40
+ const docRepo = container.get('EE.Documentos.infrastructure.DocumentosRepository')
41
+ container.register('EE.Documentos.application.DocumentosUseCase', DocumentosUseCase).addArgument(docRepo);
42
+ const docUseCase = container.get('EE.Documentos.application.DocumentosUseCase')
43
+
44
+ /**
45
+ * Expediente Electronico
46
+ */
47
+
48
+ container.register('EE.ExpedienteElectronico.infrastructure.ExpedienteElectronicoSqlRepository', ExpedienteElectronicoSqlRepository);
49
+ const expedienteRepo = container.get('EE.ExpedienteElectronico.infrastructure.ExpedienteElectronicoSqlRepository');
50
+
51
+ container.register('EE.ExpedienteElectronico.application.ExpedienteElectronicoUseCase', ExpedienteElectronicoUseCase).addArgument(expedienteRepo).addArgument(docRepo);
52
+ const expedienteUseCase = container.get('EE.ExpedienteElectronico.application.ExpedienteElectronicoUseCase');
53
+
54
+ container.register('EE.ExpedienteElectronico.infrastructure.ExpedienteElectronicoController', ExpedienteElectronicoController).addArgument(expedienteUseCase).addArgument(notificacionCtrl)
55
+
56
+ export default container;
@@ -0,0 +1,171 @@
1
+ const fs = require('fs');
2
+ import { PDFDocument, rgb, StandardFonts } from 'pdf-lib';
3
+ import * as crypto from 'crypto';
4
+ import moment from 'moment';
5
+ import PDFMerger from 'pdf-merger-js';
6
+ import SignPDF from '../domain/SignPDF';
7
+ import axios from 'axios';
8
+ import path from "node:path";
9
+ import FormData from 'form-data';
10
+
11
+
12
+ export async function obtenerFirmasDocumento(uuid: string): Promise<any[]> {
13
+
14
+ try {
15
+ const response = await axios.get(`${process.env.URL_FIRMAS_SERVICE}/detalle-firmas/${uuid}`);
16
+ return response.data; // Esto sería un array con las firmas y sus datos
17
+ } catch (error: any) {
18
+ if (error.response) {
19
+ console.error("Error obtenerFirmasDocumento: respuesta inválida del servidor");
20
+ if (error.response.data?.message == 'El documento no contiene firmas digitales') {
21
+ // devuelvo array con firmas vacías ya que el documento no tiene firmas
22
+ return [];
23
+ }
24
+ console.error(error.response.data);
25
+ console.error(error.response.status);
26
+ console.error(error.response.headers);
27
+ } else if (error.request) {
28
+ console.error("Error obtenerFirmasDocumento: No se recibió respuesta del servicio");
29
+ console.error(error.request);
30
+ } else {
31
+ console.error("Error obtenerFirmasDocumento: Error al preparar la solicitud", error.message);
32
+ }
33
+ throw new Error(`Error obtenerFirmasDocumento => ${error}`);
34
+ }
35
+ }
36
+
37
+ export async function firmarDocumento(documento: Buffer, firma: any, usuario: any, clave:any): Promise<Buffer> {
38
+
39
+ const bytes = await addSignPage(usuario);
40
+ // Crear un PDF con la firma digital y el documento original
41
+ var merger = new PDFMerger();
42
+ await merger.add(documento);
43
+ await merger.add(await Buffer.from(bytes))
44
+
45
+ const documentoFirmado = await merger.saveAsBuffer();
46
+ // const documentoFirmado = bytes;
47
+
48
+ // return documentoFirmado;
49
+ const pdfBuffer = new SignPDF(
50
+ documentoFirmado,
51
+ path.resolve(firma.path)
52
+ );
53
+
54
+ const signedDocs = await pdfBuffer.signPDF(clave);
55
+ return signedDocs;
56
+ }
57
+
58
+ export async function firmarDocumento2(token:string, uuid:any, firma: any, clave:any, x1:any, y1:any, page:any): Promise<string> {
59
+ let form = new FormData;
60
+ console.log("UUID: ", uuid);
61
+
62
+ form.append('clave', clave);
63
+ form.append('certificado', fs.createReadStream(firma.path));
64
+ form.append('uuid', uuid);
65
+ form.append('x1', x1);
66
+ form.append('y1', y1);
67
+ form.append('page', page);
68
+ const headers = {
69
+ ...form.getHeaders(),
70
+ 'Authorization': `Bearer ${token}`
71
+ };
72
+ try {
73
+
74
+ const response = await axios.post(`${process.env.URL_FIRMAS_SERVICE}/firmar-documento`, form, {headers});
75
+ return response.data.uuid;
76
+ } catch (error:any) {
77
+ if (error.response) {
78
+ console.error("Error firmarDocumento2: La respuesta fue hecha y el servidor respondió con un código de estado que esta fuera del rango de 2xx");
79
+ console.error(error.response.data);
80
+ console.error(error.response.status);
81
+ console.error(error.response.headers);
82
+ } else if (error.request) {
83
+ console.error("Error firmarDocumento2: Es probable que esté caido el servicio de EE-Firmas. La petición fue hecha pero no se recibió respuesta `error.request` es una instancia de XMLHttpRequest en el navegador y una instancia de http.ClientRequest en node.js")
84
+ console.error(error.request);
85
+ } else {
86
+ // Algo paso al preparar la petición que lanzo un Error
87
+ console.error('Error firmarDocumento2: Algo paso al preparar la petición que lanzo un Error', error.message);
88
+ }
89
+ throw new Error(`Error firmarDocumento2=> ${error}`);
90
+ }
91
+ }
92
+ async function addSignPage(usuario:any){
93
+ const response = await axios.get(`http://serverfirmas.ccba.usr.bpba:6050/ListImg/SW3UIDbGetRecInfo.php?IDX_FIR=001%20000${usuario.documento}000%20%20%20%20%20%20&IDX_TYA=TIT&IDX_LOC=ONL&TIP_DOC1=000${usuario.documento}000`, { responseType: 'arraybuffer' });
94
+ const firmaElectronica = response.data;
95
+ // Crear un nuevo documento PDF con pdf-lib
96
+
97
+ const templatePdfBytes = fs.readFileSync('src/ee-shared/digitalSignature/infrastructure/template/marco.pdf');
98
+ const templatePdfDoc = await PDFDocument.load(templatePdfBytes);
99
+ // const pdfDoc = await PDFDocument.load(documento);
100
+
101
+ const timesRomanFont = await templatePdfDoc.embedFont(StandardFonts.TimesRoman)
102
+
103
+ // Add a blank page to the document
104
+ const page = templatePdfDoc.getPage(0);
105
+ // Get the width and height of the page
106
+ const { width, height } = page.getSize()
107
+ // Draw a string of text toward the top of the page
108
+ const fontSize = 12
109
+
110
+ // const page = pdfDoc.addPage([600, 800]);
111
+ let y = (height - 4 * fontSize);
112
+ page.drawText(`Firmado electronicamente por: `, {
113
+ x: 50,
114
+ y,
115
+ size: fontSize,
116
+ font: timesRomanFont,
117
+ color: rgb(0, 0, 0),
118
+ });
119
+ y -= fontSize + 5
120
+ page.drawText(`Afiliado: ${usuario.uid}`, {
121
+ x: 50,
122
+ y,
123
+ size: fontSize,
124
+ font: timesRomanFont,
125
+ color: rgb(0, 0, 0),
126
+ });
127
+ y -= fontSize + 5
128
+ page.drawText(`Nombre completo: ${usuario.nombreCompleto}`, {
129
+ x: 50,
130
+ y,
131
+ size: fontSize,
132
+ font: timesRomanFont,
133
+ color: rgb(0, 0, 0),
134
+ });
135
+ y -= fontSize + 5
136
+ page.drawText(`Cargo: ${usuario.cargo}`, {
137
+ x: 50,
138
+ y,
139
+ size: fontSize,
140
+ font: timesRomanFont,
141
+ color: rgb(0, 0, 0),
142
+ });
143
+ y -= fontSize + 5
144
+ page.drawText(`Fecha: ${moment().locale('es').format('LLLL')}`, {
145
+ x: 50,
146
+ y,
147
+ size: fontSize,
148
+ font: timesRomanFont,
149
+ color: rgb(0, 0, 0),
150
+ });
151
+ y -= fontSize + 5
152
+ page.drawText(`Firma electrónica: `, {
153
+ x: 50,
154
+ y,
155
+ size: fontSize,
156
+ font: timesRomanFont,
157
+ color: rgb(0, 0, 0),
158
+ });
159
+ const signatureImage = await templatePdfDoc.embedPng(firmaElectronica);
160
+ const { width: imgWidth, height: imgHeight } = signatureImage.scale(0.3); // Aquí puedes ajustar el escalamiento
161
+
162
+ y -= imgHeight + 5
163
+ page.drawImage(signatureImage, {
164
+ x: 50,
165
+ y,
166
+ width: imgWidth,
167
+ height: imgHeight
168
+ });
169
+
170
+ return await templatePdfDoc.save();
171
+ }
@@ -0,0 +1,60 @@
1
+ import { PDFArray, CharCodes } from "pdf-lib";
2
+
3
+ /**
4
+ * Extends PDFArray class in order to make ByteRange look like this:
5
+ * /ByteRange [0 /********** /********** /**********]
6
+ * Not this:
7
+ * /ByteRange [ 0 /********** /********** /********** ]
8
+ *
9
+ * @see https://github.com/Hopding/pdf-lib/issues/112#issuecomment-569085380
10
+ * @author https://github.com/Hopding
11
+ */
12
+ // @ts-ignore
13
+ export default class PDFArrayCustom extends PDFArray {
14
+ static withContext(context) {
15
+ // @ts-ignore
16
+ return new PDFArrayCustom(context);
17
+ }
18
+
19
+ clone(context) {
20
+ // @ts-ignore
21
+ const clone = PDFArrayCustom.withContext(context || this.context);
22
+ for (let idx = 0, len = this.size(); idx < len; idx++) {
23
+ // @ts-ignore
24
+ clone.push(this.array[idx]);
25
+ }
26
+ return clone;
27
+ }
28
+
29
+ toString() {
30
+ let arrayString = "[";
31
+ for (let idx = 0, len = this.size(); idx < len; idx++) {
32
+ arrayString += this.get(idx).toString();
33
+ if (idx < len - 1) arrayString += " ";
34
+ }
35
+ arrayString += "]";
36
+ return arrayString;
37
+ }
38
+
39
+ sizeInBytes() {
40
+ let size = 2;
41
+ for (let idx = 0, len = this.size(); idx < len; idx++) {
42
+ size += this.get(idx).sizeInBytes();
43
+ if (idx < len - 1) size += 1;
44
+ }
45
+ return size;
46
+ }
47
+
48
+ copyBytesInto(buffer, offset) {
49
+ const initialOffset = offset;
50
+
51
+ buffer[offset++] = CharCodes.LeftSquareBracket;
52
+ for (let idx = 0, len = this.size(); idx < len; idx++) {
53
+ offset += this.get(idx).copyBytesInto(buffer, offset);
54
+ if (idx < len - 1) buffer[offset++] = CharCodes.Space;
55
+ }
56
+ buffer[offset++] = CharCodes.RightSquareBracket;
57
+
58
+ return offset - initialOffset;
59
+ }
60
+ }
@@ -0,0 +1,112 @@
1
+ import {
2
+ PDFDocument,
3
+ PDFName,
4
+ PDFNumber,
5
+ PDFHexString,
6
+ PDFString,
7
+ } from "pdf-lib";
8
+ import signer from "node-signpdf";
9
+
10
+
11
+ import fs from "fs";
12
+
13
+ import PDFArrayCustom from "./PDFArrayCustom";
14
+
15
+ export default class SignPDF {
16
+ pdfDoc: any;
17
+ certificate: any;
18
+ constructor(pdfFile:any, certFile:any) {
19
+ this.pdfDoc = pdfFile;
20
+ this.certificate = fs.readFileSync(certFile);
21
+ }
22
+
23
+ /**
24
+ * @return Promise<Buffer>
25
+ */
26
+ async signPDF(clave:any) {
27
+ try {
28
+ let newPDF = await this._addPlaceholder();
29
+ newPDF = signer.sign(newPDF, this.certificate,{ passphrase: clave });
30
+
31
+ return newPDF;
32
+ } catch (error) {
33
+ console.error("Error en la firma: ", error)
34
+ throw new Error("Contraseña invalida");
35
+
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @see https://github.com/Hopding/pdf-lib/issues/112#issuecomment-569085380
41
+ * @returns {Promise<Buffer>}
42
+ */
43
+ async _addPlaceholder() {
44
+ const loadedPdf = await PDFDocument.load(this.pdfDoc);
45
+ const ByteRange = PDFArrayCustom.withContext(loadedPdf.context);
46
+ const DEFAULT_BYTE_RANGE_PLACEHOLDER = '**********';
47
+ const SIGNATURE_LENGTH = 8192;
48
+ const pages = loadedPdf.getPages();
49
+
50
+ ByteRange.push(PDFNumber.of(0));
51
+ ByteRange.push(PDFName.of(DEFAULT_BYTE_RANGE_PLACEHOLDER));
52
+ ByteRange.push(PDFName.of(DEFAULT_BYTE_RANGE_PLACEHOLDER));
53
+ ByteRange.push(PDFName.of(DEFAULT_BYTE_RANGE_PLACEHOLDER));
54
+
55
+ const signatureDict = loadedPdf.context.obj({
56
+ Type: 'Sig',
57
+ Filter: 'Adobe.PPKLite',
58
+ SubFilter: 'adbe.pkcs7.detached',
59
+ ByteRange,
60
+ Contents: PDFHexString.of('A'.repeat(SIGNATURE_LENGTH)),
61
+ Reason: PDFString.of('Firma electrónica'),
62
+ M: PDFString.fromDate(new Date()),
63
+ });
64
+
65
+
66
+
67
+ const signatureDictRef = loadedPdf.context.register(signatureDict);
68
+
69
+ const widgetDict = loadedPdf.context.obj({
70
+ Type: 'Annot',
71
+ Subtype: 'Widget',
72
+ FT: 'Sig',
73
+ Rect: [0, 0, 0, 0], // Signature rect size
74
+ V: signatureDictRef,
75
+ T: PDFString.of('test signature'),
76
+ F: 4,
77
+ P: pages[0].ref,
78
+ });
79
+
80
+ const widgetDictRef = loadedPdf.context.register(widgetDict);
81
+
82
+ // Add signature widget to the first page
83
+ pages[0].node.set(PDFName.of('Annots'), loadedPdf.context.obj([widgetDictRef]));
84
+
85
+ loadedPdf.catalog.set(
86
+ PDFName.of('AcroForm'),
87
+ loadedPdf.context.obj({
88
+ SigFlags: 3,
89
+ Fields: [widgetDictRef],
90
+ })
91
+ );
92
+
93
+ // Allows signatures on newer PDFs
94
+ // @see https://github.com/Hopding/pdf-lib/issues/541
95
+ const pdfBytes = await loadedPdf.save({ useObjectStreams: false });
96
+
97
+ return SignPDF.unit8ToBuffer(pdfBytes);
98
+ }
99
+
100
+ /**
101
+ * @param {Uint8Array} unit8
102
+ */
103
+ static unit8ToBuffer(unit8:any) {
104
+ let buf = Buffer.alloc(unit8.byteLength);
105
+ const view = new Uint8Array(unit8);
106
+
107
+ for (let i = 0; i < buf.length; ++i) {
108
+ buf[i] = view[i];
109
+ }
110
+ return buf;
111
+ }
112
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_dependency_injection_1 = require("node-dependency-injection");
4
+ const expediente_electronico_sql_repository_1 = require("../expediente-electronico/infrastructure/repositories/expediente-electronico.sql.repository");
5
+ const expediente_electronico_useCase_1 = require("../expediente-electronico/application/expediente-electronico.useCase");
6
+ const expediente_electronico_controller_1 = require("../expediente-electronico/infrastructure/controller/expediente-electronico.controller");
7
+ const documentos_useCase_1 = require("../documentos/application/documentos.useCase");
8
+ const notificacion_controller_1 = require("../notificaciones/infrastructure/notificacion.controller");
9
+ const flujos_controller_1 = require("../estados/infrastructure/controller/flujos.controller");
10
+ const flujos_useCase_1 = require("../estados/application/flujos.useCase");
11
+ const flujos_sql_repository_1 = require("../estados/infrastructure/repositories/flujos.sql.repository");
12
+ const documentos_ftp_repository_1 = require("../documentos/infrastructure/repository/documentos.ftp.repository");
13
+ const fileServer_basic_ftp_1 = require("../infrastructure/fileServer/fileServer.basic-ftp");
14
+ let container = new node_dependency_injection_1.ContainerBuilder();
15
+ /**
16
+ * Notificaciones
17
+ */
18
+ container.register('EE.Notificaciones.infrastructure.NotificacionesController', notificacion_controller_1.NotificacionController);
19
+ const notificacionCtrl = container.get('EE.Notificaciones.infrastructure.NotificacionesController');
20
+ /**
21
+ * Flujos
22
+ */
23
+ container.register('EE.Flujos.infrastructure.FlujosRepository', flujos_sql_repository_1.FlujosRepository);
24
+ const flujosRepo = container.get('EE.Flujos.infrastructure.FlujosRepository');
25
+ container.register('EE.Flujos.application.FlujosUseCase', flujos_useCase_1.FlujosUseCase).addArgument(flujosRepo);
26
+ const flujosUseCase = container.get('EE.Flujos.application.FlujosUseCase');
27
+ container.register('EE.Flujos.infrastructure.FlujosController', flujos_controller_1.FlujosController).addArgument(flujosUseCase);
28
+ const flujosController = container.get('EE.Flujos.infrastructure.FlujosController');
29
+ container.register('EE.FTPConnection', fileServer_basic_ftp_1.FtpConnection);
30
+ const ftp = container.get('EE.FTPConnection');
31
+ /**
32
+ * Documentos
33
+ */
34
+ container.register('EE.Documentos.infrastructure.DocumentosRepository', documentos_ftp_repository_1.DocumentosFTPRepository).addArgument(ftp);
35
+ const docRepo = container.get('EE.Documentos.infrastructure.DocumentosRepository');
36
+ container.register('EE.Documentos.application.DocumentosUseCase', documentos_useCase_1.DocumentosUseCase).addArgument(docRepo);
37
+ const docUseCase = container.get('EE.Documentos.application.DocumentosUseCase');
38
+ /**
39
+ * Expediente Electronico
40
+ */
41
+ container.register('EE.ExpedienteElectronico.infrastructure.ExpedienteElectronicoSqlRepository', expediente_electronico_sql_repository_1.ExpedienteElectronicoSqlRepository);
42
+ const expedienteRepo = container.get('EE.ExpedienteElectronico.infrastructure.ExpedienteElectronicoSqlRepository');
43
+ container.register('EE.ExpedienteElectronico.application.ExpedienteElectronicoUseCase', expediente_electronico_useCase_1.ExpedienteElectronicoUseCase).addArgument(expedienteRepo).addArgument(docRepo);
44
+ const expedienteUseCase = container.get('EE.ExpedienteElectronico.application.ExpedienteElectronicoUseCase');
45
+ container.register('EE.ExpedienteElectronico.infrastructure.ExpedienteElectronicoController', expediente_electronico_controller_1.ExpedienteElectronicoController).addArgument(expedienteUseCase).addArgument(notificacionCtrl);
46
+ exports.default = container;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.firmarDocumento2 = exports.firmarDocumento = exports.obtenerFirmasDocumento = void 0;
16
+ const fs = require('fs');
17
+ const pdf_lib_1 = require("pdf-lib");
18
+ const moment_1 = __importDefault(require("moment"));
19
+ const pdf_merger_js_1 = __importDefault(require("pdf-merger-js"));
20
+ const SignPDF_1 = __importDefault(require("../domain/SignPDF"));
21
+ const axios_1 = __importDefault(require("axios"));
22
+ const node_path_1 = __importDefault(require("node:path"));
23
+ const form_data_1 = __importDefault(require("form-data"));
24
+ function obtenerFirmasDocumento(uuid) {
25
+ var _a;
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ try {
28
+ const response = yield axios_1.default.get(`${process.env.URL_FIRMAS_SERVICE}/detalle-firmas/${uuid}`);
29
+ return response.data; // Esto sería un array con las firmas y sus datos
30
+ }
31
+ catch (error) {
32
+ if (error.response) {
33
+ console.error("Error obtenerFirmasDocumento: respuesta inválida del servidor");
34
+ if (((_a = error.response.data) === null || _a === void 0 ? void 0 : _a.message) == 'El documento no contiene firmas digitales') {
35
+ // devuelvo array con firmas vacías ya que el documento no tiene firmas
36
+ return [];
37
+ }
38
+ console.error(error.response.data);
39
+ console.error(error.response.status);
40
+ console.error(error.response.headers);
41
+ }
42
+ else if (error.request) {
43
+ console.error("Error obtenerFirmasDocumento: No se recibió respuesta del servicio");
44
+ console.error(error.request);
45
+ }
46
+ else {
47
+ console.error("Error obtenerFirmasDocumento: Error al preparar la solicitud", error.message);
48
+ }
49
+ throw new Error(`Error obtenerFirmasDocumento => ${error}`);
50
+ }
51
+ });
52
+ }
53
+ exports.obtenerFirmasDocumento = obtenerFirmasDocumento;
54
+ function firmarDocumento(documento, firma, usuario, clave) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ const bytes = yield addSignPage(usuario);
57
+ // Crear un PDF con la firma digital y el documento original
58
+ var merger = new pdf_merger_js_1.default();
59
+ yield merger.add(documento);
60
+ yield merger.add(yield Buffer.from(bytes));
61
+ const documentoFirmado = yield merger.saveAsBuffer();
62
+ // const documentoFirmado = bytes;
63
+ // return documentoFirmado;
64
+ const pdfBuffer = new SignPDF_1.default(documentoFirmado, node_path_1.default.resolve(firma.path));
65
+ const signedDocs = yield pdfBuffer.signPDF(clave);
66
+ return signedDocs;
67
+ });
68
+ }
69
+ exports.firmarDocumento = firmarDocumento;
70
+ function firmarDocumento2(token, uuid, firma, clave, x1, y1, page) {
71
+ return __awaiter(this, void 0, void 0, function* () {
72
+ let form = new form_data_1.default;
73
+ console.log("UUID: ", uuid);
74
+ form.append('clave', clave);
75
+ form.append('certificado', fs.createReadStream(firma.path));
76
+ form.append('uuid', uuid);
77
+ form.append('x1', x1);
78
+ form.append('y1', y1);
79
+ form.append('page', page);
80
+ const headers = Object.assign(Object.assign({}, form.getHeaders()), { 'Authorization': `Bearer ${token}` });
81
+ try {
82
+ const response = yield axios_1.default.post(`${process.env.URL_FIRMAS_SERVICE}/firmar-documento`, form, { headers });
83
+ return response.data.uuid;
84
+ }
85
+ catch (error) {
86
+ if (error.response) {
87
+ console.error("Error firmarDocumento2: La respuesta fue hecha y el servidor respondió con un código de estado que esta fuera del rango de 2xx");
88
+ console.error(error.response.data);
89
+ console.error(error.response.status);
90
+ console.error(error.response.headers);
91
+ }
92
+ else if (error.request) {
93
+ console.error("Error firmarDocumento2: Es probable que esté caido el servicio de EE-Firmas. La petición fue hecha pero no se recibió respuesta `error.request` es una instancia de XMLHttpRequest en el navegador y una instancia de http.ClientRequest en node.js");
94
+ console.error(error.request);
95
+ }
96
+ else {
97
+ // Algo paso al preparar la petición que lanzo un Error
98
+ console.error('Error firmarDocumento2: Algo paso al preparar la petición que lanzo un Error', error.message);
99
+ }
100
+ throw new Error(`Error firmarDocumento2=> ${error}`);
101
+ }
102
+ });
103
+ }
104
+ exports.firmarDocumento2 = firmarDocumento2;
105
+ function addSignPage(usuario) {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ const response = yield axios_1.default.get(`http://serverfirmas.ccba.usr.bpba:6050/ListImg/SW3UIDbGetRecInfo.php?IDX_FIR=001%20000${usuario.documento}000%20%20%20%20%20%20&IDX_TYA=TIT&IDX_LOC=ONL&TIP_DOC1=000${usuario.documento}000`, { responseType: 'arraybuffer' });
108
+ const firmaElectronica = response.data;
109
+ // Crear un nuevo documento PDF con pdf-lib
110
+ const templatePdfBytes = fs.readFileSync('src/ee-shared/digitalSignature/infrastructure/template/marco.pdf');
111
+ const templatePdfDoc = yield pdf_lib_1.PDFDocument.load(templatePdfBytes);
112
+ // const pdfDoc = await PDFDocument.load(documento);
113
+ const timesRomanFont = yield templatePdfDoc.embedFont(pdf_lib_1.StandardFonts.TimesRoman);
114
+ // Add a blank page to the document
115
+ const page = templatePdfDoc.getPage(0);
116
+ // Get the width and height of the page
117
+ const { width, height } = page.getSize();
118
+ // Draw a string of text toward the top of the page
119
+ const fontSize = 12;
120
+ // const page = pdfDoc.addPage([600, 800]);
121
+ let y = (height - 4 * fontSize);
122
+ page.drawText(`Firmado electronicamente por: `, {
123
+ x: 50,
124
+ y,
125
+ size: fontSize,
126
+ font: timesRomanFont,
127
+ color: (0, pdf_lib_1.rgb)(0, 0, 0),
128
+ });
129
+ y -= fontSize + 5;
130
+ page.drawText(`Afiliado: ${usuario.uid}`, {
131
+ x: 50,
132
+ y,
133
+ size: fontSize,
134
+ font: timesRomanFont,
135
+ color: (0, pdf_lib_1.rgb)(0, 0, 0),
136
+ });
137
+ y -= fontSize + 5;
138
+ page.drawText(`Nombre completo: ${usuario.nombreCompleto}`, {
139
+ x: 50,
140
+ y,
141
+ size: fontSize,
142
+ font: timesRomanFont,
143
+ color: (0, pdf_lib_1.rgb)(0, 0, 0),
144
+ });
145
+ y -= fontSize + 5;
146
+ page.drawText(`Cargo: ${usuario.cargo}`, {
147
+ x: 50,
148
+ y,
149
+ size: fontSize,
150
+ font: timesRomanFont,
151
+ color: (0, pdf_lib_1.rgb)(0, 0, 0),
152
+ });
153
+ y -= fontSize + 5;
154
+ page.drawText(`Fecha: ${(0, moment_1.default)().locale('es').format('LLLL')}`, {
155
+ x: 50,
156
+ y,
157
+ size: fontSize,
158
+ font: timesRomanFont,
159
+ color: (0, pdf_lib_1.rgb)(0, 0, 0),
160
+ });
161
+ y -= fontSize + 5;
162
+ page.drawText(`Firma electrónica: `, {
163
+ x: 50,
164
+ y,
165
+ size: fontSize,
166
+ font: timesRomanFont,
167
+ color: (0, pdf_lib_1.rgb)(0, 0, 0),
168
+ });
169
+ const signatureImage = yield templatePdfDoc.embedPng(firmaElectronica);
170
+ const { width: imgWidth, height: imgHeight } = signatureImage.scale(0.3); // Aquí puedes ajustar el escalamiento
171
+ y -= imgHeight + 5;
172
+ page.drawImage(signatureImage, {
173
+ x: 50,
174
+ y,
175
+ width: imgWidth,
176
+ height: imgHeight
177
+ });
178
+ return yield templatePdfDoc.save();
179
+ });
180
+ }