diff --git a/packages/suite/src/constants/suite/firmware.ts b/packages/suite/src/constants/suite/firmware.ts index b8cdaa0fab7..34e72d2c8a8 100644 --- a/packages/suite/src/constants/suite/firmware.ts +++ b/packages/suite/src/constants/suite/firmware.ts @@ -7,12 +7,14 @@ import { FilterPropertiesByType } from '@trezor/type-utils'; * see suite-native/device/src/config/firmware.ts for Suite Lite */ +type BehaviorBaseType = { shouldReport: boolean; debugOnly?: boolean }; + // will be ignored completely -type SkippedBehavior = { type: 'skipped'; shouldReport: boolean }; +type SkippedBehavior = BehaviorBaseType & { type: 'skipped' }; // display a warning banner -type SoftWarningBehavior = { type: 'softWarning'; shouldReport: true }; +type SoftWarningBehavior = BehaviorBaseType & { type: 'softWarning'; shouldReport: true }; // display "Device Compromised" modal, after closing it display a warning banner, block receiving address -type HardModalBehavior = { type: 'hardModal'; shouldReport: true }; +type HardModalBehavior = BehaviorBaseType & { type: 'hardModal'; shouldReport: true }; type RevisionErrorBehavior = SoftWarningBehavior | HardModalBehavior; type RevisionCheckErrorScenarios = Record; @@ -33,8 +35,8 @@ export const hashCheckErrorScenarios = { 'check-unsupported': { type: 'skipped', shouldReport: false }, // could mean counterfeit firmware, but it's also caught by revision check, which handles edge-cases better 'unknown-release': { type: 'skipped', shouldReport: false }, - // TODO fix FW hash check unreliability & reenable on production - 'other-error': { type: isDevEnv ? 'hardModal' : 'skipped', shouldReport: true }, + // TODO fix FW hash check unreliability & reenable on production (outside of debug mode) + 'other-error': { type: 'hardModal', shouldReport: true, debugOnly: true }, } satisfies HashCheckErrorScenarios; export type SkippedHashCheckError = keyof FilterPropertiesByType< @@ -45,3 +47,9 @@ export type SkippedHashCheckError = keyof FilterPropertiesByType< export const isSkippedHashCheckError = ( error: FirmwareHashCheckError, ): error is SkippedHashCheckError => hashCheckErrorScenarios[error].type === 'skipped'; + +export const isDebugOnlyRevisionCheckError = (error: FirmwareRevisionCheckError): boolean => + (revisionCheckErrorScenarios[error] as RevisionErrorBehavior).debugOnly ?? false; + +export const isDebugOnlyHashCheckError = (error: FirmwareHashCheckError): boolean => + (hashCheckErrorScenarios[error] as HashErrorBehavior).debugOnly ?? false; diff --git a/packages/suite/src/reducers/suite/suiteReducer.ts b/packages/suite/src/reducers/suite/suiteReducer.ts index 2454a8c3043..bda6619140e 100644 --- a/packages/suite/src/reducers/suite/suiteReducer.ts +++ b/packages/suite/src/reducers/suite/suiteReducer.ts @@ -16,6 +16,8 @@ import type { Locale } from 'src/config/suite/languages'; import { ExperimentalFeature } from 'src/constants/suite/experimental'; import { hashCheckErrorScenarios, + isDebugOnlyHashCheckError, + isDebugOnlyRevisionCheckError, isSkippedHashCheckError, revisionCheckErrorScenarios, } from 'src/constants/suite/firmware'; @@ -493,11 +495,19 @@ export const selectFirmwareRevisionCheckError = (state: AppState) => { export const selectFirmwareRevisionCheckErrorIfEnabled = (state: AppState) => { const revisionCheckError = selectFirmwareRevisionCheckError(state); + if (revisionCheckError === null) return null; + const { isFirmwareRevisionCheckDisabled } = state.suite.settings; - const isDisabledByMessage = selectIsFeatureDisabled(state, Feature.firmwareRevisionCheck); - const isCheckEnabled = !isFirmwareRevisionCheckDisabled && !isDisabledByMessage; + if (isFirmwareRevisionCheckDisabled) return null; + + const isDisabledByMessageSystem = selectIsFeatureDisabled(state, Feature.firmwareRevisionCheck); + if (isDisabledByMessageSystem) return null; + + const isHiddenBehindDebug = + isDebugOnlyRevisionCheckError(revisionCheckError) && !selectIsDebugModeActive(state); + if (isHiddenBehindDebug) return null; - return isCheckEnabled ? revisionCheckError : null; + return revisionCheckError; }; /** @@ -518,11 +528,19 @@ export const selectFirmwareHashCheckError = (state: AppState) => { export const selectFirmwareHashCheckErrorIfEnabled = (state: AppState) => { const hashCheckError = selectFirmwareHashCheckError(state); + if (hashCheckError === null) return null; + const { isFirmwareHashCheckDisabled } = state.suite.settings; - const isDisabledByMessage = selectIsFeatureDisabled(state, Feature.firmwareHashCheck); - const isCheckEnabled = !isFirmwareHashCheckDisabled && !isDisabledByMessage; + if (isFirmwareHashCheckDisabled) return null; + + const isDisabledByMessageSystem = selectIsFeatureDisabled(state, Feature.firmwareHashCheck); + if (isDisabledByMessageSystem) return null; + + const isHiddenBehindDebug = + isDebugOnlyHashCheckError(hashCheckError) && !selectIsDebugModeActive(state); + if (isHiddenBehindDebug) return null; - return isCheckEnabled ? hashCheckError : null; + return hashCheckError; }; /**