This commit is contained in:
Lizandro Guarnizo
2026-03-10 18:42:51 -05:00
parent b57fc16ab3
commit db469b2134
98 changed files with 16365 additions and 303 deletions
+109 -7
View File
@@ -18,6 +18,23 @@ define('DB_CHARSET', 'utf8mb4');
// El sistema ahora usa autenticación basada en base de datos (admin_users table)
define('ADMIN_PASSWORD', '$2y$10$IXCY8Sm1xFkfhC6Y67Ahn.QLHxE.sjWfmTEOKFZdCN2a9s9YLVuGW'); // password123
// ── Módulos del sistema ──────────────────────────────────────────────────────
// Catálogo de todos los módulos disponibles para asignar a los roles.
// Clave: slug interno · Valor: etiqueta legible para la UI.
define('SYSTEM_MODULES', [
'whatsapp' => 'WhatsApp Bot',
'lab_dashboard' => 'Dashboard Lab',
'lab_ordenes' => 'Órdenes Médicas',
'lab_pacientes' => 'Pacientes',
'lab_domicilios' => 'Domicilios',
'lab_enfermeras' => 'Enfermeras',
'lab_formularios' => 'Formularios',
'lab_reportes' => 'Reportes',
'lab_configuracion' => 'Configuración Lab',
'usuarios' => 'Gestión de Usuarios',
'enfermero_portal' => 'Portal Enfermero',
]);
// Función para cargar archivo .env
if (!function_exists('loadEnvFile')) {
function loadEnvFile($path) {
@@ -355,8 +372,13 @@ define('WEBHOOK_VERIFY_TOKEN', getConfigFromDB('webhook_verify_token', env('WEBH
// Configuración general
define('APP_NAME', 'WhatsApp Bot System');
define('APP_VERSION', '1.0.0');
define('APP_URL', 'https://tudominio.com'); // Se auto-detectará
define('APP_VERSION', '2.0.0');
// URL auto-detectada según protocolo y host actuales
if (!defined('APP_URL')) {
$__proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$__host = $_SERVER['HTTP_HOST'] ?? 'localhost';
define('APP_URL', $__proto . '://' . $__host);
}
define('TIMEZONE', 'America/Bogota');
// Información del desarrollador
@@ -462,12 +484,30 @@ function authenticateUser($username, $password) {
// Actualizar último login
$updateLogin = $pdo->prepare("UPDATE admin_users SET last_login = NOW() WHERE id = ?");
$updateLogin->execute([$admin['id']]);
// Cargar módulos del rol
$modules = [];
$roleSlug = $admin['role'] ?? 'admin';
if (!empty($admin['role_id'])) {
$modStmt = $pdo->prepare("SELECT module_slug FROM role_modules WHERE role_id = ?");
$modStmt->execute([$admin['role_id']]);
$modules = array_column($modStmt->fetchAll(PDO::FETCH_ASSOC), 'module_slug');
} elseif ($roleSlug === 'admin') {
// Fallback: admin sin role_id tiene todos los módulos
$modules = array_keys(SYSTEM_MODULES);
} elseif ($roleSlug === 'enfermero') {
$modules = ['enfermero_portal', 'lab_formularios'];
}
return [
'id' => $admin['id'],
'username' => $admin['username'],
'full_name' => $admin['full_name'],
'email' => $admin['email']
'id' => $admin['id'],
'username' => $admin['username'],
'full_name' => $admin['full_name'],
'email' => $admin['email'],
'role' => $roleSlug,
'role_id' => $admin['role_id'] ?? null,
'enfermera_id' => $admin['enfermera_id'] ?? null,
'modules' => $modules,
];
}
} else {
@@ -534,6 +574,58 @@ function getAdminUsers() {
// Función para verificar login
if (!function_exists('isUserLoggedIn')) {
/**
* Verifica si el usuario autenticado tiene el rol indicado.
*/
function userHasRole(string $role): bool {
return isset($_SESSION['admin_user']['role']) && $_SESSION['admin_user']['role'] === $role;
}
/**
* Verdadero si el usuario es enfermero.
*/
function isEnfermero(): bool {
return userHasRole('enfermero');
}
/**
* Devuelve el ID de enfermera del usuario en sesión, o null si no aplica.
*/
function enfermeraId(): ?int {
$id = $_SESSION['admin_user']['enfermera_id'] ?? null;
return $id ? (int)$id : null;
}
/**
* Comprueba si el usuario en sesión tiene acceso al módulo indicado.
* Los administradores sin modules cargados tienen acceso total (retrocompat.).
*/
function hasModule(string $slug): bool {
$modules = $_SESSION['admin_user']['modules'] ?? null;
// Si no hay módulos en sesión (usuario legacy) y es admin → acceso total
if ($modules === null) {
return userHasRole('admin');
}
return in_array($slug, $modules, true);
}
/**
* Detiene la ejecución si el usuario no tiene el rol requerido.
*/
function requireRole(string $role): void {
if (!isUserLoggedIn()) {
header('Location: login.php');
exit;
}
if (!userHasRole($role)) {
http_response_code(403);
// Redirigir al portal correcto
$destino = userHasRole('enfermero') ? 'enfermero_portal.php' : 'index.php';
header("Location: $destino");
exit;
}
}
function isUserLoggedIn() {
return isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true;
}
@@ -658,6 +750,14 @@ function saveWhatsAppConfigToDB($whatsappConfig) {
if (isset($whatsappConfig['welcome_message'])) {
$success &= saveConfigToDB('welcome_message', $whatsappConfig['welcome_message']);
}
if (isset($whatsappConfig['terms_message'])) {
$success &= saveConfigToDB('terms_message', $whatsappConfig['terms_message']);
}
if (isset($whatsappConfig['terms_rejected_message'])) {
$success &= saveConfigToDB('terms_rejected_message', $whatsappConfig['terms_rejected_message']);
}
return $success;
}
@@ -694,6 +794,8 @@ function getWhatsAppConfigFromDB() {
'webhook_verify_token' => $webhookToken,
'business_name' => getConfigFromDB('business_name', ''),
'welcome_message' => getConfigFromDB('welcome_message', ''),
'terms_message' => getConfigFromDB('terms_message', ''),
'terms_rejected_message' => getConfigFromDB('terms_rejected_message', ''),
'status' => validateWhatsAppConfigFromDB()
];
}