mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 13:38:01 -05:00
Inji-411: vc load optimisation (#927)
* feat(inji-406): store vc before storing hmac to avoid race condition Signed-off-by: Tilak Puli <tilakpuli15@gmail.com> * feat(inji-406): waiting until vc saved completely before displaying VC card Signed-off-by: Tilak Puli <tilakpuli15@gmail.com> * feat(inji-411): read and cache vc files data on welcome screen Signed-off-by: Tilak Puli <tilakpuli15@gmail.com> * feat(inji-411): remove formatting for unnecessary files Signed-off-by: Tilak Puli <tilakpuli15@gmail.com> --------- Signed-off-by: Tilak Puli <tilakpuli15@gmail.com>
This commit is contained in:
29
.talismanrc
29
.talismanrc
@@ -0,0 +1,29 @@
|
||||
fileignoreconfig:
|
||||
- filename: package.json
|
||||
checksum: 30e3a548809705ba38385a1c286b312629ac5dd7dea0d6e26ffb9daf8def312d
|
||||
- filename: package-lock.json
|
||||
checksum: 4d595248dfa13967eef07ffee65f86809672a0d145d74b9df55b296bdbe29f78
|
||||
- filename: components/PasscodeVerify.tsx
|
||||
checksum: 14654c0f038979fcd0d260170a45894a072f81e0767ca9a0e66935d33b5cc703
|
||||
- filename: i18n.ts
|
||||
checksum: 75dd5536038ba198aa7b12eb6d2c2e7042c9ce292e5a0d5c90883ae5b2312b1e
|
||||
- filename: screens/BiometricScreenController.ts
|
||||
checksum: b3d0184fb894f4a9ffa1a4d277d2975495dbc47771593895bf1999deabafeb94
|
||||
- filename: screens/Home/MyVcs/IdInputModal.tsx
|
||||
checksum: ec48ebeaf46b8fbc756f19ef8ffe8901ce0528aef164f3c7ffdeec36fb53ffc6
|
||||
- filename: components/Passcode.tsx
|
||||
checksum: db4a18001be8c63bf7ffb389359861401fa1d22261b10ad729a76fd431c019a7
|
||||
- filename: screens/PasscodeScreen.tsx
|
||||
checksum: 0cc5b91350e491a058ee8a1878a496c16b65f14969e989bdb1c354f6e9b8c03c
|
||||
- filename: locales/spa.json
|
||||
checksum: 981103ff872d6f54610468c7ead65873d9294a11092649b105c552f770f0214b
|
||||
- filename: screens/AuthScreen.tsx
|
||||
checksum: 2c1183b2ad8ec27adf8f389a2511805493f229fdda674064e2579d2032119d1c
|
||||
- filename: screens/BiometricScreen.tsx
|
||||
checksum: 7a730731aaa7540eec9d05d73de277a665dc06425666280842e0f9ba6e5b8514
|
||||
- filename: screens/AuthScreenController.ts
|
||||
checksum: 18af825821bc95e1056050623b804a5a8e7435b9e3383916a5d63024eeba9553
|
||||
- filename: screens/WelcomeScreenController.ts
|
||||
checksum: d8fe74404c80bf435459f4d20427a661fb622f0ee9f754345616abd346b98d14
|
||||
- filename: shared/telemetry/TelemetryUtils.js
|
||||
checksum: 9a61cd59a3718adf1f14faf3024fec66a3295ef373878a878a28e5cb1287afaa
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
isCustomSecureKeystore,
|
||||
} from '../shared/cryptoutil/cryptoUtil';
|
||||
import {VCMetadata} from '../shared/VCMetadata';
|
||||
import FileStorage, {getFilePath} from '../shared/fileStorage';
|
||||
|
||||
export const keyinvalidatedString =
|
||||
'Key Invalidated due to biometric enrollment';
|
||||
@@ -173,7 +174,7 @@ export const storeMachine =
|
||||
},
|
||||
},
|
||||
ready: {
|
||||
entry: 'notifyParent',
|
||||
entry: ['notifyParent', 'cacheVCFilesData'],
|
||||
invoke: {
|
||||
src: 'store',
|
||||
id: '_store',
|
||||
@@ -259,6 +260,18 @@ export const storeMachine =
|
||||
setEncryptionKey: model.assign({
|
||||
encryptionKey: (_, event) => event.key,
|
||||
}),
|
||||
|
||||
cacheVCFilesData: context => {
|
||||
getItem(MY_VCS_STORE_KEY, [], context.encryptionKey).then(vcList => {
|
||||
if (vcList) {
|
||||
vcList?.forEach((vcMetadataStr: string) => {
|
||||
const vcKey =
|
||||
VCMetadata.fromVcMetadataString(vcMetadataStr).getVcKey();
|
||||
FileStorage.readAndCacheFile(getFilePath(vcKey));
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
services: {
|
||||
@@ -289,6 +302,7 @@ export const storeMachine =
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
checkStorageInitialisedOrNot: () => async callback => {
|
||||
const isDirectoryExist = await Storage.isVCStorageInitialised();
|
||||
if (!isDirectoryExist) {
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -84,7 +84,7 @@
|
||||
"react-native-vector-icons": "^10.0.0",
|
||||
"short-unique-id": "^4.4.4",
|
||||
"simple-pem2jwk": "^0.2.4",
|
||||
"telemetry-sdk": "git://github.com/mosip/sunbird-telemetry-sdk.git#f762be5732ee552c0c70bdd540aa4e2701554c71",
|
||||
"telemetry-sdk": "git://github.com/mosip/sunbird-telemetry-sdk.git#develop",
|
||||
"xstate": "^4.35.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -53475,7 +53475,7 @@
|
||||
"telemetry-sdk": {
|
||||
"version": "git+ssh://git@github.com/mosip/sunbird-telemetry-sdk.git#f762be5732ee552c0c70bdd540aa4e2701554c71",
|
||||
"integrity": "sha512-aeA7uO77JzNQVSuUpxzUXK3I+BtYiOzDhcmYbD6R3pAETun4toP1/GR5PBfT9/iE3N5MdGJg70sQArwCIL1XaQ==",
|
||||
"from": "telemetry-sdk@git://github.com/mosip/sunbird-telemetry-sdk.git#f762be5732ee552c0c70bdd540aa4e2701554c71",
|
||||
"from": "telemetry-sdk@git://github.com/mosip/sunbird-telemetry-sdk.git#develop",
|
||||
"requires": {
|
||||
"axios": "^1.4.0",
|
||||
"grunt-karma": "^0.12.2",
|
||||
|
||||
87
shared/fileStorage.ts
Normal file
87
shared/fileStorage.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import {
|
||||
DocumentDirectoryPath,
|
||||
exists,
|
||||
mkdir,
|
||||
readFile,
|
||||
stat,
|
||||
unlink,
|
||||
writeFile,
|
||||
} from 'react-native-fs';
|
||||
|
||||
interface CacheData {
|
||||
data?: any;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
interface Cache {
|
||||
[key: string]: CacheData;
|
||||
}
|
||||
|
||||
class FileStorage {
|
||||
cache: Cache = {};
|
||||
|
||||
async readFile(path: string) {
|
||||
return await readFile(path, 'utf8');
|
||||
}
|
||||
|
||||
async readFromCacheFile(path: string) {
|
||||
if (this.cache[path]?.data) {
|
||||
const count = this.cache[path]?.count ?? 0;
|
||||
const data = this.cache[path]?.data;
|
||||
|
||||
if (count != undefined && count <= 1) {
|
||||
this.cache[path] = {};
|
||||
} else {
|
||||
this.cache[path].count = count - 1;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return this.readFile(path);
|
||||
}
|
||||
|
||||
async readAndCacheFile(path: string, useCount: number = 1) {
|
||||
const data = await this.readFile(path);
|
||||
|
||||
this.cache[path] = {
|
||||
data,
|
||||
count: useCount,
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async writeFile(path: string, data: string) {
|
||||
return await writeFile(path, data, 'utf8');
|
||||
}
|
||||
|
||||
async createDirectory(path: string) {
|
||||
return await mkdir(path);
|
||||
}
|
||||
|
||||
async exists(path: string) {
|
||||
return await exists(path);
|
||||
}
|
||||
|
||||
async removeItem(path: string) {
|
||||
return await unlink(path);
|
||||
}
|
||||
|
||||
async getInfo(path: string) {
|
||||
return await stat(path);
|
||||
}
|
||||
}
|
||||
|
||||
export default new FileStorage();
|
||||
|
||||
/**
|
||||
* iOS: /var/mobile/Containers/Data/Application/196A05AD-6B11-403D-BA2D-6DC1F30075E1/Documents/inji/VC/<filename>
|
||||
* android: /data/user/0/io.mosip.residentapp/files/inji/VC/<filename>
|
||||
* These paths are coming from DocumentDirectoryPath in react-native-fs.
|
||||
*/
|
||||
export const getFilePath = (key: string) => {
|
||||
return `${vcDirectoryPath}/${key}.txt`;
|
||||
};
|
||||
|
||||
export const vcDirectoryPath = `${DocumentDirectoryPath}/inji/VC`;
|
||||
@@ -1,14 +1,5 @@
|
||||
import {MMKVLoader} from 'react-native-mmkv-storage';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import {
|
||||
DocumentDirectoryPath,
|
||||
exists,
|
||||
mkdir,
|
||||
readFile,
|
||||
stat,
|
||||
unlink,
|
||||
writeFile,
|
||||
} from 'react-native-fs';
|
||||
import getAllConfigurations from './commonprops/commonProps';
|
||||
import {Platform} from 'react-native';
|
||||
import {
|
||||
@@ -25,9 +16,9 @@ import {
|
||||
import {VCMetadata} from './VCMetadata';
|
||||
import {ENOENT, getItem} from '../machines/store';
|
||||
import {MY_VCS_STORE_KEY, RECEIVED_VCS_STORE_KEY} from './constants';
|
||||
import FileStorage, {getFilePath, vcDirectoryPath} from './fileStorage';
|
||||
|
||||
export const MMKV = new MMKVLoader().initialize();
|
||||
const vcDirectoryPath = `${DocumentDirectoryPath}/inji/VC`;
|
||||
|
||||
export const API_CACHED_STORAGE_KEYS = {
|
||||
fetchIssuers: 'CACHE_FETCH_ISSUERS',
|
||||
@@ -48,7 +39,7 @@ async function generateHmac(
|
||||
class Storage {
|
||||
static isVCStorageInitialised = async (): Promise<boolean> => {
|
||||
try {
|
||||
const res = await stat(vcDirectoryPath);
|
||||
const res = await FileStorage.getInfo(vcDirectoryPath);
|
||||
return res.isDirectory();
|
||||
} catch (_) {
|
||||
return false;
|
||||
@@ -148,7 +139,7 @@ class Storage {
|
||||
}
|
||||
|
||||
private static async readHmacForVC(key: string, encryptionKey: string) {
|
||||
const encryptedHMACofCurrentVC = await MMKV.getItem(getVCKeyName(key));
|
||||
const encryptedHMACofCurrentVC = await MMKV.getItem(key);
|
||||
if (encryptedHMACofCurrentVC) {
|
||||
return decryptJson(encryptionKey, encryptedHMACofCurrentVC);
|
||||
}
|
||||
@@ -156,14 +147,13 @@ class Storage {
|
||||
}
|
||||
|
||||
private static async readVCFromFile(key: string) {
|
||||
const path = getFilePath(key);
|
||||
return await readFile(path, 'utf8');
|
||||
return await FileStorage.readFromCacheFile(getFilePath(key));
|
||||
}
|
||||
|
||||
private static async storeVC(key: string, data: string) {
|
||||
await mkdir(vcDirectoryPath);
|
||||
await FileStorage.createDirectory(vcDirectoryPath);
|
||||
const path = getFilePath(key);
|
||||
return await writeFile(path, data, 'utf8');
|
||||
return await FileStorage.writeFile(path, data);
|
||||
}
|
||||
|
||||
private static async storeVcHmac(
|
||||
@@ -174,15 +164,15 @@ class Storage {
|
||||
const HMACofVC = await generateHmac(encryptionKey, data);
|
||||
console.log('[Inji-406]: Updating hmac of the vc: ', HMACofVC);
|
||||
const encryptedHMACofVC = await encryptJson(encryptionKey, HMACofVC);
|
||||
await MMKV.setItem(getVCKeyName(key), encryptedHMACofVC);
|
||||
await MMKV.setItem(key, encryptedHMACofVC);
|
||||
}
|
||||
|
||||
static removeItem = async (key: string) => {
|
||||
if (VCMetadata.isVCKey(key)) {
|
||||
const path = getFilePath(key);
|
||||
const isFileExists = await exists(path);
|
||||
const isFileExists = await FileStorage.exists(path);
|
||||
if (isFileExists) {
|
||||
return await unlink(path);
|
||||
return await FileStorage.removeItem(path);
|
||||
} else {
|
||||
console.log('file not exist`s');
|
||||
}
|
||||
@@ -192,8 +182,8 @@ class Storage {
|
||||
|
||||
static clear = async () => {
|
||||
try {
|
||||
(await exists(`${vcDirectoryPath}`)) &&
|
||||
(await unlink(`${vcDirectoryPath}`));
|
||||
(await FileStorage.exists(`${vcDirectoryPath}`)) &&
|
||||
(await FileStorage.removeItem(`${vcDirectoryPath}`));
|
||||
MMKV.clearStore();
|
||||
} catch (e) {
|
||||
console.log('Error Occurred while Clearing Storage.', e);
|
||||
@@ -218,35 +208,4 @@ class Storage {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The VC file name will not have the pinned / unpinned state, we will splice the state as this will change.
|
||||
* replace ':' with '_' in the key to get the file name as ':' are not allowed in filenames
|
||||
* eg: "vc:UIN:6732935275:e7426576-112f-466a-961a-1ed9635db628" is changed to "vc_UIN_6732935275_e7426576-112f-466a-961a-1ed9635db628"
|
||||
*/
|
||||
const getFileName = (key: string) => {
|
||||
return key.split(':').splice(0, 4).join('_');
|
||||
};
|
||||
|
||||
/**
|
||||
* iOS: /var/mobile/Containers/Data/Application/196A05AD-6B11-403D-BA2D-6DC1F30075E1/Documents/inji/VC/<filename>
|
||||
* android: /data/user/0/io.mosip.residentapp/files/inji/VC/<filename>
|
||||
* These paths are coming from DocumentDirectoryPath in react-native-fs.
|
||||
*/
|
||||
const getFilePath = (key: string) => {
|
||||
return `${vcDirectoryPath}/${key}.txt`;
|
||||
};
|
||||
|
||||
/**
|
||||
* The VC key will not have the pinned / unpinned state, we will splice the state as this will change.
|
||||
* eg: "vc:UIN:6732935275:e7426576-112f-466a-961a-1ed9635db628:true" is changed to "vc:UIN:6732935275:e7426576-112f-466a-961a-1ed9635db628"
|
||||
*/
|
||||
const getVCKeyName = (key: string) => {
|
||||
return key;
|
||||
};
|
||||
|
||||
// To print the MMKV data cal this function in getItem
|
||||
const getMMKVData = async () => {
|
||||
return await MMKV.indexer.getKeys();
|
||||
};
|
||||
|
||||
export default Storage;
|
||||
|
||||
Reference in New Issue
Block a user