fix(android): the unlock code no longer changes by itself

It went from 0000 to 00000000 with nobody deciding it. The typed code and the
code the cache is sealed under were the same variable, so every write of the
cache re-sealed under whatever sat in the field - a sync, which asks for no
code at all, was enough to change it, silently.

They are two things now. Only opening the vault touches the seal, because
that is the one moment we know the current code is known: the decryption just
proved it. Everything else - sync, background refresh, saving an entry -
rewrites the cache under the code already in place.

Hence a second field, shown only once a code exists: the current one must open
the vault for the new one to take. Without it this fix would have locked the
device under the code set by accident, which is exactly the harm it is meant
to prevent.
This commit is contained in:
r-zakarya
2026-08-21 16:30:57 +01:00
parent 5107ebf7b2
commit 5522089939
3 changed files with 90 additions and 11 deletions
+22 -2
View File
@@ -289,6 +289,18 @@
type="password" inputmode="numeric" autocomplete="off">
<div class="in-x" data-clear="pin">&#215;</div>
</div>
<!-- CHANGER LE CODE demande de connaitre l'actuel : le champ du dessus
doit ouvrir le coffre pour que celui-ci prenne effet. Sans cette
regle, toute ecriture du cache rescellait sous ce qui trainait dans
le champ - une synchronisation, qui ne demande pourtant aucun code,
suffisait a le changer sans qu'un mot le dise.
Cache tant qu'aucun code n'est pose : on n'en change pas un qui
n'existe pas, on le pose avec le champ du dessus. -->
<div class="in-wrap" id="pin2wrap" hidden>
<input class="field-in" id="pin2" placeholder="new unlock code"
type="password" inputmode="numeric" autocomplete="off">
<div class="in-x" data-clear="pin2">&#215;</div>
</div>
</div>
<!-- UNE CROIX PAR CHAMP. Vider par la touche retour demande une quarantaine
d'appuis sur un jeton, et laisse facilement un caractere - ce qui donne
@@ -423,9 +435,10 @@ function pushConfig() {
send('cfg?u=' + encodeURIComponent(elUrl.value.trim())
+ '&t=' + encodeURIComponent(elTok.value.trim())
+ '&p=' + encodeURIComponent(elPwd.value)
+ '&c=' + encodeURIComponent(elPin.value));
+ '&c=' + encodeURIComponent(elPin.value)
+ '&c2=' + encodeURIComponent(document.getElementById('pin2').value));
}
[elUrl, elTok, elPwd, elPin].forEach(function (el) {
[elUrl, elTok, elPwd, elPin, document.getElementById('pin2')].forEach(function (el) {
el.addEventListener('change', pushConfig);
el.addEventListener('blur', pushConfig);
});
@@ -954,6 +967,13 @@ var PM = {
setPinNeeded: function (on) {
document.getElementById('pin').placeholder =
on ? 'unlock code' : 'set an unlock code (optional)';
document.getElementById('pin2wrap').hidden = !on;
},
/// Le code vient d'etre change : le champ du nouveau n'a plus rien a dire,
/// et le laisser rempli le reproposerait a chaque ouverture.
pinChanged: function () {
document.getElementById('pin2').value = '';
document.getElementById('pin').value = '';
},
focusPin: function () { document.getElementById('pin').focus(); },
log: function (line) {