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,85 @@
1
+ /**
2
+ * Controlador de ejemplo para usuarios
3
+ * Archivo: examples/basic/controllers/userController.js
4
+ */
5
+
6
+ // Simulación de base de datos
7
+ let users = [
8
+ { id: 1, name: 'John Doe', email: 'john@example.com' },
9
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
10
+ ];
11
+
12
+ // Obtener todos los usuarios
13
+ function getUsers(req, res) {
14
+ res.writeHead(200, { 'Content-Type': 'application/json' });
15
+ res.end(JSON.stringify({
16
+ success: true,
17
+ data: users
18
+ }));
19
+ }
20
+
21
+ // Obtener un usuario por ID
22
+ function getUserById(req, res) {
23
+ const userId = parseInt(req.params.id);
24
+ const user = users.find(u => u.id === userId);
25
+
26
+ if (!user) {
27
+ res.writeHead(404, { 'Content-Type': 'application/json' });
28
+ res.end(JSON.stringify({
29
+ success: false,
30
+ message: 'Usuario no encontrado'
31
+ }));
32
+ return;
33
+ }
34
+
35
+ res.writeHead(200, { 'Content-Type': 'application/json' });
36
+ res.end(JSON.stringify({
37
+ success: true,
38
+ data: user
39
+ }));
40
+ }
41
+
42
+ // Crear un nuevo usuario
43
+ function createUser(req, res) {
44
+ try {
45
+ const { name, email } = req.body;
46
+
47
+ // Validar datos
48
+ if (!name || !email) {
49
+ res.writeHead(400, { 'Content-Type': 'application/json' });
50
+ res.end(JSON.stringify({
51
+ success: false,
52
+ message: 'Nombre y correo electrónico son requeridos'
53
+ }));
54
+ return;
55
+ }
56
+
57
+ // Crear nuevo usuario
58
+ const newUser = {
59
+ id: users.length + 1,
60
+ name,
61
+ email
62
+ };
63
+
64
+ users.push(newUser);
65
+
66
+ res.writeHead(201, { 'Content-Type': 'application/json' });
67
+ res.end(JSON.stringify({
68
+ success: true,
69
+ data: newUser
70
+ }));
71
+ } catch (error) {
72
+ res.writeHead(500, { 'Content-Type': 'application/json' });
73
+ res.end(JSON.stringify({
74
+ success: false,
75
+ message: 'Error al crear usuario'
76
+ }));
77
+ }
78
+ }
79
+
80
+ // Exportar handlers
81
+ module.exports = {
82
+ getUsers,
83
+ getUserById,
84
+ createUser
85
+ };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Ejemplo basico de uso del framework API SDK
3
+ * Este script demuestra cómo usar directamente los controladores
4
+ */
5
+
6
+ const { APISDK, Logger } = require('../index');
7
+ const userController = require('./basic/controllers/userController');
8
+
9
+ // Crear instancia del logger
10
+ const logger = new Logger({ level: 'info', timestamp: true });
11
+
12
+ logger.info('Iniciando ejemplo basico con controladores');
13
+
14
+ // Crear instancia del servidor
15
+ const server = new APISDK({
16
+ port: 6001,
17
+ host: 'localhost'
18
+ });
19
+
20
+ // Middleware de logging
21
+ server.use((req, res, next) => {
22
+ logger.info(`${req.method} ${req.url}`);
23
+ next();
24
+ });
25
+
26
+ // Usar los handlers directamente desde el controlador
27
+ server.addRoute('GET', '/api/users', userController.getUsers);
28
+ server.addRoute('GET', '/api/users/:id', userController.getUserById);
29
+ server.addRoute('POST', '/api/users', userController.createUser);
30
+
31
+ logger.info('Agregando rutas usando handlers del controlador userController');
32
+
33
+ logger.info('\nIniciando servidor en http://localhost:6001');
34
+
35
+ // Iniciar el servidor
36
+ const httpServer = server.start();
37
+
38
+ logger.info('\nENDPOINTS DISPONIBLES:');
39
+ logger.info('GET /api/users - Obtener todos los usuarios');
40
+ logger.info('GET /api/users/:id - Obtener usuario por ID');
41
+ logger.info('POST /api/users - Crear nuevo usuario');
42
+
43
+ logger.info('\nEJEMPLOS DE USO:');
44
+ logger.info('# Obtener todos los usuarios:');
45
+ logger.info('curl -X GET http://localhost:6001/api/users');
46
+ logger.info('');
47
+ logger.info('# Obtener usuario por ID:');
48
+ logger.info('curl -X GET http://localhost:6001/api/users/1');
49
+ logger.info('');
50
+ logger.info('# Crear nuevo usuario:');
51
+ logger.info('curl -X POST -H "Content-Type: application/json" \\');
52
+ logger.info(' -d \'{"name":"Juan Perez", "email":"juan@example.com"}\' \\');
53
+ logger.info(' http://localhost:6001/api/users');
54
+
55
+ logger.info('\nEl servidor se detendrá automáticamente en 60 segundos...');
56
+
57
+ // Programar apagado automático para la demostración
58
+ setTimeout(() => {
59
+ logger.info('Finalizando ejemplo basico...');
60
+ httpServer.close(() => {
61
+ logger.info('Servidor detenido. Ejemplo basico completado.');
62
+ console.log('\nEjemplo basico completado exitosamente!');
63
+ console.log('El framework ha demostrado su capacidad para:');
64
+ console.log(' - Usar controladores directamente');
65
+ console.log(' - Manejar rutas parametrizadas');
66
+ console.log(' - Procesar solicitudes POST con cuerpo JSON');
67
+ process.exit(0);
68
+ });
69
+ }, 60000);
70
+
71
+ // Mantener el proceso activo
72
+ process.stdin.resume();
@@ -0,0 +1,71 @@
1
+ # Ejemplo Frontend con API SDK JS
2
+
3
+ Este ejemplo demuestra cómo el Framework API SDK JS puede utilizarse para servir tanto APIs como contenido HTML para frontends, gracias a la nueva funcionalidad de especificación de content-type en el archivo routes.json.
4
+
5
+ ## Características
6
+
7
+ - API REST y páginas HTML en el mismo servidor
8
+ - Especificación de content-type en routes.json
9
+ - Soporte para diferentes tipos de contenido (HTML, CSS, JavaScript, JSON)
10
+ - Frontend completamente funcional con estilos y scripts
11
+ - Navegación entre páginas HTML
12
+
13
+ ## Configuración
14
+
15
+ 1. Asegúrate de tener instaladas las dependencias del framework API SDK
16
+ 2. No se requiere configuración adicional para este ejemplo
17
+
18
+ ## Uso
19
+
20
+ 1. Inicia el servidor:
21
+ ```bash
22
+ node app.js
23
+ ```
24
+
25
+ 2. El servidor escuchará en `http://localhost:8082`
26
+
27
+ ## Endpoints
28
+
29
+ - `GET /` - Página de inicio HTML
30
+ - `GET /about` - Página Acerca de HTML
31
+ - `GET /contact` - Formulario de contacto HTML
32
+ - `GET /api/users` - API JSON de usuarios
33
+ - `GET /api/users/:id` - API JSON de usuario específico
34
+ - `GET /styles.css` - Archivo CSS
35
+ - `GET /script.js` - Archivo JavaScript
36
+
37
+ ## Nueva funcionalidad: Content-Type en routes.json
38
+
39
+ Este ejemplo demuestra la nueva funcionalidad que permite especificar el content-type directamente en el archivo routes.json:
40
+
41
+ ```json
42
+ {
43
+ "path": "/",
44
+ "method": "GET",
45
+ "controller": "./controllers/pageController.js",
46
+ "handler": "homePage",
47
+ "auth": "none",
48
+ "contentType": "text/html"
49
+ }
50
+ ```
51
+
52
+ El campo `contentType` permite especificar el header Content-Type que se enviará con la respuesta, lo que permite servir diferentes tipos de contenido desde el mismo servidor.
53
+
54
+ ## Estructura del proyecto
55
+
56
+ ```
57
+ examples/frontend/
58
+ ├── app.js # Punto de entrada de la aplicación
59
+ ├── routes.json # Definición de rutas con content-type
60
+ ├── controllers/ # Controladores de las rutas
61
+ │ ├── pageController.js # Controladores para páginas HTML
62
+ │ ├── apiController.js # Controladores para endpoints API
63
+ │ └── staticController.js # Controladores para recursos estáticos
64
+ └── README.md
65
+ ```
66
+
67
+ ## Seguridad
68
+
69
+ - CORS configurado para permitir solicitudes desde navegadores
70
+ - No se requiere autenticación para acceder a los endpoints
71
+ - El framework incluye protección WAF por defecto
@@ -0,0 +1,71 @@
1
+ const {
2
+ APIServer,
3
+ RouteLoader,
4
+ Logger,
5
+ Cors,
6
+ SessionManager
7
+ } = require('../../index.js');
8
+
9
+ async function startServer() {
10
+ // Crear instancia del servidor
11
+ const server = new APIServer({
12
+ port: 8082,
13
+ host: 'localhost'
14
+ });
15
+
16
+ // Crear instancia del logger
17
+ const logger = new Logger({ level: 'info' });
18
+
19
+ try {
20
+ // Crear instancia del administrador de sesiones
21
+ const sessionManager = new SessionManager({
22
+ cookieName: 'frontend_session',
23
+ secret: 'frontend-session-secret-change-in-production',
24
+ timeout: 3600000 // 1 hora
25
+ });
26
+
27
+ // Aplicar middleware de sesión
28
+ server.use(sessionManager.middleware());
29
+
30
+ // Hacer que sessionManager esté disponible en el servidor para el RouteLoader
31
+ server.sessionManager = sessionManager;
32
+
33
+ // Configurar CORS para permitir solicitudes desde navegadores
34
+ const cors = new Cors({
35
+ origin: '*',
36
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
37
+ allowedHeaders: [
38
+ 'Content-Type',
39
+ 'Authorization',
40
+ 'X-Requested-With',
41
+ 'Accept',
42
+ 'Origin'
43
+ ]
44
+ });
45
+
46
+ // Aplicar middleware de CORS
47
+ server.use(cors.middleware());
48
+
49
+ // Cargar rutas desde archivo JSON
50
+ const routeLoader = new RouteLoader();
51
+ await routeLoader.loadRoutes(server, './routes.json');
52
+
53
+ // Iniciar el servidor
54
+ server.start();
55
+
56
+ logger.info('Servidor frontend iniciado en http://localhost:8082');
57
+ logger.info('Endpoints disponibles:');
58
+ logger.info('- GET / (Página de inicio HTML)');
59
+ logger.info('- GET /about (Página Acerca de HTML)');
60
+ logger.info('- GET /api/users (API JSON)');
61
+ logger.info('- GET /contact (Formulario de contacto HTML)');
62
+ } catch (error) {
63
+ logger.error('Error iniciando el servidor:', error.message);
64
+ process.exit(1);
65
+ }
66
+ }
67
+
68
+ // Iniciar el servidor
69
+ startServer();
70
+
71
+ module.exports = { startServer };
@@ -0,0 +1,39 @@
1
+ // Simulación de base de datos en memoria
2
+ const users = [
3
+ { id: 1, name: 'Juan Pérez', email: 'juan@example.com', age: 30 },
4
+ { id: 2, name: 'María García', email: 'maria@example.com', age: 25 },
5
+ { id: 3, name: 'Pedro Rodríguez', email: 'pedro@example.com', age: 35 }
6
+ ];
7
+
8
+ const apiController = {
9
+ getUsers: (req, res) => {
10
+ res.writeHead(200);
11
+ res.end(JSON.stringify({
12
+ success: true,
13
+ data: users,
14
+ count: users.length
15
+ }));
16
+ },
17
+
18
+ getUserById: (req, res) => {
19
+ const userId = parseInt(req.params.id);
20
+ const user = users.find(u => u.id === userId);
21
+
22
+ if (!user) {
23
+ res.writeHead(404);
24
+ res.end(JSON.stringify({
25
+ success: false,
26
+ error: 'Usuario no encontrado'
27
+ }));
28
+ return;
29
+ }
30
+
31
+ res.writeHead(200);
32
+ res.end(JSON.stringify({
33
+ success: true,
34
+ data: user
35
+ }));
36
+ }
37
+ };
38
+
39
+ module.exports = apiController;
@@ -0,0 +1,220 @@
1
+ const messageController = require('./messageController');
2
+
3
+ const authController = {
4
+ // Mostrar formulario de login
5
+ showLoginPage: (req, res) => {
6
+ const html = `
7
+ <!DOCTYPE html>
8
+ <html lang="es">
9
+ <head>
10
+ <meta charset="UTF-8">
11
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
12
+ <title>Login - API Frontend Demo</title>
13
+ <link rel="stylesheet" href="/styles.css">
14
+ </head>
15
+ <body>
16
+ <div class="container">
17
+ <header>
18
+ <h1>Área de Administración</h1>
19
+ <nav>
20
+ <ul>
21
+ <li><a href="/">Inicio</a></li>
22
+ <li><a href="/about">Acerca de</a></li>
23
+ <li><a href="/contact">Contacto</a></li>
24
+ <li><a href="/login">Login</a></li>
25
+ <li><a href="/api/users">Usuarios (API)</a></li>
26
+ </ul>
27
+ </nav>
28
+ </header>
29
+
30
+ <main>
31
+ <section class="login-section">
32
+ <h2>Iniciar Sesión</h2>
33
+ <form id="loginForm">
34
+ <div class="form-group">
35
+ <label for="username">Usuario:</label>
36
+ <input type="text" id="username" name="username" required>
37
+ </div>
38
+
39
+ <div class="form-group">
40
+ <label for="password">Contraseña:</label>
41
+ <input type="password" id="password" name="password" required>
42
+ </div>
43
+
44
+ <button type="submit">Ingresar</button>
45
+ </form>
46
+
47
+ <div id="login-response"></div>
48
+
49
+ <p><em>Usuario: admin | Contraseña: password123</em></p>
50
+ </section>
51
+ </main>
52
+
53
+ <footer>
54
+ <p>&copy; 2026 API SDK JS Framework</p>
55
+ </footer>
56
+ </div>
57
+ <script src="/script.js"></script>
58
+ <script>
59
+ document.addEventListener('DOMContentLoaded', function() {
60
+ const loginForm = document.getElementById('loginForm');
61
+
62
+ if (loginForm) {
63
+ loginForm.addEventListener('submit', function(e) {
64
+ e.preventDefault();
65
+
66
+ const formData = new FormData(loginForm);
67
+ const data = Object.fromEntries(formData);
68
+
69
+ fetch('/api/login', {
70
+ method: 'POST',
71
+ headers: {
72
+ 'Content-Type': 'application/json'
73
+ },
74
+ body: JSON.stringify(data)
75
+ })
76
+ .then(response => response.json())
77
+ .then(result => {
78
+ const responseDiv = document.getElementById('login-response');
79
+
80
+ if (result.success) {
81
+ responseDiv.innerHTML = '<p style="color: green;">Inicio de sesión exitoso. Redirigiendo...</p>';
82
+
83
+ // Redirigir después de un breve delay
84
+ setTimeout(() => {
85
+ window.location.href = '/messages';
86
+ }, 1500);
87
+ } else {
88
+ responseDiv.innerHTML = '<p style="color: red;">' + result.message + '</p>';
89
+ }
90
+ })
91
+ .catch(error => {
92
+ console.error('Error:', error);
93
+ const responseDiv = document.getElementById('login-response');
94
+ responseDiv.innerHTML = '<p style="color: red;">Error de conexión</p>';
95
+ });
96
+ });
97
+ }
98
+ });
99
+ </script>
100
+ </body>
101
+ </html>`;
102
+
103
+ res.writeHead(200);
104
+ res.end(html);
105
+ },
106
+
107
+ // Procesar login
108
+ processLogin: async (req, res) => {
109
+ try {
110
+ // req.body puede ser un string o un objeto, dependiendo de cómo se haya procesado
111
+ let body;
112
+ if (typeof req.body === 'string') {
113
+ body = JSON.parse(req.body);
114
+ } else {
115
+ body = req.body;
116
+ }
117
+
118
+ const { username, password } = body;
119
+
120
+ // Validar credenciales
121
+ const user = await messageController.validateUser(username, password);
122
+
123
+ if (user) {
124
+ // Crear sesión de usuario autenticado
125
+ if (req.session) {
126
+ req.session.create({
127
+ authenticated: true,
128
+ userId: user.id,
129
+ username: user.username
130
+ });
131
+ }
132
+
133
+ res.writeHead(200, { 'Content-Type': 'application/json' });
134
+ res.end(JSON.stringify({
135
+ success: true,
136
+ message: 'Inicio de sesión exitoso',
137
+ userId: user.id
138
+ }));
139
+ } else {
140
+ res.writeHead(401, { 'Content-Type': 'application/json' });
141
+ res.end(JSON.stringify({
142
+ success: false,
143
+ message: 'Credenciales inválidas'
144
+ }));
145
+ }
146
+ } catch (error) {
147
+ console.error('Error en login:', error);
148
+ res.writeHead(500, { 'Content-Type': 'application/json' });
149
+ res.end(JSON.stringify({
150
+ success: false,
151
+ message: 'Error interno del servidor'
152
+ }));
153
+ }
154
+ },
155
+
156
+ // Mostrar mensajes (requiere estar logueado - en este ejemplo simplificado no verificamos sesión)
157
+ showMessages: async (req, res) => {
158
+ try {
159
+ // Obtener mensajes de la base de datos
160
+ const messages = await messageController.getMessages();
161
+
162
+ const messagesHtml = messages.length > 0
163
+ ? messages.map(msg => `
164
+ <div class="message-item">
165
+ <h4>${msg.name} (${msg.email})</h4>
166
+ <p>${msg.message}</p>
167
+ <small>Fecha: ${msg.created_at}</small>
168
+ </div>
169
+ `).join('')
170
+ : '<p>No hay mensajes aún.</p>';
171
+
172
+ const html = `
173
+ <!DOCTYPE html>
174
+ <html lang="es">
175
+ <head>
176
+ <meta charset="UTF-8">
177
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
178
+ <title>Mensajes - API Frontend Demo</title>
179
+ <link rel="stylesheet" href="/styles.css">
180
+ </head>
181
+ <body>
182
+ <div class="container">
183
+ <header>
184
+ <h1>Mensajes Recibidos</h1>
185
+ <nav>
186
+ <ul>
187
+ <li><a href="/">Inicio</a></li>
188
+ <li><a href="/about">Acerca de</a></li>
189
+ <li><a href="/contact">Contacto</a></li>
190
+ <li><a href="/login">Login</a></li>
191
+ <li><a href="/api/users">Usuarios (API)</a></li>
192
+ </ul>
193
+ </nav>
194
+ </header>
195
+
196
+ <main>
197
+ <section class="messages-section">
198
+ ${messagesHtml}
199
+ </section>
200
+ </main>
201
+
202
+ <footer>
203
+ <p>&copy; 2026 API SDK JS Framework</p>
204
+ </footer>
205
+ </div>
206
+ <script src="/script.js"></script>
207
+ </body>
208
+ </html>`;
209
+
210
+ res.writeHead(200);
211
+ res.end(html);
212
+ } catch (error) {
213
+ console.error('Error obteniendo mensajes:', error);
214
+ res.writeHead(500);
215
+ res.end('<h1>Error obteniendo mensajes</h1>');
216
+ }
217
+ }
218
+ };
219
+
220
+ module.exports = authController;
@@ -0,0 +1,47 @@
1
+ const messageController = require('./messageController');
2
+
3
+ const formController = {
4
+ // Procesar el envío del formulario de contacto
5
+ processContactForm: async (req, res) => {
6
+ try {
7
+ // req.body puede ser un string o un objeto, dependiendo de cómo se haya procesado
8
+ let body;
9
+ if (typeof req.body === 'string') {
10
+ body = JSON.parse(req.body);
11
+ } else {
12
+ body = req.body;
13
+ }
14
+
15
+ const { name, email, message } = body;
16
+
17
+ // Validar campos
18
+ if (!name || !email || !message) {
19
+ res.writeHead(400, { 'Content-Type': 'application/json' });
20
+ res.end(JSON.stringify({
21
+ success: false,
22
+ message: 'Todos los campos son obligatorios'
23
+ }));
24
+ return;
25
+ }
26
+
27
+ // Guardar el mensaje en la base de datos
28
+ await messageController.saveMessage(name, email, message);
29
+
30
+ // Responder con éxito
31
+ res.writeHead(200, { 'Content-Type': 'application/json' });
32
+ res.end(JSON.stringify({
33
+ success: true,
34
+ message: 'Mensaje enviado exitosamente'
35
+ }));
36
+ } catch (error) {
37
+ console.error('Error procesando formulario:', error);
38
+ res.writeHead(500, { 'Content-Type': 'application/json' });
39
+ res.end(JSON.stringify({
40
+ success: false,
41
+ message: 'Error interno del servidor'
42
+ }));
43
+ }
44
+ }
45
+ };
46
+
47
+ module.exports = formController;