feat(sync): QR des reglages sur le PC, Paste settings sur le telephone
Le poste genere le QR (DelphiZXingQRCode, Apache 2.0) depuis ses prefs : URL + jeton, jamais le mot de passe de synchro. Le telephone lit le texte copie par l'appareil photo et remplit les champs ; Save valide. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,7 +35,7 @@ uses
|
||||
FMX.TMSFNCEdgeWebBrowser,
|
||||
{$ENDIF}
|
||||
PM.HTTPServer, PM.Bridge, PM.QuickUnlock, PM.PinUnlock, PM.UserPrefs, PM.Licence, PM.AutoStart,
|
||||
PM.Favicon,
|
||||
PM.Favicon, DelphiZXingQRCode,
|
||||
FMX.Platform.Win, FMX.Menus; // WindowHandleToPlatform → HWND for visibility check
|
||||
const
|
||||
// Bump on each release. Surfaced to JS via cmd://app/version, displayed
|
||||
@@ -1330,6 +1330,52 @@ begin
|
||||
PM.UserPrefs.SetPref(LKey, GetParam('value'));
|
||||
end
|
||||
|
||||
// ---- QR des reglages de synchro, pour le telephone ------------------
|
||||
// L'EXE FABRIQUE LE QR LUI-MEME : l'URL et le jeton se lisent ici, dans les
|
||||
// prefs DPAPI, et seule la matrice noir/blanc part vers la page - le jeton
|
||||
// ne transite pas en clair par le moteur de rendu (meme raison que
|
||||
// prefs/has). Le mot de passe de synchro n'y est JAMAIS : un QR se
|
||||
// photographie par-dessus l'epaule.
|
||||
// JSON nu, sans prefixe "pmsync:" : un prefixe a deux-points se lit comme un
|
||||
// lien, et l'appareil photo proposait "Ouvrir avec" au lieu de copier.
|
||||
else if ACmd = 'sync/qr' then
|
||||
begin
|
||||
var LQrUrl := PM.UserPrefs.GetPref('syncUrl');
|
||||
var LQrTok := PM.UserPrefs.GetPref('syncPwd');
|
||||
var LBits := '';
|
||||
var LSize := 0;
|
||||
if (LQrUrl <> '') and (LQrTok <> '') then
|
||||
begin
|
||||
var LJson := TJSONObject.Create;
|
||||
var LQr := TDelphiZXingQRCode.Create;
|
||||
var LSb := TStringBuilder.Create;
|
||||
try
|
||||
LJson.AddPair('pmsync', TJSONNumber.Create(1));
|
||||
LJson.AddPair('u', LQrUrl);
|
||||
LJson.AddPair('t', LQrTok);
|
||||
LQr.Encoding := qrUTF8NoBOM;
|
||||
LQr.QuietZone := 4;
|
||||
LQr.Data := LJson.ToJSON;
|
||||
LSize := LQr.Rows;
|
||||
for var R := 0 to LQr.Rows - 1 do
|
||||
for var C := 0 to LQr.Columns - 1 do
|
||||
if LQr.IsBlack[R, C] then LSb.Append('1') else LSb.Append('0');
|
||||
LBits := LSb.ToString;
|
||||
finally
|
||||
LSb.Free;
|
||||
LQr.Free;
|
||||
LJson.Free;
|
||||
end;
|
||||
end;
|
||||
if LSize > 0 then
|
||||
LogLine('sync/qr: ' + IntToStr(LSize) + ' modules')
|
||||
else
|
||||
LogLine('sync/qr: URL or token not set');
|
||||
WebBrowser.ExecuteJavaScript(
|
||||
'if(window.Bridge&&Bridge.onSyncQr)Bridge.onSyncQr(' + IntToStr(LSize) +
|
||||
',"' + LBits + '")');
|
||||
end
|
||||
|
||||
// ---- Licence hors ligne (PM.Licence) ---------------------------------
|
||||
// cmd://licence/status -> Bridge.onLicenceResult(ok, porteur)
|
||||
// cmd://licence/activate?key=<...> -> idem, apres verification + rangement
|
||||
|
||||
Reference in New Issue
Block a user