diff --git a/src/password_manager/config_manager.py b/src/password_manager/config_manager.py index 5d9d620..7c02aae 100644 --- a/src/password_manager/config_manager.py +++ b/src/password_manager/config_manager.py @@ -44,6 +44,7 @@ class ConfigManager: "pin_hash": "", "password_hash": "", "inactivity_timeout": INACTIVITY_TIMEOUT, + "additional_backup_path": "", } try: data = self.vault.load_config() @@ -54,6 +55,7 @@ class ConfigManager: data.setdefault("pin_hash", "") data.setdefault("password_hash", "") data.setdefault("inactivity_timeout", INACTIVITY_TIMEOUT) + data.setdefault("additional_backup_path", "") # Migrate legacy hashed_password.enc if present and password_hash is missing legacy_file = self.fingerprint_dir / "hashed_password.enc" @@ -130,3 +132,15 @@ class ConfigManager: """Retrieve the inactivity timeout setting in seconds.""" config = self.load_config(require_pin=False) return float(config.get("inactivity_timeout", INACTIVITY_TIMEOUT)) + + def set_additional_backup_path(self, path: Optional[str]) -> None: + """Persist an optional additional backup path in the config.""" + config = self.load_config(require_pin=False) + config["additional_backup_path"] = path or "" + self.save_config(config) + + def get_additional_backup_path(self) -> Optional[str]: + """Retrieve the additional backup path if configured.""" + config = self.load_config(require_pin=False) + value = config.get("additional_backup_path", "") + return value or None diff --git a/src/tests/test_config_manager.py b/src/tests/test_config_manager.py index 92f3f31..5be4603 100644 --- a/src/tests/test_config_manager.py +++ b/src/tests/test_config_manager.py @@ -22,6 +22,7 @@ def test_config_defaults_and_round_trip(): assert cfg["relays"] == list(DEFAULT_RELAYS) assert cfg["pin_hash"] == "" assert cfg["password_hash"] == "" + assert cfg["additional_backup_path"] == "" cfg_mgr.set_pin("1234") cfg_mgr.set_relays(["wss://example.com"], require_pin=False) @@ -111,3 +112,21 @@ def test_password_hash_migrates_from_file(tmp_path): (tmp_path / "hashed_password.enc").unlink() cfg2 = cfg_mgr.load_config(require_pin=False) assert cfg2["password_hash"] == hashed.decode() + + +def test_additional_backup_path_round_trip(): + with TemporaryDirectory() as tmpdir: + vault, enc_mgr = create_vault(Path(tmpdir), TEST_SEED, TEST_PASSWORD) + cfg_mgr = ConfigManager(vault, Path(tmpdir)) + + # default should be empty string + assert cfg_mgr.load_config(require_pin=False)["additional_backup_path"] == "" + + cfg_mgr.set_additional_backup_path("/tmp/my_backups") + cfg = cfg_mgr.load_config(require_pin=False) + assert cfg["additional_backup_path"] == "/tmp/my_backups" + assert cfg_mgr.get_additional_backup_path() == "/tmp/my_backups" + + cfg_mgr.set_additional_backup_path(None) + cfg2 = cfg_mgr.load_config(require_pin=False) + assert cfg2["additional_backup_path"] == ""