v1.0.7 — UpdateChecker filtre isBeta selon canSeeBetas de la license
Fix latent identifié en marge du v1.0.6 : UpdateChecker.CheckAsync retournait toujours la plus haute version disponible sans filtrer par isBeta, indépendamment des droits de la license courante. Conséquence possible : un client sans droits beta pouvait recevoir un popup « Nouvelle version disponible : 1.5.4.32 » puis ne pas voir cette version dans la liste (RebuildList applique le filtre canSeeBetas), et au clic il n'aurait pas pu la télécharger (entitlement backend). UX incohérente + confusion opérationnelle. Fix : IUpdateChecker.CheckAsync prend maintenant un paramètre `bool canSeeBetas`. UpdateChecker filtre les entrées isBeta=true de la sélection LatestRemote quand ce flag est false. Le manifest complet reste retourné dans le UpdateCheckResult pour le rendu ultérieur — seule la variable "quelle version est proposée comme MAJ ?" est concernée. Côté caller (MainViewModel.CheckForUpdatesAsync), on passe `_license?.CanSeeBetas ?? false` — même défaut que RebuildList, comportement cohérent bout-en-bout. Rétrocompat : aucun autre caller de CheckAsync dans le codebase (grep vérifié). Le nouveau param est requis mais n'a qu'un site d'appel. Bump : 1.0.6 → 1.0.7 (petit fix isolé, mérite d'être tracé séparément puisque la sémantique change). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#define MyAppName "PROSERVE Launcher"
|
#define MyAppName "PROSERVE Launcher"
|
||||||
#define MyAppShortName "PS_Launcher"
|
#define MyAppShortName "PS_Launcher"
|
||||||
#define MyAppVersion "1.0.6"
|
#define MyAppVersion "1.0.7"
|
||||||
#define MyAppPublisher "ASTERION VR"
|
#define MyAppPublisher "ASTERION VR"
|
||||||
#define MyAppURL "https://asterionvr.com"
|
#define MyAppURL "https://asterionvr.com"
|
||||||
#define MyAppExeName "PS_Launcher.exe"
|
#define MyAppExeName "PS_Launcher.exe"
|
||||||
|
|||||||
@@ -18,9 +18,9 @@
|
|||||||
<Product>PROSERVE Launcher</Product>
|
<Product>PROSERVE Launcher</Product>
|
||||||
<Copyright>© 2026 ASTERION VR — All rights reserved</Copyright>
|
<Copyright>© 2026 ASTERION VR — All rights reserved</Copyright>
|
||||||
<RootNamespace>PSLauncher.App</RootNamespace>
|
<RootNamespace>PSLauncher.App</RootNamespace>
|
||||||
<Version>1.0.6</Version>
|
<Version>1.0.7</Version>
|
||||||
<AssemblyVersion>1.0.6.0</AssemblyVersion>
|
<AssemblyVersion>1.0.7.0</AssemblyVersion>
|
||||||
<FileVersion>1.0.6.0</FileVersion>
|
<FileVersion>1.0.7.0</FileVersion>
|
||||||
|
|
||||||
<!-- Single-file self-contained publish profile (used by `dotnet publish`) -->
|
<!-- Single-file self-contained publish profile (used by `dotnet publish`) -->
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
|
|||||||
@@ -763,7 +763,13 @@ public sealed partial class MainViewModel : ObservableObject
|
|||||||
// on garde le cache silencieusement (pas de crash).
|
// on garde le cache silencieusement (pas de crash).
|
||||||
await RefreshLicenseFromServerAsync(CancellationToken.None);
|
await RefreshLicenseFromServerAsync(CancellationToken.None);
|
||||||
|
|
||||||
var result = await _updateChecker.CheckAsync(CancellationToken.None);
|
// Passe canSeeBetas depuis la license courante — UpdateChecker exclut les
|
||||||
|
// betas de la sélection LatestRemote quand le client n'a pas les droits.
|
||||||
|
// Évite le popup « MAJ dispo : 1.5.4.32 beta » pour un client qui ne peut
|
||||||
|
// pas voir cette version dans la liste après filtrage RebuildList.
|
||||||
|
var result = await _updateChecker.CheckAsync(
|
||||||
|
_license?.CanSeeBetas ?? false,
|
||||||
|
CancellationToken.None);
|
||||||
if (result.Error is not null)
|
if (result.Error is not null)
|
||||||
{
|
{
|
||||||
StatusMessage = Strings.StatusError(result.Error);
|
StatusMessage = Strings.StatusError(result.Error);
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ namespace PSLauncher.Core.Updates;
|
|||||||
|
|
||||||
public interface IUpdateChecker
|
public interface IUpdateChecker
|
||||||
{
|
{
|
||||||
Task<UpdateCheckResult> CheckAsync(CancellationToken ct);
|
/// <param name="canSeeBetas">
|
||||||
|
/// Si false, les versions marquées <see cref="VersionManifest.IsBeta"/> sont
|
||||||
|
/// exclues de la sélection du <c>LatestRemote</c> — pas de popup « MAJ dispo »
|
||||||
|
/// pour une beta que le client ne pourrait de toute façon pas voir dans la
|
||||||
|
/// liste après filtrage license côté <c>MainViewModel.RebuildList</c>. Le
|
||||||
|
/// manifest complet est quand même retourné pour le rendu ultérieur.
|
||||||
|
/// </param>
|
||||||
|
Task<UpdateCheckResult> CheckAsync(bool canSeeBetas, CancellationToken ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed record UpdateCheckResult(
|
public sealed record UpdateCheckResult(
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public sealed class UpdateChecker : IUpdateChecker
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UpdateCheckResult> CheckAsync(CancellationToken ct)
|
public async Task<UpdateCheckResult> CheckAsync(bool canSeeBetas, CancellationToken ct)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -32,8 +32,16 @@ public sealed class UpdateChecker : IUpdateChecker
|
|||||||
// ordonnant via VersionOrder — ça respecte la règle « non-beta > beta au
|
// ordonnant via VersionOrder — ça respecte la règle « non-beta > beta au
|
||||||
// même préfixe 3-digit » (ex : 1.5.4 non-beta > 1.5.4.32 beta), sinon
|
// même préfixe 3-digit » (ex : 1.5.4 non-beta > 1.5.4.32 beta), sinon
|
||||||
// c'est du SemVer strict.
|
// c'est du SemVer strict.
|
||||||
var latest = manifest.Versions
|
//
|
||||||
.Where(v => v.AvailableForDownload)
|
// Filtre isBeta : les clients sans droits beta ne doivent JAMAIS voir une
|
||||||
|
// beta comme LatestRemote — sinon le popup « MAJ dispo » leur propose une
|
||||||
|
// version qu'ils ne pourront pas installer (filtrée en aval par RebuildList).
|
||||||
|
// Le filtre est appliqué avant le tri VersionOrder pour éviter qu'une beta
|
||||||
|
// ne se glisse comme "latest" chez un client non-autorisé, même si elle
|
||||||
|
// aurait été détrônée par une non-beta au même préfixe 3-digit.
|
||||||
|
var candidates = manifest.Versions.Where(v => v.AvailableForDownload);
|
||||||
|
if (!canSeeBetas) candidates = candidates.Where(v => !v.IsBeta);
|
||||||
|
var latest = candidates
|
||||||
.OrderByDescending(v => v, Comparer<VersionManifest>.Create(VersionOrder.Compare))
|
.OrderByDescending(v => v, Comparer<VersionManifest>.Create(VersionOrder.Compare))
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user