mirror of
https://github.com/luxfi/safe-wallet.git
synced 2026-11-03 10:22:58 +00:00
* fix(mobile): upgrade react-native-quick-crypto for Android 16KB page size support Upgrade react-native-quick-crypto from 0.7.x to 1.0.17 to support Android 16KB page size requirement. Add react-native-nitro-modules and react-native-quick-base64 as new peer dependencies. Update react-native-device-crypto patch to remove deprecated jcenter() repository references for Gradle 9.0 compatibility. * chore(mobile): remove unused config/ethers.ts Dead code — crypto-shims.ts in platform/ is the active version imported by the root layout. * fix(mobile): deduplicate react-native-quick-base64 via resolution Add root resolution to force a single copy of react-native-quick-base64 (2.2.2), avoiding version skew between the direct dependency and the transitive one from @craftzdog/react-native-buffer. * fix(mobile): upgrade react-native-mmkv to v4 and pin MMKV pod - Upgrade react-native-mmkv from 3.x to 4.2.0 (Nitro-based rewrite) - Migrate API: new MMKV() -> createMMKV(), .delete() -> .remove() - Pin MMKV pod to ~> 2.3.0 in notification extension plugin instead of master branch, fixing sharedApplication build error in App Extensions - Update expo plugin config.ts (source of truth for Podfile template) * docs: add solution doc for Expo native file editing workflow Document that generated native files (ios/Podfile etc.) must be modified through Expo config plugins, not directly. Also unignore docs/solutions/ from .gitignore. * fix(mobile): add jest mocks for react-native-nitro-modules and mmkv v4 MMKV v4 uses NitroModules under the hood, which requires mocking in the test environment. Add mocks for both react-native-nitro-modules and the new react-native-mmkv createMMKV API. --------- Co-authored-by: Hanzo Dev <[email protected]>
126 lines
5.4 KiB
Diff
126 lines
5.4 KiB
Diff
diff --git a/android/build.gradle b/android/build.gradle
|
|
index 8eb758ed063d1905f538f72e3ee55a8c41e01d18..d1ee770a3594017357465e031c2edb4aae6a448c 100644
|
|
--- a/android/build.gradle
|
|
+++ b/android/build.gradle
|
|
@@ -3,7 +3,6 @@ buildscript {
|
|
repositories {
|
|
google()
|
|
mavenCentral()
|
|
- jcenter()
|
|
}
|
|
|
|
dependencies {
|
|
@@ -52,7 +51,6 @@ repositories {
|
|
}
|
|
google()
|
|
mavenCentral()
|
|
- jcenter()
|
|
}
|
|
|
|
dependencies {
|
|
diff --git a/android/src/main/java/com/reactnativedevicecrypto/Helpers.java b/android/src/main/java/com/reactnativedevicecrypto/Helpers.java
|
|
index 03fd79e8a389f33a2841ecf0e177ffc9ea01b78c..d903b5dc4b0110dab9a8c1a648d349200dd4e20f 100644
|
|
--- a/android/src/main/java/com/reactnativedevicecrypto/Helpers.java
|
|
+++ b/android/src/main/java/com/reactnativedevicecrypto/Helpers.java
|
|
@@ -39,6 +39,7 @@ public class Helpers {
|
|
private static final int AES_IV_SIZE = 128;
|
|
public static final String PEM_HEADER = "-----BEGIN PUBLIC KEY-----\n";
|
|
public static final String PEM_FOOTER = "-----END PUBLIC KEY-----";
|
|
+ private static Boolean sIsStrongBoxSupported = null; // Cache for StrongBox support
|
|
|
|
public interface KeyType {
|
|
@Retention(SOURCE)
|
|
@@ -81,6 +82,64 @@ public class Helpers {
|
|
}
|
|
}
|
|
|
|
+ public static boolean isStrongBoxSupported() {
|
|
+ // Return cached result if available
|
|
+ if (sIsStrongBoxSupported != null) {
|
|
+ return sIsStrongBoxSupported;
|
|
+ }
|
|
+
|
|
+ // Try to create a key with StrongBox requirement and see if it succeeds
|
|
+ String testAlias = "test_strongbox_support";
|
|
+ try {
|
|
+ // First, clean up any existing test key
|
|
+ try {
|
|
+ KeyStore keyStore = getKeyStore();
|
|
+ if (keyStore.containsAlias(testAlias)) {
|
|
+ keyStore.deleteEntry(testAlias);
|
|
+ }
|
|
+ } catch (Exception e) {
|
|
+ // Ignore errors during cleanup
|
|
+ }
|
|
+
|
|
+ // Attempt to create a key with StrongBox backing
|
|
+ KeyGenParameterSpec testSpec = new KeyGenParameterSpec.Builder(testAlias, KeyProperties.PURPOSE_ENCRYPT)
|
|
+ .setIsStrongBoxBacked(true)
|
|
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
|
|
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
|
+ .setKeySize(256)
|
|
+ .build();
|
|
+ KeyGenerator testKeyGen = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, KEY_STORE);
|
|
+ testKeyGen.init(testSpec);
|
|
+ testKeyGen.generateKey();
|
|
+
|
|
+ // If we reach here, StrongBox is supported
|
|
+ // Clean up the test key
|
|
+ KeyStore keyStore = getKeyStore();
|
|
+ keyStore.deleteEntry(testAlias);
|
|
+
|
|
+ // Cache the result
|
|
+ sIsStrongBoxSupported = true;
|
|
+ Log.i(RN_MODULE, "StrongBox is supported on this device");
|
|
+ return true;
|
|
+ } catch (Exception e) {
|
|
+ Log.i(RN_MODULE, "StrongBox not supported on this device: " + e.getMessage());
|
|
+
|
|
+ // Clean up any test key that might have been created
|
|
+ try {
|
|
+ KeyStore keyStore = getKeyStore();
|
|
+ if (keyStore.containsAlias(testAlias)) {
|
|
+ keyStore.deleteEntry(testAlias);
|
|
+ }
|
|
+ } catch (Exception cleanupEx) {
|
|
+ // Ignore errors during cleanup
|
|
+ }
|
|
+
|
|
+ // Cache the result
|
|
+ sIsStrongBoxSupported = false;
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
public static boolean isKeyExists(@NonNull String alias, @KeyType.Types int keyType) throws Exception {
|
|
KeyStore keyStore = Helpers.getKeyStore();
|
|
if (!keyStore.containsAlias(alias)) {
|
|
@@ -134,17 +193,22 @@ public class Helpers {
|
|
case AccessLevel.AUTHENTICATION_REQUIRED:
|
|
// Sets whether this key is authorized to be used only if the user has been authenticated.
|
|
builder.setUserAuthenticationRequired(true);
|
|
+
|
|
// Allow pin/pass as a fallback on API 30+
|
|
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
- builder.setUserAuthenticationParameters(0, KeyProperties.AUTH_DEVICE_CREDENTIAL | KeyProperties.AUTH_BIOMETRIC_STRONG);
|
|
- }
|
|
+ // Disabled this as it prevents invalidation of the user removes the biometric
|
|
+ // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
+ // builder.setUserAuthenticationParameters(0, KeyProperties.AUTH_DEVICE_CREDENTIAL | KeyProperties.AUTH_BIOMETRIC_STRONG);
|
|
+ // }
|
|
+
|
|
// Invalidate the keys if the user has registered a new biometric
|
|
// credential. The variable "invalidatedByBiometricEnrollment" is true by default.
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
builder.setInvalidatedByBiometricEnrollment(invalidateOnNewBiometry);
|
|
}
|
|
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
|
|
- builder.setIsStrongBoxBacked(true);
|
|
+ // Only try to enable StrongBox if API level is high enough and the device
|
|
+ // actually supports it
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && isStrongBoxSupported()) {
|
|
+ builder.setIsStrongBoxBacked(true);
|
|
}
|
|
break;
|
|
}
|