• v3.1.0 e96edfce4f

    nicolas released this 2026-11-09 16:46:23 +01:00 | 59 commits to master since this release

    🖥️ Launcher 3.1.0 — Captures d'écran et liens signalés dans les demandes des joueurs

    Les demandes des joueurs gagnent les captures d'écran : depuis le bouton Aide, un joueur peut joindre jusqu'à 3 images (fichier ou Ctrl+V). Chaque image est contrôlée et débarrassée de ses métadonnées (ni position GPS, ni appareil, ni date), par le launcher puis par le serveur.

    Côté administration, une demande contenant un lien (http, https, www, domaine, adresse IP, e-mail, formes déguisées…) est désormais signalée par un avertissement, liens désamorcés et jamais cliquables. Le journal d'audit affiche des libellés lisibles pour les actions des demandes, et la fenêtre « Aide » reste centrée avec un ascenseur. Serveur à redéployer et un bloc nginx à ajouter (voir Mise à niveau).

    ✨ En bref

    Changement
    🆕 Nouveau Captures d'écran jointes à une demande (3 au plus, fichier ou Ctrl+V) : vraie image exigée, PNG ou JPEG seulement, sans métadonnées
    🆕 Nouveau Fiche d'une demande : captures d'écran (miniature, agrandissement), revérifiées avant l'affichage
    ⚠️ Nouveau Avertissement « lien » dans le menu : icône dans la liste, bandeau dans la fiche, liens désamorcés et jamais cliquables
    🔧 Amélioré Journal d'audit : « Demande de joueur reçue », « … consultée », « … traitée »… au lieu de feedback.submit, feedback.view… ; catégorie « Demandes des joueurs »
    🔧 Amélioré Fenêtre « Aide » : centrée à chaque étape, formulaire long (Bug) avec ascenseur au lieu de déborder en bas de l'écran
    🛡️ Sécurité Image contrôlée deux fois (launcher et serveur) ; envoi autorisé par un jeton propre à la demande ; plafond porté à 1 Go
    🖧 Serveur À redéployer, avec un nouveau bloc nginx pour les captures (voir Mise à niveau)
    🧰 Outils tools\ui-snapshot.bat capture désormais la fenêtre « Aide » et la fiche d'une demande
    🧪 Qualité 30 nouveaux tests automatisés (342 au total)

    🖼️ Captures d'écran (joueurs)

    Dans le formulaire du bouton Aide, une nouvelle section « Captures d'écran (facultatif) » apparaît sous les champs, pour tous les types de demande.

    Action Comportement
    Ajouter une image… Choix d'un fichier PNG, JPEG, BMP, GIF ou WebP (30 Mo au plus) dans l'explorateur Windows (dossier Images par défaut)
    Coller (Ctrl+V) Image du presse-papiers, après Impr. écran ou Win+Maj+S. Ctrl+V fonctionne même depuis un champ de texte, quand le presse-papiers contient une image et pas de texte
    Miniatures Une vignette par image (dimensions et format), bouton « Retirer cette capture » (croix) avant l'envoi
    Après l'envoi Si une capture n'a pas pu être envoyée, un avertissement le précise : la demande, elle, est bien enregistrée

    Chaque image passe par ces étapes avant l'envoi :

    1. Format reconnu au contenu, jamais à l'extension : un fichier renommé en .png est refusé.
    2. Dimensions lues avant le décodage : une image démesurée est refusée sans être chargée en mémoire.
    3. Décodage par Windows : preuve que c'est réellement une image.
    4. Réduction à 3 840 px de côté au plus (et sous la surface acceptée par le serveur).
    5. Réencodage en PNG (ou en JPEG pour une photo, ou si le PNG dépasse 4 Mo) sans aucune métadonnée : ni position GPS, ni appareil photo, ni date, ni logiciel.

    Le nom du fichier n'est jamais envoyé : il n'est affiché qu'au joueur.


    🗂️ Page « Demandes des joueurs » (administration)

    Élément Comportement
    Liste Nouvelles icônes : image (la demande a des captures, nombre en info-bulle) et alerte (la demande contient un lien)
    Captures d'écran Section « Captures d'écran » dans la fiche : miniatures, « Agrandir » / « Réduire », dimensions, format et taille. Chaque image est revérifiée par le launcher (structure, dimensions) avant l'affichage ; rien n'est écrit sur le PC de l'administrateur
    Liens Bandeau d'avertissement en haut de la fiche (« n'ouvrez pas ces liens et ne les copiez pas dans un navigateur… En cas de doute, supprimez la demande ») listant les liens désamorcés (hxxps[://]site[.]com), et champs concernés surlignés. Les liens ne sont jamais cliquables

    🔗 Formes de liens reconnues

    Forme Exemples
    Adresses avec protocole http://, https://, ftp://, file:
    Protocoles dangereux javascript:, data:, vbscript:, ms-…:, steam:…
    Sans protocole www.site.com, domaines nus avec une extension connue (site.ru, discord.gg/…, bit.ly/…)
    Adresses techniques adresses IP, chemins réseau \\serveur\partage, adresses e-mail
    Formes déguisées hxxp, [.], (dot), dot, caractères « pleine chasse » (https://)

    Un texte ordinaire (« 3 FPS à 1920×1080 », « le log fait 2 Mo ; Windows 11 ») ne déclenche pas d'alerte.


    📜 Journal d'audit lisible

    Les nouvelles actions s'affichent avec un libellé en français, et une catégorie « Demandes des joueurs » permet de les filtrer.

    Action Libellé affiché
    feedback.submit Demande de joueur reçue
    feedback.attachment Capture d'écran reçue
    feedback.view Demande de joueur consultée
    feedback.update Demande de joueur traitée (statut ou note)
    feedback.delete Demande de joueur supprimée
    feedback.purge Anciennes demandes supprimées (conservation)
    audit.purge Anciens mois du journal supprimés (conservation)
    keyring.publish Trousseau de signature publié
    release.sign Version en ligne signée
    • Nouvelle catégorie « Signature (trousseau) » ; la catégorie du journal devient « Journal d'audit (consultations, exports, purges) ».

    🪟 Fenêtre « Aide »

    • La fenêtre reste centrée quand on passe du choix du type au formulaire, puis à la référence : elle ne déborde plus vers le bas de l'écran.
    • La zone du formulaire a une hauteur de base de 500 px (moins sur un petit écran) : un formulaire long, comme Bug, défile avec un ascenseur.
    • Chaque nouvelle étape repart du haut du formulaire.
    • Molette : elle fait défiler le formulaire, jamais une liste déroulante fermée (catégorie, gravité… ne changent plus par mégarde) ; un champ de texte arrivé en bout de course laisse défiler le formulaire. Même comportement que le menu d'administration.

    🛡️ Sécurité

    Menace Défense
    Fichier piégé déguisé en image Le serveur n'accepte que de vrais PNG ou JPEG, contrôlés sans bibliothèque de décodage : PNG (blocs et sommes de contrôle CRC, données décompressées et taille exacte de chaque ligne, filtres) ; JPEG (marqueurs, tables, début et fin d'image). Rien n'est accepté après la fin de l'image ; 16 à 4 096 px de côté, 4 Mo au plus
    Métadonnées personnelles Retirées par le launcher puis par le serveur : blocs facultatifs PNG (textes, EXIF, profils…), segments JPEG APP1 à APP15 (EXIF, XMP, GPS) et commentaires
    Capture envoyée hors d'une demande Jeton d'envoi remis par le serveur avec la demande : 128 bits, valable 15 minutes, pour cette demande et le nombre de captures annoncé seulement ; seule son empreinte est gardée, en mémoire ; comparaison à temps constant
    Disque rempli 3 captures de 4 Mo au plus par demande ; plafond global porté de 100 Mo à 1 Go (captures comprises) ; 500 Mo d'espace libre minimum
    Image piégée côté administrateur Capture servie en octets bruts (nosniff), redécodée et revérifiée par le launcher avant l'affichage, jamais écrite sur le disque
    Lien malveillant dans une demande Signalé, désamorcé, jamais cliquable
    Jeton de session volé Inchangé : statut, note et suppression restent des requêtes signées par la clé de l'administrateur (horodatage et nonce, rejeu refusé), comme tout le menu ; les lectures (liste, fiche, captures) exigent la session et feedback.read, revérifiées à chaque requête et inscrites au journal

    🔒 Vie privée

    • Captures sans métadonnées ; nom du fichier jamais envoyé.
    • Audit feedback.attachment sans adresse IP, comme feedback.submit.
    • nginx n'écrit pas la route d'envoi des captures dans ses journaux (access_log off), comme les deux autres routes des joueurs.
    • Captures supprimées avec leur demande (suppression manuelle ou purge automatique).

    🗄️ Choix du stockage

    Les captures sont des fichiers <id>-<n>.png|jpg rangés à côté du JSON de leur demande, dans les données privées du serveur (0700/0600), écrits de façon atomique. SQLite a été écarté pour les captures : des images stockées en base alourdiraient les sauvegardes et la purge, sans gain de sécurité.


    🧰 Outil de débogage ui-snapshot

    Scène Contenu
    feedback-kind Choix du type de demande
    feedback-review Avis noté (étoiles)
    feedback-bug Bug rempli avec une capture d'écran ; formulaire qui défile (pages .p2.png…)
    feedback-bug-errors Bug, champs obligatoires signalés
    feedback-done Demande envoyée, avec l'avertissement d'une capture refusée
    admin-page-feedback-requests-detail Fiche d'une demande : lien signalé, captures d'écran
    • L'API simulée connaît les routes des demandes (six demandes d'exemple : tous les types et statuts, titre très long, liens, captures).
    • Envoi simulé et images de démonstration dessinées par l'outil : aucun fichier choisi, presse-papiers intact.
    • tools/UiSnapshot/LISEZMOI.md : nouvelle section « Tenir l'outil à jour » (chaque nouvelle fenêtre ou nouveau menu s'y ajoute dans la même modification).

    🧪 Tests

    Fichier Tests
    Contracts/FeedbackContentTests.cs (nouveau) 25 : liens sous toutes leurs formes (http, https, www, domaines, IP, chemins réseau, e-mails, protocoles dangereux, formes déguisées, pleine chasse), texte ordinaire sans fausse alerte, désamorçage, métadonnées PNG et JPEG (EXIF, commentaires) retirées, fausses images ou images abîmées refusées, formats reconnus au contenu
    Server/FeedbackModuleTests.cs +3 : captures (jeton, numéro, délai, vraie image, métadonnées retirées, lecture par le menu, suppression avec la demande), capture refusée sans perte de la demande, demandes avec liens signalées
    Admin/FeedbackPanelTests.cs +2 : captures du joueur jusqu'au menu (refus d'un faux fichier et d'un presse-papiers vide, avertissement « lien », agrandissement), libellés du journal d'audit

    342 tests au vert.

    📂 Fichiers modifiés

    Contrats

    • src/GameLauncher.Contracts/Feedback/FeedbackLinks.cs (nouveau)
    • src/GameLauncher.Contracts/Feedback/FeedbackImages.cs (nouveau)
    • src/GameLauncher.Contracts/Feedback/FeedbackDtos.cs
    • src/GameLauncher.Contracts/Feedback/FeedbackRules.cs
    • src/GameLauncher.Contracts/ApiRoutes.cs

    Client de l'API

    • src/GameLauncher.ApiClient/LauncherApiClient.cs
    • src/GameLauncher.ApiClient/AdminSession.cs

    Serveur

    • server/GameLauncher.Server/Modules/Feedback/FeedbackModule.cs
    • server/GameLauncher.Server/Security/FeedbackGuard.cs
    • server/GameLauncher.Server/Storage/FeedbackStore.cs
    • server/GameLauncher.Server/Storage/SecureFiles.cs
    • server/GameLauncher.Server/Hosting/LauncherApiOptions.cs
    • server/GameLauncher.Server/appsettings.json

    Déploiement

    • server/deploy/nginx-api.conf
    • server/deploy/LISEZMOI.md

    Module « Aide »

    • src/GameLauncher.Modules.Feedback/FeedbackAttachments.cs (nouveau)
    • src/GameLauncher.Modules.Feedback/FeedbackFormViewModel.cs

    Menu d'administration

    • src/GameLauncher.Modules.Admin/Feedback/FeedbackItems.cs
    • src/GameLauncher.Modules.Admin/Feedback/FeedbackPanelViewModel.cs
    • src/GameLauncher.Modules.Admin/Audit/AuditPanelViewModel.cs

    Launcher (WPF)

    • src/GameLauncher/Services/ScreenshotSource.cs (nouveau)
    • src/GameLauncher/Services/FeedbackWindowService.cs
    • src/GameLauncher/Views/FeedbackWindow.xaml
    • src/GameLauncher/Views/FeedbackWindow.xaml.cs
    • src/GameLauncher/Controls/AdminAssist.cs
    • src/GameLauncher/Themes/Admin.xaml
    • src/GameLauncher/GameLauncher.csproj (version 3.1.0)

    Outil ui-snapshot

    • tools/UiSnapshot/Scenes/FeedbackScenes.cs (nouveau)
    • tools/UiSnapshot/Scenes/AdminScenes.cs
    • tools/UiSnapshot/Fakes/FakeApi.cs
    • tools/UiSnapshot/Fakes/SampleData.cs
    • tools/UiSnapshot/SnapshotRunner.cs
    • tools/UiSnapshot/LISEZMOI.md
    • tools/UiSnapshot/UiSnapshot.csproj

    Tests

    • tests/GameLauncher.Tests/Contracts/FeedbackContentTests.cs (nouveau)
    • tests/GameLauncher.Tests/Server/FeedbackModuleTests.cs
    • tests/GameLauncher.Tests/Admin/FeedbackPanelTests.cs

    Documentation et notes

    • README.md
    • docs/ADMIN-ARCHITECTURE.md
    • tools/notes-launcher.txt

    ⬆️ Mise à niveau

    Ordre conseillé : serveur d'abord, launcher ensuite. Un launcher 3.1.0 relié à un serveur 3.0.0 envoie bien les demandes, mais sans leurs captures : le joueur voit l'avertissement « … capture(s) sur … n'ont pas pu être envoyées. La demande, elle, est bien enregistrée. »

    • Serveur (Launcher API) : à redéployer (server/deploy/LISEZMOI.md, étape 8, puis étape 3 octies) :
      1. nginx : ajouter le troisième bloc location ^~ /api/v1/feedback/attachments/ de server/deploy/nginx-api.conf (corps de 5 Mo, access_log off, même zone feedback_par_ip) à côté des deux blocs /api/v1/feedback… de la 3.0.0 ; sudo nginx -t && sudo systemctl reload nginx ;
      2. si Feedback:MaxTotalMegabytes a été fixé dans appsettings.Production.json, le porter à 1024 (captures comprises) ; sinon, rien à faire ;
      3. sudo systemctl restart launcher-api (les sessions ouvertes sont fermées : reconnexion).
      • Bloc nginx indispensable : sans lui, les captures passent par le bloc /api/ général, qui les refuse (corps limité à 64 Ko) et journalise l'adresse IP de la requête. Les demandes, elles, arrivent normalement.
    • Administrateurs : aucune action ; les permissions feedback.read et feedback.manage donnent accès aux captures.
    • Joueurs : mise à jour automatique, aucune action requise.
    • RGPD : compléter la fiche du traitement « Demandes d'aide et retours des joueurs » : captures d'écran facultatives, sans métadonnées, conservées et supprimées avec la demande. Rappeler dans la politique de confidentialité de ne pas joindre d'image contenant des données personnelles.

    🔏 La sécurité des mises à jour du launcher ne change pas : la signature numérique et l'empreinte SHA-256 de chaque nouvelle version sont vérifiées avant toute installation.

    What's Changed

    Contributors

    Full Changelog: v3.0.0...v3.1.0

    Downloads