Skip to main content

OneVault configuration

What is OneVault?

ShareRing Vault SDK can be configured so that with multiple applications using the same Vault SDK installed on one device, they all refer to one set of files and data. Vault data will be stored on external storage (Android) and on a shared app group contrainer (iOS) so that apps can point to the same location when they read/write vault data.

For better visualization, say if a user has two apps using the SDK installed on a device, he logs in to one app, App A, and upload his documents. When he opens the other app, App B, he can just key in the passphrase and "login with App A". He can then see his data showing up on App B.

Configuration

iOS

App Groups must be enabled to allow communication between multiple apps. In <.entitlements> file, add path group group.sharering.network.

Deeplink is required to interact between apps:

  • For main app, add scheme "sharering"
  • For second app, add scheme "myapp"

Limitation

It appears that only apps signing under the same provisioning profile can share the same app group. We already take this into consideration and there could be an upgrade to our synchronisation mechanism to cover.

Android

For apps targeting Android 10 (API level 29) or earlier, declare the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permission in your Manifest.xml file.

For apps targeting Android 11 (API level 30) or later, some additional steps are required:

  1. Declare MANAGE_EXTERNAL_STORAGE permission in the manifest.
  2. Use ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent action to direct users to settings page where they can switch the Allow access to manage all files on.

Deeplink is required to interact between apps:

  • For main app, add scheme "sharering"
  • For second app, add scheme "myapp"

On React-Native, step 2 can be done as following:

Create /android/app/source/main/java/<package_name>/PermissionFileModule.java with the following content:


package com.domain.yourapp;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.uimanager.IllegalViewOperationException;

import javax.annotation.Nullable;

public class PermissionFileModule extends ReactContextBaseJavaModule implements ActivityEventListener {

public PermissionFileModule(@Nullable ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addActivityEventListener(this);
}

@NonNull
@Override
public String getName() {
return "PermissionFile";
}

@ReactMethod
public void checkPermission(Callback errorCallback, Callback successCallback) {
try {
if (!checkPermission()) {
successCallback.invoke(false);
} else {
successCallback.invoke(true);
}
} catch (IllegalViewOperationException e) {
errorCallback.invoke(e.getMessage());
}
}

@ReactMethod
public void grantPermission() {
try {
requestPermission();
} catch (Exception e) {
}
}

private boolean checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(getReactApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(getReactApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}

private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s",getReactApplicationContext().getPackageName())));
getCurrentActivity().startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
getCurrentActivity().startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions(getCurrentActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
}

@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (requestCode == 2296) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
Toast.makeText(getReactApplicationContext(), "Access granted", Toast.LENGTH_SHORT).show();
} else {
//Toast.makeText(getReactApplicationContext(), "Access not granted", Toast.LENGTH_SHORT).show();
}
}
}
}

@Override
public void onNewIntent(Intent intent) {
// do nothing
}
}

Create /android/app/source/main/java/<package_name>/PermissionFilePackage.java with the following content:


package com.domain.yourapp;

import androidx.annotation.NonNull;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.ReactPackage;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PermissionFilePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();

modules.add(new PermissionFileModule(reactContext));
return modules;
}

@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

Then, in your React-Native code you can call it like so:


function requestManagerExternalStoragePermission() {
try {
if (Platform.Version >= 30) {
PermissionFile.checkPermission(
(err) => {
//
},
(res) => {
if (res) {
//
} else {
return Alert.alert(
'Storage permission necessary..',
'This app need to access to device storage, please grant the permission on Android Settings.',
[
{ text: 'Open Settings', onPress: () => {
PermissionFile.grantPermission()
} },
],
{ cancelable: false }
)
}
},
);
} else {
return requestWriteExternalStoragePermission()
}

} catch (err) {
console.log(err)
}
}

Usage

On the target app that you want to allow users to login with the source app, use loginWithSharering() function on shr-vault sdk.