← Commit history

v2.0.650 (insiders): vault migration keyed by the real service name; upgrade cycle waits for the old windows before relaunching

John Lauer ·36f72c915c ·1mo ago ·parent 1fc8a8f
4 files changed +27−21
rust/Cargo.lock+12−12
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"  [[package]] name = "adom-pup-bridge"-version = "2.0.649"+version = "2.0.650" dependencies = [  "pup-browser",  "pup-cdp",@@ -655,7 +655,7 @@ dependencies = [  [[package]] name = "pup-browser"-version = "2.0.649"+version = "2.0.650" dependencies = [  "pup-core",  "pup-host",@@ -667,7 +667,7 @@ dependencies = [  [[package]] name = "pup-cdp"-version = "2.0.649"+version = "2.0.650" dependencies = [  "serde_json",  "thiserror",@@ -677,7 +677,7 @@ dependencies = [  [[package]] name = "pup-core"-version = "2.0.649"+version = "2.0.650" dependencies = [  "serde",  "serde_json",@@ -687,7 +687,7 @@ dependencies = [  [[package]] name = "pup-dashboard"-version = "2.0.649"+version = "2.0.650" dependencies = [  "pup-cdp",  "pup-core",@@ -700,7 +700,7 @@ dependencies = [  [[package]] name = "pup-host"-version = "2.0.649"+version = "2.0.650" dependencies = [  "serde",  "serde_json",@@ -709,14 +709,14 @@ dependencies = [  [[package]] name = "pup-host-mac"-version = "2.0.649"+version = "2.0.650" dependencies = [  "pup-host", ]  [[package]] name = "pup-host-win"-version = "2.0.649"+version = "2.0.650" dependencies = [  "pup-core",  "pup-host",@@ -726,7 +726,7 @@ dependencies = [  [[package]] name = "pup-identity"-version = "2.0.649"+version = "2.0.650" dependencies = [  "fontdue",  "image",@@ -736,7 +736,7 @@ dependencies = [  [[package]] name = "pup-session"-version = "2.0.649"+version = "2.0.650" dependencies = [  "pup-core",  "serde",@@ -746,7 +746,7 @@ dependencies = [  [[package]] name = "pup-vault"-version = "2.0.649"+version = "2.0.650" dependencies = [  "pup-core",  "pup-host",@@ -757,7 +757,7 @@ dependencies = [  [[package]] name = "pup-verbs"-version = "2.0.649"+version = "2.0.650" dependencies = [  "base64",  "png 0.17.16",
rust/Cargo.toml+1−1
@@ -4,7 +4,7 @@ members = ["core", "host", "host-win", "host-mac", "cdp", "browser", "session",  # One version for the whole bridge, in lockstep with src/BRIDGE_VERSION (tools/ship.sh bumps both). [workspace.package]-version = "2.0.649"+version = "2.0.650" edition = "2021" license = "MIT" 
rust/host-win/src/lib.rs+7−7
@@ -407,7 +407,7 @@ mod secrets {             Some(v)         }     }-    fn load(h: &WinHost) -> std::collections::BTreeMap<String, String> {+    fn load(h: &WinHost, service: &str) -> std::collections::BTreeMap<String, String> {         let mut g = CACHE.lock().unwrap_or_else(|e| e.into_inner());         if let Some(m) = g.as_ref() { return m.clone(); }         let mut m: std::collections::BTreeMap<String, String> = std::fs::read(store_path(h)).ok().and_then(|b| dpapi(&b, false)).and_then(|j| serde_json::from_slice(&j).ok()).unwrap_or_default();@@ -419,11 +419,11 @@ mod secrets {                 for e in v["entries"].as_array().cloned().unwrap_or_default() {                     let acct = e["keytarAccount"].as_str().or(e["host"].as_str()).unwrap_or("").to_string();                     if acct.is_empty() { continue; }-                    let key = format!("adom-pup/{acct}");+                    let key = format!("{service}/{acct}");                     if m.contains_key(&key) { continue; }                     if let Some(secret) = cred_read(&key) { m.insert(key.clone(), secret); cred_delete(&key); moved += 1; }                 }-                if moved > 0 { let _ = save(h, &m); eprintln!("[vault] moved {moved} login(s) from Windows Credential Manager into the DPAPI store and freed their slots"); }+                if moved > 0 { let _ = save(h, &m); pup_core::log(format!("[vault] moved {moved} login(s) from Windows Credential Manager into the DPAPI store and freed their slots")); }             }         }         *g = Some(m.clone());@@ -453,23 +453,23 @@ mod secrets {     impl HostSecrets for WinHost {         fn secret_get(&self, service: &str, account: &str) -> Option<String> {             let key = format!("{service}/{account}");-            if let Some(v) = load(self).get(&key) { return Some(v.clone()); }+            if let Some(v) = load(self, service).get(&key) { return Some(v.clone()); }             // a legacy entry the index did not name: move it too             let v = cred_read(&key)?;-            let mut m = load(self); m.insert(key.clone(), v.clone());+            let mut m = load(self, service); m.insert(key.clone(), v.clone());             if save(self, &m).is_ok() { cred_delete(&key); }             Some(v)         }         fn secret_set(&self, service: &str, account: &str, secret: &str) -> Result<(), String> {             let key = format!("{service}/{account}");-            let mut m = load(self); m.insert(key.clone(), secret.to_string());+            let mut m = load(self, service); m.insert(key.clone(), secret.to_string());             save(self, &m)?;             cred_delete(&key);   // never keep a second copy in the capped store             Ok(())         }         fn secret_delete(&self, service: &str, account: &str) -> bool {             let key = format!("{service}/{account}");-            let mut m = load(self); let had = m.remove(&key).is_some();+            let mut m = load(self, service); let had = m.remove(&key).is_some();             let saved = save(self, &m).is_ok();             let legacy = cred_delete(&key);             (had && saved) || legacy
rust/verbs/src/extdrive.rs+7−1
@@ -109,8 +109,14 @@ pub fn reload_stale_worker(ctx: &Ctx) {     let ids: Vec<String> = files.iter().filter_map(|f| f["sessionId"].as_str().map(|s| s.to_string())).collect();     crate::recovery::reserve(&ids);     for id in &ids { ctx.sessions.remove(id); }+    let hwnds: Vec<i64> = files.iter().filter_map(|f| f["hwnd"].as_i64()).collect();     let n = crate::kill_extdrive(ctx);-    pup_core::log(format!("[extdrive] lane worker {} is behind pup {}: re-staged the extension and cycled the lane browser ({n} process(es)); relaunching its {} window(s) from their files on the new extension", have.replace('-', "."), want.replace('-', "."), ids.len()));+    // 2.0.650: WAIT for the windows to be gone before relaunching. The kill is asynchronous; relaunch_from_file saw+    // every window still "alive on glass", declined ("will re-adopt"), and the sessions were lost when the browser+    // finished dying (AdomLapper, 2.0.649 upgrade: 5 windows, 4 lost).+    let t0 = std::time::Instant::now();+    while t0.elapsed() < Duration::from_secs(8) && hwnds.iter().any(|h| ctx.host.is_alive(*h)) { std::thread::sleep(Duration::from_millis(200)); }+    pup_core::log(format!("[extdrive] lane worker {} is behind pup {}: re-staged the extension and cycled the lane browser ({n} process(es), windows gone after {} ms); relaunching its {} window(s) from their files on the new extension", have.replace('-', "."), want.replace('-', "."), t0.elapsed().as_millis(), ids.len()));     for f in files { crate::recovery::relaunch_from_file(ctx, &f); } }