diff --git a/native/ios/Podfile b/native/ios/Podfile --- a/native/ios/Podfile +++ b/native/ios/Podfile @@ -73,11 +73,8 @@ '-DDONT_AUTOINSTALL_REANIMATED -DFOLLY_MOBILE -DFOLLY_USE_LIBCPP -DFOLLY_NO_CONFIG -DFOLLY_CFG_NO_COROUTINES -DFOLLY_HAVE_CLOCK_GETTIME -DRNVERSION=77 -DREANIMATED_VERSION=3.17.2' end - # Lines below are only needed to compile and use Expo Secure Store in - # Notification Service. - # If Apple disapproves 'APPLICATION_EXTENSION_API_ONLY' flag then we can - # safely delete them and use customized Expo Secure Store that does not depend - # on ExpoModulesCore + # Lines below are needed to compile Notification Service + # which depends on RN code installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO' diff --git a/native/ios/Podfile.lock b/native/ios/Podfile.lock --- a/native/ios/Podfile.lock +++ b/native/ios/Podfile.lock @@ -310,8 +310,6 @@ - React-Core - React-RCTAppDelegate - ReactCommon/turbomodule/core - - ExpoSecureStore (14.2.3): - - ExpoModulesCore - ExpoSplashScreen (0.30.8): - ExpoModulesCore - EXUpdatesInterface (1.1.0): @@ -2358,7 +2356,6 @@ - ExpoKeepAwake (from `../../node_modules/expo-keep-awake/ios`) - ExpoMediaLibrary (from `../../node_modules/expo-media-library/ios`) - ExpoModulesCore (from `../../node_modules/expo-modules-core`) - - ExpoSecureStore (from `../../node_modules/expo-secure-store/ios`) - ExpoSplashScreen (from `../../node_modules/expo-splash-screen/ios`) - EXUpdatesInterface (from `../../node_modules/expo-updates-interface/ios`) - fast_float (from `../../node_modules/react-native/third-party-podspecs/fast_float.podspec`) @@ -2523,8 +2520,6 @@ :path: "../../node_modules/expo-media-library/ios" ExpoModulesCore: :path: "../../node_modules/expo-modules-core" - ExpoSecureStore: - :path: "../../node_modules/expo-secure-store/ios" ExpoSplashScreen: :path: "../../node_modules/expo-splash-screen/ios" EXUpdatesInterface: @@ -2738,7 +2733,6 @@ ExpoKeepAwake: e8dedc115d9f6f24b153ccd2d1d8efcdfd68a527 ExpoMediaLibrary: ad61cd80ca07da02be3d676e3d9b04b311a82c2c ExpoModulesCore: a3709f29a5fc4cb3865d0bfb11b39572720eabc4 - ExpoSecureStore: 3148869ad24ab94f9e0c5777c7941d7a37d60399 ExpoSplashScreen: 418ece7a50a404f36b690f0af8ec5c5298dfd659 EXUpdatesInterface: 64f35449b8ef89ce08cdd8952a4d119b5de6821d fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6 @@ -2847,6 +2841,6 @@ Yoga: c758bfb934100bb4bf9cbaccb52557cee35e8bdf ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: 2f62288db927690f146509a7462e565e2babc0d2 +PODFILE CHECKSUM: 5e1474a246e82fdfddfca6475d6eb9acc06f5d5a COCOAPODS: 1.14.3 diff --git a/native/package.json b/native/package.json --- a/native/package.json +++ b/native/package.json @@ -89,7 +89,6 @@ "expo-image-manipulator": "~13.1.7", "expo-image-picker": "~16.1.4", "expo-media-library": "~17.1.6", - "expo-secure-store": "~14.2.3", "expo-splash-screen": "~0.30.8", "fastestsmallesttextencoderdecoder": "^1.0.22", "find-root": "^1.1.0", diff --git a/patches/expo-secure-store+12.0.0.patch b/patches/expo-secure-store+12.0.0.patch deleted file mode 100644 --- a/patches/expo-secure-store+12.0.0.patch +++ /dev/null @@ -1,98 +0,0 @@ -diff --git a/node_modules/expo-secure-store/android/src/main/java/expo/modules/securestore/SecureStoreModule.java b/node_modules/expo-secure-store/android/src/main/java/expo/modules/securestore/SecureStoreModule.java -index 91e9b85..93208a6 100644 ---- a/node_modules/expo-secure-store/android/src/main/java/expo/modules/securestore/SecureStoreModule.java -+++ b/node_modules/expo-secure-store/android/src/main/java/expo/modules/securestore/SecureStoreModule.java -@@ -8,6 +8,7 @@ import android.os.Build; - import android.preference.PreferenceManager; - import android.security.KeyPairGeneratorSpec; - import android.security.keystore.KeyGenParameterSpec; -+import android.security.keystore.KeyPermanentlyInvalidatedException; - import android.security.keystore.KeyProperties; - import android.text.TextUtils; - import android.util.Base64; -@@ -39,6 +40,7 @@ import java.security.spec.InvalidParameterSpecException; - import java.util.Date; - - import javax.crypto.Cipher; -+import javax.crypto.IllegalBlockSizeException; - import javax.crypto.KeyGenerator; - import javax.crypto.NoSuchPaddingException; - import javax.crypto.SecretKey; -@@ -81,14 +83,14 @@ public class SecureStoreModule extends ExportedModule { - @SuppressWarnings("unused") - public void setValueWithKeyAsync(String value, String key, ReadableArguments options, Promise promise) { - try { -- setItemImpl(key, value, options, promise); -+ setItemImpl(key, value, options, promise, false); - } catch (Exception e) { - Log.e(TAG, "Caught unexpected exception when writing to SecureStore", e); - promise.reject("E_SECURESTORE_WRITE_ERROR", "An unexpected error occurred when writing to SecureStore", e); - } - } - -- private void setItemImpl(String key, String value, ReadableArguments options, Promise promise) { -+ private void setItemImpl(String key, String value, ReadableArguments options, Promise promise, boolean keyIsInvalidated) { - if (key == null) { - promise.reject("E_SECURESTORE_NULL_KEY", "SecureStore keys must not be null"); - return; -@@ -109,11 +111,19 @@ public class SecureStoreModule extends ExportedModule { - try { - KeyStore keyStore = getKeyStore(); - -+ -+ - // Android API 23+ supports storing symmetric keys in the keystore and on older Android - // versions we store an asymmetric key pair and use hybrid encryption. We store the scheme we - // use in the encrypted JSON item so that we know how to decode and decrypt it when reading - // back a value. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { -+ // Fixing key invalidated crash -+ if(keyIsInvalidated) { -+ String alias = mAESEncrypter.getKeyStoreAlias(options); -+ keyStore.deleteEntry(alias); -+ } -+ - KeyStore.SecretKeyEntry secretKeyEntry = getKeyEntry(KeyStore.SecretKeyEntry.class, mAESEncrypter, options); - mAESEncrypter.createEncryptedItem(promise, value, keyStore, secretKeyEntry, options, mAuthenticationHelper.getDefaultCallback(), (innerPromise, result) -> { - JSONObject obj = (JSONObject) result; -@@ -132,10 +142,32 @@ public class SecureStoreModule extends ExportedModule { - Log.w(TAG, e); - promise.reject("E_SECURESTORE_IO_ERROR", "There was an I/O error loading the keystore for SecureStore", e); - return; -+ } catch (IllegalBlockSizeException e){ -+ boolean isInvalidationException = e.getCause() != null && e.getCause().getMessage() != null && e.getCause().getMessage().contains("Key user not authenticated"); -+ -+ if(isInvalidationException && !keyIsInvalidated) { -+ setItemImpl(key, value, options, promise, true); -+ Log.w(TAG, "IllegalBlockSizeException, retrying with the key deleted"); -+ return; -+ } -+ // If the issue persists after deleting the key it is likely not related to invalidation -+ promise.reject("E_SECURESTORE_ENCRYPT_ERROR", "Unable to decrypt the key", e); - } catch (GeneralSecurityException e) { -- Log.w(TAG, e); -- promise.reject("E_SECURESTORE_ENCRYPT_ERROR", "Could not encrypt the value for SecureStore", e); -- return; -+ boolean isInvalidationException = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && e instanceof KeyPermanentlyInvalidatedException; -+ -+ if (isInvalidationException && !keyIsInvalidated) { -+ // If the key has been invalidated by the OS we try to reinitialize it. -+ Log.w(TAG, "Key has been invalidated, retrying with the key deleted"); -+ setItemImpl(key, value, options, promise, true); -+ } else if (isInvalidationException) { -+ Log.w(TAG, e); -+ // If reinitialization of the key fails, reject the promise -+ promise.reject("E_SECURESTORE_ENCRYPT_ERROR", "Encryption Failed. The key has been permanently invalidated and cannot be reinitialized", e); -+ } else { -+ Log.w(TAG, e); -+ promise.reject("E_SECURESTORE_ENCRYPT_ERROR", "Could not encrypt the value for SecureStore", e); -+ return; -+ } - } catch (JSONException e) { - Log.w(TAG, e); - promise.reject("E_SECURESTORE_ENCODE_ERROR", "Could not create an encrypted JSON item for SecureStore", e); -@@ -661,3 +693,4 @@ public class SecureStoreModule extends ExportedModule { - } - } - } -+