v0.28.10 — Mode auto + settings lock par license + fix post-install state
Mode auto (auto-launch d'une version désignée au démarrage et après exit) : - Master toggle + version désignée via bouton AUTO (orange) sur chaque row - Countdown 5 s configurable avec popup d'annulation (StartAutoLaunchCountdown) - Args CLI passés à PROSERVE : opérateur tape juste le nom (autoconnect, login), le launcher ajoute -/=/quotes. Format produit identique à un .bat. Fix : passage de ArgumentList à Arguments string pour éviter le quotage auto .NET sur les args contenant '=' (cassait FParse::Value). - Garde-fou anti double-lancement : refuse de lancer si _runningProserve vivant OU IProcessLauncher.IsRunning() détecte une instance externe. Silent pour les triggers auto, popup pour les clics manuels. - Option « Attendre santé système » : countdown différé tant que les health checks ne sont pas tous OK (phase 1 du dialog avec liste des pending). Settings lock par license (remplace l'ancien lock global manifest) : - Colonne settings_lock_password_hash sur table licenses (migration 003) - Backoffice : bouton 🔒 par license pour set/clear hash SHA-256 - Payload /license/validate inclut settingsLockPasswordHash (v3 canonique) - 3-tier fallback signature : v3 → v2 → legacy pour compat cache offline - SettingsLockService : in-memory unlock state, gate l'expander Avancés - SettingsLockDialog : prompt mdp, persiste déverrouillé jusqu'au restart Fix post-install : la row restait en visuel « Installing » jusqu'au prochain Check Updates. Reset explicite row.State=InstalledIdle + _activeRow=null AVANT le RebuildList post-install pour purger l'instance orpheline. Migrations : - 002_channel_betas.sql réécrit en ALTER simples (DELIMITER cassait migrate.php qui split sur ';\n') - migrate.php tolère « Duplicate column/key name » comme idempotent Strings (5 langues, ~25 nouvelles) : - Renomme « Relance automatique » → « Lancement automatique » (dialog utilisé pour les 3 entry points : clic, startup, post-exit) - Tooltips auto-mode, settings lock prompts, health wait phase, etc. Bumps : 0.27.4 → 0.28.10 (csproj + .iss). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Net.Sockets;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PSLauncher.Core.Lan;
|
||||
using PSLauncher.Core.Security;
|
||||
using PSLauncher.Models;
|
||||
|
||||
namespace PSLauncher.Core.Manifests;
|
||||
@@ -20,6 +21,7 @@ public sealed class ManifestService : IManifestService
|
||||
private readonly Func<string?> _channelProvider;
|
||||
private readonly IManifestCache _manifestCache;
|
||||
private readonly IPeerManifestFetcher _peerManifestFetcher;
|
||||
private readonly ISettingsLockService _settingsLock;
|
||||
private readonly ILogger<ManifestService> _logger;
|
||||
|
||||
public ManifestSource LastSource { get; private set; } = ManifestSource.None;
|
||||
@@ -30,6 +32,7 @@ public sealed class ManifestService : IManifestService
|
||||
Func<string?> channelProvider,
|
||||
IManifestCache manifestCache,
|
||||
IPeerManifestFetcher peerManifestFetcher,
|
||||
ISettingsLockService settingsLock,
|
||||
ILogger<ManifestService> logger)
|
||||
{
|
||||
_http = http;
|
||||
@@ -37,9 +40,23 @@ public sealed class ManifestService : IManifestService
|
||||
_channelProvider = channelProvider;
|
||||
_manifestCache = manifestCache;
|
||||
_peerManifestFetcher = peerManifestFetcher;
|
||||
_settingsLock = settingsLock;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No-op depuis v0.28 : le hash settings-lock vient maintenant de la
|
||||
/// <c>LicenseValidationResponse</c> (per-license). Voir
|
||||
/// <see cref="PSLauncher.Core.Licensing.LicenseService.ValidateAsync"/> et
|
||||
/// <see cref="PSLauncher.Core.Licensing.LicenseService.GetCached"/> pour la
|
||||
/// propagation effective vers <see cref="ISettingsLockService"/>.
|
||||
/// </summary>
|
||||
private void PropagateSettingsLock(RemoteManifest? manifest)
|
||||
{
|
||||
_ = manifest;
|
||||
_ = _settingsLock;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Timeout court sur la tentative OVH : si le serveur Internet ne répond pas
|
||||
/// rapidement, on bascule sur les fallbacks LAN/cache plutôt que d'attendre les
|
||||
@@ -76,6 +93,7 @@ public sealed class ManifestService : IManifestService
|
||||
?? throw new InvalidOperationException("Empty manifest");
|
||||
await _manifestCache.SaveAsync(rawJson, ct).ConfigureAwait(false);
|
||||
LastSource = ManifestSource.Ovh;
|
||||
PropagateSettingsLock(manifest);
|
||||
return manifest;
|
||||
}
|
||||
catch (OperationCanceledException) when (ct.IsCancellationRequested) { throw; }
|
||||
@@ -86,6 +104,7 @@ public sealed class ManifestService : IManifestService
|
||||
if (cached is not null)
|
||||
{
|
||||
LastSource = ManifestSource.DiskCache;
|
||||
PropagateSettingsLock(cached);
|
||||
return cached;
|
||||
}
|
||||
throw;
|
||||
@@ -102,6 +121,7 @@ public sealed class ManifestService : IManifestService
|
||||
// Cache aussi le peer manifest pour servir aux autres clients du LAN.
|
||||
await _manifestCache.SaveAsync(peerJson, ct).ConfigureAwait(false);
|
||||
LastSource = ManifestSource.Peer;
|
||||
PropagateSettingsLock(manifest);
|
||||
return manifest;
|
||||
}
|
||||
|
||||
@@ -111,6 +131,7 @@ public sealed class ManifestService : IManifestService
|
||||
{
|
||||
_logger.LogInformation("Manifest récupéré depuis le cache disque (offline + pas de peer)");
|
||||
LastSource = ManifestSource.DiskCache;
|
||||
PropagateSettingsLock(localCache);
|
||||
return localCache;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user