jerkjs 2.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 (177) hide show
  1. package/LICENSE +200 -0
  2. package/README.md +171 -0
  3. package/doc/EXTENSION_MANUAL.md +958 -0
  4. package/doc/FIREWALL_MANUAL.md +419 -0
  5. package/doc/HOOKS_REFERENCE_IMPROVED.md +599 -0
  6. package/doc/MANUAL_API_SDK.md +539 -0
  7. package/doc/MANUAL_MVC.md +397 -0
  8. package/doc/MARIADB_TOKENS_IMPLEMENTATION.md +113 -0
  9. package/doc/MIDDLEWARE_MANUAL.md +521 -0
  10. package/doc/OAUTH2_GOOGLE_MANUAL.md +408 -0
  11. package/doc/frontend-and-sessions.md +356 -0
  12. package/examples/advanced/controllers/productController.js +64 -0
  13. package/examples/advanced/controllers/userController.js +85 -0
  14. package/examples/advanced/routes.json +51 -0
  15. package/examples/advanced_example.js +93 -0
  16. package/examples/basic/controllers/userController.js +85 -0
  17. package/examples/basic_example.js +72 -0
  18. package/examples/frontend/README.md +71 -0
  19. package/examples/frontend/app.js +71 -0
  20. package/examples/frontend/controllers/apiController.js +39 -0
  21. package/examples/frontend/controllers/authController.js +220 -0
  22. package/examples/frontend/controllers/formController.js +47 -0
  23. package/examples/frontend/controllers/messageController.js +96 -0
  24. package/examples/frontend/controllers/pageController.js +178 -0
  25. package/examples/frontend/controllers/staticController.js +167 -0
  26. package/examples/frontend/routes.json +90 -0
  27. package/examples/mvc_example/app.js +138 -0
  28. package/examples/mvc_example/views/home/index.html +26 -0
  29. package/examples/mvc_example/views/home/simple.html +3 -0
  30. package/examples/mvc_example/views/layout.html +23 -0
  31. package/examples/mvc_example/views/test.html +3 -0
  32. package/examples/mvc_example/views/user/invalid.html +6 -0
  33. package/examples/mvc_example/views/user/list.html +36 -0
  34. package/examples/mvc_example/views/user/notfound.html +6 -0
  35. package/examples/mvc_example/views/user/profile.html +11 -0
  36. package/examples/mvc_routes_example/app.js +34 -0
  37. package/examples/mvc_routes_example/controllers/mainController.js +27 -0
  38. package/examples/mvc_routes_example/controllers/productController.js +47 -0
  39. package/examples/mvc_routes_example/controllers/userController.js +76 -0
  40. package/examples/mvc_routes_example/routes.json +30 -0
  41. package/examples/mvc_routes_example/views/layout.html +31 -0
  42. package/examples/mvc_routes_example/views/main/index.html +11 -0
  43. package/examples/mvc_routes_example/views/product/catalog.html +24 -0
  44. package/examples/mvc_routes_example/views/user/invalid.html +6 -0
  45. package/examples/mvc_routes_example/views/user/list.html +40 -0
  46. package/examples/mvc_routes_example/views/user/notfound.html +6 -0
  47. package/examples/mvc_routes_example/views/user/profile.html +18 -0
  48. package/examples/public/README.md +92 -0
  49. package/examples/public/app.js +72 -0
  50. package/examples/public/controllers/healthController.js +20 -0
  51. package/examples/public/controllers/mainController.js +22 -0
  52. package/examples/public/controllers/userController.js +139 -0
  53. package/examples/public/routes.json +51 -0
  54. package/examples/v2/README.md +72 -0
  55. package/examples/v2/app.js +74 -0
  56. package/examples/v2/app_fixed.js +74 -0
  57. package/examples/v2/controllers/authController.js +64 -0
  58. package/examples/v2/controllers/mainController.js +24 -0
  59. package/examples/v2/controllers/protectedController.js +12 -0
  60. package/examples/v2/controllers/userController.js +16 -0
  61. package/examples/v2/package.json +27 -0
  62. package/examples/v2/routes.json +30 -0
  63. package/examples/v2/test_api.sh +47 -0
  64. package/examples/v2/tokens_example.sqlite +0 -0
  65. package/examples/v2.1_firewall_demo/README.md +113 -0
  66. package/examples/v2.1_firewall_demo/app.js +182 -0
  67. package/examples/v2.1_firewall_demo/package.json +27 -0
  68. package/examples/v2.1_hooks_demo/README.md +85 -0
  69. package/examples/v2.1_hooks_demo/app.js +101 -0
  70. package/examples/v2.1_hooks_demo/controllers/hooksController.js +29 -0
  71. package/examples/v2.1_hooks_demo/controllers/mainController.js +18 -0
  72. package/examples/v2.1_hooks_demo/package.json +27 -0
  73. package/examples/v2.1_hooks_demo/routes.json +16 -0
  74. package/examples/v2.1_openapi_demo/README.md +82 -0
  75. package/examples/v2.1_openapi_demo/app.js +296 -0
  76. package/examples/v2.1_openapi_demo/package.json +26 -0
  77. package/examples/v2_cors/README.md +82 -0
  78. package/examples/v2_cors/app.js +108 -0
  79. package/examples/v2_cors/package.json +23 -0
  80. package/examples/v2_json_auth/README.md +83 -0
  81. package/examples/v2_json_auth/app.js +72 -0
  82. package/examples/v2_json_auth/controllers/authController.js +67 -0
  83. package/examples/v2_json_auth/controllers/mainController.js +16 -0
  84. package/examples/v2_json_auth/controllers/protectedController.js +12 -0
  85. package/examples/v2_json_auth/controllers/tokenController.js +28 -0
  86. package/examples/v2_json_auth/controllers/userController.js +15 -0
  87. package/examples/v2_json_auth/package.json +26 -0
  88. package/examples/v2_json_auth/routes.json +37 -0
  89. package/examples/v2_json_auth/tokens.json +20 -0
  90. package/examples/v2_mariadb_auth/README.md +94 -0
  91. package/examples/v2_mariadb_auth/app.js +81 -0
  92. package/examples/v2_mariadb_auth/controllers/authController.js +95 -0
  93. package/examples/v2_mariadb_auth/controllers/mainController.js +31 -0
  94. package/examples/v2_mariadb_auth/controllers/protectedController.js +12 -0
  95. package/examples/v2_mariadb_auth/controllers/userController.js +17 -0
  96. package/examples/v2_mariadb_auth/package.json +27 -0
  97. package/examples/v2_mariadb_auth/routes.json +37 -0
  98. package/examples/v2_no_auth/README.md +75 -0
  99. package/examples/v2_no_auth/app.js +72 -0
  100. package/examples/v2_no_auth/controllers/healthController.js +14 -0
  101. package/examples/v2_no_auth/controllers/mainController.js +19 -0
  102. package/examples/v2_no_auth/controllers/productController.js +31 -0
  103. package/examples/v2_no_auth/controllers/publicController.js +16 -0
  104. package/examples/v2_no_auth/package.json +22 -0
  105. package/examples/v2_no_auth/routes.json +37 -0
  106. package/examples/v2_oauth/README.md +70 -0
  107. package/examples/v2_oauth/app.js +90 -0
  108. package/examples/v2_oauth/controllers/mainController.js +45 -0
  109. package/examples/v2_oauth/controllers/oauthController.js +247 -0
  110. package/examples/v2_oauth/controllers/protectedController.js +13 -0
  111. package/examples/v2_oauth/controllers/userController.js +17 -0
  112. package/examples/v2_oauth/package.json +26 -0
  113. package/examples/v2_oauth/routes.json +44 -0
  114. package/examples/v2_openapi/README.md +77 -0
  115. package/examples/v2_openapi/app.js +222 -0
  116. package/examples/v2_openapi/controllers/authController.js +52 -0
  117. package/examples/v2_openapi/controllers/mainController.js +26 -0
  118. package/examples/v2_openapi/controllers/productController.js +17 -0
  119. package/examples/v2_openapi/controllers/userController.js +27 -0
  120. package/examples/v2_openapi/package.json +26 -0
  121. package/examples/v2_openapi/routes.json +37 -0
  122. package/generate_token.js +10 -0
  123. package/index.js +85 -0
  124. package/jerk.jpg +0 -0
  125. package/lib/core/handler.js +86 -0
  126. package/lib/core/hooks.js +224 -0
  127. package/lib/core/router.js +204 -0
  128. package/lib/core/securityEnhancedServer.js +752 -0
  129. package/lib/core/server.js +369 -0
  130. package/lib/loader/controllerLoader.js +175 -0
  131. package/lib/loader/routeLoader.js +341 -0
  132. package/lib/middleware/auditLogger.js +208 -0
  133. package/lib/middleware/authenticator.js +565 -0
  134. package/lib/middleware/compressor.js +218 -0
  135. package/lib/middleware/cors.js +135 -0
  136. package/lib/middleware/firewall.js +443 -0
  137. package/lib/middleware/rateLimiter.js +210 -0
  138. package/lib/middleware/session.js +301 -0
  139. package/lib/middleware/validator.js +193 -0
  140. package/lib/mvc/controllerBase.js +207 -0
  141. package/lib/mvc/viewEngine.js +752 -0
  142. package/lib/utils/configParser.js +223 -0
  143. package/lib/utils/logger.js +145 -0
  144. package/lib/utils/mariadbTokenAdapter.js +226 -0
  145. package/lib/utils/openapiGenerator.js +140 -0
  146. package/lib/utils/sqliteTokenAdapter.js +224 -0
  147. package/lib/utils/tokenManager.js +254 -0
  148. package/package.json +47 -0
  149. package/v2examplle/v2_json_auth/README.md +83 -0
  150. package/v2examplle/v2_json_auth/app.js +72 -0
  151. package/v2examplle/v2_json_auth/controllers/authController.js +67 -0
  152. package/v2examplle/v2_json_auth/controllers/mainController.js +16 -0
  153. package/v2examplle/v2_json_auth/controllers/protectedController.js +12 -0
  154. package/v2examplle/v2_json_auth/controllers/tokenController.js +28 -0
  155. package/v2examplle/v2_json_auth/controllers/userController.js +15 -0
  156. package/v2examplle/v2_json_auth/package.json +26 -0
  157. package/v2examplle/v2_json_auth/routes.json +37 -0
  158. package/v2examplle/v2_json_auth/tokens.json +20 -0
  159. package/v2examplle/v2_mariadb_auth/README.md +94 -0
  160. package/v2examplle/v2_mariadb_auth/app.js +81 -0
  161. package/v2examplle/v2_mariadb_auth/controllers/authController.js +95 -0
  162. package/v2examplle/v2_mariadb_auth/controllers/mainController.js +31 -0
  163. package/v2examplle/v2_mariadb_auth/controllers/protectedController.js +12 -0
  164. package/v2examplle/v2_mariadb_auth/controllers/userController.js +17 -0
  165. package/v2examplle/v2_mariadb_auth/package.json +27 -0
  166. package/v2examplle/v2_mariadb_auth/routes.json +37 -0
  167. package/v2examplle/v2_sqlite_auth/README.md +72 -0
  168. package/v2examplle/v2_sqlite_auth/app.js +74 -0
  169. package/v2examplle/v2_sqlite_auth/app_fixed.js +74 -0
  170. package/v2examplle/v2_sqlite_auth/controllers/authController.js +64 -0
  171. package/v2examplle/v2_sqlite_auth/controllers/mainController.js +24 -0
  172. package/v2examplle/v2_sqlite_auth/controllers/protectedController.js +12 -0
  173. package/v2examplle/v2_sqlite_auth/controllers/userController.js +16 -0
  174. package/v2examplle/v2_sqlite_auth/package.json +27 -0
  175. package/v2examplle/v2_sqlite_auth/routes.json +30 -0
  176. package/v2examplle/v2_sqlite_auth/test_api.sh +47 -0
  177. package/v2examplle/v2_sqlite_auth/tokens_example.sqlite +0 -0
@@ -0,0 +1,521 @@
1
+ # Manual de Creación de Middleware para API SDK Framework
2
+
3
+ Visita nuestra página web: https://jerk.page.gd/
4
+ Repositorio oficial: https://gitlab.com/bytedogssyndicate1/jerk/
5
+
6
+ ## Tabla de Contenidos
7
+
8
+ 1. [Introducción al Middleware](#introducción-al-middleware)
9
+ 2. [Patrones de Middleware](#patrones-de-middleware)
10
+ 3. [Guía de Implementación](#guía-de-implementación)
11
+ 4. [Ejemplo Completo: Middleware de Auditoría](#ejemplo-completo-middleware-de-auditoría)
12
+ 5. [Pruebas y Validación](#pruebas-y-validación)
13
+ 6. [Integración con el Framework](#integración-con-el-framework)
14
+
15
+ ## Introducción al Middleware
16
+
17
+ El middleware en el API SDK Framework es una función que se ejecuta en el pipeline de procesamiento de solicitudes HTTP. Actúa como intermediario entre la solicitud entrante y el handler final, permitiendo modificar la solicitud, la respuesta, o incluso detener el flujo de ejecución.
18
+
19
+ ### Características del Middleware
20
+
21
+ - **Secuencial**: Se ejecutan en el orden en que se registran
22
+ - **Interceptable**: Pueden modificar `req` y `res` antes de pasar al siguiente
23
+ - **Terminable**: Pueden enviar respuesta y detener el flujo
24
+ - **Flexible**: Pueden aplicarse globalmente o a rutas específicas
25
+
26
+ ### Firma del Middleware
27
+
28
+ ```javascript
29
+ function middleware(req, res, next) {
30
+ // Lógica del middleware
31
+ next(); // Continuar con el siguiente middleware
32
+ }
33
+ ```
34
+
35
+ ## Patrones de Middleware
36
+
37
+ ### 1. Middleware de Logging
38
+
39
+ Registra información sobre las solicitudes entrantes.
40
+
41
+ ### 2. Middleware de Autenticación
42
+
43
+ Verifica credenciales antes de permitir el acceso.
44
+
45
+ ### 3. Middleware de Validación
46
+
47
+ Valida datos de entrada antes de procesarlos.
48
+
49
+ ### 4. Middleware de Seguridad
50
+
51
+ Aplica medidas de seguridad como CORS, Rate Limiting, etc.
52
+
53
+ ### 5. Middleware de Transformación
54
+
55
+ Modifica la solicitud o respuesta antes de procesarla.
56
+
57
+ ## Guía de Implementación
58
+
59
+ ### Paso 1: Definir el Propósito
60
+
61
+ Antes de crear cualquier middleware, define claramente:
62
+
63
+ 1. **¿Qué problema resolverá?**
64
+ 2. **¿En qué punto del pipeline se ejecutará?**
65
+ 3. **¿Qué datos necesita procesar?**
66
+ 4. **¿Qué efectos secundarios tendrá?**
67
+
68
+ ### Paso 2: Implementar la Función Base
69
+
70
+ ```javascript
71
+ function miMiddleware(opciones = {}) {
72
+ return (req, res, next) => {
73
+ // Lógica del middleware
74
+ next();
75
+ };
76
+ }
77
+ ```
78
+
79
+ ### Paso 3: Manejar Casos Especiales
80
+
81
+ Considera casos como:
82
+ - Solicitudes que deben ser rechazadas
83
+ - Solicitudes que requieren transformación
84
+ - Solicitudes que deben ser registradas
85
+ - Errores durante el procesamiento
86
+
87
+ ### Paso 4: Asegurar la Seguridad
88
+
89
+ - Validar entradas
90
+ - Sanitizar datos
91
+ - Aplicar límites de seguridad
92
+ - Registrar actividades sospechosas
93
+
94
+ ## Ejemplo Completo: Middleware de Auditoría
95
+
96
+ Vamos a crear un middleware de auditoría que registre todas las actividades de los usuarios:
97
+
98
+ ```javascript
99
+ // lib/middleware/auditLogger.js
100
+ const fs = require('fs');
101
+ const path = require('path');
102
+
103
+ class AuditLogger {
104
+ /**
105
+ * Constructor del middleware de auditoría
106
+ * @param {Object} options - Opciones de configuración
107
+ * @param {string} options.logFile - Ruta al archivo de logs
108
+ * @param {Array} options.events - Eventos a auditar
109
+ * @param {Function} options.filter - Función para filtrar solicitudes
110
+ * @param {boolean} options.includeBody - Incluir cuerpo de la solicitud
111
+ * @param {boolean} options.includeHeaders - Incluir headers
112
+ */
113
+ constructor(options = {}) {
114
+ this.logFile = options.logFile || './audit.log';
115
+ this.events = options.events || ['request', 'response', 'error'];
116
+ this.filter = options.filter || (() => true);
117
+ this.includeBody = options.includeBody !== false;
118
+ this.includeHeaders = options.includeHeaders !== false;
119
+ this.logger = options.logger || console;
120
+ }
121
+
122
+ /**
123
+ * Middleware de auditoría
124
+ * @returns {Function} - Middleware de auditoría
125
+ */
126
+ middleware() {
127
+ return (req, res, next) => {
128
+ // Verificar si la solicitud debe ser auditada
129
+ if (!this.filter(req)) {
130
+ next();
131
+ return;
132
+ }
133
+
134
+ const startTime = Date.now();
135
+ const requestId = this.generateRequestId();
136
+
137
+ // Registrar la solicitud entrante
138
+ this.logRequest(req, requestId);
139
+
140
+ // Capturar la respuesta original para registrarla
141
+ const originalEnd = res.end;
142
+ res.end = (chunk, encoding) => {
143
+ const duration = Date.now() - startTime;
144
+
145
+ // Registrar la respuesta
146
+ this.logResponse(req, res, chunk, duration, requestId);
147
+
148
+ // Llamar al método original
149
+ originalEnd.call(res, chunk, encoding);
150
+ };
151
+
152
+ // Capturar errores para auditarlos
153
+ const originalOnError = req.connection && req.connection.onerror;
154
+ req.connection.onerror = (err) => {
155
+ this.logError(req, err, requestId);
156
+ if (originalOnError) originalOnError.call(req.connection, err);
157
+ };
158
+
159
+ next();
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Genera un ID único para la solicitud
165
+ * @returns {string} - ID único de solicitud
166
+ */
167
+ generateRequestId() {
168
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
169
+ }
170
+
171
+ /**
172
+ * Registra la solicitud entrante
173
+ * @param {Object} req - Objeto de solicitud
174
+ * @param {string} requestId - ID de la solicitud
175
+ */
176
+ logRequest(req, requestId) {
177
+ if (!this.events.includes('request')) return;
178
+
179
+ const logEntry = {
180
+ timestamp: new Date().toISOString(),
181
+ event: 'request',
182
+ requestId,
183
+ method: req.method,
184
+ url: req.url,
185
+ ip: this.getClientIP(req),
186
+ userAgent: req.headers['user-agent'],
187
+ headers: this.includeHeaders ? req.headers : undefined,
188
+ body: this.includeBody ? req.body : undefined
189
+ };
190
+
191
+ this.writeLog(logEntry);
192
+ }
193
+
194
+ /**
195
+ * Registra la respuesta saliente
196
+ * @param {Object} req - Objeto de solicitud
197
+ * @param {Object} res - Objeto de respuesta
198
+ * @param {any} chunk - Cuerpo de la respuesta
199
+ * @param {number} duration - Duración de la solicitud
200
+ * @param {string} requestId - ID de la solicitud
201
+ */
202
+ logResponse(req, res, chunk, duration, requestId) {
203
+ if (!this.events.includes('response')) return;
204
+
205
+ const logEntry = {
206
+ timestamp: new Date().toISOString(),
207
+ event: 'response',
208
+ requestId,
209
+ method: req.method,
210
+ url: req.url,
211
+ statusCode: res.statusCode,
212
+ duration,
213
+ ip: this.getClientIP(req),
214
+ responseSize: chunk ? Buffer.byteLength(chunk) : 0
215
+ };
216
+
217
+ this.writeLog(logEntry);
218
+ }
219
+
220
+ /**
221
+ * Registra un error
222
+ * @param {Object} req - Objeto de solicitud
223
+ * @param {Error} error - Error ocurrido
224
+ * @param {string} requestId - ID de la solicitud
225
+ */
226
+ logError(req, error, requestId) {
227
+ if (!this.events.includes('error')) return;
228
+
229
+ const logEntry = {
230
+ timestamp: new Date().toISOString(),
231
+ event: 'error',
232
+ requestId,
233
+ method: req.method,
234
+ url: req.url,
235
+ ip: this.getClientIP(req),
236
+ errorMessage: error.message,
237
+ stack: error.stack
238
+ };
239
+
240
+ this.writeLog(logEntry);
241
+ }
242
+
243
+ /**
244
+ * Obtiene la IP del cliente
245
+ * @param {Object} req - Objeto de solicitud
246
+ * @returns {string} - IP del cliente
247
+ */
248
+ getClientIP(req) {
249
+ return req.headers['x-forwarded-for'] ||
250
+ req.connection.remoteAddress ||
251
+ req.socket.remoteAddress ||
252
+ (req.connection.socket ? req.connection.socket.remoteAddress : null);
253
+ }
254
+
255
+ /**
256
+ * Escribe una entrada de log
257
+ * @param {Object} entry - Entrada de log
258
+ */
259
+ writeLog(entry) {
260
+ const logLine = JSON.stringify(entry) + '\n';
261
+
262
+ // Escribir al archivo de log
263
+ fs.appendFileSync(this.logFile, logLine);
264
+
265
+ // También escribir al logger si está disponible
266
+ if (this.logger) {
267
+ this.logger.info(`AUDIT: ${entry.event} - ${entry.method} ${entry.url} - ${entry.ip}`);
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Limpia logs antiguos
273
+ * @param {number} days - Días a mantener
274
+ */
275
+ cleanupOldLogs(days = 30) {
276
+ // Esta es una implementación básica
277
+ // En una implementación real, usarías librerías como 'winston' con transporte de archivos
278
+ console.log(`Limpiando logs anteriores a ${days} días...`);
279
+ }
280
+ }
281
+
282
+ module.exports = AuditLogger;
283
+ ```
284
+
285
+ ### Uso del Middleware de Auditoría
286
+
287
+ ```javascript
288
+ // examples/v2/audit_middleware_example.js
289
+ const { JERK, Logger } = require('../../index');
290
+ const AuditLogger = require('../../lib/middleware/auditLogger');
291
+
292
+ // Crear instancia del logger
293
+ const logger = new Logger({ level: 'info', timestamp: true });
294
+
295
+ logger.info('🔐 Iniciando ejemplo con middleware de auditoría');
296
+
297
+ // Crear instancia del servidor
298
+ const server = new JERK({
299
+ port: 8084,
300
+ host: 'localhost'
301
+ });
302
+
303
+ // Crear instancia del middleware de auditoría
304
+ const auditLogger = new AuditLogger({
305
+ logFile: './audit.log',
306
+ events: ['request', 'response', 'error'],
307
+ includeBody: true,
308
+ includeHeaders: false,
309
+ filter: (req) => {
310
+ // No auditar solicitudes a /health
311
+ return req.url !== '/health';
312
+ }
313
+ });
314
+
315
+ // Aplicar middleware de auditoría
316
+ server.use(auditLogger.middleware());
317
+
318
+ // Middleware de logging normal
319
+ server.use((req, res, next) => {
320
+ logger.info(`${req.method} ${req.url} - IP: ${req.connection.remoteAddress}`);
321
+ next();
322
+ });
323
+
324
+ // Rutas de ejemplo
325
+ server.addRoute('GET', '/', (req, res) => {
326
+ res.writeHead(200, { 'Content-Type': 'application/json' });
327
+ res.end(JSON.stringify({
328
+ message: 'API con middleware de auditoría',
329
+ timestamp: new Date().toISOString()
330
+ }));
331
+ });
332
+
333
+ server.addRoute('POST', '/api/users', (req, res) => {
334
+ res.writeHead(201, { 'Content-Type': 'application/json' });
335
+ res.end(JSON.stringify({
336
+ success: true,
337
+ message: 'Usuario creado',
338
+ data: req.body
339
+ }));
340
+ });
341
+
342
+ server.addRoute('GET', '/health', (req, res) => {
343
+ res.writeHead(200, { 'Content-Type': 'application/json' });
344
+ res.end(JSON.stringify({ status: 'healthy' }));
345
+ });
346
+
347
+ logger.info('✅ Rutas configuradas con middleware de auditoría');
348
+
349
+ // Iniciar el servidor
350
+ const httpServer = server.start();
351
+
352
+ logger.info('✅ Servidor iniciado en http://localhost:8084');
353
+ logger.info('📋 Endpoints disponibles:');
354
+ logger.info(' GET / - Página principal (auditable)');
355
+ logger.info(' POST /api/users - Crear usuario (auditable)');
356
+ logger.info(' GET /health - Salud del sistema (no auditado)');
357
+
358
+ logger.info('\n🔧 Comandos de prueba con curl:');
359
+ logger.info(' # Probar endpoint principal (será auditado):');
360
+ logger.info(' curl http://localhost:8084/');
361
+ logger.info('');
362
+ logger.info(' # Crear usuario (será auditado):');
363
+ logger.info(' curl -X POST http://localhost:8084/api/users \\');
364
+ logger.info(' -H "Content-Type: application/json" \\');
365
+ logger.info(' -d \'{"name":"Test User", "email":"test@example.com"}\'');
366
+ logger.info('');
367
+ logger.info(' # Verificar salud (no será auditado):');
368
+ logger.info(' curl http://localhost:8084/health');
369
+
370
+ logger.info('\n📊 Los eventos se registrarán en ./audit.log');
371
+
372
+ // Manejo de cierre
373
+ const gracefulShutdown = () => {
374
+ logger.info('🛑 Cerrando servidor...');
375
+ httpServer.close(() => {
376
+ logger.info('🔌 Servidor detenido');
377
+ process.exit(0);
378
+ });
379
+ };
380
+
381
+ process.on('SIGTERM', gracefulShutdown);
382
+ process.on('SIGINT', gracefulShutdown);
383
+ ```
384
+
385
+ ## Pruebas y Validación
386
+
387
+ ### Prueba del Middleware de Auditoría
388
+
389
+ ```javascript
390
+ // test_audit_middleware.js
391
+ const { JERK } = require('../index');
392
+ const AuditLogger = require('../lib/middleware/auditLogger');
393
+ const fs = require('fs');
394
+ const path = require('path');
395
+
396
+ async function testAuditMiddleware() {
397
+ console.log('🧪 Probando middleware de auditoría...\n');
398
+
399
+ // Crear servidor de prueba
400
+ const server = new JERK({ port: 9998 });
401
+
402
+ // Crear middleware de auditoría para pruebas
403
+ const auditLogger = new AuditLogger({
404
+ logFile: './test_audit.log',
405
+ events: ['request', 'response'],
406
+ includeBody: true
407
+ });
408
+
409
+ // Aplicar middleware
410
+ server.use(auditLogger.middleware());
411
+
412
+ // Agregar ruta de prueba
413
+ server.addRoute('GET', '/test', (req, res) => {
414
+ res.writeHead(200, { 'Content-Type': 'application/json' });
415
+ res.end(JSON.stringify({ message: 'OK' }));
416
+ });
417
+
418
+ server.addRoute('POST', '/test-post', (req, res) => {
419
+ res.writeHead(200, { 'Content-Type': 'application/json' });
420
+ res.end(JSON.stringify({ received: req.body }));
421
+ });
422
+
423
+ console.log('✅ Middleware de auditoría aplicado');
424
+ console.log('✅ Rutas de prueba configuradas');
425
+
426
+ // Iniciar servidor (en una implementación real, aquí haríamos solicitudes de prueba)
427
+ const httpServer = server.start();
428
+
429
+ console.log('✅ Servidor de prueba iniciado');
430
+ console.log('✅ El middleware de auditoría está funcionando');
431
+ console.log('✅ Las solicitudes se registrarán en test_audit.log');
432
+
433
+ // Detener servidor después de un tiempo
434
+ setTimeout(() => {
435
+ httpServer.close();
436
+ console.log('\n✅ Prueba completada');
437
+ console.log('📊 Revisa el archivo test_audit.log para ver los registros');
438
+ }, 2000);
439
+ }
440
+
441
+ // Ejecutar prueba
442
+ testAuditMiddleware().catch(console.error);
443
+ ```
444
+
445
+ ## Integración con el Framework
446
+
447
+ ### 1. Registro en el Punto de Entrada
448
+
449
+ ```javascript
450
+ // Actualizar index.js para exportar el nuevo middleware
451
+ const AuditLogger = require('./lib/middleware/auditLogger');
452
+
453
+ module.exports = {
454
+ // ... otros componentes ...
455
+ AuditLogger // Exportar el nuevo middleware
456
+ };
457
+ ```
458
+
459
+ ### 2. Ejemplos de Uso en Aplicaciones Reales
460
+
461
+ ```javascript
462
+ // Ejemplo de uso en una aplicación real
463
+ const { APISDK, AuditLogger } = require('jerk');
464
+
465
+ const server = new JERK({ port: 3000 });
466
+
467
+ // Middleware de auditoría para eventos de seguridad
468
+ const securityAudit = new AuditLogger({
469
+ logFile: './security_audit.log',
470
+ events: ['request', 'error'],
471
+ filter: (req) => {
472
+ // Solo auditar endpoints sensibles
473
+ return req.url.startsWith('/api/admin') || req.url.startsWith('/api/users');
474
+ }
475
+ });
476
+
477
+ server.use(securityAudit.middleware());
478
+
479
+ // Middleware de auditoría general
480
+ const generalAudit = new AuditLogger({
481
+ logFile: './general_audit.log',
482
+ events: ['request', 'response']
483
+ });
484
+
485
+ server.use(generalAudit.middleware());
486
+ ```
487
+
488
+ ## Buenas Prácticas para Middleware
489
+
490
+ ### 1. Rendimiento
491
+ - Minimizar operaciones costosas
492
+ - Usar caché cuando sea posible
493
+ - Evitar operaciones de bloqueo
494
+
495
+ ### 2. Seguridad
496
+ - Validar entradas
497
+ - Sanitizar datos
498
+ - Aplicar límites de seguridad
499
+ - Registrar actividades sospechosas
500
+
501
+ ### 3. Observabilidad
502
+ - Registrar adecuadamente
503
+ - Medir tiempos de ejecución
504
+ - Detectar anomalías
505
+
506
+ ### 4. Mantenibilidad
507
+ - Código limpio y bien documentado
508
+ - Opciones configurables
509
+ - Manejo adecuado de errores
510
+
511
+ ## Conclusión
512
+
513
+ El sistema de middleware del API SDK Framework es potente y flexible, permitiendo extender la funcionalidad del servidor de múltiples maneras. El ejemplo del middleware de auditoría demuestra cómo crear middleware complejo que puede:
514
+
515
+ - Registrar eventos de solicitud, respuesta y error
516
+ - Filtrar solicitudes según criterios personalizados
517
+ - Incluir o excluir información sensible
518
+ - Integrarse completamente con el sistema de logging del framework
519
+ - Ser configurado y reutilizado en diferentes aplicaciones
520
+
521
+ Este patrón puede aplicarse para crear cualquier tipo de middleware que necesites: autenticación, autorización, validación, transformación de datos, logging, métricas, etc.