Consolidated duplicated menu loop logic from `_entry_actions_menu`, `_entry_edit_menu`, and `_entry_qr_menu` in `src/seedpass/core/manager.py` into a reusable `run_menu` method in `src/seedpass/core/menu_handler.py`. This improves maintainability by centralizing the loop handling, input prompting, and header clearing logic.
* Added `run_menu` to `MenuHandler`.
* Refactored `_entry_actions_menu` to use `run_menu`.
* Refactored `_entry_edit_menu` to use `run_menu`.
* Refactored `_entry_qr_menu` (NOSTR section) to use `run_menu`.
Co-authored-by: PR0M3TH3AN <[email protected]>
Extracts the hardcoded BeeWare GUI backend configuration (package names, versions, and SHA256 hashes) from `src/seedpass/cli/__init__.py` into a new `GUI_BACKEND_CONFIG` dictionary in `src/constants.py`. This improves maintainability by centralizing configuration and simplifying the CLI logic.
- Adds `GUI_BACKEND_CONFIG` to `src/constants.py`.
- Updates `src/seedpass/cli/__init__.py` to import and use `GUI_BACKEND_CONFIG`.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Introduced `_clear_header_add_entry`, `_mark_dirty`, `_sync_and_pause` helpers.
- Introduced `_entry_op_context` context manager for error handling.
- Applied these patterns to `handle_add_totp`, `handle_add_ssh_key`, `handle_add_seed`, `handle_add_pgp`, `handle_add_nostr_key`, `handle_add_key_value`, and `handle_add_managed_account`.
- Ensured `is_dirty` flag is set immediately after entry creation to prevent data loss if subsequent UI steps are cancelled.
Co-authored-by: PR0M3TH3AN <[email protected]>
This change mitigates an arbitrary file overwrite vulnerability in the
`backup_parent_seed` API endpoint. Previously, the endpoint did not
check if the destination file already existed, allowing attackers or
accidental misuse to overwrite critical files if the path validation
passed.
The fix introduces a check using `resolved_path.exists()` after path
validation. If the file exists, the request is rejected with a
409 Conflict error.
A reproduction test case confirmed the vulnerability and verified the
fix. Regression tests on the API passed successfully.
Co-authored-by: PR0M3TH3AN <[email protected]>
Extracted the monolithic `display_sensitive_entry_info` method from `PasswordManager` into a new `DisplayService` class in `src/seedpass/core/display_service.py`. This improves maintainability and separation of concerns.
- Created `src/seedpass/core/display_service.py` with `DisplayService` class.
- Implemented specific display methods for each entry type (TOTP, SSH, SEED, PGP, Nostr, Key/Value, Managed Account, Password).
- Updated `src/seedpass/core/manager.py` to use `DisplayService`.
- Verified with existing tests `test_manager_retrieve_totp.py` and `test_manager_search_display.py`.
Co-authored-by: PR0M3TH3AN <[email protected]>
Refactors `import_vault` endpoint in `src/seedpass/api.py` to use `asyncio.to_thread` for blocking file I/O and synchronous `PasswordManager.handle_import_database` calls.
Replaces synchronous `pm.sync_vault()` with `await pm.sync_vault_async()` (with fallback) to prevent blocking the event loop or triggering `asyncio.run` errors.
This change ensures the API remains responsive during large vault imports.
Verified with a custom benchmark script showing concurrent requests are no longer blocked.
Co-authored-by: PR0M3TH3AN <[email protected]>
This commit addresses a security vulnerability where legacy Fernet keys
were derived using PBKDF2 with an empty salt (b"").
Changes:
- Modified `_derive_legacy_key_from_password` to accept an optional `salt`
parameter.
- Updated `EncryptionManager.decrypt_legacy` to attempt decryption using
a salt derived from the user's fingerprint (unique per user) before
falling back to the empty salt for backward compatibility.
- Added a new test file `src/tests/test_legacy_salt_fix.py` to verify the
new logic.
Rationale: Using a unique salt per user is standard practice to prevent
precomputed attacks. While legacy vaults cannot be retroactively
secured, this change ensures that any future legacy-style derivations
use a unique salt if possible, while maintaining access to existing
vaults.
Co-authored-by: PR0M3TH3AN <[email protected]>
Moved the imghdr compatibility shim from `src/seedpass/core/password_generation.py`
to a new `src/seedpass/core/compat.py` module. This improves code
cleanliness and separates concerns by centralizing Python version
compatibility logic.
The shim ensures that `imghdr` is available in `sys.modules` (using
`utils.imghdr_stub` as a fallback for Python 3.13+) so that dependencies
like `pgpy` can function correctly.
Verified the change by:
- Confirming `compat.py` correctly populates `sys.modules["imghdr"]`.
- Verifying `password_generation.py` imports correctly and triggers the shim.
- Ensuring syntax correctness via `py_compile`.
Co-authored-by: PR0M3TH3AN <[email protected]>