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