Merge pull request #550 from PR0M3TH3AN/codex/fix-entry-clearing-and-qr-code-options

Fix retrieval display clearing and show QR actions
This commit is contained in:
thePR0M3TH3AN
2025-07-14 18:22:13 -04:00
committed by GitHub
2 changed files with 68 additions and 6 deletions

View File

@@ -1840,7 +1840,7 @@ class PasswordManager:
child_fingerprint=child_fp, child_fingerprint=child_fp,
) )
archived = entry.get("archived", entry.get("blacklisted", False)) archived = entry.get("archived", entry.get("blacklisted", False))
entry_type = entry.get("type", EntryType.PASSWORD.value) entry_type = entry.get("type", entry.get("kind", EntryType.PASSWORD.value))
print(colored("\n[+] Entry Actions:", "green")) print(colored("\n[+] Entry Actions:", "green"))
if archived: if archived:
print(colored("U. Unarchive", "cyan")) print(colored("U. Unarchive", "cyan"))
@@ -1922,7 +1922,7 @@ class PasswordManager:
def _entry_edit_menu(self, index: int, entry: dict) -> None: def _entry_edit_menu(self, index: int, entry: dict) -> None:
"""Sub-menu for editing common entry fields.""" """Sub-menu for editing common entry fields."""
entry_type = entry.get("type", EntryType.PASSWORD.value) entry_type = entry.get("type", entry.get("kind", EntryType.PASSWORD.value))
while True: while True:
fp, parent_fp, child_fp = self.header_fingerprint_args fp, parent_fp, child_fp = self.header_fingerprint_args
clear_header_with_notification( clear_header_with_notification(
@@ -1982,7 +1982,7 @@ class PasswordManager:
def _entry_qr_menu(self, index: int, entry: dict) -> None: def _entry_qr_menu(self, index: int, entry: dict) -> None:
"""Display QR codes for the given ``entry``.""" """Display QR codes for the given ``entry``."""
entry_type = entry.get("type") entry_type = entry.get("type", entry.get("kind"))
try: try:
if entry_type in {EntryType.SEED.value, EntryType.MANAGED_ACCOUNT.value}: if entry_type in {EntryType.SEED.value, EntryType.MANAGED_ACCOUNT.value}:
@@ -2068,7 +2068,7 @@ class PasswordManager:
pause() pause()
return return
entry_type = entry.get("type", EntryType.PASSWORD.value) entry_type = entry.get("type", entry.get("kind", EntryType.PASSWORD.value))
if entry_type == EntryType.TOTP.value: if entry_type == EntryType.TOTP.value:
label = entry.get("label", "") label = entry.get("label", "")
@@ -2166,6 +2166,7 @@ class PasswordManager:
except Exception as e: except Exception as e:
logging.error(f"Error deriving SSH key pair: {e}", exc_info=True) logging.error(f"Error deriving SSH key pair: {e}", exc_info=True)
print(colored(f"Error: Failed to derive SSH keys: {e}", "red")) print(colored(f"Error: Failed to derive SSH keys: {e}", "red"))
pause()
self._entry_actions_menu(index, entry) self._entry_actions_menu(index, entry)
pause() pause()
return return
@@ -2217,6 +2218,7 @@ class PasswordManager:
except Exception as e: except Exception as e:
logging.error(f"Error deriving seed phrase: {e}", exc_info=True) logging.error(f"Error deriving seed phrase: {e}", exc_info=True)
print(colored(f"Error: Failed to derive seed phrase: {e}", "red")) print(colored(f"Error: Failed to derive seed phrase: {e}", "red"))
pause()
self._entry_actions_menu(index, entry) self._entry_actions_menu(index, entry)
pause() pause()
return return
@@ -2254,6 +2256,7 @@ class PasswordManager:
except Exception as e: except Exception as e:
logging.error(f"Error deriving PGP key: {e}", exc_info=True) logging.error(f"Error deriving PGP key: {e}", exc_info=True)
print(colored(f"Error: Failed to derive PGP key: {e}", "red")) print(colored(f"Error: Failed to derive PGP key: {e}", "red"))
pause()
self._entry_actions_menu(index, entry) self._entry_actions_menu(index, entry)
pause() pause()
return return
@@ -2286,6 +2289,7 @@ class PasswordManager:
except Exception as e: except Exception as e:
logging.error(f"Error deriving Nostr keys: {e}", exc_info=True) logging.error(f"Error deriving Nostr keys: {e}", exc_info=True)
print(colored(f"Error: Failed to derive Nostr keys: {e}", "red")) print(colored(f"Error: Failed to derive Nostr keys: {e}", "red"))
pause()
self._entry_actions_menu(index, entry) self._entry_actions_menu(index, entry)
pause() pause()
return return
@@ -2519,7 +2523,7 @@ class PasswordManager:
if not entry: if not entry:
return return
entry_type = entry.get("type", EntryType.PASSWORD.value) entry_type = entry.get("type", entry.get("kind", EntryType.PASSWORD.value))
if entry_type == EntryType.TOTP.value: if entry_type == EntryType.TOTP.value:
label = entry.get("label", "") label = entry.get("label", "")
@@ -3810,7 +3814,7 @@ class PasswordManager:
entries = data.get("entries", {}) entries = data.get("entries", {})
counts: dict[str, int] = {etype.value: 0 for etype in EntryType} counts: dict[str, int] = {etype.value: 0 for etype in EntryType}
for entry in entries.values(): for entry in entries.values():
etype = entry.get("type", EntryType.PASSWORD.value) etype = entry.get("type", entry.get("kind", EntryType.PASSWORD.value))
counts[etype] = counts.get(etype, 0) + 1 counts[etype] = counts.get(etype, 0) + 1
stats["entries"] = counts stats["entries"] = counts
stats["total_entries"] = len(entries) stats["total_entries"] = len(entries)

View File

@@ -0,0 +1,58 @@
import sys
from pathlib import Path
from tempfile import TemporaryDirectory
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
sys.path.append(str(Path(__file__).resolve().parents[1]))
from password_manager.entry_management import EntryManager
from password_manager.backup import BackupManager
from password_manager.manager import PasswordManager, EncryptionMode
from password_manager.config_manager import ConfigManager
import pytest
@pytest.mark.parametrize(
"adder,needs_confirm",
[
(lambda mgr: mgr.add_seed("seed", TEST_SEED), True),
(lambda mgr: mgr.add_pgp_key("pgp", TEST_SEED, user_id="test"), True),
(lambda mgr: mgr.add_ssh_key("ssh", TEST_SEED), True),
(lambda mgr: mgr.add_nostr_key("nostr"), False),
],
)
def test_pause_before_entry_actions(monkeypatch, adder, needs_confirm):
with TemporaryDirectory() as tmpdir:
tmp_path = Path(tmpdir)
vault, enc_mgr = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
cfg_mgr = ConfigManager(vault, tmp_path)
backup_mgr = BackupManager(tmp_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.parent_seed = TEST_SEED
pm.fingerprint_dir = tmp_path
pm.secret_mode_enabled = False
index = adder(entry_mgr)
pause_calls = []
monkeypatch.setattr(
"password_manager.manager.pause", lambda *a, **k: pause_calls.append(True)
)
monkeypatch.setattr(pm, "_entry_actions_menu", lambda *a, **k: None)
monkeypatch.setattr("builtins.input", lambda *a, **k: str(index))
if needs_confirm:
monkeypatch.setattr(
"password_manager.manager.confirm_action", lambda *a, **k: True
)
pm.handle_retrieve_entry()
assert len(pause_calls) == 2