mirror of
https://github.com/trezor/trezor-wallet
synced 2025-05-08 09:58:47 +00:00
Merge pull request #500 from trezor/fix/setInitialUrl-race-condition
fix: setInitialUrl - race condition
This commit is contained in:
commit
bcd618aa0a
@ -429,30 +429,36 @@ export const setInitialUrl = (): PayloadAction<boolean> => (
|
|||||||
dispatch: Dispatch,
|
dispatch: Dispatch,
|
||||||
getState: GetState
|
getState: GetState
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const { initialPathname } = getState().wallet;
|
// DEVICE.CONNECT race condition, "selectDevice" method was called but currently selectedDevice is in getState (auth) process
|
||||||
if (typeof initialPathname === 'string' && !dispatch(isLandingPageUrl(initialPathname, true))) {
|
// if so, consume this action (return true) to break "selectDevice" process
|
||||||
const valid = dispatch(
|
const { selectedDevice } = getState().wallet;
|
||||||
getValidUrl({
|
if (selectedDevice && selectedDevice.type === 'acquired' && !selectedDevice.state) return true;
|
||||||
type: LOCATION_CHANGE,
|
|
||||||
payload: {
|
|
||||||
location: {
|
|
||||||
pathname: initialPathname,
|
|
||||||
hash: '',
|
|
||||||
search: '',
|
|
||||||
state: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
if (valid === initialPathname) {
|
const { initialPathname } = getState().wallet;
|
||||||
// reset initial url
|
if (typeof initialPathname !== 'string') return false;
|
||||||
dispatch({
|
|
||||||
type: SET_INITIAL_URL,
|
const valid = dispatch(
|
||||||
});
|
getValidUrl({
|
||||||
dispatch(goto(valid));
|
type: LOCATION_CHANGE,
|
||||||
return true;
|
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;
|
||||||
};
|
};
|
||||||
|
@ -169,15 +169,11 @@ export const observe = (prevState: State, action: Action): PayloadAction<boolean
|
|||||||
|
|
||||||
const state: State = getState();
|
const state: State = getState();
|
||||||
|
|
||||||
const locationChanged = reducerUtils.observeChanges(
|
|
||||||
prevState.router.location,
|
|
||||||
state.router.location
|
|
||||||
);
|
|
||||||
const device = reducerUtils.getSelectedDevice(state);
|
const device = reducerUtils.getSelectedDevice(state);
|
||||||
const selectedDeviceChanged = reducerUtils.observeChanges(state.wallet.selectedDevice, device);
|
const selectedDeviceChanged = reducerUtils.observeChanges(state.wallet.selectedDevice, device);
|
||||||
|
|
||||||
// handle devices state change (from trezor-connect events or location change)
|
// handle devices state change (from trezor-connect events or location change)
|
||||||
if (locationChanged || selectedDeviceChanged) {
|
if (selectedDeviceChanged) {
|
||||||
if (device && deviceUtils.isSelectedDevice(state.wallet.selectedDevice, device)) {
|
if (device && deviceUtils.isSelectedDevice(state.wallet.selectedDevice, device)) {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: WALLET.UPDATE_SELECTED_DEVICE,
|
type: WALLET.UPDATE_SELECTED_DEVICE,
|
||||||
|
@ -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,
|
||||||
|
state: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
// pass action and break process
|
// pass action and break process
|
||||||
return next(action);
|
return next(action);
|
||||||
}
|
}
|
||||||
@ -42,10 +47,8 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa
|
|||||||
next(action);
|
next(action);
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case WALLET.SET_INITIAL_URL:
|
case WALLET.SET_FIRST_LOCATION_CHANGE:
|
||||||
if (action.pathname) {
|
api.dispatch(LocalStorageActions.loadData());
|
||||||
api.dispatch(LocalStorageActions.loadData());
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WALLET.SET_SELECTED_DEVICE:
|
case WALLET.SET_SELECTED_DEVICE:
|
||||||
// try to authorize device
|
// try to authorize device
|
||||||
@ -63,6 +66,9 @@ 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;
|
||||||
|
|
||||||
|
// check for "selectedDevice" change before any action
|
||||||
|
const selectedDeviceDidChange = await api.dispatch(WalletActions.observe(prevState, action));
|
||||||
|
|
||||||
// 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,9 +102,8 @@ 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 "selectedDevice" didn't change observe common values in SelectedAccountReducer
|
||||||
if (!(await api.dispatch(WalletActions.observe(prevState, action)))) {
|
if (!selectedDeviceDidChange) {
|
||||||
// if "selectedDevice" didn't change observe common values in SelectedAccountReducer
|
|
||||||
if (!(await api.dispatch(SelectedAccountActions.observe(prevState, action)))) {
|
if (!(await api.dispatch(SelectedAccountActions.observe(prevState, action)))) {
|
||||||
// if "selectedAccount" didn't change observe send form props changes
|
// if "selectedAccount" didn't change observe send form props changes
|
||||||
api.dispatch(SendFormActions.observe(prevState, action));
|
api.dispatch(SendFormActions.observe(prevState, action));
|
||||||
|
Loading…
Reference in New Issue
Block a user