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

Commit

Permalink
Merge branch 'pr/35' into v4
Browse files Browse the repository at this point in the history
  • Loading branch information
emeraldsanto committed Jan 2, 2021
2 parents 226aab1 + a188cef commit 6b7dc85
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 12 deletions.
15 changes: 12 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ def getExtOrIntegerDefault(name) {
android {
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
buildToolsVersion getExtOrDefault('buildToolsVersion')

defaultConfig {
minSdkVersion 23
minSdkVersion 21
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
versionCode 300
versionCode 41
versionName "3.0.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
Expand All @@ -36,6 +37,7 @@ android {
}
}
lintOptions {
abortOnError false
disable 'GradleCompatible'
}
compileOptions {
Expand Down Expand Up @@ -120,4 +122,11 @@ dependencies {
api 'com.facebook.react:react-native:+'

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'
}
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-6.5-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 6b7dc85

Please sign in to comment.