mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-07 06:48:52 +00:00
Merge pull request #701 from PR0M3TH3AN/codex/verify-and-improve-manifest-identifier-handling
Fix manifest ID handling and add restore test
This commit is contained in:
@@ -406,6 +406,7 @@ def handle_retrieve_from_nostr(password_manager: PasswordManager):
|
||||
Handles the action of retrieving the encrypted password index from Nostr.
|
||||
"""
|
||||
try:
|
||||
password_manager.nostr_client.fingerprint = password_manager.current_fingerprint
|
||||
result = asyncio.run(password_manager.nostr_client.fetch_latest_snapshot())
|
||||
if result:
|
||||
manifest, chunks = result
|
||||
@@ -423,8 +424,12 @@ def handle_retrieve_from_nostr(password_manager: PasswordManager):
|
||||
print(colored("Encrypted index retrieved and saved successfully.", "green"))
|
||||
logging.info("Encrypted index retrieved and saved successfully from Nostr.")
|
||||
else:
|
||||
print(colored("Failed to retrieve data from Nostr.", "red"))
|
||||
logging.error("Failed to retrieve data from Nostr.")
|
||||
msg = (
|
||||
f"No Nostr events found for fingerprint"
|
||||
f" {password_manager.current_fingerprint}."
|
||||
)
|
||||
print(colored(msg, "red"))
|
||||
logging.error(msg)
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to retrieve from Nostr: {e}", exc_info=True)
|
||||
print(colored(f"Error: Failed to retrieve from Nostr: {e}", "red"))
|
||||
|
@@ -95,7 +95,7 @@ from datetime import datetime
|
||||
from utils.fingerprint_manager import FingerprintManager
|
||||
|
||||
# Import NostrClient
|
||||
from nostr.client import NostrClient, DEFAULT_RELAYS
|
||||
from nostr.client import NostrClient, DEFAULT_RELAYS, MANIFEST_ID_PREFIX
|
||||
from .config_manager import ConfigManager
|
||||
from .state_manager import StateManager
|
||||
|
||||
@@ -272,6 +272,8 @@ class PasswordManager:
|
||||
def notify(self, message: str, level: str = "INFO") -> None:
|
||||
"""Enqueue a notification and set it as the active message."""
|
||||
note = Notification(message, level)
|
||||
if not hasattr(self, "notifications"):
|
||||
self.notifications = queue.Queue()
|
||||
self.notifications.put(note)
|
||||
self._current_notification = note
|
||||
self._notification_expiry = time.time() + NOTIFICATION_DURATION
|
||||
@@ -605,6 +607,8 @@ class PasswordManager:
|
||||
selected_fingerprint = fingerprints[int(choice) - 1]
|
||||
self.fingerprint_manager.current_fingerprint = selected_fingerprint
|
||||
self.current_fingerprint = selected_fingerprint
|
||||
if not getattr(self, "manifest_id", None):
|
||||
self.manifest_id = f"{MANIFEST_ID_PREFIX}{selected_fingerprint}"
|
||||
|
||||
# Update fingerprint directory
|
||||
self.fingerprint_dir = (
|
||||
@@ -645,7 +649,9 @@ class PasswordManager:
|
||||
config_manager=getattr(self, "config_manager", None),
|
||||
parent_seed=getattr(self, "parent_seed", None),
|
||||
)
|
||||
if getattr(self, "manifest_id", None):
|
||||
if getattr(self, "manifest_id", None) and hasattr(
|
||||
self.nostr_client, "_state_lock"
|
||||
):
|
||||
from nostr.backup_models import Manifest
|
||||
|
||||
with self.nostr_client._state_lock:
|
||||
@@ -903,6 +909,8 @@ class PasswordManager:
|
||||
self.current_fingerprint = fingerprint
|
||||
self.fingerprint_manager.current_fingerprint = fingerprint
|
||||
self.fingerprint_dir = fingerprint_dir
|
||||
if not getattr(self, "manifest_id", None):
|
||||
self.manifest_id = f"{MANIFEST_ID_PREFIX}{fingerprint}"
|
||||
logging.info(f"Current seed profile set to {fingerprint}")
|
||||
|
||||
try:
|
||||
@@ -1174,7 +1182,9 @@ class PasswordManager:
|
||||
parent_seed=getattr(self, "parent_seed", None),
|
||||
)
|
||||
|
||||
if getattr(self, "manifest_id", None):
|
||||
if getattr(self, "manifest_id", None) and hasattr(
|
||||
self.nostr_client, "_state_lock"
|
||||
):
|
||||
from nostr.backup_models import Manifest
|
||||
|
||||
with self.nostr_client._state_lock:
|
||||
@@ -1197,6 +1207,8 @@ class PasswordManager:
|
||||
"""Always fetch the latest vault data from Nostr and update the local index."""
|
||||
start = time.perf_counter()
|
||||
try:
|
||||
if getattr(self, "current_fingerprint", None):
|
||||
self.nostr_client.fingerprint = self.current_fingerprint
|
||||
result = await self.nostr_client.fetch_latest_snapshot()
|
||||
if not result:
|
||||
if self.nostr_client.last_error:
|
||||
@@ -1346,6 +1358,8 @@ class PasswordManager:
|
||||
have_data = False
|
||||
start = time.perf_counter()
|
||||
try:
|
||||
if getattr(self, "current_fingerprint", None):
|
||||
self.nostr_client.fingerprint = self.current_fingerprint
|
||||
result = await self.nostr_client.fetch_latest_snapshot()
|
||||
if result:
|
||||
manifest, chunks = result
|
||||
@@ -4308,7 +4322,9 @@ class PasswordManager:
|
||||
parent_seed=getattr(self, "parent_seed", None),
|
||||
)
|
||||
|
||||
if getattr(self, "manifest_id", None):
|
||||
if getattr(self, "manifest_id", None) and hasattr(
|
||||
self.nostr_client, "_state_lock"
|
||||
):
|
||||
from nostr.backup_models import Manifest
|
||||
|
||||
with self.nostr_client._state_lock:
|
||||
|
49
src/tests/test_nostr_restore_flow.py
Normal file
49
src/tests/test_nostr_restore_flow.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from pathlib import Path
|
||||
|
||||
import main
|
||||
from helpers import create_vault, dummy_nostr_client, TEST_SEED, TEST_PASSWORD
|
||||
from seedpass.core.entry_management import EntryManager
|
||||
from seedpass.core.backup import BackupManager
|
||||
from seedpass.core.config_manager import ConfigManager
|
||||
from seedpass.core.manager import PasswordManager, EncryptionMode
|
||||
|
||||
|
||||
def _init_pm(dir_path: Path, client) -> PasswordManager:
|
||||
vault, enc_mgr = create_vault(dir_path, TEST_SEED, TEST_PASSWORD)
|
||||
cfg_mgr = ConfigManager(vault, dir_path)
|
||||
backup_mgr = BackupManager(dir_path, cfg_mgr)
|
||||
entry_mgr = EntryManager(vault, backup_mgr)
|
||||
|
||||
pm = PasswordManager.__new__(PasswordManager)
|
||||
pm.encryption_mode = EncryptionMode.SEED_ONLY
|
||||
pm.encryption_manager = enc_mgr
|
||||
pm.vault = vault
|
||||
pm.entry_manager = entry_mgr
|
||||
pm.backup_manager = backup_mgr
|
||||
pm.config_manager = cfg_mgr
|
||||
pm.nostr_client = client
|
||||
pm.fingerprint_dir = dir_path
|
||||
pm.current_fingerprint = "fp"
|
||||
pm.is_dirty = False
|
||||
return pm
|
||||
|
||||
|
||||
def test_restore_flow_from_snapshot(monkeypatch, tmp_path):
|
||||
client, relay = dummy_nostr_client.__wrapped__(tmp_path / "srv", monkeypatch)
|
||||
|
||||
dir_a = tmp_path / "A"
|
||||
dir_b = tmp_path / "B"
|
||||
dir_a.mkdir()
|
||||
dir_b.mkdir()
|
||||
|
||||
pm_a = _init_pm(dir_a, client)
|
||||
pm_a.entry_manager.add_entry("site1", 12)
|
||||
pm_a.sync_vault()
|
||||
assert relay.manifests
|
||||
|
||||
pm_b = _init_pm(dir_b, client)
|
||||
monkeypatch.setattr(main, "pause", lambda *a, **k: None)
|
||||
main.handle_retrieve_from_nostr(pm_b)
|
||||
|
||||
labels = [e[1] for e in pm_b.entry_manager.list_entries()]
|
||||
assert labels == ["site1"]
|
Reference in New Issue
Block a user