Skip to content
This repository has been archived by the owner on Nov 7, 2023. It is now read-only.

Commit

Permalink
fix: Fix library crashing on android 5.x
Browse files Browse the repository at this point in the history
  • Loading branch information
alesharik committed Dec 24, 2020
1 parent e009274 commit a188cef
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 11 deletions.
15 changes: 13 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import groovy.json.JsonSlurper

def DEFAULT_COMPILE_SDK_VERSION = 29
def DEFAULT_BUILD_TOOLS_VERSION = '28.0.3'
def DEFAULT_MIN_SDK_VERSION = 23
def DEFAULT_MIN_SDK_VERSION = 21
def DEFAULT_TARGET_SDK_VERSION = 29

def safeExtGet(prop, fallback) {
Expand Down Expand Up @@ -55,10 +55,15 @@ android {
targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION)
versionCode 41
versionName "3.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

repositories {
Expand All @@ -80,7 +85,13 @@ dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+'

implementation "androidx.security:security-crypto:1.1.0-alpha02"
implementation "androidx.security:security-crypto:1.1.0-alpha03"

testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
//noinspection GradleDependency
androidTestImplementation 'org.mockito:mockito-android:3.4.6'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

def configureReactNativePom(def pom) {
Expand Down
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.emeraldsanto.encryptedstorage;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

@RunWith(AndroidJUnit4.class)
public class RNEncryptedStorageModuleUnitTest {
private RNEncryptedStorageModule module;

@Before
public void setUp() {
module = new RNEncryptedStorageModule(new ReactApplicationContext(InstrumentationRegistry.getInstrumentation().getTargetContext()));
module.clear(mock(Promise.class));
}

@Test
public void shouldGetAndSet() {
Promise promise1 = mock(Promise.class);
module.getItem("test", promise1);
verify(promise1).resolve(null);

Promise promise2 = mock(Promise.class);
module.setItem("test", "asd", promise2);
verify(promise2).resolve("asd");

Promise promise3 = mock(Promise.class);
module.getItem("test", promise3);
verify(promise3).resolve("asd");
}

@Test
public void shouldRemove() {
Promise promise1 = mock(Promise.class);
module.setItem("test", "asd", promise1);
verify(promise1).resolve("asd");

Promise promise2 = mock(Promise.class);
module.getItem("test", promise2);
verify(promise2).resolve("asd");

Promise promise3 = mock(Promise.class);
module.removeItem("test", promise3);
verify(promise3).resolve("test");

Promise promise4 = mock(Promise.class);
module.getItem("test", promise4);
verify(promise4).resolve(null);
}

@Test
public void shouldClear() {
Promise promise1 = mock(Promise.class);
module.setItem("test", "asd", promise1);
verify(promise1).resolve("asd");

Promise promise2 = mock(Promise.class);
module.getItem("test", promise2);
verify(promise2).resolve("asd");

Promise promise3 = mock(Promise.class);
module.clear(promise3);
verify(promise3).resolve(null);

Promise promise4 = mock(Promise.class);
module.getItem("test", promise4);
verify(promise4).resolve(null);
}

@Test
public void shouldKeepValuesWhenRecreated() {
Promise promise1 = mock(Promise.class);
module.setItem("test", "asd", promise1);
verify(promise1).resolve("asd");

module = new RNEncryptedStorageModule(new ReactApplicationContext(InstrumentationRegistry.getInstrumentation().getTargetContext()));

Promise promise2 = mock(Promise.class);
module.getItem("test", promise2);
verify(promise2).resolve("asd");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,40 @@

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;

import android.util.Log;
import androidx.security.crypto.EncryptedSharedPreferences;
import androidx.security.crypto.MasterKeys;

import androidx.security.crypto.MasterKey;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class RNEncryptedStorageModule extends ReactContextBaseJavaModule {

private static String NATIVE_MODULE_NAME = "RNEncryptedStorage";
private static String SHARED_PREFERENCES_FILENAME = "RN_ENCRYPTED_STORAGE_SHARED_PREF";
private static final String NATIVE_MODULE_NAME = "RNEncryptedStorage";
private static final String SHARED_PREFERENCES_FILENAME = "RN_ENCRYPTED_STORAGE_SHARED_PREF";

private SharedPreferences sharedPreferences;

public RNEncryptedStorageModule(ReactApplicationContext context) {
super(context);

try {
MasterKey key = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();

this.sharedPreferences = EncryptedSharedPreferences.create(
RNEncryptedStorageModule.SHARED_PREFERENCES_FILENAME,
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
context,
RNEncryptedStorageModule.SHARED_PREFERENCES_FILENAME,
key,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
}

catch (Exception ex) {
Log.e(NATIVE_MODULE_NAME, "Failed to create encrypted shared preferences! Failing back to standard SharedPreferences", ex);
this.sharedPreferences = context.getSharedPreferences(RNEncryptedStorageModule.SHARED_PREFERENCES_FILENAME, Context.MODE_PRIVATE);
}
}
Expand Down

0 comments on commit a188cef

Please sign in to comment.