T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/soundstudiopro.com/public_html/api/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/api/check_track_status.php
<?php
session_start();
header('Content-Type: application/json');

// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
    echo json_encode([
        'success' => false,
        'message' => 'User not logged in'
    ]);
    exit;
}

// SECURITY: Validate and sanitize track_id parameter
$track_id_raw = $_GET['track_id'] ?? null;

if (!$track_id_raw) {
    echo json_encode([
        'success' => false,
        'message' => 'Track ID required'
    ]);
    exit;
}

// SECURITY: Validate that track_id is a positive integer
if (!is_numeric($track_id_raw) || (int)$track_id_raw <= 0) {
    error_log("SECURITY: Invalid track_id attempt in check_track_status.php: " . htmlspecialchars($track_id_raw, ENT_QUOTES, 'UTF-8'));
    echo json_encode([
        'success' => false,
        'message' => 'Invalid track ID'
    ]);
    exit;
}

$track_id = (int)$track_id_raw;

try {
    require_once '../config/database.php';
    $pdo = getDBConnection();
    
    // Get track from database
    $stmt = $pdo->prepare("
        SELECT id, title, prompt, status, audio_url, duration, created_at, api_task_id, task_id, metadata
        FROM music_tracks 
        WHERE id = ? AND user_id = ?
    ");
    $stmt->execute([$track_id, $_SESSION['user_id']]);
    $track = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$track) {
        echo json_encode([
            'success' => false,
            'message' => 'Track not found'
        ]);
        exit;
    }
    
    // Extract error message from metadata if track is failed
    $error_message = null;
    if ($track['status'] === 'failed' && !empty($track['metadata'])) {
        $metadata = json_decode($track['metadata'], true);
        if ($metadata) {
            $raw_message = $metadata['msg'] ?? 
                           $metadata['error'] ?? 
                           $metadata['error_msg'] ?? 
                           $metadata['message'] ?? 
                           null;
            
            // Format error message - ONLY remove API.Box references, keep exact error
            if ($raw_message) {
                // Remove any references to API.Box or supplier names ONLY
                $raw_message = preg_replace('/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/i', '', $raw_message);
                $raw_message = trim($raw_message);
                // Clean up multiple spaces
                $raw_message = preg_replace('/\s+/', ' ', $raw_message);
                
                // Check if this is actually a success message (not an error)
                $is_success_message = preg_match('/\b(successfully|success|complete|done|ready|finished)\b/i', $raw_message);
                
                // Only treat as error if it's NOT a success message
                if (!$is_success_message && !empty($raw_message)) {
                    $error_message = $raw_message;
                }
                // If it's a success message, leave $error_message as null (don't show anything)
                
                // Special handling for timeout errors (override any previous assignment)
                if (isset($metadata['code']) && $metadata['code'] == 408) {
                    $error_message = "Track generation timed out after 5 minutes. Please try again.";
                }
            }
            
            // If no error message found and track is failed, use default
            // But only if we didn't find a success message (which would leave $error_message as null)
            if ($error_message === null && empty($raw_message ?? null) && $track['status'] === 'failed') {
                $error_message = "Track generation failed. Please try again.";
            }
        }
    }
    
    // If track is processing and has API task ID, ALWAYS check service status
    // This ensures we catch failures even if callback wasn't received
    $task_id_to_check = $track['task_id'] ?? $track['api_task_id'] ?? null;
    $force_check = isset($_GET['force_check']) && $_GET['force_check'] == '1';
    
    if (($track['status'] === 'processing' || $force_check) && !empty($task_id_to_check) && $task_id_to_check !== 'unknown' && !str_starts_with($task_id_to_check, 'temp_') && !str_starts_with($task_id_to_check, 'retry_')) {
        $api_key = '63edba40620216c5aa2c04240ac41dbd';
        $api_url = 'https://api.api.box/api/v1/status/' . $task_id_to_check;
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $api_url);
        curl_setopt($ch, CURLOPT_HTTPGET, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $api_key,
            'Content-Type: application/json',
            'User-Agent: SoundStudioPro/1.0'
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($http_code === 200 && $response) {
            $api_data = json_decode($response, true);
            
            if ($api_data) {
                // Check for error codes first (most reliable indicator)
                $has_error_code = isset($api_data['code']) && ($api_data['code'] == 400 || $api_data['code'] == 531 || $api_data['code'] >= 400);
                $has_error_message = !empty($api_data['error']) || !empty($api_data['msg']) || !empty($api_data['error_msg']);
                $api_status = $api_data['status'] ?? null;
                
                // Determine if this is a failure
                $is_failed = false;
                $api_error_msg = null;
                $error_code = null;
                
                if ($has_error_code) {
                    $is_failed = true;
                    $error_code = $api_data['code'];
                    $api_error_msg = $api_data['msg'] ?? $api_data['error'] ?? $api_data['error_msg'] ?? 'Generation failed';
                } elseif ($api_status === 'failed' || $api_status === 'error' || $api_status === 'rejected') {
                    $is_failed = true;
                    $api_error_msg = $api_data['error'] ?? $api_data['msg'] ?? $api_data['error_msg'] ?? 'Generation failed';
                    $error_code = $api_data['code'] ?? 531;
                } elseif ($has_error_message && ($api_status === null || $api_status === 'processing')) {
                    // If we have an error message but status is still processing, it likely failed
                    // Check if there's a clear error indicator
                    $temp_error_msg = $api_data['error'] ?? $api_data['msg'] ?? $api_data['error_msg'] ?? '';
                    $error_text = strtolower($temp_error_msg);
                    if (strpos($error_text, 'failed') !== false || 
                        strpos($error_text, 'error') !== false || 
                        strpos($error_text, 'violation') !== false ||
                        strpos($error_text, 'rejected') !== false ||
                        strpos($error_text, 'contained artist name') !== false ||
                        strpos($error_text, 'song description') !== false) {
                        $is_failed = true;
                        $api_error_msg = $temp_error_msg ?: 'Generation failed';
                        $error_code = $api_data['code'] ?? 400; // Default to 400 for content violations
                    }
                }
                
                // Also check for content violation patterns in the response
                if (!$is_failed && !empty($api_data['msg'])) {
                    $msg_lower = strtolower($api_data['msg']);
                    if (strpos($msg_lower, 'contained artist name') !== false ||
                        strpos($msg_lower, 'song description') !== false ||
                        strpos($msg_lower, 'content violation') !== false) {
                        $is_failed = true;
                        $api_error_msg = $api_data['msg'];
                        $error_code = 400; // Content violation
                    }
                }
                
                // Map API.Box status to our status
                $new_status = $track['status']; // Default to current status
                
                if ($is_failed) {
                    $new_status = 'failed';
                    
                    // Extract error message from API response
                    if (!$api_error_msg) {
                        $api_error_msg = $api_data['error'] ?? $api_data['msg'] ?? $api_data['error_msg'] ?? 'Generation failed';
                    }
                    
                    // Sanitize error message - remove any references to API.Box or supplier names
                    $api_error_msg = preg_replace('/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/i', '', $api_error_msg);
                    $api_error_msg = trim($api_error_msg);
                    if (empty($api_error_msg)) {
                        $api_error_msg = 'Generation failed';
                    }
                    
                    $error_metadata = json_encode([
                        'code' => $error_code ?? 531,
                        'msg' => $api_error_msg,
                        'error_type' => ($error_code == 400) ? 'content_violation' : 'generation_failed',
                        'data' => $api_data,
                        'timestamp' => date('Y-m-d H:i:s'),
                        'detected_via' => 'status_check'
                    ]);
                    
                    // Update database with failed status and error metadata
                    $update_stmt = $pdo->prepare("
                        UPDATE music_tracks 
                        SET status = ?, metadata = ?, updated_at = NOW()
                        WHERE id = ?
                    ");
                    $update_stmt->execute([$new_status, $error_metadata, $track_id]);
                    
                    // Refund credit for failed track
                    $refund_stmt = $pdo->prepare("UPDATE users SET credits = credits + 1 WHERE id = ?");
                    $refund_stmt->execute([$_SESSION['user_id']]);
                    
                    // Record refund transaction (check if already exists)
                    $check_stmt = $pdo->prepare("SELECT COUNT(*) FROM credit_transactions WHERE user_id = ? AND type = 'refund' AND description LIKE ?");
                    $check_stmt->execute([$_SESSION['user_id'], "%Track failed: {$track_id}%"]);
                    if ($check_stmt->fetchColumn() == 0) {
                        $trans_stmt = $pdo->prepare("
                            INSERT INTO credit_transactions (user_id, amount, type, description, created_at) 
                            VALUES (?, 1, 'refund', 'Track failed: {$track_id}', NOW())
                        ");
                        $trans_stmt->execute([$_SESSION['user_id']]);
                    }
                    
                    $track['status'] = $new_status;
                    $track['metadata'] = $error_metadata;
                    $error_message = $api_error_msg;
                    
                    error_log("✅ Track $track_id marked as FAILED via status check. Error: $api_error_msg (Code: " . ($error_code ?? 'N/A') . ")");
                    
                } elseif ($api_status === 'completed' || $api_status === 'complete') {
                    // Check if we have audio URL or complete metadata
                    $audioUrl = $api_data['result']['audio_url'] ?? 
                               $api_data['data']['data'][0]['audio_url'] ?? 
                               $api_data['data']['data'][0]['source_audio_url'] ?? 
                               $api_data['data']['data'][0]['stream_audio_url'] ?? null;
                    
                    // Extract metadata to check if track is ready
                    $title = $api_data['result']['title'] ?? 
                            $api_data['data']['data'][0]['title'] ?? 
                            $api_data['title'] ?? null;
                    $duration = $api_data['result']['duration'] ?? 
                               $api_data['data']['data'][0]['duration'] ?? 
                               $api_data['duration'] ?? null;
                    $tags = $api_data['result']['tags'] ?? 
                           $api_data['data']['data'][0]['tags'] ?? 
                           $api_data['tags'] ?? null;
                    $modelName = $api_data['result']['model_name'] ?? 
                               $api_data['data']['data'][0]['model_name'] ?? 
                               $api_data['model_name'] ?? null;
                    
                    // Mark as complete if we have audio URL OR complete metadata (matching callback logic)
                    $hasAudio = !empty($audioUrl);
                    $hasCompleteMetadata = !empty($title) && !empty($duration) && (!empty($tags) || !empty($modelName));
                    
                    if ($hasAudio || $hasCompleteMetadata) {
                        $new_status = 'complete';
                        
                        // Update database with new status
                        $update_stmt = $pdo->prepare("
                            UPDATE music_tracks 
                            SET status = ?, updated_at = NOW()
                            " . ($hasAudio ? ", audio_url = ?, duration = ?" : "") . "
                            WHERE id = ?
                        ");
                        
                        if ($hasAudio) {
                            $update_stmt->execute([
                                $new_status,
                                $audioUrl,
                                $duration,
                                $track_id
                            ]);
                            $track['audio_url'] = $audioUrl;
                            $track['duration'] = $duration;
                        } else {
                            $update_stmt->execute([
                                $new_status,
                                $track_id
                            ]);
                        }
                        
                        $track['status'] = $new_status;
                        
                        error_log("✅ Track $track_id marked as COMPLETE via status check. Has audio: " . ($hasAudio ? 'YES' : 'NO') . ", Has metadata: " . ($hasCompleteMetadata ? 'YES' : 'NO'));
                    }
                }
                
                // Log the status check
                error_log("Track $track_id: Service status = " . ($api_status ?? 'N/A') . ", Local status = $new_status, Has error code = " . ($has_error_code ? 'YES' : 'NO'));
            } else {
                error_log("⚠️ Track $track_id: Service returned invalid JSON response");
            }
        } else {
            error_log("Service check failed for track $track_id: HTTP $http_code" . ($response ? " - Response: " . substr($response, 0, 200) : ""));
            
            // If API check failed but track is still processing, check task_results file
            if ($track['status'] === 'processing' && !empty($task_id_to_check)) {
                $taskResultFile = "../task_results/{$task_id_to_check}.json";
                if (file_exists($taskResultFile)) {
                    $taskResultData = json_decode(file_get_contents($taskResultFile), true);
                    if ($taskResultData) {
                        // Check if we have audio URL or complete metadata in task_results
                        $audioUrl = null;
                        $title = null;
                        $duration = null;
                        $tags = null;
                        $modelName = null;
                        
                        if (isset($taskResultData['data']['data']) && is_array($taskResultData['data']['data'])) {
                            foreach ($taskResultData['data']['data'] as $item) {
                                if (!$audioUrl) {
                                    $audioUrl = (!empty($item['audio_url'])) ? $item['audio_url'] : 
                                               ((!empty($item['source_audio_url'])) ? $item['source_audio_url'] : 
                                               ((!empty($item['stream_audio_url'])) ? $item['stream_audio_url'] : null));
                                }
                                if (!$title && !empty($item['title'])) {
                                    $title = $item['title'];
                                }
                                if (!$duration && !empty($item['duration'])) {
                                    $duration = $item['duration'];
                                }
                                if (!$tags && !empty($item['tags'])) {
                                    $tags = $item['tags'];
                                }
                                if (!$modelName && !empty($item['model_name'])) {
                                    $modelName = $item['model_name'];
                                }
                            }
                        }
                        
                        // Mark as complete if we have audio URL OR complete metadata
                        $hasAudio = !empty($audioUrl);
                        $hasCompleteMetadata = !empty($title) && !empty($duration) && (!empty($tags) || !empty($modelName));
                        
                        if ($hasAudio || $hasCompleteMetadata) {
                            $new_status = 'complete';
                            
                            $update_stmt = $pdo->prepare("
                                UPDATE music_tracks 
                                SET status = ?, updated_at = NOW()
                                " . ($hasAudio ? ", audio_url = ?, duration = ?" : "") . "
                                WHERE id = ?
                            ");
                            
                            if ($hasAudio) {
                                $update_stmt->execute([
                                    $new_status,
                                    $audioUrl,
                                    $duration,
                                    $track_id
                                ]);
                                $track['audio_url'] = $audioUrl;
                                $track['duration'] = $duration;
                            } else {
                                $update_stmt->execute([
                                    $new_status,
                                    $track_id
                                ]);
                            }
                            
                            $track['status'] = $new_status;
                            error_log("✅ Track $track_id marked as COMPLETE via task_results check. Has audio: " . ($hasAudio ? 'YES' : 'NO') . ", Has metadata: " . ($hasCompleteMetadata ? 'YES' : 'NO'));
                        }
                    }
                }
            }
        }
    }
    
    // Prepare response data
    $response_data = $track;
    if ($error_message) {
        $response_data['error_message'] = $error_message;
    }
    
    echo json_encode([
        'success' => true,
        'status' => $track['status'],
        'data' => $response_data
    ]);
    
} catch (Exception $e) {
    error_log("Track status check error: " . $e->getMessage());
    echo json_encode([
        'success' => false,
        'message' => 'Database error occurred'
    ]);
}
?> 

CasperSecurity Mini