blackcoffee2 2.1.1 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1,67 @@
1
+ # ============================================
2
+ # BlackCoffee - Variables de Entorno
3
+ # ============================================
4
+ # Copia este archivo a .env y ajusta los valores
5
+ # cp .env.example .env
6
+
7
+ # ============================================
8
+ # Servidor
9
+ # ============================================
10
+ PORT=9791
11
+ HOST=localhost
12
+
13
+ # ============================================
14
+ # HTTPS / SSL
15
+ # ============================================
16
+ SSL_KEY=key-2048.pem
17
+ SSL_CERT=cert-2048.pem
18
+
19
+ # ============================================
20
+ # Sesiones - Core BlackCoffee
21
+ # ============================================
22
+ # Nombre de la cookie de sesión
23
+ SESSION_COOKIE_NAME=blackcoffee_session
24
+
25
+ # Secret para firmar las sesiones (CAMBIAR EN PRODUCCIÓN)
26
+ SESSION_SECRET=cambia-esto-en-produccion-12345
27
+
28
+ # Timeout de sesión en milisegundos (default: 3600000 = 1 hora)
29
+ SESSION_TIMEOUT=3600000
30
+
31
+ # ============================================
32
+ # Sesiones - Admin Dashboard
33
+ # ============================================
34
+ # Nombre de la cookie para el admin (opcional, usa SESSION_COOKIE_NAME si no se define)
35
+ ADMIN_COOKIE_NAME=blackcoffee_admin_session
36
+
37
+ # Secret para sesiones del admin (opcional, usa SESSION_SECRET si no se define)
38
+ ADMIN_SESSION_SECRET=admin-secreto-cambiar-en-produccion-67890
39
+
40
+ # ============================================
41
+ # Consola Administrativa TCP
42
+ # ============================================
43
+ ADMIN_PORT=9999
44
+ ADMIN_HOST=127.0.0.1
45
+
46
+ # ============================================
47
+ # Hot Reload
48
+ # ============================================
49
+ HOT_RELOAD=true
50
+
51
+ # ============================================
52
+ # Database Pool Manager
53
+ # ============================================
54
+ DB_AUTO_CONNECT=true
55
+
56
+ # ============================================
57
+ # WAF (Web Application Firewall)
58
+ # ============================================
59
+ WAF_ENABLED=true
60
+ WAF_MAX_ATTEMPTS=5
61
+ WAF_BLOCK_DURATION=900000
62
+
63
+ # ============================================
64
+ # Logging
65
+ # ============================================
66
+ LOG_LEVEL=info
67
+ LOG_FILE=debug.log
package/CHANGELOG.md CHANGED
@@ -5,6 +5,173 @@ All notable changes to BlackCoffee will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.1.2] - 2026-02-18
9
+
10
+ ### 🔧 Variables de Entorno para Sesiones
11
+
12
+ #### Added
13
+ - **Configuración mediante variables de entorno** para sesiones de BlackCoffee
14
+ - `SESSION_COOKIE_NAME` - Nombre personalizado de la cookie
15
+ - `SESSION_SECRET` - Secret para firmar sesiones
16
+ - `SESSION_TIMEOUT` - Timeout de sesión en milisegundos
17
+ - `ADMIN_COOKIE_NAME` - Nombre de cookie para admin dashboard
18
+ - `ADMIN_SESSION_SECRET` - Secret para sesiones del admin
19
+
20
+ - **Archivo `.env.example`** - Plantilla de referencia con todas las variables
21
+
22
+ #### Changed
23
+ - **`includes/sessions.js`** - Ahora soporta `SESSION_COOKIE_NAME` y `SESSION_TIMEOUT` desde ENV
24
+ - **`programatically/initFlow.js`** - Soporta todas las variables de sesión
25
+ - **`includes/adminAuth.js`** - Soporta `ADMIN_COOKIE_NAME` y `ADMIN_SESSION_SECRET`
26
+ - **`controllers/admin/AuthController.js`** - Usa `ADMIN_COOKIE_NAME` dinámico en logout
27
+
28
+ #### Security
29
+ - ✅ Secrets configurables desde entorno (no hardcodeados)
30
+ - ✅ Nombres de cookies personalizables
31
+ - ✅ Cada aplicación puede tener sus propias variables
32
+
33
+ #### Usage
34
+ ```bash
35
+ # Variables disponibles
36
+ export SESSION_COOKIE_NAME="mi_app_session"
37
+ export SESSION_SECRET="mi-secreto-super-seguro"
38
+ export SESSION_TIMEOUT=7200000 # 2 horas
39
+ export ADMIN_COOKIE_NAME="admin_area_session"
40
+ export ADMIN_SESSION_SECRET="admin-secreto-12345"
41
+
42
+ # Iniciar servidor
43
+ node server.js
44
+ ```
45
+
46
+ #### Files Modified
47
+ - `includes/sessions.js` - Agregado soporte para `SESSION_COOKIE_NAME` y `SESSION_TIMEOUT`
48
+ - `programatically/initFlow.js` - Agregado soporte para variables de entorno
49
+ - `includes/adminAuth.js` - Agregado `ADMIN_COOKIE_NAME` y `ADMIN_SESSION_SECRET`
50
+ - `controllers/admin/AuthController.js` - Logout usa cookie name dinámica
51
+ - `.env.example` - Nuevo archivo con plantilla de variables
52
+
53
+ #### Default Values
54
+ | Variable | Default | Descripción |
55
+ |----------|---------|-------------|
56
+ | `SESSION_COOKIE_NAME` | `blackcoffee_session` | Cookie de sesión core |
57
+ | `SESSION_SECRET` | `blackcoffee-secret...` | Secret para sesiones |
58
+ | `SESSION_TIMEOUT` | `3600000` (1 hora) | Timeout en ms |
59
+ | `ADMIN_COOKIE_NAME` | `blackcoffee_admin_session` | Cookie del admin |
60
+ | `ADMIN_SESSION_SECRET` | `SESSION_SECRET` | Secret del admin |
61
+
62
+ ---
63
+
64
+ ## [2.1.1] - 2026-02-18
65
+
66
+ ### 🎯 OTrack Application - Sistema de Tracking con EJS
67
+
68
+ #### Added
69
+ - **Aplicación OTrack completa** (`apps/otrack/1-0-0/`)
70
+ - Sistema de gestión de usuarios con CRUD completo
71
+ - Autenticación JWT con tokens almacenados en MariaDB
72
+ - Vistas con **EJS Template Engine**
73
+ - Pool de base de datos independiente `otrack-db`
74
+
75
+ - **Modelos de Datos**
76
+ - `UserModel` - Gestión de usuarios con bcryptjs para hash de contraseñas
77
+ - `JwtTokenModel` - Tokens JWT con uuid para generación única
78
+ - `SessionModel` - Sesiones persistentes en base de datos
79
+ - Validaciones con `validator` library
80
+
81
+ - **Controladores**
82
+ - `OtrackController` - CRUD de usuarios y vistas dashboard/users
83
+ - `AuthController` - Login, logout, registro con sesiones en BD
84
+
85
+ - **Middleware Independiente** (`middleware/OtrackAuth.js`)
86
+ - Autenticación por cookie `otrack_session_token`
87
+ - Verificación de sesiones en base de datos
88
+ - Soporte para JWT tokens
89
+ - **Aislamiento total** de sesiones de BlackCoffee admin
90
+
91
+ - **Vistas EJS**
92
+ - `login.ejs` - Formulario de login con registro
93
+ - `dashboard.ejs` - Dashboard con estadísticas
94
+ - `users.ejs` - Manager de usuarios con modal CRUD
95
+ - `index.ejs` - Landing page
96
+
97
+ - **ViewHelper con EJS** (`core/ViewHelper.js`)
98
+ - Motor de plantillas EJS independiente
99
+ - Soporte para `.ejs` y `.html`
100
+ - Renderizado desde aplicaciones sin modificar el core
101
+
102
+ - **Hot Reload para OTrack**
103
+ - Detección automática de cambios en controllers/models/views
104
+ - Recarga sin reiniciar servidor
105
+
106
+ #### Changed
107
+ - **Sesiones Independientes** - OTrack usa su propia BD y cookies
108
+ - Cookie: `otrack_session_token` (diferente de `blackcoffee_admin_session`)
109
+ - BD: MariaDB `tracking.sessions` (diferente de SQLite admin)
110
+ - **Sin cruce de sesiones** entre aplicaciones
111
+
112
+ - **Formato de versión BSD** - `1-0-0` en lugar de `1.0.0`
113
+ - Evita problemas con ViewEngine y puntos en rutas
114
+
115
+ - **UserModel actualizado**
116
+ - Método `getById()` agregado
117
+ - bcryptjs para hash de contraseñas
118
+ - validator para emails y usernames
119
+
120
+ #### Security
121
+ - ✅ Contraseñas con bcryptjs (salt rounds: 10)
122
+ - ✅ Tokens UUID v4 únicos por sesión
123
+ - ✅ Cookies HttpOnly con SameSite=Lax
124
+ - ✅ Verificación de sesiones en base de datos
125
+ - ✅ Aislamiento de sesiones entre aplicaciones
126
+
127
+ #### Files Added
128
+ - `apps/otrack/1-0-0/manifest.json`
129
+ - `apps/otrack/1-0-0/package.json` (con dependencias propias)
130
+ - `apps/otrack/1-0-0/controllers/OtrackController.js`
131
+ - `apps/otrack/1-0-0/controllers/AuthController.js`
132
+ - `apps/otrack/1-0-0/models/UserModel.js`
133
+ - `apps/otrack/1-0-0/models/JwtTokenModel.js`
134
+ - `apps/otrack/1-0-0/models/SessionModel.js`
135
+ - `apps/otrack/1-0-0/middleware/OtrackAuth.js`
136
+ - `apps/otrack/1-0-0/views/otrack/*.ejs` (4 vistas)
137
+ - `apps/otrack/1-0-0/routes/static.json`
138
+ - `apps/otrack/1-0-0/scripts/init-db.sql`
139
+ - `core/ViewHelper.js`
140
+
141
+ #### Files Modified
142
+ - `config/database.json` - Agregado pool `otrack-db`
143
+ - `core/hotReload.js` - Fix: `manifestPath` no estaba definido
144
+
145
+ #### Dependencies (OTrack)
146
+ ```json
147
+ {
148
+ "uuid": "^9.0.0",
149
+ "validator": "^13.11.0",
150
+ "bcryptjs": "^2.4.3",
151
+ "ejs": "^3.1.x"
152
+ }
153
+ ```
154
+
155
+ #### Endpoints
156
+ | Método | Endpoint | Descripción |
157
+ |--------|----------|-------------|
158
+ | GET | `/otrack/1-0-0/` | Landing page |
159
+ | GET | `/otrack/1-0-0/dashboard` | Dashboard (protegido) |
160
+ | GET | `/otrack/1-0-0/users/view` | Users Manager (protegido) |
161
+ | GET | `/otrack/1-0-0/users` | API lista de usuarios |
162
+ | POST | `/otrack/1-0-0/users` | API crear usuario |
163
+ | PUT | `/otrack/1-0-0/users/:id` | API actualizar usuario |
164
+ | DELETE | `/otrack/1-0-0/users/:id` | API eliminar usuario |
165
+ | POST | `/otrack/1-0-0/auth/login` | Login |
166
+ | POST | `/otrack/1-0-0/auth/logout` | Logout |
167
+ | POST | `/otrack/1-0-0/auth/register` | Registro |
168
+
169
+ #### Default Credentials
170
+ - **Username:** `admin` | **Password:** `admin123`
171
+ - **Username:** `testuser` | **Password:** `user123`
172
+
173
+ ---
174
+
8
175
  ## [2.1.0] - 2026-02-18
9
176
 
10
177
  ### 🔐 Sistema de Autenticación para Dashboard Admin
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ☕ BlackCoffee v2.0.0 - App Server
1
+ # ☕ BlackCoffee v2.1.x - App Server
2
2
 
3
3
  ![Version](https://img.shields.io/badge/version-2.0.0-blue.svg)
4
4
  ![Insitu Framework](https://img.shields.io/badge/insitu--framework-1.3.0-green.svg)
@@ -6,8 +6,6 @@
6
6
  ![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)
7
7
  ![Progress](https://img.shields.io/badge/roadmap-71%25-orange.svg)
8
8
 
9
- **✅ Fases 0-5 COMPLETADAS** - App Server funcional con Database Pools y Hot Reload.
10
-
11
9
  ---
12
10
 
13
11
  ## 🎯 ¿Qué es BlackCoffee?
@@ -23,6 +23,17 @@
23
23
  "password": "",
24
24
  "database": "otrack_db",
25
25
  "connectionLimit": 10
26
+ },
27
+ "otrack-db": {
28
+ "type": "mariadb",
29
+ "connected": false,
30
+ "host": "localhost",
31
+ "port": 3306,
32
+ "user": "root",
33
+ "password": "",
34
+ "database": "tracking",
35
+ "connectionLimit": 10,
36
+ "timezone": "Z"
26
37
  }
27
38
  }
28
39
  }
@@ -104,7 +104,8 @@ class AuthController {
104
104
  static async logout(req, res) {
105
105
  try {
106
106
  // Limpiar cookie de sesión
107
- res.setHeader('Set-Cookie', 'blackcoffee_admin_session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly');
107
+ const cookieName = process.env.ADMIN_COOKIE_NAME || 'blackcoffee_admin_session';
108
+ res.setHeader('Set-Cookie', `${cookieName}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly`);
108
109
 
109
110
  res.writeHead(200, { 'Content-Type': 'application/json' });
110
111
  res.end(JSON.stringify({
@@ -0,0 +1,75 @@
1
+ /**
2
+ * ViewHelper - Helper de BlackCoffee para renderizado de vistas
3
+ * Usa EJS como motor de plantillas
4
+ *
5
+ * Proporciona un método render personalizado que funciona con la estructura
6
+ * de aplicaciones de BlackCoffee (apps/{name}/{version}/views/)
7
+ *
8
+ * Uso en controladores:
9
+ * const ViewHelper = require('../../core/ViewHelper');
10
+ * ViewHelper.render(res, 'otrack/1-0-0/views/otrack/index', data);
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const ejs = require('ejs');
16
+
17
+ class ViewHelper {
18
+ /**
19
+ * Renderiza una vista con datos usando EJS
20
+ * @param {Object} res - Response object
21
+ * @param {string} viewPath - Ruta de la vista relativa a apps/
22
+ * @param {Object} data - Datos para pasar a la vista
23
+ * @param {number} statusCode - Código de estado HTTP (default: 200)
24
+ */
25
+ static render(res, viewPath, data = {}, statusCode = 200) {
26
+ try {
27
+ // Construir ruta completa: apps/{viewPath}.ejs o .html
28
+ const appsDir = path.join(__dirname, '..', 'apps');
29
+
30
+ // Intentar con extensión .ejs primero, luego .html
31
+ let fullPath = path.join(appsDir, `${viewPath}.ejs`);
32
+ if (!fs.existsSync(fullPath)) {
33
+ fullPath = path.join(appsDir, `${viewPath}.html`);
34
+ }
35
+
36
+ // Verificar si la vista existe
37
+ if (!fs.existsSync(fullPath)) {
38
+ throw new Error(`Vista no encontrada: ${fullPath}`);
39
+ }
40
+
41
+ // Leer el contenido de la vista
42
+ const template = fs.readFileSync(fullPath, 'utf8');
43
+
44
+ // Renderizar con EJS
45
+ const renderedHtml = ejs.render(template, data, {
46
+ filename: fullPath,
47
+ root: appsDir
48
+ });
49
+
50
+ // Enviar respuesta
51
+ res.writeHead(statusCode, { 'Content-Type': 'text/html; charset=utf-8' });
52
+ res.end(renderedHtml);
53
+
54
+ } catch (error) {
55
+ console.error(`[ViewHelper] Error renderizando ${viewPath}:`, error.message);
56
+
57
+ // Enviar página de error
58
+ res.writeHead(500, { 'Content-Type': 'text/html; charset=utf-8' });
59
+ res.end(`
60
+ <!DOCTYPE html>
61
+ <html>
62
+ <head><title>Error - ViewHelper</title></head>
63
+ <body style="font-family: monospace; padding: 2rem; background: #1a1a2e; color: #fff;">
64
+ <h1 style="color: #ff5252;">❌ Error de Vista</h1>
65
+ <p><strong>Vista:</strong> ${viewPath}</p>
66
+ <p><strong>Error:</strong> ${error.message}</p>
67
+ <pre style="background: rgba(0,0,0,0.3); padding: 1rem; border-radius: 5px; overflow-x: auto;">${error.stack}</pre>
68
+ </body>
69
+ </html>
70
+ `);
71
+ }
72
+ }
73
+ }
74
+
75
+ module.exports = ViewHelper;
package/core/hotReload.js CHANGED
@@ -219,7 +219,7 @@ class HotReloadManager {
219
219
 
220
220
  const appsDir = path.join(__dirname, '..', 'apps');
221
221
  const appPath = path.join(appsDir, appName, version);
222
- const packageJsonPath = path.join(appPath, 'package.json');
222
+ const manifestPath = path.join(appPath, 'manifest.json');
223
223
 
224
224
  try {
225
225
  // 1. Limpiar caché de módulos de la app
Binary file
Binary file
@@ -99,8 +99,8 @@ function authMiddleware() {
99
99
  */
100
100
  async function initAdminAuth(server) {
101
101
  const config = {
102
- cookieName: 'blackcoffee_admin_session',
103
- secret: process.env.SESSION_SECRET || 'blackcoffee-session-secret-change-in-production',
102
+ cookieName: process.env.ADMIN_COOKIE_NAME || 'blackcoffee_admin_session',
103
+ secret: process.env.ADMIN_SESSION_SECRET || process.env.SESSION_SECRET || 'blackcoffee-admin-session-secret-change-in-production',
104
104
  timeout: 3600000, // 1 hora
105
105
  secure: false, // Cambiar a true en producción con HTTPS
106
106
  httpOnly: true,
@@ -114,9 +114,11 @@ async function initAdminAuth(server) {
114
114
 
115
115
  // Registrar middleware de sesión PRIMERO
116
116
  server.use(sessionManager.middleware());
117
-
117
+
118
118
  server.sessionManager = sessionManager;
119
119
  console.log('🔐 Session Manager inicializado\n');
120
+ console.log(` Cookie: ${config.cookieName}`);
121
+ console.log(` Secret: ${config.secret.substring(0, 10)}...\n`);
120
122
 
121
123
  // ============================================
122
124
  // Rutas estáticas para CSS y JS (ANTES del middleware de auth)
@@ -26,7 +26,7 @@ function init(server, options = {}) {
26
26
 
27
27
  // Configuración por defecto
28
28
  const config = {
29
- cookieName: options.cookieName || 'blackcoffee_session',
29
+ cookieName: options.cookieName || process.env.SESSION_COOKIE_NAME || 'blackcoffee_session',
30
30
  secret: options.secret || process.env.SESSION_SECRET || 'blackcoffee-secret-change-in-production',
31
31
  timeout: options.timeout || parseInt(process.env.SESSION_TIMEOUT, 10) || 3600000, // 1 hora
32
32
  ...options
package/otrack.tar.gz ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blackcoffee2",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "A app server built with Insitu Framework",
5
5
  "main": "server.js",
6
6
  "author": "Benjamin Sanchez Cardenas <bytedogssyndicate@gmail.com>",
@@ -22,6 +22,7 @@
22
22
  "dependencies": {
23
23
  "better-sqlite3": "^12.6.2",
24
24
  "chokidar": "^5.0.0",
25
+ "ejs": "^4.0.1",
25
26
  "gtk3-node": "^1.3.0",
26
27
  "insitu-js": "^1.3.0"
27
28
  },
@@ -29,8 +29,8 @@ function register(server) {
29
29
  console.log('📦 Componente: Sesiones');
30
30
  const sessions = require('../includes/sessions');
31
31
  sessions.init(server, {
32
- cookieName: 'blackcoffee_session',
33
- timeout: 3600000, // 1 hora
32
+ cookieName: process.env.SESSION_COOKIE_NAME || 'blackcoffee_session',
33
+ timeout: parseInt(process.env.SESSION_TIMEOUT, 10) || 3600000, // 1 hora
34
34
  secret: process.env.SESSION_SECRET || 'cambia-esto-en-produccion'
35
35
  });
36
36
  console.log('');