feat(apk): choisir d'ouvrir avec le verrouillage d'ecran, un code ou le mot de passe du coffre
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+62
-40
@@ -395,6 +395,9 @@
|
|||||||
|
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
<button class="btn wide main" id="btnOpen">➜ Open vault</button>
|
<button class="btn wide main" id="btnOpen">➜ Open vault</button>
|
||||||
|
<!-- LA SORTIE DE SECOURS DU VERROUILLAGE D'ECRAN : empreinte refusee,
|
||||||
|
schema oublie - le mot de passe du coffre ouvre toujours. -->
|
||||||
|
<button class="btn wide" id="btnUsePwd" hidden>Use the vault password</button>
|
||||||
<button class="btn wide" id="btnSync">↻ Sync</button>
|
<button class="btn wide" id="btnSync">↻ Sync</button>
|
||||||
<!-- UN SEUL BOUTON, ET IL NE MENT PAS SUR SA DESTINATION.
|
<!-- UN SEUL BOUTON, ET IL NE MENT PAS SUR SA DESTINATION.
|
||||||
Il y en avait deux, "Settings" et "Log", et le second a fini par
|
Il y en avait deux, "Settings" et "Log", et le second a fini par
|
||||||
@@ -582,22 +585,21 @@
|
|||||||
clair en main : les deux ne pourraient que refuser, et proposer une
|
clair en main : les deux ne pourraient que refuser, et proposer une
|
||||||
action qui refuse toujours vaut moins que ne rien proposer. -->
|
action qui refuse toujours vaut moins que ne rien proposer. -->
|
||||||
<div id="secCode" hidden>
|
<div id="secCode" hidden>
|
||||||
<h2>Unlock code</h2>
|
<h2>Unlock with</h2>
|
||||||
|
<!-- TROIS FACONS D'OUVRIR, UNE SEULE COPIE LOCALE. Le coffre lui-meme n'est
|
||||||
|
jamais touche : seul le scellement de la copie rapide change. Le champ
|
||||||
|
sert a tout - nouveau code, mot de passe du coffre, ou code courant
|
||||||
|
pour revenir au verrouillage d'ecran (retirer une protection demande
|
||||||
|
de la connaitre). -->
|
||||||
<div class="in-wrap">
|
<div class="in-wrap">
|
||||||
<input class="field-in" id="sPinNew" placeholder="new unlock code or password"
|
<input class="field-in" id="sPinNew" placeholder="code or password"
|
||||||
type="password" autocomplete="off">
|
type="password" autocomplete="off">
|
||||||
<div class="in-x" data-clear="sPinNew">×</div>
|
<div class="in-x" data-clear="sPinNew">×</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn wide" id="sPinSet">Set this code</button>
|
<button class="btn wide" id="sModeDevice">Screen lock (fingerprint, pattern...)</button>
|
||||||
<!-- Le champ ci-dessus sert aux deux : le NOUVEAU code pour "Set", le code
|
<button class="btn wide" id="sModeCode">App code (type it above)</button>
|
||||||
COURANT pour "Remove". Retirer une protection demande de la connaitre,
|
<button class="btn wide" id="sModePwd">Vault password (type it above)</button>
|
||||||
sinon quiconque trouve le telephone ouvert la leve en deux appuis. -->
|
<div class="note" id="sModeNote"></div>
|
||||||
<button class="btn wide danger" id="sPinClear">Remove the unlock code</button>
|
|
||||||
<div class="note">To remove the code, type the current one above first.
|
|
||||||
The code seals the copy kept on this device. It can be
|
|
||||||
digits or a full password - a longer one is harder to guess, and it is
|
|
||||||
asked for only when the vault opens. Removing it leaves the vault
|
|
||||||
readable by anyone holding the phone unlocked.</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Diagnostics</h2>
|
<h2>Diagnostics</h2>
|
||||||
@@ -1648,14 +1650,49 @@ document.getElementById('histBody').addEventListener('click', function (ev) {
|
|||||||
document.getElementById('sLog').addEventListener('click', function () {
|
document.getElementById('sLog').addEventListener('click', function () {
|
||||||
showLog(document.getElementById('log').hidden);
|
showLog(document.getElementById('log').hidden);
|
||||||
});
|
});
|
||||||
document.getElementById('sPinSet').addEventListener('click', function () {
|
// FACON D'OUVRIR. Delphi dit laquelle est en place (PM.setUnlockMode) ; chaque
|
||||||
var v = document.getElementById('sPinNew').value;
|
// bouton envoie la commande qui existe deja pour la poser. Revenir au
|
||||||
if (!v) { toast('Type a code first'); return; }
|
// verrouillage d'ecran, c'est retirer le code : il faut donc le code courant.
|
||||||
// DEMANDE EXPLICITE, EFFET IMMEDIAT. Le code ne se depose plus dans un champ
|
var unlockMode = 'none', canDeviceLock = false, hasContainer = false;
|
||||||
// que l'ouverture suivante appliquerait : Delphi refuse si le coffre n'est
|
function syncUnlockUi() {
|
||||||
// pas ouvert, ce qui prouve que le code courant est connu.
|
['device', 'code', 'password'].forEach(function (m) {
|
||||||
|
var id = { device: 'sModeDevice', code: 'sModeCode', password: 'sModePwd' }[m];
|
||||||
|
document.getElementById(id).classList.toggle('main', unlockMode === m);
|
||||||
|
});
|
||||||
|
document.getElementById('sModeDevice').disabled = !canDeviceLock;
|
||||||
|
document.getElementById('sModeNote').textContent =
|
||||||
|
{ device: 'Now: screen lock. Changing the screen lock or adding a fingerprint never deletes the vault.',
|
||||||
|
code: 'Now: app code. To go back to the screen lock, type the current code above.',
|
||||||
|
password: 'Now: vault password. To go back to the screen lock, type it above.',
|
||||||
|
none: 'Now: no protection - anyone holding the phone unlocked can open the vault.' }[unlockMode]
|
||||||
|
+ (canDeviceLock ? '' : ' This phone has no screen lock.');
|
||||||
|
document.getElementById('btnUsePwd').hidden =
|
||||||
|
!(authMode === 'open' && unlockMode === 'device' && hasContainer);
|
||||||
|
}
|
||||||
|
function modeField() {
|
||||||
|
var el = document.getElementById('sPinNew'), v = el.value;
|
||||||
|
el.value = '';
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
document.getElementById('sModeCode').addEventListener('click', function () {
|
||||||
|
var v = modeField();
|
||||||
|
if (!v) { toast('Type the new code above first'); return; }
|
||||||
send('pinset?c=' + encodeURIComponent(v));
|
send('pinset?c=' + encodeURIComponent(v));
|
||||||
document.getElementById('sPinNew').value = '';
|
});
|
||||||
|
document.getElementById('sModePwd').addEventListener('click', function () {
|
||||||
|
var v = modeField();
|
||||||
|
if (!v) { toast('Type the vault password above first'); return; }
|
||||||
|
send('pinset?pw=1&c=' + encodeURIComponent(v));
|
||||||
|
});
|
||||||
|
document.getElementById('sModeDevice').addEventListener('click', function () {
|
||||||
|
if (unlockMode === 'device') { toast('Already using the screen lock'); return; }
|
||||||
|
var v = modeField();
|
||||||
|
if (!v && unlockMode !== 'none') { toast('Type the current code or password above first'); return; }
|
||||||
|
send('pinclear?c=' + encodeURIComponent(v));
|
||||||
|
});
|
||||||
|
document.getElementById('btnUsePwd').addEventListener('click', function () {
|
||||||
|
PM.setAuthMode('login');
|
||||||
|
document.getElementById('pass').focus();
|
||||||
});
|
});
|
||||||
document.getElementById('sWipe').addEventListener('click', function (ev) {
|
document.getElementById('sWipe').addEventListener('click', function (ev) {
|
||||||
// DEUX APPUIS, comme pour retirer le code : un effacement sans retour ne se
|
// DEUX APPUIS, comme pour retirer le code : un effacement sans retour ne se
|
||||||
@@ -1675,27 +1712,6 @@ document.getElementById('sWipe').addEventListener('click', function (ev) {
|
|||||||
send('wipelocal');
|
send('wipelocal');
|
||||||
closeSettings();
|
closeSettings();
|
||||||
});
|
});
|
||||||
document.getElementById('sPinClear').addEventListener('click', function (ev) {
|
|
||||||
var b = ev.currentTarget;
|
|
||||||
if (b.getAttribute('data-armed') === null) {
|
|
||||||
b.setAttribute('data-armed', '1');
|
|
||||||
b.textContent = 'Really remove - tap again';
|
|
||||||
setTimeout(function () {
|
|
||||||
b.removeAttribute('data-armed');
|
|
||||||
b.textContent = 'Remove the unlock code';
|
|
||||||
}, 4000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b.removeAttribute('data-armed');
|
|
||||||
b.textContent = 'Remove the unlock code';
|
|
||||||
// LE CODE COURANT VOYAGE AVEC LA DEMANDE. Le coffre ouvert ne prouve rien :
|
|
||||||
// il peut l'etre depuis une heure et rester a l'ecran. Delphi compare a ce
|
|
||||||
// sous quoi le cache est reellement scelle, et refuse sinon.
|
|
||||||
send('pinclear?c=' + encodeURIComponent(
|
|
||||||
document.getElementById('sPinNew').value));
|
|
||||||
document.getElementById('sPinNew').value = '';
|
|
||||||
});
|
|
||||||
|
|
||||||
function goList() {
|
function goList() {
|
||||||
closeMenu();
|
closeMenu();
|
||||||
document.body.classList.remove('on-detail');
|
document.body.classList.remove('on-detail');
|
||||||
@@ -1826,6 +1842,12 @@ var PM = {
|
|||||||
syncPinbox();
|
syncPinbox();
|
||||||
document.getElementById('btnAuth').textContent =
|
document.getElementById('btnAuth').textContent =
|
||||||
(mode === 'register') ? 'Create vault' : 'Sign in';
|
(mode === 'register') ? 'Create vault' : 'Sign in';
|
||||||
|
syncUnlockUi();
|
||||||
|
},
|
||||||
|
|
||||||
|
setUnlockMode: function (mode, canDevice, container) {
|
||||||
|
unlockMode = mode; canDeviceLock = canDevice; hasContainer = container;
|
||||||
|
syncUnlockUi();
|
||||||
},
|
},
|
||||||
|
|
||||||
setPinNeeded: function (on) {
|
setPinNeeded: function (on) {
|
||||||
|
|||||||
+44
-3
@@ -337,6 +337,7 @@ type
|
|||||||
/// le code courant deja connu - c'est ce qui empeche un tiers d'en poser un
|
/// le code courant deja connu - c'est ce qui empeche un tiers d'en poser un
|
||||||
/// que le proprietaire ne connaitrait pas.
|
/// que le proprietaire ne connaitrait pas.
|
||||||
procedure SetUnlockCode(const ANew: string);
|
procedure SetUnlockCode(const ANew: string);
|
||||||
|
procedure PushUnlockMode;
|
||||||
/// Va chercher l'icone du site de l'entree ouverte, ou l'efface.
|
/// Va chercher l'icone du site de l'entree ouverte, ou l'efface.
|
||||||
procedure SetEntryIcon(AFetch: Boolean);
|
procedure SetEntryIcon(AFetch: Boolean);
|
||||||
/// Le depot a bouge, ou ne l'a plus : LE DRAPEAU ET SON TEMOIN ENSEMBLE.
|
/// Le depot a bouge, ou ne l'a plus : LE DRAPEAU ET SON TEMOIN ENSEMBLE.
|
||||||
@@ -534,6 +535,7 @@ begin
|
|||||||
WebCall('PM.setAuthMode("login")')
|
WebCall('PM.setAuthMode("login")')
|
||||||
else
|
else
|
||||||
WebCall('PM.setAuthMode("register")');
|
WebCall('PM.setAuthMode("register")');
|
||||||
|
PushUnlockMode;
|
||||||
|
|
||||||
LCanOpen := HasVault and not FVaultUnreadable;
|
LCanOpen := HasVault and not FVaultUnreadable;
|
||||||
if LCanOpen then
|
if LCanOpen then
|
||||||
@@ -1701,7 +1703,10 @@ begin
|
|||||||
Exit // Touch a deja eu lieu plus haut
|
Exit // Touch a deja eu lieu plus haut
|
||||||
|
|
||||||
else if LAction = 'state' then
|
else if LAction = 'state' then
|
||||||
FWebView := Param('view')
|
begin
|
||||||
|
FWebView := Param('view');
|
||||||
|
if FWebView = 'settings' then PushUnlockMode;
|
||||||
|
end
|
||||||
|
|
||||||
else if LAction = 'open' then
|
else if LAction = 'open' then
|
||||||
OpenEntry(StrToIntDef(Param('i'), -1))
|
OpenEntry(StrToIntDef(Param('i'), -1))
|
||||||
@@ -1789,7 +1794,16 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
else if LAction = 'pinset' then
|
else if LAction = 'pinset' then
|
||||||
SetUnlockCode(TNetEncoding.URL.Decode(Param('c')))
|
begin
|
||||||
|
// MODE MOT DE PASSE = le code EST le mot de passe du coffre. On le
|
||||||
|
// verifie : sinon une faute de frappe scellerait sous un "mot de passe"
|
||||||
|
// que l'utilisateur ne retapera jamais a l'identique.
|
||||||
|
if (Param('pw') = '1') and
|
||||||
|
((FPlain = '') or (TNetEncoding.URL.Decode(Param('c')) <> CachePwd)) then
|
||||||
|
WebCall('PM.toast("Wrong vault password")')
|
||||||
|
else
|
||||||
|
SetUnlockCode(TNetEncoding.URL.Decode(Param('c')));
|
||||||
|
end
|
||||||
|
|
||||||
else if LAction = 'pinclear' then
|
else if LAction = 'pinclear' then
|
||||||
ClearUnlockCode(TNetEncoding.URL.Decode(Param('c')))
|
ClearUnlockCode(TNetEncoding.URL.Decode(Param('c')))
|
||||||
@@ -3070,6 +3084,7 @@ begin
|
|||||||
Log('Unlock code set');
|
Log('Unlock code set');
|
||||||
WebCall('PM.toast("Unlock code set")');
|
WebCall('PM.toast("Unlock code set")');
|
||||||
WebCall('PM.pinChanged()');
|
WebCall('PM.pinChanged()');
|
||||||
|
PushUnlockMode;
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
begin
|
begin
|
||||||
@@ -3079,6 +3094,28 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
/// Dit a la page comment le cache est scelle. 'password' = scelle sous un code
|
||||||
|
/// egal au mot de passe du coffre - connu seulement une fois ouvert (FPinSealed).
|
||||||
|
procedure TForm8.PushUnlockMode;
|
||||||
|
var
|
||||||
|
LMode: string;
|
||||||
|
begin
|
||||||
|
if VaultNeedsPin then
|
||||||
|
begin
|
||||||
|
if (FPinSealed <> '') and (FPinSealed = CachePwd) then
|
||||||
|
LMode := 'password'
|
||||||
|
else
|
||||||
|
LMode := 'code';
|
||||||
|
end
|
||||||
|
else if VaultNeedsAuth then
|
||||||
|
LMode := 'device'
|
||||||
|
else
|
||||||
|
LMode := 'none';
|
||||||
|
WebCall(Format('PM.setUnlockMode("%s", %s, %s)',
|
||||||
|
[LMode, LowerCase(BoolToStr(BiometricAvailable, True)),
|
||||||
|
LowerCase(BoolToStr(HasLocalContainer, True))]));
|
||||||
|
end;
|
||||||
|
|
||||||
function TForm8.CachePwd: string;
|
function TForm8.CachePwd: string;
|
||||||
begin
|
begin
|
||||||
if HasLocalContainer then Result := FVaultPwd else Result := FSyncPwd;
|
if HasLocalContainer then Result := FVaultPwd else Result := FSyncPwd;
|
||||||
@@ -3117,7 +3154,10 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
try
|
try
|
||||||
SaveVault(FPlain, FETag, CachePwd, BiometricAvailable, False, '',
|
// Cle NEUVE : le verrouillage d'ecran a pu changer pendant que le code
|
||||||
|
// protegeait, et une ancienne paire invalidee scellerait un fichier
|
||||||
|
// impossible a rouvrir.
|
||||||
|
SaveVault(FPlain, FETag, CachePwd, BiometricAvailable, True, '',
|
||||||
FKey, FKeySalt, FKeyIters, True);
|
FKey, FKeySalt, FKeyIters, True);
|
||||||
if VaultNeedsPin then
|
if VaultNeedsPin then
|
||||||
begin
|
begin
|
||||||
@@ -3130,6 +3170,7 @@ begin
|
|||||||
Log('Unlock code removed');
|
Log('Unlock code removed');
|
||||||
WebCall('PM.toast("Unlock code removed")');
|
WebCall('PM.toast("Unlock code removed")');
|
||||||
WebCall('PM.pinChanged()');
|
WebCall('PM.pinChanged()');
|
||||||
|
PushUnlockMode;
|
||||||
ShowUnlock;
|
ShowUnlock;
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
|
|||||||
Reference in New Issue
Block a user