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:
47
src/PSLauncher.Core/Security/SettingsLockService.cs
Normal file
47
src/PSLauncher.Core/Security/SettingsLockService.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace PSLauncher.Core.Security;
|
||||
|
||||
public sealed class SettingsLockService : ISettingsLockService
|
||||
{
|
||||
private string? _expectedHashHex;
|
||||
private bool _unlocked;
|
||||
|
||||
public bool HasLockConfigured =>
|
||||
!string.IsNullOrWhiteSpace(_expectedHashHex);
|
||||
|
||||
public bool IsLocked => HasLockConfigured && !_unlocked;
|
||||
|
||||
public bool TryUnlock(string password)
|
||||
{
|
||||
if (!HasLockConfigured)
|
||||
{
|
||||
_unlocked = true;
|
||||
return true;
|
||||
}
|
||||
if (string.IsNullOrEmpty(password)) return false;
|
||||
var inputHash = HashHex(password);
|
||||
var match = string.Equals(inputHash, _expectedHashHex, StringComparison.OrdinalIgnoreCase);
|
||||
if (match) _unlocked = true;
|
||||
return match;
|
||||
}
|
||||
|
||||
public void Lock() => _unlocked = false;
|
||||
|
||||
public void SetPasswordHash(string? hash)
|
||||
{
|
||||
_expectedHashHex = string.IsNullOrWhiteSpace(hash) ? null : hash.Trim();
|
||||
// Si le hash change (admin a modifié le password backoffice), on re-verrouille.
|
||||
_unlocked = false;
|
||||
}
|
||||
|
||||
/// <summary>SHA-256 hex lowercase d'une string UTF-8. Format attendu par le backoffice.</summary>
|
||||
public static string HashHex(string input)
|
||||
{
|
||||
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(input));
|
||||
var sb = new StringBuilder(bytes.Length * 2);
|
||||
foreach (var b in bytes) sb.Append(b.ToString("x2"));
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user