Preserve legacy credentials when vault migration cannot run

Users upgrading from the plaintext credentials file should not lose access to existing settings just because the OS vault backend is temporarily unavailable or migration cannot be written. Keep the old file migration-only, but return its contents as the compatibility source when vault reads or writes fail.

Constraint: credentials.json remains a legacy compatibility source only, not the normal write target.

Rejected: Return defaults on vault read/write errors | hides existing upgrade data and makes configured providers appear empty.

Confidence: high

Scope-risk: narrow

Directive: Do not reintroduce plaintext writes; fallback reads are only for pre-PR legacy migration compatibility.

Tested: cargo check --manifest-path src-tauri/Cargo.toml

Tested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit

Tested: npm run -s build

Tested: git diff --check

Not-tested: Manual vault-unavailable upgrade run on Windows/macOS/Linux.

Related: #230
This commit is contained in:
H-Chris233 committed 2026-05-06 14:39:40 +08:00
1 parent 64296e3555
commit ddd6528088
1 file changed
+8 -6
@@ -388,26 +388,28 @@ fn load_keyring_credentials() -> Result<Option<CredsRoot>> {
.context("decode system credential vault payload")
}
fn load_legacy_credentials() -> Option<CredsRoot> {
credentials_path()
.ok()
.and_then(|p| read_legacy_credentials_file(&p))
}
fn load_credentials() -> CredsRoot {
match load_keyring_credentials() {
Ok(Some(root)) => return root,
Ok(None) => {}
Err(e) => {
log::warn!("[vault] system credential read failed: {e}");
return CredsRoot::default();
return load_legacy_credentials().unwrap_or_default();
}
}
let Some(legacy) = credentials_path()
.ok()
.and_then(|p| read_legacy_credentials_file(&p))
else {
let Some(legacy) = load_legacy_credentials() else {
return CredsRoot::default();
};
if let Err(e) = save_credentials(&legacy) {
log::warn!("[vault] legacy credential migration failed: {e}");
return CredsRoot::default();
}
legacy
}