diff --git a/src/main.py b/src/main.py index e2295b9..3b06edc 100644 --- a/src/main.py +++ b/src/main.py @@ -577,8 +577,7 @@ def handle_profiles_menu(password_manager: PasswordManager) -> None: print(color_text("2. Add a New Seed Profile", "menu")) print(color_text("3. Remove an Existing Seed Profile", "menu")) print(color_text("4. List All Seed Profiles", "menu")) - print(color_text("5. Back", "menu")) - choice = input("Select an option: ").strip() + choice = input("Select an option or press Enter to go back: ").strip() password_manager.update_activity() if choice == "1": if not password_manager.handle_switch_fingerprint(): @@ -589,7 +588,7 @@ def handle_profiles_menu(password_manager: PasswordManager) -> None: handle_remove_fingerprint(password_manager) elif choice == "4": handle_list_fingerprints(password_manager) - elif choice == "5": + elif not choice: break else: print(colored("Invalid choice.", "red")) @@ -617,8 +616,7 @@ def handle_nostr_menu(password_manager: PasswordManager) -> None: print(color_text("5. Remove a relay by number", "menu")) print(color_text("6. Reset to default relays", "menu")) print(color_text("7. Display Nostr Public Key", "menu")) - print(color_text("8. Back", "menu")) - choice = input("Select an option: ").strip() + choice = input("Select an option or press Enter to go back: ").strip() password_manager.update_activity() if choice == "1": handle_post_to_nostr(password_manager) @@ -634,7 +632,7 @@ def handle_nostr_menu(password_manager: PasswordManager) -> None: handle_reset_relays(password_manager) elif choice == "7": handle_display_npub(password_manager) - elif choice == "8": + elif not choice: break else: print(colored("Invalid choice.", "red")) @@ -659,8 +657,7 @@ def handle_settings(password_manager: PasswordManager) -> None: print(color_text("12. Lock Vault", "menu")) print(color_text("13. Stats", "menu")) print(color_text("14. Toggle Secret Mode", "menu")) - print(color_text("15. Back", "menu")) - choice = input("Select an option: ").strip() + choice = input("Select an option or press Enter to go back: ").strip() if choice == "1": handle_profiles_menu(password_manager) pause() @@ -707,7 +704,7 @@ def handle_settings(password_manager: PasswordManager) -> None: elif choice == "14": handle_toggle_secret_mode(password_manager) pause() - elif choice == "15": + elif not choice: break else: print(colored("Invalid choice.", "red")) @@ -730,7 +727,6 @@ def display_menu( 5. Modify an Existing Entry 6. 2FA Codes 7. Settings - 8. Exit """ display_fn = getattr(password_manager, "display_stats", None) if callable(display_fn): @@ -757,7 +753,8 @@ def display_menu( print(color_text(menu, "menu")) try: choice = timed_input( - "Enter your choice (1-8): ", inactivity_timeout + "Enter your choice (1-7) or press Enter to exit: ", + inactivity_timeout, ).strip() except TimeoutError: print(colored("Session timed out. Vault locked.", "yellow")) @@ -766,13 +763,10 @@ def display_menu( continue password_manager.update_activity() if not choice: - print( - colored( - "No input detected. Please enter a number between 1 and 8.", - "yellow", - ) - ) - continue # Re-display the menu without marking as invalid + logging.info("Exiting the program.") + print(colored("Exiting the program.", "green")) + password_manager.nostr_client.close_client_pool() + sys.exit(0) if choice == "1": while True: print(color_text("\nAdd Entry:", "menu")) @@ -782,8 +776,9 @@ def display_menu( print(color_text("4. Seed Phrase", "menu")) print(color_text("5. Nostr Key Pair", "menu")) print(color_text("6. PGP Key", "menu")) - print(color_text("7. Back", "menu")) - sub_choice = input("Select entry type: ").strip() + sub_choice = input( + "Select entry type or press Enter to go back: " + ).strip() password_manager.update_activity() if sub_choice == "1": password_manager.handle_add_password() @@ -803,7 +798,7 @@ def display_menu( elif sub_choice == "6": password_manager.handle_add_pgp() break - elif sub_choice == "7": + elif not sub_choice: break else: print(colored("Invalid choice.", "red")) @@ -826,11 +821,6 @@ def display_menu( elif choice == "7": password_manager.update_activity() handle_settings(password_manager) - elif choice == "8": - logging.info("Exiting the program.") - print(colored("Exiting the program.", "green")) - password_manager.nostr_client.close_client_pool() - sys.exit(0) else: print(colored("Invalid choice. Please select a valid option.", "red")) diff --git a/src/password_manager/manager.py b/src/password_manager/manager.py index d756aa5..a0776e1 100644 --- a/src/password_manager/manager.py +++ b/src/password_manager/manager.py @@ -978,8 +978,7 @@ class PasswordManager: print("\nAdd TOTP:") print("1. Make 2FA (derive from seed)") print("2. Import 2FA (paste otpauth URI or secret)") - print("3. Back") - choice = input("Select option: ").strip() + choice = input("Select option or press Enter to go back: ").strip() if choice == "1": label = input("Label: ").strip() if not label: @@ -1062,7 +1061,7 @@ class PasswordManager: break except ValueError as err: print(colored(f"Error: {err}", "red")) - elif choice == "3": + elif not choice: return else: print(colored("Invalid choice.", "red")) @@ -1978,8 +1977,7 @@ class PasswordManager: print(color_text("5. Seed Phrase", "menu")) print(color_text("6. Nostr Key Pair", "menu")) print(color_text("7. PGP", "menu")) - print(color_text("8. Back", "menu")) - choice = input("Select entry type: ").strip() + choice = input("Select entry type or press Enter to go back: ").strip() if choice == "1": filter_kind = None elif choice == "2": @@ -1994,7 +1992,7 @@ class PasswordManager: filter_kind = EntryType.NOSTR.value elif choice == "7": filter_kind = EntryType.PGP.value - elif choice == "8": + elif not choice: return else: print(colored("Invalid choice.", "red")) diff --git a/src/tests/test_auto_sync.py b/src/tests/test_auto_sync.py index 7c8466e..53cf949 100644 --- a/src/tests/test_auto_sync.py +++ b/src/tests/test_auto_sync.py @@ -31,7 +31,7 @@ def test_auto_sync_triggers_post(monkeypatch): called = True monkeypatch.setattr(main, "handle_post_to_nostr", fake_post) - monkeypatch.setattr(main, "timed_input", lambda *_: "8") + monkeypatch.setattr(main, "timed_input", lambda *_: "") with pytest.raises(SystemExit): main.display_menu(pm, sync_interval=0.1) diff --git a/src/tests/test_cli_invalid_input.py b/src/tests/test_cli_invalid_input.py index 7fa4b16..6331c8c 100644 --- a/src/tests/test_cli_invalid_input.py +++ b/src/tests/test_cli_invalid_input.py @@ -52,12 +52,11 @@ def _make_pm(called, locked=None): def test_empty_and_non_numeric_choice(monkeypatch, capsys): called = {"add": False, "retrieve": False, "modify": False} pm, _ = _make_pm(called) - inputs = iter(["", "abc", "8"]) + inputs = iter(["abc", ""]) monkeypatch.setattr(main, "timed_input", lambda *_: next(inputs)) with pytest.raises(SystemExit): main.display_menu(pm, sync_interval=1000, inactivity_timeout=1000) out = capsys.readouterr().out - assert "No input detected" in out assert "Invalid choice. Please select a valid option." in out assert not any(called.values()) @@ -65,7 +64,7 @@ def test_empty_and_non_numeric_choice(monkeypatch, capsys): def test_out_of_range_menu(monkeypatch, capsys): called = {"add": False, "retrieve": False, "modify": False} pm, _ = _make_pm(called) - inputs = iter(["9", "8"]) + inputs = iter(["9", ""]) monkeypatch.setattr(main, "timed_input", lambda *_: next(inputs)) with pytest.raises(SystemExit): main.display_menu(pm, sync_interval=1000, inactivity_timeout=1000) @@ -77,7 +76,7 @@ def test_out_of_range_menu(monkeypatch, capsys): def test_invalid_add_entry_submenu(monkeypatch, capsys): called = {"add": False, "retrieve": False, "modify": False} pm, _ = _make_pm(called) - inputs = iter(["1", "8", "7", "8"]) + inputs = iter(["1", "8", "", ""]) monkeypatch.setattr(main, "timed_input", lambda *_: next(inputs)) monkeypatch.setattr("builtins.input", lambda *_: next(inputs)) with pytest.raises(SystemExit): @@ -92,7 +91,7 @@ def test_inactivity_timeout_loop(monkeypatch, capsys): pm, locked = _make_pm(called) pm.last_activity = 0 monkeypatch.setattr(time, "time", lambda: 100.0) - monkeypatch.setattr(main, "timed_input", lambda *_: "8") + monkeypatch.setattr(main, "timed_input", lambda *_: "") with pytest.raises(SystemExit): main.display_menu(pm, sync_interval=1000, inactivity_timeout=0.1) out = capsys.readouterr().out diff --git a/src/tests/test_inactivity_lock.py b/src/tests/test_inactivity_lock.py index 46253f4..0c68561 100644 --- a/src/tests/test_inactivity_lock.py +++ b/src/tests/test_inactivity_lock.py @@ -36,7 +36,7 @@ def test_inactivity_triggers_lock(monkeypatch): unlock_vault=unlock_vault, ) - monkeypatch.setattr(main, "timed_input", lambda *_: "8") + monkeypatch.setattr(main, "timed_input", lambda *_: "") with pytest.raises(SystemExit): main.display_menu(pm, sync_interval=1000, inactivity_timeout=0.1) @@ -72,7 +72,7 @@ def test_input_timeout_triggers_lock(monkeypatch): unlock_vault=unlock_vault, ) - responses = iter([TimeoutError(), "8"]) + responses = iter([TimeoutError(), ""]) def fake_input(*_args, **_kwargs): val = next(responses) diff --git a/src/tests/test_menu_options.py b/src/tests/test_menu_options.py index c45ba9d..ff8e7cf 100644 --- a/src/tests/test_menu_options.py +++ b/src/tests/test_menu_options.py @@ -30,7 +30,7 @@ def _make_pm(calls): def test_menu_totp_option(monkeypatch): calls = [] pm = _make_pm(calls) - inputs = iter(["6", "8"]) + inputs = iter(["6", ""]) monkeypatch.setattr(main, "timed_input", lambda *_: next(inputs)) monkeypatch.setattr(main, "handle_settings", lambda *_: None) with pytest.raises(SystemExit): @@ -41,7 +41,7 @@ def test_menu_totp_option(monkeypatch): def test_menu_settings_option(monkeypatch): calls = [] pm = _make_pm(calls) - inputs = iter(["7", "8"]) + inputs = iter(["7", ""]) monkeypatch.setattr(main, "timed_input", lambda *_: next(inputs)) monkeypatch.setattr(main, "handle_settings", lambda *_: calls.append("settings")) with pytest.raises(SystemExit): diff --git a/src/tests/test_menu_search.py b/src/tests/test_menu_search.py index 7f1d70e..0e1d439 100644 --- a/src/tests/test_menu_search.py +++ b/src/tests/test_menu_search.py @@ -30,7 +30,7 @@ def _make_pm(called): def test_menu_search_option(monkeypatch): called = [] pm = _make_pm(called) - inputs = iter(["3", "8"]) + inputs = iter(["3", ""]) monkeypatch.setattr(main, "timed_input", lambda *_: next(inputs)) monkeypatch.setattr("builtins.input", lambda *_: "query") with pytest.raises(SystemExit): diff --git a/src/tests/test_settings_menu.py b/src/tests/test_settings_menu.py index bd8a6f0..6899822 100644 --- a/src/tests/test_settings_menu.py +++ b/src/tests/test_settings_menu.py @@ -93,7 +93,7 @@ def test_settings_menu_additional_backup(monkeypatch): tmp_path = Path(tmpdir) pm, cfg_mgr, fp_mgr = setup_pm(tmp_path, monkeypatch) - inputs = iter(["10", "15"]) + inputs = iter(["10", ""]) with patch("main.handle_set_additional_backup_location") as handler: with patch("builtins.input", side_effect=lambda *_: next(inputs)): main.handle_settings(pm)