mirror of
https://github.com/selfxyz/self.git
synced 2026-01-15 01:28:18 -05:00
generating and storing secret, storing passport data securely
This commit is contained in:
@@ -1,18 +1,20 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import "react-native-get-random-values"
|
||||
import "@ethersproject/shims"
|
||||
import MainScreen from './src/screens/MainScreen';
|
||||
import { Buffer } from 'buffer';
|
||||
import { YStack } from 'tamagui';
|
||||
import { useToastController } from '@tamagui/toast';
|
||||
import { downloadZkey } from './src/utils/zkeyDownload';
|
||||
import useNavigationStore from './src/stores/navigationStore';
|
||||
import { AMPLITUDE_KEY } from '@env';
|
||||
import * as amplitude from '@amplitude/analytics-react-native';
|
||||
import useUserStore from './src/stores/userStore';
|
||||
global.Buffer = Buffer;
|
||||
|
||||
function App(): JSX.Element {
|
||||
const toast = useToastController();
|
||||
const setToast = useNavigationStore((state) => state.setToast);
|
||||
const initUserStore = useUserStore((state) => state.initUserStore);
|
||||
|
||||
useEffect(() => {
|
||||
setToast(toast);
|
||||
@@ -20,10 +22,7 @@ function App(): JSX.Element {
|
||||
|
||||
useEffect(() => {
|
||||
amplitude.init(AMPLITUDE_KEY);
|
||||
|
||||
// downloadZkey("register_sha256WithRSAEncryption_65537"); // might move after nfc scanning
|
||||
// downloadZkey("disclose");
|
||||
downloadZkey("proof_of_passport");
|
||||
initUserStore();
|
||||
}, []);
|
||||
|
||||
// TODO: when passportData already stored, retrieve and jump to main screen
|
||||
|
||||
@@ -291,6 +291,8 @@ PODS:
|
||||
- React-jsinspector (0.72.3)
|
||||
- React-logger (0.72.3):
|
||||
- glog
|
||||
- react-native-get-random-values (1.11.0):
|
||||
- React-Core
|
||||
- react-native-netinfo (11.3.1):
|
||||
- React-Core
|
||||
- React-NativeModulesApple (0.72.3):
|
||||
@@ -398,12 +400,12 @@ PODS:
|
||||
- React-jsi (= 0.72.3)
|
||||
- React-logger (= 0.72.3)
|
||||
- React-perflogger (= 0.72.3)
|
||||
- RNCAsyncStorage (1.23.1):
|
||||
- React-Core
|
||||
- RNCClipboard (1.5.1):
|
||||
- React-Core
|
||||
- RNFS (2.20.0):
|
||||
- React-Core
|
||||
- RNKeychain (8.2.0):
|
||||
- React-Core
|
||||
- RNSVG (13.4.0):
|
||||
- React-Core
|
||||
- RNZipArchive (6.1.0):
|
||||
@@ -443,6 +445,7 @@ DEPENDENCIES:
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- react-native-get-random-values (from `../node_modules/react-native-get-random-values`)
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
|
||||
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||
@@ -461,9 +464,9 @@ DEPENDENCIES:
|
||||
- React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
|
||||
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
||||
- "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)"
|
||||
- RNFS (from `../node_modules/react-native-fs`)
|
||||
- RNKeychain (from `../node_modules/react-native-keychain`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
- RNZipArchive (from `../node_modules/react-native-zip-archive`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
@@ -524,6 +527,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
React-logger:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
react-native-get-random-values:
|
||||
:path: "../node_modules/react-native-get-random-values"
|
||||
react-native-netinfo:
|
||||
:path: "../node_modules/@react-native-community/netinfo"
|
||||
React-NativeModulesApple:
|
||||
@@ -560,12 +565,12 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/utils"
|
||||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||
RNCClipboard:
|
||||
:path: "../node_modules/@react-native-community/clipboard"
|
||||
RNFS:
|
||||
:path: "../node_modules/react-native-fs"
|
||||
RNKeychain:
|
||||
:path: "../node_modules/react-native-keychain"
|
||||
RNSVG:
|
||||
:path: "../node_modules/react-native-svg"
|
||||
RNZipArchive:
|
||||
@@ -605,6 +610,7 @@ SPEC CHECKSUMS:
|
||||
React-jsiexecutor: 2c15ba1bace70177492368d5180b564f165870fd
|
||||
React-jsinspector: b511447170f561157547bc0bef3f169663860be7
|
||||
React-logger: c5b527272d5f22eaa09bb3c3a690fee8f237ae95
|
||||
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
|
||||
react-native-netinfo: bdb108d340cdb41875c9ced535977cac6d2ff321
|
||||
React-NativeModulesApple: 0438665fc7473be6edc496e823e6ea0b0537b46c
|
||||
React-perflogger: 6bd153e776e6beed54c56b0847e1220a3ff92ba5
|
||||
@@ -623,9 +629,9 @@ SPEC CHECKSUMS:
|
||||
React-runtimescheduler: ec1066a4f2d1152eb1bc3fb61d69376b3bc0dde0
|
||||
React-utils: d55ba834beb39f01b0b470ae43478c0a3a024abe
|
||||
ReactCommon: 68e3a815fbb69af3bb4196e04c6ae7abb306e7a8
|
||||
RNCAsyncStorage: 826b603ae9c0f88b5ac4e956801f755109fa4d5c
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
|
||||
RNKeychain: bfe3d12bf4620fe488771c414530bf16e88f3678
|
||||
RNSVG: 07dbd870b0dcdecc99b3a202fa37c8ca163caec2
|
||||
RNZipArchive: ef9451b849c45a29509bf44e65b788829ab07801
|
||||
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
<key>NFCReaderUsageDescription</key>
|
||||
<string>Need NFC to read Passport</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict/>
|
||||
<string></string>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>Needed to secure the secret</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Needed to scan your passport MRZ, you can however enter it manually.</string>
|
||||
<string>Needed to scan the passport MRZ.</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
"@amplitude/analytics-react-native": "^1.4.7",
|
||||
"@babel/plugin-transform-private-methods": "^7.23.3",
|
||||
"@ethersproject/shims": "^5.7.0",
|
||||
"@react-native-async-storage/async-storage": "^1.23.1",
|
||||
"@react-native-community/clipboard": "^1.5.1",
|
||||
"@react-native-community/netinfo": "^11.3.1",
|
||||
"@tamagui/colors": "^1.94.3",
|
||||
@@ -40,6 +39,8 @@
|
||||
"react-native": "0.72.3",
|
||||
"react-native-canvas": "^0.1.39",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-keychain": "^8.2.0",
|
||||
"react-native-passport-reader": "^1.0.3",
|
||||
"react-native-svg": "13.4.0",
|
||||
"react-native-zip-archive": "^6.1.0",
|
||||
|
||||
@@ -128,17 +128,8 @@ export const sbtApp: AppType = {
|
||||
{ developmentMode: false }
|
||||
);
|
||||
|
||||
// remove that when it's only disclosure proof
|
||||
amplitude.track(`Sig alg supported: ${passportData.signatureAlgorithm}`);
|
||||
|
||||
Object.keys(inputs).forEach((key) => {
|
||||
if (Array.isArray(inputs[key as keyof typeof inputs])) {
|
||||
console.log(key, inputs[key as keyof typeof inputs].slice(0, 10), '...');
|
||||
} else {
|
||||
console.log(key, inputs[key as keyof typeof inputs]);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('inputs:', inputs);
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
const proof = await generateProof(
|
||||
|
||||
@@ -31,7 +31,9 @@ const MainScreen: React.FC = () => {
|
||||
dateOfBirth,
|
||||
dateOfExpiry,
|
||||
deleteMrzFields,
|
||||
update
|
||||
update,
|
||||
clearPassportDataFromStorage,
|
||||
clearSecretFromStorage,
|
||||
} = useUserStore()
|
||||
|
||||
const {
|
||||
@@ -73,6 +75,7 @@ const MainScreen: React.FC = () => {
|
||||
scan();
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (passportNumber?.length === 9 && (dateOfBirth?.length === 6 && dateOfExpiry?.length === 6)) {
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
@@ -251,6 +254,25 @@ const MainScreen: React.FC = () => {
|
||||
<VenetianMask color={textColor1} />
|
||||
</Button>
|
||||
</Fieldset>
|
||||
|
||||
<Fieldset gap="$4" mt="$1" horizontal>
|
||||
<Label color={textColor1} width={200} justifyContent="flex-end" htmlFor="skip" >
|
||||
Delete passport data
|
||||
</Label>
|
||||
<Button bg={componentBgColor} jc="center" borderColor={borderColor} borderWidth={1.2} size="$3.5" ml="$2" onPress={clearPassportDataFromStorage}>
|
||||
<VenetianMask color={textColor1} />
|
||||
</Button>
|
||||
</Fieldset>
|
||||
|
||||
<Fieldset gap="$4" mt="$1" horizontal>
|
||||
<Label color={textColor1} width={200} justifyContent="flex-end" htmlFor="skip" >
|
||||
Delete secret (caution)
|
||||
</Label>
|
||||
<Button bg={componentBgColor} jc="center" borderColor={borderColor} borderWidth={1.2} size="$3.5" ml="$2" onPress={clearSecretFromStorage}>
|
||||
<VenetianMask color={textColor1} />
|
||||
</Button>
|
||||
</Fieldset>
|
||||
|
||||
<YStack flex={1} />
|
||||
|
||||
<YStack mb="$0">
|
||||
|
||||
@@ -40,7 +40,12 @@ const ProveScreen: React.FC = () => {
|
||||
majority,
|
||||
disclosure,
|
||||
update
|
||||
} = useAppStore() ;
|
||||
} = useAppStore();
|
||||
|
||||
const {
|
||||
registered,
|
||||
passportData,
|
||||
} = useUserStore();
|
||||
|
||||
const handleDisclosureChange = (field: string) => {
|
||||
const requiredOrOptional = selectedApp.disclosureOptions[field as keyof typeof selectedApp.disclosureOptions];
|
||||
@@ -58,7 +63,6 @@ const ProveScreen: React.FC = () => {
|
||||
};
|
||||
|
||||
const { height } = useWindowDimensions();
|
||||
const passportData = useUserStore(state => state.passportData);
|
||||
|
||||
useEffect(() => {
|
||||
// this already checks if downloading is required
|
||||
@@ -210,7 +214,14 @@ const ProveScreen: React.FC = () => {
|
||||
backgroundColor={address == ethers.ZeroAddress ? "#cecece" : "#3185FC"}
|
||||
alignSelf='center'
|
||||
>
|
||||
{isZkeyDownloading[selectedApp.circuit] ? (
|
||||
{!registered ? (
|
||||
<XStack ai="center" gap="$1">
|
||||
<Spinner />
|
||||
<Text color={textColor1} fow="bold">
|
||||
Registering identity...
|
||||
</Text>
|
||||
</XStack>
|
||||
) : isZkeyDownloading[selectedApp.circuit] ? (
|
||||
<XStack ai="center" gap="$1">
|
||||
<Spinner />
|
||||
<Text color={textColor1} fow="bold">
|
||||
|
||||
@@ -6,12 +6,25 @@ import {
|
||||
} from '@env';
|
||||
import { mockPassportData_sha256WithRSAEncryption_65537 } from '../../../common/src/utils/mockPassportData';
|
||||
import { PassportData } from '../../../common/src/utils/types';
|
||||
import * as Keychain from 'react-native-keychain';
|
||||
import * as amplitude from '@amplitude/analytics-react-native';
|
||||
import useNavigationStore from './navigationStore';
|
||||
import { Steps } from '../utils/utils';
|
||||
import { ethers } from 'ethers';
|
||||
import { downloadZkey } from '../utils/zkeyDownload';
|
||||
|
||||
interface UserState {
|
||||
passportNumber: string
|
||||
dateOfBirth: string
|
||||
dateOfExpiry: string
|
||||
registered: boolean
|
||||
passportData: PassportData
|
||||
secret: string
|
||||
initUserStore: () => void
|
||||
registerPassportData: (passportData: PassportData) => void
|
||||
registerCommitment: (secret: string, passportData: PassportData) => void
|
||||
clearPassportDataFromStorage: () => void
|
||||
clearSecretFromStorage: () => void
|
||||
update: (patch: any) => void
|
||||
deleteMrzFields: () => void
|
||||
}
|
||||
@@ -21,7 +34,138 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
dateOfBirth: DEFAULT_DOB ?? "",
|
||||
dateOfExpiry: DEFAULT_DOE ?? "",
|
||||
|
||||
registered: false,
|
||||
passportData: mockPassportData_sha256WithRSAEncryption_65537,
|
||||
secret: "",
|
||||
|
||||
// When user opens the app, checks presence of passportData
|
||||
// - If passportData is not present, starts the onboarding flow
|
||||
// - If passportData is present, then secret must be here too (they are always set together). Request the tree.
|
||||
// - If the commitment is present in the tree, proceed to main screen
|
||||
// - If the commitment is not present in the tree, proceed to main screen AND try registering it in the background
|
||||
initUserStore: async () => {
|
||||
const passportDataCreds = await Keychain.getGenericPassword({ service: "passportData" });
|
||||
if (!passportDataCreds) {
|
||||
console.log("No passport data found, starting onboarding flow")
|
||||
return;
|
||||
}
|
||||
const secretCreds = await Keychain.getGenericPassword({ service: "secret" })
|
||||
|
||||
const secret = (secretCreds as Keychain.UserCredentials).password
|
||||
|
||||
set({
|
||||
passportData: JSON.parse(passportDataCreds.password),
|
||||
secret,
|
||||
});
|
||||
useNavigationStore.getState().setStep(Steps.NFC_SCAN_COMPLETED); // this currently means go to app selection screen
|
||||
|
||||
// download zkeys if they are not already downloaded
|
||||
// downloadZkey("register_sha256WithRSAEncryption_65537"); // might move after nfc scanning
|
||||
// downloadZkey("disclose");
|
||||
downloadZkey("proof_of_passport");
|
||||
|
||||
// TODO: check if the commitment is already registered, if not retry registering it
|
||||
|
||||
// set({
|
||||
// registered: true,
|
||||
// });
|
||||
},
|
||||
|
||||
// When reading passport for the first time:
|
||||
// - Check presence of secret. If there is none, create one and store it
|
||||
// - Store the passportData and try registering the commitment in the background
|
||||
registerPassportData: async (passportData) => {
|
||||
const secretCreds = await Keychain.getGenericPassword({ service: "secret" });
|
||||
|
||||
if (secretCreds && secretCreds.password) {
|
||||
// This should only ever happen if the user deletes the passport data in the options
|
||||
console.log("secret is already registered, let's keep it.")
|
||||
} else {
|
||||
const randomWallet = ethers.Wallet.createRandom();
|
||||
const secret = randomWallet.privateKey;
|
||||
await Keychain.setGenericPassword("secret", secret, { service: "secret" });
|
||||
}
|
||||
|
||||
const newSecretCreds = await Keychain.getGenericPassword({ service: "secret" })
|
||||
const secret = (newSecretCreds as Keychain.UserCredentials).password
|
||||
|
||||
const passportDataCreds = await Keychain.getGenericPassword({ service: "passportData" });
|
||||
|
||||
if (passportDataCreds && passportDataCreds.password) {
|
||||
throw new Error("passportData is already registered, this should never happen")
|
||||
}
|
||||
|
||||
await Keychain.setGenericPassword("passportData", JSON.stringify(passportData), { service: "passportData" });
|
||||
|
||||
get().registerCommitment(
|
||||
secret,
|
||||
passportData
|
||||
)
|
||||
|
||||
set({
|
||||
passportData,
|
||||
secret
|
||||
});
|
||||
},
|
||||
|
||||
registerCommitment: async (secret, passportData) => {
|
||||
// just like in handleProve, generate inputs and launch commitment registration
|
||||
const {
|
||||
toast
|
||||
} = useNavigationStore.getState();
|
||||
|
||||
try {
|
||||
// const inputs = generateCircuitInputsRegister(
|
||||
// passportData,
|
||||
// secret,
|
||||
// { developmentMode: false }
|
||||
// );
|
||||
|
||||
// amplitude.track(`Sig alg supported: ${passportData.signatureAlgorithm}`);
|
||||
|
||||
// Object.keys(inputs).forEach((key) => {
|
||||
// if (Array.isArray(inputs[key as keyof typeof inputs])) {
|
||||
// console.log(key, inputs[key as keyof typeof inputs].slice(0, 10), '...');
|
||||
// } else {
|
||||
// console.log(key, inputs[key as keyof typeof inputs]);
|
||||
// }
|
||||
// });
|
||||
|
||||
// const start = Date.now();
|
||||
|
||||
// const proof = await generateProof(
|
||||
// `Register_${passportData.signatureAlgorithm}`, // TODO format it
|
||||
// inputs,
|
||||
// );
|
||||
|
||||
// const end = Date.now();
|
||||
// console.log('Total proof time from frontend:', end - start);
|
||||
// amplitude.track('Proof generation successful, took ' + ((end - start) / 1000) + ' seconds');
|
||||
|
||||
// // TODO send the proof to the relayer
|
||||
|
||||
// set({
|
||||
// registered: true,
|
||||
// });
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast?.show('Error', {
|
||||
message: "Error registering your identity, please relaunch the app",
|
||||
customData: {
|
||||
type: "error",
|
||||
},
|
||||
})
|
||||
amplitude.track(error.message);
|
||||
}
|
||||
},
|
||||
|
||||
clearPassportDataFromStorage: async () => {
|
||||
await Keychain.resetGenericPassword({ service: "passportData" });
|
||||
},
|
||||
|
||||
clearSecretFromStorage: async () => {
|
||||
await Keychain.resetGenericPassword({ service: "secret" });
|
||||
},
|
||||
|
||||
update: (patch) => {
|
||||
set({
|
||||
|
||||
@@ -40,32 +40,34 @@ export const scan = async () => {
|
||||
setStep(Steps.NFC_SCANNING);
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
scanAndroid(setStep, toast);
|
||||
scanAndroid();
|
||||
} else {
|
||||
scanIOS(setStep, toast);
|
||||
scanIOS();
|
||||
}
|
||||
};
|
||||
|
||||
const scanAndroid = async (
|
||||
setStep: (value: number) => void,
|
||||
toast: any
|
||||
) => {
|
||||
const userState = useUserStore.getState()
|
||||
const scanAndroid = async () => {
|
||||
const {
|
||||
passportNumber,
|
||||
dateOfBirth,
|
||||
dateOfExpiry
|
||||
} = useUserStore.getState()
|
||||
const {toast, setStep} = useNavigationStore.getState();
|
||||
|
||||
try {
|
||||
const response = await PassportReader.scan({
|
||||
documentNumber: userState.passportNumber,
|
||||
dateOfBirth: userState.dateOfBirth,
|
||||
dateOfExpiry: userState.dateOfExpiry
|
||||
documentNumber: passportNumber,
|
||||
dateOfBirth: dateOfBirth,
|
||||
dateOfExpiry: dateOfExpiry
|
||||
});
|
||||
console.log('scanned');
|
||||
amplitude.track('NFC scan successful');
|
||||
handleResponseAndroid(response, setStep);
|
||||
handleResponseAndroid(response);
|
||||
} catch (e: any) {
|
||||
console.log('error during scan:', e);
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
amplitude.track('NFC scan unsuccessful', { error: JSON.stringify(e) });
|
||||
toast.show('Error', {
|
||||
toast?.show('Error', {
|
||||
message: e.message,
|
||||
customData: {
|
||||
type: "error",
|
||||
@@ -75,27 +77,29 @@ const scanAndroid = async (
|
||||
}
|
||||
};
|
||||
|
||||
const scanIOS = async (
|
||||
setStep: (value: number) => void,
|
||||
toast: any
|
||||
) => {
|
||||
const userState = useUserStore.getState()
|
||||
const scanIOS = async () => {
|
||||
const {
|
||||
passportNumber,
|
||||
dateOfBirth,
|
||||
dateOfExpiry
|
||||
} = useUserStore.getState()
|
||||
const {toast, setStep} = useNavigationStore.getState();
|
||||
|
||||
try {
|
||||
const response = await NativeModules.PassportReader.scanPassport(
|
||||
userState.passportNumber,
|
||||
userState.dateOfBirth,
|
||||
userState.dateOfExpiry
|
||||
passportNumber,
|
||||
dateOfBirth,
|
||||
dateOfExpiry
|
||||
);
|
||||
console.log('scanned');
|
||||
handleResponseIOS(response, setStep);
|
||||
handleResponseIOS(response);
|
||||
amplitude.track('NFC scan successful');
|
||||
} catch (e: any) {
|
||||
console.log('error during scan:', e);
|
||||
setStep(Steps.MRZ_SCAN_COMPLETED);
|
||||
amplitude.track(`NFC scan unsuccessful, error ${e.message}`);
|
||||
if (!e.message.includes("UserCanceled")) {
|
||||
toast.show('Failed to read passport', {
|
||||
toast?.show('Failed to read passport', {
|
||||
message: e.message,
|
||||
customData: {
|
||||
type: "error",
|
||||
@@ -107,7 +111,6 @@ const scanIOS = async (
|
||||
|
||||
const handleResponseIOS = async (
|
||||
response: any,
|
||||
setStep: (value: number) => void,
|
||||
) => {
|
||||
const parsed = JSON.parse(response);
|
||||
|
||||
@@ -164,15 +167,12 @@ const handleResponseIOS = async (
|
||||
|
||||
// console.log('passportData', JSON.stringify(passportData, null, 2));
|
||||
|
||||
useUserStore.setState({
|
||||
passportData
|
||||
})
|
||||
setStep(Steps.NFC_SCAN_COMPLETED);
|
||||
useUserStore.getState().registerPassportData(passportData)
|
||||
useNavigationStore.getState().setStep(Steps.NFC_SCAN_COMPLETED);
|
||||
};
|
||||
|
||||
const handleResponseAndroid = async (
|
||||
response: any,
|
||||
setStep: (value: number) => void,
|
||||
) => {
|
||||
const {
|
||||
mrz,
|
||||
@@ -221,9 +221,6 @@ const handleResponseAndroid = async (
|
||||
console.log("unicodeVersion", unicodeVersion)
|
||||
console.log("encapContent", encapContent)
|
||||
|
||||
useUserStore.setState({
|
||||
passportData
|
||||
})
|
||||
|
||||
setStep(Steps.NFC_SCAN_COMPLETED);
|
||||
useUserStore.getState().registerPassportData(passportData)
|
||||
useNavigationStore.getState().setStep(Steps.NFC_SCAN_COMPLETED);
|
||||
};
|
||||
@@ -1702,7 +1702,7 @@
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@react-native-async-storage/async-storage@^1.17.11", "@react-native-async-storage/async-storage@^1.23.1":
|
||||
"@react-native-async-storage/async-storage@^1.17.11":
|
||||
version "1.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.23.1.tgz#cad3cd4fab7dacfe9838dce6ecb352f79150c883"
|
||||
integrity sha512-Qd2kQ3yi6Y3+AcUlrHxSLlnBvpdCEMVGFlVBneVOjaFaPU61g1huc38g339ysXspwY1QZA2aNhrk/KlHGO+ewA==
|
||||
@@ -4817,6 +4817,11 @@ express@^4.18.2:
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
fast-base64-decode@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418"
|
||||
integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==
|
||||
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
@@ -7597,6 +7602,18 @@ react-native-fs@^2.20.0:
|
||||
base-64 "^0.1.0"
|
||||
utf8 "^3.0.0"
|
||||
|
||||
react-native-get-random-values@^1.11.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-get-random-values/-/react-native-get-random-values-1.11.0.tgz#1ca70d1271f4b08af92958803b89dccbda78728d"
|
||||
integrity sha512-4BTbDbRmS7iPdhYLRcz3PGFIpFJBwNZg9g42iwa2P6FOv9vZj/xJc678RZXnLNZzd0qd7Q3CCF6Yd+CU2eoXKQ==
|
||||
dependencies:
|
||||
fast-base64-decode "^1.0.0"
|
||||
|
||||
react-native-keychain@^8.2.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-8.2.0.tgz#aea82df37aacbb04f8b567a8e0e6d7292025610a"
|
||||
integrity sha512-SkRtd9McIl1Ss2XSWNLorG+KMEbgeVqX+gV+t3u1EAAqT8q2/OpRmRbxpneT2vnb/dMhiU7g6K/pf3nxLUXRvA==
|
||||
|
||||
react-native-passport-reader@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/react-native-passport-reader/-/react-native-passport-reader-1.0.3.tgz#3242bbdb3c1ade4c050a8632cca6f11fe0edc648"
|
||||
|
||||
Reference in New Issue
Block a user