Skip to content

Commit

Permalink
refactor(suite): authorize device thunk (#12438)
Browse files Browse the repository at this point in the history
* refactor(suite): authorize device thunk

* feat(suite-native): duplicit passphrase handling

* fix(suite-native): avoid type casting in thunks

* refactor(suite): remove redundant comment
  • Loading branch information
juriczech authored May 22, 2024
1 parent f181c98 commit 05304da
Show file tree
Hide file tree
Showing 48 changed files with 419 additions and 172 deletions.
28 changes: 14 additions & 14 deletions packages/suite/src/actions/suite/__fixtures__/suiteActions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { testMocks } from '@suite-common/test-utils';
import { discoveryActions, deviceActions } from '@suite-common/wallet-core';
import { discoveryActions, deviceActions, authorizeDeviceThunk } from '@suite-common/wallet-core';
import { DEVICE, TRANSPORT } from '@trezor/connect';
import { notificationsActions } from '@suite-common/toast-notifications';

import { SUITE, MODAL } from 'src/actions/suite/constants';
import { SUITE } from 'src/actions/suite/constants';
import { TorStatus } from 'src/types/suite';

import * as suiteActions from '../suiteActions';
Expand Down Expand Up @@ -764,18 +764,18 @@ const acquireDevice = [
},
];

const authorizeDevice = [
const authorizeDeviceActions = [
{
description: `without device`,
state: {},
result: undefined,
result: authorizeDeviceThunk.rejected.type,
},
{
description: `with disconnected device`,
state: {
selectedDevice: getSuiteDevice(),
},
result: undefined,
result: authorizeDeviceThunk.rejected.type,
},
{
description: `with unacquired device`,
Expand All @@ -785,7 +785,7 @@ const authorizeDevice = [
connected: true,
}),
},
result: undefined,
result: authorizeDeviceThunk.rejected.type,
},
{
description: `with device which already has state`,
Expand All @@ -795,7 +795,7 @@ const authorizeDevice = [
state: '012345',
}),
},
result: undefined,
result: authorizeDeviceThunk.rejected.type,
},
{
description: `with device in unexpected mode`,
Expand All @@ -805,7 +805,7 @@ const authorizeDevice = [
mode: 'bootloader',
}),
},
result: undefined,
result: authorizeDeviceThunk.rejected.type,
},
{
description: `with device which needs FW update`,
Expand All @@ -815,7 +815,7 @@ const authorizeDevice = [
firmware: 'required',
}),
},
result: undefined,
result: authorizeDeviceThunk.rejected.type,
},
{
description: `success`,
Expand All @@ -824,7 +824,7 @@ const authorizeDevice = [
connected: true,
}),
},
result: deviceActions.authDevice.type,
result: authorizeDeviceThunk.fulfilled.type,
},
{
description: `duplicate detected`,
Expand All @@ -849,7 +849,7 @@ const authorizeDevice = [
state: undefined,
}),
],
result: MODAL.OPEN_USER_CONTEXT,
result: authorizeDeviceThunk.rejected.type,
deviceReducerResult: [
getSuiteDevice({
connected: true,
Expand Down Expand Up @@ -891,7 +891,7 @@ const authorizeDevice = [
state: undefined,
}),
],
result: MODAL.OPEN_USER_CONTEXT,
result: authorizeDeviceThunk.rejected.type,
deviceReducerResult: [
getSuiteDevice({
connected: true,
Expand Down Expand Up @@ -920,7 +920,7 @@ const authorizeDevice = [
error: 'getDeviceState error',
},
},
result: notificationsActions.addToast.type,
result: authorizeDeviceThunk.rejected.type,
},
];

Expand Down Expand Up @@ -1085,7 +1085,7 @@ export default {
forgetDisconnectedDevices,
observeSelectedDevice,
acquireDevice,
authorizeDevice,
authorizeDeviceActions,
authConfirm,
createDeviceInstance,
switchDuplicatedDevice,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
deviceActions,
acquireDevice,
authConfirm,
authorizeDevice,
authorizeDeviceThunk,
createDeviceInstance,
forgetDisconnectedDevices,
handleDeviceConnect,
Expand Down Expand Up @@ -237,19 +237,19 @@ describe('Suite Actions', () => {
});
});

fixtures.authorizeDevice.forEach(f => {
fixtures.authorizeDeviceActions.forEach(f => {
it(`authorizeDevice: ${f.description}`, async () => {
setTrezorConnectFixtures(f.getDeviceState);
const state = getInitialState(undefined, {
selectedDevice: f.suiteState?.selectedDevice,
devices: f.devicesState ?? [],
});
const store = initStore(state);
await store.dispatch(authorizeDevice());
await store.dispatch(authorizeDeviceThunk());
if (!f.result) {
expect(filterThunkActionTypes(store.getActions()).length).toEqual(0);
} else {
const action = filterThunkActionTypes(store.getActions()).pop();
const action = store.getActions().pop();
expect(action?.type).toEqual(f.result);
if (f.deviceReducerResult) {
const devices = selectDevices(store.getState());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { authorizeDevice, switchDuplicatedDevice } from '@suite-common/wallet-core';
import { Button, Column, H3, Text } from '@trezor/components';

import { authorizeDeviceThunk, switchDuplicatedDevice } from '@suite-common/wallet-core';

import { Translation } from 'src/components/suite';
import { useDevice, useDispatch } from 'src/hooks/suite';
import { TrezorDevice } from 'src/types/suite';
Expand All @@ -18,7 +19,7 @@ export const PassphraseDuplicateModal = ({ device, duplicate }: PassphraseDuplic
const isDeviceLocked = isLocked();

const handleSwitchDevice = () => dispatch(switchDuplicatedDevice({ device, duplicate }));
const handleAuthorizeDevice = () => dispatch(authorizeDevice());
const handleAuthorizeDevice = () => dispatch(authorizeDeviceThunk());

return (
<SwitchDeviceRenderer isCancelable={false} data-test="@passphrase-duplicate">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { ComponentType } from 'react';

import type { NotificationEntry } from '@suite-common/toast-notifications';
import { deviceActions } from '@suite-common/wallet-core';
import { AUTH_DEVICE, type NotificationEntry } from '@suite-common/toast-notifications';
import { DEVICE } from '@trezor/connect';

import { NotificationViewProps } from 'src/components/suite';
Expand Down Expand Up @@ -218,7 +217,7 @@ export const NotificationRenderer = ({
case 'coinjoin-interrupted':
return error(render, notification, 'TR_COINJOIN_INTERRUPTED_ERROR');
// Events:
case deviceActions.authDevice.type:
case AUTH_DEVICE:
return info(render, notification, 'EVENT_WALLET_CREATED');
case DEVICE.CONNECT:
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { authorizeDevice } from '@suite-common/wallet-core';
import { authorizeDeviceThunk } from '@suite-common/wallet-core';

import { useDevice, useDispatch } from 'src/hooks/suite';
import { Translation } from 'src/components/suite';
Expand All @@ -8,7 +8,7 @@ export const AuthFailed = () => {
const dispatch = useDispatch();
const { isLocked } = useDevice();

const handleClick = () => dispatch(authorizeDevice());
const handleClick = () => dispatch(authorizeDeviceThunk());

return (
<AccountExceptionLayout
Expand Down
4 changes: 2 additions & 2 deletions packages/suite/src/middlewares/suite/analyticsMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
discoveryActions,
selectDevices,
selectDevicesCount,
deviceActions,
authorizeDeviceThunk,
} from '@suite-common/wallet-core';
import { analytics, EventType } from '@trezor/suite-analytics';
import { TRANSPORT, DEVICE } from '@trezor/connect';
Expand Down Expand Up @@ -49,7 +49,7 @@ const analyticsMiddleware =

const state = api.getState();

if (deviceActions.authDevice.match(action)) {
if (authorizeDeviceThunk.fulfilled.match(action)) {
analytics.report({
type: EventType.SelectWalletType,
payload: { type: action.payload.device.walletNumber ? 'hidden' : 'standard' },
Expand Down
11 changes: 8 additions & 3 deletions packages/suite/src/middlewares/suite/eventsMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import {
selectDevice,
accountsActions,
deviceActions,
authorizeDeviceThunk,
} from '@suite-common/wallet-core';
import * as deviceUtils from '@suite-common/suite-utils';
import { DEVICE } from '@trezor/connect';
import { notificationsActions, removeAccountEventsThunk } from '@suite-common/toast-notifications';
import {
AUTH_DEVICE,
notificationsActions,
removeAccountEventsThunk,
} from '@suite-common/toast-notifications';

import { SUITE } from 'src/actions/suite/constants';
import { AppState, Action, Dispatch } from 'src/types/suite';
Expand Down Expand Up @@ -103,8 +108,8 @@ const eventsMiddleware =
});
}

if (deviceActions.authDevice.match(action)) {
api.dispatch(notificationsActions.addEvent({ type: action.type, seen: true }));
if (authorizeDeviceThunk.fulfilled.match(action)) {
api.dispatch(notificationsActions.addEvent({ type: AUTH_DEVICE, seen: true }));
}

return action;
Expand Down
17 changes: 14 additions & 3 deletions packages/suite/src/middlewares/suite/logsMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { MiddlewareAPI } from 'redux';

import { deviceActions, discoveryActions } from '@suite-common/wallet-core';
import { authorizeDeviceThunk, deviceActions, discoveryActions } from '@suite-common/wallet-core';
import { addLog } from '@suite-common/logger';
import { TRANSPORT, DEVICE } from '@trezor/connect';
import { redactUserPathFromString } from '@trezor/utils';
Expand Down Expand Up @@ -48,6 +47,19 @@ const log =
}
}

if (authorizeDeviceThunk.fulfilled.match(action)) {
api.dispatch(
addLog({
type: 'authorizeDeviceThunk.fulfilled',
payload: {
device: action.payload.device,
firmwareRelease: undefined,
unavailableCapabilities: undefined,
},
}),
);
}

switch (action.type) {
case SUITE.SET_LANGUAGE:
case SUITE.SET_THEME:
Expand Down Expand Up @@ -88,7 +100,6 @@ const log =
}),
);
break;
case deviceActions.authDevice.type:
case DEVICE.CONNECT:
case DEVICE.DISCONNECT:
case discoveryActions.completeDiscovery.type:
Expand Down
3 changes: 2 additions & 1 deletion packages/suite/src/middlewares/suite/sentryMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
blockchainActions,
selectDevice,
deviceActions,
authorizeDeviceThunk,
} from '@suite-common/wallet-core';
import {
getBootloaderVersion,
Expand Down Expand Up @@ -55,7 +56,7 @@ const breadcrumbActions = [
DESKTOP_UPDATE.NOT_AVAILABLE,
DESKTOP_UPDATE.READY,
MODAL.CLOSE,
deviceActions.authDevice.type,
authorizeDeviceThunk.fulfilled.type,
DEVICE.CONNECT,
DEVICE.DISCONNECT,
accountsActions.createAccount.type,
Expand Down
5 changes: 3 additions & 2 deletions packages/suite/src/middlewares/suite/suiteMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AnyAction, isAnyOf } from '@reduxjs/toolkit';

import {
authConfirm,
authorizeDeviceThunk,
deviceActions,
forgetDisconnectedDevices,
handleDeviceConnect,
Expand All @@ -21,8 +22,8 @@ import { appChanged, setFlag } from 'src/actions/suite/suiteActions';
const isActionDeviceRelated = (action: AnyAction): boolean => {
if (
isAnyOf(
deviceActions.authDevice,
deviceActions.authFailed,
authorizeDeviceThunk.fulfilled,
authorizeDeviceThunk.rejected,
deviceActions.selectDevice,
deviceActions.receiveAuthConfirm,
deviceActions.updatePassphraseMode,
Expand Down
8 changes: 4 additions & 4 deletions packages/suite/src/middlewares/wallet/discoveryMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
authorizeDevice,
authorizeDeviceThunk,
deviceActions,
selectDevice,
selectDeviceDiscovery,
Expand Down Expand Up @@ -106,11 +106,11 @@ export const prepareDiscoveryMiddleware = createMiddlewareWithExtraDeps(

// 3. begin auth process
if (authorizationIntent) {
dispatch(authorizeDevice());
dispatch(authorizeDeviceThunk());
}

// 4. device state received
if (deviceActions.authDevice.match(action)) {
if (authorizeDeviceThunk.fulfilled.match(action)) {
// `device` is always present here
// to avoid typescript conditioning use device from action as a fallback (never used)
dispatch(
Expand Down Expand Up @@ -138,7 +138,7 @@ export const prepareDiscoveryMiddleware = createMiddlewareWithExtraDeps(
becomesConnected ||
action.type === SUITE.APP_CHANGED ||
deviceActions.selectDevice.match(action) ||
deviceActions.authDevice.match(action) ||
authorizeDeviceThunk.fulfilled.match(action) ||
walletSettingsActions.changeNetworks.match(action) ||
accountsActions.changeAccountVisibility.match(action)
) {
Expand Down
12 changes: 6 additions & 6 deletions packages/suite/src/reducers/suite/__fixtures__/deviceReducer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { testMocks } from '@suite-common/test-utils';
import { deviceActions } from '@suite-common/wallet-core';
import { authorizeDeviceThunk, deviceActions } from '@suite-common/wallet-core';
import { DEVICE } from '@trezor/connect';

const { getConnectDevice, getSuiteDevice } = testMocks;
Expand Down Expand Up @@ -850,7 +850,7 @@ const authDevice = [
initialState: { devices: [SUITE_DEVICE] },
actions: [
{
type: deviceActions.authDevice.type,
type: authorizeDeviceThunk.fulfilled.type,
payload: {
device: SUITE_DEVICE,
state: 'A',
Expand All @@ -875,7 +875,7 @@ const authDevice = [
},
actions: [
{
type: deviceActions.authDevice.type,
type: authorizeDeviceThunk.fulfilled.type,
payload: {
device: SUITE_DEVICE,
state: 'A',
Expand Down Expand Up @@ -904,7 +904,7 @@ const authDevice = [
},
actions: [
{
type: deviceActions.authDevice.type,
type: authorizeDeviceThunk.fulfilled.type,
payload: {
device: getSuiteDevice({ instance: 1 }),
state: 'A',
Expand Down Expand Up @@ -933,7 +933,7 @@ const authDevice = [
initialState: { devices: [SUITE_DEVICE] },
actions: [
{
type: deviceActions.authDevice.type,
type: authorizeDeviceThunk.fulfilled.type,
payload: {
device: getConnectDevice({
type: 'unacquired',
Expand All @@ -953,7 +953,7 @@ const authDevice = [
initialState: { devices: [] },
actions: [
{
type: deviceActions.authDevice.type,
type: authorizeDeviceThunk.fulfilled.type,
payload: {
device: SUITE_DEVICE,
state: 'A',
Expand Down
Loading

0 comments on commit 05304da

Please sign in to comment.