mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 23:38:49 +00:00
Add view option for archived entries
This commit is contained in:
@@ -257,7 +257,7 @@ When choosing **Add Entry**, you can now select **Password**, **2FA (TOTP)**,
|
|||||||
2. SeedPass will show the current label, period, digit count, and archived status.
|
2. SeedPass will show the current label, period, digit count, and archived status.
|
||||||
3. Enter new values or press **Enter** to keep the existing settings.
|
3. Enter new values or press **Enter** to keep the existing settings.
|
||||||
4. The updated entry is saved back to your encrypted vault.
|
4. The updated entry is saved back to your encrypted vault.
|
||||||
5. Archived entries are hidden from lists but can be restored from the **List Archived** menu.
|
5. Archived entries are hidden from lists but can be viewed or restored from the **List Archived** menu.
|
||||||
|
|
||||||
### Using Secret Mode
|
### Using Secret Mode
|
||||||
|
|
||||||
|
@@ -2157,7 +2157,7 @@ class PasswordManager:
|
|||||||
print(colored(f"Error: Failed to archive entry: {e}", "red"))
|
print(colored(f"Error: Failed to archive entry: {e}", "red"))
|
||||||
|
|
||||||
def handle_view_archived_entries(self) -> None:
|
def handle_view_archived_entries(self) -> None:
|
||||||
"""Display archived entries and optionally restore one."""
|
"""Display archived entries and optionally view or restore them."""
|
||||||
try:
|
try:
|
||||||
archived = self.entry_manager.list_entries(include_archived=True)
|
archived = self.entry_manager.list_entries(include_archived=True)
|
||||||
archived = [e for e in archived if e[4]]
|
archived = [e for e in archived if e[4]]
|
||||||
@@ -2171,26 +2171,45 @@ class PasswordManager:
|
|||||||
"Main Menu > Archived Entries",
|
"Main Menu > Archived Entries",
|
||||||
)
|
)
|
||||||
print(colored("\n[+] Archived Entries:\n", "green"))
|
print(colored("\n[+] Archived Entries:\n", "green"))
|
||||||
for idx, label, username, url, _ in archived:
|
for idx, label, _username, _url, _ in archived:
|
||||||
print(colored(f"{idx}. {label}", "cyan"))
|
print(colored(f"{idx}. {label}", "cyan"))
|
||||||
idx_input = input(
|
idx_input = input(
|
||||||
"Enter index to restore or press Enter to go back: "
|
"Enter index to manage or press Enter to go back: "
|
||||||
).strip()
|
).strip()
|
||||||
if not idx_input:
|
if not idx_input:
|
||||||
break
|
break
|
||||||
if not idx_input.isdigit():
|
if not idx_input.isdigit() or int(idx_input) not in [
|
||||||
|
e[0] for e in archived
|
||||||
|
]:
|
||||||
print(colored("Invalid index.", "red"))
|
print(colored("Invalid index.", "red"))
|
||||||
continue
|
continue
|
||||||
restore_index = int(idx_input)
|
entry_index = int(idx_input)
|
||||||
self.entry_manager.restore_entry(restore_index)
|
while True:
|
||||||
self.is_dirty = True
|
action = (
|
||||||
self.last_update = time.time()
|
input(
|
||||||
pause()
|
"Enter 'v' to view details, 'r' to restore, or press Enter to go back: "
|
||||||
archived = [e for e in archived if e[0] != restore_index]
|
)
|
||||||
if not archived:
|
.strip()
|
||||||
print(colored("All entries restored.", "green"))
|
.lower()
|
||||||
pause()
|
)
|
||||||
break
|
if action == "v":
|
||||||
|
self.display_entry_details(entry_index)
|
||||||
|
pause()
|
||||||
|
elif action == "r":
|
||||||
|
self.entry_manager.restore_entry(entry_index)
|
||||||
|
self.is_dirty = True
|
||||||
|
self.last_update = time.time()
|
||||||
|
pause()
|
||||||
|
archived = [e for e in archived if e[0] != entry_index]
|
||||||
|
if not archived:
|
||||||
|
print(colored("All entries restored.", "green"))
|
||||||
|
pause()
|
||||||
|
return
|
||||||
|
break
|
||||||
|
elif not action:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(colored("Invalid choice.", "red"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Error viewing archived entries: {e}", exc_info=True)
|
logging.error(f"Error viewing archived entries: {e}", exc_info=True)
|
||||||
print(colored(f"Error: Failed to view archived entries: {e}", "red"))
|
print(colored(f"Error: Failed to view archived entries: {e}", "red"))
|
||||||
|
@@ -74,7 +74,40 @@ def test_view_archived_entries_cli(monkeypatch):
|
|||||||
pm.handle_archive_entry()
|
pm.handle_archive_entry()
|
||||||
assert entry_mgr.retrieve_entry(idx)["archived"] is True
|
assert entry_mgr.retrieve_entry(idx)["archived"] is True
|
||||||
|
|
||||||
inputs = iter([str(idx), ""])
|
inputs = iter([str(idx), "r", "", ""])
|
||||||
monkeypatch.setattr("builtins.input", lambda *_: next(inputs))
|
monkeypatch.setattr("builtins.input", lambda *_: next(inputs))
|
||||||
pm.handle_view_archived_entries()
|
pm.handle_view_archived_entries()
|
||||||
assert entry_mgr.retrieve_entry(idx)["archived"] is False
|
assert entry_mgr.retrieve_entry(idx)["archived"] is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_view_archived_entries_view_only(monkeypatch, capsys):
|
||||||
|
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.nostr_client = SimpleNamespace()
|
||||||
|
pm.fingerprint_dir = tmp_path
|
||||||
|
pm.is_dirty = False
|
||||||
|
|
||||||
|
idx = entry_mgr.add_entry("example.com", 8)
|
||||||
|
|
||||||
|
monkeypatch.setattr("builtins.input", lambda *_: str(idx))
|
||||||
|
pm.handle_archive_entry()
|
||||||
|
assert entry_mgr.retrieve_entry(idx)["archived"] is True
|
||||||
|
|
||||||
|
inputs = iter([str(idx), "v", "", "", ""])
|
||||||
|
monkeypatch.setattr("builtins.input", lambda *_: next(inputs))
|
||||||
|
pm.handle_view_archived_entries()
|
||||||
|
assert entry_mgr.retrieve_entry(idx)["archived"] is True
|
||||||
|
out = capsys.readouterr().out
|
||||||
|
assert "example.com" in out
|
||||||
|
Reference in New Issue
Block a user