Two robustness fixes after a real-world miss where v1.4.7 was uploaded but the launcher kept reporting v1.4.6 as latest: 1. UpdateChecker: ignore the `latest` field of the manifest entirely. Always pick the highest SemVer in the versions[] array (filtered by availableForDownload). Removes a class of "I forgot to bump latest" bugs at the server. 2. ManifestService: send Cache-Control: no-cache, no-store + Pragma: no-cache when fetching. The user explicitly clicked "Check for updates", they want fresh data — bypass any intermediate cache (browser-style HTTP cache, OVH static handler default 2-day expires). 3. sign-manifest.php: after hashing the uploaded ZIPs, auto-update `manifest.latest` to the highest version that actually has a ZIP on the server. Prevents the same drift the client now ignores, but keeps the field meaningful for any consumer that reads it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
92 lines
3.3 KiB
PHP
92 lines
3.3 KiB
PHP
<?php
|
|
/**
|
|
* Met à jour les champs `download.sizeBytes` et `download.sha256` de versions.json
|
|
* en lisant les ZIPs présents dans /builds/. Le nom local du ZIP est dérivé du
|
|
* champ `download.url` (basename de l'URL), donc tu peux nommer ton fichier comme
|
|
* tu veux tant que le manifest pointe vers le bon nom.
|
|
*
|
|
* Usage (à exécuter via SSH OVH dans www/PS_Launcher/) :
|
|
* php tools/sign-manifest.php
|
|
*
|
|
* (v0.4) Ajoutera la signature Ed25519 globale du manifest.
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
$root = dirname(__DIR__);
|
|
$manifestPath = "$root/manifest/versions.json";
|
|
$buildsDir = "$root/builds";
|
|
|
|
if (!is_file($manifestPath)) {
|
|
fwrite(STDERR, "Manifest not found: $manifestPath\n");
|
|
exit(1);
|
|
}
|
|
|
|
$manifest = json_decode(file_get_contents($manifestPath), true, 512, JSON_THROW_ON_ERROR);
|
|
|
|
$updated = 0;
|
|
$hashedVersions = [];
|
|
foreach ($manifest['versions'] as &$v) {
|
|
$version = $v['version'] ?? '?';
|
|
$url = $v['download']['url'] ?? '';
|
|
if ($url === '') {
|
|
echo " [skip] $version : pas d'URL dans le manifest\n";
|
|
continue;
|
|
}
|
|
|
|
$filename = basename(parse_url($url, PHP_URL_PATH) ?: '');
|
|
$zip = "$buildsDir/$filename";
|
|
|
|
if (!is_file($zip)) {
|
|
// Fallback : si le fichier n'existe pas exactement avec le nom de l'URL,
|
|
// on tente une recherche tolérante par version (espaces / casse / séparateurs).
|
|
$candidates = glob("$buildsDir/*{$version}*.zip", GLOB_NOSORT) ?: [];
|
|
$candidates = array_values(array_filter($candidates, 'is_file'));
|
|
if (count($candidates) === 1) {
|
|
$zip = $candidates[0];
|
|
echo " [info] $version : URL pointait vers '{$filename}', utilisé '" . basename($zip) . "' à la place\n";
|
|
} else {
|
|
echo " [skip] $version : ZIP introuvable pour $url\n";
|
|
if (count($candidates) > 1) {
|
|
echo " Plusieurs candidats : " . implode(', ', array_map('basename', $candidates)) . "\n";
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$size = filesize($zip);
|
|
echo " [hash] $version : " . basename($zip) . " ($size octets)...";
|
|
$sha = hash_file('sha256', $zip);
|
|
echo " sha256={$sha}\n";
|
|
|
|
$v['download']['sizeBytes'] = $size;
|
|
$v['download']['sha256'] = $sha;
|
|
$updated++;
|
|
$hashedVersions[] = $version;
|
|
}
|
|
unset($v);
|
|
|
|
// Met à jour automatiquement le champ `latest` avec la plus haute version
|
|
// effectivement uploadée (celle pour laquelle on a calculé un hash).
|
|
if (!empty($hashedVersions)) {
|
|
usort($hashedVersions, function ($a, $b) {
|
|
return version_compare($a, $b);
|
|
});
|
|
$newLatest = end($hashedVersions);
|
|
if (($manifest['latest'] ?? null) !== $newLatest) {
|
|
echo " [latest] {$manifest['latest']} -> {$newLatest}\n";
|
|
$manifest['latest'] = $newLatest;
|
|
}
|
|
}
|
|
|
|
// (v0.4) Signature Ed25519 — pour l'instant on laisse 'signature' = null.
|
|
// $config = require __DIR__ . '/../api/config.php';
|
|
// $sk = sodium_hex2bin($config['ed25519']['private_key_hex']);
|
|
// $payload = json_encode($manifest, JSON_UNESCAPED_SLASHES);
|
|
// $manifest['signature'] = base64_encode(sodium_crypto_sign_detached($payload, $sk));
|
|
|
|
file_put_contents(
|
|
$manifestPath,
|
|
json_encode($manifest, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"
|
|
);
|
|
echo "Manifest mis à jour ({$updated} version(s)) : $manifestPath\n";
|