/home/suroeste/public_html/payments.transportessuroeste.com/src/Services
NameSizeModeActions
ClientDatabaseService.php44440644editdlrm
EncryptionService.php38670644editdlrm
LogService.php96780644editdlrm
PaymentService.php283570644editdlrm
Edit: /home/suroeste/public_html/payments.transportessuroeste.com/src/Services/LogService.php (9678B)
100, 'INFO' => 200, 'WARNING' => 300, 'ERROR' => 400, 'CRITICAL' => 500]; private static int $minLevel = 200; public static function setMinLevel(string $level): void { self::$minLevel = self::LEVELS[strtoupper($level)] ?? 200; } public static function debug(string $channel, string $message, array $context = []): void { self::log('DEBUG', $channel, $message, $context); } public static function info(string $channel, string $message, array $context = []): void { self::log('INFO', $channel, $message, $context); } public static function warning(string $channel, string $message, array $context = []): void { self::log('WARNING', $channel, $message, $context); } public static function error(string $channel, string $message, array $context = []): void { self::log('ERROR', $channel, $message, $context); } public static function critical(string $channel, string $message, array $context = []): void { self::log('CRITICAL', $channel, $message, $context); } /** * Log de acceso a la API */ public static function access(string $method, string $uri, int $statusCode, float $responseTime = 0, ?string $clientId = null): void { $context = [ 'method' => $method, 'uri' => $uri, 'status_code' => $statusCode, 'response_time_ms' => round($responseTime, 2), 'client_id' => $clientId, 'ip_address' => self::getClientIp(), 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown', 'timestamp' => self::getMicrotime() ]; self::log('INFO', 'access', "{$method} {$uri} - {$statusCode}", $context); } /** * Log de transaccion para auditoria bancaria */ public static function transaction(string $transactionId, string $action, string $status, array $data = []): void { $context = [ 'transaction_id' => $transactionId, 'action' => $action, 'status' => $status, 'ip_address' => self::getClientIp(), 'timestamp' => self::getMicrotime(), 'data' => self::sanitize($data) ]; self::log('INFO', 'transactions', "TX {$transactionId}: {$action} - {$status}", $context); // Guardar en BD con todos los campos requeridos self::saveToDb('transaction_logs', [ 'log_uuid' => self::generateUuidV4(), 'log_type' => $action, 'action' => "{$action} - {$status}", 'ip_address' => self::getClientIp(), 'created_at' => date('Y-m-d H:i:s'), ]); } /** * Log de evento de seguridad */ public static function security(string $eventType, string $message, array $context = []): void { $data = array_merge([ 'event_type' => $eventType, 'source_ip' => self::getClientIp(), 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown', 'timestamp' => self::getMicrotime() ], $context); self::log('WARNING', 'security', $message, $data); // Guardar en BD con todos los campos requeridos self::saveToDb('security_events', [ 'event_uuid' => self::generateUuidV4(), 'event_type' => $eventType, 'severity' => self::classifySeverity($eventType), 'source_ip' => self::getClientIp(), 'description' => $message, 'created_at' => date('Y-m-d H:i:s'), ]); } /** * Log de auditoria */ public static function audit(string $action, string $entity, ?string $entityId = null, array $data = []): void { $context = [ 'action' => $action, 'entity_type' => $entity, 'entity_id' => $entityId, 'actor_ip' => self::getClientIp(), 'audit_uuid' => self::generateUuidV4(), 'created_at' => self::getMicrotime() ]; self::log('INFO', 'audit', "{$action} on {$entity}", array_merge($context, $data)); // Guardar en BD con todos los campos requeridos (incluye actor_type) self::saveToDb('audit_trail', [ 'audit_uuid' => $context['audit_uuid'], 'entity_type' => $entity, 'entity_id' => $entityId, 'action' => $action, 'actor_type' => $data['actor_type'] ?? 'system', 'actor_ip' => self::getClientIp(), 'created_at' => date('Y-m-d H:i:s'), ]); } private static function log(string $level, string $channel, string $message, array $context = []): void { if (self::LEVELS[$level] < self::$minLevel) return; $entry = [ 'timestamp' => self::getMicrotime(), 'level' => $level, 'channel' => $channel, 'message' => $message, 'context' => self::sanitize($context), 'request_id' => self::getRequestId() ]; self::writeToFile($channel, $entry); } private static function writeToFile(string $channel, array $entry): void { $path = LOG_CONFIG['path']; if (!is_dir($path)) mkdir($path, 0750, true); $file = $path . (LOG_CONFIG['channels'][$channel] ?? 'app.log'); $line = json_encode($entry, JSON_UNESCAPED_UNICODE) . PHP_EOL; file_put_contents($file, $line, FILE_APPEND | LOCK_EX); } private static function saveToDb(string $table, array $data): void { try { $validFields = match($table) { 'transaction_logs' => ['log_uuid', 'transaction_id', 'epayco_session_id', 'log_type', 'action', 'ip_address', 'created_at'], 'security_events' => ['event_uuid', 'event_type', 'severity', 'source_ip', 'description', 'created_at'], 'audit_trail' => ['audit_uuid', 'entity_type', 'entity_id', 'action', 'actor_type', 'actor_ip', 'created_at'], default => [] }; $filtered = array_intersect_key($data, array_flip($validFields)); if (!empty($filtered)) { Database::getInstance()->insert($table, $filtered); } } catch (\Exception $e) { // Log a archivo para poder diagnosticar fallos en BD $errorMsg = sprintf( "[%s] Audit DB Error on table '%s': %s | Data: %s", date('Y-m-d H:i:s'), $table, $e->getMessage(), json_encode($data, JSON_UNESCAPED_UNICODE) ); error_log($errorMsg); // Tambien escribir al canal de errores de la app self::writeToFile('errors', [ 'timestamp' => self::getMicrotime(), 'level' => 'ERROR', 'channel' => 'audit_db', 'message' => "Error guardando en {$table}: " . $e->getMessage(), 'context' => ['table' => $table, 'data_keys' => array_keys($data)], 'request_id' => self::getRequestId() ]); } } /** * Clasificar severidad segun tipo de evento */ private static function classifySeverity(string $eventType): string { return match($eventType) { 'sql_injection_attempt', 'xss_attempt', 'path_traversal' => 'critical', 'rate_limit_exceeded', 'auth_failure', 'webhook_blocked' => 'high', 'malicious_bot', 'invalid_signature' => 'medium', default => 'low' }; } /** * Generar UUID v4 sin dependencia de EncryptionService (evita recursion) */ private static function generateUuidV4(): string { $data = random_bytes(16); $data[6] = chr(ord($data[6]) & 0x0f | 0x40); $data[8] = chr(ord($data[8]) & 0x3f | 0x80); return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } private static function sanitize(array $data): array { $sensitive = ['password', 'secret', 'token', 'api_key', 'card_number', 'cvv', 'pin']; $result = []; foreach ($data as $key => $value) { $lower = strtolower($key); foreach ($sensitive as $s) { if (str_contains($lower, $s)) { $result[$key] = '***REDACTED***'; continue 2; } } $result[$key] = is_array($value) ? self::sanitize($value) : $value; } return $result; } private static function getMicrotime(): string { $mt = microtime(true); return date('Y-m-d H:i:s.', (int)$mt) . sprintf('%06d', ($mt - floor($mt)) * 1000000); } private static function getRequestId(): string { static $id = null; return $id ??= $_SERVER['HTTP_X_REQUEST_ID'] ?? bin2hex(random_bytes(16)); } public static function getClientIp(): string { foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'REMOTE_ADDR'] as $h) { if (!empty($_SERVER[$h])) { $ip = trim(explode(',', $_SERVER[$h])[0]); if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip; } } return '0.0.0.0'; } }