remove device instances with different "passphrase_protection" settings

while DEVICE.CONNECT event
pull/2/merge
Szymon Lesisz 6 years ago
parent 1e89993727
commit 46c1f8b2b7

@ -3,8 +3,10 @@
import { LOCATION_CHANGE } from 'react-router-redux';
import * as WALLET from './constants/wallet';
import * as CONNECT from './constants/TrezorConnect';
import * as stateUtils from '../reducers/utils';
import type { Device } from 'trezor-connect';
import type
{
Account,
@ -12,7 +14,6 @@ import type
Discovery,
Token,
Web3Instance,
TrezorDevice,
RouterLocationState,
ThunkAction,
@ -41,6 +42,9 @@ export type WalletAction = {
} | {
type: typeof WALLET.UPDATE_SELECTED_DEVICE,
device: TrezorDevice
} | {
type: typeof WALLET.CLEAR_UNAVAILABLE_DEVICE_DATA,
devices: Array<TrezorDevice>
}
export const init = (): ThunkAction => {
@ -70,6 +74,32 @@ export const toggleDeviceDropdown = (opened: boolean): WalletAction => {
}
}
// This method will be called after each DEVICE.CONNECT action
// if connected device has different "passphrase_protection" settings than saved instances
// all saved instances will be removed immediately inside DevicesReducer
// This method will clear leftovers associated with removed instances from reducers.
// (DiscoveryReducer, AccountReducer, TokensReducer)
export const clearUnavailableDevicesData = (prevState: State, device: Device): ThunkAction => {
return (dispatch: Dispatch, getState: GetState): void => {
if (!device.features) return;
const affectedDevices = prevState.devices.filter(d =>
d.features
&& d.features.device_id === device.features.device_id
&& d.features.passphrase_protection !== device.features.passphrase_protection
);
if (affectedDevices.length > 0) {
dispatch({
type: WALLET.CLEAR_UNAVAILABLE_DEVICE_DATA,
devices: affectedDevices,
})
}
}
}
export const updateSelectedValues = (prevState: State, action: Action): AsyncAction => {
return async (dispatch: Dispatch, getState: GetState): Promise<void> => {

@ -7,4 +7,6 @@ export const SET_INITIAL_URL: 'wallet__set_initial_url' = 'wallet__set_initial_u
export const ONLINE_STATUS: 'wallet__online_status' = 'wallet__online_status';
export const SET_SELECTED_DEVICE: 'wallet__set_selected_device' = 'wallet__set_selected_device';
export const UPDATE_SELECTED_DEVICE: 'wallet__update_selected_device' = 'wallet__update_selected_device';
export const UPDATE_SELECTED_DEVICE: 'wallet__update_selected_device' = 'wallet__update_selected_device';
export const CLEAR_UNAVAILABLE_DEVICE_DATA: 'wallet__clear_unavailable_device_data' = 'wallet__clear_unavailable_device_data';

@ -2,6 +2,7 @@
'use strict';
import * as CONNECT from '../actions/constants/TrezorConnect';
import * as WALLET from '../actions/constants/wallet';
import * as ACCOUNT from '../actions/constants/account';
import type { Action, TrezorDevice } from '~/flowtype';
@ -71,6 +72,14 @@ const removeAccounts = (state: State, device: TrezorDevice): State => {
return state.filter(account => account.deviceState !== device.state);
}
const clear = (state: State, devices: Array<TrezorDevice>): State => {
let newState: State = [ ...state ];
devices.forEach(d => {
newState = removeAccounts(newState, d);
});
return newState;
}
const setBalance = (state: State, action: AccountSetBalanceAction): State => {
const index: number = state.findIndex(account => account.address === action.address && account.network === action.network && account.deviceState === action.deviceState);
const newState: State = [ ...state ];
@ -98,6 +107,9 @@ export default (state: State = initialState, action: Action): State => {
case CONNECT.FORGET_SINGLE :
return removeAccounts(state, action.device);
case WALLET.CLEAR_UNAVAILABLE_DEVICE_DATA :
return clear(state, action.devices);
//case CONNECT.FORGET_SINGLE :
// return forgetAccounts(state, action);

@ -89,28 +89,35 @@ const addDevice = (state: State, device: Device): State => {
if (affectedDevices.length > 0 ) {
// check if freshly added device has different "passphrase_protection" settings
let hasDifferentPassphraseSettings: boolean = false;
let hasInstancesWithPassphraseSettings: boolean = false;
const changedDevices: Array<TrezorDevice> = affectedDevices.map(d => {
if (d.features && d.features.passphrase_protection === device.features.passphrase_protection) {
hasInstancesWithPassphraseSettings = true;
return mergeDevices(d, { ...device, connected: true, available: true } );
} else {
hasDifferentPassphraseSettings = true;
d.connected = true;
d.available = false;
return d;
}
});
// let hasDifferentPassphraseSettings: boolean = false;
// let hasInstancesWithPassphraseSettings: boolean = false;
// const changedDevices: Array<TrezorDevice> = affectedDevices.map(d => {
// if (d.features && d.features.passphrase_protection === device.features.passphrase_protection) {
// hasInstancesWithPassphraseSettings = true;
// return mergeDevices(d, { ...device, connected: true, available: true } );
// } else {
// hasDifferentPassphraseSettings = true;
// d.connected = true;
// d.available = false;
// return d;
// }
// });
// edge case: freshly connected device has different "passphrase_protection" than saved instances
// need to automatically create another instance with default instance name
if (hasDifferentPassphraseSettings && !hasInstancesWithPassphraseSettings) {
const instance = getNewInstance(affectedDevices, device);
// if (hasDifferentPassphraseSettings && !hasInstancesWithPassphraseSettings) {
// const instance = getNewInstance(affectedDevices, device);
// newDevice.instance = instance;
// newDevice.instanceLabel = `${device.label} (${instance})`;
newDevice.instance = instance;
newDevice.instanceLabel = `${device.label} (${instance})`;
// changedDevices.push(newDevice);
// }
const changedDevices: Array<TrezorDevice> = affectedDevices.filter(d => d.features && d.features.passphrase_protection === device.features.passphrase_protection).map(d => {
return mergeDevices(d, { ...device, connected: true, available: true } );
});
if (changedDevices.length !== affectedDevices.length) {
changedDevices.push(newDevice);
}

@ -6,6 +6,7 @@ import HDKey from 'hdkey';
import * as DISCOVERY from '../actions/constants/discovery';
import * as ACCOUNT from '../actions/constants/account';
import * as CONNECT from '../actions/constants/TrezorConnect';
import * as WALLET from '../actions/constants/wallet';
import type { Action, TrezorDevice } from '~/flowtype';
import type {
@ -87,6 +88,14 @@ const forgetDiscovery = (state: State, device: TrezorDevice): State => {
return state.filter(d => d.deviceState !== device.state);
}
const clear = (state: State, devices: Array<TrezorDevice>): State => {
let newState: State = [ ...state ];
devices.forEach(d => {
newState = forgetDiscovery(newState, d);
});
return newState;
}
const stop = (state: State, action: DiscoveryStopAction): State => {
const newState: State = [ ...state ];
return newState.map( (d: Discovery) => {
@ -184,6 +193,8 @@ export default function discovery(state: State = initialState, action: Action):
case CONNECT.FORGET :
case CONNECT.FORGET_SINGLE :
return forgetDiscovery(state, action.device);
case WALLET.CLEAR_UNAVAILABLE_DEVICE_DATA :
return clear(state, action.devices);
default:
return state;

@ -2,6 +2,7 @@
'use strict';
import * as CONNECT from '../actions/constants/TrezorConnect';
import * as WALLET from '../actions/constants/wallet';
import * as TOKEN from '../actions/constants/token';
import type { Action, TrezorDevice } from '~/flowtype';
@ -43,7 +44,7 @@ export const findAccountTokens = (state: Array<Token>, account: Account): Array<
// }
const create = (state: State, token: Token): State => {
const newState: Array<Token> = [ ...state ];
const newState: State = [ ...state ];
newState.push(token);
return newState;
}
@ -52,6 +53,14 @@ const forget = (state: State, device: TrezorDevice): State => {
return state.filter(t => t.deviceState !== device.state);
}
const clear = (state: State, devices: Array<TrezorDevice>): State => {
let newState: State = [ ...state ];
devices.forEach(d => {
newState = forget(newState, d);
});
return newState;
}
const remove = (state: State, token: Token): State => {
return state.filter(t => {
return !(t.ethAddress === token.ethAddress && t.address === token.address && t.deviceState === token.deviceState);
@ -76,6 +85,9 @@ export default (state: State = initialState, action: Action): State => {
case CONNECT.FORGET_SINGLE :
return forget(state, action.device);
case WALLET.CLEAR_UNAVAILABLE_DEVICE_DATA :
return clear(state, action.devices);
default:
return state;
}

@ -1,6 +1,7 @@
/* @flow */
'use strict';
import { DEVICE } from 'trezor-connect';
import { LOCATION_CHANGE } from 'react-router-redux';
import * as WALLET from '../actions/constants/wallet';
import * as SEND from '../actions/constants/wallet';
@ -42,6 +43,10 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa
// pass action
next(action);
if (action.type === DEVICE.CONNECT) {
api.dispatch( WalletActions.clearUnavailableDevicesData(prevState, action.device) );
}
// update common values in WallerReducer
api.dispatch( WalletActions.updateSelectedValues(prevState, action) );

Loading…
Cancel
Save