From 8e01cadbbac41b23fa5b533595678bb320e557de Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 25 Feb 2024 23:09:18 -0400 Subject: [PATCH 1/3] ADD: If OS supports passcode, provide explanation --- ios/BlueWallet.xcodeproj/project.pbxproj | 14 ++-- loc/en.json | 1 + package-lock.json | 14 ++-- screen/settings/encryptStorage.js | 101 ++++++++++++++--------- 4 files changed, 77 insertions(+), 53 deletions(-) diff --git a/ios/BlueWallet.xcodeproj/project.pbxproj b/ios/BlueWallet.xcodeproj/project.pbxproj index 7e484e392..f18a03f93 100644 --- a/ios/BlueWallet.xcodeproj/project.pbxproj +++ b/ios/BlueWallet.xcodeproj/project.pbxproj @@ -91,7 +91,7 @@ B4AB225E2B02AD12001F4328 /* XMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4AB225C2B02AD12001F4328 /* XMLParserDelegate.swift */; }; B4EE583C226703320003363C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B40D4E35225841ED00428FCC /* Assets.xcassets */; }; C59F90CE0D04D3E4BB39BC5D /* libPods-BlueWalletUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F02C2F7CA3591E4E0B06EBA /* libPods-BlueWalletUITests.a */; }; - C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; + C978A716948AB7DEC5B6F677 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; E5D4794B26781FC0007838C1 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = 6DD410AD266CAF1F0087DE03 /* fiatUnits.json */; }; E5D4794C26781FC1007838C1 /* fiatUnits.json in Resources */ = {isa = PBXBuildFile; fileRef = 6DD410AD266CAF1F0087DE03 /* fiatUnits.json */; }; /* End PBXBuildFile section */ @@ -399,7 +399,7 @@ files = ( 782F075B5DD048449E2DECE9 /* libz.tbd in Frameworks */, 764B49B1420D4AEB8109BF62 /* libsqlite3.0.tbd in Frameworks */, - C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */, + C978A716948AB7DEC5B6F677 /* (null) in Frameworks */, 773E382FE62E836172AAB98B /* libPods-BlueWallet.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1024,7 +1024,7 @@ ); mainGroup = 83CBB9F61A601CBA00E9B192; packageReferences = ( - 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */, + 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */, B41B76832B66B2FF002C48D5 /* XCRemoteSwiftPackageReference "bugsnag-cocoa" */, ); productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; @@ -1661,7 +1661,7 @@ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development io.bluewallet.bluewallet"; "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match AppStore io.bluewallet.bluewallet catalyst"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = YES; + SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h"; @@ -1716,7 +1716,7 @@ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore io.bluewallet.bluewallet"; "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match AppStore io.bluewallet.bluewallet catalyst"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = YES; + SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h"; @@ -2518,7 +2518,7 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */ = { + 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/EFPrefix/EFQRCode.git"; requirement = { @@ -2539,7 +2539,7 @@ /* Begin XCSwiftPackageProductDependency section */ 6DFC806F24EA0B6C007B8700 /* EFQRCode */ = { isa = XCSwiftPackageProductDependency; - package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */; + package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */; productName = EFQRCode; }; B41B76842B66B2FF002C48D5 /* Bugsnag */ = { diff --git a/loc/en.json b/loc/en.json index 6dd2810c7..8fecd52a2 100644 --- a/loc/en.json +++ b/loc/en.json @@ -271,6 +271,7 @@ "encrypt_tstorage": "Storage", "encrypt_use": "Use {type}", "encrypt_use_expl": "{type} will be used to confirm your identity before making a transaction, unlocking, exporting, or deleting a wallet. {type} will not be used to unlock encrypted storage.", + "biometrics_fail": "If {type} is not enabled, or fails to unlock, you can use your device passcode as an alternative.", "general": "General", "general_adv_mode": "Advanced Mode", "general_adv_mode_e": "When enabled, you will see advanced options such as different wallet types, the ability to specify the LNDHub instance you wish to connect to, and custom entropy during wallet creation.", diff --git a/package-lock.json b/package-lock.json index 28614d992..007c750ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "coinselect": "3.1.13", "crypto-js": "4.2.0", "dayjs": "1.11.10", - "detox": "20.17.1", + "detox": "20.18.3", "ecpair": "2.0.1", "ecurve": "1.0.6", "electrum-client": "github:BlueWallet/rn-electrum-client#1bfe3cc", @@ -9646,9 +9646,9 @@ } }, "node_modules/detox": { - "version": "20.17.1", - "resolved": "https://registry.npmjs.org/detox/-/detox-20.17.1.tgz", - "integrity": "sha512-10pey6CR9D5GSloRkH60ObBGZ8VS11H7iuBNY7qq6jO2swiqqckHhPLRXfH9+WGR7l3vDnfU+G/gQs7JxQkJwA==", + "version": "20.18.3", + "resolved": "https://registry.npmjs.org/detox/-/detox-20.18.3.tgz", + "integrity": "sha512-ssC7pWLDOs48Rocu7TDdLaYWiDWF5A8EAf/YcCsseHIqAqr6ECX6Hve8MIh3wUkPGYWoZaJHQfT9cyZjklt8AQ==", "hasInstallScript": true, "dependencies": { "ajv": "^8.6.3", @@ -29910,9 +29910,9 @@ "dev": true }, "detox": { - "version": "20.17.1", - "resolved": "https://registry.npmjs.org/detox/-/detox-20.17.1.tgz", - "integrity": "sha512-10pey6CR9D5GSloRkH60ObBGZ8VS11H7iuBNY7qq6jO2swiqqckHhPLRXfH9+WGR7l3vDnfU+G/gQs7JxQkJwA==", + "version": "20.18.3", + "resolved": "https://registry.npmjs.org/detox/-/detox-20.18.3.tgz", + "integrity": "sha512-ssC7pWLDOs48Rocu7TDdLaYWiDWF5A8EAf/YcCsseHIqAqr6ECX6Hve8MIh3wUkPGYWoZaJHQfT9cyZjklt8AQ==", "requires": { "ajv": "^8.6.3", "bunyan": "^1.8.12", diff --git a/screen/settings/encryptStorage.js b/screen/settings/encryptStorage.js index 8754f9949..651e8ae42 100644 --- a/screen/settings/encryptStorage.js +++ b/screen/settings/encryptStorage.js @@ -1,5 +1,5 @@ import React, { useEffect, useState, useCallback, useContext } from 'react'; -import { View, ScrollView, Alert, TouchableOpacity, TouchableWithoutFeedback, Text, StyleSheet } from 'react-native'; +import { View, ScrollView, Alert, TouchableOpacity, TouchableWithoutFeedback, Text, StyleSheet, Platform } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import navigationStyle from '../../components/navigationStyle'; import { BlueLoading, BlueSpacing20, BlueCard, BlueText } from '../../BlueComponents'; @@ -124,57 +124,80 @@ const EncryptStorage = () => { navigate('PlausibleDeniability'); }; - return isLoading ? ( - - - - ) : ( - - - {biometrics.isDeviceBiometricCapable && ( + const renderPasscodeExplanation = () => { + let isCapable = true; + if (Platform.OS === 'android') { + if (Platform.Version < 30) { + isCapable = false; + } + } + if (isCapable) { + return isCapable ? ( <> + + {loc.formatString(loc.settings.biometrics_fail, { type: biometrics.biometricsType })} + + ) : null; + } + }; + + return ( + + {isLoading ? ( + + ) : ( + <> + + {biometrics.isDeviceBiometricCapable && ( + <> + + {loc.settings.biometrics} + + + + {loc.formatString(loc.settings.encrypt_use_expl, { type: biometrics.biometricsType })} + {renderPasscodeExplanation()} + + + + )} - {loc.settings.biometrics} + {loc.settings.encrypt_tstorage} - - {loc.formatString(loc.settings.encrypt_use_expl, { type: biometrics.biometricsType })} - - + {storageIsEncryptedSwitchEnabled && ( + + )} )} - - {loc.settings.encrypt_tstorage} - - - {storageIsEncryptedSwitchEnabled && ( - - )} + {isLoading && } ); }; const styles = StyleSheet.create({ - root: { - flex: 1, - }, - paddingTop: { paddingTop: 19 }, + paddingTop: { paddingTop: 36 }, headerText: { fontWeight: 'bold', fontSize: 30, From e384229ee9f7bd573f8b87283f71203873d181bb Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Mon, 26 Feb 2024 18:38:28 -0400 Subject: [PATCH 2/3] Update encryptStorage.js --- screen/settings/encryptStorage.js | 101 ++++++++++++++++-------------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/screen/settings/encryptStorage.js b/screen/settings/encryptStorage.js index 651e8ae42..be10b1cdd 100644 --- a/screen/settings/encryptStorage.js +++ b/screen/settings/encryptStorage.js @@ -2,7 +2,7 @@ import React, { useEffect, useState, useCallback, useContext } from 'react'; import { View, ScrollView, Alert, TouchableOpacity, TouchableWithoutFeedback, Text, StyleSheet, Platform } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import navigationStyle from '../../components/navigationStyle'; -import { BlueLoading, BlueSpacing20, BlueCard, BlueText } from '../../BlueComponents'; +import { BlueSpacing20, BlueCard, BlueText } from '../../BlueComponents'; import Biometric from '../../class/biometrics'; import loc from '../../loc'; import { BlueStorageContext } from '../../blue_modules/storage-context'; @@ -14,11 +14,11 @@ const prompt = require('../../helpers/prompt'); const EncryptStorage = () => { const { isStorageEncrypted, encryptStorage, decryptStorage, saveToDisk } = useContext(BlueStorageContext); - const [isLoading, setIsLoading] = useState(true); const [biometrics, setBiometrics] = useState({ isDeviceBiometricCapable: false, isBiometricsEnabled: false, biometricsType: '' }); const [storageIsEncryptedSwitchEnabled, setStorageIsEncryptedSwitchEnabled] = useState(false); const { navigate, popToTop } = useNavigation(); const { colors } = useTheme(); + const [isLoading, setIsLoading] = useState({ encryptStorage: false, biometrics: false }); const styleHooks = StyleSheet.create({ root: { backgroundColor: colors.background, @@ -35,7 +35,6 @@ const EncryptStorage = () => { const isStorageEncryptedSwitchEnabled = await isStorageEncrypted(); setStorageIsEncryptedSwitchEnabled(isStorageEncryptedSwitchEnabled); setBiometrics({ isBiometricsEnabled, isDeviceBiometricCapable, biometricsType }); - setIsLoading(false); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { @@ -63,26 +62,26 @@ const EncryptStorage = () => { }; const onEncryptStorageSwitch = async value => { - setIsLoading(true); + setIsLoading(prev => ({ ...prev, encryptStorage: true })); if (value === true) { let p1 = await prompt(loc.settings.password, loc.settings.password_explain).catch(() => { - setIsLoading(false); + setIsLoading(prev => ({ ...prev, encryptStorage: false })); p1 = undefined; }); if (!p1) { - setIsLoading(false); + setIsLoading(prev => ({ ...prev, encryptStorage: false })); return; } const p2 = await prompt(loc.settings.password, loc.settings.retype_password).catch(() => { - setIsLoading(false); + setIsLoading(prev => ({ ...prev, encryptStorage: false })); }); if (p1 === p2) { await encryptStorage(p1); - setIsLoading(false); setStorageIsEncryptedSwitchEnabled(await isStorageEncrypted()); saveToDisk(); + setIsLoading(prev => ({ ...prev, encryptStorage: false })); } else { - setIsLoading(false); + setIsLoading(prev => ({ ...prev, encryptStorage: false })); triggerHapticFeedback(HapticFeedbackTypes.NotificationError); presentAlert({ message: loc.settings.passwords_do_not_match }); } @@ -94,7 +93,7 @@ const EncryptStorage = () => { { text: loc._.cancel, style: 'cancel', - onPress: () => setIsLoading(false), + onPress: () => setIsLoading(prev => ({ ...prev, encryptStorage: false })), }, { text: loc._.ok, @@ -108,6 +107,7 @@ const EncryptStorage = () => { }; const onUseBiometricSwitch = async value => { + setIsLoading(prev => ({ ...prev, biometrics: true })); const isBiometricsEnabled = { isDeviceBiometricCapable: biometrics.isDeviceBiometricCapable, isBiometricsEnabled: biometrics.isBiometricsEnabled, @@ -118,6 +118,7 @@ const EncryptStorage = () => { await Biometric.setBiometricUseEnabled(value); setBiometrics(isBiometricsEnabled); } + setIsLoading(prev => ({ ...prev, biometrics: false })); }; const navigateToPlausibleDeniability = () => { @@ -148,50 +149,55 @@ const EncryptStorage = () => { contentInsetAdjustmentBehavior="automatic" centerContent={isLoading} > - {isLoading ? ( - - ) : ( + + {biometrics.isDeviceBiometricCapable && ( <> - - {biometrics.isDeviceBiometricCapable && ( - <> - - {loc.settings.biometrics} - - - - {loc.formatString(loc.settings.encrypt_use_expl, { type: biometrics.biometricsType })} - {renderPasscodeExplanation()} - - - - )} - {loc.settings.encrypt_tstorage} + {loc.settings.biometrics} - {storageIsEncryptedSwitchEnabled && ( - - )} + + {loc.formatString(loc.settings.encrypt_use_expl, { type: biometrics.biometricsType })} + {renderPasscodeExplanation()} + + )} - {isLoading && } + + {loc.settings.encrypt_tstorage} + + + {storageIsEncryptedSwitchEnabled && ( + + )} ); }; @@ -203,6 +209,9 @@ const styles = StyleSheet.create({ fontSize: 30, marginLeft: 17, }, + rowItemContainerStyle: { + minHeight: 60, + }, }); export default EncryptStorage; From 9f3c4bf6f1930f05f7e70e5e1beade34ddc351b4 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Mon, 26 Feb 2024 18:46:13 -0400 Subject: [PATCH 3/3] Update encryptStorage.js --- screen/settings/encryptStorage.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/screen/settings/encryptStorage.js b/screen/settings/encryptStorage.js index be10b1cdd..b71277a34 100644 --- a/screen/settings/encryptStorage.js +++ b/screen/settings/encryptStorage.js @@ -132,14 +132,12 @@ const EncryptStorage = () => { isCapable = false; } } - if (isCapable) { - return isCapable ? ( - <> - - {loc.formatString(loc.settings.biometrics_fail, { type: biometrics.biometricsType })} - - ) : null; - } + return isCapable ? ( + <> + + {loc.formatString(loc.settings.biometrics_fail, { type: biometrics.biometricsType })} + + ) : null; }; return (