feat(licence): ecran d'activation au demarrage

ensureLicence() en tete d'init(), avant tout le reste : un ecran
d'authentification qui s'affiche puis se fait recouvrir donnerait
l'impression que le coffre etait accessible.

L'ecran reprend les classes de l'ecran d'authentification — zero style
nouveau hormis un z-index. Le statut est demande deux fois avant de le
montrer : un demarrage a froid lent manquerait la fenetre de reponse, et
le silence se lirait comme un refus.

Une cle refusee ne dit pas pourquoi, et le journal note le verdict sans
jamais la cle.

ATTENTION : tant que LicencePublicKeyBlob est a zero, l'ecran est
infranchissable. Poser la cle publique avant de deployer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-09-05 14:58:19 +01:00
parent 960d2b388a
commit cd6e70449d
5 changed files with 156 additions and 1 deletions
+33 -1
View File
@@ -34,7 +34,7 @@ uses
{$IFDEF USE_EDGE_BROWSER}
FMX.TMSFNCEdgeWebBrowser,
{$ENDIF}
PM.HTTPServer, PM.Bridge, PM.QuickUnlock, PM.PinUnlock, PM.UserPrefs, PM.AutoStart,
PM.HTTPServer, PM.Bridge, PM.QuickUnlock, PM.PinUnlock, PM.UserPrefs, PM.Licence, PM.AutoStart,
PM.Favicon,
FMX.Platform.Win, FMX.Menus; // WindowHandleToPlatform → HWND for visibility check
const
@@ -1330,6 +1330,38 @@ begin
PM.UserPrefs.SetPref(LKey, GetParam('value'));
end
// ---- Licence hors ligne (PM.Licence) ---------------------------------
// cmd://licence/status -> Bridge.onLicenceResult(ok, porteur)
// cmd://licence/activate?key=<...> -> idem, apres verification + rangement
//
// La cle est du base64url plus un point : que des caracteres surs dans une
// URL, donc rien a encoder ni a decoder de special sur ce trajet.
else if (ACmd = 'licence/status') or (ACmd = 'licence/activate') then
begin
var LLicOk: Boolean;
var LLicInfo: TLicenceInfo;
if ACmd = 'licence/activate' then
begin
LLicOk := PM.Licence.ActivateLicence(GetParam('key'), LLicInfo);
// On journalise le VERDICT, jamais la cle : le journal se copie et
// s'envoie, et une licence valable est une valeur transmissible.
LogLine('Licence activation: ' + BoolToStr(LLicOk, True));
end
else
begin
LLicOk := PM.Licence.IsLicensed;
LLicInfo := PM.Licence.LicenceInfo;
end;
var LHolder := LLicInfo.Holder;
if LHolder = '' then LHolder := LLicInfo.Email;
LHolder := StringReplace(LHolder, '\', '\\', [rfReplaceAll]);
LHolder := StringReplace(LHolder, '"', '\"', [rfReplaceAll]);
WebBrowser.ExecuteJavaScript(
'if(window.Bridge&&Bridge.onLicenceResult)' +
'Bridge.onLicenceResult(' + BoolToStr(LLicOk, True).ToLower +
',"' + LHolder + '")');
end
// ---- Start with Windows (HKCU Run registry) --------------------------
else if ACmd = 'autostart/get' then
begin