add remember login

This commit is contained in:
Michele Balistreri 2024-10-04 10:19:50 +02:00
parent b7b559a16a
commit 42892185ff
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
2 changed files with 61 additions and 18 deletions

View File

@ -121,6 +121,7 @@ const Main = () => {
//fallthrough //fallthrough
case Step.Authentication: case Step.Authentication:
walletKey.current = await Keycard.exportKeyWithPath(pinRef.current, WALLET_DERIVATION_PATH); walletKey.current = await Keycard.exportKeyWithPath(pinRef.current, WALLET_DERIVATION_PATH);
await AsyncStorage.setItem("wallet-key", walletKey.current);
setStep(Step.Home); setStep(Step.Home);
break; break;
case Step.Home: case Step.Home:
@ -169,7 +170,7 @@ const Main = () => {
body: loginReq, body: loginReq,
}); });
const respJson = resp.json(); const respJson = await resp.json();
if (respJson['error']) { if (respJson['error']) {
//TODO: handle error //TODO: handle error
} }
@ -193,11 +194,17 @@ const Main = () => {
if (!didMount.current) { if (!didMount.current) {
didMount.current = true; didMount.current = true;
const loadPairing = async () => { const loadData = async () => {
await Keycard.setPairings(await getPairings()); await Keycard.setPairings(await getPairings());
const tmp = await AsyncStorage.getItem("wallet-key");
walletKey.current = tmp !== null ? tmp : "";
if (walletKey.current) {
setStep(Step.Home);
}
}; };
loadPairing().catch(console.log); loadData().catch(console.log);
} }
return () => { return () => {
@ -244,13 +251,19 @@ const Main = () => {
return true; return true;
} }
const login = (sessionId: string, challenge: string) => { const login = (sessionId: string, challenge: string, p?: string) => {
if (p) {
pinRef.current = p;
}
sessionRef.current = sessionId; sessionRef.current = sessionId;
challengeRef.current = challenge; challengeRef.current = challenge;
return connectCard(); return connectCard();
} }
const cancel = () => { const cancel = () => {
walletKey.current = "";
AsyncStorage.removeItem("wallet-key");
setStep(Step.Discovery); setStep(Step.Discovery);
} }
@ -269,7 +282,7 @@ const Main = () => {
{step == Step.Initialization && <InitializationScreen onPressFunc={initPin} onCancelFunc={cancel}></InitializationScreen>} {step == Step.Initialization && <InitializationScreen onPressFunc={initPin} onCancelFunc={cancel}></InitializationScreen>}
{step == Step.Loading && <MnemonicScreen pinRequired={pinRef.current ? false : true} pinRetryCounter={pinDisplayCounter()} onPressFunc={loadMnemonic} onCancelFunc={cancel}></MnemonicScreen>} {step == Step.Loading && <MnemonicScreen pinRequired={pinRef.current ? false : true} pinRetryCounter={pinDisplayCounter()} onPressFunc={loadMnemonic} onCancelFunc={cancel}></MnemonicScreen>}
{step == Step.Authentication && <Dialpad pinRetryCounter={pinDisplayCounter()} prompt={"Choose PIN"} onCancelFunc={cancel} onNextFunc={authenticate}></Dialpad>} {step == Step.Authentication && <Dialpad pinRetryCounter={pinDisplayCounter()} prompt={"Choose PIN"} onCancelFunc={cancel} onNextFunc={authenticate}></Dialpad>}
{step == Step.Home && <HomeScreen walletKey={walletKey.current} onPressFunc={login} onCancelFunc={cancel}></HomeScreen>} {step == Step.Home && <HomeScreen pinRequired={pinRef.current ? false : true} pinRetryCounter={pinDisplayCounter()} walletKey={walletKey.current} onPressFunc={login} onCancelFunc={cancel}></HomeScreen>}
{step == Step.FactoryReset && <FactoryResetScreen pinRetryCounter={pinDisplayCounter()} onPressFunc={connectCard} onCancelFunc={cancel}></FactoryResetScreen>} {step == Step.FactoryReset && <FactoryResetScreen pinRetryCounter={pinDisplayCounter()} onPressFunc={connectCard} onCancelFunc={cancel}></FactoryResetScreen>}
<NFCModal isVisible={isModalVisible} onChangeFunc={stopNFC}></NFCModal> <NFCModal isVisible={isModalVisible} onChangeFunc={stopNFC}></NFCModal>
</SafeAreaView> </SafeAreaView>

View File

@ -1,30 +1,38 @@
import {FC, useEffect, useState } from "react"; import {FC, useEffect, useRef, useState } from "react";
import { SafeAreaView, StyleSheet, Text, View } from "react-native"; import { SafeAreaView, StyleSheet, Text, View } from "react-native";
import Button from "../Button"; import Button from "../Button";
import { Camera, useCameraDevice, useCameraPermission, useCodeScanner } from "react-native-vision-camera"; import { Camera, useCameraDevice, useCameraPermission, useCodeScanner } from "react-native-vision-camera";
import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; import { hexToBytes } from "@noble/hashes/utils";
import { bech32 } from "bech32"; import { bech32 } from "bech32";
import { ripemd160 } from "@noble/hashes/ripemd160"; import { ripemd160 } from "@noble/hashes/ripemd160";
import { sha256 } from "@noble/hashes/sha256"; import { sha256 } from "@noble/hashes/sha256";
import ReceiveModal from "../../ReceiveModal"; import ReceiveModal from "../../ReceiveModal";
import Dialpad from "../Dialpad";
enum HomeSteps { enum HomeSteps {
Home, Home,
ScanCode ScanCode,
InsertPin
} }
type HomeScreenProps = { type HomeScreenProps = {
pinRequired: boolean;
pinRetryCounter: number;
walletKey: string; walletKey: string;
onPressFunc: (sessionId: string, challenge: string) => void; onPressFunc: (sessionId: string, challenge: string, p?: string) => void;
onCancelFunc: () => void; onCancelFunc: () => void;
}; };
const HomeScreen: FC<HomeScreenProps> = props => { const HomeScreen: FC<HomeScreenProps> = props => {
const {walletKey, onPressFunc, onCancelFunc} = props; const {pinRequired, pinRetryCounter, walletKey, onPressFunc, onCancelFunc} = props;
const [step, setStep] = useState(HomeSteps.Home); const [step, setStep] = useState(HomeSteps.Home);
const [receiveVisible, setReceiveVisible] = useState(false) const [receiveVisible, setReceiveVisible] = useState(false)
const challengeRef = useRef("");
const sessionRef = useRef("");
const cameraDevice = useCameraDevice('back'); const cameraDevice = useCameraDevice('back');
const {hasPermission, requestPermission} = useCameraPermission(); const {hasPermission, requestPermission} = useCameraPermission();
const codeScanner = useCodeScanner({ const codeScanner = useCodeScanner({
codeTypes: ['qr'], codeTypes: ['qr'],
onCodeScanned: (codes) => { onCodeScanned: (codes) => {
@ -39,12 +47,24 @@ const HomeScreen: FC<HomeScreenProps> = props => {
return; return;
} }
setStep(HomeSteps.Home); challengeRef.current = payload["challenge"];
onPressFunc(payload["session-id"], payload["challenge"]); sessionRef.current = payload["session-id"];
if (pinRequired) {
setStep(HomeSteps.InsertPin);
} else {
onPressFunc(sessionRef.current, challengeRef.current)
setStep(HomeSteps.Home);
}
} catch(e) {} } catch(e) {}
} }
}); });
const submitPin = (p: string) => {
onPressFunc(sessionRef.current, challengeRef.current, p);
return true;
}
const walletAddress = () => { const walletAddress = () => {
var pubkey = hexToBytes(walletKey); var pubkey = hexToBytes(walletKey);
if (pubkey[0] == 0x04 && (pubkey.length == 65)) { if (pubkey[0] == 0x04 && (pubkey.length == 65)) {
@ -68,19 +88,29 @@ const HomeScreen: FC<HomeScreenProps> = props => {
} }
}); });
if (step == HomeSteps.Home) { return <View style={styles.container}>
return <SafeAreaView> {step == HomeSteps.Home &&
<View>
<Button label="Scan" disabled={false} btnColor="#199515" btnBorderColor="#199515" btnFontSize={17} btnBorderWidth={1} btnWidth="100%" onChangeFunc={() => setStep(HomeSteps.ScanCode)} btnJustifyContent='center'></Button> <Button label="Scan" disabled={false} btnColor="#199515" btnBorderColor="#199515" btnFontSize={17} btnBorderWidth={1} btnWidth="100%" onChangeFunc={() => setStep(HomeSteps.ScanCode)} btnJustifyContent='center'></Button>
<Button label="Receive" disabled={false} btnColor="#199515" btnBorderColor="#199515" btnFontSize={17} btnBorderWidth={1} btnWidth="100%" onChangeFunc={() => setReceiveVisible(true)} btnJustifyContent='center'></Button> <Button label="Receive" disabled={false} btnColor="#199515" btnBorderColor="#199515" btnFontSize={17} btnBorderWidth={1} btnWidth="100%" onChangeFunc={() => setReceiveVisible(true)} btnJustifyContent='center'></Button>
<Button label="Cancel" disabled={false} btnColor="#199515" btnBorderColor="#199515" btnFontSize={17} btnBorderWidth={1} btnWidth="100%" onChangeFunc={onCancelFunc} btnJustifyContent='center'></Button> <Button label="Cancel" disabled={false} btnColor="#199515" btnBorderColor="#199515" btnFontSize={17} btnBorderWidth={1} btnWidth="100%" onChangeFunc={onCancelFunc} btnJustifyContent='center'></Button>
<ReceiveModal address={walletAddress()} isVisible={receiveVisible} onChangeFunc={() => {setReceiveVisible(false)} } /> <ReceiveModal address={walletAddress()} isVisible={receiveVisible} onChangeFunc={() => {setReceiveVisible(false)} } />
</SafeAreaView> </View>
} else if (step == HomeSteps.ScanCode) { }
return <Camera style={StyleSheet.absoluteFill} device={cameraDevice!} isActive={true} codeScanner={codeScanner}/> {step == HomeSteps.ScanCode &&
} <View style={styles.container}>
<Camera style={StyleSheet.absoluteFill} device={cameraDevice!} isActive={true} codeScanner={codeScanner}/>
</View>
}
{step == HomeSteps.InsertPin && <Dialpad pinRetryCounter={pinRetryCounter} prompt={"Enter PIN"} onCancelFunc={() => setStep(HomeSteps.Home)} onNextFunc={submitPin}></Dialpad>}
</View>
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'black',
},
heading: { heading: {
textAlign: 'center', textAlign: 'center',
fontSize: 30, fontSize: 30,