Skip to content

Commit 3b8d7fd

Browse files
committed
fix(native-suite): device authenticity action refactoring
1 parent 5686672 commit 3b8d7fd

6 files changed

+92
-62
lines changed

suite-native/module-device-settings/src/components/DeviceAuthenticityCard.tsx

+5-55
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ import { useSelector } from 'react-redux';
33

44
import { useNavigation } from '@react-navigation/native';
55

6-
import { selectIsDeviceDiscoveryActive, selectSelectedDevice } from '@suite-common/wallet-core';
6+
import { selectIsDeviceDiscoveryActive } from '@suite-common/wallet-core';
77
import { useAlert } from '@suite-native/alerts';
8-
import { DeviceAuthenticityCheckResult, EventType, analytics } from '@suite-native/analytics';
98
import { Button, IconListTextItem, Text, VStack } from '@suite-native/atoms';
10-
import { requestPrioritizedDeviceAccess } from '@suite-native/device-mutex';
119
import { Translation } from '@suite-native/intl';
1210
import {
1311
DeviceAuthenticityStackParamList,
@@ -17,7 +15,6 @@ import {
1715
StackToStackCompositeNavigationProps,
1816
} from '@suite-native/navigation';
1917
import { SettingsCardWithIconLayout } from '@suite-native/settings';
20-
import TrezorConnect from '@trezor/connect';
2118

2219
type NavigationProp = StackToStackCompositeNavigationProps<
2320
DeviceAuthenticityStackParamList,
@@ -31,56 +28,9 @@ export const DeviceAuthenticityCard = () => {
3128

3229
const { showAlert } = useAlert();
3330

34-
const device = useSelector(selectSelectedDevice);
35-
36-
const reportCheckResult = useCallback(
37-
(result: DeviceAuthenticityCheckResult) =>
38-
analytics.report({
39-
type: EventType.DeviceSettingsAuthenticityCheck,
40-
payload: { result },
41-
}),
42-
[],
43-
);
44-
45-
const checkAuthenticity = useCallback(async () => {
31+
const navigateToDeviceAuthenticityStack = useCallback(() => {
4632
navigation.navigate(DeviceStackRoutes.DeviceAuthenticity);
47-
48-
const result = await requestPrioritizedDeviceAccess({
49-
deviceCallback: () =>
50-
TrezorConnect.authenticateDevice({
51-
device: {
52-
path: device?.path,
53-
},
54-
}),
55-
});
56-
if (!result.success) {
57-
return;
58-
}
59-
60-
const { success, payload } = result.payload;
61-
if (success) {
62-
const checkResult = payload.valid ? 'successful' : 'compromised';
63-
const configExpired = payload.error === 'CA_PUBKEY_NOT_FOUND' && payload.configExpired;
64-
navigation.navigate(DeviceAuthenticityStackRoutes.AuthenticitySummary, {
65-
checkResult: configExpired ? 'successful' : checkResult,
66-
});
67-
reportCheckResult(configExpired ? 'configExpired' : checkResult);
68-
} else {
69-
const errorCode = payload.code;
70-
if (errorCode === 'Failure_ActionCancelled' || errorCode === 'Failure_PinCancelled') {
71-
navigation.goBack();
72-
reportCheckResult('cancelled');
73-
} else if (errorCode === 'Method_Interrupted' || errorCode === undefined) {
74-
// navigation.goBack() already called via the X button (or the device was disconnected)
75-
reportCheckResult('cancelled');
76-
} else {
77-
navigation.navigate(DeviceAuthenticityStackRoutes.AuthenticitySummary, {
78-
checkResult: 'compromised',
79-
});
80-
reportCheckResult('failed');
81-
}
82-
}
83-
}, [device, navigation, reportCheckResult]);
33+
}, [navigation]);
8434

8535
const showInfoAlert = useCallback(() => {
8636
showAlert({
@@ -102,9 +52,9 @@ export const DeviceAuthenticityCard = () => {
10252
primaryButtonTitle: (
10353
<Translation id="moduleDeviceSettings.authenticity.info.letsDoItButton" />
10454
),
105-
onPressPrimaryButton: checkAuthenticity,
55+
onPressPrimaryButton: navigateToDeviceAuthenticityStack,
10656
});
107-
}, [showAlert, checkAuthenticity]);
57+
}, [showAlert, navigateToDeviceAuthenticityStack]);
10858

10959
return (
11060
<SettingsCardWithIconLayout

suite-native/module-device-settings/src/components/DeviceInteractionScreenWrapper.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useNavigation } from '@react-navigation/native';
55

66
import { selectSelectedDevice } from '@suite-common/wallet-core';
77
import { Screen, ScreenHeader } from '@suite-native/navigation';
8+
import TrezorConnect from '@trezor/connect';
89

910
type DeviceInteractionScreenWrapperProps = {
1011
children: ReactNode;
@@ -18,6 +19,7 @@ export const DeviceInteractionScreenWrapper = ({
1819
const device = useSelector(selectSelectedDevice);
1920

2021
const closeAction = useCallback(() => {
22+
TrezorConnect.cancel();
2123
navigation.goBack();
2224
}, [navigation]);
2325

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { useCallback, useEffect } from 'react';
2+
import { useSelector } from 'react-redux';
3+
4+
import { useNavigation } from '@react-navigation/native';
5+
6+
import { selectIsDeviceConnected, selectSelectedDevice } from '@suite-common/wallet-core';
7+
import { DeviceAuthenticityCheckResult, EventType, analytics } from '@suite-native/analytics';
8+
import { requestPrioritizedDeviceAccess } from '@suite-native/device-mutex';
9+
import {
10+
DeviceAuthenticityStackParamList,
11+
DeviceAuthenticityStackRoutes,
12+
DeviceSettingsStackParamList,
13+
DeviceStackRoutes,
14+
StackToStackCompositeNavigationProps,
15+
} from '@suite-native/navigation';
16+
import TrezorConnect from '@trezor/connect';
17+
18+
type NavigationProp = StackToStackCompositeNavigationProps<
19+
DeviceAuthenticityStackParamList,
20+
DeviceAuthenticityStackRoutes,
21+
DeviceSettingsStackParamList
22+
>;
23+
export const useDeviceAuthenticityAction = () => {
24+
const navigation = useNavigation<NavigationProp>();
25+
const isDeviceConnected = useSelector(selectIsDeviceConnected);
26+
27+
const device = useSelector(selectSelectedDevice);
28+
const reportCheckResult = useCallback(
29+
(result: DeviceAuthenticityCheckResult) =>
30+
analytics.report({
31+
type: EventType.DeviceSettingsAuthenticityCheck,
32+
payload: { result },
33+
}),
34+
[],
35+
);
36+
const checkAuthenticity = useCallback(async () => {
37+
navigation.navigate(DeviceStackRoutes.DeviceAuthenticity);
38+
39+
const result = await requestPrioritizedDeviceAccess({
40+
deviceCallback: () =>
41+
TrezorConnect.authenticateDevice({
42+
device: {
43+
path: device?.path,
44+
},
45+
}),
46+
});
47+
if (!result.success) {
48+
return;
49+
}
50+
51+
const { success, payload } = result.payload;
52+
if (success) {
53+
const checkResult = payload.valid ? 'successful' : 'compromised';
54+
const configExpired = payload.error === 'CA_PUBKEY_NOT_FOUND' && payload.configExpired;
55+
navigation.navigate(DeviceAuthenticityStackRoutes.AuthenticitySummary, {
56+
checkResult: configExpired ? 'successful' : checkResult,
57+
});
58+
reportCheckResult(configExpired ? 'configExpired' : checkResult);
59+
} else {
60+
const errorCode = payload.code;
61+
if (errorCode === 'Failure_ActionCancelled' || errorCode === 'Failure_PinCancelled') {
62+
navigation.goBack();
63+
reportCheckResult('cancelled');
64+
} else if (errorCode === 'Method_Interrupted' || errorCode === undefined) {
65+
// navigation.goBack() already called via the X button (or the device was disconnected)
66+
reportCheckResult('cancelled');
67+
} else {
68+
navigation.navigate(DeviceAuthenticityStackRoutes.AuthenticitySummary, {
69+
checkResult: 'compromised',
70+
});
71+
reportCheckResult('failed');
72+
}
73+
}
74+
}, [device, navigation, reportCheckResult]);
75+
76+
useEffect(() => {
77+
if (isDeviceConnected) void checkAuthenticity();
78+
79+
// eslint-disable-next-line react-hooks/exhaustive-deps
80+
}, [isDeviceConnected]);
81+
};

suite-native/module-device-settings/src/hooks/useDeviceChangedCheck.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
SettingsStackParamList,
1414
StackToStackCompositeNavigationProps,
1515
} from '@suite-native/navigation';
16+
import TrezorConnect from '@trezor/connect';
1617

1718
type NavigationProps = StackToStackCompositeNavigationProps<
1819
SettingsStackParamList,
@@ -35,6 +36,7 @@ export const useDeviceChangedCheck = () => {
3536

3637
// Check for device mismatch only after initial device ID is set
3738
if (initialDeviceIdRef.current && device?.id && initialDeviceIdRef.current !== device.id) {
39+
TrezorConnect.cancel();
3840
navigation.navigate(RootStackRoutes.AppTabs, {
3941
screen: AppTabsRoutes.HomeStack,
4042
params: {

suite-native/module-device-settings/src/hooks/usePinAction.tsx

-7
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,4 @@ export const usePinAction = () => {
134134

135135
// eslint-disable-next-line react-hooks/exhaustive-deps
136136
}, [isDeviceConnected]);
137-
138-
useEffect(
139-
() => () => {
140-
TrezorConnect.cancel();
141-
},
142-
[],
143-
);
144137
};

suite-native/module-device-settings/src/navigation/DeviceAuthenticityStackNavigator.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import {
66
stackNavigationOptionsConfig,
77
} from '@suite-native/navigation';
88

9+
import { useDeviceAuthenticityAction } from '../hooks/useDeviceAuthenticityAction';
910
import { useDeviceConnectionGuard } from '../hooks/useDeviceConnectionGuard';
1011
import { ContinueOnTrezorScreen } from '../screens/ContinueOnTrezorScreen';
1112
import { DeviceAuthenticitySummaryScreen } from '../screens/DeviceAuthenticitySummaryScreen';
1213

1314
const DeviceAuthenticityStack = createNativeStackNavigator<DeviceAuthenticityStackParamList>();
1415

1516
export const DeviceAuthenticityStackNavigator = () => {
17+
useDeviceAuthenticityAction();
1618
const { isDeviceConnected } = useDeviceConnectionGuard();
1719

1820
if (!isDeviceConnected) return;

0 commit comments

Comments
 (0)