mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-07 14:58:56 +00:00
Expose quick unlock and offline mode
This commit is contained in:
@@ -410,6 +410,8 @@ Back in the Settings menu you can:
|
||||
- Select `13` to lock the vault and require re-entry of your password.
|
||||
- Select `14` to view seed profile stats. The summary lists counts for 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 `15` to toggle Secret Mode and set the clipboard clear delay.
|
||||
- Select `16` to toggle Offline Mode and disable Nostr synchronization.
|
||||
- Choose `17` to toggle Quick Unlock for skipping the password prompt after the first unlock.
|
||||
Press **Enter** at any time to return to the main menu.
|
||||
You can adjust these settings directly from the command line:
|
||||
|
||||
@@ -421,7 +423,7 @@ seedpass config set nostr_max_retries 2
|
||||
seedpass config set nostr_retry_delay 1
|
||||
```
|
||||
|
||||
The default configuration uses **50,000** PBKDF2 iterations. Lower iteration counts speed up vault decryption but make brute-force attacks easier. A long backup interval means fewer backups and increases the risk of data loss.
|
||||
The default configuration uses **50,000** PBKDF2 iterations. Increase this value for stronger password hashing or lower it for faster startup (not recommended). Offline Mode skips all Nostr communication, keeping your data local until you re-enable syncing. Quick Unlock stores a hashed copy of your password in the encrypted config so that after the initial unlock, subsequent operations won't prompt for the password until you exit the program. Avoid enabling Quick Unlock on shared machines.
|
||||
|
||||
## Running Tests
|
||||
|
||||
@@ -491,6 +493,8 @@ Mutation testing is disabled in the GitHub workflow due to reliability issues an
|
||||
- **No PBKDF2 Salt Required:** SeedPass deliberately omits an explicit PBKDF2 salt. Every password is derived from a unique 512-bit BIP-85 child seed, which already provides stronger per-password uniqueness than a conventional 128-bit salt.
|
||||
- **Default KDF Iterations:** New profiles start with 50,000 PBKDF2 iterations. Adjust this with `seedpass config set kdf_iterations`.
|
||||
- **KDF Iteration Caution:** Lowering `kdf_iterations` makes password cracking easier, while a high `backup_interval` leaves fewer recent backups.
|
||||
- **Offline Mode:** When enabled, SeedPass skips all Nostr operations so your vault stays local until syncing is turned back on.
|
||||
- **Quick Unlock:** Stores a hashed copy of your password in the encrypted config so you only need to enter it once per session. Avoid this on shared computers.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@@ -412,7 +412,9 @@ Back in the Settings menu you can:
|
||||
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.
|
||||
* Select `15` to toggle Offline Mode and work locally without contacting Nostr.
|
||||
* Choose `16` to toggle Quick Unlock so subsequent actions skip the password prompt.
|
||||
* Select `17` to return to the main menu.
|
||||
|
||||
## Running Tests
|
||||
|
||||
@@ -496,6 +498,8 @@ Mutation testing is disabled in the GitHub workflow due to reliability issues an
|
||||
- **Multiple Seeds Management:** While managing multiple seeds adds flexibility, it also increases the responsibility to secure each seed and its associated password.
|
||||
- **No PBKDF2 Salt Required:** SeedPass deliberately omits an explicit PBKDF2 salt. Every password is derived from a unique 512-bit BIP-85 child seed, which already provides stronger per-password uniqueness than a conventional 128-bit salt.
|
||||
- **Default KDF Iterations:** New profiles start with 50,000 PBKDF2 iterations. Use `seedpass config set kdf_iterations` to change this.
|
||||
- **Offline Mode:** Disable Nostr sync to keep all operations local until you re-enable networking.
|
||||
- **Quick Unlock:** Store a hashed copy of your password so future actions don't prompt again during the session. Use with caution on shared systems.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
63
src/main.py
63
src/main.py
@@ -617,6 +617,61 @@ def handle_toggle_secret_mode(pm: PasswordManager) -> None:
|
||||
print(colored(f"Error: {exc}", "red"))
|
||||
|
||||
|
||||
def handle_toggle_quick_unlock(pm: PasswordManager) -> None:
|
||||
"""Enable or disable Quick Unlock."""
|
||||
cfg = pm.config_manager
|
||||
if cfg is None:
|
||||
print(colored("Configuration manager unavailable.", "red"))
|
||||
return
|
||||
try:
|
||||
enabled = cfg.get_quick_unlock()
|
||||
except Exception as exc:
|
||||
logging.error(f"Error loading quick unlock setting: {exc}")
|
||||
print(colored(f"Error loading settings: {exc}", "red"))
|
||||
return
|
||||
print(colored(f"Quick Unlock is currently {'ON' if enabled else 'OFF'}", "cyan"))
|
||||
choice = input("Enable Quick Unlock? (y/n, blank to keep): ").strip().lower()
|
||||
if choice in ("y", "yes"):
|
||||
enabled = True
|
||||
elif choice in ("n", "no"):
|
||||
enabled = False
|
||||
try:
|
||||
cfg.set_quick_unlock(enabled)
|
||||
status = "enabled" if enabled else "disabled"
|
||||
print(colored(f"Quick Unlock {status}.", "green"))
|
||||
except Exception as exc:
|
||||
logging.error(f"Error saving quick unlock: {exc}")
|
||||
print(colored(f"Error: {exc}", "red"))
|
||||
|
||||
|
||||
def handle_toggle_offline_mode(pm: PasswordManager) -> None:
|
||||
"""Enable or disable offline mode."""
|
||||
cfg = pm.config_manager
|
||||
if cfg is None:
|
||||
print(colored("Configuration manager unavailable.", "red"))
|
||||
return
|
||||
try:
|
||||
enabled = cfg.get_offline_mode()
|
||||
except Exception as exc:
|
||||
logging.error(f"Error loading offline mode setting: {exc}")
|
||||
print(colored(f"Error loading settings: {exc}", "red"))
|
||||
return
|
||||
print(colored(f"Offline mode is currently {'ON' if enabled else 'OFF'}", "cyan"))
|
||||
choice = input("Enable offline mode? (y/n, blank to keep): ").strip().lower()
|
||||
if choice in ("y", "yes"):
|
||||
enabled = True
|
||||
elif choice in ("n", "no"):
|
||||
enabled = False
|
||||
try:
|
||||
cfg.set_offline_mode(enabled)
|
||||
pm.offline_mode = enabled
|
||||
status = "enabled" if enabled else "disabled"
|
||||
print(colored(f"Offline mode {status}.", "green"))
|
||||
except Exception as exc:
|
||||
logging.error(f"Error saving offline mode: {exc}")
|
||||
print(colored(f"Error: {exc}", "red"))
|
||||
|
||||
|
||||
def handle_profiles_menu(password_manager: PasswordManager) -> None:
|
||||
"""Submenu for managing seed profiles."""
|
||||
while True:
|
||||
@@ -737,6 +792,8 @@ def handle_settings(password_manager: PasswordManager) -> None:
|
||||
print(color_text("13. Lock Vault", "menu"))
|
||||
print(color_text("14. Stats", "menu"))
|
||||
print(color_text("15. Toggle Secret Mode", "menu"))
|
||||
print(color_text("16. Toggle Offline Mode", "menu"))
|
||||
print(color_text("17. Toggle Quick Unlock", "menu"))
|
||||
choice = input("Select an option or press Enter to go back: ").strip()
|
||||
if choice == "1":
|
||||
handle_profiles_menu(password_manager)
|
||||
@@ -787,6 +844,12 @@ def handle_settings(password_manager: PasswordManager) -> None:
|
||||
elif choice == "15":
|
||||
handle_toggle_secret_mode(password_manager)
|
||||
pause()
|
||||
elif choice == "16":
|
||||
handle_toggle_offline_mode(password_manager)
|
||||
pause()
|
||||
elif choice == "17":
|
||||
handle_toggle_quick_unlock(password_manager)
|
||||
pause()
|
||||
elif not choice:
|
||||
break
|
||||
else:
|
||||
|
Reference in New Issue
Block a user