BROOKO icon
BROOKO UK NETWORK
Where code meets creativity & adventure
File viewer

changelog_api.php

Type
php
Size
2.53 KB
Modified
15 May
changelog_api.php 2.53 KB
<?php
require_once __DIR__ . '/../bootstrap.php';
requireAuth();

header('Content-Type: application/json; charset=utf-8');

$version = trim($_GET['v'] ?? '');
if ($version === '') {
    echo json_encode(['ok' => false, 'error' => 'Missing version']);
    exit;
}

// Strict version format to avoid path traversal.
if (!preg_match('/^[0-9]+\.[0-9]+\.[0-9]+(?:-[A-Za-z0-9._-]+)?$/', $version)) {
    echo json_encode(['ok' => false, 'error' => 'Invalid version']);
    exit;
}



$logDir = realpath(__DIR__ . '/../assets/changelog');
if (!$logDir || !is_dir($logDir)) {
    echo json_encode(['ok' => false, 'error' => 'Changelog folder not found']);
    exit;
}

$filename = 'update_log_' . $version . '.md';

// Preferred: read from single archive
$archive = $logDir . '/updates.zip';
if (is_readable($archive)) {
    $zip = class_exists('ZipArchive') ? new ZipArchive() : null;
    if ($zip && $zip->open($archive) === true) {
        $content = $zip->getFromName($filename);
        $stat = $zip->statName($filename);
        $zip->close();
        if ($content !== false) {
            $content = str_replace("
", "
", (string)$content);
            if (strlen($content) > 200000) {
                $content = substr($content, 0, 200000) . "

…";
            }
            echo json_encode([
                'ok' => true,
                'version' => $version,
                'content' => $content,
                'mtime' => isset($stat['mtime']) ? (int)$stat['mtime'] : null,
                'source' => 'archive',
                'legacy' => (strpos($content, 'Legacy update log') !== false && strpos($content, 'Not recorded') !== false),
            ]);
            exit;
        }
    }
}

// Fallback: legacy loose files
$path = realpath($logDir . DIRECTORY_SEPARATOR . $filename);

// Ensure resolved path stays inside changelog directory.
if (!$path || strncmp($path, $logDir, strlen($logDir)) !== 0 || !is_readable($path)) {
    echo json_encode(['ok' => false, 'error' => 'Update log not found']);
    exit;
}

$content = file_get_contents($path);
if ($content === false) {
    echo json_encode(['ok' => false, 'error' => 'Unable to read update log']);
    exit;
}

$content = str_replace("
", "
", $content);
if (strlen($content) > 200000) {
    $content = substr($content, 0, 200000) . "

…";
}

echo json_encode([
    'ok' => true,
    'version' => $version,
    'content' => $content,
    'mtime' => @filemtime($path) ?: null,
    'source' => 'files',
    'legacy' => (strpos($content, 'Legacy update log') !== false && strpos($content, 'Not recorded') !== false),
]);