up
This commit is contained in:
+674
-40
@@ -2,22 +2,337 @@
|
||||
/**
|
||||
* Configuración del sistema WhatsApp Bot Manager
|
||||
* Desarrollado por U-Site.app
|
||||
* Fecha: 13 de noviembre de 2025
|
||||
* Fecha: 4 de enero de 2026 - Sistema de autenticación unificado
|
||||
*/
|
||||
|
||||
// Configuración de la base de datos (compatible con cPanel)
|
||||
define('DB_HOST', 'localhost');
|
||||
define('DB_HOST', '77.37.126.126');
|
||||
define('DB_PORT', '3306');
|
||||
define('DB_NAME', 'whatsapp_bot');
|
||||
define('DB_USER', 'whatsapp_user');
|
||||
define('DB_PASS', ''); // Se generará automáticamente en la instalación
|
||||
define('DB_NAME', 'usite_whatsapp_bot');
|
||||
define('DB_USER', 'usite_whatsapp_user');
|
||||
define('DB_PASS', '6q!Vio0fn@PFmsLyHjH5'); // Se generará automáticamente en la instalación
|
||||
define('DB_CHARSET', 'utf8mb4');
|
||||
|
||||
// WhatsApp Business API (se configurará después de la instalación)
|
||||
define('WHATSAPP_TOKEN', 'TU_TOKEN_DE_WHATSAPP_AQUI');
|
||||
define('WHATSAPP_PHONE_NUMBER_ID', 'TU_PHONE_ID_AQUI');
|
||||
define('WHATSAPP_API_URL', 'https://graph.facebook.com/v22.0/');
|
||||
define('WEBHOOK_VERIFY_TOKEN', 'mi_token_secreto_123');
|
||||
// Configuración de autenticación (LEGACY - migrado a BD)
|
||||
// NOTA: Esta constante se mantiene para retrocompatibilidad durante la migración
|
||||
// El sistema ahora usa autenticación basada en base de datos (admin_users table)
|
||||
define('ADMIN_PASSWORD', '$2y$10$IXCY8Sm1xFkfhC6Y67Ahn.QLHxE.sjWfmTEOKFZdCN2a9s9YLVuGW'); // password123
|
||||
|
||||
// Función para cargar archivo .env
|
||||
function loadEnvFile($path) {
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (strpos($line, '#') === 0 || strpos($line, '=') === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[$name, $value] = explode('=', $line, 2);
|
||||
$name = trim($name);
|
||||
$value = trim($value, " \t\n\r\0\x0B\"'");
|
||||
|
||||
if (!array_key_exists($name, $_ENV)) {
|
||||
$_ENV[$name] = $value;
|
||||
putenv("$name=$value");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Cargar .env si existe
|
||||
loadEnvFile(__DIR__ . '/../.env');
|
||||
|
||||
// Función helper para obtener variables de entorno
|
||||
function env($key, $default = null) {
|
||||
return $_ENV[$key] ?? getenv($key) ?: $default;
|
||||
}
|
||||
|
||||
// Función para verificar si la instalación está completada
|
||||
function isInstallationCompleted() {
|
||||
return file_exists(dirname(__DIR__) . '/.installation_completed');
|
||||
}
|
||||
|
||||
// Función para obtener configuración desde base de datos
|
||||
function getConfigFromDB($key, $default = null) {
|
||||
static $configs = null;
|
||||
global $config_cache_cleared;
|
||||
|
||||
if ($configs === null || $config_cache_cleared) {
|
||||
$config_cache_cleared = false;
|
||||
|
||||
if (isInstallationCompleted()) {
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]
|
||||
);
|
||||
|
||||
// Verificar si existe la tabla system_config
|
||||
$tableExists = $pdo->query("SHOW TABLES LIKE 'system_config'")->rowCount() > 0;
|
||||
|
||||
if ($tableExists) {
|
||||
$stmt = $pdo->query("SELECT config_key, config_value FROM system_config");
|
||||
$configs = [];
|
||||
while ($row = $stmt->fetch()) {
|
||||
$configs[$row['config_key']] = $row['config_value'];
|
||||
}
|
||||
} else {
|
||||
// Si no existe la tabla, usar valores por defecto
|
||||
$configs = [];
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
error_log("Error loading config: " . $e->getMessage());
|
||||
$configs = [];
|
||||
}
|
||||
} else {
|
||||
$configs = [];
|
||||
}
|
||||
}
|
||||
|
||||
return $configs[$key] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guarda una configuración en la base de datos
|
||||
* @param string $key Clave de configuración
|
||||
* @param mixed $value Valor de configuración
|
||||
* @param string $description Descripción opcional
|
||||
* @return bool True si se guardó correctamente
|
||||
*/
|
||||
function saveConfigToDB($key, $value, $description = null) {
|
||||
try {
|
||||
if (!isInstallationCompleted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pdo = createDbConnection();
|
||||
|
||||
// Crear tabla si no existe
|
||||
createSystemConfigTable($pdo);
|
||||
|
||||
// Verificar si ya existe la configuración
|
||||
$stmt = $pdo->prepare("SELECT id FROM system_config WHERE config_key = ?");
|
||||
$stmt->execute([$key]);
|
||||
$exists = $stmt->fetch();
|
||||
|
||||
if ($exists) {
|
||||
// Actualizar configuración existente
|
||||
$sql = "UPDATE system_config SET config_value = ?, updated_at = NOW()";
|
||||
$params = [$value];
|
||||
|
||||
if ($description !== null) {
|
||||
$sql .= ", description = ?";
|
||||
$params[] = $description;
|
||||
}
|
||||
|
||||
$sql .= " WHERE config_key = ?";
|
||||
$params[] = $key;
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$result = $stmt->execute($params);
|
||||
} else {
|
||||
// Insertar nueva configuración
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO system_config (config_key, config_value, description, created_at, updated_at)
|
||||
VALUES (?, ?, ?, NOW(), NOW())
|
||||
");
|
||||
$result = $stmt->execute([$key, $value, $description]);
|
||||
}
|
||||
|
||||
// Limpiar cache estático
|
||||
if ($result) {
|
||||
clearConfigCache();
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("Error guardando configuración '$key': " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Guarda múltiples configuraciones en una sola transacción
|
||||
* @param array $configs Array asociativo [key => value]
|
||||
* @return bool True si todas se guardaron correctamente
|
||||
*/
|
||||
function saveMultipleConfigsToDB($configs) {
|
||||
try {
|
||||
if (!isInstallationCompleted() || empty($configs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pdo = createDbConnection();
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// Crear tabla si no existe
|
||||
createSystemConfigTable($pdo);
|
||||
|
||||
$success = true;
|
||||
foreach ($configs as $key => $value) {
|
||||
// Verificar si ya existe
|
||||
$stmt = $pdo->prepare("SELECT id FROM system_config WHERE config_key = ?");
|
||||
$stmt->execute([$key]);
|
||||
$exists = $stmt->fetch();
|
||||
|
||||
if ($exists) {
|
||||
// Actualizar
|
||||
$stmt = $pdo->prepare("UPDATE system_config SET config_value = ?, updated_at = NOW() WHERE config_key = ?");
|
||||
$result = $stmt->execute([$value, $key]);
|
||||
} else {
|
||||
// Insertar
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO system_config (config_key, config_value, created_at, updated_at)
|
||||
VALUES (?, ?, NOW(), NOW())
|
||||
");
|
||||
$result = $stmt->execute([$key, $value]);
|
||||
}
|
||||
|
||||
if (!$result) {
|
||||
$success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
$pdo->commit();
|
||||
clearConfigCache();
|
||||
return true;
|
||||
} else {
|
||||
$pdo->rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
if (isset($pdo) && $pdo->inTransaction()) {
|
||||
$pdo->rollback();
|
||||
}
|
||||
error_log("Error guardando configuraciones múltiples: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene todas las configuraciones de la base de datos
|
||||
* @return array Array asociativo con todas las configuraciones
|
||||
*/
|
||||
function getAllConfigsFromDB() {
|
||||
try {
|
||||
if (!isInstallationCompleted()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$pdo = createDbConnection();
|
||||
|
||||
// Verificar si existe la tabla
|
||||
$tableExists = $pdo->query("SHOW TABLES LIKE 'system_config'")->rowCount() > 0;
|
||||
|
||||
if (!$tableExists) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$stmt = $pdo->query("
|
||||
SELECT config_key, config_value, description, created_at, updated_at
|
||||
FROM system_config
|
||||
ORDER BY config_key
|
||||
");
|
||||
|
||||
$configs = [];
|
||||
while ($row = $stmt->fetch()) {
|
||||
$configs[$row['config_key']] = [
|
||||
'value' => $row['config_value'],
|
||||
'description' => $row['description'],
|
||||
'created_at' => $row['created_at'],
|
||||
'updated_at' => $row['updated_at']
|
||||
];
|
||||
}
|
||||
|
||||
return $configs;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("Error obteniendo todas las configuraciones: " . $e->getMessage());
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina una configuración de la base de datos
|
||||
* @param string $key Clave de configuración a eliminar
|
||||
* @return bool True si se eliminó correctamente
|
||||
*/
|
||||
function deleteConfigFromDB($key) {
|
||||
try {
|
||||
if (!isInstallationCompleted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pdo = createDbConnection();
|
||||
$stmt = $pdo->prepare("DELETE FROM system_config WHERE config_key = ?");
|
||||
$result = $stmt->execute([$key]);
|
||||
|
||||
if ($result) {
|
||||
clearConfigCache();
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("Error eliminando configuración '$key': " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpia el cache estático de configuraciones
|
||||
*/
|
||||
function clearConfigCache() {
|
||||
// Necesitamos acceder a la variable estática de getConfigFromDB
|
||||
// Como no podemos modificar directamente variables estáticas de otra función,
|
||||
// establecemos una flag para que getConfigFromDB reinicie el cache
|
||||
global $config_cache_cleared;
|
||||
$config_cache_cleared = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crea la tabla system_config si no existe
|
||||
* @param PDO $pdo Conexión a la base de datos
|
||||
* @return bool True si se creó o ya existía
|
||||
*/
|
||||
function createSystemConfigTable($pdo) {
|
||||
try {
|
||||
$sql = "CREATE TABLE IF NOT EXISTS system_config (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
config_key VARCHAR(255) NOT NULL UNIQUE,
|
||||
config_value TEXT,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_config_key (config_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
|
||||
|
||||
return $pdo->exec($sql) !== false;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("Error creando tabla system_config: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// WhatsApp Business API (prioridad: BD > .env > default)
|
||||
define('WHATSAPP_TOKEN', getConfigFromDB('whatsapp_token', env('WHATSAPP_TOKEN', 'TU_TOKEN_DE_WHATSAPP_AQUI')));
|
||||
define('WHATSAPP_PHONE_NUMBER_ID', getConfigFromDB('whatsapp_phone_number_id', env('WHATSAPP_PHONE_NUMBER_ID', 'TU_PHONE_ID_AQUI')));
|
||||
define('WHATSAPP_API_URL', getConfigFromDB('whatsapp_api_url', env('WHATSAPP_API_URL', 'https://graph.facebook.com/v22.0/')));
|
||||
define('WEBHOOK_VERIFY_TOKEN', getConfigFromDB('webhook_verify_token', env('WEBHOOK_VERIFY_TOKEN', 'mi_token_secreto_123')));
|
||||
|
||||
// Configuración general
|
||||
define('APP_NAME', 'WhatsApp Bot System');
|
||||
@@ -33,8 +348,9 @@ define('DEVELOPER_SUPPORT', 'https://u-site.app/support');
|
||||
|
||||
// Configuración de seguridad
|
||||
define('INSTALLATION_LOCK', '.installation_completed'); // Archivo de bloqueo
|
||||
define('SECRET_KEY', 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
|
||||
define('ADMIN_USERNAME', 'admin'); // Usuario administrador por defecto
|
||||
define('ADMIN_PASSWORD', ''); // Se configurará en instalación
|
||||
// ADMIN_PASSWORD movido arriba como parte del sistema unificado (línea 18)
|
||||
define('SESSION_TIMEOUT', 1800); // 30 minutos
|
||||
define('MAX_LOGIN_ATTEMPTS', 3); // Intentos máximos de login
|
||||
define('LOGIN_LOCKOUT_TIME', 900); // 15 minutos de bloqueo tras fallos
|
||||
@@ -75,9 +391,126 @@ if (!defined('AUTO_DETECTED_URL')) {
|
||||
define('AUTO_DETECTED_URL', $protocol . $host . $path);
|
||||
}
|
||||
|
||||
// Función para verificar si la instalación está completada
|
||||
function isInstallationCompleted() {
|
||||
return file_exists(dirname(__DIR__) . '/.installation_completed');
|
||||
|
||||
// ========================================
|
||||
// SISTEMA DE AUTENTICACIÓN UNIFICADO
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Crea conexión a la base de datos
|
||||
* @return PDO
|
||||
*/
|
||||
function createDbConnection() {
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]
|
||||
);
|
||||
return $pdo;
|
||||
} catch (PDOException $e) {
|
||||
error_log("Error de conexión BD: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autentica un usuario usando la base de datos
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return array|false Datos del usuario o false si falla
|
||||
*/
|
||||
function authenticateUser($username, $password) {
|
||||
try {
|
||||
$pdo = createDbConnection();
|
||||
|
||||
// Primero verificar si existe la tabla admin_users
|
||||
$checkTable = $pdo->query("SHOW TABLES LIKE 'admin_users'");
|
||||
$tableExists = $checkTable->rowCount() > 0;
|
||||
|
||||
if ($tableExists) {
|
||||
// Sistema moderno: autenticación por BD
|
||||
$stmt = $pdo->prepare("SELECT * FROM admin_users WHERE username = ? AND is_active = 1");
|
||||
$stmt->execute([$username]);
|
||||
$admin = $stmt->fetch();
|
||||
|
||||
if ($admin && password_verify($password, $admin['password_hash'])) {
|
||||
// Actualizar último login
|
||||
$updateLogin = $pdo->prepare("UPDATE admin_users SET last_login = NOW() WHERE id = ?");
|
||||
$updateLogin->execute([$admin['id']]);
|
||||
|
||||
return [
|
||||
'id' => $admin['id'],
|
||||
'username' => $admin['username'],
|
||||
'full_name' => $admin['full_name'],
|
||||
'email' => $admin['email']
|
||||
];
|
||||
}
|
||||
} else {
|
||||
// Sistema legacy: usar constante ADMIN_PASSWORD
|
||||
if ($username === 'admin' && password_verify($password, ADMIN_PASSWORD)) {
|
||||
return [
|
||||
'id' => 1,
|
||||
'username' => 'admin',
|
||||
'full_name' => 'Administrador',
|
||||
'email' => 'admin@sistema.local'
|
||||
];
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log("Error en autenticación: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica si el sistema está migrado a BD
|
||||
* @return bool
|
||||
*/
|
||||
function isAuthSystemMigrated() {
|
||||
try {
|
||||
$pdo = createDbConnection();
|
||||
$checkTable = $pdo->query("SHOW TABLES LIKE 'admin_users'");
|
||||
return $checkTable->rowCount() > 0;
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene todos los administradores del sistema
|
||||
* @return array
|
||||
*/
|
||||
function getAdminUsers() {
|
||||
try {
|
||||
$pdo = createDbConnection();
|
||||
|
||||
if (isAuthSystemMigrated()) {
|
||||
$stmt = $pdo->query("SELECT * FROM admin_users ORDER BY created_at DESC");
|
||||
return $stmt->fetchAll();
|
||||
} else {
|
||||
// Sistema legacy: retornar admin por defecto
|
||||
return [[
|
||||
'id' => 1,
|
||||
'username' => 'admin',
|
||||
'full_name' => 'Administrador',
|
||||
'email' => 'admin@sistema.local',
|
||||
'is_active' => 1,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'last_login' => null
|
||||
]];
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log("Error obteniendo usuarios admin: " . $e->getMessage());
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Función para verificar login
|
||||
@@ -160,35 +593,222 @@ spl_autoload_register(function ($class) {
|
||||
}
|
||||
});
|
||||
|
||||
// Función para obtener configuración desde base de datos
|
||||
function getConfigFromDB($key, $default = null) {
|
||||
static $configs = null;
|
||||
|
||||
|
||||
/**
|
||||
* Guarda la configuración completa de WhatsApp
|
||||
* @param array $whatsappConfig Array con las configuraciones de WhatsApp
|
||||
* @return bool True si se guardó correctamente
|
||||
*/
|
||||
function saveWhatsAppConfigToDB($whatsappConfig) {
|
||||
$success = true;
|
||||
|
||||
if ($configs === null && isInstallationCompleted()) {
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]
|
||||
);
|
||||
|
||||
$stmt = $pdo->query("SELECT config_key, config_value FROM system_config");
|
||||
$configs = [];
|
||||
while ($row = $stmt->fetch()) {
|
||||
$configs[$row['config_key']] = $row['config_value'];
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
error_log("Error loading config: " . $e->getMessage());
|
||||
$configs = [];
|
||||
}
|
||||
// Mapear configuraciones de WhatsApp y guardar individualmente
|
||||
if (isset($whatsappConfig['token'])) {
|
||||
$success &= saveConfigToDB('whatsapp_token', $whatsappConfig['token']);
|
||||
}
|
||||
|
||||
return $configs[$key] ?? $default;
|
||||
if (isset($whatsappConfig['phone_number_id'])) {
|
||||
$success &= saveConfigToDB('whatsapp_phone_number_id', $whatsappConfig['phone_number_id']);
|
||||
}
|
||||
|
||||
if (isset($whatsappConfig['api_url'])) {
|
||||
$success &= saveConfigToDB('whatsapp_api_url', $whatsappConfig['api_url']);
|
||||
}
|
||||
|
||||
if (isset($whatsappConfig['webhook_verify_token'])) {
|
||||
$success &= saveConfigToDB('webhook_verify_token', $whatsappConfig['webhook_verify_token']);
|
||||
}
|
||||
|
||||
if (isset($whatsappConfig['business_name'])) {
|
||||
$success &= saveConfigToDB('business_name', $whatsappConfig['business_name']);
|
||||
}
|
||||
|
||||
if (isset($whatsappConfig['welcome_message'])) {
|
||||
$success &= saveConfigToDB('welcome_message', $whatsappConfig['welcome_message']);
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene toda la configuración de WhatsApp desde BD
|
||||
* @return array Configuración completa de WhatsApp
|
||||
*/
|
||||
function getWhatsAppConfigFromDB() {
|
||||
return [
|
||||
'token' => getConfigFromDB('whatsapp_token', ''),
|
||||
'phone_number_id' => getConfigFromDB('whatsapp_phone_number_id', ''),
|
||||
'api_url' => getConfigFromDB('whatsapp_api_url', 'https://graph.facebook.com/v22.0/'),
|
||||
'webhook_verify_token' => getConfigFromDB('webhook_verify_token', ''),
|
||||
'business_name' => getConfigFromDB('business_name', ''),
|
||||
'welcome_message' => getConfigFromDB('welcome_message', ''),
|
||||
'status' => validateWhatsAppConfigFromDB()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida la configuración de WhatsApp desde BD
|
||||
* @return array Estado de validación
|
||||
*/
|
||||
function validateWhatsAppConfigFromDB() {
|
||||
$token = getConfigFromDB('whatsapp_token', '');
|
||||
$phoneId = getConfigFromDB('whatsapp_phone_number_id', '');
|
||||
$webhookToken = getConfigFromDB('webhook_verify_token', '');
|
||||
|
||||
$errors = [];
|
||||
$warnings = [];
|
||||
|
||||
if (empty($token) || $token === 'TU_TOKEN_DE_WHATSAPP_AQUI') {
|
||||
$errors[] = 'Token de WhatsApp no configurado';
|
||||
}
|
||||
|
||||
if (empty($phoneId) || $phoneId === 'TU_PHONE_ID_AQUI') {
|
||||
$errors[] = 'Phone Number ID no configurado';
|
||||
} elseif ($phoneId === '858157464051987') {
|
||||
$warnings[] = 'Phone Number ID problemático detectado (858157464051987)';
|
||||
}
|
||||
|
||||
if (empty($webhookToken)) {
|
||||
$errors[] = 'Token de verificación del webhook no configurado';
|
||||
}
|
||||
|
||||
return [
|
||||
'valid' => empty($errors),
|
||||
'errors' => $errors,
|
||||
'warnings' => $warnings,
|
||||
'configured_fields' => [
|
||||
'token' => !empty($token) && $token !== 'TU_TOKEN_DE_WHATSAPP_AQUI',
|
||||
'phone_id' => !empty($phoneId) && $phoneId !== 'TU_PHONE_ID_AQUI',
|
||||
'webhook_token' => !empty($webhookToken)
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicializa configuraciones por defecto en la base de datos
|
||||
* @return bool True si se inicializaron correctamente
|
||||
*/
|
||||
function initializeDefaultConfigs() {
|
||||
$defaultConfigs = [
|
||||
// Configuración de WhatsApp
|
||||
'whatsapp_token' => env('WHATSAPP_TOKEN', 'TU_TOKEN_DE_WHATSAPP_AQUI'),
|
||||
'whatsapp_phone_number_id' => env('WHATSAPP_PHONE_NUMBER_ID', 'TU_PHONE_ID_AQUI'),
|
||||
'whatsapp_api_url' => env('WHATSAPP_API_URL', 'https://graph.facebook.com/v22.0/'),
|
||||
'webhook_verify_token' => env('WEBHOOK_VERIFY_TOKEN', 'mi_token_secreto_123'),
|
||||
|
||||
// Configuración de la aplicación
|
||||
'app_name' => 'WhatsApp Bot System',
|
||||
'app_version' => '1.0.0',
|
||||
'timezone' => 'America/Bogota',
|
||||
'developer_name' => 'U-Site.app',
|
||||
'developer_url' => 'https://u-site.app',
|
||||
'developer_email' => 'support@u-site.app',
|
||||
|
||||
// Configuración de logs y archivos
|
||||
'enable_logging' => '1',
|
||||
'log_level' => 'INFO',
|
||||
'upload_max_size' => '10485760',
|
||||
'allowed_file_types' => 'jpg,jpeg,png,gif,pdf,doc,docx',
|
||||
|
||||
// Configuración de seguridad
|
||||
'session_timeout' => '1800',
|
||||
'max_login_attempts' => '3',
|
||||
'login_lockout_time' => '900'
|
||||
];
|
||||
|
||||
return saveMultipleConfigsToDB($defaultConfigs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migra configuraciones desde constantes/archivos a la base de datos
|
||||
* @return bool True si la migración fue exitosa
|
||||
*/
|
||||
function migrateConfigsToDatabase() {
|
||||
try {
|
||||
writeLog('INFO', 'Iniciando migración de configuraciones a BD');
|
||||
|
||||
// Crear tabla si no existe
|
||||
$pdo = createDbConnection();
|
||||
if (!createSystemConfigTable($pdo)) {
|
||||
writeLog('ERROR', 'No se pudo crear la tabla system_config');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Migrar configuraciones actuales
|
||||
$success = initializeDefaultConfigs();
|
||||
|
||||
if ($success) {
|
||||
writeLog('INFO', 'Migración de configuraciones completada exitosamente');
|
||||
} else {
|
||||
writeLog('ERROR', 'Error durante la migración de configuraciones');
|
||||
}
|
||||
|
||||
return $success;
|
||||
|
||||
} catch (Exception $e) {
|
||||
writeLog('ERROR', 'Error crítico en migración de configuraciones: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Función para validar configuración de WhatsApp
|
||||
function validateWhatsAppConfig() {
|
||||
$errors = [];
|
||||
|
||||
if (WHATSAPP_TOKEN === 'TU_TOKEN_DE_WHATSAPP_AQUI' || empty(WHATSAPP_TOKEN)) {
|
||||
$errors[] = 'Token de WhatsApp no configurado';
|
||||
}
|
||||
|
||||
if (WHATSAPP_PHONE_NUMBER_ID === 'TU_PHONE_ID_AQUI' || empty(WHATSAPP_PHONE_NUMBER_ID)) {
|
||||
$errors[] = 'Phone Number ID de WhatsApp no configurado';
|
||||
}
|
||||
|
||||
// Detectar Phone Number ID problemático conocido
|
||||
if (WHATSAPP_PHONE_NUMBER_ID === '858157464051987') {
|
||||
$errors[] = '⚠️ PHONE NUMBER ID PROBLEMÁTICO: El ID 858157464051987 genera errores. <a href="fix_phone_number_id.php" class="alert-link"><strong>Corregir ahora</strong></a>';
|
||||
}
|
||||
|
||||
if (empty(WEBHOOK_VERIFY_TOKEN)) {
|
||||
$errors[] = 'Token de verificación del webhook no configurado';
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
// Función para logging centralizado
|
||||
function writeLog($level, $message, $context = []) {
|
||||
if (!ENABLE_LOGGING) return;
|
||||
|
||||
$logLevels = ['DEBUG' => 0, 'INFO' => 1, 'WARNING' => 2, 'ERROR' => 3];
|
||||
$currentLevel = $logLevels[LOG_LEVEL] ?? 1;
|
||||
|
||||
if (($logLevels[$level] ?? 1) < $currentLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
$contextStr = $context ? ' ' . json_encode($context) : '';
|
||||
$logMessage = "[$timestamp] [$level] $message$contextStr" . PHP_EOL;
|
||||
|
||||
$logDir = dirname(__DIR__) . '/logs';
|
||||
if (!is_dir($logDir)) {
|
||||
mkdir($logDir, 0755, true);
|
||||
}
|
||||
|
||||
file_put_contents($logDir . '/system.log', $logMessage, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
||||
// Crear directorios necesarios
|
||||
$requiredDirs = [
|
||||
dirname(__DIR__) . '/logs',
|
||||
dirname(__DIR__) . '/uploads'
|
||||
];
|
||||
|
||||
foreach ($requiredDirs as $dir) {
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializar sesión si no está activa
|
||||
@@ -208,4 +828,18 @@ if (isUserLoggedIn() && isset($_SESSION['last_activity'])) {
|
||||
if (isUserLoggedIn()) {
|
||||
$_SESSION['last_activity'] = time();
|
||||
}
|
||||
|
||||
// Función para verificar autenticación en APIs
|
||||
function requireAuthentication() {
|
||||
if (!isUserLoggedIn()) {
|
||||
http_response_code(401);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => 'No autorizado. Inicie sesión.',
|
||||
'redirect' => 'login.php'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user