Initial scaffolding: PS_Launcher v0.2
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>
This commit is contained in:
52
server/tools/sign-manifest.php
Normal file
52
server/tools/sign-manifest.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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";
|
||||
Reference in New Issue
Block a user