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/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..e969f63 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, ) @@ -2488,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() @@ -2501,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", []) @@ -2573,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", ) ) 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 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