mirror of
https://github.com/trezor/trezor-wallet
synced 2025-03-28 14:05:44 +00:00
fix: setInitialUrl - race condition
- Do not set initialUrl if it is landingPage - Block "RouterAction.selectDevice" if currently selected device is in auth process - Move WalletActions.observe() before DiscoveryActions.restore() in "WalletSerivce"
This commit is contained in:
parent
241e59dc98
commit
585c79a738
@ -430,29 +430,42 @@ export const setInitialUrl = (): PayloadAction<boolean> => (
|
|||||||
getState: GetState
|
getState: GetState
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const { initialPathname } = getState().wallet;
|
const { initialPathname } = getState().wallet;
|
||||||
if (typeof initialPathname === 'string' && !dispatch(isLandingPageUrl(initialPathname, true))) {
|
if (typeof initialPathname !== 'string') return false;
|
||||||
const valid = dispatch(
|
|
||||||
getValidUrl({
|
|
||||||
type: LOCATION_CHANGE,
|
|
||||||
payload: {
|
|
||||||
location: {
|
|
||||||
pathname: initialPathname,
|
|
||||||
hash: '',
|
|
||||||
search: '',
|
|
||||||
state: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
if (valid === initialPathname) {
|
// DEVICE.CONNECT race condition, "selectDevice" method was called but currently selectedDevice is in getState (auth) process
|
||||||
// reset initial url
|
// if so, consume this action (return true) to break "selectDevice" process
|
||||||
dispatch({
|
// "setInitialUrl" will be called again after AUTH_DEVICE action
|
||||||
type: SET_INITIAL_URL,
|
const { selectedDevice } = getState().wallet;
|
||||||
});
|
if (
|
||||||
dispatch(goto(valid));
|
selectedDevice &&
|
||||||
return true;
|
selectedDevice.type === 'acquired' &&
|
||||||
}
|
!selectedDevice.features.passphrase_protection &&
|
||||||
|
!selectedDevice.state
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const valid = dispatch(
|
||||||
|
getValidUrl({
|
||||||
|
type: LOCATION_CHANGE,
|
||||||
|
payload: {
|
||||||
|
location: {
|
||||||
|
pathname: initialPathname,
|
||||||
|
hash: '',
|
||||||
|
search: '',
|
||||||
|
state: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (valid === initialPathname) {
|
||||||
|
// reset initial url
|
||||||
|
dispatch({
|
||||||
|
type: SET_INITIAL_URL,
|
||||||
|
});
|
||||||
|
dispatch(goto(valid));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -29,11 +29,16 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa
|
|||||||
api.dispatch(WalletActions.init());
|
api.dispatch(WalletActions.init());
|
||||||
// set initial url
|
// set initial url
|
||||||
// TODO: validate if initial url is potentially correct
|
// TODO: validate if initial url is potentially correct
|
||||||
api.dispatch({
|
// exclude landing page url
|
||||||
type: WALLET.SET_INITIAL_URL,
|
const { pathname } = action.payload.location;
|
||||||
pathname: action.payload.location.pathname,
|
const isValidPath = !api.dispatch(RouterActions.isLandingPageUrl(pathname, true));
|
||||||
state: {},
|
if (isValidPath) {
|
||||||
});
|
api.dispatch({
|
||||||
|
type: WALLET.SET_INITIAL_URL,
|
||||||
|
pathname: action.payload.location.pathname,
|
||||||
|
state: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
// pass action and break process
|
// pass action and break process
|
||||||
return next(action);
|
return next(action);
|
||||||
}
|
}
|
||||||
@ -63,6 +68,29 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa
|
|||||||
// update common values ONLY if application is ready
|
// update common values ONLY if application is ready
|
||||||
if (!api.getState().wallet.ready) return action;
|
if (!api.getState().wallet.ready) return action;
|
||||||
|
|
||||||
|
// observe common values in WallerReducer
|
||||||
|
if (!(await api.dispatch(WalletActions.observe(prevState, action)))) {
|
||||||
|
// if "selectedDevice" didn't change observe common values in SelectedAccountReducer
|
||||||
|
if (!(await api.dispatch(SelectedAccountActions.observe(prevState, action)))) {
|
||||||
|
// if "selectedAccount" didn't change observe send form props changes
|
||||||
|
api.dispatch(SendFormActions.observe(prevState, action));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no changes in common values
|
||||||
|
if (action.type === CONNECT.RECEIVE_WALLET_TYPE) {
|
||||||
|
if (action.device.state) {
|
||||||
|
// redirect to root view (Dashboard) if device was authenticated before
|
||||||
|
api.dispatch(RouterActions.selectFirstAvailableDevice(true));
|
||||||
|
}
|
||||||
|
api.dispatch(TrezorConnectActions.authorizeDevice());
|
||||||
|
}
|
||||||
|
if (action.type === CONNECT.AUTH_DEVICE) {
|
||||||
|
// selected device did changed
|
||||||
|
// try to restore discovery after device authentication
|
||||||
|
api.dispatch(DiscoveryActions.restore());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// double verification needed
|
// double verification needed
|
||||||
// Corner case: LOCATION_CHANGE was called but pathname didn't changed (redirection from RouterService)
|
// Corner case: LOCATION_CHANGE was called but pathname didn't changed (redirection from RouterService)
|
||||||
const prevLocation = prevState.router.location;
|
const prevLocation = prevState.router.location;
|
||||||
@ -96,29 +124,6 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa
|
|||||||
api.dispatch(NotificationActions.clear(prevLocation.state, currentLocation.state));
|
api.dispatch(NotificationActions.clear(prevLocation.state, currentLocation.state));
|
||||||
}
|
}
|
||||||
|
|
||||||
// observe common values in WallerReducer
|
|
||||||
if (!(await api.dispatch(WalletActions.observe(prevState, action)))) {
|
|
||||||
// if "selectedDevice" didn't change observe common values in SelectedAccountReducer
|
|
||||||
if (!(await api.dispatch(SelectedAccountActions.observe(prevState, action)))) {
|
|
||||||
// if "selectedAccount" didn't change observe send form props changes
|
|
||||||
api.dispatch(SendFormActions.observe(prevState, action));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no changes in common values
|
|
||||||
if (action.type === CONNECT.RECEIVE_WALLET_TYPE) {
|
|
||||||
if (action.device.state) {
|
|
||||||
// redirect to root view (Dashboard) if device was authenticated before
|
|
||||||
api.dispatch(RouterActions.selectFirstAvailableDevice(true));
|
|
||||||
}
|
|
||||||
api.dispatch(TrezorConnectActions.authorizeDevice());
|
|
||||||
}
|
|
||||||
if (action.type === CONNECT.AUTH_DEVICE) {
|
|
||||||
// selected device did changed
|
|
||||||
// try to restore discovery after device authentication
|
|
||||||
api.dispatch(DiscoveryActions.restore());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// even if "selectedDevice" didn't change because it was updated on DEVICE.CHANGED before DEVICE.CONNECT action
|
// even if "selectedDevice" didn't change because it was updated on DEVICE.CHANGED before DEVICE.CONNECT action
|
||||||
// try to restore discovery
|
// try to restore discovery
|
||||||
if (action.type === DEVICE.CONNECT) {
|
if (action.type === DEVICE.CONNECT) {
|
||||||
|
Loading…
Reference in New Issue
Block a user