feat(INJI-458): show loading screen after closing of web view in OpenID4VCI flow (#932)

* perf(INJI-458): cache fixed result of custom keystore presence

Each call over the RN bridge can take significant user-visible time, and since
the result is used multiple times and cannot change for a device in runtime,
it can be computed once stored for later use.

Signed-off-by: Harsh Vardhan <harsh59v@gmail.com>

* feat(INJI-458): show loading for android h/w keystore check & generation

Signed-off-by: Harsh Vardhan <harsh59v@gmail.com>

* feat(INJI-472): show loader on issuer select

Co-authored-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com>
Signed-off-by: Harsh Vardhan <harsh59v@gmail.com>

* refactor(INJI-458): rename const name to isHardwareKeystoreExists

Signed-off-by: Harsh Vardhan <harsh59v@gmail.com>

---------

Signed-off-by: Harsh Vardhan <harsh59v@gmail.com>
Co-authored-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com>
This commit is contained in:
Harsh Vardhan
2023-10-20 12:14:21 +05:30
committed by GitHub
parent 294ed12cca
commit 86840edcc1
16 changed files with 474 additions and 680 deletions

View File

@@ -25,11 +25,21 @@ fileignoreconfig:
checksum: 18af825821bc95e1056050623b804a5a8e7435b9e3383916a5d63024eeba9553
- filename: screens/WelcomeScreenController.ts
checksum: d8fe74404c80bf435459f4d20427a661fb622f0ee9f754345616abd346b98d14
- filename: shared/telemetry/TelemetryUtils.js
checksum: 9a61cd59a3718adf1f14faf3024fec66a3295ef373878a878a28e5cb1287afaa
- filename: machines/VCItemMachine/ExistingMosipVCItem/ExistingMosipVCItemMachine.ts
checksum: 237a2640b7db70770d65da67c79f2929581e32f1162517e50b8d37e409f3387d
- filename: machines/store.ts
checksum: bbee269bd9703644c2a345819291caa42479b5ad0d5288713da780495b2ffb49
checksum: b9884f86b498dfbff75816d1f0d521c79971c8c28afa7824122d025b2699cdc4
- filename: shared/cryptoutil/cryptoUtil.ts
checksum: b785ff3f01ab9530119072c4d38195048bfeee6155c54ea7dd031559acb722f3
- filename: shared/telemetry/TelemetryUtils.js
checksum: ffe9aac2dcc590b98b0d588885c088eff189504ade653a77f74b67312bfd27ad
- filename: shared/fileStorage.ts
checksum: 07cb337dc1d5b0f0eef56270ac4f4f589260ee5e490183c024cf98a2aeafb139
- filename: shared/storage.ts
checksum: c8d874aa373bdf526bf59192139822f56915e702ef673bac4e0d7549b0fea3d0
checksum: f9711b617b986af9bb733a31373e49494667ef07b74988fbf09688cb50ca73bd
- filename: machines/VCItemMachine/EsignetMosipVCItem/EsignetMosipVCItemMachine.ts
checksum: eec77ca61540327ff7cab3489ebdfd47aa373fd20b3ff87a6c322cd48d35fe8f
- filename: machines/VCItemMachine/EsignetMosipVCItem/EsignetMosipVCItemMachine.typegen.ts
checksum: f1f504bd8c14496ee71f8eb7f40d54411cc05be03347d644dcc2cca187a20678
version: ""

View File

@@ -18,7 +18,7 @@ import {Alert} from 'react-native';
import {configureTelemetry} from './shared/telemetry/TelemetryUtils';
import {MessageOverlay} from './components/MessageOverlay';
import SecureKeystore from 'react-native-secure-keystore';
import {isCustomSecureKeystore} from './shared/cryptoutil/cryptoUtil';
import {isHardwareKeystoreExists} from './shared/cryptoutil/cryptoUtil';
import i18n from './i18n';
import './shared/flipperConfig';
@@ -91,7 +91,7 @@ const AppInitialization: React.FC = () => {
const {t} = useTranslation('common');
useEffect(() => {
if (isCustomSecureKeystore()) {
if (isHardwareKeystoreExists) {
SecureKeystore.updatePopup(
t('biometricPopup.title'),
t('biometricPopup.description'),

View File

@@ -12,7 +12,10 @@ import {MY_VCS_STORE_KEY, ESIGNET_BASE_URL} from '../shared/constants';
import {StoreEvents} from './store';
import {linkTransactionResponse, VC} from '../types/VC/ExistingMosipVC/vc';
import {request} from '../shared/request';
import {getJwt, isCustomSecureKeystore} from '../shared/cryptoutil/cryptoUtil';
import {
getJwt,
isHardwareKeystoreExists,
} from '../shared/cryptoutil/cryptoUtil';
import {
getBindingCertificateConstant,
getPrivateKey,
@@ -363,7 +366,7 @@ export const qrLoginMachine =
sendAuthenticate: async context => {
let privateKey;
const individualId = context.selectedVc.vcMetadata.id;
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
privateKey = await getPrivateKey(
context.selectedVc.walletBindingResponse?.walletBindingId,
);
@@ -397,7 +400,7 @@ export const qrLoginMachine =
sendConsent: async context => {
let privateKey;
const individualId = context.selectedVc.vcMetadata.id;
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
privateKey = await getPrivateKey(
context.selectedVc.walletBindingResponse?.walletBindingId,
);

View File

@@ -1,83 +0,0 @@
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.QrLogin.linkTransaction:invocation[0]': {
type: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.QrLogin.sendingAuthenticate:invocation[0]': {
type: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.QrLogin.linkTransaction:invocation[0]': {
type: 'error.platform.QrLogin.linkTransaction:invocation[0]';
data: unknown;
};
'error.platform.QrLogin.sendingAuthenticate:invocation[0]': {
type: 'error.platform.QrLogin.sendingAuthenticate:invocation[0]';
data: unknown;
};
'error.platform.QrLogin.sendingConsent:invocation[0]': {
type: 'error.platform.QrLogin.sendingConsent:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
linkTransaction: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
sendAuthenticate: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
sendConsent: 'done.invoke.QrLogin.sendingConsent:invocation[0]';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
SetErrorMessage:
| 'error.platform.QrLogin.linkTransaction:invocation[0]'
| 'error.platform.QrLogin.sendingAuthenticate:invocation[0]'
| 'error.platform.QrLogin.sendingConsent:invocation[0]';
expandLinkTransResp: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
forwardToParent: 'DISMISS';
loadMyVcs: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
loadThumbprint: 'CONFIRM';
resetLinkTransactionId: 'GET';
resetSelectedVoluntaryClaims: 'GET';
setClaims: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
setConsentClaims: 'TOGGLE_CONSENT_CLAIM';
setLinkedTransactionId: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
setMyVcs: 'STORE_RESPONSE';
setScanData: 'GET';
setSelectedVc: 'SELECT_VC';
setThumbprint: 'STORE_RESPONSE';
setlinkTransactionResponse: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {};
eventsCausingServices: {
linkTransaction: 'GET';
sendAuthenticate: never;
sendConsent: 'STORE_RESPONSE';
};
matchesStates:
| 'ShowError'
| 'done'
| 'faceAuth'
| 'invalidIdentity'
| 'linkTransaction'
| 'loadMyVcs'
| 'loadingThumbprint'
| 'requestConsent'
| 'sendingAuthenticate'
| 'sendingConsent'
| 'showvcList'
| 'success'
| 'waitingForData';
tags: never;
}

View File

@@ -5,7 +5,7 @@ import {VCMetadata} from '../../../shared/VCMetadata';
import {VC} from '../../../types/VC/ExistingMosipVC/vc';
import {
generateKeys,
isCustomSecureKeystore,
isHardwareKeystoreExists,
WalletBindingResponse,
} from '../../../shared/cryptoutil/cryptoUtil';
import {log} from 'xstate/lib/actions';
@@ -632,7 +632,7 @@ export const EsignetMosipVCItemMachine = model.createMachine(
),
setPublicKey: assign({
publicKey: (context, event) => {
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return (event.data as KeyPair).public;
}
return event.data as string;
@@ -788,7 +788,7 @@ export const EsignetMosipVCItemMachine = model.createMachine(
return walletResponse;
},
generateKeyPair: async context => {
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return await generateKeys();
}
const isBiometricsEnabled = SecureKeystore.hasBiometricsEnabled();
@@ -825,7 +825,7 @@ export const EsignetMosipVCItemMachine = model.createMachine(
return vc != null;
},
isCustomSecureKeystore: () => isCustomSecureKeystore(),
isCustomSecureKeystore: () => isHardwareKeystoreExists,
},
},
);

View File

@@ -128,7 +128,255 @@ export interface Typegen0 {
sendWalletBindingSuccess:
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]';
setContext: 'STORE_RESPONSE';
setContext: 'GET_VC_RESPONSE' | 'STORE_RESPONSE';
setGeneratedOn: 'GET_VC_RESPONSE';
setOtp: 'INPUT_OTP';
setPinCard: 'PIN_CARD';
setPrivateKey:
| 'done.invoke.vc-item-openid4vci.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]';
setPublicKey:
| 'done.invoke.vc-item-openid4vci.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]';
setThumbprintForWalletBindingId:
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]';
setVcKey: 'REMOVE';
setVcMetadata: 'UPDATE_VC_METADATA';
setVerifiableCredential: 'GET_VC_RESPONSE' | 'STORE_RESPONSE';
setWalletBindingError:
| 'error.platform.vc-item-openid4vci.addKeyPair:invocation[0]'
| 'error.platform.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]'
| 'error.platform.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item-openid4vci.kebabPopUp.requestingBindingOtp:invocation[0]'
| 'error.platform.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'error.platform.vc-item-openid4vci.requestingBindingOtp:invocation[0]'
| 'error.platform.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
setWalletBindingErrorEmpty:
| 'CANCEL'
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
setWalletBindingId:
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]';
setWalletBindingSuccess: 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
storeContext:
| 'PIN_CARD'
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
updatePrivateKey:
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
updateVc:
| 'STORE_RESPONSE'
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
hasCredential: 'GET_VC_RESPONSE';
isCustomSecureKeystore:
| 'done.invoke.vc-item-openid4vci.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]';
};
eventsCausingServices: {
addWalletBindnigId:
| 'done.invoke.vc-item-openid4vci.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]';
generateKeyPair: 'INPUT_OTP';
requestBindingOtp: 'CONFIRM';
requestOtp: 'RESEND_OTP';
updatePrivateKey:
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]';
};
matchesStates:
| 'acceptingBindingOtp'
| 'acceptingBindingOtp.idle'
| 'acceptingBindingOtp.resendOTP'
| 'addKeyPair'
| 'addingWalletBindingId'
| 'checkingStore'
| 'checkingVc'
| 'idle'
| 'kebabPopUp'
| 'kebabPopUp.acceptingBindingOtp'
| 'kebabPopUp.acceptingBindingOtp.idle'
| 'kebabPopUp.acceptingBindingOtp.resendOTP'
| 'kebabPopUp.addKeyPair'
| 'kebabPopUp.addingWalletBindingId'
| 'kebabPopUp.idle'
| 'kebabPopUp.removeWallet'
| 'kebabPopUp.removingVc'
| 'kebabPopUp.requestingBindingOtp'
| 'kebabPopUp.showActivities'
| 'kebabPopUp.showBindingWarning'
| 'kebabPopUp.showingWalletBindingError'
| 'kebabPopUp.updatingPrivateKey'
| 'pinCard'
| 'requestingBindingOtp'
| 'showBindingWarning'
| 'showingWalletBindingError'
| 'updatingPrivateKey'
| {
acceptingBindingOtp?: 'idle' | 'resendOTP';
kebabPopUp?:
| 'acceptingBindingOtp'
| 'addKeyPair'
| 'addingWalletBindingId'
| 'idle'
| 'removeWallet'
| 'removingVc'
| 'requestingBindingOtp'
| 'showActivities'
| 'showBindingWarning'
| 'showingWalletBindingError'
| 'updatingPrivateKey'
| {acceptingBindingOtp?: 'idle' | 'resendOTP'};
};
tags: never;
}
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.vc-item-openid4vci.addKeyPair:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.addKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-openid4vci.kebabPopUp.requestingBindingOtp:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.kebabPopUp.requestingBindingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-openid4vci.requestingBindingOtp:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.requestingBindingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]': {
type: 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.vc-item-openid4vci.addKeyPair:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.addKeyPair:invocation[0]';
data: unknown;
};
'error.platform.vc-item-openid4vci.addingWalletBindingId:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.addingWalletBindingId:invocation[0]';
data: unknown;
};
'error.platform.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]';
data: unknown;
};
'error.platform.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]';
data: unknown;
};
'error.platform.vc-item-openid4vci.kebabPopUp.requestingBindingOtp:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.kebabPopUp.requestingBindingOtp:invocation[0]';
data: unknown;
};
'error.platform.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]';
data: unknown;
};
'error.platform.vc-item-openid4vci.requestingBindingOtp:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.requestingBindingOtp:invocation[0]';
data: unknown;
};
'error.platform.vc-item-openid4vci.updatingPrivateKey:invocation[0]': {
type: 'error.platform.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
addWalletBindnigId:
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]';
generateKeyPair:
| 'done.invoke.vc-item-openid4vci.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addKeyPair:invocation[0]';
requestBindingOtp:
| 'done.invoke.vc-item-openid4vci.kebabPopUp.requestingBindingOtp:invocation[0]'
| 'done.invoke.vc-item-openid4vci.requestingBindingOtp:invocation[0]';
requestOtp:
| 'done.invoke.vc-item-openid4vci.acceptingBindingOtp.resendOTP:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.acceptingBindingOtp.resendOTP:invocation[0]';
updatePrivateKey:
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
};
missingImplementations: {
actions: 'clearTransactionId';
delays: never;
guards: never;
services: 'requestOtp';
};
eventsCausingActions: {
VcUpdated: 'STORE_RESPONSE';
clearOtp:
| 'DISMISS'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.requestingBindingOtp:invocation[0]'
| 'done.invoke.vc-item-openid4vci.requestingBindingOtp:invocation[0]';
clearTransactionId: 'DISMISS';
logVCremoved: 'STORE_RESPONSE';
logWalletBindingFailure:
| 'error.platform.vc-item-openid4vci.addKeyPair:invocation[0]'
| 'error.platform.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item-openid4vci.requestingBindingOtp:invocation[0]'
| 'error.platform.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
logWalletBindingSuccess:
| 'done.invoke.vc-item-openid4vci.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item-openid4vci.updatingPrivateKey:invocation[0]';
removeVcItem: 'CONFIRM';
removedVc: 'STORE_RESPONSE';
requestStoredContext: 'GET_VC_RESPONSE' | 'REFRESH';
requestVcContext: 'DISMISS' | 'xstate.init';
resetWalletBindingSuccess: 'DISMISS';
sendVcUpdated: 'STORE_RESPONSE';
sendWalletBindingSuccess:
| 'done.invoke.vc-item-openid4vci.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-openid4vci.kebabPopUp.updatingPrivateKey:invocation[0]';
setContext: 'GET_VC_RESPONSE' | 'STORE_RESPONSE';
setGeneratedOn: 'GET_VC_RESPONSE';
setOtp: 'INPUT_OTP';
setPinCard: 'PIN_CARD';

View File

@@ -15,7 +15,7 @@ import {verifyCredential} from '../../../shared/vcjs/verifyCredential';
import {log} from 'xstate/lib/actions';
import {
generateKeys,
isCustomSecureKeystore,
isHardwareKeystoreExists,
WalletBindingResponse,
} from '../../../shared/cryptoutil/cryptoUtil';
import {KeyPair} from 'react-native-rsa-native';
@@ -854,7 +854,7 @@ export const ExistingMosipVCItemMachine =
),
setPublicKey: assign({
publicKey: (context, event) => {
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return (event.data as KeyPair).public;
}
return event.data as string;
@@ -1250,7 +1250,7 @@ export const ExistingMosipVCItemMachine =
},
generateKeyPair: async context => {
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return await generateKeys();
}
const isBiometricsEnabled = SecureKeystore.hasBiometricsEnabled();
@@ -1425,7 +1425,7 @@ export const ExistingMosipVCItemMachine =
return context.isVerified;
},
isCustomSecureKeystore: () => isCustomSecureKeystore(),
isCustomSecureKeystore: () => isHardwareKeystoreExists,
},
},
);

View File

@@ -1,392 +0,0 @@
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'': {type: ''};
'done.invoke.checkStatus': {
type: 'done.invoke.checkStatus';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.downloadCredential': {
type: 'done.invoke.downloadCredential';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.addKeyPair:invocation[0]': {
type: 'done.invoke.vc-item.addKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.addingWalletBindingId:invocation[0]': {
type: 'done.invoke.vc-item.addingWalletBindingId:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]': {
type: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.kebabPopUp.addKeyPair:invocation[0]': {
type: 'done.invoke.vc-item.kebabPopUp.addKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]': {
type: 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.kebabPopUp.requestingBindingOtp:invocation[0]': {
type: 'done.invoke.vc-item.kebabPopUp.requestingBindingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]': {
type: 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingBindingOtp:invocation[0]': {
type: 'done.invoke.vc-item.requestingBindingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingLock:invocation[0]': {
type: 'done.invoke.vc-item.requestingLock:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingOtp:invocation[0]': {
type: 'done.invoke.vc-item.requestingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.requestingRevoke:invocation[0]': {
type: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.updatingPrivateKey:invocation[0]': {
type: 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item.verifyingCredential:invocation[0]': {
type: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.checkStatus': {
type: 'error.platform.checkStatus';
data: unknown;
};
'error.platform.downloadCredential': {
type: 'error.platform.downloadCredential';
data: unknown;
};
'error.platform.vc-item.addKeyPair:invocation[0]': {
type: 'error.platform.vc-item.addKeyPair:invocation[0]';
data: unknown;
};
'error.platform.vc-item.addingWalletBindingId:invocation[0]': {
type: 'error.platform.vc-item.addingWalletBindingId:invocation[0]';
data: unknown;
};
'error.platform.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]': {
type: 'error.platform.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
data: unknown;
};
'error.platform.vc-item.kebabPopUp.addKeyPair:invocation[0]': {
type: 'error.platform.vc-item.kebabPopUp.addKeyPair:invocation[0]';
data: unknown;
};
'error.platform.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]': {
type: 'error.platform.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]';
data: unknown;
};
'error.platform.vc-item.kebabPopUp.requestingBindingOtp:invocation[0]': {
type: 'error.platform.vc-item.kebabPopUp.requestingBindingOtp:invocation[0]';
data: unknown;
};
'error.platform.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]': {
type: 'error.platform.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]';
data: unknown;
};
'error.platform.vc-item.requestingBindingOtp:invocation[0]': {
type: 'error.platform.vc-item.requestingBindingOtp:invocation[0]';
data: unknown;
};
'error.platform.vc-item.requestingLock:invocation[0]': {
type: 'error.platform.vc-item.requestingLock:invocation[0]';
data: unknown;
};
'error.platform.vc-item.requestingRevoke:invocation[0]': {
type: 'error.platform.vc-item.requestingRevoke:invocation[0]';
data: unknown;
};
'error.platform.vc-item.updatingPrivateKey:invocation[0]': {
type: 'error.platform.vc-item.updatingPrivateKey:invocation[0]';
data: unknown;
};
'error.platform.vc-item.verifyingCredential:invocation[0]': {
type: 'error.platform.vc-item.verifyingCredential:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
addWalletBindnigId:
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]';
checkDownloadExpiryLimit: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
checkStatus: 'done.invoke.checkStatus';
downloadCredential: 'done.invoke.downloadCredential';
generateKeyPair:
| 'done.invoke.vc-item.addKeyPair:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addKeyPair:invocation[0]';
requestBindingOtp:
| 'done.invoke.vc-item.kebabPopUp.requestingBindingOtp:invocation[0]'
| 'done.invoke.vc-item.requestingBindingOtp:invocation[0]';
requestLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
requestOtp:
| 'done.invoke.vc-item.acceptingOtpInput.resendOTP:invocation[0]'
| 'done.invoke.vc-item.requestingOtp:invocation[0]';
requestRevoke: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
updatePrivateKey:
| 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
verifyCredential: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
addVcToInProgressDownloads: 'STORE_RESPONSE';
clearOtp:
| ''
| 'CANCEL'
| 'DISMISS'
| 'REVOKE_VC'
| 'STORE_RESPONSE'
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.requestingBindingOtp:invocation[0]'
| 'done.invoke.vc-item.requestingBindingOtp:invocation[0]'
| 'done.invoke.vc-item.requestingOtp:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
| 'error.platform.vc-item.requestingLock:invocation[0]'
| 'error.platform.vc-item.requestingRevoke:invocation[0]'
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
clearTransactionId:
| ''
| 'CANCEL'
| 'DISMISS'
| 'STORE_RESPONSE'
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]'
| 'error.platform.vc-item.verifyingCredential:invocation[0]';
incrementDownloadCounter: 'POLL';
logDownloaded: 'STORE_RESPONSE';
logRevoked: 'STORE_RESPONSE';
logVCremoved: 'STORE_RESPONSE';
logWalletBindingFailure:
| 'error.platform.vc-item.addKeyPair:invocation[0]'
| 'error.platform.vc-item.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item.requestingBindingOtp:invocation[0]'
| 'error.platform.vc-item.updatingPrivateKey:invocation[0]';
logWalletBindingSuccess:
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
markVcValid: 'done.invoke.vc-item.verifyingCredential:invocation[0]';
refreshMyVcs: 'STORE_RESPONSE';
removeTamperedVcItem: 'TAMPERED_VC';
removeVcFromInProgressDownloads: 'STORE_RESPONSE';
removeVcItem: 'CONFIRM';
removeVcMetaDataFromStorage: 'STORE_ERROR';
removeVcMetaDataFromVcMachine: 'DISMISS';
requestStoredContext: 'GET_VC_RESPONSE' | 'REFRESH';
requestVcContext: 'DISMISS' | 'xstate.init';
resetWalletBindingSuccess: 'DISMISS';
revokeVID: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
sendTamperedVc: 'TAMPERED_VC';
sendVcUpdated: 'PIN_CARD';
sendWalletBindingSuccess:
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]';
setCredential: 'GET_VC_RESPONSE' | 'STORE_RESPONSE';
setDownloadInterval: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
setLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
setMaxDownloadCount: 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
setOtp: 'INPUT_OTP';
setOtpError:
| 'error.platform.vc-item.requestingLock:invocation[0]'
| 'error.platform.vc-item.requestingRevoke:invocation[0]';
setPinCard: 'PIN_CARD';
setPrivateKey:
| 'done.invoke.vc-item.addKeyPair:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addKeyPair:invocation[0]';
setPublicKey:
| 'done.invoke.vc-item.addKeyPair:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addKeyPair:invocation[0]';
setRevoke: 'done.invoke.vc-item.requestingRevoke:invocation[0]';
setStoreVerifiableCredential: 'CREDENTIAL_DOWNLOADED';
setThumbprintForWalletBindingId:
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]';
setTransactionId:
| 'INPUT_OTP'
| 'REVOKE_VC'
| 'done.invoke.vc-item.requestingOtp:invocation[0]'
| 'error.platform.vc-item.requestingLock:invocation[0]'
| 'error.platform.vc-item.requestingRevoke:invocation[0]';
setVcKey: 'REMOVE';
setVcMetadata: 'UPDATE_VC_METADATA';
setVerifiableCredential: 'STORE_RESPONSE';
setWalletBindingError:
| 'error.platform.vc-item.addKeyPair:invocation[0]'
| 'error.platform.vc-item.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item.kebabPopUp.addKeyPair:invocation[0]'
| 'error.platform.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item.kebabPopUp.requestingBindingOtp:invocation[0]'
| 'error.platform.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'error.platform.vc-item.requestingBindingOtp:invocation[0]'
| 'error.platform.vc-item.updatingPrivateKey:invocation[0]';
setWalletBindingErrorEmpty:
| 'CANCEL'
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
setWalletBindingId:
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]';
setWalletBindingSuccess: 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
storeContext:
| 'CREDENTIAL_DOWNLOADED'
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]';
storeLock: 'done.invoke.vc-item.requestingLock:invocation[0]';
updatePrivateKey:
| 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]';
updateVc:
| 'STORE_RESPONSE'
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item.verifyingCredential:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
hasCredential: 'GET_VC_RESPONSE' | 'STORE_RESPONSE';
isCustomSecureKeystore:
| 'done.invoke.vc-item.addKeyPair:invocation[0]'
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addKeyPair:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]';
isDownloadAllowed: 'POLL';
isVcValid: '';
};
eventsCausingServices: {
addWalletBindnigId:
| 'done.invoke.vc-item.addKeyPair:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addKeyPair:invocation[0]';
checkDownloadExpiryLimit: 'STORE_RESPONSE';
checkStatus:
| 'done.invoke.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]'
| 'error.platform.vc-item.checkingServerData.verifyingDownloadLimitExpiry:invocation[0]';
downloadCredential: 'DOWNLOAD_READY';
generateKeyPair: 'INPUT_OTP';
requestBindingOtp: 'CONFIRM';
requestLock: 'INPUT_OTP';
requestOtp: 'LOCK_VC' | 'RESEND_OTP';
requestRevoke: 'INPUT_OTP';
updatePrivateKey:
| 'done.invoke.vc-item.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]';
verifyCredential: '' | 'VERIFY';
};
matchesStates:
| 'acceptingBindingOtp'
| 'acceptingOtpInput'
| 'acceptingOtpInput.idle'
| 'acceptingOtpInput.resendOTP'
| 'acceptingRevokeInput'
| 'addKeyPair'
| 'addingWalletBindingId'
| 'checkingServerData'
| 'checkingServerData.checkingStatus'
| 'checkingServerData.downloadingCredential'
| 'checkingServerData.savingFailed'
| 'checkingServerData.savingFailed.idle'
| 'checkingServerData.savingFailed.viewingVc'
| 'checkingServerData.verifyingDownloadLimitExpiry'
| 'checkingStore'
| 'checkingVc'
| 'checkingVerificationStatus'
| 'idle'
| 'invalid'
| 'invalid.backend'
| 'invalid.otp'
| 'kebabPopUp'
| 'kebabPopUp.acceptingBindingOtp'
| 'kebabPopUp.addKeyPair'
| 'kebabPopUp.addingWalletBindingId'
| 'kebabPopUp.idle'
| 'kebabPopUp.removeWallet'
| 'kebabPopUp.removingVc'
| 'kebabPopUp.requestingBindingOtp'
| 'kebabPopUp.showActivities'
| 'kebabPopUp.showBindingWarning'
| 'kebabPopUp.showingWalletBindingError'
| 'kebabPopUp.updatingPrivateKey'
| 'lockingVc'
| 'loggingRevoke'
| 'pinCard'
| 'requestingBindingOtp'
| 'requestingLock'
| 'requestingOtp'
| 'requestingRevoke'
| 'revokingVc'
| 'showBindingWarning'
| 'showingWalletBindingError'
| 'updatingPrivateKey'
| 'verifyingCredential'
| {
acceptingOtpInput?: 'idle' | 'resendOTP';
checkingServerData?:
| 'checkingStatus'
| 'downloadingCredential'
| 'savingFailed'
| 'verifyingDownloadLimitExpiry'
| {savingFailed?: 'idle' | 'viewingVc'};
invalid?: 'backend' | 'otp';
kebabPopUp?:
| 'acceptingBindingOtp'
| 'addKeyPair'
| 'addingWalletBindingId'
| 'idle'
| 'removeWallet'
| 'removingVc'
| 'requestingBindingOtp'
| 'showActivities'
| 'showBindingWarning'
| 'showingWalletBindingError'
| 'updatingPrivateKey';
};
tags: never;
}

View File

@@ -7,7 +7,7 @@ import {AppServices} from '../shared/GlobalContext';
import NetInfo from '@react-native-community/netinfo';
import {
generateKeys,
isCustomSecureKeystore,
isHardwareKeystoreExists,
} from '../shared/cryptoutil/cryptoUtil';
import SecureKeystore from 'react-native-secure-keystore';
import {KeyPair} from 'react-native-rsa-native';
@@ -122,7 +122,7 @@ export const IssuersMachine = model.createMachine(
},
{
description: 'not fetched issuers config yet',
actions: ['setLoadingReasonAsDisplayIssuers', 'resetError'],
actions: ['setLoadingReasonAsSettingUp', 'resetError'],
target: 'downloadIssuerConfig',
},
],
@@ -139,7 +139,7 @@ export const IssuersMachine = model.createMachine(
actions: sendParent('DOWNLOAD_ID'),
},
SELECTED_ISSUER: {
actions: 'setSelectedIssuerId',
actions: ['setSelectedIssuerId', 'setLoadingReasonAsSettingUp'],
target: 'downloadIssuerConfig',
},
},
@@ -222,7 +222,7 @@ export const IssuersMachine = model.createMachine(
},
checkKeyPair: {
description: 'checks whether key pair is generated',
entry: [send('CHECK_KEY_PAIR')],
entry: ['setLoadingReasonAsSettingUp', send('CHECK_KEY_PAIR')],
on: {
CHECK_KEY_PAIR: [
{
@@ -457,7 +457,7 @@ export const IssuersMachine = model.createMachine(
}),
setPublicKey: assign({
publicKey: (_, event) => {
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return (event.data as KeyPair).public;
}
return event.data as string;
@@ -533,8 +533,8 @@ export const IssuersMachine = model.createMachine(
constructAuthorizationConfiguration(context.selectedIssuer),
);
},
generateKeyPair: async context => {
if (!isCustomSecureKeystore()) {
generateKeyPair: async () => {
if (!isHardwareKeystoreExists) {
return await generateKeys();
}
const isBiometricsEnabled = SecureKeystore.hasBiometricsEnabled();
@@ -579,7 +579,7 @@ export const IssuersMachine = model.createMachine(
);
},
shouldFetchIssuersAgain: context => context.issuers.length === 0,
isCustomSecureKeystore: () => isCustomSecureKeystore(),
isCustomSecureKeystore: () => isHardwareKeystoreExists,
},
},
);

View File

@@ -1,32 +1,77 @@
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.checkInternet": { type: "done.invoke.checkInternet"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.displayIssuers:invocation[0]": { type: "done.invoke.issuersMachine.displayIssuers:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.downloadCredentials:invocation[0]": { type: "done.invoke.issuersMachine.downloadCredentials:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]": { type: "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.generateKeyPair:invocation[0]": { type: "done.invoke.issuersMachine.generateKeyPair:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.performAuthorization:invocation[0]": { type: "done.invoke.issuersMachine.performAuthorization:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.verifyingCredential:invocation[0]": { type: "done.invoke.issuersMachine.verifyingCredential:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform.checkInternet": { type: "error.platform.checkInternet"; data: unknown };
"error.platform.issuersMachine.displayIssuers:invocation[0]": { type: "error.platform.issuersMachine.displayIssuers:invocation[0]"; data: unknown };
"error.platform.issuersMachine.downloadCredentials:invocation[0]": { type: "error.platform.issuersMachine.downloadCredentials:invocation[0]"; data: unknown };
"error.platform.issuersMachine.downloadIssuerConfig:invocation[0]": { type: "error.platform.issuersMachine.downloadIssuerConfig:invocation[0]"; data: unknown };
"error.platform.issuersMachine.performAuthorization:invocation[0]": { type: "error.platform.issuersMachine.performAuthorization:invocation[0]"; data: unknown };
"error.platform.issuersMachine.verifyingCredential:invocation[0]": { type: "error.platform.issuersMachine.verifyingCredential:invocation[0]"; data: unknown };
"xstate.init": { type: "xstate.init" };
'done.invoke.checkInternet': {
type: 'done.invoke.checkInternet';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.displayIssuers:invocation[0]': {
type: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.downloadCredentials:invocation[0]': {
type: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]': {
type: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.generateKeyPair:invocation[0]': {
type: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.performAuthorization:invocation[0]': {
type: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.verifyingCredential:invocation[0]': {
type: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.checkInternet': {
type: 'error.platform.checkInternet';
data: unknown;
};
'error.platform.issuersMachine.displayIssuers:invocation[0]': {
type: 'error.platform.issuersMachine.displayIssuers:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.downloadCredentials:invocation[0]': {
type: 'error.platform.issuersMachine.downloadCredentials:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]': {
type: 'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.performAuthorization:invocation[0]': {
type: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.verifyingCredential:invocation[0]': {
type: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
"checkInternet": "done.invoke.checkInternet";
"downloadCredential": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
"downloadIssuerConfig": "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]";
"downloadIssuersList": "done.invoke.issuersMachine.displayIssuers:invocation[0]";
"generateKeyPair": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"invokeAuthorization": "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"verifyCredential": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
checkInternet: 'done.invoke.checkInternet';
downloadCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
downloadIssuerConfig: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
downloadIssuersList: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
generateKeyPair: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
invokeAuthorization: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
verifyCredential: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
};
missingImplementations: {
actions: never;
@@ -35,56 +80,83 @@
services: never;
};
eventsCausingActions: {
"getKeyPairFromStore": "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"loadKeyPair": "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"logDownloaded": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"resetError": "RESET_ERROR" | "TRY_AGAIN" | "error.platform.issuersMachine.performAuthorization:invocation[0]";
"resetLoadingReason": "done.invoke.checkInternet" | "done.invoke.issuersMachine.displayIssuers:invocation[0]" | "error.platform.issuersMachine.downloadCredentials:invocation[0]" | "error.platform.issuersMachine.downloadIssuerConfig:invocation[0]" | "error.platform.issuersMachine.performAuthorization:invocation[0]";
"sendErrorEndEvent": "error.platform.issuersMachine.verifyingCredential:invocation[0]";
"sendImpressionEvent": "done.invoke.issuersMachine.displayIssuers:invocation[0]";
"sendSuccessEndEvent": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"setCredentialWrapper": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
"setError": "error.platform.issuersMachine.displayIssuers:invocation[0]" | "error.platform.issuersMachine.downloadCredentials:invocation[0]" | "error.platform.issuersMachine.downloadIssuerConfig:invocation[0]" | "error.platform.issuersMachine.performAuthorization:invocation[0]";
"setIssuers": "done.invoke.issuersMachine.displayIssuers:invocation[0]";
"setLoadingReasonAsDisplayIssuers": "TRY_AGAIN";
"setLoadingReasonAsDownloadingCredentials": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"setLoadingReasonAsSettingUp": "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"setNoInternet": "done.invoke.checkInternet";
"setOIDCConfigError": "error.platform.issuersMachine.performAuthorization:invocation[0]";
"setPrivateKey": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"setPublicKey": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"setSelectedIssuerId": "SELECTED_ISSUER";
"setSelectedIssuers": "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]";
"setTokenResponse": "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"setVerifiableCredential": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
"storeKeyPair": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"storeVcMetaContext": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"storeVcsContext": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"storeVerifiableCredentialData": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"storeVerifiableCredentialMeta": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
};
eventsCausingDelays: {
getKeyPairFromStore: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
loadKeyPair: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
logDownloaded: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
resetError:
| 'RESET_ERROR'
| 'TRY_AGAIN'
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
resetLoadingReason:
| 'done.invoke.checkInternet'
| 'done.invoke.issuersMachine.displayIssuers:invocation[0]'
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
| 'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]'
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
sendErrorEndEvent: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
sendImpressionEvent: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
sendSuccessEndEvent: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
setCredentialWrapper: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
setError:
| 'error.platform.issuersMachine.displayIssuers:invocation[0]'
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
| 'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]'
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
setIssuers: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
setLoadingReasonAsDisplayIssuers: 'TRY_AGAIN';
setLoadingReasonAsDownloadingCredentials: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setLoadingReasonAsSettingUp:
| 'SELECTED_ISSUER'
| 'TRY_AGAIN'
| 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
setNoInternet: 'done.invoke.checkInternet';
setOIDCConfigError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
setPrivateKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setPublicKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setSelectedIssuerId: 'SELECTED_ISSUER';
setSelectedIssuers: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
setTokenResponse: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
setVerifiableCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
storeKeyPair: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
storeVcMetaContext: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
storeVcsContext: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
storeVerifiableCredentialData: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
storeVerifiableCredentialMeta: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
"canSelectIssuerAgain": "TRY_AGAIN";
"hasKeyPair": "CHECK_KEY_PAIR";
"isCustomSecureKeystore": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"isInternetConnected": "done.invoke.checkInternet";
"isOIDCConfigError": "error.platform.issuersMachine.performAuthorization:invocation[0]";
"isOIDCflowCancelled": "error.platform.issuersMachine.performAuthorization:invocation[0]";
"shouldFetchIssuersAgain": "TRY_AGAIN";
canSelectIssuerAgain: 'TRY_AGAIN';
hasKeyPair: 'CHECK_KEY_PAIR';
isCustomSecureKeystore: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
isInternetConnected: 'done.invoke.checkInternet';
isOIDCConfigError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
isOIDCflowCancelled: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
shouldFetchIssuersAgain: 'TRY_AGAIN';
};
eventsCausingServices: {
"checkInternet": "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]";
"downloadCredential": "CHECK_KEY_PAIR" | "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"downloadIssuerConfig": "SELECTED_ISSUER" | "TRY_AGAIN";
"downloadIssuersList": "TRY_AGAIN" | "xstate.init";
"generateKeyPair": "CHECK_KEY_PAIR";
"invokeAuthorization": "done.invoke.checkInternet";
"verifyCredential": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
checkInternet: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
downloadCredential:
| 'CHECK_KEY_PAIR'
| 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
downloadIssuerConfig: 'SELECTED_ISSUER' | 'TRY_AGAIN';
downloadIssuersList: 'TRY_AGAIN' | 'xstate.init';
generateKeyPair: 'CHECK_KEY_PAIR';
invokeAuthorization: 'done.invoke.checkInternet';
verifyCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
};
matchesStates: "checkInternet" | "checkKeyPair" | "displayIssuers" | "done" | "downloadCredentials" | "downloadIssuerConfig" | "error" | "generateKeyPair" | "idle" | "performAuthorization" | "selectingIssuer" | "storing" | "verifyingCredential";
matchesStates:
| 'checkInternet'
| 'checkKeyPair'
| 'displayIssuers'
| 'done'
| 'downloadCredentials'
| 'downloadIssuerConfig'
| 'error'
| 'generateKeyPair'
| 'idle'
| 'performAuthorization'
| 'selectingIssuer'
| 'storing'
| 'verifyingCredential';
tags: never;
}

View File

@@ -17,7 +17,7 @@ import getAllConfigurations, {
import Storage from '../shared/storage';
import ShortUniqueId from 'short-unique-id';
import {__AppId} from '../shared/GlobalVariables';
import {isCustomSecureKeystore} from '../shared/cryptoutil/cryptoUtil';
import {isHardwareKeystoreExists} from '../shared/cryptoutil/cryptoUtil';
const model = createModel(
{
@@ -274,7 +274,7 @@ function generateAppId() {
}
function deviceSupportsHardwareKeystore() {
return isIOS() ? true : isCustomSecureKeystore();
return isIOS() ? true : isHardwareKeystoreExists;
}
type State = StateFrom<typeof settingsMachine>;

View File

@@ -22,7 +22,7 @@ import {
ENCRYPTION_ID,
encryptJson,
HMAC_ALIAS,
isCustomSecureKeystore,
isHardwareKeystoreExists,
} from '../shared/cryptoutil/cryptoUtil';
import {VCMetadata} from '../shared/VCMetadata';
import FileStorage, {getFilePath} from '../shared/fileStorage';
@@ -82,7 +82,7 @@ export const storeMachine =
events: {} as EventFrom<typeof model>,
},
id: 'store',
initial: !isCustomSecureKeystore()
initial: !isHardwareKeystoreExists
? 'gettingEncryptionKey'
: 'checkEncryptionKey',
states: {
@@ -441,7 +441,7 @@ export const storeMachine =
generateEncryptionKey: () => async callback => {
const randomBytes = await generateSecureRandom(32);
const randomBytesString = binaryToBase64(randomBytes);
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
const hasSetCredentials = await Keychain.setGenericPassword(
ENCRYPTION_ID,
randomBytesString,
@@ -475,7 +475,7 @@ export const storeMachine =
},
guards: {
isCustomSecureKeystore: () => isCustomSecureKeystore(),
isCustomSecureKeystore: () => isHardwareKeystoreExists,
},
},
);

View File

@@ -1,75 +0,0 @@
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke._store': {
type: 'done.invoke._store';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.store.resettingStorage:invocation[0]': {
type: 'done.invoke.store.resettingStorage:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform._store': {type: 'error.platform._store'; data: unknown};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
checkStorageInitialisedOrNot: 'done.invoke.store.checkStorageInitialisation:invocation[0]';
clear: 'done.invoke.store.resettingStorage:invocation[0]';
generateEncryptionKey: 'done.invoke.store.generatingEncryptionKey:invocation[0]';
getEncryptionKey: 'done.invoke.store.gettingEncryptionKey:invocation[0]';
hasAndroidEncryptionKey: 'done.invoke.store.checkEncryptionKey:invocation[0]';
store: 'done.invoke._store';
};
missingImplementations: {
actions: 'logKey';
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
forwardStoreRequest:
| 'APPEND'
| 'CLEAR'
| 'GET'
| 'PREPEND'
| 'REMOVE'
| 'REMOVE_ITEMS'
| 'REMOVE_VC_METADATA'
| 'SET'
| 'UPDATE';
logKey: 'KEY_RECEIVED';
notifyParent:
| 'KEY_RECEIVED'
| 'READY'
| 'done.invoke.store.resettingStorage:invocation[0]';
setEncryptionKey: 'KEY_RECEIVED';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isCustomSecureKeystore: 'KEY_RECEIVED';
};
eventsCausingServices: {
checkStorageInitialisedOrNot: 'ERROR';
clear: 'KEY_RECEIVED';
generateEncryptionKey: 'ERROR' | 'IGNORE' | 'READY';
getEncryptionKey: 'TRY_AGAIN';
hasAndroidEncryptionKey: never;
store:
| 'KEY_RECEIVED'
| 'READY'
| 'done.invoke.store.resettingStorage:invocation[0]';
};
matchesStates:
| 'checkEncryptionKey'
| 'checkStorageInitialisation'
| 'failedReadingKey'
| 'generatingEncryptionKey'
| 'gettingEncryptionKey'
| 'ready'
| 'resettingStorage';
tags: never;
}

View File

@@ -18,6 +18,11 @@ export function generateKeys(): Promise<KeyPair> {
return Promise.resolve(RSA.generateKeys(4096));
}
/**
* isCustomKeystore is a cached check of existence of a hardware keystore.
*/
export const isHardwareKeystoreExists = isCustomSecureKeystore();
export async function getJwt(
privateKey: string,
individualId: string,
@@ -70,7 +75,7 @@ export async function createSignature(
) {
let signature64;
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
const key = forge.pki.privateKeyFromPem(privateKey);
const md = forge.md.sha256.create();
md.update(preHash, 'utf8');
@@ -98,7 +103,13 @@ export function encodeB64(str: string) {
return replaceCharactersInB64(encodedB64);
}
export function isCustomSecureKeystore() {
/**
* DO NOT USE DIRECTLY and/or REPEATEDLY in application lifeycle.
*
* This can make a call to the Android native layer hence taking up more time,
* use the isCustomKeystore constant in the app lifeycle instead.
*/
function isCustomSecureKeystore() {
return !isIOS() ? SecureKeystore.deviceSupportsHardware() : false;
}
@@ -112,7 +123,7 @@ export interface WalletBindingResponse {
export async function clear() {
try {
console.log('clearing entire storage');
if (isCustomSecureKeystore()) {
if (isHardwareKeystoreExists) {
SecureKeystore.clearKeys();
}
await Storage.clear();
@@ -131,7 +142,7 @@ export async function encryptJson(
return JSON.stringify(data);
}
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return CryptoJS.AES.encrypt(data, encryptionKey).toString();
}
return await SecureKeystore.encryptData(ENCRYPTION_ID, data);
@@ -147,7 +158,7 @@ export async function decryptJson(
return JSON.parse(encryptedData);
}
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return CryptoJS.AES.decrypt(encryptedData, encryptionKey).toString(
CryptoJS.enc.Utf8,
);

View File

@@ -11,7 +11,7 @@ import {
decryptJson,
encryptJson,
HMAC_ALIAS,
isCustomSecureKeystore,
isHardwareKeystoreExists,
} from './cryptoutil/cryptoUtil';
import {VCMetadata} from './VCMetadata';
import {ENOENT, getItem} from '../machines/store';
@@ -30,7 +30,7 @@ async function generateHmac(
encryptionKey: string,
data: string,
): Promise<string> {
if (!isCustomSecureKeystore()) {
if (!isHardwareKeystoreExists) {
return CryptoJS.HmacSHA256(encryptionKey, data).toString();
}
return await SecureKeystore.generateHmacSha(HMAC_ALIAS, data);

View File

@@ -11,7 +11,7 @@ import {
} from '../GlobalVariables';
import {OBSRV_HOST} from 'react-native-dotenv';
import DeviceInfo from 'react-native-device-info';
import {isCustomSecureKeystore} from '../cryptoutil/cryptoUtil';
import {isHardwareKeystoreExists} from '../cryptoutil/cryptoUtil';
import * as RNLocalize from 'react-native-localize';
export function sendStartEvent(data) {
@@ -124,7 +124,7 @@ export function getAppInfoEventData() {
osName: DeviceInfo.getSystemName(),
osVersion: DeviceInfo.getSystemVersion(),
osApiLevel: Platform.Version.toString(),
isHardwareKeystoreSupported: isCustomSecureKeystore(),
isHardwareKeystoreSupported: isHardwareKeystoreExists,
dateTime: new Date().getTime(),
zone: RNLocalize.getTimeZone(),
offset: new Date().getTimezoneOffset() * 60 * 1000,