Client (C# / .NET 8 / WPF, MVVM via CommunityToolkit.Mvvm):
- PSLauncher.App: WPF UI dark theme (Epic-style sidebar + hero + big play button)
with UpdateAvailableDialog rendering Markdown release notes via Markdig.Wpf.
- PSLauncher.Core: services for installation registry (scans Proserve v{X.Y.Z}/),
process launcher, manifest fetch, SHA-256 integrity, HTTP download with
progress, ZIP install via .tmp + atomic rename, update orchestrator.
- PSLauncher.Models: RemoteManifest, InstalledVersion, LocalConfig DTOs.
Server (PHP 8 for OVH mutualisé, deployed under www/PS_Launcher/):
- Front controller + routes /manifest and /releasenotes/{version}.
- Static signed-manifest workflow with tools/sign-manifest.php CLI to
recompute SHA-256 and sizeBytes after each ZIP upload.
- .htaccess: HTTPS redirect, rewrite, security headers.
- config.example.php template; real config.php is gitignored.
Cohabiting versions: each release lives in its own Proserve v{version}/ folder
under installRoot. Old versions are never deleted automatically.
Roadmap: v0.3 = HTTP Range resume + Polly retry + state.json,
v0.4 = MySQL license + Ed25519 signatures + DPAPI, v0.5 = settings/UX polish.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
53 lines
1.7 KiB
PHP
53 lines
1.7 KiB
PHP
<?php
|
|
/**
|
|
* Met à jour les champs `download.sizeBytes` et `download.sha256` de versions.json
|
|
* en lisant les ZIPs présents dans /builds/, puis (v0.4) signera le manifest avec Ed25519.
|
|
*
|
|
* Usage (à exécuter via SSH OVH dans www/PS_Launcher/) :
|
|
* php tools/sign-manifest.php
|
|
*
|
|
* Convention attendue : pour chaque entrée du manifest, le ZIP est dans
|
|
* builds/proserve-{version}.zip
|
|
*/
|
|
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);
|
|
|
|
foreach ($manifest['versions'] as &$v) {
|
|
$version = $v['version'];
|
|
$zip = "$buildsDir/proserve-{$version}.zip";
|
|
if (!is_file($zip)) {
|
|
echo " [skip] $version : ZIP absent ($zip)\n";
|
|
continue;
|
|
}
|
|
$size = filesize($zip);
|
|
echo " [hash] $version : $size octets...";
|
|
$sha = hash_file('sha256', $zip);
|
|
echo " sha256={$sha}\n";
|
|
|
|
$v['download']['sizeBytes'] = $size;
|
|
$v['download']['sha256'] = $sha;
|
|
}
|
|
unset($v);
|
|
|
|
// (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 : $manifestPath\n";
|