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/private_html/api/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/api/get_track_data.php
<?php
require_once '../config/database.php';
require_once '../utils/audio_token.php';
session_start();

header('Content-Type: application/json');

$track_id = $_GET['id'] ?? null;
$user_id = $_SESSION['user_id'] ?? null;

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

try {
    $pdo = getDBConnection();
    
    // Check if track_votes table exists
    $votes_table_exists = false;
    try {
        $check_stmt = $pdo->query("SHOW TABLES LIKE 'track_votes'");
        $votes_table_exists = $check_stmt->rowCount() > 0;
    } catch (Exception $e) {
        $votes_table_exists = false;
    }
    
    // Get the specific track with all details
    if ($votes_table_exists) {
        $track_query = "
            SELECT 
                mt.*,
                u.name as artist_name,
                u.plan as artist_plan,
                COALESCE(tp.play_count, 0) as play_count,
                COALESCE(tl.like_count, 0) as like_count,
                COALESCE(tv.vote_count, 0) as vote_count,
                CASE WHEN tl_user.track_id IS NOT NULL THEN 1 ELSE 0 END as user_liked,
                tv_user.vote_type as user_vote
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) tp ON mt.id = tp.track_id
            LEFT JOIN (SELECT track_id, COUNT(*) as like_count FROM track_likes GROUP BY track_id) tl ON mt.id = tl.track_id
            LEFT JOIN (
                SELECT 
                    track_id, 
                    SUM(CASE WHEN vote_type = 'up' THEN 1 ELSE -1 END) as vote_count
                FROM track_votes 
                GROUP BY track_id
            ) tv ON mt.id = tv.track_id
            LEFT JOIN track_likes tl_user ON mt.id = tl_user.track_id AND tl_user.user_id = ?
            LEFT JOIN track_votes tv_user ON mt.id = tv_user.track_id AND tv_user.user_id = ?
            WHERE mt.id = ? AND mt.status = 'complete'
        ";
        $stmt = $pdo->prepare($track_query);
        $stmt->execute([$user_id, $user_id, $track_id]);
    } else {
        $track_query = "
            SELECT 
                mt.*,
                u.name as artist_name,
                u.plan as artist_plan,
                COALESCE(tp.play_count, 0) as play_count,
                COALESCE(tl.like_count, 0) as like_count,
                0 as vote_count,
                CASE WHEN tl_user.track_id IS NOT NULL THEN 1 ELSE 0 END as user_liked,
                NULL as user_vote
            FROM music_tracks mt
            JOIN users u ON mt.user_id = u.id
            LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) tp ON mt.id = tp.track_id
            LEFT JOIN (SELECT track_id, COUNT(*) as like_count FROM track_likes GROUP BY track_id) tl ON mt.id = tl.track_id
            LEFT JOIN track_likes tl_user ON mt.id = tl_user.track_id AND tl_user.user_id = ?
            WHERE mt.id = ? AND mt.status = 'complete'
        ";
        $stmt = $pdo->prepare($track_query);
        $stmt->execute([$user_id, $track_id]);
    }
    
    $track = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$track) {
        echo json_encode(['success' => false, 'error' => 'Track not found']);
        exit;
    }
    
    // SECURITY: Check if track is private and user has access
    // Only the track owner can view private tracks, OR users with a valid share token
    $isOwner = ($user_id && $track['user_id'] == $user_id);
    $isPublic = ($track['is_public'] == 1 || $track['is_public'] === null);
    
    // Check for share token
    $share_token = $_GET['share'] ?? '';
    $hasValidShareToken = false;
    
    if (!empty($share_token) && !$isPublic) {
        require_once __DIR__ . '/../utils/share_token.php';
        $hasValidShareToken = isValidShareToken($track_id, $share_token);
    }
    
    // If track is private, check access
    if (!$isPublic) {
        if (!$isOwner && !$hasValidShareToken) {
            // User is not the owner and doesn't have a valid share token - deny access
            echo json_encode(['success' => false, 'error' => 'Access denied. This track is private.']);
            exit;
        }
    }
    
    // Check if this is a variation and get the main track title
    $display_title = $track['title'];
    if (!empty($track['task_id'])) {
        $main_track_query = "
            SELECT id, title 
            FROM music_tracks 
            WHERE task_id = ? AND status = 'complete' 
            ORDER BY created_at ASC, id ASC 
            LIMIT 1
        ";
        $main_track_stmt = $pdo->prepare($main_track_query);
        $main_track_stmt->execute([$track['task_id']]);
        $main_track = $main_track_stmt->fetch(PDO::FETCH_ASSOC);
        
        // If main track exists and is different from current track, use main track's title
        if ($main_track && $main_track['id'] != $track['id'] && !empty($main_track['title'])) {
            $display_title = $main_track['title'];
        }
    }
    
    // Get all variations for this track (CRITICAL FIX: fetch ALL variations, not just one)
    $trackVariations = [];
    if ($track['variations_count'] > 0) {
        try {
            $var_stmt = $pdo->prepare("
                SELECT 
                    variation_index,
                    audio_url,
                    duration,
                    title,
                    tags,
                    image_url,
                    source_audio_url
                FROM audio_variations 
                WHERE track_id = ? 
                ORDER BY variation_index ASC
            ");
            $var_stmt->execute([$track_id]);
            $trackVariations = $var_stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error getting variations for track {$track_id} in get_track_data.php: " . $e->getMessage());
            $trackVariations = [];
        }
    }
    
    // CRITICAL SECURITY: Sanitize audio URLs before returning
    // Replace raw audio_url with signed URL that requires token validation
    $signedAudioUrl = getSignedAudioUrl($track['id']);
    
    // Sanitize variations - remove raw audio URLs
    $sanitizedVariations = [];
    foreach ($trackVariations as $var) {
        $sanitizedVar = $var;
        // Replace raw audio_url with signed URL
        if (isset($var['variation_index'])) {
            $sanitizedVar['audio_url'] = getSignedAudioUrl($track['id'], $var['variation_index']);
        } else {
            $sanitizedVar['audio_url'] = $signedAudioUrl; // Fallback to main track signed URL
        }
        // Remove source URLs
        unset($sanitizedVar['source_audio_url']);
        $sanitizedVariations[] = $sanitizedVar;
    }
    
    // Parse metadata for BPM/key
    $metadata = json_decode($track['metadata'] ?? '{}', true) ?: [];
    
    // Return track data with all variations
    echo json_encode([
        'success' => true,
        'track' => [
            'id' => $track['id'],
            'title' => $display_title,
            'artist_name' => $track['artist_name'],
            'user_id' => $track['user_id'],
            'prompt' => $track['prompt'],
            'audio_url' => $signedAudioUrl, // Use signed URL instead of raw path
            'signed_audio_url' => $signedAudioUrl, // Explicit signed URL field
            'image_url' => $track['image_url'],
            'duration' => $track['duration'],
            'play_count' => $track['play_count'],
            'like_count' => $track['like_count'],
            'vote_count' => $track['vote_count'] ?? 0,
            'user_liked' => $track['user_liked'],
            'user_vote' => $track['user_vote'] ?? null,
            'variations_count' => $track['variations_count'] ?? 0,
            'variations' => $sanitizedVariations, // Sanitized variations
            'metadata' => $metadata // Include metadata for BPM/key updates
        ]
    ]);
    
} catch (Exception $e) {
    error_log("Track data API error: " . $e->getMessage());
    echo json_encode(['success' => false, 'error' => 'Internal server error']);
}
?> 

CasperSecurity Mini