Skip to content

Commit

Permalink
[Wallet] Don't allow going back after wallet is imported successfully (
Browse files Browse the repository at this point in the history
…#6279)

### Description

After successfully restoring a wallet, it's not possible to go back anymore by swiping on iOS or using the back button on Android.

### Tested

Manually

### Related issues

- Fixes #4393

### Backwards compatibility

Yes
  • Loading branch information
gnardini authored Dec 22, 2020
1 parent d0ec73a commit 51f643d
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const navigate = jest.fn()
export const navigateClearingStack = jest.fn()
export const replace = jest.fn()
export const navigateHome = jest.fn()
export const navigateBack = jest.fn()
Expand Down
4 changes: 2 additions & 2 deletions packages/mobile/src/import/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
importBackupPhraseSuccess,
} from 'src/import/actions'
import { redeemInviteSuccess } from 'src/invite/actions'
import { navigate, navigateHome } from 'src/navigator/NavigationService'
import { navigate, navigateClearingStack, navigateHome } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { fetchTokenBalanceInWeiWithRetry } from 'src/tokens/saga'
import Logger from 'src/utils/Logger'
Expand Down Expand Up @@ -82,7 +82,7 @@ export function* importBackupPhraseSaga({ phrase, useEmptyWallet }: ImportBackup
yield put(setHasSeenVerificationNux(true))
navigateHome()
} else {
navigate(Screens.VerificationEducationScreen)
navigateClearingStack(Screens.VerificationEducationScreen)
}

yield put(importBackupPhraseSuccess())
Expand Down
20 changes: 19 additions & 1 deletion packages/mobile/src/navigator/NavigationService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// (https://github.com/react-navigation/react-navigation/issues/1439)

import { NavigationActions, StackActions } from '@react-navigation/compat'
import { NavigationContainerRef } from '@react-navigation/native'
import { CommonActions, NavigationContainerRef } from '@react-navigation/native'
import { createRef } from 'react'
import sleep from 'sleep-promise'
import { PincodeType } from 'src/account/reducer'
Expand Down Expand Up @@ -88,6 +88,24 @@ export function navigate<RouteName extends keyof StackParamList>(
})
}

export const navigateClearingStack: SafeNavigate = (...args) => {
const [routeName, params] = args
ensureNavigator()
.then(() => {
Logger.debug(`${TAG}@navigateClearingStack`, `Dispatch ${routeName}`)

navigationRef.current?.dispatch(
CommonActions.reset({
index: 0,
routes: [{ name: routeName, params }],
})
)
})
.catch((reason) => {
Logger.error(`${TAG}@navigateClearingStack`, `Navigation failure: ${reason}`)
})
}

export async function ensurePincode(): Promise<boolean> {
const pincodeType = pincodeTypeSelector(store.getState())

Expand Down
4 changes: 3 additions & 1 deletion packages/mobile/src/onboarding/UseBackToWelcomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ export function useBackToWelcomeScreen({ backAnalyticsEvents }: Props) {
// See https://reactnavigation.org/docs/preventing-going-back
const cancelBeforeRemove = navigation.addListener('beforeRemove', (event) => {
const resetScreenName = (event?.data?.action?.payload as any)?.routes?.[0]?.name
if (resetScreenName !== Screens.DrawerNavigator) {
const processCanceled =
[Screens.VerificationEducationScreen, Screens.DrawerNavigator].indexOf(resetScreenName) < 0
if (processCanceled) {
backAnalyticsEvents.forEach((analyticsEvent) => {
ValoraAnalytics.track(analyticsEvent)
})
Expand Down
10 changes: 2 additions & 8 deletions packages/mobile/src/pincode/PincodeSet.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CommonActions } from '@react-navigation/native'
import * as React from 'react'
import { fireEvent, flushMicrotasksQueue, render } from 'react-native-testing-library'
import { Provider } from 'react-redux'
import { navigateClearingStack } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import PincodeSet from 'src/pincode/PincodeSet'
import { createMockStore, getMockStackScreenProps } from 'test/utils'
Expand Down Expand Up @@ -56,13 +56,7 @@ describe('Pincode', () => {
jest.runAllTimers()
await flushMicrotasksQueue()

const dispatchAction = mockDispatch.mock.calls[0][0]()
expect(dispatchAction).toEqual(
CommonActions.reset({
index: 0,
routes: [{ name: Screens.VerificationEducationScreen }],
})
)
expect(navigateClearingStack).toBeCalledWith(Screens.VerificationEducationScreen)
})

it("displays an error text when the pins don't match", async () => {
Expand Down
20 changes: 7 additions & 13 deletions packages/mobile/src/pincode/PincodeSet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* This is a reactnavigation SCREEN, which we use to set a PIN.
*/
import colors from '@celo/react-components/styles/colors'
import { CommonActions } from '@react-navigation/native'
import { StackScreenProps } from '@react-navigation/stack'
import * as React from 'react'
import { WithTranslation } from 'react-i18next'
Expand All @@ -16,6 +15,7 @@ import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import DevSkipButton from 'src/components/DevSkipButton'
import { Namespaces, withTranslation } from 'src/i18n'
import { nuxNavigationOptions } from 'src/navigator/Headers'
import { navigate, navigateClearingStack } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { StackParamList } from 'src/navigator/types'
import { DEFAULT_CACHE_ACCOUNT, isPinValid } from 'src/pincode/authentication'
Expand Down Expand Up @@ -60,12 +60,12 @@ export class PincodeSet extends React.Component<Props, State> {
errorText: undefined,
}

getNextScreen = () => {
navigateToNextScreen = () => {
if (this.props.choseToRestoreAccount) {
return Screens.ImportWallet
navigate(Screens.ImportWallet)
} else {
navigateClearingStack(Screens.VerificationEducationScreen)
}

return Screens.VerificationEducationScreen
}

onChangePin1 = (pin1: string) => {
Expand Down Expand Up @@ -103,13 +103,7 @@ export class PincodeSet extends React.Component<Props, State> {
setCachedPin(DEFAULT_CACHE_ACCOUNT, pin1)
this.props.setPincode(PincodeType.CustomPin)
ValoraAnalytics.track(OnboardingEvents.pin_set)

this.props.navigation.dispatch(() => {
return CommonActions.reset({
index: 0,
routes: [{ name: this.getNextScreen() }],
})
})
this.navigateToNextScreen()
} else {
this.props.navigation.setParams({ isVerifying: false })
ValoraAnalytics.track(OnboardingEvents.pin_invalid, { error: 'Pins do not match' })
Expand All @@ -128,7 +122,7 @@ export class PincodeSet extends React.Component<Props, State> {

return (
<SafeAreaView style={styles.container}>
<DevSkipButton nextScreen={this.getNextScreen()} />
<DevSkipButton onSkip={this.navigateToNextScreen} />
{isVerifying ? (
// Verify
<Pincode
Expand Down

0 comments on commit 51f643d

Please sign in to comment.