mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-09 15:58:48 +00:00
Return all Nostr event IDs
This commit is contained in:
17
src/main.py
17
src/main.py
@@ -365,14 +365,15 @@ def handle_post_to_nostr(
|
|||||||
Handles the action of posting the encrypted password index to Nostr.
|
Handles the action of posting the encrypted password index to Nostr.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
event_id = password_manager.sync_vault(alt_summary=alt_summary)
|
result = password_manager.sync_vault(alt_summary=alt_summary)
|
||||||
if event_id:
|
if result:
|
||||||
print(
|
print(colored("\N{WHITE HEAVY CHECK MARK} Sync complete.", "green"))
|
||||||
colored(
|
print("Event IDs:")
|
||||||
f"\N{WHITE HEAVY CHECK MARK} Sync complete. Event ID: {event_id}",
|
print(f" manifest: {result['manifest_id']}")
|
||||||
"green",
|
for cid in result["chunk_ids"]:
|
||||||
)
|
print(f" chunk: {cid}")
|
||||||
)
|
for did in result["delta_ids"]:
|
||||||
|
print(f" delta: {did}")
|
||||||
logging.info("Encrypted index posted to Nostr successfully.")
|
logging.info("Encrypted index posted to Nostr successfully.")
|
||||||
else:
|
else:
|
||||||
print(colored("\N{CROSS MARK} Sync failed…", "red"))
|
print(colored("\N{CROSS MARK} Sync failed…", "red"))
|
||||||
|
@@ -3517,8 +3517,10 @@ class PasswordManager:
|
|||||||
# Re-raise the exception to inform the calling function of the failure
|
# Re-raise the exception to inform the calling function of the failure
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def sync_vault(self, alt_summary: str | None = None) -> str | None:
|
def sync_vault(
|
||||||
"""Publish the current vault contents to Nostr."""
|
self, alt_summary: str | None = None
|
||||||
|
) -> dict[str, list[str] | str] | None:
|
||||||
|
"""Publish the current vault contents to Nostr and return event IDs."""
|
||||||
try:
|
try:
|
||||||
if getattr(self, "offline_mode", False):
|
if getattr(self, "offline_mode", False):
|
||||||
return None
|
return None
|
||||||
@@ -3526,16 +3528,28 @@ class PasswordManager:
|
|||||||
if not encrypted:
|
if not encrypted:
|
||||||
return None
|
return None
|
||||||
pub_snap = getattr(self.nostr_client, "publish_snapshot", None)
|
pub_snap = getattr(self.nostr_client, "publish_snapshot", None)
|
||||||
|
manifest = None
|
||||||
|
event_id = None
|
||||||
if callable(pub_snap):
|
if callable(pub_snap):
|
||||||
if asyncio.iscoroutinefunction(pub_snap):
|
if asyncio.iscoroutinefunction(pub_snap):
|
||||||
_, event_id = asyncio.run(pub_snap(encrypted))
|
manifest, event_id = asyncio.run(pub_snap(encrypted))
|
||||||
else:
|
else:
|
||||||
_, event_id = pub_snap(encrypted)
|
manifest, event_id = pub_snap(encrypted)
|
||||||
else:
|
else:
|
||||||
# Fallback for tests using simplified stubs
|
# Fallback for tests using simplified stubs
|
||||||
event_id = self.nostr_client.publish_json_to_nostr(encrypted)
|
event_id = self.nostr_client.publish_json_to_nostr(encrypted)
|
||||||
self.is_dirty = False
|
self.is_dirty = False
|
||||||
return event_id
|
if event_id is None:
|
||||||
|
return None
|
||||||
|
chunk_ids: list[str] = []
|
||||||
|
if manifest is not None:
|
||||||
|
chunk_ids = [c.event_id for c in manifest.chunks if c.event_id]
|
||||||
|
delta_ids = getattr(self.nostr_client, "_delta_events", [])
|
||||||
|
return {
|
||||||
|
"manifest_id": event_id,
|
||||||
|
"chunk_ids": chunk_ids,
|
||||||
|
"delta_ids": list(delta_ids),
|
||||||
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Failed to sync vault: {e}", exc_info=True)
|
logging.error(f"Failed to sync vault: {e}", exc_info=True)
|
||||||
return None
|
return None
|
||||||
|
@@ -419,9 +419,14 @@ def vault_reveal_parent_seed(
|
|||||||
def nostr_sync(ctx: typer.Context) -> None:
|
def nostr_sync(ctx: typer.Context) -> None:
|
||||||
"""Sync with configured Nostr relays."""
|
"""Sync with configured Nostr relays."""
|
||||||
pm = _get_pm(ctx)
|
pm = _get_pm(ctx)
|
||||||
event_id = pm.sync_vault()
|
result = pm.sync_vault()
|
||||||
if event_id:
|
if result:
|
||||||
typer.echo(event_id)
|
typer.echo("Event IDs:")
|
||||||
|
typer.echo(f"- manifest: {result['manifest_id']}")
|
||||||
|
for cid in result["chunk_ids"]:
|
||||||
|
typer.echo(f"- chunk: {cid}")
|
||||||
|
for did in result["delta_ids"]:
|
||||||
|
typer.echo(f"- delta: {did}")
|
||||||
else:
|
else:
|
||||||
typer.echo("Error: Failed to sync vault")
|
typer.echo("Error: Failed to sync vault")
|
||||||
|
|
||||||
|
@@ -53,7 +53,11 @@ class DummyPM:
|
|||||||
self.nostr_client = SimpleNamespace(
|
self.nostr_client = SimpleNamespace(
|
||||||
key_manager=SimpleNamespace(get_npub=lambda: "npub")
|
key_manager=SimpleNamespace(get_npub=lambda: "npub")
|
||||||
)
|
)
|
||||||
self.sync_vault = lambda: "event"
|
self.sync_vault = lambda: {
|
||||||
|
"manifest_id": "event",
|
||||||
|
"chunk_ids": ["c1"],
|
||||||
|
"delta_ids": [],
|
||||||
|
}
|
||||||
self.config_manager = SimpleNamespace(
|
self.config_manager = SimpleNamespace(
|
||||||
load_config=lambda require_pin=False: {"inactivity_timeout": 30},
|
load_config=lambda require_pin=False: {"inactivity_timeout": 30},
|
||||||
set_inactivity_timeout=lambda v: None,
|
set_inactivity_timeout=lambda v: None,
|
||||||
|
@@ -9,12 +9,17 @@ import main
|
|||||||
|
|
||||||
def test_handle_post_success(capsys):
|
def test_handle_post_success(capsys):
|
||||||
pm = SimpleNamespace(
|
pm = SimpleNamespace(
|
||||||
sync_vault=lambda alt_summary=None: "abcd",
|
sync_vault=lambda alt_summary=None: {
|
||||||
|
"manifest_id": "abcd",
|
||||||
|
"chunk_ids": ["c1", "c2"],
|
||||||
|
"delta_ids": ["d1"],
|
||||||
|
},
|
||||||
)
|
)
|
||||||
main.handle_post_to_nostr(pm)
|
main.handle_post_to_nostr(pm)
|
||||||
out = capsys.readouterr().out
|
out = capsys.readouterr().out
|
||||||
assert "✅ Sync complete." in out
|
assert "✅ Sync complete." in out
|
||||||
assert "abcd" in out
|
assert "abcd" in out
|
||||||
|
assert "c1" in out and "c2" in out and "d1" in out
|
||||||
|
|
||||||
|
|
||||||
def test_handle_post_failure(capsys):
|
def test_handle_post_failure(capsys):
|
||||||
|
@@ -288,7 +288,11 @@ def test_nostr_sync(monkeypatch):
|
|||||||
|
|
||||||
def sync_vault():
|
def sync_vault():
|
||||||
called["called"] = True
|
called["called"] = True
|
||||||
return "evt123"
|
return {
|
||||||
|
"manifest_id": "evt123",
|
||||||
|
"chunk_ids": ["c1"],
|
||||||
|
"delta_ids": ["d1"],
|
||||||
|
}
|
||||||
|
|
||||||
pm = SimpleNamespace(sync_vault=sync_vault, select_fingerprint=lambda fp: None)
|
pm = SimpleNamespace(sync_vault=sync_vault, select_fingerprint=lambda fp: None)
|
||||||
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
monkeypatch.setattr(cli, "PasswordManager", lambda: pm)
|
||||||
@@ -296,6 +300,8 @@ def test_nostr_sync(monkeypatch):
|
|||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert called.get("called") is True
|
assert called.get("called") is True
|
||||||
assert "evt123" in result.stdout
|
assert "evt123" in result.stdout
|
||||||
|
assert "c1" in result.stdout
|
||||||
|
assert "d1" in result.stdout
|
||||||
|
|
||||||
|
|
||||||
def test_generate_password(monkeypatch):
|
def test_generate_password(monkeypatch):
|
||||||
|
Reference in New Issue
Block a user