Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage: migrate to RN Encrypted Storage and add updateSettings func #1229

Merged
merged 3 commits into from
Dec 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'com.android.support:multidex:1.0.3'
implementation project(':react-native-randombytes')
implementation project(':react-native-secure-key-store')
implementation "androidx.core:core:1.1.0"
implementation "com.facebook.react:react-native:+" // From node_modules
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
Expand Down
2 changes: 0 additions & 2 deletions android/app/src/main/java/com/zeus/MainApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
import com.facebook.react.ReactPackage;
import android.content.Context;

import com.reactlibrary.securekeystore.RNSecureKeyStorePackage;

import com.facebook.soloader.SoLoader;

import java.lang.reflect.InvocationTargetException;
Expand Down
4 changes: 0 additions & 4 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ include ':react-native-gesture-handler'
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
include ':react-native-randombytes'
project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android')
include ':react-native-secure-key-store'
project(':react-native-secure-key-store').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-secure-key-store/android')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':react-native-secure-key-store'
project(':react-native-secure-key-store').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-secure-key-store/android')
include ':react-native-restart'
project(':react-native-restart').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-restart/android')

Expand Down
12 changes: 0 additions & 12 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ PODS:
- React-Core
- react-native-safe-area-context (0.6.2):
- React
- react-native-secure-key-store (2.0.10):
- React-Core
- react-native-tor (0.1.8):
- React
- react-native-udp (2.7.0):
Expand Down Expand Up @@ -337,8 +335,6 @@ PODS:
- React-jsi (= 0.70.6)
- React-logger (= 0.70.6)
- React-perflogger (= 0.70.6)
- RNCAsyncStorage (1.15.17):
- React-Core
- RNCClipboard (1.9.0):
- React-Core
- RNCMaskedView (0.1.11):
Expand Down Expand Up @@ -392,7 +388,6 @@ DEPENDENCIES:
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-restart (from `../node_modules/react-native-restart`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-secure-key-store (from `../node_modules/react-native-secure-key-store`)
- react-native-tor (from `../node_modules/react-native-tor`)
- react-native-udp (from `../node_modules/react-native-udp`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
Expand All @@ -407,7 +402,6 @@ DEPENDENCIES:
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
- "RNCPicker (from `../node_modules/@react-native-picker/picker`)"
Expand Down Expand Up @@ -486,8 +480,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-restart"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-secure-key-store:
:path: "../node_modules/react-native-secure-key-store"
react-native-tor:
:path: "../node_modules/react-native-tor"
react-native-udp:
Expand Down Expand Up @@ -516,8 +508,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
RNCAsyncStorage:
:path: "../node_modules/@react-native-async-storage/async-storage"
RNCClipboard:
:path: "../node_modules/@react-native-clipboard/clipboard"
RNCMaskedView:
Expand Down Expand Up @@ -571,7 +561,6 @@ SPEC CHECKSUMS:
react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23
react-native-restart: 45c8dca02491980f2958595333cbccd6877cb57e
react-native-safe-area-context: 25260c5d0b9c53fd7aa88e569e2edae72af1f6a3
react-native-secure-key-store: 910e6df6bc33cb790aba6ee24bc7818df1fe5898
react-native-tor: 3b14e9160b2eb7fa3f310921b2dee71a5171e5b7
react-native-udp: ff9d13e523f2b58e6bc5d4d32321ac60671b5dc9
React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
Expand All @@ -586,7 +575,6 @@ SPEC CHECKSUMS:
React-RCTVibration: c75ceef7aa60a33b2d5731ebe5800ddde40cefc4
React-runtimeexecutor: 15437b576139df27635400de0599d9844f1ab817
ReactCommon: 349be31adeecffc7986a0de875d7fb0dcf4e251c
RNCAsyncStorage: 6bd5a7ba3dde1c3facba418aa273f449bdc5437a
RNCClipboard: 99fc8ad669a376b756fbc8098ae2fd05c0ed0668
RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
RNCPicker: 0bf8ef8f7800524f32d2bb2a8bcadd53eda0ecd1
Expand Down
43 changes: 0 additions & 43 deletions ios/zeus.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -255,20 +255,6 @@
remoteGlobalIDString = 163CDE4E2087CAD3001065FB;
remoteInfo = "RNRandomBytes-tvOS";
};
971EAC8C23DCF75600DB5FB3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 971EAC8723DCF75600DB5FB3 /* RNSecureKeyStore.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RNSecureKeyStore;
};
971EAC8E23DCF75600DB5FB3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 971EAC8723DCF75600DB5FB3 /* RNSecureKeyStore.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 465057B52107394900FD399B;
remoteInfo = "RNSecureKeyStore-tvOS";
};
ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
Expand Down Expand Up @@ -360,7 +346,6 @@
8F0CAEBF09CC44E0A55DFB2A /* Coins.svg */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Coins.svg; path = ../assets/images/SVG/Coins.svg; sourceTree = "<group>"; };
904B772D015A42D58EF60A9A /* Word Logo - no outline.svg */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Word Logo - no outline.svg"; path = "../assets/images/SVG/Word Logo - no outline.svg"; sourceTree = "<group>"; };
970050862460D71500AA6E33 /* RNRandomBytes.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNRandomBytes.xcodeproj; path = "../node_modules/react-native-randombytes/RNRandomBytes.xcodeproj"; sourceTree = "<group>"; };
971EAC8723DCF75600DB5FB3 /* RNSecureKeyStore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNSecureKeyStore.xcodeproj; path = "../node_modules/react-native-secure-key-store/ios/RNSecureKeyStore.xcodeproj"; sourceTree = "<group>"; };
97D6EB5926C47CF5002ADC8C /* ioslauncher.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ioslauncher.png; sourceTree = "<group>"; };
97D9A8F5652E4AC580E97DEF /* Mempool.svg */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Mempool.svg; path = ../assets/images/affiliates/Mempool.svg; sourceTree = "<group>"; };
97F6D46922054E640030F13B /* Octicons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Octicons.ttf; sourceTree = "<group>"; };
Expand Down Expand Up @@ -589,7 +574,6 @@
isa = PBXGroup;
children = (
970050862460D71500AA6E33 /* RNRandomBytes.xcodeproj */,
971EAC8723DCF75600DB5FB3 /* RNSecureKeyStore.xcodeproj */,
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */,
Expand Down Expand Up @@ -663,15 +647,6 @@
name = Products;
sourceTree = "<group>";
};
971EAC8823DCF75600DB5FB3 /* Products */ = {
isa = PBXGroup;
children = (
971EAC8D23DCF75600DB5FB3 /* libRNSecureKeyStore.a */,
971EAC8F23DCF75600DB5FB3 /* libRNSecureKeyStore-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
};
97CC1CCA2200A9920031CA45 /* Recovered References */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -965,10 +940,6 @@
ProductGroup = 970050872460D71500AA6E33 /* Products */;
ProjectRef = 970050862460D71500AA6E33 /* RNRandomBytes.xcodeproj */;
},
{
ProductGroup = 971EAC8823DCF75600DB5FB3 /* Products */;
ProjectRef = 971EAC8723DCF75600DB5FB3 /* RNSecureKeyStore.xcodeproj */;
},
);
projectRoot = "";
targets = (
Expand Down Expand Up @@ -1128,20 +1099,6 @@
remoteRef = 9700508D2460D71600AA6E33 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
971EAC8D23DCF75600DB5FB3 /* libRNSecureKeyStore.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRNSecureKeyStore.a;
remoteRef = 971EAC8C23DCF75600DB5FB3 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
971EAC8F23DCF75600DB5FB3 /* libRNSecureKeyStore-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRNSecureKeyStore-tvOS.a";
remoteRef = 971EAC8E23DCF75600DB5FB3 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"@keystonehq/bc-ur-registry": "0.4.2",
"@lightninglabs/lnc-rn": "0.2.1-alpha.2",
"@ngraveio/bc-ur": "1.1.6",
"@react-native-async-storage/async-storage": "1.15.17",
"@react-native-clipboard/clipboard": "1.9.0",
"@react-native-community/masked-view": "0.1.11",
"@react-native-picker/picker": "2.4.8",
Expand Down Expand Up @@ -82,7 +81,6 @@
"react-native-restart": "0.0.24",
"react-native-safe-area-context": "0.6.2",
"react-native-screens": "3.10.1",
"react-native-secure-key-store": "2.0.10",
"react-native-snap-carousel": "meliorence/react-native-snap-carousel#962/head",
"react-native-svg": "13.6.0",
"react-native-svg-transformer": "1.0.0",
Expand Down
59 changes: 13 additions & 46 deletions stores/LnurlPayStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { action } from 'mobx';
import { LNURLPaySuccessAction } from 'js-lnurl';
import AsyncStorage from '@react-native-async-storage/async-storage';
import EncryptedStorage from 'react-native-encrypted-storage';
import SettingsStore from './SettingsStore';
import NodeInfoStore from './NodeInfoStore';

Expand All @@ -11,22 +11,13 @@ export interface LnurlPayTransaction {
metadata_hash: string;
successAction: LNURLPaySuccessAction;
time: number;
metadata?: Metadata; // only after an independent load from AsyncStorage.
metadata?: Metadata; // only after an independent load from EncryptedStorage.
}

interface Metadata {
metadata: string;
}

// interface LnurlPaySuccessAction {
// tag: string;
// description?: string;
// url: string;
// message: string;
// iv: string;
// ciphertext: string;
// }

interface LnurlPayMetadataEntry {
metadata: string;
last_stored: number;
Expand All @@ -42,44 +33,16 @@ export default class LnurlPayStore {
constructor(settingsStore: SettingsStore, nodeInfoStore: NodeInfoStore) {
this.settingsStore = settingsStore;
this.nodeInfoStore = nodeInfoStore;

if (Math.random() < 0.1) {
setTimeout(() => {
this.deleteOld();
}, 100000);
}
}

deleteOld = async () => {
// delete all lnurlpay keys older than 30 days
const daysago30 = new Date().getTime() - 1000 * 60 * 60 * 24 * 30;
const allKeys = await AsyncStorage.getAllKeys();
const toRemove = [];
for (let i = 0; i < allKeys.length; i++) {
const key = allKeys[i];
if (key.slice(0, 9) === 'lnurlpay:') {
const itemString = await AsyncStorage.getItem(key);
const item = JSON.parse(itemString || '');
if (
(item.last_stored && item.last_stored < daysago30) ||
(item.time && item.time < daysago30)
) {
toRemove.push(key);
}
}
}

AsyncStorage.multiRemove(toRemove);
};

@action
public load = async (paymentHash: string): Promise<LnurlPayTransaction> => {
let lnurlpaytx: any = await AsyncStorage.getItem(
let lnurlpaytx: any = await EncryptedStorage.getItem(
'lnurlpay:' + paymentHash
);
if (lnurlpaytx) {
lnurlpaytx = JSON.parse(lnurlpaytx);
const metadata: any = await AsyncStorage.getItem(
const metadata: any = await EncryptedStorage.getItem(
'lnurlpay:' + lnurlpaytx.metadata_hash
);
if (metadata) {
Expand All @@ -91,7 +54,7 @@ export default class LnurlPayStore {
};

@action
public keep = (
public keep = async (
paymentHash: string,
domain: string,
lnurl: string,
Expand All @@ -115,10 +78,14 @@ export default class LnurlPayStore {
last_stored: now
};

AsyncStorage.multiSet([
['lnurlpay:' + paymentHash, JSON.stringify(transactionData)],
['lnurlpay:' + descriptionHash, JSON.stringify(metadataEntry)]
]);
await EncryptedStorage.setItem(
'lnurlpay:' + paymentHash,
JSON.stringify(transactionData)
);
await EncryptedStorage.setItem(
'lnurlpay:' + descriptionHash,
JSON.stringify(metadataEntry)
);

this.paymentHash = paymentHash;
this.successAction = successAction;
Expand Down
31 changes: 20 additions & 11 deletions stores/SettingsStore.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import RNSecureKeyStore, { ACCESSIBLE } from 'react-native-secure-key-store';
import EncryptedStorage from 'react-native-encrypted-storage';
import { action, observable } from 'mobx';
import ReactNativeBlobUtil from 'react-native-blob-util';

Expand Down Expand Up @@ -155,6 +155,9 @@ export const THEME_KEYS = [
export const DEFAULT_THEME = 'dark';
export const DEFAULT_FIAT = 'Disabled';
export const DEFAULT_LOCALE = 'English';

const STORAGE_KEY = 'zeus-settings';

export default class SettingsStore {
@observable settings: Settings = {
privacy: {
Expand Down Expand Up @@ -333,8 +336,8 @@ export default class SettingsStore {
this.loading = true;
try {
// Retrieve the credentials
const credentials: any = await RNSecureKeyStore.get(
'zeus-settings'
const credentials: any = await EncryptedStorage.getItem(
STORAGE_KEY
);
if (credentials) {
this.settings = JSON.parse(credentials);
Expand Down Expand Up @@ -373,16 +376,22 @@ export default class SettingsStore {
@action
public async setSettings(settings: string) {
this.loading = true;

// Store the credentials
await RNSecureKeyStore.set('zeus-settings', settings, {
accessible: ACCESSIBLE.WHEN_UNLOCKED
}).then(() => {
this.loading = false;
return settings;
});
await EncryptedStorage.setItem(STORAGE_KEY, settings);
this.loading = false;
return settings;
}

@action
public updateSettings = async (newSetting: any) => {
const newSettings = {
...this.settings,
...newSetting
};

await this.setSettings(JSON.stringify(newSettings));
return newSettings;
};

// LNDHub
@action
public createAccount = (
Expand Down
Loading