feat: the last three passwords travel, and the phone can show them
The desktop keeps twenty previous versions per entry and never sent any. It now sends three. Three, not twenty, because the trade is not symmetrical. On the desktop they sit encrypted column by column and never move. In the snapshot everything travels in the clear inside the container, and comes down into a phone cache sealed only by the device key - not by the master password. An old password stays sensitive: it is often still valid somewhere else. The real use of the list is short - "I changed it recently, what was it?" - and three cover it. The other seventeen would be copies with no need facing them. The phone reads them ON DEMAND from the raw snapshot, never into TVault: loading them with the vault would put every entry's old passwords in the clear in memory from the moment it opens, for something one looks at now and then. Copying goes by RANK, not by value. The page displays the text but never sends it back - that is the bridge's rule everywhere else, and an old password has no reason to be the exception just because it happens to be on screen. They leave with the plaintext at lock, on both sides.
This commit is contained in:
@@ -303,6 +303,29 @@ async function buildSyncSnapshot() {
|
||||
e.custom_fields, e.custom_fields_iv); }
|
||||
catch (_) {}
|
||||
}
|
||||
// TROIS ANCIENNES VERSIONS, PAS VINGT.
|
||||
//
|
||||
// La table en garde vingt, et c'est bien sur le poste : elles y restent
|
||||
// chiffrees colonne par colonne et ne bougent jamais. Dans l'instantane
|
||||
// tout voyage EN CLAIR a l'interieur du conteneur, et redescend dans le
|
||||
// cache d'un telephone que seule la cle de l'appareil scelle - pas le
|
||||
// mot de passe maitre. Un ancien mot de passe reste sensible : il est
|
||||
// souvent encore valide ailleurs.
|
||||
//
|
||||
// L'usage reel de cette liste est court - "je l'ai change recemment,
|
||||
// quel etait l'ancien ?" - et trois le couvrent. Les dix-sept autres
|
||||
// seraient des copies supplementaires sans besoin en face.
|
||||
let history = [];
|
||||
try {
|
||||
const hist = await api('/entries/' + e.id + '/history',
|
||||
{ headers: authHeaders() });
|
||||
for (const h of (hist || []).slice(0, 3)) {
|
||||
const old = await decryptPwd(h.encrypted_password, h.iv);
|
||||
if (old === '[ERROR]') continue;
|
||||
history.push({ password: old, changed_at: h.changed_at });
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
let attachments = [];
|
||||
try {
|
||||
const metas = await api('/entries/' + e.id + '/attachments',
|
||||
@@ -339,6 +362,11 @@ async function buildSyncSnapshot() {
|
||||
icon_custom: e.icon_custom ? 1 : 0,
|
||||
created_at: e.created_at,
|
||||
updated_at: e.updated_at,
|
||||
// Lecture seule pour les autres appareils : la table du poste est
|
||||
// la source, et applyRemoteSnapshot ignore ce champ. Il survit aux
|
||||
// ecritures du telephone parce que celui-ci modifie le JSON recu
|
||||
// sans jamais le reserialiser.
|
||||
password_history: history,
|
||||
});
|
||||
}
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user