mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-07 06:48:52 +00:00
Merge pull request #692 from PR0M3TH3AN/codex/enhance-password-management-options
Add per-entry password policy prompts
This commit is contained in:
@@ -223,5 +223,5 @@ Shut down the server with `seedpass api stop`.
|
||||
- Use the `--help` flag for details on any command.
|
||||
- Set a strong master password and regularly export encrypted backups.
|
||||
- Adjust configuration values like `kdf_iterations`, `backup_interval`, `inactivity_timeout`, `secret_mode_enabled`, `nostr_max_retries`, `nostr_retry_delay`, or `quick_unlock` through the `config` commands.
|
||||
- Customize password complexity with `config set min_uppercase 3`, `config set min_digits 4`, and similar commands.
|
||||
- Customize the global password policy with commands like `config set min_uppercase 3`. When adding a password interactively you can override these values, choose a safe special-character set, and exclude ambiguous characters.
|
||||
- `entry get` is script‑friendly and can be piped into other commands.
|
||||
|
@@ -1441,6 +1441,60 @@ class PasswordManager:
|
||||
)
|
||||
return
|
||||
|
||||
include_special_input = (
|
||||
input("Include special characters? (Y/n): ").strip().lower()
|
||||
)
|
||||
include_special_chars: bool | None = None
|
||||
if include_special_input:
|
||||
include_special_chars = include_special_input != "n"
|
||||
|
||||
allowed_special_chars = input(
|
||||
"Allowed special characters (leave blank for default): "
|
||||
).strip()
|
||||
if not allowed_special_chars:
|
||||
allowed_special_chars = None
|
||||
|
||||
special_mode = input("Special character mode (safe/leave blank): ").strip()
|
||||
if not special_mode:
|
||||
special_mode = None
|
||||
|
||||
exclude_ambiguous_input = (
|
||||
input("Exclude ambiguous characters? (y/N): ").strip().lower()
|
||||
)
|
||||
exclude_ambiguous: bool | None = None
|
||||
if exclude_ambiguous_input:
|
||||
exclude_ambiguous = exclude_ambiguous_input == "y"
|
||||
|
||||
min_uppercase_input = input(
|
||||
"Minimum uppercase letters (blank for default): "
|
||||
).strip()
|
||||
if min_uppercase_input and not min_uppercase_input.isdigit():
|
||||
print(colored("Error: Minimum uppercase must be a number.", "red"))
|
||||
return
|
||||
min_uppercase = int(min_uppercase_input) if min_uppercase_input else None
|
||||
|
||||
min_lowercase_input = input(
|
||||
"Minimum lowercase letters (blank for default): "
|
||||
).strip()
|
||||
if min_lowercase_input and not min_lowercase_input.isdigit():
|
||||
print(colored("Error: Minimum lowercase must be a number.", "red"))
|
||||
return
|
||||
min_lowercase = int(min_lowercase_input) if min_lowercase_input else None
|
||||
|
||||
min_digits_input = input("Minimum digits (blank for default): ").strip()
|
||||
if min_digits_input and not min_digits_input.isdigit():
|
||||
print(colored("Error: Minimum digits must be a number.", "red"))
|
||||
return
|
||||
min_digits = int(min_digits_input) if min_digits_input else None
|
||||
|
||||
min_special_input = input(
|
||||
"Minimum special characters (blank for default): "
|
||||
).strip()
|
||||
if min_special_input and not min_special_input.isdigit():
|
||||
print(colored("Error: Minimum special must be a number.", "red"))
|
||||
return
|
||||
min_special = int(min_special_input) if min_special_input else None
|
||||
|
||||
# Add the entry to the index and get the assigned index
|
||||
index = self.entry_manager.add_entry(
|
||||
website_name,
|
||||
@@ -1451,6 +1505,14 @@ class PasswordManager:
|
||||
notes=notes,
|
||||
custom_fields=custom_fields,
|
||||
tags=tags,
|
||||
include_special_chars=include_special_chars,
|
||||
allowed_special_chars=allowed_special_chars,
|
||||
special_mode=special_mode,
|
||||
exclude_ambiguous=exclude_ambiguous,
|
||||
min_uppercase=min_uppercase,
|
||||
min_lowercase=min_lowercase,
|
||||
min_digits=min_digits,
|
||||
min_special=min_special,
|
||||
)
|
||||
|
||||
# Mark database as dirty for background sync
|
||||
|
@@ -52,6 +52,14 @@ def test_handle_add_password(monkeypatch, dummy_nostr_client, capsys):
|
||||
"", # tags
|
||||
"n", # add custom field
|
||||
"", # length (default)
|
||||
"", # include special default
|
||||
"", # allowed special default
|
||||
"", # special mode default
|
||||
"", # exclude ambiguous default
|
||||
"", # min uppercase
|
||||
"", # min lowercase
|
||||
"", # min digits
|
||||
"", # min special
|
||||
]
|
||||
)
|
||||
monkeypatch.setattr("builtins.input", lambda *a, **k: next(inputs))
|
||||
@@ -113,6 +121,14 @@ def test_handle_add_password_secret_mode(monkeypatch, dummy_nostr_client, capsys
|
||||
"", # tags
|
||||
"n", # add custom field
|
||||
"", # length (default)
|
||||
"", # include special default
|
||||
"", # allowed special default
|
||||
"", # special mode default
|
||||
"", # exclude ambiguous default
|
||||
"", # min uppercase
|
||||
"", # min lowercase
|
||||
"", # min digits
|
||||
"", # min special
|
||||
]
|
||||
)
|
||||
monkeypatch.setattr("builtins.input", lambda *a, **k: next(inputs))
|
||||
|
@@ -57,6 +57,14 @@ def test_manager_workflow(monkeypatch):
|
||||
"", # tags
|
||||
"n", # add custom field
|
||||
"", # length (default)
|
||||
"", # include special default
|
||||
"", # allowed special default
|
||||
"", # special mode default
|
||||
"", # exclude ambiguous default
|
||||
"", # min uppercase
|
||||
"", # min lowercase
|
||||
"", # min digits
|
||||
"", # min special
|
||||
"0", # retrieve index
|
||||
"", # no action in entry menu
|
||||
"0", # modify index
|
||||
|
Reference in New Issue
Block a user