Remove deprecated website field

This commit is contained in:
thePR0M3TH3AN
2025-07-05 10:00:46 -04:00
parent 8a8bd0ada5
commit bacf32b46e
16 changed files with 123 additions and 68 deletions

View File

@@ -65,6 +65,13 @@ class EntryManager:
if "kind" not in entry:
entry["kind"] = entry.get("type", EntryType.PASSWORD.value)
entry.setdefault("type", entry["kind"])
if "label" not in entry and "website" in entry:
entry["label"] = entry["website"]
if (
"website" in entry
and entry.get("type") == EntryType.PASSWORD.value
):
entry.pop("website", None)
logger.debug("Index loaded successfully.")
return data
except Exception as e:
@@ -106,7 +113,7 @@ class EntryManager:
def add_entry(
self,
website_name: str,
label: str,
length: int,
username: Optional[str] = None,
url: Optional[str] = None,
@@ -117,7 +124,7 @@ class EntryManager:
"""
Adds a new entry to the encrypted JSON index file.
:param website_name: The name of the website.
:param label: A label describing the entry (e.g. website name).
:param length: The desired length of the password.
:param username: (Optional) The username associated with the website.
:param url: (Optional) The URL of the website.
@@ -131,7 +138,7 @@ class EntryManager:
data.setdefault("entries", {})
data["entries"][str(index)] = {
"website": website_name,
"label": label,
"length": length,
"username": username if username else "",
"url": url if url else "",
@@ -222,7 +229,11 @@ class EntryManager:
raise
def add_ssh_key(
self, parent_seed: str, index: int | None = None, notes: str = ""
self,
label: str,
parent_seed: str,
index: int | None = None,
notes: str = "",
) -> int:
"""Add a new SSH key pair entry.
@@ -240,6 +251,7 @@ class EntryManager:
"type": EntryType.SSH.value,
"kind": EntryType.SSH.value,
"index": index,
"label": label,
"notes": notes,
}
self._save_index(data)
@@ -263,6 +275,7 @@ class EntryManager:
def add_pgp_key(
self,
label: str,
parent_seed: str,
index: int | None = None,
key_type: str = "ed25519",
@@ -280,6 +293,7 @@ class EntryManager:
"type": EntryType.PGP.value,
"kind": EntryType.PGP.value,
"index": index,
"label": label,
"key_type": key_type,
"user_id": user_id,
"notes": notes,
@@ -362,6 +376,7 @@ class EntryManager:
def add_seed(
self,
label: str,
parent_seed: str,
index: int | None = None,
words_num: int = 24,
@@ -378,6 +393,7 @@ class EntryManager:
"type": EntryType.SEED.value,
"kind": EntryType.SEED.value,
"index": index,
"label": label,
"words": words_num,
"notes": notes,
}
@@ -596,11 +612,11 @@ class EntryManager:
idx_str, entry = item
if sort_by == "index":
return int(idx_str)
if sort_by == "website":
return entry.get("website", "").lower()
if sort_by in {"website", "label"}:
return entry.get("label", entry.get("website", "")).lower()
if sort_by == "username":
return entry.get("username", "").lower()
raise ValueError("sort_by must be 'index', 'website', or 'username'")
raise ValueError("sort_by must be 'index', 'label', or 'username'")
sorted_items = sorted(entries_data.items(), key=sort_key)
@@ -616,19 +632,20 @@ class EntryManager:
entries: List[Tuple[int, str, Optional[str], Optional[str], bool]] = []
for idx, entry in filtered_items:
label = entry.get("label", entry.get("website", ""))
etype = entry.get("type", entry.get("kind", EntryType.PASSWORD.value))
if etype == EntryType.TOTP.value:
entries.append((idx, entry.get("label", ""), None, None, False))
else:
if etype == EntryType.PASSWORD.value:
entries.append(
(
idx,
entry.get("website", ""),
label,
entry.get("username", ""),
entry.get("url", ""),
entry.get("blacklisted", False),
)
)
else:
entries.append((idx, label, None, None, False))
logger.debug(f"Total entries found: {len(entries)}")
for idx, entry in filtered_items:
@@ -644,8 +661,13 @@ class EntryManager:
"cyan",
)
)
else:
print(colored(f" Website: {entry.get('website', '')}", "cyan"))
elif etype == EntryType.PASSWORD.value:
print(
colored(
f" Label: {entry.get('label', entry.get('website', ''))}",
"cyan",
)
)
print(
colored(f" Username: {entry.get('username') or 'N/A'}", "cyan")
)
@@ -656,6 +678,13 @@ class EntryManager:
"cyan",
)
)
else:
print(colored(f" Label: {entry.get('label', '')}", "cyan"))
print(
colored(
f" Derivation Index: {entry.get('index', index)}", "cyan"
)
)
print("-" * 40)
return entries
@@ -680,16 +709,14 @@ class EntryManager:
for idx, entry in sorted(entries_data.items(), key=lambda x: int(x[0])):
etype = entry.get("type", entry.get("kind", EntryType.PASSWORD.value))
if etype == EntryType.TOTP.value:
label = entry.get("label", "")
notes = entry.get("notes", "")
if query_lower in label.lower() or query_lower in notes.lower():
results.append((int(idx), label, None, None, False))
else:
website = entry.get("website", "")
label = entry.get("label", entry.get("website", ""))
notes = entry.get("notes", "")
label_match = query_lower in label.lower()
notes_match = query_lower in notes.lower()
if etype == EntryType.PASSWORD.value:
username = entry.get("username", "")
url = entry.get("url", "")
notes = entry.get("notes", "")
custom_fields = entry.get("custom_fields", [])
custom_match = any(
query_lower in str(cf.get("label", "")).lower()
@@ -697,21 +724,24 @@ class EntryManager:
for cf in custom_fields
)
if (
query_lower in website.lower()
label_match
or query_lower in username.lower()
or query_lower in url.lower()
or query_lower in notes.lower()
or notes_match
or custom_match
):
results.append(
(
int(idx),
website,
label,
username,
url,
entry.get("blacklisted", False),
)
)
else:
if label_match or notes_match:
results.append((int(idx), label, None, None, False))
return results
@@ -829,7 +859,7 @@ class EntryManager:
for entry in entries:
index, website, username, url, blacklisted = entry
print(colored(f"Index: {index}", "cyan"))
print(colored(f" Website: {website}", "cyan"))
print(colored(f" Label: {website}", "cyan"))
print(colored(f" Username: {username or 'N/A'}", "cyan"))
print(colored(f" URL: {url or 'N/A'}", "cyan"))
print(
@@ -856,19 +886,9 @@ class EntryManager:
if filter_kind and etype != filter_kind:
continue
if etype == EntryType.PASSWORD.value:
label = entry.get("website", "")
elif etype == EntryType.TOTP.value:
label = entry.get("label", "")
elif etype == EntryType.SSH.value:
label = "SSH Key"
elif etype == EntryType.SEED.value:
label = "Seed Phrase"
elif etype == EntryType.NOSTR.value:
label = entry.get("label", "Nostr Key")
elif etype == EntryType.PGP.value:
label = "PGP Key"
label = entry.get("label", entry.get("website", ""))
else:
label = etype
label = entry.get("label", etype)
summaries.append((int(idx_str), label))
summaries.sort(key=lambda x: x[0])

View File

@@ -859,9 +859,9 @@ class PasswordManager:
def handle_add_password(self) -> None:
try:
website_name = input("Enter the website name: ").strip()
website_name = input("Enter the label or website name: ").strip()
if not website_name:
print(colored("Error: Website name cannot be empty.", "red"))
print(colored("Error: Label cannot be empty.", "red"))
return
username = input("Enter the username (optional): ").strip()
@@ -1040,8 +1040,12 @@ class PasswordManager:
def handle_add_ssh_key(self) -> None:
"""Add an SSH key pair entry and display the derived keys."""
try:
label = input("Label: ").strip()
if not label:
print(colored("Error: Label cannot be empty.", "red"))
return
notes = input("Notes (optional): ").strip()
index = self.entry_manager.add_ssh_key(self.parent_seed, notes=notes)
index = self.entry_manager.add_ssh_key(label, self.parent_seed, notes=notes)
priv_pem, pub_pem = self.entry_manager.get_ssh_key_pair(
index, self.parent_seed
)
@@ -1075,6 +1079,10 @@ class PasswordManager:
def handle_add_seed(self) -> None:
"""Add a derived BIP-39 seed phrase entry."""
try:
label = input("Label: ").strip()
if not label:
print(colored("Error: Label cannot be empty.", "red"))
return
words_input = input("Word count (12 or 24, default 24): ").strip()
notes = input("Notes (optional): ").strip()
if words_input and words_input not in {"12", "24"}:
@@ -1082,7 +1090,7 @@ class PasswordManager:
return
words = int(words_input) if words_input else 24
index = self.entry_manager.add_seed(
self.parent_seed, words_num=words, notes=notes
label, self.parent_seed, words_num=words, notes=notes
)
phrase = self.entry_manager.get_seed_phrase(index, self.parent_seed)
self.is_dirty = True
@@ -1117,6 +1125,10 @@ class PasswordManager:
def handle_add_pgp(self) -> None:
"""Add a PGP key entry and display the generated key."""
try:
label = input("Label: ").strip()
if not label:
print(colored("Error: Label cannot be empty.", "red"))
return
key_type = (
input("Key type (ed25519 or rsa, default ed25519): ").strip().lower()
or "ed25519"
@@ -1124,6 +1136,7 @@ class PasswordManager:
user_id = input("User ID (optional): ").strip()
notes = input("Notes (optional): ").strip()
index = self.entry_manager.add_pgp_key(
label,
self.parent_seed,
key_type=key_type,
user_id=user_id,
@@ -1162,7 +1175,10 @@ class PasswordManager:
def handle_add_nostr_key(self) -> None:
"""Add a Nostr key entry and display the derived keys."""
try:
label = input("Label (optional): ").strip()
label = input("Label: ").strip()
if not label:
print(colored("Error: Label cannot be empty.", "red"))
return
notes = input("Notes (optional): ").strip()
index = self.entry_manager.add_nostr_key(label, notes=notes)
npub, nsec = self.entry_manager.get_nostr_key_pair(index, self.parent_seed)
@@ -1779,6 +1795,7 @@ class PasswordManager:
print(colored(f" Notes: {notes}", "cyan"))
elif etype == EntryType.SEED.value:
print(colored(" Type: Seed Phrase", "cyan"))
print(colored(f" Label: {entry.get('label', '')}", "cyan"))
print(colored(f" Words: {entry.get('words', 24)}", "cyan"))
print(colored(f" Derivation Index: {entry.get('index', index)}", "cyan"))
notes = entry.get("notes", "")
@@ -1786,12 +1803,14 @@ class PasswordManager:
print(colored(f" Notes: {notes}", "cyan"))
elif etype == EntryType.SSH.value:
print(colored(" Type: SSH Key", "cyan"))
print(colored(f" Label: {entry.get('label', '')}", "cyan"))
print(colored(f" Derivation Index: {entry.get('index', index)}", "cyan"))
notes = entry.get("notes", "")
if notes:
print(colored(f" Notes: {notes}", "cyan"))
elif etype == EntryType.PGP.value:
print(colored(" Type: PGP Key", "cyan"))
print(colored(f" Label: {entry.get('label', '')}", "cyan"))
print(colored(f" Key Type: {entry.get('key_type', 'ed25519')}", "cyan"))
uid = entry.get("user_id", "")
if uid:
@@ -1808,11 +1827,11 @@ class PasswordManager:
if notes:
print(colored(f" Notes: {notes}", "cyan"))
else:
website = entry.get("website", "")
website = entry.get("label", entry.get("website", ""))
username = entry.get("username", "")
url = entry.get("url", "")
blacklisted = entry.get("blacklisted", False)
print(colored(f" Website: {website}", "cyan"))
print(colored(f" Label: {website}", "cyan"))
print(colored(f" Username: {username or 'N/A'}", "cyan"))
print(colored(f" URL: {url or 'N/A'}", "cyan"))
print(colored(f" Blacklisted: {'Yes' if blacklisted else 'No'}", "cyan"))

View File

@@ -33,6 +33,10 @@ def _v1_to_v2(data: dict) -> dict:
for k, v in passwords.items():
v.setdefault("type", "password")
v.setdefault("notes", "")
if "label" not in v and "website" in v:
v["label"] = v["website"]
if v.get("type") == "password" and "website" in v:
v.pop("website", None)
entries[k] = v
data["entries"] = entries
data["schema_version"] = 2
@@ -46,6 +50,10 @@ def _v2_to_v3(data: dict) -> dict:
for entry in entries.values():
entry.setdefault("custom_fields", [])
entry.setdefault("origin", "")
if entry.get("type", "password") == "password":
if "label" not in entry and "website" in entry:
entry["label"] = entry["website"]
entry.pop("website", None)
data["schema_version"] = 3
return data