feat(INJI-202): hash uin/vid to store in mmkv and file storage (#780)

* feat(INJI-202): hash uin/vid to store in mmkv and file storage

* feat(INJI-202): refactor to store salt in constants

* feat(INJI-202): refactor argon2i salt and add function to get MMKV data

* feat(INJI-202): refactor to get mkkv data method

---------

Co-authored-by: Pooja Babusingh <68894211+PoojaBabusingh@users.noreply.github.com>
This commit is contained in:
PoojaBabusing
2023-08-29 12:48:18 +05:30
committed by GitHub
parent 101edaa3c3
commit 3b9baa0962
7 changed files with 80 additions and 9 deletions

View File

@@ -1,6 +1,11 @@
import { assign, ErrorPlatformEvent, EventFrom, send, StateFrom } from 'xstate';
import { createModel } from 'xstate/lib/model';
import { HOST, MY_VCS_STORE_KEY, VC_ITEM_STORE_KEY } from '../shared/constants';
import {
HOST,
MY_VCS_STORE_KEY,
VC_ITEM_STORE_KEY,
VC_ITEM_STORE_KEY_AFTER_DOWNLOAD,
} from '../shared/constants';
import { AppServices } from '../shared/GlobalContext';
import { CredentialDownloadResponse, request } from '../shared/request';
import {
@@ -60,6 +65,7 @@ const model = createModel(
walletBindingError: '',
publicKey: '',
privateKey: '',
hashedId: '',
},
{
events: {
@@ -195,7 +201,11 @@ export const vcItemMachine =
},
],
CREDENTIAL_DOWNLOADED: {
actions: ['setStoreVerifiableCredential', 'storeContext'],
actions: [
'setStoreVerifiableCredential',
'storeContext',
'editVcKey',
],
},
STORE_RESPONSE: {
actions: [
@@ -907,6 +917,14 @@ export const vcItemMachine =
}
),
editVcKey: send((context) => {
const { serviceRefs, ...data } = context;
return StoreEvents.SET(
VC_ITEM_STORE_KEY_AFTER_DOWNLOAD(context),
data
);
}),
setTag: model.assign({
tag: (_, event) => event.tag,
}),
@@ -1331,7 +1349,7 @@ export const createVcItemMachine = (
serviceRefs: AppServices,
vcKey: string
) => {
const [, idType, id, requestId, isPinned] = vcKey.split(':');
const [, idType, hashedId, requestId, isPinned, id] = vcKey.split(':');
return vcItemMachine.withContext({
...vcItemMachine.context,
serviceRefs,
@@ -1339,6 +1357,7 @@ export const createVcItemMachine = (
idType: idType as VcIdType,
requestId,
isPinned: isPinned == 'true' ? true : false,
hashedId,
});
};

View File

@@ -165,6 +165,7 @@ export interface Typegen0 {
services: never;
};
'eventsCausingActions': {
VcUpdated: 'STORE_RESPONSE';
clearOtp:
| ''
| 'CANCEL'
@@ -189,6 +190,7 @@ export interface Typegen0 {
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
editVcKey: 'CREDENTIAL_DOWNLOADED';
incrementDownloadCounter: 'POLL';
logDownloaded: 'STORE_RESPONSE';
logRevoked: 'STORE_RESPONSE';

View File

@@ -9,9 +9,14 @@ import {
} from 'xstate';
import { createModel } from 'xstate/lib/model';
import { BackendResponseError, request } from '../../../shared/request';
import { VC_ITEM_STORE_KEY } from '../../../shared/constants';
import {
argon2iConfigForUinVid,
argon2iSalt,
VC_ITEM_STORE_KEY,
} from '../../../shared/constants';
import { VcIdType } from '../../../types/vc';
import i18n from '../../../i18n';
import { hashData } from '../../../shared/commonUtil';
const model = createModel(
{
@@ -24,6 +29,7 @@ const model = createModel(
transactionId: '',
requestId: '',
isPinned: false,
hashedId: '',
},
{
events: {
@@ -206,7 +212,7 @@ export const AddVcModalMachine =
onDone: [
{
actions: 'setRequestId',
target: 'done',
target: 'calculatingHashedId',
},
],
onError: [
@@ -222,6 +228,15 @@ export const AddVcModalMachine =
],
},
},
calculatingHashedId: {
invoke: {
src: 'calculateHashedId',
onDone: {
actions: 'setHashedId',
target: 'done',
},
},
},
done: {
type: 'final',
data: (context) => VC_ITEM_STORE_KEY(context),
@@ -281,6 +296,11 @@ export const AddVcModalMachine =
clearId: model.assign({ id: '' }),
setHashedId: model.assign({
hashedId: (_context, event) =>
(event as DoneInvokeEvent<string>).data,
}),
clearIdError: model.assign({ idError: '' }),
setIdErrorEmpty: model.assign({
@@ -349,6 +369,17 @@ export const AddVcModalMachine =
);
return response.response.requestId;
},
calculateHashedId: async (context) => {
const value = context.id;
const hashedid = await hashData(
value,
argon2iSalt,
argon2iConfigForUinVid
);
context.hashedId = hashedid;
return hashedid;
},
},
guards: {

View File

@@ -6,7 +6,6 @@ export const hashData = async (
config: Argon2iConfig
): Promise<string> => {
const result = await argon2(data, salt, config);
console.log('argon--result', result);
return result.rawHash as string;
};
@@ -15,5 +14,5 @@ export interface Argon2iConfig {
memory: number;
parallelism: number;
hashLength: number;
mode: String;
mode: string;
}

View File

@@ -17,11 +17,14 @@ export const RECEIVED_VCS_STORE_KEY = 'receivedVCs';
export const MY_LOGIN_STORE_KEY = 'myLogins';
export const VC_ITEM_STORE_KEY = (vc: Partial<VC>) =>
`vc:${vc.idType}:${vc.id}:${vc.requestId}:${vc.isPinned}`;
`vc:${vc.idType}:${vc.hashedId}:${vc.requestId}:${vc.isPinned}:${vc.id}`;
export const VC_ITEM_STORE_KEY_AFTER_DOWNLOAD = (vc: Partial<VC>) =>
`vc:${vc.idType}:${vc.hashedId}:${vc.requestId}:${vc.isPinned}`;
//Regex expression to evaluate if the key is for a VC
export const VC_ITEM_STORE_KEY_REGEX =
'^vc:(UIN|VID):[0-9]+:[a-z0-9-]+:[true|false]+$';
'^vc:(UIN|VID):[a-z0-9]+:[a-z0-9-]+:[true|false]+(:[0-9-]+)?$';
//To compare the vckey with requestId, when the vc is pinned
export const isSameVC = (vcKey: string, pinnedVcKey: string) => {
@@ -69,3 +72,14 @@ export const argon2iConfig: Argon2iConfig = {
hashLength: 20,
mode: 'argon2i',
};
export const argon2iConfigForUinVid: Argon2iConfig = {
iterations: 5,
memory: 16 * 1024,
parallelism: 2,
hashLength: 5,
mode: 'argon2i',
};
export const argon2iSalt =
'1234567891011121314151617181920212223242526272829303132333435363';

View File

@@ -183,4 +183,9 @@ const getVCKeyName = (key: string) => {
return key.split(':').splice(0, 4).join(':');
};
// To print the MMKV data cal this function in getItem
const getMMKVData = async () => {
const mmkvData = await MMKV.indexer.getKeys();
};
export default Storage;

View File

@@ -17,6 +17,7 @@ export interface VC {
walletBindingResponse?: WalletBindingResponse;
credentialRegistry: string;
isPinned?: boolean;
hashedId: string;
}
export interface VCSharingReason {