Skip to content

Commit

Permalink
fix(suite-native): prohibit swiping back from authorize device screens
Browse files Browse the repository at this point in the history
  • Loading branch information
yanascz committed Jan 24, 2025
1 parent 61f1d57 commit f1b822d
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 62 deletions.
1 change: 1 addition & 0 deletions suite-native/app/src/navigation/RootStackNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const RootStackNavigator = () => {
options={{
...stackNavigationOptionsConfig,
animation: 'slide_from_bottom',
gestureEnabled: false,
}}
/>
<RootStack.Screen
Expand Down
13 changes: 3 additions & 10 deletions suite-native/coin-enabling/src/screens/CoinEnablingInitScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { useDispatch, useSelector } from 'react-redux';
import Animated, { SlideInDown, SlideOutDown } from 'react-native-reanimated';
import { useEffect } from 'react';
import { BackHandler, View } from 'react-native';
import { View } from 'react-native';

import { A } from '@mobily/ts-belt';
import { useNavigation } from '@react-navigation/native';
import { LinearGradient } from 'expo-linear-gradient';

import { Screen } from '@suite-native/navigation';
import { Screen, useHandleHardwareBackNavigation } from '@suite-native/navigation';
import { Box, Button, Text, VStack } from '@suite-native/atoms';
import {
applyDiscoveryChangesThunk,
Expand Down Expand Up @@ -52,6 +51,7 @@ const buttonStyle = prepareNativeStyle(utils => ({
export const CoinEnablingInitScreen = () => {
const dispatch = useDispatch();
const navigation = useNavigation();
useHandleHardwareBackNavigation();

const { applyStyle, utils } = useNativeStyles();
const enabledNetworkSymbols = useSelector(selectDeviceEnabledDiscoveryNetworkSymbols);
Expand All @@ -69,13 +69,6 @@ export const CoinEnablingInitScreen = () => {
}
};

useEffect(() => {
//prevent dismissing screen via HW
const subscription = BackHandler.addEventListener('hardwareBackPress', () => true);

return () => subscription.remove();
}, []);

// 'transparent' color is not working in context of LinearGradient on iOS. RGBA has to be used instead.
const transparentColor = hexToRgba(utils.colors.backgroundSurfaceElevation0, 0.01);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useCallback, useEffect, useState } from 'react';
import { BackHandler } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';

import { selectFiatCurrencyCode } from '@suite-native/settings';
Expand All @@ -9,6 +8,7 @@ import {
RootStackParamList,
Screen,
StackToStackCompositeScreenProps,
useHandleHardwareBackNavigation,
} from '@suite-native/navigation';
import { AccountInfo } from '@trezor/connect';
import { SpinnerLoadingState } from '@suite-native/atoms';
Expand Down Expand Up @@ -36,6 +36,8 @@ export const AccountImportLoadingScreen = ({
const [accountInfoFetchResult, setAccountInfoFetchResult] =
useState<SpinnerLoadingState>('idle');

useHandleHardwareBackNavigation();

const fetchAccountInfo = useCallback(async () => {
try {
const response = await dispatch(
Expand Down Expand Up @@ -71,13 +73,6 @@ export const AccountImportLoadingScreen = ({
[error, showImportError],
);

useEffect(() => {
// prevent dismissing screen via HW
const subscription = BackHandler.addEventListener('hardwareBackPress', () => true);

return () => subscription.remove();
}, []);

useEffect(() => {
fetchAccountInfo();
}, [fetchAccountInfo]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useEffect } from 'react';
import { BackHandler } from 'react-native';
import { useSelector } from 'react-redux';

import {
Expand All @@ -16,6 +14,7 @@ import {
AccountsImportStackRoutes,
RootStackParamList,
StackToTabCompositeScreenProps,
useHandleHardwareBackNavigation,
} from '@suite-native/navigation';

import { AccountAlreadyImportedScreen } from '../components/AccountAlreadyImportedScreen';
Expand All @@ -31,6 +30,8 @@ export const AccountImportSummaryScreen = ({
const { accountInfo, networkSymbol } = route.params;

const isRegtestEnabled = useFeatureFlag(FeatureFlag.IsRegtestEnabled);
useHandleHardwareBackNavigation();

const account = useSelector((state: AccountsRootState & DeviceRootState) =>
selectDeviceAccountByDescriptorAndNetworkSymbol(
state,
Expand All @@ -40,13 +41,6 @@ export const AccountImportSummaryScreen = ({
);
const portfolioTrackerSupportedNetworks = useSelector(selectPortfolioTrackerNetworkSymbols);

useEffect(() => {
// prevent dismissing screen via HW
const subscription = BackHandler.addEventListener('hardwareBackPress', () => true);

return () => subscription.remove();
}, []);

const isAccountImportSupported =
portfolioTrackerSupportedNetworks.some(
supportedSymbol => supportedSymbol === networkSymbol,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { BackHandler } from 'react-native';
import { useCallback, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';

Expand All @@ -11,6 +10,7 @@ import {
NavigateParameters,
RootStackParamList,
StackToTabCompositeProps,
useHandleHardwareBackNavigation,
} from '@suite-native/navigation';
import { IconButton, ScreenHeaderWrapper } from '@suite-native/atoms';
import { useAlert } from '@suite-native/alerts';
Expand Down Expand Up @@ -49,18 +49,22 @@ export const ConnectDeviceScreenHeader = ({

const handleCancel = useCallback(() => {
if (hasDiscovery) {
// Do not allow to cancel PIN entry while discovery is in progress
showAlert({
title: <Translation id="moduleConnectDevice.pinCanceledDuringDiscovery.title" />,
description: (
<Translation id="moduleConnectDevice.pinCanceledDuringDiscovery.subtitle" />
),
pictogramVariant: 'critical',
primaryButtonTitle: (
<Translation id="moduleConnectDevice.pinCanceledDuringDiscovery.button" />
),
onPressPrimaryButton: hideAlert,
});
if (hasDeviceRequestedPin) {
// Do not allow to cancel PIN entry while discovery is in progress
showAlert({
title: (
<Translation id="moduleConnectDevice.pinCanceledDuringDiscovery.title" />
),
description: (
<Translation id="moduleConnectDevice.pinCanceledDuringDiscovery.subtitle" />
),
pictogramVariant: 'critical',
primaryButtonTitle: (
<Translation id="moduleConnectDevice.pinCanceledDuringDiscovery.button" />
),
onPressPrimaryButton: hideAlert,
});
}
} else {
// Remove unauthorized passphrase device if it was created before prompting the PIN.
if (isCreatingNewWalletInstance) {
Expand Down Expand Up @@ -92,16 +96,7 @@ export const ConnectDeviceScreenHeader = ({
onCancelNavigationTarget,
]);

// Handle hardware back button press same as cancel button
useEffect(() => {
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
handleCancel();

return true;
});

return () => subscription.remove();
}, [handleCancel]);
useHandleHardwareBackNavigation(handleCancel);

// Hide alert when navigating away from the PIN entry screen (PIN entered or canceled on device)
// eslint-disable-next-line arrow-body-style
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useDispatch, useSelector } from 'react-redux';
import { useCallback, useEffect } from 'react';
import { BackHandler } from 'react-native';
import { useCallback } from 'react';

import { useNavigation, useRoute } from '@react-navigation/native';

Expand All @@ -20,6 +19,7 @@ import {
RootStackParamList,
StackToTabCompositeProps,
useNavigateToInitialScreen,
useHandleHardwareBackNavigation,
} from '@suite-native/navigation';
import { useAlert } from '@suite-native/alerts';
import { EventType, analytics } from '@suite-native/analytics';
Expand Down Expand Up @@ -78,15 +78,7 @@ export const PassphraseScreenHeader = () => {
}
}, [handleClose, navigateToInitialScreen, isCreatingNewWalletInstance, showAlert]);

useEffect(() => {
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
handleCancel();

return true;
});

return () => subscription.remove();
}, [handleCancel]);
useHandleHardwareBackNavigation(handleCancel);

return (
<ScreenHeaderWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ export const AuthorizeDeviceStackNavigator = () => {
useHandleDuplicatePassphrase();

return (
<AuthorizeDeviceStack.Navigator screenOptions={stackNavigationOptionsConfig}>
<AuthorizeDeviceStack.Navigator
screenOptions={{ ...stackNavigationOptionsConfig, gestureEnabled: false }}
>
{
// For proper screen transitions on both cancel and success PIN entry
// we need to remove those screens from the stack so we can navigate
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ActivityIndicator } from 'react-native';

import { useHandleHardwareBackNavigation } from '@suite-native/navigation';
import { Text, VStack, Box } from '@suite-native/atoms';
import { Icon } from '@suite-native/icons';
import { useNativeStyles, prepareNativeStyle } from '@trezor/styles';
Expand All @@ -16,6 +17,8 @@ const screenStyle = prepareNativeStyle(() => ({

export const ConnectingDeviceScreen = () => {
useOnDeviceReadyNavigation();
useHandleHardwareBackNavigation();

const { applyStyle } = useNativeStyles();

return (
Expand Down
1 change: 1 addition & 0 deletions suite-native/navigation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from './navigators';
export * from './routes';
export * from './types';
export * from './config';
export * from './useHandleHardwareBackNavigation';
export * from './useNavigateToInitialScreen';
export * from './useScrollDivider';
export * from './components/TabBar';
Expand Down
15 changes: 15 additions & 0 deletions suite-native/navigation/src/useHandleHardwareBackNavigation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useEffect } from 'react';
import { BackHandler } from 'react-native';

export const useHandleHardwareBackNavigation = (onPress?: () => void) => {
useEffect(() => {
// do nothing unless onPress has some custom handling
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
onPress?.();

return true;
});

return () => subscription.remove();
}, [onPress]);
};

0 comments on commit f1b822d

Please sign in to comment.