From 09fc0ebf3e91e2b1146cc8a6e5c6c4b735f4becb Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Wed, 5 Jun 2024 10:52:50 +0200 Subject: [PATCH] fix(core): add missing tap to confirm screens to mercury [no changelog] --- core/src/apps/base.py | 1 + core/src/apps/management/apply_settings.py | 9 +++++++++ core/src/apps/management/authenticate_device.py | 1 + core/src/apps/management/change_language.py | 1 + core/src/apps/management/change_wipe_code.py | 1 + .../src/apps/management/get_next_u2f_counter.py | 1 + .../src/apps/management/reboot_to_bootloader.py | 1 + core/src/apps/management/sd_protect.py | 4 +++- core/src/apps/management/set_u2f_counter.py | 1 + core/src/apps/misc/cipher_key_value.py | 8 +++++++- core/src/apps/misc/get_entropy.py | 1 + core/src/apps/monero/layout.py | 4 ++++ core/src/apps/stellar/layout.py | 1 + core/src/trezor/ui/layouts/mercury/fido.py | 1 + tests/click_tests/common.py | 11 +++++++++++ tests/click_tests/test_autolock.py | 4 +++- tests/click_tests/test_pin.py | 17 +++++++++++++++-- 17 files changed, 62 insertions(+), 5 deletions(-) diff --git a/core/src/apps/base.py b/core/src/apps/base.py index 36de3a71e5..02621f252a 100644 --- a/core/src/apps/base.py +++ b/core/src/apps/base.py @@ -328,6 +328,7 @@ async def handle_UnlockPath(msg: UnlockPath) -> protobuf.MessageType: title="Coinjoin", description=TR.coinjoin__access_account, verb=TR.buttons__access, + prompt_screen=True, ) wire_types = (MessageType.GetAddress, MessageType.GetPublicKey, MessageType.SignTx) diff --git a/core/src/apps/management/apply_settings.py b/core/src/apps/management/apply_settings.py index 0ce4ae6a77..1f06cd1e18 100644 --- a/core/src/apps/management/apply_settings.py +++ b/core/src/apps/management/apply_settings.py @@ -155,6 +155,7 @@ async def _require_confirm_change_passphrase(use: bool) -> None: description=description, verb=verb, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) @@ -171,6 +172,7 @@ async def _require_confirm_change_passphrase_source( TR.passphrase__title_source, description=description, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) @@ -192,6 +194,7 @@ async def _require_confirm_change_display_rotation(rotation: int) -> None: description=TR.rotation__change_template, description_param=label, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) @@ -211,6 +214,7 @@ async def _require_confirm_change_autolock_delay(delay_ms: int) -> None: description=TR.auto_lock__change_template, description_param=format_duration_ms(delay_ms, unit_plurals), br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) @@ -223,6 +227,7 @@ async def _require_confirm_safety_checks(level: SafetyCheckLevel) -> None: TR.safety_checks__title, description=TR.safety_checks__enforce_strict, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) elif level in (SafetyCheckLevel.PromptAlways, SafetyCheckLevel.PromptTemporarily): description = ( @@ -239,6 +244,7 @@ async def _require_confirm_safety_checks(level: SafetyCheckLevel) -> None: verb=TR.buttons__hold_to_confirm, reverse=True, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) else: raise ValueError # enum value out of range @@ -253,6 +259,7 @@ async def _require_confirm_experimental_features(enable: bool) -> None: TR.experimental_mode__enable, reverse=True, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) @@ -263,6 +270,7 @@ async def _require_confirm_hide_passphrase_from_host(enable: bool) -> None: TR.passphrase__title_hide, description=TR.passphrase__hide, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) @@ -275,4 +283,5 @@ if utils.USE_HAPTIC: TR.haptic_feedback__enable if enable else TR.haptic_feedback__disable, subtitle=TR.haptic_feedback__subtitle, br_code=BRT_PROTECT_CALL, + prompt_screen=True, ) diff --git a/core/src/apps/management/authenticate_device.py b/core/src/apps/management/authenticate_device.py index 2ea2f9d1fb..d1c2fbe6e9 100644 --- a/core/src/apps/management/authenticate_device.py +++ b/core/src/apps/management/authenticate_device.py @@ -25,6 +25,7 @@ async def authenticate_device(msg: AuthenticateDevice) -> AuthenticityProof: TR.authenticate__header, description=TR.authenticate__confirm_template.format(utils.MODEL_FULL_NAME), verb=TR.buttons__allow, + prompt_screen=True, ) header = b"AuthenticateDevice:" diff --git a/core/src/apps/management/change_language.py b/core/src/apps/management/change_language.py index d942e8c09a..88c8dcbf4d 100644 --- a/core/src/apps/management/change_language.py +++ b/core/src/apps/management/change_language.py @@ -169,6 +169,7 @@ async def _require_confirm_change_language( description=TR.language__change_to_template.format(lang), verb="OK", # going for an international word, so it does not need translations br_code=ButtonRequestType.ProtectCall, + prompt_screen=True, ) diff --git a/core/src/apps/management/change_wipe_code.py b/core/src/apps/management/change_wipe_code.py index 7516f665e2..b5256fd459 100644 --- a/core/src/apps/management/change_wipe_code.py +++ b/core/src/apps/management/change_wipe_code.py @@ -68,6 +68,7 @@ def _require_confirm_action( TR.wipe_code__title_settings, description=TR.wipe_code__turn_off, verb=TR.buttons__turn_off, + prompt_screen=True, ) if not msg.remove and has_wipe_code: diff --git a/core/src/apps/management/get_next_u2f_counter.py b/core/src/apps/management/get_next_u2f_counter.py index e97536df32..90035d4a74 100644 --- a/core/src/apps/management/get_next_u2f_counter.py +++ b/core/src/apps/management/get_next_u2f_counter.py @@ -20,6 +20,7 @@ async def get_next_u2f_counter(msg: GetNextU2FCounter) -> NextU2FCounter: TR.u2f__title_get, description=TR.u2f__get, br_code=ButtonRequestType.ProtectCall, + prompt_screen=True, ) return NextU2FCounter(u2f_counter=storage_device.next_u2f_counter()) diff --git a/core/src/apps/management/reboot_to_bootloader.py b/core/src/apps/management/reboot_to_bootloader.py index b1fa64297d..85596c0268 100644 --- a/core/src/apps/management/reboot_to_bootloader.py +++ b/core/src/apps/management/reboot_to_bootloader.py @@ -83,6 +83,7 @@ async def reboot_to_bootloader(msg: RebootToBootloader) -> NoReturn: TR.reboot_to_bootloader__title, TR.reboot_to_bootloader__restart, verb=TR.buttons__restart, + prompt_screen=True, ) boot_command = BootCommand.STOP_AND_WAIT boot_args = None diff --git a/core/src/apps/management/sd_protect.py b/core/src/apps/management/sd_protect.py index b21a818070..74717fea02 100644 --- a/core/src/apps/management/sd_protect.py +++ b/core/src/apps/management/sd_protect.py @@ -171,4 +171,6 @@ def require_confirm_sd_protect(msg: SdProtect) -> Awaitable[None]: else: raise ProcessError("Unknown operation") - return confirm_action("set_sd", TR.sd_card__title, description=text) + return confirm_action( + "set_sd", TR.sd_card__title, description=text, prompt_screen=True + ) diff --git a/core/src/apps/management/set_u2f_counter.py b/core/src/apps/management/set_u2f_counter.py index 19959f8752..85d32085ae 100644 --- a/core/src/apps/management/set_u2f_counter.py +++ b/core/src/apps/management/set_u2f_counter.py @@ -23,6 +23,7 @@ async def set_u2f_counter(msg: SetU2FCounter) -> Success: description_param=str(msg.u2f_counter), verb=TR.buttons__set, br_code=ButtonRequestType.ProtectCall, + prompt_screen=True, ) storage_device.set_u2f_counter(msg.u2f_counter) diff --git a/core/src/apps/misc/cipher_key_value.py b/core/src/apps/misc/cipher_key_value.py index 823f863161..c4f130ee60 100644 --- a/core/src/apps/misc/cipher_key_value.py +++ b/core/src/apps/misc/cipher_key_value.py @@ -36,7 +36,13 @@ async def cipher_key_value(msg: CipherKeyValue) -> CipheredKeyValue: title = TR.misc__decrypt_value verb = TR.buttons__confirm - await confirm_action("cipher_key_value", title, description=msg.key, verb=verb) + await confirm_action( + "cipher_key_value", + title, + description=msg.key, + verb=verb, + prompt_screen=True, + ) node = keychain.derive(msg.address_n) diff --git a/core/src/apps/misc/get_entropy.py b/core/src/apps/misc/get_entropy.py index dae1c238a7..b3b654268d 100644 --- a/core/src/apps/misc/get_entropy.py +++ b/core/src/apps/misc/get_entropy.py @@ -17,6 +17,7 @@ async def get_entropy(msg: GetEntropy) -> Entropy: TR.entropy__send, TR.words__know_what_your_doing, br_code=ButtonRequestType.ProtectCall, + prompt_screen=True, ) size = min(msg.size, 1024) diff --git a/core/src/apps/monero/layout.py b/core/src/apps/monero/layout.py index bf37b473f6..127c1eb986 100644 --- a/core/src/apps/monero/layout.py +++ b/core/src/apps/monero/layout.py @@ -65,6 +65,7 @@ async def require_confirm_watchkey() -> None: TR.monero__confirm_export, description=TR.monero__wanna_export_watchkey, br_code=BRT_SignTx, + prompt_screen=True, ) @@ -74,6 +75,7 @@ async def require_confirm_keyimage_sync() -> None: TR.monero__confirm_ki_sync, description=TR.monero__wanna_sync_key_images, br_code=BRT_SignTx, + prompt_screen=True, ) @@ -83,6 +85,7 @@ async def require_confirm_live_refresh() -> None: TR.monero__confirm_refresh, description=TR.monero__wanna_start_refresh, br_code=BRT_SignTx, + prompt_screen=True, ) @@ -95,6 +98,7 @@ async def require_confirm_tx_key(export_key: bool = False) -> None: TR.monero__confirm_export, description=description, br_code=BRT_SignTx, + prompt_screen=True, ) diff --git a/core/src/apps/stellar/layout.py b/core/src/apps/stellar/layout.py index 72f8c206b6..3d3a5107d0 100644 --- a/core/src/apps/stellar/layout.py +++ b/core/src/apps/stellar/layout.py @@ -89,6 +89,7 @@ async def require_confirm_memo(memo_type: StellarMemoType, memo_text: str) -> No TR.stellar__no_memo_set, TR.stellar__exchanges_require_memo, br_code=ButtonRequestType.ConfirmOutput, + prompt_screen=True, ) await layouts.confirm_blob( diff --git a/core/src/trezor/ui/layouts/mercury/fido.py b/core/src/trezor/ui/layouts/mercury/fido.py index 390fb4b7e0..b7bcacbd54 100644 --- a/core/src/trezor/ui/layouts/mercury/fido.py +++ b/core/src/trezor/ui/layouts/mercury/fido.py @@ -84,6 +84,7 @@ async def confirm_fido_reset() -> bool: action=TR.fido__erase_credentials, description=TR.words__really_wanna, reverse=True, + prompt_screen=True, ) ) return (await confirm) is trezorui2.CONFIRMED diff --git a/tests/click_tests/common.py b/tests/click_tests/common.py index 781cfb47bf..e85fc2b956 100644 --- a/tests/click_tests/common.py +++ b/tests/click_tests/common.py @@ -56,6 +56,17 @@ def go_next(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None: raise RuntimeError("Unknown model") +def tap_to_confirm(debug: "DebugLink", wait: bool = False) -> "LayoutContent" | None: + if debug.model in (models.T2T1,): + return debug.read_layout() # type: ignore + elif debug.model in (models.T2B1,): + return debug.read_layout() # type: ignore + elif debug.model in (models.T3T1,): + return debug.click(buttons.TAP_TO_CONFIRM, wait=wait) + else: + raise RuntimeError("Unknown model") + + def go_back( debug: "DebugLink", wait: bool = False, r_middle: bool = False ) -> "LayoutContent" | None: diff --git a/tests/click_tests/test_autolock.py b/tests/click_tests/test_autolock.py index 14e81ba39e..e2ec5729d9 100644 --- a/tests/click_tests/test_autolock.py +++ b/tests/click_tests/test_autolock.py @@ -29,7 +29,7 @@ from .. import translations as TR from ..device_tests.bitcoin.payment_req import make_coinjoin_request from ..tx_cache import TxCache from . import recovery -from .common import go_next, unlock_gesture +from .common import go_next, tap_to_confirm, unlock_gesture if TYPE_CHECKING: from trezorlib.debuglink import DebugLink, LayoutContent @@ -70,6 +70,8 @@ def set_autolock_delay(device_handler: "BackgroundDeviceHandler", delay_ms: int) ) layout = go_next(debug, wait=True) + if debug.model in (models.T3T1,): + layout = tap_to_confirm(debug, wait=True) assert layout.main_component() == "Homescreen" assert device_handler.result() == "Settings applied" diff --git a/tests/click_tests/test_pin.py b/tests/click_tests/test_pin.py index 48845c50fc..410cf43e5d 100644 --- a/tests/click_tests/test_pin.py +++ b/tests/click_tests/test_pin.py @@ -74,6 +74,7 @@ class Situation(Enum): PIN_SETUP = 2 PIN_CHANGE = 3 WIPE_CODE_SETUP = 4 + PIN_INPUT_CANCEL = 5 @contextmanager @@ -88,10 +89,16 @@ def prepare( # without reseeding "again", the results are still random. debug.reseed(0) + tap = False + # Setup according to the wanted situation if situation == Situation.PIN_INPUT: # Any action triggering the PIN dialogue device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore + tap = True + if situation == Situation.PIN_INPUT_CANCEL: + # Any action triggering the PIN dialogue + device_handler.run(device.apply_settings, auto_lock_delay_ms=300_000) # type: ignore elif situation == Situation.PIN_SETUP: # Set new PIN device_handler.run(device.change_pin) # type: ignore @@ -130,7 +137,13 @@ def prepare( debug.wait_layout() _assert_pin_entry(debug) yield debug - go_next(debug) + + if debug.model in (models.T3T1,) and tap: + go_next(debug, wait=True) + debug.click(buttons.TAP_TO_CONFIRM) + else: + go_next(debug) + device_handler.result() @@ -290,7 +303,7 @@ def test_pin_incorrect(device_handler: "BackgroundDeviceHandler"): @pytest.mark.skip_t2b1("TODO: will we support cancelling on T2B1?") @pytest.mark.setup_client(pin=PIN4) def test_pin_cancel(device_handler: "BackgroundDeviceHandler"): - with PIN_CANCELLED, prepare(device_handler) as debug: + with PIN_CANCELLED, prepare(device_handler, Situation.PIN_INPUT_CANCEL) as debug: _input_pin(debug, PIN4) _see_pin(debug) _delete_pin(debug, len(PIN4))