mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 07:18:47 +00:00
Enforce 12-word managed account seeds
This commit is contained in:
@@ -81,7 +81,7 @@ The following table provides a quick reference to all available advanced CLI com
|
||||
| Add Notes to an Entry | `add-notes` | `-AN` | `--add-notes` | `seedpass add-notes --index 3 --notes "This is a secured account"` |
|
||||
| Add Tags to an Entry | `add-tags` | `-AT` | `--add-tags` | `seedpass add-tags --index 3 --tags "personal,finance"` |
|
||||
| Add Key/Value entry | `add-kv` | `-KV` | `--add-kv` | `seedpass add-kv --label "API" --value "secret"`
|
||||
| Add Managed Account | `add-managed` | `-AM` | `--add-managed` | `seedpass add-managed --label "Account" --words 12`
|
||||
| Add Managed Account | `add-managed` | `-AM` | `--add-managed` | `seedpass add-managed --label "Account"`
|
||||
| Search by Tag or Title | `search-by` | `-SB` | `--search-by` | `seedpass search-by --tag "work"` or `seedpass search-by --title "GitHub"` |
|
||||
| Automatically Post Deltas After Edit | `auto-post` | `-AP` | `--auto-post` | `seedpass auto-post --enable` or `seedpass auto-post --disable` |
|
||||
| Initial Setup Prompt for Seed Generation/Import | `setup` | `-ST` | `--setup` | `seedpass setup` |
|
||||
@@ -612,9 +612,11 @@ seedpass add-kv --label "API" --value "secret" --notes "Service token"
|
||||
**Description:**
|
||||
Creates a managed account derived from the current seed profile. The child profile is stored in `.seedpass/<parent_fp>/accounts/<child_fp>`.
|
||||
|
||||
Managed account seeds are always **12 words** long.
|
||||
|
||||
**Usage Example:**
|
||||
```bash
|
||||
seedpass add-managed --label "Account" --words 12
|
||||
seedpass add-managed --label "Account"
|
||||
```
|
||||
|
||||
When loaded, the breadcrumb shows `<parent_fp> > Managed Account > <child_fp>`. Press Enter on the main menu to return to the parent profile.
|
||||
|
@@ -95,7 +95,7 @@ Each entry is stored within `seedpass_entries_db.json.enc` under the `entries` d
|
||||
- **origin** (`string`, optional): Source identifier for imported data.
|
||||
- **value** (`string`, optional): For `key_value` entries, stores the secret value.
|
||||
- **index** (`integer`, optional): BIP-85 derivation index for entries that derive material from a seed.
|
||||
- **word_count** (`integer`, managed_account only): Number of words when deriving the child seed (12 or 24).
|
||||
- **word_count** (`integer`, managed_account only): Number of words in the child seed. Managed accounts always use `12`.
|
||||
- **fingerprint** (`string`, managed_account only): Identifier of the child profile, used for its directory name.
|
||||
Example:
|
||||
|
||||
|
@@ -481,11 +481,13 @@ class EntryManager:
|
||||
parent_seed: str,
|
||||
*,
|
||||
index: int | None = None,
|
||||
word_count: int = 24,
|
||||
notes: str = "",
|
||||
archived: bool = False,
|
||||
) -> int:
|
||||
"""Add a new managed account seed entry."""
|
||||
"""Add a new managed account seed entry.
|
||||
|
||||
Managed accounts always use a 12-word seed phrase.
|
||||
"""
|
||||
|
||||
if index is None:
|
||||
index = self.get_next_index()
|
||||
@@ -497,6 +499,8 @@ class EntryManager:
|
||||
seed_bytes = Bip39SeedGenerator(parent_seed).Generate()
|
||||
bip85 = BIP85(seed_bytes)
|
||||
|
||||
word_count = 12
|
||||
|
||||
seed_phrase = derive_seed_phrase(bip85, index, word_count)
|
||||
fingerprint = generate_fingerprint(seed_phrase)
|
||||
|
||||
@@ -540,7 +544,7 @@ class EntryManager:
|
||||
seed_bytes = Bip39SeedGenerator(parent_seed).Generate()
|
||||
bip85 = BIP85(seed_bytes)
|
||||
|
||||
words = int(entry.get("word_count", 24))
|
||||
words = int(entry.get("word_count", 12))
|
||||
seed_index = int(entry.get("index", index))
|
||||
return derive_seed_phrase(bip85, seed_index, words)
|
||||
|
||||
|
@@ -1464,14 +1464,9 @@ class PasswordManager:
|
||||
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"}:
|
||||
print(colored("Invalid word count. Choose 12 or 24.", "red"))
|
||||
return
|
||||
words = int(words_input) if words_input else 24
|
||||
index = self.entry_manager.add_managed_account(
|
||||
label, self.parent_seed, word_count=words, notes=notes
|
||||
label, self.parent_seed, notes=notes
|
||||
)
|
||||
seed = self.entry_manager.get_managed_account_seed(index, self.parent_seed)
|
||||
self.is_dirty = True
|
||||
|
@@ -26,7 +26,7 @@ def test_add_managed_account_fields_and_dir():
|
||||
tmp_path = Path(tmpdir)
|
||||
mgr = setup_entry_manager(tmp_path)
|
||||
|
||||
idx = mgr.add_managed_account("acct", TEST_SEED, word_count=12)
|
||||
idx = mgr.add_managed_account("acct", TEST_SEED)
|
||||
entry = mgr.retrieve_entry(idx)
|
||||
|
||||
assert entry["type"] == "managed_account"
|
||||
|
@@ -29,7 +29,7 @@ def test_add_and_get_managed_account_seed():
|
||||
tmp_path = Path(tmpdir)
|
||||
mgr = setup_mgr(tmp_path)
|
||||
|
||||
idx = mgr.add_managed_account("acct", TEST_SEED, word_count=12)
|
||||
idx = mgr.add_managed_account("acct", TEST_SEED)
|
||||
entry = mgr.retrieve_entry(idx)
|
||||
assert entry["type"] == "managed_account"
|
||||
assert entry["kind"] == "managed_account"
|
||||
|
Reference in New Issue
Block a user