Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Wallet] Pin Setup Flow v2 #1054

Merged
merged 10 commits into from
Sep 24, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/mobile/__mocks__/react-native-randombytes.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export const randomBytes = jest.fn(() => ({
toString: jest.fn(),
}))

export default {}
1 change: 0 additions & 1 deletion packages/mobile/locales/en-US/backupKeyFlow6.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
"Don’t take a screenshot or save it in your phone notes. Make sure to write the Backup Key down and keep it safe."
},
"setBackupKey": "Set Backup Key",
"skip": "Skip",
"areYouSure": "Are you sure?",
"backupSkipText": {
"0": "Without a Backup Key, you can lose access to your wallet ",
Expand Down
2 changes: 2 additions & 0 deletions packages/mobile/locales/en-US/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"adjustDate": "Adjust Date",
"submit": "Submit",
"continue": "Continue",
"save": "Save",
"next": "Next",
"skip": "Skip",
"downloadRewards": "Download Celo Rewards",
"chooseLanguage": "Choose Language",
"wallet": "Wallet",
Expand Down
31 changes: 10 additions & 21 deletions packages/mobile/locales/en-US/nuxNamePin1.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,22 @@
"cancel": "Cancel",
"important": "Important",
"createPin": {
"title": "Create 6 digit PIN Code",
"intro": "Create a PIN to secure your Celo Wallet.",
"why":
"You'll need this PIN occasionally when you want to send {{CeloDollars}} to your friends.",
"warn":
"Write down your 6 digit PIN code & secure it somewhere safe. You will be asked for this later to access your wallet.",
"title": "Set a 6 digit PIN",
"yourPin": "Your PIN"
},
"enableSecurity": "Enable Security",
"verifyPin": {
"title": "Re-enter your PIN",
"finalPin": "Create PIN"
"title": "Re-Enter PIN"
},
"confirmPin": {
"title": "Enter 6 digit PIN Code",
"submit": "Submit"
"title": "Enter PIN"
},
"systemAuth": {
"title": "Secure Your Phone",
"secure": "Adding a PIN to your phone helps to keep your funds in Celo safe and secure.",
"intro":
"We will need you to input your device's lockscreen PIN or thumbprint, if your device supports it.",
"why":
"We need this additional level of protection to ensure that the value in your wallet stays secure.",
"pincodeEducation": {
"title": "Secure Your Wallet",
"intro": "To protect your account, the Celo Wallet requires a PIN.",
"summary":
"Celo requires phones to be secured with a PIN or fingerprint. Your device’s lock helps ensure that the funds in your wallet are protected."
"You can use your phone’s existing authentication or create a new PIN for this application.",
"usePhoneAuth": "Use Phone Authentication",
"createNewPin": "Create New PIN"
},
"goToSystemSecuritySettingsActionLabel": "Go to security",
"enableSystemScreenLockFailedMessage": "Failed to enable screen lock",
Expand All @@ -94,6 +84,5 @@
"1": "Don’t worry—connecting does not send invites to your contacts.",
"enable": "Enable Contact Access",
"loading": "Finding friends on Celo..."
},
"skip": "Skip"
}
}
1 change: 0 additions & 1 deletion packages/mobile/locales/es-419/backupKeyFlow6.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"No haga una captura de pantalla ni la guarde en las notas de tu teléfono. Asegúrese de escribir la clave de respaldo a mano y mantenerla segura."
},
"setBackupKey": "Crear clave de respaldo",
"skip": "Saltar paso",
"areYouSure": "¿Está seguro?",
"shareBackupKey": "Compartir clave de respaldo",
"backupRecovery":
Expand Down
2 changes: 2 additions & 0 deletions packages/mobile/locales/es-419/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"adjustDate": "Arreglar hora",
"submit": "Enviar",
"continue": "Continuar",
"save": "Guarda",
"next": "Siguiente",
"skip": "Saltar",
"downloadRewards": "Descargar Recompensas Celo",
"chooseLanguage": "Elegir idioma",
"wallet": "Monedero",
Expand Down
31 changes: 10 additions & 21 deletions packages/mobile/locales/es-419/nuxNamePin1.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,22 @@
"cancel": "Cancelar",
"important": "Importante",
"createPin": {
"title": "Crear un código PIN de 6 dígitos",
"intro": "Cree un PIN para proteger tu Monedero Celo.",
"why": "En ciertos casos, necesitará este PIN para enviar {{CeloDollars}} a sus amigos.",
"warn":
"escribe tu código PIN de 6 dígitos en un papel y guárdelo en algún sitio seguro. Se lo solicitaremos más tarde para acceder a tu monedero.",
"title": "Crear un PIN de 6 dígitos",
"yourPin": "Su PIN"
},
"enableSecurity": "Habilitar seguridad",
"verifyPin": {
"title": "Repetir el código PIN de 6 dígitos",
"finalPin": "Crear PIN"
"title": "Repetir el PIN"
},
"confirmPin": {
"title": "Ingrese el código PIN de 6 dígitos",
"submit": "Enviar"
"title": "Ingrese su PIN"
},
"systemAuth": {
"title": "Asegura tu celular",
"secure":
"Agregar un PIN a tu teléfono ayuda a que tus fondos en Celo se mantengan seguros y protegidos.",
"intro":
"Necesitaremos que ingreses el código de bloqueo de pantalla de tu dispositivo o tu huella, si el mismo lo soporta.",
"why":
"Necesitamos este nivel de protección adicional para asegurar que el contenido de tu monedero se encuentra a salvo.",
"pincodeEducation": {
"title": "Asegure su billetera",
"intro": "Para proteger su cuenta, Celo billetera requiere un PIN.",
"summary":
"Celo requiere que los teléfonos estén protegidos con un PIN o huella digital. Bloquear de tu dispositivo ayuda a garantizar que los fondos en tu billetera estén protegidos."
"Puede usar la autenticación existente de su teléfono o crear un nuevo PIN para esta aplicación.",
"usePhoneAuth": "Usar Autenticación de Teléfono",
"createNewPin": "Crear nuevo PIN"
},
"goToSystemSecuritySettingsActionLabel": "Vaya a seguridad",
"enableSystemScreenLockFailedMessage": "Error al intentar habilitar el bloqueo de pantalla",
Expand All @@ -95,6 +85,5 @@
"1": "No se preocupe: la conexión no envía invitaciones a sus contactos.",
"enable": "Habilitar acceso a contactos",
"loading": "Encontrar amigos en Celo..."
},
"skip": "Saltar"
}
}
43 changes: 0 additions & 43 deletions packages/mobile/src/account/actions.test.ts

This file was deleted.

107 changes: 33 additions & 74 deletions packages/mobile/src/account/actions.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import { PincodeType } from 'src/account/reducer'
import { PaymentRequest } from 'src/account/types'
import { showError } from 'src/alert/actions'
import CeloAnalytics from 'src/analytics/CeloAnalytics'
import { DefaultEventNames } from 'src/analytics/constants'
import { ErrorMessages } from 'src/app/ErrorMessages'
import { SUPPORTS_KEYSTORE } from 'src/config'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { getPin as getPinCred, setPin as setPinCred } from 'src/pincode/PincodeViaAndroidKeystore'
import { DispatchType, GetStateType } from 'src/redux/reducers'
import Logger from 'src/utils/Logger'

const TAG = 'account/actions'

export enum Actions {
SET_NAME = 'ACCOUNT/SET_NAME',
SET_PHONE_NUMBER = 'ACCOUNT/SET_PHONE_NUMBER',
DEV_MODE_TRIGGER_CLICKED = 'ACCOUNT/NAME_CLICKED',
PHOTOSNUX_CLICKED = 'ACCOUNT/PHOTOSNUX_CLICKED',
PINCODE_SET = 'ACCOUNT/PINCODE_SET',
SET_PINCODE = 'ACCOUNT/SET_PINCODE',
SET_PINCODE_SUCCESS = 'ACCOUNT/SET_PINCODE_SUCCESS',
SET_PINCODE_FAILURE = 'ACCOUNT/SET_PINCODE_FAILURE',
SET_ACCOUNT_CREATION_TIME_ACTION = 'ACCOUNT/SET_ACCOUNT_CREATION_TIME_ACTION',
SET_BACKUP_COMPLETED_ACTION = 'ACCOUNT/SET_BACKUP_COMPLETED_ACTION',
SET_BACKUP_DELAYED_ACTION = 'ACCOUNT/SET_BACKUP_DELAYED_ACTION',
Expand Down Expand Up @@ -46,8 +39,19 @@ export interface PhotosNUXClickedAction {
type: Actions.PHOTOSNUX_CLICKED
}

export interface PincodeSetAction {
type: Actions.PINCODE_SET
export interface SetPincodeAction {
type: Actions.SET_PINCODE
pincodeType: PincodeType
pin?: string
}

export interface SetPincodeSuccessAction {
type: Actions.SET_PINCODE_SUCCESS
pincodeType: PincodeType
}

export interface SetPincodeFailureAction {
type: Actions.SET_PINCODE_FAILURE
}

export interface SetAccountCreationAction {
Expand Down Expand Up @@ -86,7 +90,9 @@ export type ActionTypes =
| SetPhoneNumberAction
| DevModeTriggerClickedAction
| PhotosNUXClickedAction
| PincodeSetAction
| SetPincodeAction
| SetPincodeSuccessAction
| SetPincodeFailureAction
| SetAccountCreationAction
| SetBackupCompletedAction
| SetBackupDelayedAction
Expand Down Expand Up @@ -119,8 +125,19 @@ export const photosNUXCompleted = (): PhotosNUXClickedAction => ({
type: Actions.PHOTOSNUX_CLICKED,
})

export const pincodeSet = (): PincodeSetAction => ({
type: Actions.PINCODE_SET,
export const setPincode = (pincodeType: PincodeType, pin?: string): SetPincodeAction => ({
type: Actions.SET_PINCODE,
pincodeType,
pin,
})

export const setPincodeSuccess = (pincodeType: PincodeType): SetPincodeSuccessAction => ({
type: Actions.SET_PINCODE_SUCCESS,
pincodeType,
})

export const setPincodeFailure = (): SetPincodeFailureAction => ({
type: Actions.SET_PINCODE_FAILURE,
})

export const setAccountCreationTime = (): SetAccountCreationAction => ({
Expand Down Expand Up @@ -158,61 +175,3 @@ export const setUserContactDetails = (
contactId,
thumbnailPath,
})

export const setPin = (pin: string) => async (dispatch: DispatchType, getState: GetStateType) => {
let success

const state = getState()
if (state.account.pincodeSet) {
Logger.debug(TAG + '@setPin', 'Pincode has already been set')
throw Error('Can not set PIN twice')
}
if (!pin) {
Logger.debug(TAG + '@setPin', 'setpin got falsy pin: ' + pin)
throw Error('Can not set falsy PIN')
}
if (SUPPORTS_KEYSTORE) {
Logger.info(TAG + '@setPin', 'supports keystore')
try {
success = await setPinCred(pin)
} catch (e) {
Logger.debug(TAG + '@setPin', 'setpin failed with:' + e)
success = false
}
Logger.info(TAG + '@setPin', 'keystore setpin: ' + success)
}

if (success) {
await dispatch(pincodeSet())
Logger.info(TAG + '@setPin', 'pincode set')
return true
} else {
dispatch(showError(ErrorMessages.SET_PIN_FAILED))
return false
}
}

export const getPincode = async () => {
let pin
if (SUPPORTS_KEYSTORE) {
Logger.info(TAG + '@getPincode', 'using keystore')
pin = await getPinCred()
} else {
Logger.debug(TAG + '@getPincode', 'NOT using keystore')
const pincodeEntered = new Promise((resolve, reject) => {
navigate(Screens.PincodeConfirmation, { resolve, reject })
})
pin = await pincodeEntered
}

if (!pin) {
Logger.debug(TAG + '@getPincode', 'pin seems to be falsy')
Logger.showMessage(
'PIN might be corrupted, please get backup key, wipe app data, update the app and recover from backup key'
)
return
} else {
Logger.debug(TAG + '@getPincode', 'get keystore pincode')
}
return pin
}
30 changes: 25 additions & 5 deletions packages/mobile/src/account/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export interface State {
devModeActive: boolean
devModeClickCount: number
photosNUXClicked: boolean
pincodeSet: boolean
pincodeType: PincodeType
isSettingPin: boolean
accountCreationTime: number
backupCompleted: boolean
backupDelayedTime: number
Expand All @@ -22,6 +23,12 @@ export interface State {
dismissedInviteFriends: boolean
}

export enum PincodeType {
Unset = 'Unset',
PhoneAuth = 'PhoneAuth',
CustomPin = 'CustomPin',
}

export interface UserContactDetails {
contactId: string | null
thumbnailPath: string | null
Expand All @@ -38,7 +45,8 @@ export const initialState = {
devModeActive: DEV_SETTINGS_ACTIVE_INITIALLY,
devModeClickCount: 0,
photosNUXClicked: false,
pincodeSet: false,
pincodeType: PincodeType.Unset,
isSettingPin: false,
accountCreationTime: 99999999999999,
paymentRequests: [],
backupCompleted: false,
Expand Down Expand Up @@ -75,10 +83,22 @@ export const reducer = (state: State | undefined = initialState, action: ActionT
...state,
photosNUXClicked: true,
}
case Actions.PINCODE_SET:
case Actions.SET_PINCODE:
return {
...state,
isSettingPin: true,
}
case Actions.SET_PINCODE_SUCCESS:
return {
...state,
pincodeType: action.pincodeType,
isSettingPin: false,
}
case Actions.SET_PINCODE_FAILURE:
return {
...state,
pincodeSet: true,
pincodeType: PincodeType.Unset,
isSettingPin: false,
}
case Actions.SET_ACCOUNT_CREATION_TIME_ACTION:
return {
Expand Down Expand Up @@ -128,4 +148,4 @@ export const nameSelector = (state: RootState) => state.account.name
export const e164NumberSelector = (state: RootState) => state.account.e164PhoneNumber
export const defaultCountryCodeSelector = (state: RootState) => state.account.defaultCountryCode
export const userContactDetailsSelector = (state: RootState) => state.account.contactDetails
export const pincodeSelector = (state: RootState) => state.account.pincodeSet
export const pincodeTypeSelector = (state: RootState) => state.account.pincodeType
Loading