From d52fa58354d113e76e216b4322f69cc060975c72 Mon Sep 17 00:00:00 2001 From: Avi Date: Sun, 20 Sep 2026 20:42:08 -0500 Subject: [PATCH] test(e2e): isolate the e2e vault at the real data_dir path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both e2e vault setups wrote the isolation vault to $XDG_DATA_HOME/ profiles_vault.json, but vault::data_dir() is $XDG_DATA_HOME/keynectr — so the app never found the seeded vault and load_vault() fell through to try_migrate_legacy_vault(), which picked up the legacy repo vault (CARGO_MANIFEST_DIR/profiles_vault.json — the user's real profile with a plaintext secret key) and migrated it into the test process. Forensics: two legacy-vault backups appeared Sep 19 20:43:54 + 20:44:30, exactly the cargo-test runs around the edd4e56 commit, proving every e2e run was migrating the user's real legacy vault. The pairing-trace "identity adopted" lines from that window were e2e sessions, not a live Amber scan (no "pairing started" line, no new capture events — session- level traces are not gated by live_capture). Fix: seed the vault at tmp/keynectr/profiles_vault.json. Verified green after the change: repo legacy vault byte-identical, backup count unchanged, 3/3 e2e pass. --- tests/nip46_e2e.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/nip46_e2e.rs b/tests/nip46_e2e.rs index 470b7e7..c166a5f 100644 --- a/tests/nip46_e2e.rs +++ b/tests/nip46_e2e.rs @@ -342,9 +342,14 @@ async fn nip46_client_handshake_and_sign_against_fake_amber() { let app = { let _guard = VAULT_ENV_LOCK.lock().unwrap(); let tmp = std::env::temp_dir().join(format!("keynectr-e2e-{}", std::process::id())); - std::fs::create_dir_all(&tmp).unwrap(); + // data_dir() is $XDG_DATA_HOME/keynectr — the isolation vault must + // live there. Writing it one level too shallow left the app finding + // NO vault at the real path, which silently migrated the legacy + // repo vault (with the user's real keys!) into the test instead. + let app_dir = tmp.join("keynectr"); + std::fs::create_dir_all(&app_dir).unwrap(); std::fs::write( - tmp.join("profiles_vault.json"), + app_dir.join("profiles_vault.json"), serde_json::to_string(&Vault::empty()).unwrap(), ) .unwrap(); @@ -634,9 +639,13 @@ async fn run_qr_pairing(connect_shape: &'static str) { std::process::id(), connect_shape )); - std::fs::create_dir_all(&tmp).unwrap(); + // Must be $XDG_DATA_HOME/keynectr/profiles_vault.json (see the + // sibling test above): the old shallow path let every e2e run + // migrate the real legacy repo vault into the test process. + let app_dir = tmp.join("keynectr"); + std::fs::create_dir_all(&app_dir).unwrap(); std::fs::write( - tmp.join("profiles_vault.json"), + app_dir.join("profiles_vault.json"), serde_json::to_string(&Vault::empty()).unwrap(), ) .unwrap();