commit 8f9ee257ea8c2f14be0af88f137ce06882a97bab
parent 95bcf4cc2a0aec19fc323620d71d8c517f87e2f8
Author: triesap <tyson@radroots.org>
Date: Wed, 1 Jul 2026 22:56:37 +0000
nostr_accounts: remove account migration paths
Diffstat:
2 files changed, 41 insertions(+), 93 deletions(-)
diff --git a/crates/nostr_accounts/src/manager.rs b/crates/nostr_accounts/src/manager.rs
@@ -47,20 +47,14 @@ impl RadrootsNostrAccountsManager {
vault: Arc<dyn RadrootsSecretVault>,
) -> Result<Self, RadrootsNostrAccountsError> {
let mut state = store.load()?;
- let mut state_dirty = match state.version {
- 1 => {
- state.version = crate::model::RADROOTS_NOSTR_ACCOUNTS_STORE_VERSION;
- true
- }
- crate::model::RADROOTS_NOSTR_ACCOUNTS_STORE_VERSION => false,
- _ => {
- return Err(RadrootsNostrAccountsError::InvalidState(format!(
- "unsupported accounts schema version {}",
- state.version
- )));
- }
- };
+ if state.version != crate::model::RADROOTS_NOSTR_ACCOUNTS_STORE_VERSION {
+ return Err(RadrootsNostrAccountsError::InvalidState(format!(
+ "unsupported accounts schema version {}",
+ state.version
+ )));
+ }
+ let mut state_dirty = false;
if let Some(default_account_id) = state.default_account_id.clone() {
let exists = state
.accounts
@@ -470,16 +464,6 @@ impl RadrootsNostrAccountsManager {
.map_err(Into::into)
}
- pub fn migrate_legacy_identity_file(
- &self,
- path: impl AsRef<Path>,
- label: Option<String>,
- make_default: bool,
- ) -> Result<RadrootsIdentityId, RadrootsNostrAccountsError> {
- let identity = RadrootsIdentity::load_from_path_auto(path)?;
- self.upsert_identity(&identity, label, make_default)
- }
-
fn resolve_signing_identity(
&self,
record: RadrootsNostrAccountRecord,
@@ -855,62 +839,39 @@ mod tests {
}
#[test]
- fn new_migrates_legacy_store_file_to_default_account_semantics() {
+ fn new_rejects_non_current_store_file_schema() {
let temp = tempfile::tempdir().expect("tempdir");
let path = temp.path().join("accounts.json");
- let identity = RadrootsIdentity::generate();
- let public_identity = identity.to_public();
- let account_id = public_identity.id.clone();
- let legacy_record =
- RadrootsNostrAccountRecord::new(public_identity, Some("legacy".into()), 1);
fs::write(
&path,
serde_json::to_vec_pretty(&json!({
"version": 1,
- "selected_account_id": account_id,
- "accounts": [legacy_record],
+ "default_account_id": RadrootsIdentity::generate().id(),
+ "accounts": [],
}))
- .expect("serialize legacy store"),
+ .expect("serialize store"),
)
- .expect("write legacy store");
+ .expect("write store");
let vault = Arc::new(RadrootsNostrSecretVaultMemory::new());
- vault
- .store_secret(
- account_secret_slot(&account_id).as_str(),
- identity.secret_key_hex().as_str(),
- )
- .expect("store secret");
-
- let manager = RadrootsNostrAccountsManager::new(
+ let err = match RadrootsNostrAccountsManager::new(
Arc::new(RadrootsNostrFileAccountStore::new(&path)),
vault,
- )
- .expect("manager");
-
- assert_eq!(
- manager.default_account_id().expect("default"),
- Some(account_id.clone())
- );
+ ) {
+ Ok(_) => panic!("unsupported schema was accepted"),
+ Err(error) => error,
+ };
- let migrated_store: serde_json::Value =
- serde_json::from_slice(&fs::read(&path).expect("read migrated store"))
- .expect("parse migrated store");
- assert_eq!(
- migrated_store["version"],
- serde_json::Value::from(crate::model::RADROOTS_NOSTR_ACCOUNTS_STORE_VERSION),
- );
- assert_eq!(
- migrated_store["default_account_id"],
- serde_json::Value::from(account_id.to_string()),
+ assert!(
+ err.to_string()
+ .contains("unsupported accounts schema version 1")
);
- assert!(migrated_store.get("selected_account_id").is_none());
}
#[test]
fn new_reports_save_error_when_dirty_state_requires_rewrite() {
let mut state = RadrootsNostrAccountStoreState::default();
- state.version = 1;
+ state.default_account_id = Some(RadrootsIdentity::generate().id());
let store = Arc::new(SaveErrorStore::new(state));
let vault = Arc::new(RadrootsNostrSecretVaultMemory::new());
@@ -1303,28 +1264,27 @@ mod tests {
}
#[test]
- fn migrate_legacy_identity_file_imports_identity() {
- let temp = tempfile::tempdir().expect("tempdir");
- let legacy_path = temp.path().join("legacy_identity.json");
- let legacy_identity = RadrootsIdentity::generate();
- legacy_identity
- .save_json(&legacy_path)
- .expect("legacy save");
+ fn manager_source_rejects_identity_migration_api() {
+ let source = include_str!("manager.rs");
+ let removed_api = ["migrate", "_legacy", "_identity", "_file"].concat();
+ assert!(
+ !source.contains(removed_api.as_str()),
+ "nostr accounts manager must not expose removed identity migration API"
+ );
+ }
- let store = Arc::new(RadrootsNostrFileAccountStore::new(
- temp.path().join("accounts.json"),
- ));
- let vault = Arc::new(RadrootsNostrSecretVaultMemory::new());
- let manager = RadrootsNostrAccountsManager::new(store, vault).expect("manager");
- let id = manager
- .migrate_legacy_identity_file(&legacy_path, Some("legacy".into()), true)
- .expect("migrate");
- assert_eq!(
- manager
- .default_account_id()
- .expect("default")
- .expect("default id"),
- id
+ #[test]
+ fn model_source_rejects_account_store_aliases() {
+ let source = include_str!("model.rs");
+ let removed_field = ["selected", "_account", "_id"].concat();
+ let removed_serde_alias = ["serde", "(alias"].concat();
+ assert!(
+ !source.contains(removed_field.as_str()),
+ "nostr account store model must not accept removed account-store field aliases"
+ );
+ assert!(
+ !source.contains(removed_serde_alias.as_str()),
+ "nostr account store model must not expose serde alias compatibility"
);
}
@@ -1934,17 +1894,6 @@ mod tests {
}
#[test]
- fn migrate_legacy_identity_file_returns_error_for_missing_path() {
- let manager = RadrootsNostrAccountsManager::new_in_memory();
- let temp = tempfile::tempdir().expect("tempdir");
- let missing = temp.path().join("missing_legacy.json");
- let migrated = manager
- .migrate_legacy_identity_file(&missing, None, false)
- .expect_err("missing legacy");
- assert!(migrated.to_string().starts_with("identity error:"));
- }
-
- #[test]
fn manager_reports_poisoned_state_locks() {
let manager = RadrootsNostrAccountsManager::new_in_memory();
poison_manager_state(&manager);
diff --git a/crates/nostr_accounts/src/model.rs b/crates/nostr_accounts/src/model.rs
@@ -16,7 +16,6 @@ pub struct RadrootsNostrAccountRecord {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RadrootsNostrAccountStoreState {
pub version: u32,
- #[serde(alias = "selected_account_id")]
pub default_account_id: Option<RadrootsIdentityId>,
pub accounts: Vec<RadrootsNostrAccountRecord>,
}