From b23f4cbd00093ede28aebe4d933d01cf0145b8fd Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sat, 5 Jul 2025 15:29:19 -0400 Subject: [PATCH 1/3] Allow editing password entry label --- src/password_manager/entry_management.py | 5 ++++- src/password_manager/manager.py | 11 ++++++++++- src/tests/test_manager_workflow.py | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/password_manager/entry_management.py b/src/password_manager/entry_management.py index 1a657cc..80acb09 100644 --- a/src/password_manager/entry_management.py +++ b/src/password_manager/entry_management.py @@ -521,7 +521,7 @@ class EntryManager: :param url: (Optional) The new URL (password entries). :param blacklisted: (Optional) The new blacklist status. :param notes: (Optional) New notes to attach to the entry. - :param label: (Optional) The new label for TOTP entries. + :param label: (Optional) The new label for the entry. :param period: (Optional) The new TOTP period in seconds. :param digits: (Optional) The new number of digits for TOTP codes. """ @@ -554,6 +554,9 @@ class EntryManager: entry["digits"] = digits logger.debug(f"Updated digits to '{digits}' for index {index}.") else: + if label is not None: + entry["label"] = label + logger.debug(f"Updated label to '{label}' for index {index}.") if username is not None: entry["username"] = username logger.debug(f"Updated username to '{username}' for index {index}.") diff --git a/src/password_manager/manager.py b/src/password_manager/manager.py index 3868068..1d87d5b 100644 --- a/src/password_manager/manager.py +++ b/src/password_manager/manager.py @@ -1665,7 +1665,7 @@ class PasswordManager: custom_fields=custom_fields, ) else: - website_name = entry.get("website") + website_name = entry.get("label", entry.get("website")) username = entry.get("username") url = entry.get("url") blacklisted = entry.get("blacklisted") @@ -1677,6 +1677,7 @@ class PasswordManager: "cyan", ) ) + print(colored(f"Current Label: {website_name}", "cyan")) print(colored(f"Current Username: {username or 'N/A'}", "cyan")) print(colored(f"Current URL: {url or 'N/A'}", "cyan")) print( @@ -1686,6 +1687,13 @@ class PasswordManager: ) ) + new_label = ( + input( + f'Enter new label (leave blank to keep "{website_name}"): ' + ).strip() + or website_name + ) + new_username = ( input( f'Enter new username (leave blank to keep "{username or "N/A"}"): ' @@ -1747,6 +1755,7 @@ class PasswordManager: new_url, new_blacklisted, new_notes, + label=new_label, custom_fields=custom_fields, ) diff --git a/src/tests/test_manager_workflow.py b/src/tests/test_manager_workflow.py index 3a1a59e..dac3a2e 100644 --- a/src/tests/test_manager_workflow.py +++ b/src/tests/test_manager_workflow.py @@ -57,6 +57,7 @@ def test_manager_workflow(monkeypatch): "", # length (default) "0", # retrieve index "0", # modify index + "", # new label "user", # new username "", # new url "", # blacklist status From b163ca1bf7b2acc72ef7d0cd38978083ac476867 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sat, 5 Jul 2025 15:37:27 -0400 Subject: [PATCH 2/3] Fix PGP key determinism --- src/password_manager/password_generation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/password_manager/password_generation.py b/src/password_manager/password_generation.py index 8d95e0d..a5a3f91 100644 --- a/src/password_manager/password_generation.py +++ b/src/password_manager/password_generation.py @@ -469,5 +469,6 @@ def derive_pgp_key( hashes=[HashAlgorithm.SHA256], ciphers=[SymmetricKeyAlgorithm.AES256], compression=[CompressionAlgorithm.ZLIB], + created=created, ) return str(key), key.fingerprint From 2779df6e383cb57c8b11f253c9e1256e5b71e7b1 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sat, 5 Jul 2025 15:49:22 -0400 Subject: [PATCH 3/3] Show script checksum in stats --- README.md | 4 +++- src/password_manager/manager.py | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 76e61e2..6eecfaa 100644 --- a/README.md +++ b/README.md @@ -328,7 +328,9 @@ Back in the Settings menu you can: * Select `11` to change the inactivity timeout. * Choose `12` to lock the vault and require re-entry of your password. * Select `13` to view seed profile stats. The summary lists counts for - passwords, TOTP codes, SSH keys, seed phrases, and PGP keys. + passwords, TOTP codes, SSH keys, seed phrases, and PGP keys. It also shows + whether both the encrypted database and the script itself pass checksum + validation. * Choose `14` to toggle Secret Mode and set the clipboard clear delay. * Select `15` to return to the main menu. diff --git a/src/password_manager/manager.py b/src/password_manager/manager.py index 1d87d5b..e969f63 100644 --- a/src/password_manager/manager.py +++ b/src/password_manager/manager.py @@ -2497,7 +2497,7 @@ class PasswordManager: stats["entries"] = counts stats["total_entries"] = len(entries) - # Schema version and checksum status + # Schema version and database checksum status stats["schema_version"] = data.get("schema_version") json_content = json.dumps(data, indent=4) current_checksum = hashlib.sha256(json_content.encode("utf-8")).hexdigest() @@ -2510,6 +2510,19 @@ class PasswordManager: stats["checksum_ok"] = False stats["checksum"] = stored + # Script checksum status + script_path = Path(__file__).resolve() + try: + script_checksum = calculate_checksum(str(script_path)) + except Exception: + script_checksum = None + + if SCRIPT_CHECKSUM_FILE.exists() and script_checksum: + stored_script = SCRIPT_CHECKSUM_FILE.read_text().strip() + stats["script_checksum_ok"] = stored_script == script_checksum + else: + stats["script_checksum_ok"] = False + # Relay info cfg = self.config_manager.load_config(require_pin=False) relays = cfg.get("relays", []) @@ -2582,7 +2595,13 @@ class PasswordManager: print(colored(f"Schema version: {stats['schema_version']}", "cyan")) print( colored( - f"Checksum ok: {'yes' if stats['checksum_ok'] else 'no'}", + f"Database checksum ok: {'yes' if stats['checksum_ok'] else 'no'}", + "cyan", + ) + ) + print( + colored( + f"Script checksum ok: {'yes' if stats['script_checksum_ok'] else 'no'}", "cyan", ) )