Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:jolocom/smartwallet-app into fix…
Browse files Browse the repository at this point in the history
…/error_handling

Conflicts:
	src/actions/account/index.ts

updated the errors to match
  • Loading branch information
mnzaki committed May 10, 2019
2 parents 701062f + 116ac69 commit 3f24699
Show file tree
Hide file tree
Showing 26 changed files with 205 additions and 359 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@ module.exports = {
// use ES6-style imports instead
'@typescript-eslint/no-triple-slash-reference': ['error'],
'@typescript-eslint/no-var-requires': ['off'],
'@typescript-eslint/no-use-before-define': ['off']
},
}
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ import com.android.build.OutputFile
project.ext.react = [
cliPath: "node_modules/haul/bin/cli.js",
extraPackagerArgs: ['--minify', 'false'],
entryFile: "index.js"
entryFile: "index.ts"
]

apply from: "../../node_modules/react-native/react.gradle"
Expand Down
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"ts",
"tsx"
],
"transformer": "node_modules/react-native-typescript-transformer/index.js"
"transformer": "node_modules/react-native-typescript-transformer/index.ts"
}
},
"name": "smartwallet",
Expand Down
5 changes: 0 additions & 5 deletions index.js

This file was deleted.

5 changes: 5 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { AppRegistry } from 'react-native'

import App from 'src/App'

AppRegistry.registerComponent('jolocomwallet', () => App)
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
"clean:ios": "cd ios && xcodebuild clean",
"clean:react": "rm -rf $TMP/react*",
"clean:all": "yarn run clean:ios && yarn run clean:android && yarn run clean:react && yarn run clean:node",
"build:ios": "haul bundle --entry-file='index.js' --bundle-output='./ios/smartwallet/main.jsbundle' --minify=false --dev=false --platform='ios' --assets-dest='./ios'",
"build:ios": "haul bundle --entry-file='index.ts' --bundle-output='./ios/smartwallet/main.jsbundle' --minify=false --dev=false --platform='ios' --assets-dest='./ios'",
"build:android": "haul bundle --entry-file='index.ts' --minify=true --dev=false --platform='android'",
"test": "node node_modules/jest/bin/jest.js",
"format": "eslint --fix --ext .ts --ext .tsx ."
},
Expand Down Expand Up @@ -124,10 +125,8 @@
"react-native-languages": "^3.0.1",
"react-native-material-textfield": "^0.12.0",
"react-native-material-ui": "^1.22.2",
"react-native-md-textinput": "^2.0.4",
"react-native-qrcode-scanner": "^1.0.1",
"react-native-randombytes": "^3.5.2",
"react-native-remote-svg": "^1.2.0",
"react-native-snap-carousel": "^3.6.0",
"react-native-splash-screen": "3.0.6",
"react-native-sqlite-storage": "^3.3.4",
Expand Down
30 changes: 13 additions & 17 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import React from 'react'
import { Provider } from 'react-redux'
import { Navigator } from 'src/NavigatorContainer'
import { store } from 'src/store'
import { JolocomTheme } from 'src/styles/jolocom-theme'
import SplashScreen from 'react-native-splash-screen'
import { initStore } from './store'

const { ThemeProvider } = require('react-native-material-ui')
const assign = require('object.assign/implementation')

Object.assign = assign

// tslint:disable-next-line: no-default-export
export default class App extends React.Component {
componentDidMount() {
SplashScreen.hide()
}
console.disableYellowBox = true

render() {
return (
<ThemeProvider uiTheme={JolocomTheme}>
<Provider store={store}>
<Navigator dispatch={store.dispatch} />
</Provider>
</ThemeProvider>
)
}
const App = () => {
const store = initStore()
return (
<ThemeProvider uiTheme={JolocomTheme}>
<Provider store={store}>
<Navigator dispatch={store.dispatch} />
</Provider>
</ThemeProvider>
)
}

export default App
19 changes: 10 additions & 9 deletions src/NavigatorContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { BackHandler, Linking, StatusBar } from 'react-native'
import { AnyAction } from 'redux'
import { Routes } from 'src/routes'
import { RootState } from 'src/reducers/'
import { navigationActions, accountActions } from 'src/actions/'
import { navigationActions, accountActions, genericActions } from 'src/actions/'
import { BottomActionBar } from './ui/generic/'
import { routeList } from './routeList'
import { LoadingSpinner } from 'src/ui/generic/loadingSpinner'
Expand All @@ -24,6 +24,7 @@ interface ConnectProps {
goBack: () => void
handleDeepLink: (url: string) => void
checkIfAccountExists: () => void
initApp: () => Promise<void>
}

interface OwnProps {
Expand All @@ -45,14 +46,13 @@ export class NavigatorContainer extends React.Component<Props> {
this.addListener = createReduxBoundAddListener('root')
}

UNSAFE_componentWillMount() {
Linking.getInitialURL().then((url: string) => {
if (!url) {
this.props.checkIfAccountExists()
} else {
this.props.handleDeepLink(url)
}
})
async componentDidMount() {
await this.props.initApp()
await this.props.checkIfAccountExists()
const url = await Linking.getInitialURL()
if (url) {
this.props.handleDeepLink(url)
}

Linking.addEventListener('url', this.handleOpenURL)
BackHandler.addEventListener('hardwareBackPress', this.navigateBack)
Expand Down Expand Up @@ -116,6 +116,7 @@ const mapDispatchToProps = (dispatch: Function) => ({
navigationActions.navigate({ routeName: routeList.QRCodeScanner }),
),
checkIfAccountExists: () => dispatch(accountActions.checkIdentityExists()),
initApp: async () => await dispatch(genericActions.initApp()),
})

export const Navigator = connect(
Expand Down
42 changes: 21 additions & 21 deletions src/actions/account/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
getClaimMetadataByCredentialType,
getCredentialUiCategory,
getUiCredentialTypeByType,
instantiateIdentityWallet,
} from '../../lib/util'
import { cancelReceiving } from '../sso'
import { JolocomLib } from 'jolocom-lib'
import { AppError, ErrorCode } from 'src/lib/errors'

export const setDid = (did: string) => ({
Expand Down Expand Up @@ -43,37 +43,37 @@ export const checkIdentityExists = () => async (
getState: Function,
backendMiddleware: BackendMiddleware,
) => {
const { storageLib } = backendMiddleware

try {
const personas = await storageLib.get.persona()
if (!personas.length) {
const { keyChainLib, storageLib, encryptionLib } = backendMiddleware
const encryptedEntropy = await storageLib.get.encryptedSeed()
if (!encryptedEntropy) {
dispatch(toggleLoading(false))
dispatch(
navigationActions.navigatorReset({ routeName: routeList.Landing }),
)
return
}

dispatch(setDid(personas[0].did))
await instantiateIdentityWallet(backendMiddleware)
const password = await keyChainLib.getPassword()
const decryptedSeed = encryptionLib.decryptWithPass({
cipher: encryptedEntropy,
pass: password,
})
// TODO: rework the seed param on lib, currently cleartext seed is being passed around. Bad.
const userVault = new JolocomLib.KeyProvider(
Buffer.from(decryptedSeed, 'hex'),
password,
)
await backendMiddleware.setIdentityWallet(userVault, password)
const identityWallet = backendMiddleware.identityWallet
dispatch(setDid(identityWallet.identity.did))

dispatch(toggleLoading(false))
dispatch(navigationActions.navigatorReset({ routeName: routeList.Home }))
} catch (err) {
if (err.message.indexOf('no such table') === 0) {
return
}
dispatch(genericActions.showErrorScreen(new AppError(ErrorCode.CheckIdentityFailed, err)))
}
}

export const setIdentityWallet = () => async (
dispatch: Dispatch<AnyAction>,
getState: Function,
backendMiddleware: BackendMiddleware,
) => {
try {
await instantiateIdentityWallet(backendMiddleware)
} catch (err) {
dispatch(genericActions.showErrorScreen(new AppError(ErrorCode.IdentityWalletFailed, err)))
dispatch(genericActions.showErrorScreen(new AppError(ErrorCode.WalletInitFailed, err)))
}
}

Expand Down
17 changes: 16 additions & 1 deletion src/actions/generic/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { navigationActions } from 'src/actions/'
import { Dispatch, AnyAction } from 'redux'
import { AnyAction, Dispatch } from 'redux'
import { routeList } from 'src/routeList'
import { BackendMiddleware } from '../../backendMiddleware'
import SplashScreen from 'react-native-splash-screen'

export const showErrorScreen = (error: Error, returnTo = routeList.Home) => (
dispatch: Dispatch<AnyAction>,
Expand All @@ -11,3 +13,16 @@ export const showErrorScreen = (error: Error, returnTo = routeList.Home) => (
params: { returnTo, error },
}),
)

export const initApp = () => async (
dispatch: Dispatch<AnyAction>,
getState: Function,
backendMiddleware: BackendMiddleware,
) => {
try {
await backendMiddleware.initStorage()
SplashScreen.hide()
} catch (e) {
dispatch(showErrorScreen(e, routeList.Landing))
}
}
22 changes: 10 additions & 12 deletions src/actions/navigation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {
} from 'react-navigation'
import { AnyAction, Dispatch } from 'redux'
import { ssoActions } from 'src/actions/'
import { setDid, toggleLoading } from '../account'
import { toggleLoading } from '../account'
import { BackendMiddleware } from 'src/backendMiddleware'
import { instantiateIdentityWallet } from 'src/lib/util'
import { setDeepLinkLoading, toggleDeepLinkFlag } from '../sso'
import { routeList } from 'src/routeList'

export const navigate = (options: NavigationNavigateActionPayload) =>
NavigationActions.navigate(options)
Expand All @@ -22,8 +22,8 @@ export const navigatorReset = (newScreen: NavigationNavigateActionPayload) =>

/**
* The function that parses a deep link to get the route name and params
* It then matches the route name and dispatches a correcponding action
* @param url - a deep link string with the following schemat: appName://routeName/params
* It then matches the route name and dispatches a corresponding action
* @param url - a deep link string with the following schema: appName://routeName/params
*/
export const handleDeepLink = (url: string) => async (
dispatch: Dispatch<AnyAction>,
Expand All @@ -33,24 +33,22 @@ export const handleDeepLink = (url: string) => async (
dispatch(toggleLoading(true))
const route: string = url.replace(/.*?:\/\//g, '')
const params: string = (route.match(/\/([^\/]+)\/?$/) as string[])[1] || ''
const routeName = route!.split('/')[0]
const routeName = route.split('/')[0]

if (
routeName === 'consent' ||
routeName === 'payment' ||
routeName === 'authenticate'
) {
dispatch(setDeepLinkLoading(true))
dispatch(toggleDeepLinkFlag(true))
const personas = await backendMiddleware.storageLib.get.persona()

if (!personas.length) {
// The identityWallet is initialised before the deep link is handled.
if (!backendMiddleware.identityWallet) {
dispatch(toggleLoading(false))
dispatch(navigatorReset({ routeName: routeList.Landing }))
return
}

dispatch(setDid(personas[0].did))
await instantiateIdentityWallet(backendMiddleware)
dispatch(setDeepLinkLoading(true))
dispatch(toggleDeepLinkFlag(true))
dispatch(ssoActions.parseJWT(params))
}
}
4 changes: 2 additions & 2 deletions src/actions/registration/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AnyAction, Dispatch } from 'redux'
import { navigationActions, genericActions, accountActions } from 'src/actions/'
import { navigationActions, genericActions } from 'src/actions/'
import { BackendMiddleware } from 'src/backendMiddleware'
import { routeList } from 'src/routeList'
import * as loading from 'src/actions/registration/loadingStages'
Expand Down Expand Up @@ -90,7 +90,7 @@ export const createIdentity = (encodedEntropy: string) => async (
await storageLib.store.persona(personaData)
dispatch(setDid(identityWallet.identity.did))
dispatch(setLoadingMsg(loading.loadingStages[3]))
dispatch(accountActions.setIdentityWallet())
await backendMiddleware.setIdentityWallet(userVault, password)

return dispatch(
navigationActions.navigatorReset({
Expand Down
18 changes: 2 additions & 16 deletions src/actions/sso/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { CredentialsReceive } from 'jolocom-lib/js/interactionTokens/credentials
import { CredentialRequest } from 'jolocom-lib/js/interactionTokens/credentialRequest'
import { getIssuerPublicKey } from 'jolocom-lib/js/utils/helper'
import { SoftwareKeyProvider } from 'jolocom-lib/js/vaultedKeyProvider/softwareProvider'
import { KeyTypes } from 'jolocom-lib/js/vaultedKeyProvider/types'
import { consumePaymentRequest } from './paymentRequest'
import { Authentication } from 'jolocom-lib/js/interactionTokens/authentication'
import { consumeAuthenticationRequest } from './authenticationRequest'
Expand Down Expand Up @@ -273,27 +272,14 @@ export const sendCredentialResponse = (
getState: Function,
backendMiddleware: BackendMiddleware,
) => {
const { storageLib, keyChainLib, encryptionLib, registry } = backendMiddleware
const { storageLib, keyChainLib, identityWallet } = backendMiddleware
const {
activeCredentialRequest: { callbackURL, requestJWT },
isDeepLinkInteraction,
} = getState().sso

try {
const password = await keyChainLib.getPassword()
const decryptedSeed = encryptionLib.decryptWithPass({
cipher: await storageLib.get.encryptedSeed(),
pass: password,
})
const userVault = new SoftwareKeyProvider(
Buffer.from(decryptedSeed, 'hex'),
password,
)

const wallet = await registry.authenticate(userVault, {
derivationPath: KeyTypes.jolocomIdentityKey,
encryptionPass: password,
})

const credentials = await Promise.all(
selectedCredentials.map(
Expand All @@ -305,7 +291,7 @@ export const sendCredentialResponse = (
const jsonCredentials = credentials.map(cred => cred.toJSON())

const request = JolocomLib.parse.interactionToken.fromJWT(requestJWT)
const response = await wallet.create.interactionTokens.response.share(
const response = await identityWallet.create.interactionTokens.response.share(
{
callbackURL,
suppliedCredentials: jsonCredentials,
Expand Down
18 changes: 11 additions & 7 deletions src/backendMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import { jolocomEthereumResolver } from 'jolocom-lib/js/ethereum/ethereum'
import { jolocomContractsGateway } from 'jolocom-lib/js/contracts/contractsGateway'

export class BackendMiddleware {
identityWallet!: IdentityWallet
storageLib: Storage
encryptionLib: EncryptionLibInterface
keyChainLib: KeyChainInterface
registry: IRegistry
public identityWallet!: IdentityWallet
public storageLib: Storage
public encryptionLib: EncryptionLibInterface
public keyChainLib: KeyChainInterface
public registry: IRegistry

constructor(config: {
public constructor(config: {
fuelingEndpoint: string
typeOrmConfig: ConnectionOptions
}) {
Expand All @@ -40,7 +40,11 @@ export class BackendMiddleware {
})
}

async setIdentityWallet(
public async initStorage(): Promise<void> {
await this.storageLib.initConnection()
}

public async setIdentityWallet(
userVault: SoftwareKeyProvider,
pass: string,
): Promise<void> {
Expand Down
Loading

0 comments on commit 3f24699

Please sign in to comment.