feat(INJI-255): hash the passcode and store in mmkv

This commit is contained in:
Dhivya
2023-08-24 11:42:18 +05:30
parent a5cec84d35
commit 4cf62e07b3
11 changed files with 233 additions and 42 deletions

View File

@@ -23,6 +23,7 @@ export const Passcode: React.FC<PasscodeProps> = (props) => {
onSuccess={props.onSuccess}
onError={props.onError}
passcode={props.storedPasscode}
salt={props.salt}
/>
</Column>
<Column fill>
@@ -39,6 +40,7 @@ interface PasscodeProps {
message?: string;
error: string;
storedPasscode: string;
salt: string;
onSuccess: () => void;
onError: (value: string) => void;
onDismiss: () => void;

View File

@@ -1,6 +1,8 @@
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PinInput } from './PinInput';
import { hashData } from '../shared/commonUtil';
import { argon2iConfig } from '../shared/constants';
export const MAX_PIN = 6;
@@ -16,8 +18,9 @@ export const PasscodeVerify: React.FC<PasscodeVerifyProps> = (props) => {
return <PinInput length={MAX_PIN} onDone={verify} />;
function verify(value: string) {
if (props.passcode === value) {
async function verify(value: string) {
const hashedPasscode = await hashData(value, props.salt, argon2iConfig);
if (props.passcode === hashedPasscode) {
setIsVerified(true);
} else {
props.onError(t('passcodeMismatchError'));
@@ -29,4 +32,5 @@ interface PasscodeVerifyProps {
passcode: string;
onSuccess: () => void;
onError?: (error: string) => void;
salt: string;
}

View File

@@ -2,6 +2,7 @@ PODS:
- boost-for-react-native (1.63.0)
- BVLinearGradient (2.6.2):
- React-Core
- CatCrypto (0.3.2)
- CrcSwift (0.0.3)
- DoubleConversion (1.1.6)
- EXApplication (4.0.2):
@@ -275,6 +276,8 @@ PODS:
- React-jsi (= 0.64.4)
- React-perflogger (= 0.64.4)
- React-jsinspector (0.64.4)
- react-native-location (2.5.0):
- React
- react-native-mmkv-storage (0.8.0):
- MMKV (= 1.2.13)
- React-Core
@@ -358,6 +361,9 @@ PODS:
- React-cxxreact (= 0.64.4)
- React-jsi (= 0.64.4)
- React-perflogger (= 0.64.4)
- RNArgon2 (2.0.1):
- CatCrypto
- React-Core
- RNBluetoothStateManager (1.3.4):
- React-Core
- RNCClipboard (1.11.2):
@@ -435,6 +441,7 @@ DEPENDENCIES:
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- react-native-location (from `../node_modules/react-native-location`)
- react-native-mmkv-storage (from `../node_modules/react-native-mmkv-storage`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-restart (from `../node_modules/react-native-restart`)
@@ -455,6 +462,7 @@ DEPENDENCIES:
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- RNArgon2 (from `../node_modules/react-native-argon2`)
- RNBluetoothStateManager (from `../node_modules/react-native-bluetooth-state-manager`)
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- "RNCPicker (from `../node_modules/@react-native-picker/picker`)"
@@ -473,6 +481,7 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- boost-for-react-native
- CatCrypto
- CrcSwift
- GoogleInterchangeUtilities
- GoogleNetworkingUtilities
@@ -563,6 +572,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
React-jsinspector:
:path: "../node_modules/react-native/ReactCommon/jsinspector"
react-native-location:
:path: "../node_modules/react-native-location"
react-native-mmkv-storage:
:path: "../node_modules/react-native-mmkv-storage"
react-native-netinfo:
@@ -603,6 +614,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
RNArgon2:
:path: "../node_modules/react-native-argon2"
RNBluetoothStateManager:
:path: "../node_modules/react-native-bluetooth-state-manager"
RNCClipboard:
@@ -635,6 +648,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
BVLinearGradient: 34a999fda29036898a09c6a6b728b0b4189e1a44
CatCrypto: a477899b6be4954e75be4897e732da098cc0a5a8
CrcSwift: f85dea6b41dddb5f98bb3743fd777ce58b77bc2e
DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
EXApplication: 54fe5bd6268d697771645e8f1aef8b806a65247a
@@ -682,6 +696,7 @@ SPEC CHECKSUMS:
React-jsi: 64f80675a66899bf0f4a58b8e3908966fa516234
React-jsiexecutor: 8c077bef1c64430b6034f27df1000d194551e2eb
React-jsinspector: d4f6973dd474357dbaaf6f52f31ffc713bf3e766
react-native-location: 5a40ec1cc6abf2f6d94df979f98ec76c3a415681
react-native-mmkv-storage: 8ba3c0216a6df283ece11205b442a3e435aec4e5
react-native-netinfo: 42c0965fca99069b92e3f7360ab2d425985e5104
react-native-restart: 45c8dca02491980f2958595333cbccd6877cb57e
@@ -702,6 +717,7 @@ SPEC CHECKSUMS:
React-RCTVibration: 761849eea2a1abc99d5e4171bae17ab3da3143ac
React-runtimeexecutor: 5b441857030bb6c3abaa7517f333cb01875ae499
ReactCommon: b4a65d2d6e9eeffd4b32dde1245962b3f43907d0
RNArgon2: 1481820722fd4af1575c09f7fc9ad67c00ee8a42
RNBluetoothStateManager: ae6a26260cbdf1827b58bd3bcc563527d61e6488
RNCClipboard: 3f0451a8100393908bea5c5c5b16f96d45f30bfc
RNCPicker: cb57c823d5ce8d2d0b5dfb45ad97b737260dc59e

View File

@@ -6,11 +6,14 @@ import getAllConfigurations, {
} from '../shared/commonprops/commonProps';
import { AppServices } from '../shared/GlobalContext';
import { StoreEvents, StoreResponseEvent } from './store';
import { generateSecureRandom } from 'react-native-securerandom';
import binaryToBase64 from 'react-native/Libraries/Utilities/binaryToBase64';
const model = createModel(
{
serviceRefs: {} as AppServices,
passcode: '',
passcodeSalt: '',
biometrics: '',
canUseBiometrics: false,
selectLanguage: false,
@@ -79,6 +82,12 @@ export const authMachine = model.createMachine(
},
},
introSlider: {
invoke: {
src: 'generatePasscodeSalt',
onDone: {
actions: ['setPasscodeSalt', 'storeContext'],
},
},
on: {
NEXT: {
target: 'settingUp',
@@ -151,12 +160,22 @@ export const authMachine = model.createMachine(
setLanguage: assign({
selectLanguage: (context) => true,
}),
setPasscodeSalt: assign({
passcodeSalt: (context, event) => {
return event.data as string;
},
}),
},
services: {
downloadFaceSdkModel: () => () => {
downloadModel();
},
generatePasscodeSalt: () => async (context) => {
const randomBytes = await generateSecureRandom(16);
return binaryToBase64(randomBytes) as string;
},
},
guards: {
@@ -188,6 +207,10 @@ export function selectPasscode(state: State) {
return state.context.passcode;
}
export function selectPasscodeSalt(state: State) {
return state.context.passcodeSalt;
}
export function selectBiometrics(state: State) {
return state.context.biometrics;
}

View File

@@ -9,10 +9,16 @@ export interface Typegen0 {
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.auth.introSlider:invocation[0]': {
type: 'done.invoke.auth.introSlider:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'xstate.init': { type: 'xstate.init' };
};
'invokeSrcNameMap': {
downloadFaceSdkModel: 'done.invoke.auth.authorized:invocation[0]';
generatePasscodeSalt: 'done.invoke.auth.introSlider:invocation[0]';
};
'missingImplementations': {
actions: never;
@@ -26,11 +32,13 @@ export interface Typegen0 {
setContext: 'STORE_RESPONSE';
setLanguage: 'SETUP_BIOMETRICS' | 'SETUP_PASSCODE';
setPasscode: 'SETUP_PASSCODE';
setPasscodeSalt: 'done.invoke.auth.introSlider:invocation[0]';
storeContext:
| 'SETUP_BIOMETRICS'
| 'SETUP_PASSCODE'
| 'STORE_RESPONSE'
| 'done.invoke.auth.authorized:invocation[0]';
| 'done.invoke.auth.authorized:invocation[0]'
| 'done.invoke.auth.introSlider:invocation[0]';
};
'eventsCausingDelays': {};
'eventsCausingGuards': {
@@ -41,6 +49,7 @@ export interface Typegen0 {
};
'eventsCausingServices': {
downloadFaceSdkModel: 'LOGIN' | 'SETUP_PASSCODE';
generatePasscodeSalt: 'SELECT';
};
'matchesStates':
| 'authorized'

165
package-lock.json generated
View File

@@ -51,6 +51,7 @@
"react-native": "0.64.4",
"react-native-animated-pagination-dot": "^0.4.0",
"react-native-app-intro-slider": "^4.0.4",
"react-native-argon2": "^2.0.1",
"react-native-biometrics-changed": "^1.1.8",
"react-native-bluetooth-state-manager": "^1.3.2",
"react-native-cli": "^2.0.1",
@@ -21314,6 +21315,31 @@
}
}
},
"node_modules/react-dom": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
"integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.19.1"
},
"peerDependencies": {
"react": "^16.13.1"
}
},
"node_modules/react-dom/node_modules/scheduler": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
"integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"node_modules/react-error-overlay": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
@@ -21423,6 +21449,11 @@
"resolved": "https://registry.npmjs.org/react-native-app-intro-slider/-/react-native-app-intro-slider-4.0.4.tgz",
"integrity": "sha512-Zkjaol6X3BbZkHUpVDj2LjdidpS6rCgKi0fx80xgGKa0pHxBRd4swWTv2bHnnvu5k1/HXwYk0mY2TbK+2jHl5w=="
},
"node_modules/react-native-argon2": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/react-native-argon2/-/react-native-argon2-2.0.1.tgz",
"integrity": "sha512-/iOi0S+VVgS1gQGtQgL4ZxUVS4gz6Lav3bgIbtNmr9KbOunnBYzP6/yBe/XxkbpXvasHDwdQnuppOH/nuOBn7w=="
},
"node_modules/react-native-biometrics-changed": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/react-native-biometrics-changed/-/react-native-biometrics-changed-1.1.8.tgz",
@@ -25232,8 +25263,7 @@
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/tsutils": {
"version": "3.21.0",
@@ -31471,7 +31501,8 @@
"@idpass/smartshare-react-native": {
"version": "0.2.3-beta.2",
"resolved": "https://registry.npmjs.org/@idpass/smartshare-react-native/-/smartshare-react-native-0.2.3-beta.2.tgz",
"integrity": "sha512-R0BQdFhaym85c9G0TNEpHMOkmTrQI5x4Rm+I49RqPWtlse2BDuS4JuRU6FlrTxop09g6o9HnTEoRWgfRW0A1PQ=="
"integrity": "sha512-R0BQdFhaym85c9G0TNEpHMOkmTrQI5x4Rm+I49RqPWtlse2BDuS4JuRU6FlrTxop09g6o9HnTEoRWgfRW0A1PQ==",
"requires": {}
},
"@jest/create-cache-key-function": {
"version": "26.6.2",
@@ -31666,7 +31697,8 @@
"@react-native-clipboard/clipboard": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz",
"integrity": "sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ=="
"integrity": "sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ==",
"requires": {}
},
"@react-native-community/cli": {
"version": "5.0.1",
@@ -32374,12 +32406,14 @@
"@react-native-community/netinfo": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-7.1.3.tgz",
"integrity": "sha512-E8q3yuges6NYhrXBDQdzwCnG0bBQXATRjs6fpTjRJ37nURmdpe4HLq1awvooG4ymGTpZhrx4elcs/aUM7PTgrA=="
"integrity": "sha512-E8q3yuges6NYhrXBDQdzwCnG0bBQXATRjs6fpTjRJ37nURmdpe4HLq1awvooG4ymGTpZhrx4elcs/aUM7PTgrA==",
"requires": {}
},
"@react-native-picker/picker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.2.1.tgz",
"integrity": "sha512-EC7yv22QLHlTfnbC1ez9IUdXTOh1W31x96Oir0PfskSGFFJMWWdLTg4VrcE2DsGLzbfjjkBk123c173vf2a5MQ=="
"integrity": "sha512-EC7yv22QLHlTfnbC1ez9IUdXTOh1W31x96Oir0PfskSGFFJMWWdLTg4VrcE2DsGLzbfjjkBk123c173vf2a5MQ==",
"requires": {}
},
"@react-native/assets": {
"version": "1.0.0",
@@ -32446,7 +32480,8 @@
"@react-navigation/elements": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.7.tgz",
"integrity": "sha512-OZg2N/dd2tl6qkfrWvmUjFsYsbEyHEv4NbZSBuT+CR+d1pzmexN2IeVmi4cEMoR7U7GwhFcHRevF36yBsjU/dw=="
"integrity": "sha512-OZg2N/dd2tl6qkfrWvmUjFsYsbEyHEv4NbZSBuT+CR+d1pzmexN2IeVmi4cEMoR7U7GwhFcHRevF36yBsjU/dw==",
"requires": {}
},
"@react-navigation/native": {
"version": "6.0.14",
@@ -33191,7 +33226,8 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
"dev": true,
"requires": {}
},
"address": {
"version": "1.1.2",
@@ -33225,13 +33261,15 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
"integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
"dev": true
"dev": true,
"requires": {}
},
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true
"dev": true,
"requires": {}
},
"alphanum-sort": {
"version": "1.0.2",
@@ -33658,7 +33696,8 @@
"babel-core": {
"version": "7.0.0-bridge.0",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
"integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg=="
"integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
"requires": {}
},
"babel-loader": {
"version": "8.1.0",
@@ -36697,7 +36736,8 @@
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.13.0.tgz",
"integrity": "sha512-t3m7ta0EspzDxSOZh3cEOJIJVZgN/TlJYaBGnQlK6W/PZNbWep8q4RQskkJkA7/zwNpX0BaoEOSUUrqaADVoqA==",
"dev": true
"dev": true,
"requires": {}
},
"eslint-scope": {
"version": "5.1.1",
@@ -37213,7 +37253,8 @@
"expo-application": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/expo-application/-/expo-application-4.0.2.tgz",
"integrity": "sha512-ngTaFplTkWn0X45gMC+VNXGyJfGxX4wOwKmtr17rNMVWOQUhhLlyMkTj9bAamzsuwZh35l3S/eD/N1aMWWUwMw=="
"integrity": "sha512-ngTaFplTkWn0X45gMC+VNXGyJfGxX4wOwKmtr17rNMVWOQUhhLlyMkTj9bAamzsuwZh35l3S/eD/N1aMWWUwMw==",
"requires": {}
},
"expo-asset": {
"version": "8.4.6",
@@ -37753,7 +37794,8 @@
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/expo-error-recovery/-/expo-error-recovery-3.0.5.tgz",
"integrity": "sha512-VM6OOecjt0aPu5/eCdGGJfNjvAZIemaQym0JF/+SA5IlLiPpEfbVCDTO/5yiS8Zb5fKpeABx+GCRmtfnFqvRRw==",
"optional": true
"optional": true,
"requires": {}
},
"expo-file-system": {
"version": "13.1.4",
@@ -37775,7 +37817,8 @@
"expo-image-loader": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-3.1.1.tgz",
"integrity": "sha512-ZX4Bh3K4CCX1aZflnmbOgFNLS+c0/GUys4wdvqxO+4A4KU1NNb3jE7RVa/OFYNPDcGhEw20c1QjyE/WsVURJpg=="
"integrity": "sha512-ZX4Bh3K4CCX1aZflnmbOgFNLS+c0/GUys4wdvqxO+4A4KU1NNb3jE7RVa/OFYNPDcGhEw20c1QjyE/WsVURJpg==",
"requires": {}
},
"expo-json-utils": {
"version": "0.2.1",
@@ -37785,7 +37828,8 @@
"expo-keep-awake": {
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-10.0.2.tgz",
"integrity": "sha512-Ro1lgyKldbFs4mxhWM+goX9sg0S2SRR8FiJJeOvaRzf8xNhrZfWA00Zpr+/3ocCoWQ3eEL+X9UF4PXXHf0KoOg=="
"integrity": "sha512-Ro1lgyKldbFs4mxhWM+goX9sg0S2SRR8FiJJeOvaRzf8xNhrZfWA00Zpr+/3ocCoWQ3eEL+X9UF4PXXHf0KoOg==",
"requires": {}
},
"expo-local-authentication": {
"version": "12.0.1",
@@ -38347,7 +38391,8 @@
"expo-updates-interface": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-0.5.1.tgz",
"integrity": "sha512-RLvC69o1BkhHP6hNaWiIvSiTgXABB9v4HnoietoXKFHlAyxlQCupy6ki164KpZNrOS/PFJ2WWqZOvKfiyDVO+w=="
"integrity": "sha512-RLvC69o1BkhHP6hNaWiIvSiTgXABB9v4HnoietoXKFHlAyxlQCupy6ki164KpZNrOS/PFJ2WWqZOvKfiyDVO+w==",
"requires": {}
},
"express": {
"version": "4.16.4",
@@ -42473,7 +42518,8 @@
"mosip-inji-face-sdk": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/mosip-inji-face-sdk/-/mosip-inji-face-sdk-0.1.12.tgz",
"integrity": "sha512-lnoaa2lL0pS9u/9fwH4Q9OU2U56oqjXf2z4JjGxX80DQOqJGWvj49PfvPMYGFEfVucqIJyQBZUfvfpqfYO0+vw=="
"integrity": "sha512-lnoaa2lL0pS9u/9fwH4Q9OU2U56oqjXf2z4JjGxX80DQOqJGWvj49PfvPMYGFEfVucqIJyQBZUfvfpqfYO0+vw==",
"requires": {}
},
"move-concurrently": {
"version": "1.0.1",
@@ -45213,7 +45259,32 @@
"ws": {
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
"integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A=="
"integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==",
"requires": {}
}
}
},
"react-dom": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
"integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==",
"peer": true,
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.19.1"
},
"dependencies": {
"scheduler": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
"integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
"peer": true,
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
}
}
},
@@ -45226,7 +45297,8 @@
"react-freeze": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.0.tgz",
"integrity": "sha512-yQaiOqDmoKqks56LN9MTgY06O0qQHgV4FUrikH357DydArSZHQhl0BJFqGKIZoTqi8JizF9Dxhuk1FIZD6qCaw=="
"integrity": "sha512-yQaiOqDmoKqks56LN9MTgY06O0qQHgV4FUrikH357DydArSZHQhl0BJFqGKIZoTqi8JizF9Dxhuk1FIZD6qCaw==",
"requires": {}
},
"react-i18next": {
"version": "11.16.6",
@@ -45318,15 +45390,22 @@
"resolved": "https://registry.npmjs.org/react-native-app-intro-slider/-/react-native-app-intro-slider-4.0.4.tgz",
"integrity": "sha512-Zkjaol6X3BbZkHUpVDj2LjdidpS6rCgKi0fx80xgGKa0pHxBRd4swWTv2bHnnvu5k1/HXwYk0mY2TbK+2jHl5w=="
},
"react-native-argon2": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/react-native-argon2/-/react-native-argon2-2.0.1.tgz",
"integrity": "sha512-/iOi0S+VVgS1gQGtQgL4ZxUVS4gz6Lav3bgIbtNmr9KbOunnBYzP6/yBe/XxkbpXvasHDwdQnuppOH/nuOBn7w=="
},
"react-native-biometrics-changed": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/react-native-biometrics-changed/-/react-native-biometrics-changed-1.1.8.tgz",
"integrity": "sha512-vV9B0V5YKgt1azT8NikV3iepw7EGfH8XJ7PVwl03P7PSY/RAeAIwGAoxqxsdWI+I7l8d+FNAaQZ5so5Gi9crIg=="
"integrity": "sha512-vV9B0V5YKgt1azT8NikV3iepw7EGfH8XJ7PVwl03P7PSY/RAeAIwGAoxqxsdWI+I7l8d+FNAaQZ5so5Gi9crIg==",
"requires": {}
},
"react-native-bluetooth-state-manager": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/react-native-bluetooth-state-manager/-/react-native-bluetooth-state-manager-1.3.4.tgz",
"integrity": "sha512-aPSoNYoz1lRC5UorRajzAzME8UUanrEIIbvzdnPFrMDrKiJNCdjwcsyEZlNBKPdDAUrSSWyGaCZ4jHVGnd4bwA=="
"integrity": "sha512-aPSoNYoz1lRC5UorRajzAzME8UUanrEIIbvzdnPFrMDrKiJNCdjwcsyEZlNBKPdDAUrSSWyGaCZ4jHVGnd4bwA==",
"requires": {}
},
"react-native-cli": {
"version": "2.0.1",
@@ -45399,7 +45478,8 @@
"react-native-device-info": {
"version": "8.7.1",
"resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-8.7.1.tgz",
"integrity": "sha512-cVMZztFa2Qn6qpQa601W61CtUwZQ1KXfqCOeltejAWEXmgIWivC692WGSdtGudj4upSi1UgMSaGcvKjfcpdGjg=="
"integrity": "sha512-cVMZztFa2Qn6qpQa601W61CtUwZQ1KXfqCOeltejAWEXmgIWivC692WGSdtGudj4upSi1UgMSaGcvKjfcpdGjg==",
"requires": {}
},
"react-native-dotenv": {
"version": "3.3.1",
@@ -45460,27 +45540,32 @@
"react-native-linear-gradient": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.6.2.tgz",
"integrity": "sha512-Z8Xxvupsex+9BBFoSYS87bilNPWcRfRsGC0cpJk72Nxb5p2nEkGSBv73xZbEHnW2mUFvP+huYxrVvjZkr/gRjQ=="
"integrity": "sha512-Z8Xxvupsex+9BBFoSYS87bilNPWcRfRsGC0cpJk72Nxb5p2nEkGSBv73xZbEHnW2mUFvP+huYxrVvjZkr/gRjQ==",
"requires": {}
},
"react-native-location": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/react-native-location/-/react-native-location-2.5.0.tgz",
"integrity": "sha512-myT54tZuFmN6d5RruMVfoa8eY+voJWkSd73xUVhjzJDnQr5uu5MFoH7hMg3trHF1CAkaY/2gIneOspUdGxv59Q=="
"integrity": "sha512-myT54tZuFmN6d5RruMVfoa8eY+voJWkSd73xUVhjzJDnQr5uu5MFoH7hMg3trHF1CAkaY/2gIneOspUdGxv59Q==",
"requires": {}
},
"react-native-mmkv-storage": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/react-native-mmkv-storage/-/react-native-mmkv-storage-0.8.0.tgz",
"integrity": "sha512-L782Le5IuDYlDLGXF/qimbnzvkbYsSmV5PiDleo1DSS8Kr8Q31UK8YWtUICrDGQ9Fm7Xx4PxP9ffe2XzGeWaHQ=="
"integrity": "sha512-L782Le5IuDYlDLGXF/qimbnzvkbYsSmV5PiDleo1DSS8Kr8Q31UK8YWtUICrDGQ9Fm7Xx4PxP9ffe2XzGeWaHQ==",
"requires": {}
},
"react-native-permissions": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-3.6.1.tgz",
"integrity": "sha512-fzPpPQXeD34inUccqtoResSwYubfrwUguP4qrVUUv8+KSMjYSaHGoS5HaIJLZHlN9gO+TvLJZ2L5ZljTsb6qnQ=="
"integrity": "sha512-fzPpPQXeD34inUccqtoResSwYubfrwUguP4qrVUUv8+KSMjYSaHGoS5HaIJLZHlN9gO+TvLJZ2L5ZljTsb6qnQ==",
"requires": {}
},
"react-native-popable": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-native-popable/-/react-native-popable-0.4.3.tgz",
"integrity": "sha512-khoK9TVLfJV+mBO5FTRx0eZip7djYVDfjaTRDhFPgVq2Exq9X6139Rfjg1sWHPvAQ2VCszTuC45o6iT373kFPw=="
"integrity": "sha512-khoK9TVLfJV+mBO5FTRx0eZip7djYVDfjaTRDhFPgVq2Exq9X6139Rfjg1sWHPvAQ2VCszTuC45o6iT373kFPw==",
"requires": {}
},
"react-native-qrcode-svg": {
"version": "6.1.2",
@@ -45502,7 +45587,8 @@
"react-native-restart": {
"version": "0.0.24",
"resolved": "https://registry.npmjs.org/react-native-restart/-/react-native-restart-0.0.24.tgz",
"integrity": "sha512-pvJNU3NwQk6bCG2gOWcQpZ4IxhtELB0K9gzmtixfsaTFbW1UXXHkJNjk1kHazcbH5hrD7QbUkR63fsAVh8X4VQ=="
"integrity": "sha512-pvJNU3NwQk6bCG2gOWcQpZ4IxhtELB0K9gzmtixfsaTFbW1UXXHkJNjk1kHazcbH5hrD7QbUkR63fsAVh8X4VQ==",
"requires": {}
},
"react-native-rsa-native": {
"version": "2.0.5",
@@ -45512,7 +45598,8 @@
"react-native-safe-area-context": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.3.2.tgz",
"integrity": "sha512-yOwiiPJ1rk+/nfK13eafbpW6sKW0jOnsRem2C1LPJjM3tfTof6hlvV5eWHATye3XOpu2cJ7N+HdkUvUDGwFD2Q=="
"integrity": "sha512-yOwiiPJ1rk+/nfK13eafbpW6sKW0jOnsRem2C1LPJjM3tfTof6hlvV5eWHATye3XOpu2cJ7N+HdkUvUDGwFD2Q==",
"requires": {}
},
"react-native-screens": {
"version": "3.10.2",
@@ -45553,7 +45640,8 @@
"react-native-size-matters": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/react-native-size-matters/-/react-native-size-matters-0.3.1.tgz",
"integrity": "sha512-mKOfBLIBFBcs9br1rlZDvxD5+mAl8Gfr5CounwJtxI6Z82rGrMO+Kgl9EIg3RMVf3G855a85YVqHJL2f5EDRlw=="
"integrity": "sha512-mKOfBLIBFBcs9br1rlZDvxD5+mAl8Gfr5CounwJtxI6Z82rGrMO+Kgl9EIg3RMVf3G855a85YVqHJL2f5EDRlw==",
"requires": {}
},
"react-native-svg": {
"version": "12.1.1",
@@ -45633,7 +45721,8 @@
"react-universal-interface": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz",
"integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw=="
"integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==",
"requires": {}
},
"react-use": {
"version": "17.4.0",
@@ -48296,8 +48385,7 @@
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"tsutils": {
"version": "3.21.0",
@@ -48661,7 +48749,8 @@
"use-isomorphic-layout-effect": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA=="
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
"requires": {}
},
"use-latest-callback": {
"version": "0.1.5",
@@ -48671,12 +48760,14 @@
"use-subscription": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.6.0.tgz",
"integrity": "sha512-0Y/cTLlZfw547tJhJMoRA16OUbVqRm6DmvGpiGbmLST6BIA5KU5cKlvlz8DVMrACnWpyEjCkgmhLatthP4jUbA=="
"integrity": "sha512-0Y/cTLlZfw547tJhJMoRA16OUbVqRm6DmvGpiGbmLST6BIA5KU5cKlvlz8DVMrACnWpyEjCkgmhLatthP4jUbA==",
"requires": {}
},
"use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA=="
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"requires": {}
},
"utf8": {
"version": "3.0.0",

View File

@@ -56,6 +56,7 @@
"react-native": "0.64.4",
"react-native-animated-pagination-dot": "^0.4.0",
"react-native-app-intro-slider": "^4.0.4",
"react-native-argon2": "^2.0.1",
"react-native-biometrics-changed": "^1.1.8",
"react-native-bluetooth-state-manager": "^1.3.2",
"react-native-cli": "^2.0.1",

View File

@@ -7,11 +7,18 @@ import { Column, Text } from '../components/ui';
import { Theme } from '../components/ui/styleUtils';
import { PasscodeRouteProps } from '../routes';
import { usePasscodeScreen } from './PasscodeScreenController';
import { hashData } from '../shared/commonUtil';
import { argon2iConfig } from '../shared/constants';
export const PasscodeScreen: React.FC<PasscodeRouteProps> = (props) => {
const { t } = useTranslation('PasscodeScreen');
const controller = usePasscodeScreen(props);
const setPasscode = async (passcode: string) => {
const data = await hashData(passcode, controller.storedSalt, argon2iConfig);
controller.setPasscode(data);
};
const passcodeSetup =
controller.passcode === '' ? (
<React.Fragment>
@@ -28,7 +35,7 @@ export const PasscodeScreen: React.FC<PasscodeRouteProps> = (props) => {
</Text>
</Column>
<PinInput length={MAX_PIN} onDone={controller.setPasscode} />
<PinInput length={MAX_PIN} onDone={setPasscode} />
</React.Fragment>
) : (
<React.Fragment>
@@ -48,6 +55,7 @@ export const PasscodeScreen: React.FC<PasscodeRouteProps> = (props) => {
onSuccess={controller.SETUP_PASSCODE}
onError={controller.setError}
passcode={controller.passcode}
salt={controller.storedSalt}
/>
</React.Fragment>
);
@@ -75,6 +83,7 @@ export const PasscodeScreen: React.FC<PasscodeRouteProps> = (props) => {
onSuccess={controller.LOGIN}
onError={controller.setError}
passcode={controller.storedPasscode}
salt={controller.storedSalt}
/>
</Column>
)}

View File

@@ -1,6 +1,11 @@
import { useSelector } from '@xstate/react';
import { useContext, useEffect, useState } from 'react';
import { AuthEvents, selectAuthorized, selectPasscode } from '../machines/auth';
import {
AuthEvents,
selectAuthorized,
selectPasscode,
selectPasscodeSalt,
} from '../machines/auth';
import { PasscodeRouteProps } from '../routes';
import { GlobalContext } from '../shared/GlobalContext';
@@ -37,5 +42,7 @@ export function usePasscodeScreen(props: PasscodeRouteProps) {
SETUP_PASSCODE: () => {
authService.send(AuthEvents.SETUP_PASSCODE(passcode));
},
storedSalt: useSelector(authService, selectPasscodeSalt),
};
}

19
shared/commonUtil.ts Normal file
View File

@@ -0,0 +1,19 @@
import argon2 from 'react-native-argon2';
export const hashData = async (
data: string,
salt: string,
config: Argon2iConfig
): Promise<string> => {
const result = await argon2(data, salt, config);
console.log('argon--result', result);
return result.rawHash as string;
};
export interface Argon2iConfig {
iterations: number;
memory: number;
parallelism: number;
hashLength: number;
mode: String;
}

View File

@@ -4,6 +4,7 @@ import {
MIMOTO_HOST,
GOOGLE_NEARBY_MESSAGES_API_KEY,
} from 'react-native-dotenv';
import { Argon2iConfig } from './commonUtil';
export let HOST = MIMOTO_HOST;
@@ -59,3 +60,12 @@ export const APP_ID_DICTIONARY = [
export function isIOS(): boolean {
return Platform.OS === 'ios';
}
// Configuration for argon2i hashing algorithm
export const argon2iConfig: Argon2iConfig = {
iterations: 5,
memory: 16 * 1024,
parallelism: 2,
hashLength: 20,
mode: 'argon2i',
};