Add editing options for 2FA entries

This commit is contained in:
thePR0M3TH3AN
2025-07-08 14:53:47 -04:00
parent 8f43e62dd5
commit 8e7b7b3ac0
4 changed files with 100 additions and 3 deletions

View File

@@ -267,9 +267,10 @@ When choosing **Add Entry**, you can now select from:
1. From the main menu choose **Modify an Existing Entry** and enter the index of the 2FA code you want to edit.
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.
4. The updated entry is saved back to your encrypted vault.
5. Archived entries are hidden from lists but can be viewed or restored from the **List Archived** menu.
6. When editing an archived entry you'll be prompted to restore it after saving your changes.
4. When retrieving a 2FA entry you can press **E** to edit the label, period or digit count, or **A** to archive/unarchive it.
5. The updated entry is saved back to your encrypted vault.
6. Archived entries are hidden from lists but can be viewed or restored from the **List Archived** menu.
7. When editing an archived entry you'll be prompted to restore it after saving your changes.
### Using Secret Mode

View File

@@ -1674,6 +1674,9 @@ class PasswordManager:
if entry_type == EntryType.PASSWORD.value:
print(colored("U. Edit Username", "cyan"))
print(colored("R. Edit URL", "cyan"))
elif entry_type == EntryType.TOTP.value:
print(colored("P. Edit Period", "cyan"))
print(colored("D. Edit Digits", "cyan"))
choice = input("Select option or press Enter to go back: ").strip().lower()
if not choice:
break
@@ -1693,6 +1696,22 @@ class PasswordManager:
self.entry_manager.modify_entry(index, url=new_url)
self.is_dirty = True
self.last_update = time.time()
elif entry_type == EntryType.TOTP.value and choice == "p":
period_str = input("New period (seconds): ").strip()
if period_str.isdigit():
self.entry_manager.modify_entry(index, period=int(period_str))
self.is_dirty = True
self.last_update = time.time()
else:
print(colored("Invalid period value.", "red"))
elif entry_type == EntryType.TOTP.value and choice == "d":
digits_str = input("New digits: ").strip()
if digits_str.isdigit():
self.entry_manager.modify_entry(index, digits=int(digits_str))
self.is_dirty = True
self.last_update = time.time()
else:
print(colored("Invalid digits value.", "red"))
else:
print(colored("Invalid choice.", "red"))
entry = self.entry_manager.retrieve_entry(index) or entry

View File

@@ -0,0 +1,57 @@
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
class FakeNostrClient:
def __init__(self, *args, **kwargs):
self.published = []
def publish_snapshot(self, data: bytes):
self.published.append(data)
return None, "abcd"
def test_edit_totp_period_from_retrieve(monkeypatch):
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 = FakeNostrClient()
pm.fingerprint_dir = tmp_path
pm.is_dirty = False
pm.secret_mode_enabled = False
entry_mgr.add_totp("Example", TEST_SEED)
inputs = iter(["0", "e", "p", "45", "", ""])
monkeypatch.setattr("builtins.input", lambda *a, **k: next(inputs))
monkeypatch.setattr(pm.entry_manager, "get_totp_code", lambda *a, **k: "123456")
monkeypatch.setattr(
pm.entry_manager, "get_totp_time_remaining", lambda *a, **k: 1
)
monkeypatch.setattr("password_manager.manager.time.sleep", lambda *a, **k: None)
monkeypatch.setattr("password_manager.manager.timed_input", lambda *a, **k: "b")
pm.handle_retrieve_entry()
entry = entry_mgr.retrieve_entry(0)
assert entry["period"] == 45

View File

@@ -0,0 +1,20 @@
from helpers import create_vault, TEST_SEED, TEST_PASSWORD
from password_manager.entry_management import EntryManager
from password_manager.backup import BackupManager
from password_manager.config_manager import ConfigManager
def test_modify_totp_entry_period_digits_and_archive(tmp_path):
vault, _ = create_vault(tmp_path, TEST_SEED, TEST_PASSWORD)
cfg_mgr = ConfigManager(vault, tmp_path)
backup_mgr = BackupManager(tmp_path, cfg_mgr)
em = EntryManager(vault, backup_mgr)
em.add_totp("Example", TEST_SEED, period=30, digits=6)
em.modify_entry(0, period=60, digits=8, archived=True)
entry = em.retrieve_entry(0)
assert entry["period"] == 60
assert entry["digits"] == 8
assert entry["archived"] is True