mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-09 07:48:57 +00:00
Merge pull request #295 from PR0M3TH3AN/codex/sync-data-after-user-logs-in
sync on login
This commit is contained in:
@@ -187,6 +187,7 @@ class PasswordManager:
|
|||||||
self.initialize_managers()
|
self.initialize_managers()
|
||||||
self.locked = False
|
self.locked = False
|
||||||
self.update_activity()
|
self.update_activity()
|
||||||
|
self.sync_index_from_nostr()
|
||||||
|
|
||||||
def initialize_fingerprint_manager(self):
|
def initialize_fingerprint_manager(self):
|
||||||
"""
|
"""
|
||||||
@@ -833,6 +834,29 @@ class PasswordManager:
|
|||||||
print(colored(f"Error: Failed to initialize managers: {e}", "red"))
|
print(colored(f"Error: Failed to initialize managers: {e}", "red"))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
def sync_index_from_nostr(self) -> None:
|
||||||
|
"""Always fetch the latest vault data from Nostr and update the local index."""
|
||||||
|
try:
|
||||||
|
result = asyncio.run(self.nostr_client.fetch_latest_snapshot())
|
||||||
|
if not result:
|
||||||
|
return
|
||||||
|
manifest, chunks = result
|
||||||
|
encrypted = gzip.decompress(b"".join(chunks))
|
||||||
|
if manifest.delta_since:
|
||||||
|
try:
|
||||||
|
version = int(manifest.delta_since)
|
||||||
|
deltas = asyncio.run(self.nostr_client.fetch_deltas_since(version))
|
||||||
|
if deltas:
|
||||||
|
encrypted = deltas[-1]
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
current = self.vault.get_encrypted_index()
|
||||||
|
if current != encrypted:
|
||||||
|
self.vault.decrypt_and_save_index_from_nostr(encrypted)
|
||||||
|
logger.info("Local database synchronized from Nostr.")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Unable to sync index from Nostr: {e}")
|
||||||
|
|
||||||
def sync_index_from_nostr_if_missing(self) -> None:
|
def sync_index_from_nostr_if_missing(self) -> None:
|
||||||
"""Retrieve the password database from Nostr if it doesn't exist locally."""
|
"""Retrieve the password database from Nostr if it doesn't exist locally."""
|
||||||
index_file = self.fingerprint_dir / "seedpass_entries_db.json.enc"
|
index_file = self.fingerprint_dir / "seedpass_entries_db.json.enc"
|
||||||
|
@@ -81,6 +81,7 @@ def test_password_change_and_unlock(monkeypatch):
|
|||||||
)
|
)
|
||||||
monkeypatch.setattr(PasswordManager, "initialize_bip85", lambda self: None)
|
monkeypatch.setattr(PasswordManager, "initialize_bip85", lambda self: None)
|
||||||
monkeypatch.setattr(PasswordManager, "initialize_managers", lambda self: None)
|
monkeypatch.setattr(PasswordManager, "initialize_managers", lambda self: None)
|
||||||
|
monkeypatch.setattr(PasswordManager, "sync_index_from_nostr", lambda self: None)
|
||||||
|
|
||||||
pm.unlock_vault()
|
pm.unlock_vault()
|
||||||
|
|
||||||
|
26
src/tests/test_unlock_sync.py
Normal file
26
src/tests/test_unlock_sync.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import time
|
||||||
|
from types import SimpleNamespace
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.path.append(str(Path(__file__).resolve().parents[1]))
|
||||||
|
|
||||||
|
from password_manager.manager import PasswordManager
|
||||||
|
|
||||||
|
|
||||||
|
def test_unlock_triggers_sync(monkeypatch, tmp_path):
|
||||||
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
|
pm.fingerprint_dir = tmp_path
|
||||||
|
pm.setup_encryption_manager = lambda *a, **k: None
|
||||||
|
pm.initialize_bip85 = lambda: None
|
||||||
|
pm.initialize_managers = lambda: None
|
||||||
|
called = {"sync": False}
|
||||||
|
|
||||||
|
def fake_sync(self):
|
||||||
|
called["sync"] = True
|
||||||
|
|
||||||
|
monkeypatch.setattr(PasswordManager, "sync_index_from_nostr", fake_sync)
|
||||||
|
|
||||||
|
pm.unlock_vault()
|
||||||
|
|
||||||
|
assert called["sync"]
|
Reference in New Issue
Block a user