From 7e0e6b5eca75ac5e9bad0f08cd0f9233f167ed32 Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Mon, 16 Jun 2025 16:18:20 +0500 Subject: [PATCH 01/12] initial commit of ui --- src/screens/AppSettings/PrivacyAndDisplay.tsx | 127 +++++++++++------- 1 file changed, 82 insertions(+), 45 deletions(-) diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index 25d847d2a..de6779875 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -38,6 +38,7 @@ import { resetCredsChanged } from 'src/store/reducers/login'; import Buttons from 'src/components/Buttons'; import WalletHeader from 'src/components/WalletHeader'; import usePlan from 'src/hooks/usePlan'; +import SettingCard from '../Home/components/Settings/Component/SettingCard'; const RNBiometrics = new ReactNativeBiometrics(); @@ -294,55 +295,83 @@ function PrivacyAndDisplay({ route }) { setSensorAvailable(false); } }; + const PrivacyAndDisplay = [ + { + title: sensorType || settings.Biometrics, + description: sensorType + ? formatString(settings.UseBiometricSubTitle, sensorType) + : settings.NoBiometricSubTitle, + onPress: onChangeLoginMethod, + disabled: !sensorType, + rightIcon: + sensorAvailable || !sensorType ? ( + + ) : ( + + + + {common.Enable} {sensorType} + + + + ), + }, + ]; return ( - - - - - onChangeLoginMethod()} - disabled={!sensorType} - Icon={ - sensorAvailable || !sensorType ? ( - - ) : ( - - - - {common.Enable} {sensorType} - - - - ) - } - /> - - + + + {/* { - setVisiblePassCode(true); - }} + title={sensorType || settings.Biometrics} + description={ + sensorType + ? formatString(settings.UseBiometricSubTitle, sensorType) + : settings.NoBiometricSubTitle + } + callback={() => onChangeLoginMethod()} + disabled={!sensorType} + Icon={ + sensorAvailable || !sensorType ? ( + + ) : ( + + + + {common.Enable} {sensorType} + + + + ) + } /> - - + */} + + + { + setVisiblePassCode(true); + }} + /> + Date: Tue, 17 Jun 2025 10:22:48 +0500 Subject: [PATCH 02/12] access screen ui --- src/assets/images/biometric-image.svg | 14 +++++++++ src/assets/images/password-ico.svg | 13 +++++++++ src/assets/images/pin-icon.svg | 5 ++++ src/screens/AppSettings/PrivacyAndDisplay.tsx | 29 +++++++++++++------ .../Settings/Component/SettingCard.tsx | 15 ++++++---- 5 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 src/assets/images/biometric-image.svg create mode 100644 src/assets/images/password-ico.svg create mode 100644 src/assets/images/pin-icon.svg diff --git a/src/assets/images/biometric-image.svg b/src/assets/images/biometric-image.svg new file mode 100644 index 000000000..f608622c6 --- /dev/null +++ b/src/assets/images/biometric-image.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/assets/images/password-ico.svg b/src/assets/images/password-ico.svg new file mode 100644 index 000000000..035444214 --- /dev/null +++ b/src/assets/images/password-ico.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/assets/images/pin-icon.svg b/src/assets/images/pin-icon.svg new file mode 100644 index 000000000..fca778f41 --- /dev/null +++ b/src/assets/images/pin-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index de6779875..485a72570 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -39,6 +39,9 @@ import Buttons from 'src/components/Buttons'; import WalletHeader from 'src/components/WalletHeader'; import usePlan from 'src/hooks/usePlan'; import SettingCard from '../Home/components/Settings/Component/SettingCard'; +import BiometricIcon from 'src/assets/images/biometric-image.svg'; +import PasswordIcon from 'src/assets/images/password-ico.svg'; +import PinIcon from 'src/assets/images/pin-icon.svg'; const RNBiometrics = new ReactNativeBiometrics(); @@ -295,14 +298,30 @@ function PrivacyAndDisplay({ route }) { setSensorAvailable(false); } }; + const PrivacyAndDisplay = [ + { + title: 'PIN', + description: 'Current Screen Lock', + onPress: () => setVisiblePassCode(true), + icon: , + }, + { + title: 'Password', + description: 'Enter 4 or more digits/letters', + onPress: () => setVisiblePassCode(true), + icon: , + }, { title: sensorType || settings.Biometrics, description: sensorType ? formatString(settings.UseBiometricSubTitle, sensorType) : settings.NoBiometricSubTitle, onPress: onChangeLoginMethod, - disabled: !sensorType, + isDisabled: !sensorType, + icon: , + onRightPress: sensorAvailable || !sensorType ? onChangeLoginMethod : requestPermission, + rightIcon: sensorAvailable || !sensorType ? ( - - { - setVisiblePassCode(true); - }} - /> void; onRightPress?: () => void; + isDisabled?: boolean; } interface SettingCardProps { @@ -64,11 +65,14 @@ const SettingCard: React.FC = ({ borderColor={borderColor} > {items.map((item, index) => { - const applyDiamondCheck = item?.isHodler - ? isOnL2Above - : item?.isDiamond - ? isOnL3Above - : true; + const applyDiamondCheck = + item?.isDisabled !== undefined + ? !item.isDisabled + : item?.isHodler + ? isOnL2Above + : item?.isDiamond + ? isOnL3Above + : true; return ( @@ -121,6 +125,7 @@ const SettingCard: React.FC = ({ {item.rightIcon} From ffd6b548fdb08048294a6a79de7500eabcceed01 Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Tue, 17 Jun 2025 11:03:32 +0500 Subject: [PATCH 03/12] test --- src/screens/AppSettings/PrivacyAndDisplay.tsx | 33 ++----------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index 485a72570..37185eae7 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -194,6 +194,7 @@ function PrivacyAndDisplay({ route }) { const [sensorType, setSensorType] = useState(null); const [sensorAvailable, setSensorAvailable] = useState(false); const [visiblePasscode, setVisiblePassCode] = useState(false); + const [visiblePassword, setVisiblePassword] = useState(false); const [showConfirmSeedModal, setShowConfirmSeedModal] = useState(false); const [confirmPasscode, setConfirmPasscode] = useState(false); const [oldPassword, setOldPassword] = useState(''); @@ -309,7 +310,7 @@ function PrivacyAndDisplay({ route }) { { title: 'Password', description: 'Enter 4 or more digits/letters', - onPress: () => setVisiblePassCode(true), + onPress: () => setVisiblePassword(true), icon: , }, { @@ -346,36 +347,6 @@ function PrivacyAndDisplay({ route }) { - {/* - onChangeLoginMethod()} - disabled={!sensorType} - Icon={ - sensorAvailable || !sensorType ? ( - - ) : ( - - - - {common.Enable} {sensorType} - - - - ) - } - /> - */} Date: Wed, 18 Jun 2025 16:34:31 +0500 Subject: [PATCH 04/12] password functionality --- src/components/Modal/PasscodeVerify.tsx | 4 + src/models/enums/LoginMethod.ts | 1 + .../AppSettings/CreatePasswordContent.tsx | 99 +++++++++++ .../AppSettings/PasswordModalContent.tsx | 97 +++++++++++ src/screens/AppSettings/PrivacyAndDisplay.tsx | 100 +++++++++-- src/screens/LoginScreen/Login.tsx | 162 +++++++++++++----- src/screens/SeedScreens/ExportSeedScreen.tsx | 9 +- src/store/sagas/login.ts | 14 +- 8 files changed, 423 insertions(+), 63 deletions(-) create mode 100644 src/screens/AppSettings/CreatePasswordContent.tsx create mode 100644 src/screens/AppSettings/PasswordModalContent.tsx diff --git a/src/components/Modal/PasscodeVerify.tsx b/src/components/Modal/PasscodeVerify.tsx index 93d523648..b637cbf02 100644 --- a/src/components/Modal/PasscodeVerify.tsx +++ b/src/components/Modal/PasscodeVerify.tsx @@ -48,6 +48,10 @@ function PasscodeVerifyModal({ const { loginMethod } = useAppSelector((state) => state.settings); const { appId, failedAttempts, lastLoginFailedAt } = useAppSelector((state) => state.storage); + console.log('isAuthenticated', isAuthenticated); + console.log('authenticationFailed', authenticationFailed); + console.log('loginError', loginError); + useEffect(() => { if (useBiometrics) { if (processing) return; diff --git a/src/models/enums/LoginMethod.ts b/src/models/enums/LoginMethod.ts index cafce6405..2c89d61b4 100644 --- a/src/models/enums/LoginMethod.ts +++ b/src/models/enums/LoginMethod.ts @@ -1,5 +1,6 @@ enum LoginMethod { PIN = 'PIN', BIOMETRIC = 'BIOMETRIC', + PASSWORD = 'PASSWORD', } export default LoginMethod; diff --git a/src/screens/AppSettings/CreatePasswordContent.tsx b/src/screens/AppSettings/CreatePasswordContent.tsx new file mode 100644 index 000000000..2b533792f --- /dev/null +++ b/src/screens/AppSettings/CreatePasswordContent.tsx @@ -0,0 +1,99 @@ +import { Box, useColorMode } from 'native-base'; +import React, { useContext, useEffect, useState } from 'react'; +import { StyleSheet } from 'react-native'; +import { useDispatch } from 'react-redux'; +import Buttons from 'src/components/Buttons'; +import Text from 'src/components/KeeperText'; +import KeeperTextInput from 'src/components/KeeperTextInput'; +import { hp } from 'src/constants/responsive'; +import { LocalizationContext } from 'src/context/Localization/LocContext'; +import LoginMethod from 'src/models/enums/LoginMethod'; +import { changeAuthCred, changeLoginMethod } from 'src/store/sagaActions/login'; + +interface Props { + close?: () => void; + onSuccess?: () => void; + oldPassword?: string; +} + +const CreatePasswordContent = ({ close, onSuccess, oldPassword }: Props) => { + const { colorMode } = useColorMode(); + const { translations } = useContext(LocalizationContext); + const { common } = translations; + const dispatch = useDispatch(); + + const [password, setPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [error, setError] = useState(''); + + const handleContinue = () => { + if (!password || !confirmPassword) { + setError('Please fill out both fields'); + } else if (password !== confirmPassword) { + setError('Passwords do not match'); + } else { + setError(''); + dispatch(changeAuthCred(oldPassword, password)); + dispatch(changeLoginMethod(LoginMethod.PASSWORD)); + onSuccess(); + close(); + } + }; + + return ( + + + + {!!error && ( + + {error} + + )} + + + + + ); +}; + +export default CreatePasswordContent; + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: hp(-10), + }, + btnsContainer: { + marginTop: hp(20), + }, + errorText: { + textAlign: 'right', + fontStyle: 'italic', + marginRight: 10, + marginTop: 8, + }, +}); diff --git a/src/screens/AppSettings/PasswordModalContent.tsx b/src/screens/AppSettings/PasswordModalContent.tsx new file mode 100644 index 000000000..cd2a9f15b --- /dev/null +++ b/src/screens/AppSettings/PasswordModalContent.tsx @@ -0,0 +1,97 @@ +import { Box, useColorMode } from 'native-base'; +import React, { useContext, useEffect, useState } from 'react'; +import { StyleSheet } from 'react-native'; +import Buttons from 'src/components/Buttons'; +import Text from 'src/components/KeeperText'; +import KeeperTextInput from 'src/components/KeeperTextInput'; +import { hp } from 'src/constants/responsive'; +import { LocalizationContext } from 'src/context/Localization/LocContext'; +import LoginMethod from 'src/models/enums/LoginMethod'; +import { useAppDispatch, useAppSelector } from 'src/store/hooks'; +import { credsAuth } from 'src/store/sagaActions/login'; +import { credsAuthenticated } from 'src/store/reducers/login'; + +interface Props { + close?: Function; + onSuccess?: Function; +} +const PasswordModalContent = ({ close, onSuccess }: Props) => { + const { colorMode } = useColorMode(); + const dispatch = useAppDispatch(); + const { translations } = useContext(LocalizationContext); + const { common } = translations; + const [password, setPassword] = useState(''); + const [loginError, setLoginError] = useState(false); + const [errMessage, setErrMessage] = useState(''); + + const { isAuthenticated, authenticationFailed } = useAppSelector((state) => state.login); + + const attemptLogin = (passcode: string) => { + dispatch(credsAuth(passcode, LoginMethod.PASSWORD, true)); + }; + + useEffect(() => { + if (isAuthenticated) { + onSuccess(password); + close(); + dispatch(credsAuthenticated(false)); + } + }, [isAuthenticated]); + useEffect(() => { + if (authenticationFailed && password !== '') { + setLoginError(true); + setErrMessage('Incorrect password'); + dispatch(credsAuthenticated(false)); + } else { + setLoginError(false); + setErrMessage(''); + } + }, [authenticationFailed]); + return ( + + setPassword(text.toLowerCase())} + inpuBorderColor={`${colorMode}.separator`} + inpuBackgroundColor={`${colorMode}.boxSecondaryBackground`} + /> + {loginError && ( + + {errMessage} + + )} + + { + attemptLogin(password); + }} + primaryText={common.continue} + secondaryText={common.cancel} + secondaryCallback={() => { + close(); + }} + /> + + + ); +}; + +export default PasswordModalContent; + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: hp(-10), + }, + btnsContainer: { + marginTop: hp(20), + }, + errorText: { + textAlign: 'right', + fontStyle: 'italic', + marginRight: 10, + }, +}); diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index 37185eae7..ad2f8e853 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -1,8 +1,7 @@ import React, { useContext, useEffect, useState } from 'react'; -import { Box, ScrollView, useColorMode } from 'native-base'; +import { Box, useColorMode } from 'native-base'; import ReactNativeBiometrics from 'react-native-biometrics'; import ScreenWrapper from 'src/components/ScreenWrapper'; -import OptionCard from 'src/components/OptionCard'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import Switch from 'src/components/Switch/Switch'; import { useAppDispatch, useAppSelector } from 'src/store/hooks'; @@ -42,10 +41,17 @@ import SettingCard from '../Home/components/Settings/Component/SettingCard'; import BiometricIcon from 'src/assets/images/biometric-image.svg'; import PasswordIcon from 'src/assets/images/password-ico.svg'; import PinIcon from 'src/assets/images/pin-icon.svg'; +import PasswordModalContent from './PasswordModalContent'; +import CreatePasswordContent from './CreatePasswordContent'; const RNBiometrics = new ReactNativeBiometrics(); -function ConfirmPasscode({ oldPassword, setConfirmPasscodeModal, onCredsChange }) { +function ConfirmPasscode({ + oldPassword, + setConfirmPasscodeModal, + onCredsChange, + setShowSetPasscodeModal, +}) { const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); @@ -160,6 +166,8 @@ function ConfirmPasscode({ oldPassword, setConfirmPasscodeModal, onCredsChange } primaryText={common.confirm} primaryCallback={() => { dispatch(changeAuthCred(oldPassword, passcode)); + dispatch(changeLoginMethod(LoginMethod.PIN)); + setShowSetPasscodeModal(false); }} fullWidth /> @@ -201,6 +209,8 @@ function PrivacyAndDisplay({ route }) { const [backupModalVisible, setBackupModalVisible] = useState(false); const [RKHealthCheckModal, setRKHealthCheckModal] = useState(false); const [passcodeHCModal, setPasscodeHCModal] = useState(false); + const [showSetPasscodeModal, setShowSetPasscodeModal] = useState(false); + const [createPasswordModal, setCreatePasswordModal] = useState(false); const { translations, formatString } = useContext(LocalizationContext); const { settings, common, error: errorText } = translations; @@ -225,10 +235,15 @@ function PrivacyAndDisplay({ route }) { useEffect(() => { init(); }, []); + console.log('route?.params', route?.params); useEffect(() => { if (RKBackedUp) { - setConfirmPasscode(true); + if (showSetPasscodeModal) { + setConfirmPasscode(true); + } else { + setCreatePasswordModal(true); + } setOldPassword(oldPasscode); } }, [route?.params]); @@ -266,6 +281,8 @@ function PrivacyAndDisplay({ route }) { console.log(error); } }; + console.log('loginMethod', loginMethod); + console.log('showSetPasscodeModal', showSetPasscodeModal); const requestPermission = () => { Linking.openSettings(); @@ -275,7 +292,7 @@ function PrivacyAndDisplay({ route }) { try { const { available } = await RNBiometrics.isSensorAvailable(); if (available) { - if (loginMethod === LoginMethod.PIN) { + if (loginMethod === LoginMethod.PIN || loginMethod === LoginMethod.PASSWORD) { const { keysExist } = await RNBiometrics.biometricKeysExist(); if (keysExist) { await RNBiometrics.deleteKeys(); @@ -288,7 +305,7 @@ function PrivacyAndDisplay({ route }) { dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey)); } } else { - dispatch(changeLoginMethod(LoginMethod.PIN)); + dispatch(changeLoginMethod(LoginMethod.PIN || LoginMethod.PASSWORD)); } } else { setSensorAvailable(false); @@ -304,13 +321,28 @@ function PrivacyAndDisplay({ route }) { { title: 'PIN', description: 'Current Screen Lock', - onPress: () => setVisiblePassCode(true), + onPress: () => { + if (loginMethod === LoginMethod.PIN) { + setVisiblePassCode(true); + } else { + setVisiblePassword(true); + } + setShowSetPasscodeModal(true); + }, icon: , }, { title: 'Password', description: 'Enter 4 or more digits/letters', - onPress: () => setVisiblePassword(true), + onPress: () => { + if (loginMethod === LoginMethod.PASSWORD) { + setVisiblePassword(true); + setShowSetPasscodeModal(false); + } else { + setVisiblePassCode(true); + setShowSetPasscodeModal(false); + } + }, icon: , }, { @@ -389,6 +421,29 @@ function PrivacyAndDisplay({ route }) { /> )} /> + setVisiblePassword(false)} + title="Set password" + subTitle="Enter your existing password" + modalBackground={`${colorMode}.modalWhiteBackground`} + textColor={`${colorMode}.textGreen`} + subTitleColor={`${colorMode}.modalSubtitleBlack`} + Content={() => ( + setVisiblePassword(false)} + onSuccess={(password) => { + if (data.length === 0) { + setRKHealthCheckModal(true); + setOldPassword(password); + } else { + setOldPassword(password); + setPasscodeHCModal(true); + } + }} + /> + )} + /> setPasscodeHCModal(false)} @@ -431,7 +486,11 @@ function PrivacyAndDisplay({ route }) { if (backupMethod === BackupType.SEED) { setShowConfirmSeedModal(false); dispatch(seedBackedConfirmed(true)); - setConfirmPasscode(true); + if (showSetPasscodeModal) { + setConfirmPasscode(true); + } else { + setCreatePasswordModal(true); + } } }} /> @@ -451,6 +510,7 @@ function PrivacyAndDisplay({ route }) { setConfirmPasscodeModal={setConfirmPasscode} oldPassword={oldPassword} onCredsChange={() => setCredsChanged('changed')} + setShowSetPasscodeModal={setShowSetPasscodeModal} /> )} /> @@ -499,11 +559,28 @@ function PrivacyAndDisplay({ route }) { next: true, parentScreen: PRIVACYANDDISPLAY, oldPasscode: oldPassword, + showSetPasscodeModal: showSetPasscodeModal, }) ); }} Content={BackupModalContent} /> + setCreatePasswordModal(false)} + title="Set Password" + subTitle="Enter Your new Password" + modalBackground={`${colorMode}.primaryBackground`} + subTitleColor={`${colorMode}.secondaryText`} + textColor={`${colorMode}.modalGreenTitle`} + Content={() => ( + setCreatePasswordModal(false)} + onSuccess={() => setCredsChanged('changed')} + oldPassword={oldPassword} + /> + )} + /> ); } @@ -511,11 +588,6 @@ const styles = StyleSheet.create({ wrapper: { marginTop: hp(35), gap: 50, - // alignSelf: 'center', - // borderWidth: 1, - // borderRadius: 10, - // padding: 20, - // width: '95%', }, container: { width: '95%', diff --git a/src/screens/LoginScreen/Login.tsx b/src/screens/LoginScreen/Login.tsx index df2dee348..8787fc8e4 100644 --- a/src/screens/LoginScreen/Login.tsx +++ b/src/screens/LoginScreen/Login.tsx @@ -52,6 +52,7 @@ import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import CampaignModalIllustration from 'src/assets/images/CampaignModalIllustration.svg'; import { uaiType } from 'src/models/interfaces/Uai'; import { addToUaiStack, uaiChecks } from 'src/store/sagaActions/uai'; +import KeeperTextInput from 'src/components/KeeperTextInput'; const RNBiometrics = new ReactNativeBiometrics(); @@ -105,6 +106,7 @@ function LoginScreen({ navigation, route }) { const onChangeTorStatus = (status: TorStatus) => { settorStatus(status); }; + console.log('loginScreen method', loginMethod); async function requestUserPermission() { const authStatus = await messaging().requestPermission(); @@ -303,8 +305,11 @@ function LoginScreen({ navigation, route }) { const attemptLogin = (passcode: string) => { setLoginModal(true); - - dispatch(credsAuth(passcode, LoginMethod.PIN, relogin)); + if (loginMethod === LoginMethod.PIN) { + dispatch(credsAuth(passcode, LoginMethod.PIN, relogin)); + } else if (loginMethod === LoginMethod.PASSWORD) { + dispatch(credsAuth(passcode, LoginMethod.PASSWORD, relogin)); + } }; const modelAsset = useMemo(() => { @@ -469,55 +474,102 @@ function LoginScreen({ navigation, route }) { - - - {isTestnet() && } - - {relogin ? title : login.welcomeback} - + {loginMethod === LoginMethod.PIN ? ( + - - - {login.enter_your} - {login.passcode} - - + + {isTestnet() && } + + + {relogin ? title : login.welcomeback} + + + + + {login.enter_your} + {login.passcode} + + + + + + {loginError && ( + + {errMessage} + + )} - - {loginError && ( - - {errMessage} - - )} + } + bubbleEffect + keyColor={login_text_color} + /> + + { + setLoginError(false); + setLogging(true); + }} + primaryText={common.proceed} + primaryDisable={passcode.length !== 4} + primaryBackgroundColor={login_button_backGround} + primaryTextColor={login_button_text_color} + fullWidth + /> - } - bubbleEffect - keyColor={login_text_color} - /> - - { - setLoginError(false); - setLogging(true); - }} - primaryText={common.proceed} - primaryDisable={passcode.length !== 4} - primaryBackgroundColor={login_button_backGround} - primaryTextColor={login_button_text_color} - fullWidth - /> + ) : ( + + + + {isTestnet() && } + + + {relogin ? title : login.welcomeback} + + + + Unlock the app with your password + + + + + {loginError && ( + + {errMessage} + + )} + + { + setLoginError(false); + setLogging(true); + }} + primaryText={common.proceed} + primaryBackgroundColor={login_button_backGround} + primaryTextColor={login_button_text_color} + fullWidth + /> + - + )} { @@ -654,6 +710,12 @@ const styles = StyleSheet.create({ textAlign: 'center', marginTop: 18, }, + passwordError: { + fontStyle: 'italic', + fontSize: 12, + textAlign: 'right', + marginBottom: 10, + }, forgotPassWrapper: { flex: 0.8, margin: 20, @@ -713,6 +775,14 @@ const styles = StyleSheet.create({ marginTop: hp(45), gap: hp(15), }, + passwordWrapper: { + justifyContent: 'center', + marginTop: hp(120), + paddingHorizontal: wp(15), + }, + passwordInput: { + marginTop: hp(10), + }, }); export default LoginScreen; diff --git a/src/screens/SeedScreens/ExportSeedScreen.tsx b/src/screens/SeedScreens/ExportSeedScreen.tsx index 1c4ca9ac7..65cd34fe4 100644 --- a/src/screens/SeedScreens/ExportSeedScreen.tsx +++ b/src/screens/SeedScreens/ExportSeedScreen.tsx @@ -54,6 +54,7 @@ function ExportSeedScreen({ route, navigation }) { parentScreen, oldPasscode, isFromMobileKey = false, + showSetPasscodeModal, }: { vaultKey: string; vaultId: string; @@ -68,6 +69,7 @@ function ExportSeedScreen({ route, navigation }) { parentScreen?: string; oldPasscode?: string; isFromMobileKey: boolean; + showSetPasscodeModal: boolean; } = route.params; const { showToast } = useToastMessage(); const [words, setWords] = useState(seed.split(' ')); @@ -301,7 +303,12 @@ function ExportSeedScreen({ route, navigation }) { dismissible={false} close={ isChangePassword - ? () => navigation.navigate('PrivacyAndDisplay', { RKBackedUp: true, oldPasscode }) + ? () => + navigation.navigate('PrivacyAndDisplay', { + RKBackedUp: true, + oldPasscode, + showSetPasscodeModal, + }) : () => {} } title={BackupWallet.backupSuccessTitle} diff --git a/src/store/sagas/login.ts b/src/store/sagas/login.ts index dfd5a901e..db7fea791 100644 --- a/src/store/sagas/login.ts +++ b/src/store/sagas/login.ts @@ -149,7 +149,7 @@ function* credentialsAuthWorker({ payload }) { yield put(setupLoading('authenticating')); let hash; let encryptedKey; - if (method === LoginMethod.PIN) { + if (method === LoginMethod.PIN || method === LoginMethod.PASSWORD) { hash = yield call(hash512, payload.passcode); if (payload.reLogin) encryptedKey = yield call(SecureStore.fetchSpecific, hash, appId); else encryptedKey = yield call(SecureStore.fetch, hash); @@ -273,6 +273,7 @@ function* credentialsAuthWorker({ payload }) { RealmSchema.KeeperApp ); if (updatedSubs.level > 2) yield put(setAllCampaigns(true)); + console.log('method', method); const { pendingAllBackup, automaticCloudBackup } = yield select( (state: RootState) => state.bhr @@ -297,8 +298,17 @@ function* credentialsAuthWorker({ payload }) { } yield put(loadConciergeUserOnLogin({ appId: keeperApp.id })); yield put( + // setLoginMethod( + // keeperApp.id === biometricEnabledAppId + // ? LoginMethod.BIOMETRIC + // : LoginMethod.PIN || LoginMethod.PASSWORD + // ) setLoginMethod( - keeperApp.id === biometricEnabledAppId ? LoginMethod.BIOMETRIC : LoginMethod.PIN + keeperApp.id === biometricEnabledAppId + ? LoginMethod.BIOMETRIC + : method === LoginMethod.PIN + ? LoginMethod.PIN + : LoginMethod.PASSWORD ) ); if (backupMethodByAppId[keeperApp.id]) From a7ae428c9c14fbe6208d2869689649127311fbe5 Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Fri, 20 Jun 2025 16:26:37 +0500 Subject: [PATCH 05/12] hide password --- src/screens/AppSettings/PasswordModalContent.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/screens/AppSettings/PasswordModalContent.tsx b/src/screens/AppSettings/PasswordModalContent.tsx index cd2a9f15b..ed1841444 100644 --- a/src/screens/AppSettings/PasswordModalContent.tsx +++ b/src/screens/AppSettings/PasswordModalContent.tsx @@ -53,6 +53,7 @@ const PasswordModalContent = ({ close, onSuccess }: Props) => { placeholder={''} value={password} autoCorrect={false} + secureTextEntry autoComplete="off" onChangeText={(text) => setPassword(text.toLowerCase())} inpuBorderColor={`${colorMode}.separator`} From 1f93d74026cc26738050b34ad8107010d5f93d9a Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Tue, 24 Jun 2025 10:47:18 +0500 Subject: [PATCH 06/12] login method --- .../AppSettings/CreatePasswordContent.tsx | 18 ++++- .../AppSettings/PasswordModalContent.tsx | 7 +- src/screens/AppSettings/PrivacyAndDisplay.tsx | 76 ++++++++++++++++--- src/screens/LoginScreen/Login.tsx | 16 +++- src/store/reducers/settings.ts | 6 ++ src/store/sagaActions/login.ts | 7 +- src/store/sagas/login.ts | 14 +++- 7 files changed, 123 insertions(+), 21 deletions(-) diff --git a/src/screens/AppSettings/CreatePasswordContent.tsx b/src/screens/AppSettings/CreatePasswordContent.tsx index 2b533792f..3c0399053 100644 --- a/src/screens/AppSettings/CreatePasswordContent.tsx +++ b/src/screens/AppSettings/CreatePasswordContent.tsx @@ -1,5 +1,5 @@ import { Box, useColorMode } from 'native-base'; -import React, { useContext, useEffect, useState } from 'react'; +import React, { useContext, useState } from 'react'; import { StyleSheet } from 'react-native'; import { useDispatch } from 'react-redux'; import Buttons from 'src/components/Buttons'; @@ -8,15 +8,22 @@ import KeeperTextInput from 'src/components/KeeperTextInput'; import { hp } from 'src/constants/responsive'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import LoginMethod from 'src/models/enums/LoginMethod'; +import { useAppSelector } from 'src/store/hooks'; import { changeAuthCred, changeLoginMethod } from 'src/store/sagaActions/login'; interface Props { close?: () => void; onSuccess?: () => void; oldPassword?: string; + updateBiometricAfterPasscodeChange?: () => void; } -const CreatePasswordContent = ({ close, onSuccess, oldPassword }: Props) => { +const CreatePasswordContent = ({ + close, + onSuccess, + oldPassword, + updateBiometricAfterPasscodeChange, +}: Props) => { const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); const { common } = translations; @@ -25,6 +32,7 @@ const CreatePasswordContent = ({ close, onSuccess, oldPassword }: Props) => { const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [error, setError] = useState(''); + const { loginMethod }: { loginMethod: LoginMethod } = useAppSelector((state) => state.settings); const handleContinue = () => { if (!password || !confirmPassword) { @@ -34,7 +42,11 @@ const CreatePasswordContent = ({ close, onSuccess, oldPassword }: Props) => { } else { setError(''); dispatch(changeAuthCred(oldPassword, password)); - dispatch(changeLoginMethod(LoginMethod.PASSWORD)); + if (loginMethod === LoginMethod.BIOMETRIC) { + updateBiometricAfterPasscodeChange(); + } else { + dispatch(changeLoginMethod(LoginMethod.PASSWORD)); + } onSuccess(); close(); } diff --git a/src/screens/AppSettings/PasswordModalContent.tsx b/src/screens/AppSettings/PasswordModalContent.tsx index ed1841444..4e3f6d8d7 100644 --- a/src/screens/AppSettings/PasswordModalContent.tsx +++ b/src/screens/AppSettings/PasswordModalContent.tsx @@ -14,8 +14,9 @@ import { credsAuthenticated } from 'src/store/reducers/login'; interface Props { close?: Function; onSuccess?: Function; + oldPassword?: any; } -const PasswordModalContent = ({ close, onSuccess }: Props) => { +const PasswordModalContent = ({ close, onSuccess, oldPassword }: Props) => { const { colorMode } = useColorMode(); const dispatch = useAppDispatch(); const { translations } = useContext(LocalizationContext); @@ -24,6 +25,8 @@ const PasswordModalContent = ({ close, onSuccess }: Props) => { const [loginError, setLoginError] = useState(false); const [errMessage, setErrMessage] = useState(''); + console.log('passwordauth', password); + const { isAuthenticated, authenticationFailed } = useAppSelector((state) => state.login); const attemptLogin = (passcode: string) => { @@ -55,7 +58,7 @@ const PasswordModalContent = ({ close, onSuccess }: Props) => { autoCorrect={false} secureTextEntry autoComplete="off" - onChangeText={(text) => setPassword(text.toLowerCase())} + onChangeText={(text) => setPassword(text)} inpuBorderColor={`${colorMode}.separator`} inpuBackgroundColor={`${colorMode}.boxSecondaryBackground`} /> diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index ad2f8e853..9331135c0 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -9,7 +9,7 @@ import LoginMethod from 'src/models/enums/LoginMethod'; import { changeAuthCred, changeLoginMethod } from 'src/store/sagaActions/login'; import ToastErrorIcon from 'src/assets/images/toast_error.svg'; import useToastMessage from 'src/hooks/useToastMessage'; -import { setThemeMode } from 'src/store/reducers/settings'; +import { setFallbackLoginMethod, setThemeMode } from 'src/store/reducers/settings'; import ThemeMode from 'src/models/enums/ThemeMode'; import { Linking, StyleSheet, TouchableOpacity } from 'react-native'; import { hp, wp } from 'src/constants/responsive'; @@ -43,6 +43,7 @@ import PasswordIcon from 'src/assets/images/password-ico.svg'; import PinIcon from 'src/assets/images/pin-icon.svg'; import PasswordModalContent from './PasswordModalContent'; import CreatePasswordContent from './CreatePasswordContent'; +import { useSelector } from 'react-redux'; const RNBiometrics = new ReactNativeBiometrics(); @@ -51,6 +52,7 @@ function ConfirmPasscode({ setConfirmPasscodeModal, onCredsChange, setShowSetPasscodeModal, + updateBiometricAfterPasscodeChange, }) { const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); @@ -62,6 +64,9 @@ function ConfirmPasscode({ const [passcodeFlag, setPasscodeFlag] = useState(true); const [confirmPasscodeFlag, setConfirmPasscodeFlag] = useState(0); const { credsChanged } = useAppSelector((state) => state.login); + const { loginMethod }: { loginMethod: LoginMethod } = useAppSelector((state) => state.settings); + + console.log('loginMethod in pin ', loginMethod); useEffect(() => { if (credsChanged === 'changed') { @@ -166,7 +171,12 @@ function ConfirmPasscode({ primaryText={common.confirm} primaryCallback={() => { dispatch(changeAuthCred(oldPassword, passcode)); - dispatch(changeLoginMethod(LoginMethod.PIN)); + if (loginMethod === LoginMethod.BIOMETRIC) { + // dispatch(setFallbackLoginMethod(LoginMethod.PIN)); + updateBiometricAfterPasscodeChange(); + } else { + dispatch(changeLoginMethod(LoginMethod.PIN)); + } setShowSetPasscodeModal(false); }} fullWidth @@ -223,6 +233,8 @@ function PrivacyAndDisplay({ route }) { const app: KeeperApp = useQuery(RealmSchema.KeeperApp).map(getJSONFromRealmObject)[0]; const [credsChanged, setCredsChanged] = useState(''); const { isOnL4 } = usePlan(); + const fallbackLoginMethod = useSelector((state) => state.settings.fallbackLoginMethod); + console.log('fallbackLoginMethod', fallbackLoginMethod); useEffect(() => { if (credsChanged === 'changed') { @@ -235,7 +247,6 @@ function PrivacyAndDisplay({ route }) { useEffect(() => { init(); }, []); - console.log('route?.params', route?.params); useEffect(() => { if (RKBackedUp) { @@ -282,7 +293,6 @@ function PrivacyAndDisplay({ route }) { } }; console.log('loginMethod', loginMethod); - console.log('showSetPasscodeModal', showSetPasscodeModal); const requestPermission = () => { Linking.openSettings(); @@ -302,10 +312,10 @@ function PrivacyAndDisplay({ route }) { }); if (success) { const { publicKey } = await RNBiometrics.createKeys(); - dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey)); + dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey, loginMethod)); } - } else { - dispatch(changeLoginMethod(LoginMethod.PIN || LoginMethod.PASSWORD)); + } else if (loginMethod === LoginMethod.BIOMETRIC) { + dispatch(changeLoginMethod(fallbackLoginMethod || LoginMethod.PIN)); } } else { setSensorAvailable(false); @@ -317,12 +327,53 @@ function PrivacyAndDisplay({ route }) { } }; + const updateBiometricAfterPasscodeChange = async () => { + try { + const { available } = await RNBiometrics.isSensorAvailable(); + + if (!available) { + setSensorAvailable(false); + showToast(errorText.biometricNotEnabled, ); + return; + } + const { keysExist } = await RNBiometrics.biometricKeysExist(); + const { success } = await RNBiometrics.simplePrompt({ + promptMessage: errorText.confirmIdentity, + }); + + if (!success) { + showToast('Failed to update biometric authentication.', ); + if (fallbackLoginMethod === 'PIN') { + dispatch(changeLoginMethod(LoginMethod.PIN)); + } else if (fallbackLoginMethod === 'PASSWORD') { + dispatch(changeLoginMethod(LoginMethod.PASSWORD)); + } + return; + } + if (keysExist) { + await RNBiometrics.deleteKeys(); + } + const { publicKey } = await RNBiometrics.createKeys(); + + dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey, fallbackLoginMethod)); + showToast('Biometric updated successfully'); + } catch (error) { + console.log('Biometric update failed:', error); + showToast('Failed to update biometric authentication.', ); + setSensorAvailable(false); + } + }; + console.log('loginMethod', loginMethod); + const PrivacyAndDisplay = [ { title: 'PIN', description: 'Current Screen Lock', onPress: () => { - if (loginMethod === LoginMethod.PIN) { + if ( + loginMethod === LoginMethod.PIN || + (loginMethod === LoginMethod.BIOMETRIC && fallbackLoginMethod === 'PIN') + ) { setVisiblePassCode(true); } else { setVisiblePassword(true); @@ -335,7 +386,10 @@ function PrivacyAndDisplay({ route }) { title: 'Password', description: 'Enter 4 or more digits/letters', onPress: () => { - if (loginMethod === LoginMethod.PASSWORD) { + if ( + loginMethod === LoginMethod.PASSWORD || + (loginMethod === LoginMethod.BIOMETRIC && fallbackLoginMethod === 'PASSWORD') + ) { setVisiblePassword(true); setShowSetPasscodeModal(false); } else { @@ -374,6 +428,7 @@ function PrivacyAndDisplay({ route }) { ), }, ]; + console.log('showSetPasscodeModal', showSetPasscodeModal); return ( @@ -431,6 +486,7 @@ function PrivacyAndDisplay({ route }) { subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( setVisiblePassword(false)} onSuccess={(password) => { if (data.length === 0) { @@ -511,6 +567,7 @@ function PrivacyAndDisplay({ route }) { oldPassword={oldPassword} onCredsChange={() => setCredsChanged('changed')} setShowSetPasscodeModal={setShowSetPasscodeModal} + updateBiometricAfterPasscodeChange={updateBiometricAfterPasscodeChange} /> )} /> @@ -578,6 +635,7 @@ function PrivacyAndDisplay({ route }) { close={() => setCreatePasswordModal(false)} onSuccess={() => setCredsChanged('changed')} oldPassword={oldPassword} + updateBiometricAfterPasscodeChange={updateBiometricAfterPasscodeChange} /> )} /> diff --git a/src/screens/LoginScreen/Login.tsx b/src/screens/LoginScreen/Login.tsx index 8787fc8e4..eee55102e 100644 --- a/src/screens/LoginScreen/Login.tsx +++ b/src/screens/LoginScreen/Login.tsx @@ -53,6 +53,7 @@ import CampaignModalIllustration from 'src/assets/images/CampaignModalIllustrati import { uaiType } from 'src/models/interfaces/Uai'; import { addToUaiStack, uaiChecks } from 'src/store/sagaActions/uai'; import KeeperTextInput from 'src/components/KeeperTextInput'; +import { useSelector } from 'react-redux'; const RNBiometrics = new ReactNativeBiometrics(); @@ -99,6 +100,7 @@ function LoginScreen({ navigation, route }) { const { login } = translations; const { common } = translations; const { allAccounts, biometricEnabledAppId } = useAppSelector((state) => state.account); + const fallbackLoginMethod = useSelector((state) => state.settings.fallbackLoginMethod); const [showCampaignModal, setShowCampaignModal] = useState(false); const [campaignDetails, setCampaignDetails] = useState(null); @@ -188,6 +190,8 @@ function LoginScreen({ navigation, route }) { try { setTimeout(async () => { if (canLogin) { + console.log('canLogin', canLogin); + const { success, signature } = await RNBiometrics.createSignature({ promptMessage: 'Authenticate', payload: appId, @@ -305,9 +309,15 @@ function LoginScreen({ navigation, route }) { const attemptLogin = (passcode: string) => { setLoginModal(true); - if (loginMethod === LoginMethod.PIN) { + if ( + loginMethod === LoginMethod.PIN || + (loginMethod === LoginMethod.BIOMETRIC && fallbackLoginMethod === 'PIN') + ) { dispatch(credsAuth(passcode, LoginMethod.PIN, relogin)); - } else if (loginMethod === LoginMethod.PASSWORD) { + } else if ( + loginMethod === LoginMethod.PASSWORD || + (loginMethod === LoginMethod.BIOMETRIC && fallbackLoginMethod === 'PASSWORD') + ) { dispatch(credsAuth(passcode, LoginMethod.PASSWORD, relogin)); } }; @@ -474,7 +484,7 @@ function LoginScreen({ navigation, route }) { - {loginMethod === LoginMethod.PIN ? ( + {loginMethod === LoginMethod.PIN || fallbackLoginMethod === 'PIN' ? ( diff --git a/src/store/reducers/settings.ts b/src/store/reducers/settings.ts index b16be856f..352e2beee 100644 --- a/src/store/reducers/settings.ts +++ b/src/store/reducers/settings.ts @@ -8,6 +8,7 @@ import * as bitcoinJS from 'bitcoinjs-lib'; const initialState: { loginMethod: LoginMethod; + fallbackLoginMethod: LoginMethod | null; themeMode: ThemeMode; currencyKind: CurrencyKind; currencyCode: string; @@ -23,6 +24,7 @@ const initialState: { bitcoinNetworkType: NetworkType; } = { loginMethod: LoginMethod.PIN, + fallbackLoginMethod: null, themeMode: ThemeMode.LIGHT, currencyKind: CurrencyKind.BITCOIN, currencyCode: 'USD', @@ -45,6 +47,9 @@ const settingsSlice = createSlice({ setLoginMethod: (state, action: PayloadAction) => { state.loginMethod = action.payload; }, + setFallbackLoginMethod: (state, action: PayloadAction) => { + state.fallbackLoginMethod = action.payload; + }, setThemeMode: (state, action: PayloadAction) => { state.themeMode = action.payload; }, @@ -94,6 +99,7 @@ export const { setBackupModal, setSubscription, setBitcoinNetwork, + setFallbackLoginMethod, } = settingsSlice.actions; export default settingsSlice.reducer; diff --git a/src/store/sagaActions/login.ts b/src/store/sagaActions/login.ts index 151c9c825..83d9da8ea 100644 --- a/src/store/sagaActions/login.ts +++ b/src/store/sagaActions/login.ts @@ -19,11 +19,16 @@ export const storeCreds = (passcode, callback = null) => ({ }, }); -export const changeLoginMethod = (method: LoginMethod, pubKey: string = '') => ({ +export const changeLoginMethod = ( + method: LoginMethod, + pubKey: string = '', + fallbackMethod = null +) => ({ type: CHANGE_LOGIN_METHOD, payload: { method, pubKey, + fallbackMethod, }, }); diff --git a/src/store/sagas/login.ts b/src/store/sagas/login.ts index db7fea791..5fffa9823 100644 --- a/src/store/sagas/login.ts +++ b/src/store/sagas/login.ts @@ -49,7 +49,7 @@ import { import { RootState, store } from '../store'; import { createWatcher } from '../utilities'; import { fetchExchangeRates } from '../sagaActions/send_and_receive'; -import { setLoginMethod } from '../reducers/settings'; +import { setLoginMethod, setFallbackLoginMethod } from '../reducers/settings'; import { setSubscription } from 'src/store/sagaActions/settings'; import { backupAllSignersAndVaults } from '../sagaActions/bhr'; import { uaiChecks } from '../sagaActions/uai'; @@ -410,20 +410,28 @@ export const changeAuthCredWatcher = createWatcher(changeAuthCredWorker, CHANGE_ function* changeLoginMethodWorker({ payload, }: { - payload: { method: LoginMethod; pubKey: string }; + payload: { + method: LoginMethod; + pubKey: string; + fallbackMethod: LoginMethod.PIN | LoginMethod.PASSWORD; + }; }) { try { - const { method, pubKey } = payload; + const { method, pubKey, fallbackMethod } = payload; + console.log('payload', payload); + const keeperApp = yield call(dbManager.getObjectByIndex, RealmSchema.KeeperApp); if (method === LoginMethod.BIOMETRIC) { const savePubKey = yield call(SecureStore.storeBiometricPubKey, pubKey, keeperApp?.id); if (savePubKey) { yield put(setLoginMethod(method)); + yield put(setFallbackLoginMethod(fallbackMethod)); if (keeperApp?.id) yield put(setBiometricEnabledAppId(keeperApp?.id)); } } else { yield put(setLoginMethod(method)); yield put(setBiometricEnabledAppId(null)); + yield put(setFallbackLoginMethod(null)); } } catch (err) { console.log('🚀 ~ changeLoginMethodWorker:', err); From e8a70b850355f942db675e4a99bb73f6e6e4a184 Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Tue, 24 Jun 2025 14:29:26 +0500 Subject: [PATCH 07/12] fix biometric issue --- src/components/Modal/PasscodeVerify.tsx | 6 +-- .../AppSettings/CreatePasswordContent.tsx | 19 +++------- src/screens/AppSettings/PrivacyAndDisplay.tsx | 38 +++++++++---------- src/screens/LoginScreen/Login.tsx | 1 - src/store/sagas/login.ts | 2 +- 5 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/components/Modal/PasscodeVerify.tsx b/src/components/Modal/PasscodeVerify.tsx index b637cbf02..e4cfaf6cf 100644 --- a/src/components/Modal/PasscodeVerify.tsx +++ b/src/components/Modal/PasscodeVerify.tsx @@ -46,11 +46,7 @@ function PasscodeVerifyModal({ const [errMessage, setErrMessage] = useState(login.Incorrect); const { isAuthenticated, authenticationFailed } = useAppSelector((state) => state.login); const { loginMethod } = useAppSelector((state) => state.settings); - const { appId, failedAttempts, lastLoginFailedAt } = useAppSelector((state) => state.storage); - - console.log('isAuthenticated', isAuthenticated); - console.log('authenticationFailed', authenticationFailed); - console.log('loginError', loginError); + const { appId } = useAppSelector((state) => state.storage); useEffect(() => { if (useBiometrics) { diff --git a/src/screens/AppSettings/CreatePasswordContent.tsx b/src/screens/AppSettings/CreatePasswordContent.tsx index 3c0399053..560de2d0a 100644 --- a/src/screens/AppSettings/CreatePasswordContent.tsx +++ b/src/screens/AppSettings/CreatePasswordContent.tsx @@ -9,21 +9,16 @@ import { hp } from 'src/constants/responsive'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import LoginMethod from 'src/models/enums/LoginMethod'; import { useAppSelector } from 'src/store/hooks'; -import { changeAuthCred, changeLoginMethod } from 'src/store/sagaActions/login'; +import { setFallbackLoginMethod } from 'src/store/reducers/settings'; +import { changeAuthCred } from 'src/store/sagaActions/login'; interface Props { close?: () => void; - onSuccess?: () => void; + onSuccess?: (method: LoginMethod) => void; oldPassword?: string; - updateBiometricAfterPasscodeChange?: () => void; } -const CreatePasswordContent = ({ - close, - onSuccess, - oldPassword, - updateBiometricAfterPasscodeChange, -}: Props) => { +const CreatePasswordContent = ({ close, onSuccess, oldPassword }: Props) => { const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); const { common } = translations; @@ -43,11 +38,9 @@ const CreatePasswordContent = ({ setError(''); dispatch(changeAuthCred(oldPassword, password)); if (loginMethod === LoginMethod.BIOMETRIC) { - updateBiometricAfterPasscodeChange(); - } else { - dispatch(changeLoginMethod(LoginMethod.PASSWORD)); + dispatch(setFallbackLoginMethod(LoginMethod.PASSWORD)); } - onSuccess(); + onSuccess(LoginMethod.PASSWORD); close(); } }; diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index 9331135c0..c7f66f0c3 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -52,7 +52,6 @@ function ConfirmPasscode({ setConfirmPasscodeModal, onCredsChange, setShowSetPasscodeModal, - updateBiometricAfterPasscodeChange, }) { const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); @@ -65,9 +64,6 @@ function ConfirmPasscode({ const [confirmPasscodeFlag, setConfirmPasscodeFlag] = useState(0); const { credsChanged } = useAppSelector((state) => state.login); const { loginMethod }: { loginMethod: LoginMethod } = useAppSelector((state) => state.settings); - - console.log('loginMethod in pin ', loginMethod); - useEffect(() => { if (credsChanged === 'changed') { onCredsChange(); @@ -172,10 +168,7 @@ function ConfirmPasscode({ primaryCallback={() => { dispatch(changeAuthCred(oldPassword, passcode)); if (loginMethod === LoginMethod.BIOMETRIC) { - // dispatch(setFallbackLoginMethod(LoginMethod.PIN)); - updateBiometricAfterPasscodeChange(); - } else { - dispatch(changeLoginMethod(LoginMethod.PIN)); + dispatch(setFallbackLoginMethod(LoginMethod.PIN)); } setShowSetPasscodeModal(false); }} @@ -234,7 +227,6 @@ function PrivacyAndDisplay({ route }) { const [credsChanged, setCredsChanged] = useState(''); const { isOnL4 } = usePlan(); const fallbackLoginMethod = useSelector((state) => state.settings.fallbackLoginMethod); - console.log('fallbackLoginMethod', fallbackLoginMethod); useEffect(() => { if (credsChanged === 'changed') { @@ -292,7 +284,6 @@ function PrivacyAndDisplay({ route }) { console.log(error); } }; - console.log('loginMethod', loginMethod); const requestPermission = () => { Linking.openSettings(); @@ -327,7 +318,7 @@ function PrivacyAndDisplay({ route }) { } }; - const updateBiometricAfterPasscodeChange = async () => { + const updateBiometricAfterPasscodeChange = async (newFallbackMethod) => { try { const { available } = await RNBiometrics.isSensorAvailable(); @@ -355,15 +346,13 @@ function PrivacyAndDisplay({ route }) { } const { publicKey } = await RNBiometrics.createKeys(); - dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey, fallbackLoginMethod)); + dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey, newFallbackMethod)); showToast('Biometric updated successfully'); } catch (error) { - console.log('Biometric update failed:', error); showToast('Failed to update biometric authentication.', ); setSensorAvailable(false); } }; - console.log('loginMethod', loginMethod); const PrivacyAndDisplay = [ { @@ -428,7 +417,6 @@ function PrivacyAndDisplay({ route }) { ), }, ]; - console.log('showSetPasscodeModal', showSetPasscodeModal); return ( @@ -565,9 +553,15 @@ function PrivacyAndDisplay({ route }) { setCredsChanged('changed')} + onCredsChange={() => { + setCredsChanged('changed'); + if (loginMethod === LoginMethod.BIOMETRIC) { + updateBiometricAfterPasscodeChange(LoginMethod.PIN); + } else { + dispatch(changeLoginMethod(LoginMethod.PIN)); + } + }} setShowSetPasscodeModal={setShowSetPasscodeModal} - updateBiometricAfterPasscodeChange={updateBiometricAfterPasscodeChange} /> )} /> @@ -633,9 +627,15 @@ function PrivacyAndDisplay({ route }) { Content={() => ( setCreatePasswordModal(false)} - onSuccess={() => setCredsChanged('changed')} + onSuccess={(newFallbackMethod) => { + setCredsChanged('changed'); + if (loginMethod === LoginMethod.BIOMETRIC) { + updateBiometricAfterPasscodeChange(newFallbackMethod); + } else { + dispatch(changeLoginMethod(LoginMethod.PASSWORD)); + } + }} oldPassword={oldPassword} - updateBiometricAfterPasscodeChange={updateBiometricAfterPasscodeChange} /> )} /> diff --git a/src/screens/LoginScreen/Login.tsx b/src/screens/LoginScreen/Login.tsx index eee55102e..45425ddbc 100644 --- a/src/screens/LoginScreen/Login.tsx +++ b/src/screens/LoginScreen/Login.tsx @@ -108,7 +108,6 @@ function LoginScreen({ navigation, route }) { const onChangeTorStatus = (status: TorStatus) => { settorStatus(status); }; - console.log('loginScreen method', loginMethod); async function requestUserPermission() { const authStatus = await messaging().requestPermission(); diff --git a/src/store/sagas/login.ts b/src/store/sagas/login.ts index 5fffa9823..7b84d1e78 100644 --- a/src/store/sagas/login.ts +++ b/src/store/sagas/login.ts @@ -413,7 +413,7 @@ function* changeLoginMethodWorker({ payload: { method: LoginMethod; pubKey: string; - fallbackMethod: LoginMethod.PIN | LoginMethod.PASSWORD; + fallbackMethod: any; }; }) { try { From a8f548eb97a0241b9987a9bb1b64263567cf3966 Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Tue, 24 Jun 2025 14:41:33 +0500 Subject: [PATCH 08/12] fix fallback from create pin --- src/screens/LoginScreen/CreatePin.tsx | 2 +- src/screens/LoginScreen/Login.tsx | 2 -- src/store/sagas/login.ts | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/screens/LoginScreen/CreatePin.tsx b/src/screens/LoginScreen/CreatePin.tsx index 04d21dec2..5f99eab33 100644 --- a/src/screens/LoginScreen/CreatePin.tsx +++ b/src/screens/LoginScreen/CreatePin.tsx @@ -167,7 +167,7 @@ export default function CreatePin(props) { if (success) { const { publicKey } = await RNBiometrics.createKeys(); - dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey)); + dispatch(changeLoginMethod(LoginMethod.BIOMETRIC, publicKey, LoginMethod.PIN)); props.navigation.replace('OnBoardingSlides'); } else { showToast(errorText.biometicAuthFailed, ); diff --git a/src/screens/LoginScreen/Login.tsx b/src/screens/LoginScreen/Login.tsx index 45425ddbc..9eaeea998 100644 --- a/src/screens/LoginScreen/Login.tsx +++ b/src/screens/LoginScreen/Login.tsx @@ -189,8 +189,6 @@ function LoginScreen({ navigation, route }) { try { setTimeout(async () => { if (canLogin) { - console.log('canLogin', canLogin); - const { success, signature } = await RNBiometrics.createSignature({ promptMessage: 'Authenticate', payload: appId, diff --git a/src/store/sagas/login.ts b/src/store/sagas/login.ts index 7b84d1e78..54a9d2671 100644 --- a/src/store/sagas/login.ts +++ b/src/store/sagas/login.ts @@ -273,8 +273,6 @@ function* credentialsAuthWorker({ payload }) { RealmSchema.KeeperApp ); if (updatedSubs.level > 2) yield put(setAllCampaigns(true)); - console.log('method', method); - const { pendingAllBackup, automaticCloudBackup } = yield select( (state: RootState) => state.bhr ); @@ -418,8 +416,6 @@ function* changeLoginMethodWorker({ }) { try { const { method, pubKey, fallbackMethod } = payload; - console.log('payload', payload); - const keeperApp = yield call(dbManager.getObjectByIndex, RealmSchema.KeeperApp); if (method === LoginMethod.BIOMETRIC) { const savePubKey = yield call(SecureStore.storeBiometricPubKey, pubKey, keeperApp?.id); From 50aeaff1459b350b8ac6176a774dea96cbaf8ebe Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Tue, 24 Jun 2025 15:32:57 +0500 Subject: [PATCH 09/12] change the modals --- src/components/ConfirmCredentialModal.tsx | 57 +++++++++++++++++++ src/components/RKSignersModal.tsx | 10 ++-- src/screens/AppSettings/AppBackupSettings.tsx | 8 +-- src/screens/AppSettings/ManageWallets.tsx | 12 ++-- .../AppSettings/PasswordModalContent.tsx | 5 +- src/screens/AppSettings/PrivacyAndDisplay.tsx | 6 +- .../Settings/Component/SettingModal.tsx | 8 +-- .../components/Settings/keeperSettings.tsx | 10 ++-- .../components/LetterOfAttorney.tsx | 8 +-- .../components/MasterRecoveryKey.tsx | 8 +-- src/screens/Send/SendConfirmation.tsx | 8 +-- .../SignTransaction/SignTransactionScreen.tsx | 6 +- src/screens/SigningDevices/DeleteKeys.tsx | 8 +-- src/screens/SigningDevices/ManageSigners.tsx | 6 +- src/screens/Vault/HardwareModalMap.tsx | 6 +- src/screens/Vault/SignerAdvanceSettings.tsx | 6 +- src/screens/Vault/SigningDeviceDetails.tsx | 8 +-- src/screens/WalletDetails/WalletSettings.tsx | 8 +-- 18 files changed, 119 insertions(+), 69 deletions(-) create mode 100644 src/components/ConfirmCredentialModal.tsx diff --git a/src/components/ConfirmCredentialModal.tsx b/src/components/ConfirmCredentialModal.tsx new file mode 100644 index 000000000..225403ced --- /dev/null +++ b/src/components/ConfirmCredentialModal.tsx @@ -0,0 +1,57 @@ +import { Box } from 'native-base'; +import React from 'react'; +import { useSelector } from 'react-redux'; +import LoginMethod from 'src/models/enums/LoginMethod'; +import { useAppSelector } from 'src/store/hooks'; +import PasscodeVerifyModal from './Modal/PasscodeVerify'; +import PasswordModalContent from 'src/screens/AppSettings/PasswordModalContent'; + +type Props = { + close?: () => void; + success?: any; + useBiometrics?: boolean; + forcedMode?: any; + onForceSuccess?: any; + primaryText?: string; +}; + +const ConfirmCredentialModal = ({ + success, + close, + useBiometrics, + forcedMode, + onForceSuccess, + primaryText, +}: Props) => { + const { loginMethod }: { loginMethod: LoginMethod } = useAppSelector((state) => state.settings); + const fallbackLoginMethod = useSelector((state) => state.settings.fallbackLoginMethod); + + console.log({ loginMethod, fallbackLoginMethod }); + + return ( + + {(loginMethod === LoginMethod.BIOMETRIC && fallbackLoginMethod === 'PIN') || + (loginMethod !== LoginMethod.BIOMETRIC && loginMethod === LoginMethod.PIN) ? ( + { + close(); + }} + forcedMode={forcedMode} + onForceSuccess={onForceSuccess} + onSuccess={success} + primaryText={primaryText} + /> + ) : ( + { + close(); + }} + onSuccess={success} + /> + )} + + ); +}; + +export default ConfirmCredentialModal; diff --git a/src/components/RKSignersModal.tsx b/src/components/RKSignersModal.tsx index c11362c5b..a317284f5 100644 --- a/src/components/RKSignersModal.tsx +++ b/src/components/RKSignersModal.tsx @@ -14,7 +14,6 @@ import { CKTapCard } from 'cktap-protocol-react-native'; import useNfcModal from 'src/hooks/useNfcModal'; import NfcPrompt from 'src/components/NfcPromptAndroid'; import KeeperModal from 'src/components/KeeperModal'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import { Box, useColorMode } from 'native-base'; import { SIGNTRANSACTION } from 'src/navigation/contants'; import { useDispatch } from 'react-redux'; @@ -30,6 +29,7 @@ import { KeeperApp } from 'src/models/interfaces/KeeperApp'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import { useAppSelector } from 'src/store/hooks'; import ShareKeyModalContent from 'src/screens/Vault/components/ShareKeyModalContent'; +import ConfirmCredentialModal from './ConfirmCredentialModal'; const RKSignersModal = ({ signer, psbt, isMiniscript, vaultId }, ref) => { const { primaryMnemonic }: KeeperApp = useQuery(RealmSchema.KeeperApp)[0]; @@ -344,12 +344,10 @@ const RKSignersModal = ({ signer, psbt, isMiniscript, vaultId }, ref) => { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - setConfirmPassVisible(false)} + success={signTransaction} useBiometrics={false} - close={() => { - setConfirmPassVisible(false); - }} - onSuccess={signTransaction} /> )} /> diff --git a/src/screens/AppSettings/AppBackupSettings.tsx b/src/screens/AppSettings/AppBackupSettings.tsx index 7b72701ea..1a903a3c7 100644 --- a/src/screens/AppSettings/AppBackupSettings.tsx +++ b/src/screens/AppSettings/AppBackupSettings.tsx @@ -6,7 +6,6 @@ import { CommonActions, useNavigation } from '@react-navigation/native'; import OptionCard from 'src/components/OptionCard'; import KeeperModal from 'src/components/KeeperModal'; import ScreenWrapper from 'src/components/ScreenWrapper'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import { wp } from 'src/constants/responsive'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import { RealmSchema } from 'src/storage/realm/enum'; @@ -31,6 +30,7 @@ import { NewVaultInfo } from 'src/store/sagas/wallets'; import BackupModalContent from './BackupModal'; import { credsAuthenticated } from 'src/store/reducers/login'; import WalletHeader from 'src/components/WalletHeader'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; function AppBackupSettings() { const { colorMode } = useColorMode(); @@ -160,15 +160,15 @@ function AppBackupSettings() { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={() => { + success={() => { setConfirmPassVisible(false); setBackupModalVisible(true); }} + useBiometrics={true} /> )} /> diff --git a/src/screens/AppSettings/ManageWallets.tsx b/src/screens/AppSettings/ManageWallets.tsx index 5852445d4..554ec0bd0 100644 --- a/src/screens/AppSettings/ManageWallets.tsx +++ b/src/screens/AppSettings/ManageWallets.tsx @@ -22,7 +22,6 @@ import KeeperModal from 'src/components/KeeperModal'; import { captureError } from 'src/services/sentry'; import useWallets from 'src/hooks/useWallets'; import { useDispatch, useSelector } from 'react-redux'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import useVault from 'src/hooks/useVault'; import { Vault } from 'src/services/wallets/interfaces/vault'; import HexagonIcon from 'src/components/HexagonIcon'; @@ -46,6 +45,7 @@ import MiniscriptPathSelector, { } from 'src/components/MiniscriptPathSelector'; import WalletHeader from 'src/components/WalletHeader'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; enum PasswordMode { DEFAULT = 'DEFAULT', @@ -414,13 +414,13 @@ function ManageWallets() { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={onProceed} + success={onProceed} + useBiometrics={false} onForceSuccess={onForceProceed} /> )} @@ -436,12 +436,12 @@ function ManageWallets() { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPasscodeVisible(false); }} - onSuccess={deleteSelectedEntity} + success={deleteSelectedEntity} /> )} /> diff --git a/src/screens/AppSettings/PasswordModalContent.tsx b/src/screens/AppSettings/PasswordModalContent.tsx index 4e3f6d8d7..1388ff59b 100644 --- a/src/screens/AppSettings/PasswordModalContent.tsx +++ b/src/screens/AppSettings/PasswordModalContent.tsx @@ -14,9 +14,8 @@ import { credsAuthenticated } from 'src/store/reducers/login'; interface Props { close?: Function; onSuccess?: Function; - oldPassword?: any; } -const PasswordModalContent = ({ close, onSuccess, oldPassword }: Props) => { +const PasswordModalContent = ({ close, onSuccess }: Props) => { const { colorMode } = useColorMode(); const dispatch = useAppDispatch(); const { translations } = useContext(LocalizationContext); @@ -25,8 +24,6 @@ const PasswordModalContent = ({ close, onSuccess, oldPassword }: Props) => { const [loginError, setLoginError] = useState(false); const [errMessage, setErrMessage] = useState(''); - console.log('passwordauth', password); - const { isAuthenticated, authenticationFailed } = useAppSelector((state) => state.login); const attemptLogin = (passcode: string) => { diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index c7f66f0c3..3334f576e 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -18,7 +18,6 @@ import { KeeperApp } from 'src/models/interfaces/KeeperApp'; import { useQuery } from '@realm/react'; import { RealmSchema } from 'src/storage/realm/enum'; import { getJSONFromRealmObject } from 'src/storage/realm/utils'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import KeeperModal from 'src/components/KeeperModal'; import ModalWrapper from 'src/components/Modal/ModalWrapper'; import HealthCheckComponent from 'src/components/Backup/HealthCheckComponent'; @@ -44,6 +43,7 @@ import PinIcon from 'src/assets/images/pin-icon.svg'; import PasswordModalContent from './PasswordModalContent'; import CreatePasswordContent from './CreatePasswordContent'; import { useSelector } from 'react-redux'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; const RNBiometrics = new ReactNativeBiometrics(); @@ -447,7 +447,7 @@ function PrivacyAndDisplay({ route }) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setVisiblePassCode(false); @@ -461,6 +461,7 @@ function PrivacyAndDisplay({ route }) { setPasscodeHCModal(true); } }} + useBiometrics={false} /> )} /> @@ -474,7 +475,6 @@ function PrivacyAndDisplay({ route }) { subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( setVisiblePassword(false)} onSuccess={(password) => { if (data.length === 0) { diff --git a/src/screens/Home/components/Settings/Component/SettingModal.tsx b/src/screens/Home/components/Settings/Component/SettingModal.tsx index 91aa9e554..e60f1a1a8 100644 --- a/src/screens/Home/components/Settings/Component/SettingModal.tsx +++ b/src/screens/Home/components/Settings/Component/SettingModal.tsx @@ -2,8 +2,8 @@ import { CommonActions, useNavigation } from '@react-navigation/native'; import { useQuery } from '@realm/react'; import { Box, useColorMode } from 'native-base'; import React, { useContext, useEffect, useState } from 'react'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; import KeeperModal from 'src/components/KeeperModal'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import { wp } from 'src/constants/responsive'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import { KeeperApp } from 'src/models/interfaces/KeeperApp'; @@ -46,13 +46,13 @@ const SettingModal = ({ isUaiFlow, confirmPass, setConfirmPass }) => { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); setConfirmPass(false); }} - onSuccess={() => { + success={() => { setConfirmPassVisible(false); setBackupModalVisible(true); }} diff --git a/src/screens/Home/components/Settings/keeperSettings.tsx b/src/screens/Home/components/Settings/keeperSettings.tsx index 60c228209..34cac8b57 100644 --- a/src/screens/Home/components/Settings/keeperSettings.tsx +++ b/src/screens/Home/components/Settings/keeperSettings.tsx @@ -25,8 +25,8 @@ import usePlan from 'src/hooks/usePlan'; import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; import { useAppSelector } from 'src/store/hooks'; import KeeperModal from 'src/components/KeeperModal'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; const KeeperSettings = ({ route }) => { const { colorMode } = useColorMode(); @@ -180,12 +180,10 @@ const KeeperSettings = ({ route }) => { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - setHiddenKeyPass(false)} + success={onSuccess} useBiometrics={false} - close={() => { - setHiddenKeyPass(false); - }} - onSuccess={onSuccess} /> )} /> diff --git a/src/screens/InheritanceToolsAndTips/components/LetterOfAttorney.tsx b/src/screens/InheritanceToolsAndTips/components/LetterOfAttorney.tsx index b3c0cf681..cde14dc22 100644 --- a/src/screens/InheritanceToolsAndTips/components/LetterOfAttorney.tsx +++ b/src/screens/InheritanceToolsAndTips/components/LetterOfAttorney.tsx @@ -11,12 +11,12 @@ import DashedButton from 'src/components/DashedButton'; import GenerateLetterToAtternyPDFInheritanceTool from 'src/utils/GenerateLetterToAtternyPDFInheritanceTool'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import useSigners from 'src/hooks/useSigners'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import KeeperModal from 'src/components/KeeperModal'; import { credsAuthenticated } from 'src/store/reducers/login'; import { useDispatch } from 'react-redux'; import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; function LetterOfAttorney() { const { signers } = useSigners(); @@ -83,12 +83,12 @@ function LetterOfAttorney() { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={() => { + success={() => { setConfirmPassVisible(false); if (fingerPrints) { GenerateLetterToAtternyPDFInheritanceTool(fingerPrints).then((res) => { diff --git a/src/screens/InheritanceToolsAndTips/components/MasterRecoveryKey.tsx b/src/screens/InheritanceToolsAndTips/components/MasterRecoveryKey.tsx index 6e2d328a1..6273b0b34 100644 --- a/src/screens/InheritanceToolsAndTips/components/MasterRecoveryKey.tsx +++ b/src/screens/InheritanceToolsAndTips/components/MasterRecoveryKey.tsx @@ -14,10 +14,10 @@ import { getJSONFromRealmObject } from 'src/storage/realm/utils'; import { CommonActions } from '@react-navigation/native'; import { LocalizationContext } from 'src/context/Localization/LocContext'; import MasterKey from 'src/assets/images/master_key.svg'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import KeeperModal from 'src/components/KeeperModal'; import { credsAuthenticated } from 'src/store/reducers/login'; import { useDispatch } from 'react-redux'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; function MasterRecoveryKey({ navigation }) { const { colorMode } = useColorMode(); @@ -80,12 +80,12 @@ function MasterRecoveryKey({ navigation }) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={() => { + success={() => { setConfirmPassVisible(false); navigation.dispatch( CommonActions.navigate('ExportSeed', { diff --git a/src/screens/Send/SendConfirmation.tsx b/src/screens/Send/SendConfirmation.tsx index 4af391469..466fa9f3b 100644 --- a/src/screens/Send/SendConfirmation.tsx +++ b/src/screens/Send/SendConfirmation.tsx @@ -28,7 +28,6 @@ import useToastMessage from 'src/hooks/useToastMessage'; import useBalance from 'src/hooks/useBalance'; import useWallets from 'src/hooks/useWallets'; import useVault from 'src/hooks/useVault'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import { InputUTXOs, UTXO } from 'src/services/wallets/interfaces'; import CurrencyTypeSwitch from 'src/components/Switch/CurrencyTypeSwitch'; import FeeInsights from 'src/screens/FeeInsights/FeeInsightsContent'; @@ -67,6 +66,7 @@ import SendingCardIcon from 'src/assets/images/vault_icon.svg'; import WalletIcon from 'src/assets/images/daily_wallet.svg'; import MultiSendSvg from 'src/assets/images/@.svg'; import useExchangeRates from 'src/hooks/useExchangeRates'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; export interface SendConfirmationRouteParams { sender: Wallet | Vault; @@ -797,12 +797,12 @@ function SendConfirmation({ route }) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={onProceed} + success={onProceed} /> )} /> diff --git a/src/screens/SignTransaction/SignTransactionScreen.tsx b/src/screens/SignTransaction/SignTransactionScreen.tsx index 7fb3ca3e5..cb91eeb0d 100644 --- a/src/screens/SignTransaction/SignTransactionScreen.tsx +++ b/src/screens/SignTransaction/SignTransactionScreen.tsx @@ -30,7 +30,6 @@ import { LocalizationContext } from 'src/context/Localization/LocContext'; import useSignerMap from 'src/hooks/useSignerMap'; import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; import { getTxHexFromKeystonePSBT } from 'src/hardware/keystone'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import { DelayedTransaction } from 'src/models/interfaces/AssistedKeys'; import { hash256 } from 'src/utils/service-utilities/encryption'; import { hcStatusType } from 'src/models/interfaces/HeathCheckTypes'; @@ -60,6 +59,7 @@ import { } from './signWithSD'; import SendSuccessfulContent from '../Send/SendSuccessfulContent'; import WalletHeader from 'src/components/WalletHeader'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; function SignTransactionScreen() { const route = useRoute(); @@ -799,12 +799,12 @@ function SignTransactionScreen() { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={onSuccess} + success={onSuccess} /> )} /> diff --git a/src/screens/SigningDevices/DeleteKeys.tsx b/src/screens/SigningDevices/DeleteKeys.tsx index 6b5e7bb9c..5dba3edb6 100644 --- a/src/screens/SigningDevices/DeleteKeys.tsx +++ b/src/screens/SigningDevices/DeleteKeys.tsx @@ -1,9 +1,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { Box, useColorMode } from 'native-base'; import { hp, windowWidth, wp } from 'src/constants/responsive'; -import HiddenKeyIcon from 'src/assets/images/hidden-key.svg'; import ScreenWrapper from 'src/components/ScreenWrapper'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import KeeperModal from 'src/components/KeeperModal'; import useSigners from 'src/hooks/useSigners'; import { StyleSheet, ScrollView } from 'react-native'; @@ -35,6 +33,7 @@ import TorAsset from 'src/components/Loader'; import moment from 'moment'; import { getKeyUID } from 'src/utils/utilities'; import WalletHeader from 'src/components/WalletHeader'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; function DeleteKeys({ route }) { const { colorMode } = useColorMode(); @@ -311,10 +310,11 @@ function DeleteKeys({ route }) { )} - setConfirmPassVisible(false)} - onSuccess={onSuccess} + success={onSuccess} /> )} diff --git a/src/screens/SigningDevices/ManageSigners.tsx b/src/screens/SigningDevices/ManageSigners.tsx index 4b46b2c15..c1829ee78 100644 --- a/src/screens/SigningDevices/ManageSigners.tsx +++ b/src/screens/SigningDevices/ManageSigners.tsx @@ -40,7 +40,6 @@ import ToastErrorIcon from 'src/assets/images/toast_error.svg'; import { setupKeeperSigner } from 'src/hardware/signerSetup'; import { getKeyUID } from 'src/utils/utilities'; import { SentryErrorBoundary } from 'src/services/sentry'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import EnhancedKeysSection from './components/EnhancedKeysSection'; import ConciergeNeedHelp from 'src/assets/images/conciergeNeedHelp.svg'; import { @@ -53,6 +52,7 @@ import HWError from 'src/hardware/HWErrorState'; import { HWErrorType } from 'src/models/enums/Hardware'; import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; type ScreenProps = NativeStackScreenProps; @@ -308,12 +308,12 @@ function ManageSigners({ route }: ScreenProps) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={onSuccess} + success={onSuccess} /> )} /> diff --git a/src/screens/Vault/HardwareModalMap.tsx b/src/screens/Vault/HardwareModalMap.tsx index 15dab895e..99ff46e5b 100644 --- a/src/screens/Vault/HardwareModalMap.tsx +++ b/src/screens/Vault/HardwareModalMap.tsx @@ -82,7 +82,6 @@ import { setupSpecter, } from 'src/hardware/signerSetup'; import { extractColdCardExport } from 'src/hardware/coldcard'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import useCanaryWalletSetup from 'src/hooks/UseCanaryWalletSetup'; import { hcStatusType } from 'src/models/interfaces/HeathCheckTypes'; import NFC from 'src/services/nfc'; @@ -100,6 +99,7 @@ import BackupModalContent from '../AppSettings/BackupModal'; import SignerOptionCard from './components/signerOptionCard'; import ColdCardUSBInstruction from './components/ColdCardUSBInstruction'; import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; const RNBiometrics = new ReactNativeBiometrics(); const SIGEERS_SUPPORT_MULTIPLE_XPUBS = [ @@ -2209,11 +2209,11 @@ function HardwareModalMap({ textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={() => { + success={() => { if (type === SignerType.MY_KEEPER && mode === InteracationMode.HEALTH_CHECK) { setConfirmPassVisible(false); setBackupModalVisible(true); diff --git a/src/screens/Vault/SignerAdvanceSettings.tsx b/src/screens/Vault/SignerAdvanceSettings.tsx index af118493f..3a19287ed 100644 --- a/src/screens/Vault/SignerAdvanceSettings.tsx +++ b/src/screens/Vault/SignerAdvanceSettings.tsx @@ -31,7 +31,6 @@ import { getAccountFromSigner, getKeyUID } from 'src/utils/utilities'; import useSignerMap from 'src/hooks/useSignerMap'; import { getSignerNameFromType } from 'src/hardware'; import { KEEPER_KNOWLEDGEBASE } from 'src/utils/service-utilities/config'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import { NewVaultInfo } from 'src/store/sagas/wallets'; import { addNewVault, refillMobileKey } from 'src/store/sagaActions/vaults'; import { generateVaultId } from 'src/services/wallets/factories/VaultFactory'; @@ -64,6 +63,7 @@ import HardwareModalMap, { InteracationMode } from './HardwareModalMap'; import RegisterSignerContent from './components/RegisterSignerContent'; import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; const { width } = Dimensions.get('screen'); @@ -1075,12 +1075,12 @@ function SignerAdvanceSettings({ route }: any) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={onSuccess} + success={onSuccess} /> )} /> diff --git a/src/screens/Vault/SigningDeviceDetails.tsx b/src/screens/Vault/SigningDeviceDetails.tsx index ca65e0397..d9aacd594 100644 --- a/src/screens/Vault/SigningDeviceDetails.tsx +++ b/src/screens/Vault/SigningDeviceDetails.tsx @@ -48,7 +48,6 @@ import { uaiType } from 'src/models/interfaces/Uai'; import { ConciergeTag } from 'src/models/enums/ConciergeTag'; import { hcStatusType } from 'src/models/interfaces/HeathCheckTypes'; import { Signer, Vault } from 'src/services/wallets/interfaces/vault'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import BackupModalContent from 'src/screens/AppSettings/BackupModal'; import { getPersistedDocument } from 'src/services/documents'; import { generateDataFromPSBT, getAccountFromSigner, getKeyUID } from 'src/utils/utilities'; @@ -78,6 +77,7 @@ import nfcManager, { NfcTech } from 'react-native-nfc-manager'; import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; import HexagonIcon from 'src/components/HexagonIcon'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; export const SignersReqVault = [ SignerType.LEDGER, @@ -997,12 +997,12 @@ function SigningDeviceDetails({ route }) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={() => { + success={() => { setShowMobileKeyModal(false); setBackupModalVisible(true); }} diff --git a/src/screens/WalletDetails/WalletSettings.tsx b/src/screens/WalletDetails/WalletSettings.tsx index 9d0c9da8b..8d4e7cf0f 100644 --- a/src/screens/WalletDetails/WalletSettings.tsx +++ b/src/screens/WalletDetails/WalletSettings.tsx @@ -10,7 +10,6 @@ import TickIcon from 'src/assets/images/icon_tick.svg'; import useWallets from 'src/hooks/useWallets'; import { Pressable, StyleSheet } from 'react-native'; import ScreenWrapper from 'src/components/ScreenWrapper'; -import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; import useTestSats from 'src/hooks/useTestSats'; import idx from 'idx'; import dbManager from 'src/storage/realm/dbManager'; @@ -31,6 +30,7 @@ import ToastErrorIcon from 'src/assets/images/toast_error.svg'; import Instruction from 'src/components/Instruction'; import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; function WalletSettings({ route }) { const { colorMode } = useColorMode(); @@ -176,12 +176,12 @@ function WalletSettings({ route }) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setConfirmPassVisible(false); }} - onSuccess={() => { + success={() => { setConfirmPassVisible(false); setBackupModalVisible(true); }} From aed5e8596571ee8c947be16d9634683830131d39 Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Tue, 24 Jun 2025 15:34:05 +0500 Subject: [PATCH 10/12] remove log --- src/components/ConfirmCredentialModal.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/ConfirmCredentialModal.tsx b/src/components/ConfirmCredentialModal.tsx index 225403ced..19b751418 100644 --- a/src/components/ConfirmCredentialModal.tsx +++ b/src/components/ConfirmCredentialModal.tsx @@ -26,8 +26,6 @@ const ConfirmCredentialModal = ({ const { loginMethod }: { loginMethod: LoginMethod } = useAppSelector((state) => state.settings); const fallbackLoginMethod = useSelector((state) => state.settings.fallbackLoginMethod); - console.log({ loginMethod, fallbackLoginMethod }); - return ( {(loginMethod === LoginMethod.BIOMETRIC && fallbackLoginMethod === 'PIN') || From c303ecca686c636f484a556124abb5c4d469ae02 Mon Sep 17 00:00:00 2001 From: Raheel1258 Date: Tue, 24 Jun 2025 16:44:04 +0500 Subject: [PATCH 11/12] fix modal --- src/screens/AppSettings/PrivacyAndDisplay.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index 3334f576e..2a7e7af33 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -43,7 +43,7 @@ import PinIcon from 'src/assets/images/pin-icon.svg'; import PasswordModalContent from './PasswordModalContent'; import CreatePasswordContent from './CreatePasswordContent'; import { useSelector } from 'react-redux'; -import ConfirmCredentialModal from 'src/components/ConfirmCredentialModal'; +import PasscodeVerifyModal from 'src/components/Modal/PasscodeVerify'; const RNBiometrics = new ReactNativeBiometrics(); @@ -447,7 +447,7 @@ function PrivacyAndDisplay({ route }) { textColor={`${colorMode}.textGreen`} subTitleColor={`${colorMode}.modalSubtitleBlack`} Content={() => ( - { setVisiblePassCode(false); From 5224a235f8d269268bb89c04f206b6498f939071 Mon Sep 17 00:00:00 2001 From: benk10 Date: Fri, 27 Jun 2025 13:05:46 +0200 Subject: [PATCH 12/12] Update text --- src/screens/AppSettings/PrivacyAndDisplay.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screens/AppSettings/PrivacyAndDisplay.tsx b/src/screens/AppSettings/PrivacyAndDisplay.tsx index 2a7e7af33..6beaa1cdf 100644 --- a/src/screens/AppSettings/PrivacyAndDisplay.tsx +++ b/src/screens/AppSettings/PrivacyAndDisplay.tsx @@ -357,7 +357,7 @@ function PrivacyAndDisplay({ route }) { const PrivacyAndDisplay = [ { title: 'PIN', - description: 'Current Screen Lock', + description: 'Choose a 4 digits PIN code', onPress: () => { if ( loginMethod === LoginMethod.PIN || @@ -373,7 +373,7 @@ function PrivacyAndDisplay({ route }) { }, { title: 'Password', - description: 'Enter 4 or more digits/letters', + description: 'Choose a strong password', onPress: () => { if ( loginMethod === LoginMethod.PASSWORD ||