From ed7763195e0484c1f6743cf7768b8d54d403f50d Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Wed, 6 Aug 2025 19:07:40 -0400 Subject: [PATCH] Improve password change flow --- src/main.py | 17 ++++++++++++-- src/tests/test_settings_menu.py | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/main.py b/src/main.py index ead323c..527b5f3 100644 --- a/src/main.py +++ b/src/main.py @@ -24,7 +24,11 @@ from seedpass.core.manager import PasswordManager from nostr.client import NostrClient from seedpass.core.entry_types import EntryType from constants import INACTIVITY_TIMEOUT, initialize_app -from utils.password_prompt import PasswordPromptError +from utils.password_prompt import ( + PasswordPromptError, + prompt_existing_password, + prompt_new_password, +) from utils import ( timed_input, copy_to_clipboard, @@ -986,7 +990,16 @@ def handle_settings(password_manager: PasswordManager) -> None: elif choice == "2": handle_nostr_menu(password_manager) elif choice == "3": - password_manager.change_password() + try: + old_pw = prompt_existing_password("Enter your current password: ") + new_pw = prompt_new_password() + password_manager.change_password(old_pw, new_pw) + except ValueError: + print(colored("Incorrect password.", "red")) + except PasswordPromptError: + pass + except Exception as e: + print(colored(f"Error: {e}", "red")) pause() elif choice == "4": password_manager.handle_verify_checksum() diff --git a/src/tests/test_settings_menu.py b/src/tests/test_settings_menu.py index d7699d0..a0b9fba 100644 --- a/src/tests/test_settings_menu.py +++ b/src/tests/test_settings_menu.py @@ -98,3 +98,42 @@ def test_settings_menu_additional_backup(monkeypatch): with patch("builtins.input", side_effect=lambda *_: next(inputs)): main.handle_settings(pm) handler.assert_called_once_with(pm) + + +def test_settings_menu_change_password(monkeypatch): + with TemporaryDirectory() as tmpdir: + tmp_path = Path(tmpdir) + pm, _, _ = setup_pm(tmp_path, monkeypatch) + calls: list[tuple[str, str]] = [] + pm.change_password = lambda old, new: calls.append((old, new)) + + inputs = iter(["3", ""]) + monkeypatch.setattr(main, "prompt_existing_password", lambda *_: "oldpw") + monkeypatch.setattr(main, "prompt_new_password", lambda *_: "newpw") + monkeypatch.setattr(main, "pause", lambda: None) + + with patch("builtins.input", side_effect=lambda *_: next(inputs)): + main.handle_settings(pm) + + assert calls == [("oldpw", "newpw")] + + +def test_settings_menu_change_password_incorrect(monkeypatch, capsys): + with TemporaryDirectory() as tmpdir: + tmp_path = Path(tmpdir) + pm, _, _ = setup_pm(tmp_path, monkeypatch) + + def fail_change(old, new): + raise ValueError("Incorrect password") + + pm.change_password = fail_change + inputs = iter(["3", ""]) + monkeypatch.setattr(main, "prompt_existing_password", lambda *_: "badpw") + monkeypatch.setattr(main, "prompt_new_password", lambda *_: "newpw") + monkeypatch.setattr(main, "pause", lambda: None) + + with patch("builtins.input", side_effect=lambda *_: next(inputs)): + main.handle_settings(pm) + + out = capsys.readouterr().out + assert "Incorrect password" in out