mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 13:38:01 -05:00
[INJIMOB-1240] : Fix face auth consent for minified view share (#1397)
* [INJIMOB-1240] Resolve conflicts Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-1240] Refactor scan machine and QrLogin machine Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-1240] Refactor scan machine and QrLogin machine Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-1240] Refactor scan machine and QrLogin machine Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-1240]: Fix.Share with selfie pop up bug Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-1240]: Refactor. scanMachine and qrLoginMachine Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-1240]: Refactor. scanMachine and qrLoginMachine Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> --------- Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>
This commit is contained in:
@@ -21,7 +21,7 @@ import {ScanEvents} from '../machines/bleShare/scan/scanMachine';
|
||||
import {BOTTOM_TAB_ROUTES, ScanStackParamList} from '../routes/routesConstants';
|
||||
import {NavigationProp, useNavigation} from '@react-navigation/native';
|
||||
import {MainBottomTabParamList} from '../routes/main';
|
||||
import {selectIsScanning} from '../machines/bleShare/scan/selectors';
|
||||
import {selectIsScanning} from '../machines/bleShare/scan/scanSelectors';
|
||||
import {
|
||||
VCItemEvents,
|
||||
VCItemMachine,
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
"verifyCredential": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
actions: "getKeyPairFromStore" | "loadKeyPair" | "logDownloaded" | "resetError" | "resetLoadingReason" | "resetVerificationErrorMessage" | "sendBackupEvent" | "sendErrorEndEvent" | "sendImpressionEvent" | "sendSuccessEndEvent" | "setCredentialTypes" | "setCredentialWrapper" | "setError" | "setIssuers" | "setLoadingReasonAsDisplayIssuers" | "setLoadingReasonAsDownloadingCredentials" | "setLoadingReasonAsSettingUp" | "setMetadataInCredentialData" | "setNoInternet" | "setOIDCConfigError" | "setPrivateKey" | "setPublicKey" | "setSelectedCredentialType" | "setSelectedIssuerId" | "setSelectedIssuers" | "setTokenResponse" | "setVCMetadata" | "setVerifiableCredential" | "storeKeyPair" | "storeVcMetaContext" | "storeVcsContext" | "storeVerifiableCredentialData" | "storeVerifiableCredentialMeta" | "updateVerificationErrorMessage";
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
guards: "canSelectIssuerAgain" | "hasKeyPair" | "hasUserCancelledBiometric" | "isCustomSecureKeystore" | "isInternetConnected" | "isMultipleCredentialsSupported" | "isOIDCConfigError" | "isOIDCflowCancelled" | "isSignedIn" | "shouldFetchIssuersAgain";
|
||||
services: "checkInternet" | "downloadCredential" | "downloadCredentialTypes" | "downloadIssuerConfig" | "downloadIssuersList" | "generateKeyPair" | "invokeAuthorization" | "isUserSignedAlready" | "verifyCredential";
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"getKeyPairFromStore": "TRY_AGAIN" | "done.invoke.issuersMachine.performAuthorization:invocation[0]";
|
||||
|
||||
170
machines/QrLogin/QrLoginActions.ts
Normal file
170
machines/QrLogin/QrLoginActions.ts
Normal file
@@ -0,0 +1,170 @@
|
||||
import { assign, send, sendParent } from "xstate";
|
||||
import i18n from "../../i18n";
|
||||
import { VCShareFlowType } from "../../shared/Utils";
|
||||
import { parseMetadatas } from "../../shared/VCMetadata";
|
||||
import { SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW, MY_VCS_STORE_KEY } from "../../shared/constants";
|
||||
import { getBindingCertificateConstant } from "../../shared/keystore/SecureKeystore";
|
||||
import { VC, linkTransactionResponse } from "../VerifiableCredential/VCMetaMachine/vc";
|
||||
import { StoreEvents } from "../store";
|
||||
|
||||
|
||||
|
||||
export const QrLoginActions=(model:any)=>{
|
||||
|
||||
return{
|
||||
setShowFaceAuthConsent: model.assign({
|
||||
showFaceAuthConsent: (_, event) => {
|
||||
return !event.isDoNotAskAgainChecked;
|
||||
},
|
||||
}),
|
||||
|
||||
storeShowFaceAuthConsent: send(
|
||||
(context, event) =>
|
||||
StoreEvents.SET(SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW, !event.isDoNotAskAgainChecked),
|
||||
{
|
||||
to: context => context.serviceRefs.store,
|
||||
},
|
||||
),
|
||||
|
||||
forwardToParent: sendParent('DISMISS'),
|
||||
|
||||
setScanData: model.assign((context, event) => {
|
||||
const linkCode = event.linkCode;
|
||||
const flowType = event.flowType;
|
||||
const selectedVc = event.selectedVc;
|
||||
return {
|
||||
...context,
|
||||
linkCode: linkCode,
|
||||
flowType: flowType,
|
||||
selectedVc: selectedVc,
|
||||
};
|
||||
}),
|
||||
getFaceAuthConsent: send(StoreEvents.GET(SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW), {
|
||||
to: (context:any) => context.serviceRefs.store,
|
||||
}),
|
||||
|
||||
updateShowFaceAuthConsent: model.assign({
|
||||
showFaceAuthConsent: (_, event) => {
|
||||
return event.response || event.response === null;
|
||||
},
|
||||
}),
|
||||
|
||||
// TODO: loaded VCMetadatas are not used anywhere. remove?
|
||||
loadMyVcs: send(StoreEvents.GET(MY_VCS_STORE_KEY), {
|
||||
to: context => context.serviceRefs.store,
|
||||
}),
|
||||
|
||||
setMyVcs: model.assign({
|
||||
myVcs: (_context, event) =>
|
||||
parseMetadatas((event.response || []) as object[]),
|
||||
}),
|
||||
|
||||
loadThumbprint: send(
|
||||
context =>
|
||||
StoreEvents.GET(
|
||||
getBindingCertificateConstant(
|
||||
context.selectedVc.walletBindingResponse?.walletBindingId,
|
||||
),
|
||||
),
|
||||
{to: context => context.serviceRefs.store},
|
||||
),
|
||||
setThumbprint: assign({
|
||||
thumbprint: (_context, event) => {
|
||||
return (event.response || '') as string;
|
||||
},
|
||||
}),
|
||||
resetLinkTransactionId: model.assign({
|
||||
linkTransactionId: () => '',
|
||||
}),
|
||||
|
||||
resetSelectedVoluntaryClaims: model.assign({
|
||||
selectedVoluntaryClaims: () => [],
|
||||
}),
|
||||
|
||||
setSelectedVc: assign({
|
||||
selectedVc: (context, event) => {
|
||||
return {...event.vc};
|
||||
},
|
||||
}),
|
||||
|
||||
resetSelectedVc: assign({
|
||||
selectedVc: {} as VC,
|
||||
}),
|
||||
|
||||
resetFlowType: assign({
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
}),
|
||||
|
||||
setlinkTransactionResponse: assign({
|
||||
linkTransactionResponse: (context, event) =>
|
||||
event.data as linkTransactionResponse,
|
||||
}),
|
||||
|
||||
expandLinkTransResp: assign({
|
||||
authFactors: context => context.linkTransactionResponse.authFactors,
|
||||
|
||||
authorizeScopes: context =>
|
||||
context.linkTransactionResponse.authorizeScopes,
|
||||
|
||||
clientName: context => context.linkTransactionResponse.clientName,
|
||||
|
||||
configs: context => context.linkTransactionResponse.configs,
|
||||
|
||||
essentialClaims: context =>
|
||||
context.linkTransactionResponse.essentialClaims,
|
||||
|
||||
linkTransactionId: context =>
|
||||
context.linkTransactionResponse.linkTransactionId,
|
||||
|
||||
logoUrl: context => context.linkTransactionResponse.logoUrl,
|
||||
|
||||
voluntaryClaims: context =>
|
||||
context.linkTransactionResponse.voluntaryClaims,
|
||||
}),
|
||||
|
||||
setClaims: context => {
|
||||
context.voluntaryClaims.map(claim => {
|
||||
context.isSharing[claim] = false;
|
||||
});
|
||||
},
|
||||
|
||||
SetErrorMessage: assign({
|
||||
errorMessage: (context, event) => {
|
||||
const message = event.data.name;
|
||||
const ID_ERRORS_MAP = {
|
||||
invalid_link_code: 'invalidQR',
|
||||
};
|
||||
const errorMessage = ID_ERRORS_MAP[message]
|
||||
? i18n.t(`errors.${ID_ERRORS_MAP[message]}`, {
|
||||
ns: 'QrLogin',
|
||||
})
|
||||
: i18n.t(`errors.genericError`, {
|
||||
ns: 'common',
|
||||
});
|
||||
|
||||
return errorMessage;
|
||||
},
|
||||
}),
|
||||
|
||||
setConsentClaims: assign({
|
||||
isSharing: (context, event) => {
|
||||
context.isSharing[event.claim] = !event.enable;
|
||||
if (!event.enable) {
|
||||
context.selectedVoluntaryClaims.push(event.claim);
|
||||
} else {
|
||||
context.selectedVoluntaryClaims =
|
||||
context.selectedVoluntaryClaims.filter(
|
||||
eachClaim => eachClaim !== event.claim,
|
||||
);
|
||||
}
|
||||
return {...context.isSharing};
|
||||
},
|
||||
}),
|
||||
setLinkedTransactionId: assign({
|
||||
linkedTransactionId: (context, event) =>
|
||||
event.data.linkedTransactionId as string,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
machines/QrLogin/QrLoginGuards.ts
Normal file
13
machines/QrLogin/QrLoginGuards.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { VCShareFlowType } from "../../shared/Utils";
|
||||
|
||||
export const QrLoginGuards={
|
||||
showFaceAuthConsentScreen: context => {
|
||||
return context.showFaceAuthConsent;
|
||||
},
|
||||
|
||||
isConsentAlreadyCaptured: (_, event) =>
|
||||
event.data?.consentAction === 'NOCAPTURE',
|
||||
|
||||
isSimpleShareFlow: (context, _event) =>
|
||||
context.flowType === VCShareFlowType.SIMPLE_SHARE,
|
||||
}
|
||||
277
machines/QrLogin/QrLoginMachine.ts
Normal file
277
machines/QrLogin/QrLoginMachine.ts
Normal file
@@ -0,0 +1,277 @@
|
||||
import {
|
||||
ActorRefFrom,
|
||||
EventFrom
|
||||
} from 'xstate';
|
||||
import { AppServices } from '../../shared/GlobalContext';
|
||||
import { TelemetryConstants } from '../../shared/telemetry/TelemetryConstants';
|
||||
import {
|
||||
getEndEventData,
|
||||
sendEndEvent,
|
||||
} from '../../shared/telemetry/TelemetryUtils';
|
||||
import { QrLoginActions } from './QrLoginActions';
|
||||
import { QrLoginmodel } from './QrLoginModel';
|
||||
import { QrLoginServices } from './QrLoginServices';
|
||||
import { QrLoginGuards } from './QrLoginGuards';
|
||||
|
||||
const model = QrLoginmodel;
|
||||
|
||||
export const QrLoginEvents = model.events;
|
||||
export type QrLoginRef = ActorRefFrom<typeof qrLoginMachine>;
|
||||
|
||||
export const qrLoginMachine =
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QEUBOAZA9lAlgOwDocIAbMAYgGUBhAQQDl6BJegcQH0ARAeXoFEA2gAYAuolAAHTLBwAXHJjziQAD0QBGACzqATAQCs+nZv0BmABzqL50zoA0IAJ6IA7KaEFNATnPmv6oUMhHUMAX1CHNCxcQmIyck4mSgBZJMphMSQQKRl5RWU1BF1zFwIvHQrTFxdNCxcANgdnBH16j1NbdT8vfW8q9XDIjGx8AhJ8AGsAFVQAQzxYWYBjPLxyCEUwIjwAN0wJraiRwnG8abmF5dWEfD2l2dWMjOUcuQUlLMKtXQMjEwsrL5bE1EF4XOYCEJ6iEXF4ekIOppzIMQEcYmNJjN5osVu9yGBUKhMKgCBISA8AGbEgC2BDRo1O52xV3eN12mHuj1Ezyyr1WBQ0JQhmlhotMZmM+hcIIQNX0nnUhh65h06hcOhKKPphFgAAtMAB3ADqs1QeHwUHI1F4ADEmAAlZI8yTSN75T6IEIeHT+eo1Lyaeriwwy+pggiwtXw9SKjU6LXDdF6w0ms0Wq0Mah8dDO7Ku-kehBegg+9R+7yB4P6GV+dQRlwBIRqoTqjX1BPRUaUfUGviE4kZ+hZnOiF7594Coo9TSQtyqqUx9zApyINpeCNIoVaYzlUwd45jTCzCDJRwANSWsCoU249r47DvlAACrxKIJR7zx+7QIU-fLofoMaATYWjaKGLjylCOjQi4gSmJoOgNPuSY9jsSzoDgsCyFQ2Z8NQUzsGe1C5nyE6Fr4M4BkI3j6DYtEttWK4tDGEb1H6DbmEYAZschozJgaaEYVh5Bnnw9pMDaACaJFfh8P6uLRZRIoqKl0UI5gyiK9SQtobjUZu0KaLxOqoehmHYYkKRpDJuRkfJRTqRCpj1PoTYBj01QVKGPwVIBHT6AGqq1MZBAUssYC0AArrIurkDatBZoRtDoEwnA2W6cmqJ6rklr6-qVoYjHNP4kI2Jo1ENr01EBiFYVLBF0WxfFiUsGeyWpelBb2cWpbltxVahiKuVqmGXT1IG6heLV4VRTFg7Dp1dlZUWOW9flQaFTW2glrBYK0SqZaqiFtyzOMEBMBAYB4PIsiOAkSSpJQ6Qfi6tnfstf4EABQFdKYoHqKG1EECUrnmEIcJ+FC7YRKiiajCdZ0XVdN13XeUz2pJhFiRJTB0FMTC8It72FD1eUVhtIZMQF2mRjUHT1FYPTQ0MnaEKgYAAI6RXAsjUIosDI1atoOk6L15m9mW-hBX0hD9IGaGBTEIfKvTNoGOhVF4zOw6zBDs1zPN8wsgt0EO2ZE5Lq7S99ql-QrANMe4M6RqNDa6NC5hGTD2oEBseAUJZj3PZkr0ZZOAS+AQzmuZNNGefYSshAYunUdCmvaz7+vc1hFpGwL13rJs2x7AcdJw2znPZ-IeBQHnyNsncDzvE8YukcTq42GUYYtuNgFsQGMqqnWNjwSNiFeACe7e+XeuVzzuf84LBJEiSZKUjSZe61n8813X10NxyTeKC3Ifi2HhYR05LluXHrY1qYO2OanY1sciKJ4Jgl3wFk2pjhLk4AFpGhMQAfKOE4CIGQKnizA8cQwB-3PvZYoEJVT+FVCUaC-hNDeXlDYCoipwRCCIeKEKjIsSXFxO9NulsiguWdpYIMQZoK9F6DKOmX0FYQSITHHoU1p6634qmc0NcEFdWWghNh4MCBlnqGDLQ7EAxvxgeibsho+wr1EUtEmLYIQqmjvbeCKoiqrgCCWTc4JtzeA1qQo8J5zyXk0e3BAIph7jTYvBQIwQLDgWdv4Bo5UkTqjMCFfiglzKOJoX4bS4oGyIR9FUIhCdmgMz0EEqw4pApaGgTrA8dUGoxQiZOGoX0Si1CDFYAKCEkkaChKVUeHQNYNGosdXYp1iBI2unIZoocxGFCRHoKU40VT+H2n4QG8oqig3Bj4LwUIXAhW3lhPeshCmFiROucqhlYK6AXA7Zoxg6wTwgv09JHRfAhT9vAz8-9Cz+HXJUxUCIzBIiRJpaCOkRoNlMGCME8EFlzxzrvRe11Vn2RBtI1oDM-pGAsF4GsdZXJEI8n8Go41wjhCAA */
|
||||
model.createMachine(
|
||||
{
|
||||
predictableActionArguments: true,
|
||||
preserveActionOrder: true,
|
||||
tsTypes: {} as import('./QrLoginMachine.typegen').Typegen0,
|
||||
schema: {
|
||||
context: model.initialContext,
|
||||
events: {} as EventFrom<typeof model>,
|
||||
},
|
||||
id: 'QrLogin',
|
||||
initial: 'waitingForData',
|
||||
entry: ['resetSelectedVc', 'resetFlowType'],
|
||||
states: {
|
||||
waitingForData: {
|
||||
on: {
|
||||
GET: {
|
||||
actions: [
|
||||
'setScanData',
|
||||
'resetLinkTransactionId',
|
||||
'resetSelectedVoluntaryClaims',
|
||||
],
|
||||
target: 'checkFaceAuthConsent',
|
||||
},
|
||||
},
|
||||
},
|
||||
checkFaceAuthConsent: {
|
||||
entry: 'getFaceAuthConsent',
|
||||
on: {
|
||||
STORE_RESPONSE: {
|
||||
actions: 'updateShowFaceAuthConsent',
|
||||
target: 'linkTransaction',
|
||||
},
|
||||
},
|
||||
},
|
||||
linkTransaction: {
|
||||
invoke: {
|
||||
src: 'linkTransaction',
|
||||
onDone: [
|
||||
{
|
||||
cond: 'isSimpleShareFlow',
|
||||
actions: [
|
||||
'setlinkTransactionResponse',
|
||||
'expandLinkTransResp',
|
||||
'setClaims',
|
||||
],
|
||||
target: 'loadMyVcs',
|
||||
},
|
||||
{
|
||||
cond: 'showFaceAuthConsentScreen',
|
||||
target: 'faceVerificationConsent',
|
||||
},
|
||||
{
|
||||
actions: [
|
||||
'setlinkTransactionResponse',
|
||||
'expandLinkTransResp',
|
||||
'setClaims',
|
||||
],
|
||||
target: 'faceAuth',
|
||||
},
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
actions: 'SetErrorMessage',
|
||||
target: 'ShowError',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
ShowError: {
|
||||
on: {
|
||||
DISMISS: {
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
},
|
||||
},
|
||||
loadMyVcs: {
|
||||
entry: 'loadMyVcs',
|
||||
on: {
|
||||
STORE_RESPONSE: {
|
||||
actions: 'setMyVcs',
|
||||
target: 'showvcList',
|
||||
},
|
||||
},
|
||||
},
|
||||
showvcList: {
|
||||
on: {
|
||||
SELECT_VC: {
|
||||
actions: 'setSelectedVc',
|
||||
},
|
||||
VERIFY: [
|
||||
{
|
||||
cond: 'showFaceAuthConsentScreen',
|
||||
target: 'faceVerificationConsent',
|
||||
},
|
||||
{
|
||||
target: 'faceAuth',
|
||||
},
|
||||
],
|
||||
DISMISS: {
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
},
|
||||
},
|
||||
faceVerificationConsent: {
|
||||
on: {
|
||||
FACE_VERIFICATION_CONSENT: {
|
||||
actions: ['storeShowFaceAuthConsent', 'setShowFaceAuthConsent'],
|
||||
target: 'faceAuth',
|
||||
},
|
||||
DISMISS: [{
|
||||
cond:'isSimpleShareFlow',
|
||||
target: 'showvcList',
|
||||
},
|
||||
{
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
faceAuth: {
|
||||
on: {
|
||||
FACE_VALID: {
|
||||
target: 'loadingThumbprint',
|
||||
},
|
||||
FACE_INVALID: {
|
||||
target: 'invalidIdentity',
|
||||
},
|
||||
CANCEL: [
|
||||
{
|
||||
cond: 'isSimpleShareFlow',
|
||||
target: 'showvcList',
|
||||
},
|
||||
{
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
invalidIdentity: {
|
||||
on: {
|
||||
DISMISS: [
|
||||
{
|
||||
cond: 'isSimpleShareFlow',
|
||||
target: 'showvcList',
|
||||
},
|
||||
{
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
,],
|
||||
RETRY_VERIFICATION: {
|
||||
target: 'faceAuth',
|
||||
},
|
||||
},
|
||||
},
|
||||
sendingAuthenticate: {
|
||||
invoke: {
|
||||
src: 'sendAuthenticate',
|
||||
onDone: [
|
||||
{
|
||||
cond: 'isConsentAlreadyCaptured',
|
||||
target: 'success',
|
||||
},
|
||||
{
|
||||
target: 'requestConsent',
|
||||
actions: 'setLinkedTransactionId',
|
||||
},
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
actions: 'SetErrorMessage',
|
||||
target: 'ShowError',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
requestConsent: {
|
||||
on: {
|
||||
CONFIRM: {
|
||||
target: 'sendingConsent',
|
||||
},
|
||||
TOGGLE_CONSENT_CLAIM: {
|
||||
actions: 'setConsentClaims',
|
||||
target: 'requestConsent',
|
||||
},
|
||||
DISMISS: {
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
},
|
||||
},
|
||||
loadingThumbprint: {
|
||||
entry: 'loadThumbprint',
|
||||
on: {
|
||||
STORE_RESPONSE: {
|
||||
actions: 'setThumbprint',
|
||||
target: 'sendingAuthenticate',
|
||||
},
|
||||
},
|
||||
},
|
||||
sendingConsent: {
|
||||
invoke: {
|
||||
src: 'sendConsent',
|
||||
onDone: {
|
||||
target: 'success',
|
||||
},
|
||||
onError: [
|
||||
{
|
||||
actions: 'SetErrorMessage',
|
||||
target: 'ShowError',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
success: {
|
||||
entry: [
|
||||
() =>
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.qrLogin,
|
||||
TelemetryConstants.EndEventStatus.success,
|
||||
),
|
||||
),
|
||||
],
|
||||
on: {
|
||||
CONFIRM: {
|
||||
target: 'done',
|
||||
},
|
||||
},
|
||||
},
|
||||
done: {
|
||||
type: 'final',
|
||||
data: context => context,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
actions:QrLoginActions(model),
|
||||
services:QrLoginServices,
|
||||
guards: QrLoginGuards,
|
||||
},
|
||||
);
|
||||
|
||||
export function createQrLoginMachine(serviceRefs: AppServices) {
|
||||
return qrLoginMachine.withContext({
|
||||
...qrLoginMachine.context,
|
||||
serviceRefs,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
64
machines/QrLogin/QrLoginMachine.typegen.ts
Normal file
64
machines/QrLogin/QrLoginMachine.typegen.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
// 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: "SetErrorMessage" | "expandLinkTransResp" | "forwardToParent" | "getFaceAuthConsent" | "loadMyVcs" | "loadThumbprint" | "resetFlowType" | "resetLinkTransactionId" | "resetSelectedVc" | "resetSelectedVoluntaryClaims" | "setClaims" | "setConsentClaims" | "setLinkedTransactionId" | "setMyVcs" | "setScanData" | "setSelectedVc" | "setShowFaceAuthConsent" | "setThumbprint" | "setlinkTransactionResponse" | "storeShowFaceAuthConsent" | "updateShowFaceAuthConsent";
|
||||
delays: never;
|
||||
guards: "isConsentAlreadyCaptured" | "isSimpleShareFlow" | "showFaceAuthConsentScreen";
|
||||
services: "linkTransaction" | "sendAuthenticate" | "sendConsent";
|
||||
};
|
||||
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": "CANCEL" | "DISMISS";
|
||||
"getFaceAuthConsent": "GET";
|
||||
"loadMyVcs": "done.invoke.QrLogin.linkTransaction:invocation[0]";
|
||||
"loadThumbprint": "FACE_VALID";
|
||||
"resetFlowType": "xstate.init";
|
||||
"resetLinkTransactionId": "GET";
|
||||
"resetSelectedVc": "xstate.init";
|
||||
"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";
|
||||
"setShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
|
||||
"setThumbprint": "STORE_RESPONSE";
|
||||
"setlinkTransactionResponse": "done.invoke.QrLogin.linkTransaction:invocation[0]";
|
||||
"storeShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
|
||||
"updateShowFaceAuthConsent": "STORE_RESPONSE";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"isConsentAlreadyCaptured": "done.invoke.QrLogin.sendingAuthenticate:invocation[0]";
|
||||
"isSimpleShareFlow": "CANCEL" | "DISMISS" | "done.invoke.QrLogin.linkTransaction:invocation[0]";
|
||||
"showFaceAuthConsentScreen": "VERIFY" | "done.invoke.QrLogin.linkTransaction:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"linkTransaction": "STORE_RESPONSE";
|
||||
"sendAuthenticate": "STORE_RESPONSE";
|
||||
"sendConsent": "CONFIRM";
|
||||
};
|
||||
matchesStates: "ShowError" | "checkFaceAuthConsent" | "done" | "faceAuth" | "faceVerificationConsent" | "invalidIdentity" | "linkTransaction" | "loadMyVcs" | "loadingThumbprint" | "requestConsent" | "sendingAuthenticate" | "sendingConsent" | "showvcList" | "success" | "waitingForData";
|
||||
tags: never;
|
||||
}
|
||||
|
||||
69
machines/QrLogin/QrLoginModel.ts
Normal file
69
machines/QrLogin/QrLoginModel.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { createModel } from "xstate/lib/model";
|
||||
import { AppServices } from "../../shared/GlobalContext";
|
||||
import { VCShareFlowType } from "../../shared/Utils";
|
||||
import { VCMetadata } from "../../shared/VCMetadata";
|
||||
import { VC, linkTransactionResponse } from "../VerifiableCredential/VCMetaMachine/vc";
|
||||
|
||||
const QrLoginEvents= {
|
||||
SELECT_VC: (vc: VC) => ({vc}),
|
||||
SCANNING_DONE: (params: string) => ({params}),
|
||||
STORE_RESPONSE: (response: unknown) => ({response}),
|
||||
STORE_ERROR: (error: Error) => ({error}),
|
||||
TOGGLE_CONSENT_CLAIM: (enable: boolean, claim: string) => ({
|
||||
enable,
|
||||
claim,
|
||||
}),
|
||||
DISMISS: () => ({}),
|
||||
CONFIRM: () => ({}),
|
||||
GET: (
|
||||
linkCode: string,
|
||||
flowType: string,
|
||||
selectedVc: VC,
|
||||
faceAuthConsentGiven: boolean,
|
||||
) => ({
|
||||
linkCode,
|
||||
flowType,
|
||||
selectedVc,
|
||||
faceAuthConsentGiven,
|
||||
}),
|
||||
VERIFY: () => ({}),
|
||||
CANCEL: () => ({}),
|
||||
FACE_VALID: () => ({}),
|
||||
FACE_INVALID: () => ({}),
|
||||
RETRY_VERIFICATION: () => ({}),
|
||||
FACE_VERIFICATION_CONSENT: (isDoNotAskAgainChecked: boolean) => ({
|
||||
isDoNotAskAgainChecked,
|
||||
}),
|
||||
}
|
||||
|
||||
export const QrLoginmodel = createModel(
|
||||
{
|
||||
serviceRefs: {} as AppServices,
|
||||
selectedVc: {} as VC,
|
||||
linkCode: '',
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
myVcs: [] as VCMetadata[],
|
||||
thumbprint: '',
|
||||
linkTransactionResponse: {} as linkTransactionResponse,
|
||||
authFactors: [],
|
||||
authorizeScopes: null,
|
||||
clientName: {},
|
||||
configs: {},
|
||||
essentialClaims: [],
|
||||
linkTransactionId: '',
|
||||
logoUrl: '',
|
||||
voluntaryClaims: [],
|
||||
selectedVoluntaryClaims: [],
|
||||
errorMessage: '',
|
||||
domainName: '',
|
||||
consentClaims: ['name', 'picture'],
|
||||
isSharing: {},
|
||||
linkedTransactionId: '',
|
||||
showFaceAuthConsent: true as boolean,
|
||||
},
|
||||
{
|
||||
events:QrLoginEvents,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
117
machines/QrLogin/QrLoginSelectors.ts
Normal file
117
machines/QrLogin/QrLoginSelectors.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { StateFrom } from "xstate";
|
||||
import { getMosipLogo } from "../../components/VC/common/VCUtils";
|
||||
import { VCMetadata } from "../../shared/VCMetadata";
|
||||
import { qrLoginMachine } from "./QrLoginMachine";
|
||||
|
||||
type State = StateFrom<typeof qrLoginMachine>;
|
||||
|
||||
export function selectMyVcs(state: State) {
|
||||
return state.context.myVcs;
|
||||
}
|
||||
|
||||
export function selectIsWaitingForData(state: State) {
|
||||
return state.matches('waitingForData');
|
||||
}
|
||||
|
||||
export function selectDomainName(state: State) {
|
||||
return state.context.domainName;
|
||||
}
|
||||
|
||||
export function selectIsLinkTransaction(state: State) {
|
||||
return state.matches('linkTransaction');
|
||||
}
|
||||
|
||||
export function selectIsloadMyVcs(state: State) {
|
||||
return state.matches('loadMyVcs');
|
||||
}
|
||||
|
||||
export function selectIsShowingVcList(state: State) {
|
||||
return state.matches('showvcList');
|
||||
}
|
||||
|
||||
export function selectIsisVerifyingIdentity(state: State) {
|
||||
return state.matches('faceAuth');
|
||||
}
|
||||
|
||||
export function selectIsInvalidIdentity(state: State) {
|
||||
return state.matches('invalidIdentity');
|
||||
}
|
||||
|
||||
export function selectIsShowError(state: State) {
|
||||
return state.matches('ShowError');
|
||||
}
|
||||
|
||||
export function selectIsRequestConsent(state: State) {
|
||||
return state.matches('requestConsent');
|
||||
}
|
||||
|
||||
export function selectIsSendingAuthenticate(state: State) {
|
||||
return state.matches('sendingAuthenticate');
|
||||
}
|
||||
|
||||
export function selectIsSendingConsent(state: State) {
|
||||
return state.matches('sendingConsent');
|
||||
}
|
||||
|
||||
export function selectIsVerifyingSuccesful(state: State) {
|
||||
return state.matches('success');
|
||||
}
|
||||
|
||||
export function selectCredential(state: State) {
|
||||
return new VCMetadata(state.context.selectedVc?.vcMetadata).isFromOpenId4VCI()
|
||||
? state.context.selectedVc?.verifiableCredential?.credential
|
||||
: state.context.selectedVc?.credential;
|
||||
}
|
||||
|
||||
export function selectVerifiableCredentialData(state: State) {
|
||||
const vcMetadata = new VCMetadata(state.context.selectedVc?.vcMetadata);
|
||||
return vcMetadata.isFromOpenId4VCI()
|
||||
? {
|
||||
vcMetadata: vcMetadata,
|
||||
face: state.context.selectedVc?.verifiableCredential?.credential
|
||||
?.credentialSubject?.face,
|
||||
issuerLogo: state.context.selectedVc?.verifiableCredential?.issuerLogo,
|
||||
wellKnown: state.context.selectedVc?.verifiableCredential?.wellKnown,
|
||||
credentialTypes:
|
||||
state.context.selectedVc?.verifiableCredential?.credentialTypes,
|
||||
issuer: vcMetadata.issuer,
|
||||
}
|
||||
: {
|
||||
vcMetadata: vcMetadata,
|
||||
issuer: vcMetadata.issuer,
|
||||
face: state.context.selectedVc?.credential?.biometrics?.face,
|
||||
issuerLogo: getMosipLogo(),
|
||||
};
|
||||
}
|
||||
|
||||
export function selectLinkTransactionResponse(state: State) {
|
||||
return state.context.linkTransactionResponse;
|
||||
}
|
||||
|
||||
export function selectEssentialClaims(state: State) {
|
||||
return state.context.essentialClaims;
|
||||
}
|
||||
|
||||
export function selectVoluntaryClaims(state: State) {
|
||||
return state.context.voluntaryClaims;
|
||||
}
|
||||
|
||||
export function selectLogoUrl(state: State) {
|
||||
return state.context.logoUrl;
|
||||
}
|
||||
|
||||
export function selectClientName(state: State) {
|
||||
return state.context.clientName;
|
||||
}
|
||||
|
||||
export function selectErrorMessage(state: State) {
|
||||
return state.context.errorMessage;
|
||||
}
|
||||
|
||||
export function selectIsSharing(state: State) {
|
||||
return state.context.isSharing;
|
||||
}
|
||||
|
||||
export function selectIsFaceVerificationConsent(state: State) {
|
||||
return state.matches('faceVerificationConsent');
|
||||
}
|
||||
111
machines/QrLogin/QrLoginServices.ts
Normal file
111
machines/QrLogin/QrLoginServices.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import {request} from '../../shared/request';
|
||||
import getAllConfigurations, { API_URLS } from "../../shared/api";
|
||||
import { ESIGNET_BASE_URL } from "../../shared/constants";
|
||||
import { isHardwareKeystoreExists, getJWT } from "../../shared/cryptoutil/cryptoUtil";
|
||||
import { getPrivateKey } from "../../shared/keystore/SecureKeystore";
|
||||
|
||||
export const QrLoginServices= {
|
||||
linkTransaction: async context => {
|
||||
const response = await request(
|
||||
API_URLS.linkTransaction.method,
|
||||
API_URLS.linkTransaction.buildURL(),
|
||||
{
|
||||
requestTime: String(new Date().toISOString()),
|
||||
request: {
|
||||
linkCode: context.linkCode,
|
||||
},
|
||||
},
|
||||
ESIGNET_BASE_URL,
|
||||
);
|
||||
return response.response;
|
||||
},
|
||||
|
||||
sendAuthenticate: async context => {
|
||||
let privateKey;
|
||||
const individualId = context.selectedVc.vcMetadata.id;
|
||||
if (!isHardwareKeystoreExists) {
|
||||
privateKey = await getPrivateKey(
|
||||
context.selectedVc.walletBindingResponse?.walletBindingId,
|
||||
);
|
||||
}
|
||||
|
||||
var config = await getAllConfigurations();
|
||||
const header = {
|
||||
alg: 'RS256',
|
||||
'x5t#S256': context.thumbprint,
|
||||
};
|
||||
|
||||
const payload = {
|
||||
iss: config.issuer,
|
||||
sub: individualId,
|
||||
aud: config.audience,
|
||||
iat: Math.floor(new Date().getTime() / 1000),
|
||||
exp: Math.floor(new Date().getTime() / 1000) + 18000,
|
||||
};
|
||||
|
||||
const jwt = await getJWT(header, payload, individualId, privateKey);
|
||||
|
||||
const response = await request(
|
||||
API_URLS.authenticate.method,
|
||||
API_URLS.authenticate.buildURL(),
|
||||
{
|
||||
requestTime: String(new Date().toISOString()),
|
||||
request: {
|
||||
linkedTransactionId: context.linkTransactionId,
|
||||
individualId: individualId,
|
||||
challengeList: [
|
||||
{
|
||||
authFactorType: 'WLA',
|
||||
challenge: jwt,
|
||||
format: 'jwt',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
ESIGNET_BASE_URL,
|
||||
);
|
||||
return response.response;
|
||||
},
|
||||
|
||||
sendConsent: async context => {
|
||||
let privateKey;
|
||||
const individualId = context.selectedVc.vcMetadata.id;
|
||||
if (!isHardwareKeystoreExists) {
|
||||
privateKey = await getPrivateKey(
|
||||
context.selectedVc.walletBindingResponse?.walletBindingId,
|
||||
);
|
||||
}
|
||||
|
||||
const header = {
|
||||
alg: 'RS256',
|
||||
'x5t#S256': context.thumbprint,
|
||||
};
|
||||
const payload = {
|
||||
accepted_claims: context.essentialClaims
|
||||
.concat(context.selectedVoluntaryClaims)
|
||||
.sort(),
|
||||
permitted_authorized_scopes: context.authorizeScopes,
|
||||
};
|
||||
|
||||
const JWT = await getJWT(header, payload, individualId, privateKey);
|
||||
const jwtComponents = JWT.split('.');
|
||||
const detachedSignature = jwtComponents[0] + '.' + jwtComponents[2];
|
||||
|
||||
const resp = await request(
|
||||
API_URLS.sendConsent.method,
|
||||
API_URLS.sendConsent.buildURL(),
|
||||
{
|
||||
requestTime: String(new Date().toISOString()),
|
||||
request: {
|
||||
linkedTransactionId: context.linkedTransactionId,
|
||||
acceptedClaims: context.essentialClaims
|
||||
.concat(context.selectedVoluntaryClaims)
|
||||
.sort(),
|
||||
permittedAuthorizeScopes: context.authorizeScopes,
|
||||
signature: detachedSignature,
|
||||
},
|
||||
},
|
||||
ESIGNET_BASE_URL,
|
||||
);
|
||||
},
|
||||
}
|
||||
@@ -1,710 +0,0 @@
|
||||
import {
|
||||
ActorRefFrom,
|
||||
assign,
|
||||
EventFrom,
|
||||
send,
|
||||
sendParent,
|
||||
StateFrom,
|
||||
} from 'xstate';
|
||||
import {createModel} from 'xstate/lib/model';
|
||||
import {AppServices} from '../shared/GlobalContext';
|
||||
import {
|
||||
ESIGNET_BASE_URL,
|
||||
FACE_AUTH_CONSENT,
|
||||
MY_VCS_STORE_KEY,
|
||||
} from '../shared/constants';
|
||||
import {StoreEvents} from './store';
|
||||
import {
|
||||
linkTransactionResponse,
|
||||
VC,
|
||||
} from './VerifiableCredential/VCMetaMachine/vc';
|
||||
import {request} from '../shared/request';
|
||||
import {
|
||||
getJWT,
|
||||
isHardwareKeystoreExists,
|
||||
} from '../shared/cryptoutil/cryptoUtil';
|
||||
import {
|
||||
getBindingCertificateConstant,
|
||||
getPrivateKey,
|
||||
} from '../shared/keystore/SecureKeystore';
|
||||
import i18n from '../i18n';
|
||||
import {parseMetadatas, VCMetadata} from '../shared/VCMetadata';
|
||||
import {
|
||||
getEndEventData,
|
||||
sendEndEvent,
|
||||
} from '../shared/telemetry/TelemetryUtils';
|
||||
import {TelemetryConstants} from '../shared/telemetry/TelemetryConstants';
|
||||
import getAllConfigurations, {API_URLS} from '../shared/api';
|
||||
import {VCShareFlowType} from '../shared/Utils';
|
||||
import {getMosipLogo} from '../components/VC/common/VCUtils';
|
||||
|
||||
const model = createModel(
|
||||
{
|
||||
serviceRefs: {} as AppServices,
|
||||
selectedVc: {} as VC,
|
||||
linkCode: '',
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
myVcs: [] as VCMetadata[],
|
||||
thumbprint: '',
|
||||
linkTransactionResponse: {} as linkTransactionResponse,
|
||||
authFactors: [],
|
||||
authorizeScopes: null,
|
||||
clientName: {},
|
||||
configs: {},
|
||||
essentialClaims: [],
|
||||
linkTransactionId: '',
|
||||
logoUrl: '',
|
||||
voluntaryClaims: [],
|
||||
selectedVoluntaryClaims: [],
|
||||
errorMessage: '',
|
||||
domainName: '',
|
||||
consentClaims: ['name', 'picture'],
|
||||
isSharing: {},
|
||||
linkedTransactionId: '',
|
||||
showFaceAuthConsent: true as boolean,
|
||||
},
|
||||
{
|
||||
events: {
|
||||
SELECT_VC: (vc: VC) => ({vc}),
|
||||
SCANNING_DONE: (params: string) => ({params}),
|
||||
STORE_RESPONSE: (response: unknown) => ({response}),
|
||||
STORE_ERROR: (error: Error) => ({error}),
|
||||
TOGGLE_CONSENT_CLAIM: (enable: boolean, claim: string) => ({
|
||||
enable,
|
||||
claim,
|
||||
}),
|
||||
DISMISS: () => ({}),
|
||||
CONFIRM: () => ({}),
|
||||
GET: (
|
||||
linkCode: string,
|
||||
flowType: string,
|
||||
selectedVc: VC,
|
||||
faceAuthConsentGiven: boolean,
|
||||
) => ({
|
||||
linkCode,
|
||||
flowType,
|
||||
selectedVc,
|
||||
faceAuthConsentGiven,
|
||||
}),
|
||||
VERIFY: () => ({}),
|
||||
CANCEL: () => ({}),
|
||||
FACE_VALID: () => ({}),
|
||||
FACE_INVALID: () => ({}),
|
||||
RETRY_VERIFICATION: () => ({}),
|
||||
FACE_VERIFICATION_CONSENT: (isConsentGiven: boolean) => ({
|
||||
isConsentGiven,
|
||||
}),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export const QrLoginEvents = model.events;
|
||||
export type QrLoginRef = ActorRefFrom<typeof qrLoginMachine>;
|
||||
|
||||
export const qrLoginMachine =
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QEUBOAZA9lAlgOwDocIAbMAYgGUBhAQQDl6BJegcQH0ARAeXoFEA2gAYAuolAAHTLBwAXHJjziQAD0QBGACzqATAQCs+nZv0BmABzqL50zoA0IAJ6IA7KaEFNATnPmv6oUMhHUMAX1CHNCxcQmIyck4mSgBZJMphMSQQKRl5RWU1BF1zFwIvHQrTFxdNCxcANgdnBH16j1NbdT8vfW8q9XDIjGx8AhJ8AGsAFVQAQzxYWYBjPLxyCEUwIjwAN0wJraiRwnG8abmF5dWEfD2l2dWMjOUcuQUlLMKtXQMjEwsrL5bE1EF4XOYCEJ6iEXF4ekIOppzIMQEcYmNJjN5osVu9yGBUKhMKgCBISA8AGbEgC2BDRo1O52xV3eN12mHuj1Ezyyr1WBQ0JQhmlhotMZmM+hcIIQNX0nnUhh65h06hcOhKKPphFgAAtMAB3ADqs1QeHwUHI1F4ADEmAAlZI8yTSN75T6IEIeHT+eo1Lyaeriwwy+pggiwtXw9SKjU6LXDdF6w0ms0Wq0Mah8dDO7Ku-kehBegg+9R+7yB4P6GV+dQRlwBIRqoTqjX1BPRUaUfUGviE4kZ+hZnOiF7594Coo9TSQtyqqUx9zApyINpeCNIoVaYzlUwd45jTCzCDJRwANSWsCoU249r47DvlAACrxKIJR7zx+7QIU-fLofoMaATYWjaKGLjylCOjQi4gSmJoOgNPuSY9jsSzoDgsCyFQ2Z8NQUzsGe1C5nyE6Fr4M4BkI3j6DYtEttWK4tDGEb1H6DbmEYAZschozJgaaEYVh5Bnnw9pMDaACaJFfh8P6uLRZRIoqKl0UI5gyiK9SQtobjUZu0KaLxOqoehmHYYkKRpDJuRkfJRTqRCpj1PoTYBj01QVKGPwVIBHT6AGqq1MZBAUssYC0AArrIurkDatBZoRtDoEwnA2W6cmqJ6rklr6-qVoYjHNP4kI2Jo1ENr01EBiFYVLBF0WxfFiUsGeyWpelBb2cWpbltxVahiKuVqmGXT1IG6heLV4VRTFg7Dp1dlZUWOW9flQaFTW2glrBYK0SqZaqiFtyzOMEBMBAYB4PIsiOAkSSpJQ6Qfi6tnfstf4EABQFdKYoHqKG1EECUrnmEIcJ+FC7YRKiiajCdZ0XVdN13XeUz2pJhFiRJTB0FMTC8It72FD1eUVhtIZMQF2mRjUHT1FYPTQ0MnaEKgYAAI6RXAsjUIosDI1atoOk6L15m9mW-hBX0hD9IGaGBTEIfKvTNoGOhVF4zOw6zBDs1zPN8wsgt0EO2ZE5Lq7S99ql-QrANMe4M6RqNDa6NC5hGTD2oEBseAUJZj3PZkr0ZZOAS+AQzmuZNNGefYSshAYunUdCmvaz7+vc1hFpGwL13rJs2x7AcdJw2znPZ-IeBQHnyNsncDzvE8YukcTq42GUYYtuNgFsQGMqqnWNjwSNiFeACe7e+XeuVzzuf84LBJEiSZKUjSZe61n8813X10NxyTeKC3Ifi2HhYR05LluXHrY1qYO2OanY1sciKJ4Jgl3wFk2pjhLk4AFpGhMQAfKOE4CIGQKnizA8cQwB-3PvZYoEJVT+FVCUaC-hNDeXlDYCoipwRCCIeKEKjIsSXFxO9NulsiguWdpYIMQZoK9F6DKOmX0FYQSITHHoU1p6634qmc0NcEFdWWghNh4MCBlnqGDLQ7EAxvxgeibsho+wr1EUtEmLYIQqmjvbeCKoiqrgCCWTc4JtzeA1qQo8J5zyXk0e3BAIph7jTYvBQIwQLDgWdv4Bo5UkTqjMCFfiglzKOJoX4bS4oGyIR9FUIhCdmgMz0EEqw4pApaGgTrA8dUGoxQiZOGoX0Si1CDFYAKCEkkaChKVUeHQNYNGosdXYp1iBI2unIZoocxGFCRHoKU40VT+H2n4QG8oqig3Bj4LwUIXAhW3lhPeshCmFiROucqhlYK6AXA7Zoxg6wTwgv09JHRfAhT9vAz8-9Cz+HXJUxUCIzBIiRJpaCOkRoNlMGCME8EFlzxzrvRe11Vn2RBtI1oDM-pGAsF4GsdZXJEI8n8Go41wjhCAA */
|
||||
model.createMachine(
|
||||
{
|
||||
predictableActionArguments: true,
|
||||
preserveActionOrder: true,
|
||||
tsTypes: {} as import('./QrLoginMachine.typegen').Typegen0,
|
||||
schema: {
|
||||
context: model.initialContext,
|
||||
events: {} as EventFrom<typeof model>,
|
||||
},
|
||||
id: 'QrLogin',
|
||||
initial: 'waitingForData',
|
||||
entry: ['resetSelectedVc', 'resetFlowType'],
|
||||
states: {
|
||||
waitingForData: {
|
||||
on: {
|
||||
GET: {
|
||||
actions: [
|
||||
'setScanData',
|
||||
'setFaceAuthConsent',
|
||||
'resetLinkTransactionId',
|
||||
'resetSelectedVoluntaryClaims',
|
||||
],
|
||||
target: 'linkTransaction',
|
||||
},
|
||||
},
|
||||
},
|
||||
linkTransaction: {
|
||||
invoke: {
|
||||
src: 'linkTransaction',
|
||||
onDone: [
|
||||
{
|
||||
cond: 'isSimpleShareFlow',
|
||||
actions: [
|
||||
'setlinkTransactionResponse',
|
||||
'expandLinkTransResp',
|
||||
'setClaims',
|
||||
],
|
||||
target: 'loadMyVcs',
|
||||
},
|
||||
{
|
||||
actions: [
|
||||
'setlinkTransactionResponse',
|
||||
'expandLinkTransResp',
|
||||
'setClaims',
|
||||
],
|
||||
target: 'faceAuth',
|
||||
},
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
actions: 'SetErrorMessage',
|
||||
target: 'ShowError',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
ShowError: {
|
||||
on: {
|
||||
DISMISS: {
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
},
|
||||
},
|
||||
loadMyVcs: {
|
||||
entry: 'loadMyVcs',
|
||||
on: {
|
||||
STORE_RESPONSE: {
|
||||
actions: 'setMyVcs',
|
||||
target: 'showvcList',
|
||||
},
|
||||
},
|
||||
},
|
||||
showvcList: {
|
||||
on: {
|
||||
SELECT_VC: {
|
||||
actions: 'setSelectedVc',
|
||||
},
|
||||
VERIFY: [
|
||||
{
|
||||
cond: 'showFaceAuthConsentScreen',
|
||||
target: 'faceVerificationConsent',
|
||||
},
|
||||
{
|
||||
target: 'faceAuth',
|
||||
},
|
||||
],
|
||||
DISMISS: {
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
},
|
||||
},
|
||||
faceVerificationConsent: {
|
||||
on: {
|
||||
FACE_VERIFICATION_CONSENT: {
|
||||
actions: ['storeShowFaceAuthConsent', 'setShowFaceAuthConsent'],
|
||||
target: 'faceAuth',
|
||||
},
|
||||
DISMISS: {
|
||||
target: 'showvcList',
|
||||
},
|
||||
},
|
||||
},
|
||||
faceAuth: {
|
||||
on: {
|
||||
FACE_VALID: {
|
||||
target: 'loadingThumbprint',
|
||||
},
|
||||
FACE_INVALID: {
|
||||
target: 'invalidIdentity',
|
||||
},
|
||||
CANCEL: [
|
||||
{
|
||||
cond: 'isSimpleShareFlow',
|
||||
target: 'showvcList',
|
||||
},
|
||||
{
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
invalidIdentity: {
|
||||
on: {
|
||||
DISMISS: {
|
||||
target: 'showvcList',
|
||||
},
|
||||
RETRY_VERIFICATION: {
|
||||
target: 'faceAuth',
|
||||
},
|
||||
},
|
||||
},
|
||||
sendingAuthenticate: {
|
||||
invoke: {
|
||||
src: 'sendAuthenticate',
|
||||
onDone: [
|
||||
{
|
||||
cond: 'isConsentAlreadyCaptured',
|
||||
target: 'success',
|
||||
},
|
||||
{
|
||||
target: 'requestConsent',
|
||||
actions: 'setLinkedTransactionId',
|
||||
},
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
actions: 'SetErrorMessage',
|
||||
target: 'ShowError',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
requestConsent: {
|
||||
on: {
|
||||
CONFIRM: {
|
||||
target: 'sendingConsent',
|
||||
},
|
||||
TOGGLE_CONSENT_CLAIM: {
|
||||
actions: 'setConsentClaims',
|
||||
target: 'requestConsent',
|
||||
},
|
||||
DISMISS: {
|
||||
actions: 'forwardToParent',
|
||||
target: 'waitingForData',
|
||||
},
|
||||
},
|
||||
},
|
||||
loadingThumbprint: {
|
||||
entry: 'loadThumbprint',
|
||||
on: {
|
||||
STORE_RESPONSE: {
|
||||
actions: 'setThumbprint',
|
||||
target: 'sendingAuthenticate',
|
||||
},
|
||||
},
|
||||
},
|
||||
sendingConsent: {
|
||||
invoke: {
|
||||
src: 'sendConsent',
|
||||
onDone: {
|
||||
target: 'success',
|
||||
},
|
||||
onError: [
|
||||
{
|
||||
actions: 'SetErrorMessage',
|
||||
target: 'ShowError',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
success: {
|
||||
entry: [
|
||||
() =>
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.qrLogin,
|
||||
TelemetryConstants.EndEventStatus.success,
|
||||
),
|
||||
),
|
||||
],
|
||||
on: {
|
||||
CONFIRM: {
|
||||
target: 'done',
|
||||
},
|
||||
},
|
||||
},
|
||||
done: {
|
||||
type: 'final',
|
||||
data: context => context,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
actions: {
|
||||
setShowFaceAuthConsent: model.assign({
|
||||
showFaceAuthConsent: (_, event) => {
|
||||
return !event.isConsentGiven;
|
||||
},
|
||||
}),
|
||||
|
||||
storeShowFaceAuthConsent: send(
|
||||
(context, event) =>
|
||||
StoreEvents.SET(FACE_AUTH_CONSENT, !event.isConsentGiven),
|
||||
{
|
||||
to: context => context.serviceRefs.store,
|
||||
},
|
||||
),
|
||||
|
||||
forwardToParent: sendParent('DISMISS'),
|
||||
|
||||
setScanData: model.assign((context, event) => {
|
||||
const linkCode = event.linkCode;
|
||||
const flowType = event.flowType;
|
||||
const selectedVc = event.selectedVc;
|
||||
return {
|
||||
...context,
|
||||
linkCode: linkCode,
|
||||
flowType: flowType,
|
||||
selectedVc: selectedVc,
|
||||
};
|
||||
}),
|
||||
|
||||
setFaceAuthConsent: assign({
|
||||
showFaceAuthConsent: (context, event) => {
|
||||
return event.faceAuthConsentGiven;
|
||||
},
|
||||
}),
|
||||
|
||||
// TODO: loaded VCMetadatas are not used anywhere. remove?
|
||||
loadMyVcs: send(StoreEvents.GET(MY_VCS_STORE_KEY), {
|
||||
to: context => context.serviceRefs.store,
|
||||
}),
|
||||
|
||||
setMyVcs: model.assign({
|
||||
myVcs: (_context, event) =>
|
||||
parseMetadatas((event.response || []) as object[]),
|
||||
}),
|
||||
|
||||
loadThumbprint: send(
|
||||
context =>
|
||||
StoreEvents.GET(
|
||||
getBindingCertificateConstant(
|
||||
context.selectedVc.walletBindingResponse?.walletBindingId,
|
||||
),
|
||||
),
|
||||
{to: context => context.serviceRefs.store},
|
||||
),
|
||||
setThumbprint: assign({
|
||||
thumbprint: (_context, event) => {
|
||||
return (event.response || '') as string;
|
||||
},
|
||||
}),
|
||||
resetLinkTransactionId: model.assign({
|
||||
linkTransactionId: () => '',
|
||||
}),
|
||||
|
||||
resetSelectedVoluntaryClaims: model.assign({
|
||||
selectedVoluntaryClaims: () => [],
|
||||
}),
|
||||
|
||||
setSelectedVc: assign({
|
||||
selectedVc: (context, event) => {
|
||||
return {...event.vc};
|
||||
},
|
||||
}),
|
||||
|
||||
resetSelectedVc: assign({
|
||||
selectedVc: {} as VC,
|
||||
}),
|
||||
|
||||
resetFlowType: assign({
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
}),
|
||||
|
||||
setlinkTransactionResponse: assign({
|
||||
linkTransactionResponse: (context, event) =>
|
||||
event.data as linkTransactionResponse,
|
||||
}),
|
||||
|
||||
expandLinkTransResp: assign({
|
||||
authFactors: context => context.linkTransactionResponse.authFactors,
|
||||
|
||||
authorizeScopes: context =>
|
||||
context.linkTransactionResponse.authorizeScopes,
|
||||
|
||||
clientName: context => context.linkTransactionResponse.clientName,
|
||||
|
||||
configs: context => context.linkTransactionResponse.configs,
|
||||
|
||||
essentialClaims: context =>
|
||||
context.linkTransactionResponse.essentialClaims,
|
||||
|
||||
linkTransactionId: context =>
|
||||
context.linkTransactionResponse.linkTransactionId,
|
||||
|
||||
logoUrl: context => context.linkTransactionResponse.logoUrl,
|
||||
|
||||
voluntaryClaims: context =>
|
||||
context.linkTransactionResponse.voluntaryClaims,
|
||||
}),
|
||||
|
||||
setClaims: context => {
|
||||
context.voluntaryClaims.map(claim => {
|
||||
context.isSharing[claim] = false;
|
||||
});
|
||||
},
|
||||
|
||||
SetErrorMessage: assign({
|
||||
errorMessage: (context, event) => {
|
||||
const message = event.data.name;
|
||||
const ID_ERRORS_MAP = {
|
||||
invalid_link_code: 'invalidQR',
|
||||
};
|
||||
const errorMessage = ID_ERRORS_MAP[message]
|
||||
? i18n.t(`errors.${ID_ERRORS_MAP[message]}`, {
|
||||
ns: 'QrLogin',
|
||||
})
|
||||
: i18n.t(`errors.genericError`, {
|
||||
ns: 'common',
|
||||
});
|
||||
|
||||
return errorMessage;
|
||||
},
|
||||
}),
|
||||
|
||||
setConsentClaims: assign({
|
||||
isSharing: (context, event) => {
|
||||
context.isSharing[event.claim] = !event.enable;
|
||||
if (!event.enable) {
|
||||
context.selectedVoluntaryClaims.push(event.claim);
|
||||
} else {
|
||||
context.selectedVoluntaryClaims =
|
||||
context.selectedVoluntaryClaims.filter(
|
||||
eachClaim => eachClaim !== event.claim,
|
||||
);
|
||||
}
|
||||
return {...context.isSharing};
|
||||
},
|
||||
}),
|
||||
setLinkedTransactionId: assign({
|
||||
linkedTransactionId: (context, event) =>
|
||||
event.data.linkedTransactionId as string,
|
||||
}),
|
||||
},
|
||||
services: {
|
||||
linkTransaction: async context => {
|
||||
const response = await request(
|
||||
API_URLS.linkTransaction.method,
|
||||
API_URLS.linkTransaction.buildURL(),
|
||||
{
|
||||
requestTime: String(new Date().toISOString()),
|
||||
request: {
|
||||
linkCode: context.linkCode,
|
||||
},
|
||||
},
|
||||
ESIGNET_BASE_URL,
|
||||
);
|
||||
return response.response;
|
||||
},
|
||||
|
||||
sendAuthenticate: async context => {
|
||||
let privateKey;
|
||||
const individualId = context.selectedVc.vcMetadata.id;
|
||||
if (!isHardwareKeystoreExists) {
|
||||
privateKey = await getPrivateKey(
|
||||
context.selectedVc.walletBindingResponse?.walletBindingId,
|
||||
);
|
||||
}
|
||||
|
||||
var config = await getAllConfigurations();
|
||||
const header = {
|
||||
alg: 'RS256',
|
||||
'x5t#S256': context.thumbprint,
|
||||
};
|
||||
|
||||
const payload = {
|
||||
iss: config.issuer,
|
||||
sub: individualId,
|
||||
aud: config.audience,
|
||||
iat: Math.floor(new Date().getTime() / 1000),
|
||||
exp: Math.floor(new Date().getTime() / 1000) + 18000,
|
||||
};
|
||||
|
||||
const jwt = await getJWT(header, payload, individualId, privateKey);
|
||||
|
||||
const response = await request(
|
||||
API_URLS.authenticate.method,
|
||||
API_URLS.authenticate.buildURL(),
|
||||
{
|
||||
requestTime: String(new Date().toISOString()),
|
||||
request: {
|
||||
linkedTransactionId: context.linkTransactionId,
|
||||
individualId: individualId,
|
||||
challengeList: [
|
||||
{
|
||||
authFactorType: 'WLA',
|
||||
challenge: jwt,
|
||||
format: 'jwt',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
ESIGNET_BASE_URL,
|
||||
);
|
||||
return response.response;
|
||||
},
|
||||
|
||||
sendConsent: async context => {
|
||||
let privateKey;
|
||||
const individualId = context.selectedVc.vcMetadata.id;
|
||||
if (!isHardwareKeystoreExists) {
|
||||
privateKey = await getPrivateKey(
|
||||
context.selectedVc.walletBindingResponse?.walletBindingId,
|
||||
);
|
||||
}
|
||||
|
||||
const header = {
|
||||
alg: 'RS256',
|
||||
'x5t#S256': context.thumbprint,
|
||||
};
|
||||
const payload = {
|
||||
accepted_claims: context.essentialClaims
|
||||
.concat(context.selectedVoluntaryClaims)
|
||||
.sort(),
|
||||
permitted_authorized_scopes: context.authorizeScopes,
|
||||
};
|
||||
|
||||
const JWT = await getJWT(header, payload, individualId, privateKey);
|
||||
const jwtComponents = JWT.split('.');
|
||||
const detachedSignature = jwtComponents[0] + '.' + jwtComponents[2];
|
||||
|
||||
const resp = await request(
|
||||
API_URLS.sendConsent.method,
|
||||
API_URLS.sendConsent.buildURL(),
|
||||
{
|
||||
requestTime: String(new Date().toISOString()),
|
||||
request: {
|
||||
linkedTransactionId: context.linkedTransactionId,
|
||||
acceptedClaims: context.essentialClaims
|
||||
.concat(context.selectedVoluntaryClaims)
|
||||
.sort(),
|
||||
permittedAuthorizeScopes: context.authorizeScopes,
|
||||
signature: detachedSignature,
|
||||
},
|
||||
},
|
||||
ESIGNET_BASE_URL,
|
||||
);
|
||||
},
|
||||
},
|
||||
guards: {
|
||||
showFaceAuthConsentScreen: context => {
|
||||
return context.showFaceAuthConsent;
|
||||
},
|
||||
|
||||
isConsentAlreadyCaptured: (_, event) =>
|
||||
event.data?.consentAction === 'NOCAPTURE',
|
||||
|
||||
isSimpleShareFlow: (context, _event) =>
|
||||
context.flowType === VCShareFlowType.SIMPLE_SHARE,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export function createQrLoginMachine(serviceRefs: AppServices) {
|
||||
return qrLoginMachine.withContext({
|
||||
...qrLoginMachine.context,
|
||||
serviceRefs,
|
||||
});
|
||||
}
|
||||
|
||||
type State = StateFrom<typeof qrLoginMachine>;
|
||||
|
||||
export function selectMyVcs(state: State) {
|
||||
return state.context.myVcs;
|
||||
}
|
||||
|
||||
export function selectIsWaitingForData(state: State) {
|
||||
return state.matches('waitingForData');
|
||||
}
|
||||
|
||||
export function selectDomainName(state: State) {
|
||||
return state.context.domainName;
|
||||
}
|
||||
|
||||
export function selectIsLinkTransaction(state: State) {
|
||||
return state.matches('linkTransaction');
|
||||
}
|
||||
|
||||
export function selectIsloadMyVcs(state: State) {
|
||||
return state.matches('loadMyVcs');
|
||||
}
|
||||
|
||||
export function selectIsShowingVcList(state: State) {
|
||||
return state.matches('showvcList');
|
||||
}
|
||||
|
||||
export function selectIsisVerifyingIdentity(state: State) {
|
||||
return state.matches('faceAuth');
|
||||
}
|
||||
|
||||
export function selectIsInvalidIdentity(state: State) {
|
||||
return state.matches('invalidIdentity');
|
||||
}
|
||||
|
||||
export function selectIsShowError(state: State) {
|
||||
return state.matches('ShowError');
|
||||
}
|
||||
|
||||
export function selectIsRequestConsent(state: State) {
|
||||
return state.matches('requestConsent');
|
||||
}
|
||||
|
||||
export function selectIsSendingAuthenticate(state: State) {
|
||||
return state.matches('sendingAuthenticate');
|
||||
}
|
||||
|
||||
export function selectIsSendingConsent(state: State) {
|
||||
return state.matches('sendingConsent');
|
||||
}
|
||||
|
||||
export function selectIsVerifyingSuccesful(state: State) {
|
||||
return state.matches('success');
|
||||
}
|
||||
|
||||
export function selectCredential(state: State) {
|
||||
return new VCMetadata(state.context.selectedVc?.vcMetadata).isFromOpenId4VCI()
|
||||
? state.context.selectedVc?.verifiableCredential?.credential
|
||||
: state.context.selectedVc?.credential;
|
||||
}
|
||||
|
||||
export function selectVerifiableCredentialData(state: State) {
|
||||
const vcMetadata = new VCMetadata(state.context.selectedVc?.vcMetadata);
|
||||
return vcMetadata.isFromOpenId4VCI()
|
||||
? {
|
||||
vcMetadata: vcMetadata,
|
||||
face: state.context.selectedVc?.verifiableCredential?.credential
|
||||
?.credentialSubject?.face,
|
||||
issuerLogo: state.context.selectedVc?.verifiableCredential?.issuerLogo,
|
||||
wellKnown: state.context.selectedVc?.verifiableCredential?.wellKnown,
|
||||
credentialTypes:
|
||||
state.context.selectedVc?.verifiableCredential?.credentialTypes,
|
||||
issuer: vcMetadata.issuer,
|
||||
}
|
||||
: {
|
||||
vcMetadata: vcMetadata,
|
||||
issuer: vcMetadata.issuer,
|
||||
face: state.context.selectedVc?.credential?.biometrics?.face,
|
||||
issuerLogo: getMosipLogo(),
|
||||
};
|
||||
}
|
||||
|
||||
export function selectLinkTransactionResponse(state: State) {
|
||||
return state.context.linkTransactionResponse;
|
||||
}
|
||||
|
||||
export function selectEssentialClaims(state: State) {
|
||||
return state.context.essentialClaims;
|
||||
}
|
||||
|
||||
export function selectVoluntaryClaims(state: State) {
|
||||
return state.context.voluntaryClaims;
|
||||
}
|
||||
|
||||
export function selectLogoUrl(state: State) {
|
||||
return state.context.logoUrl;
|
||||
}
|
||||
|
||||
export function selectClientName(state: State) {
|
||||
return state.context.clientName;
|
||||
}
|
||||
|
||||
export function selectErrorMessage(state: State) {
|
||||
return state.context.errorMessage;
|
||||
}
|
||||
|
||||
export function selectIsSharing(state: State) {
|
||||
return state.context.isSharing;
|
||||
}
|
||||
|
||||
export function selectIsFaceVerificationConsent(state: State) {
|
||||
return state.matches('faceVerificationConsent');
|
||||
}
|
||||
@@ -1,95 +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: 'CANCEL' | 'DISMISS';
|
||||
loadMyVcs: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
|
||||
loadThumbprint: 'FACE_VALID';
|
||||
resetFlowType: 'xstate.init';
|
||||
resetLinkTransactionId: 'GET';
|
||||
resetSelectedVc: 'xstate.init';
|
||||
resetSelectedVoluntaryClaims: 'GET';
|
||||
setClaims: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
|
||||
setConsentClaims: 'TOGGLE_CONSENT_CLAIM';
|
||||
setFaceAuthConsent: 'GET';
|
||||
setLinkedTransactionId: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
|
||||
setMyVcs: 'STORE_RESPONSE';
|
||||
setScanData: 'GET';
|
||||
setSelectedVc: 'SELECT_VC';
|
||||
setShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
|
||||
setThumbprint: 'STORE_RESPONSE';
|
||||
setlinkTransactionResponse: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
|
||||
storeShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isConsentAlreadyCaptured: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
|
||||
isSimpleShareFlow:
|
||||
| 'CANCEL'
|
||||
| 'done.invoke.QrLogin.linkTransaction:invocation[0]';
|
||||
showFaceAuthConsentScreen: 'VERIFY';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
linkTransaction: 'GET';
|
||||
sendAuthenticate: 'STORE_RESPONSE';
|
||||
sendConsent: 'CONFIRM';
|
||||
};
|
||||
matchesStates:
|
||||
| 'ShowError'
|
||||
| 'done'
|
||||
| 'faceAuth'
|
||||
| 'faceVerificationConsent'
|
||||
| 'invalidIdentity'
|
||||
| 'linkTransaction'
|
||||
| 'loadMyVcs'
|
||||
| 'loadingThumbprint'
|
||||
| 'requestConsent'
|
||||
| 'sendingAuthenticate'
|
||||
| 'sendingConsent'
|
||||
| 'showvcList'
|
||||
| 'success'
|
||||
| 'waitingForData';
|
||||
tags: never;
|
||||
}
|
||||
@@ -1,384 +1,123 @@
|
||||
|
||||
// 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-machine.kebabPopUp.triggerAutoBackup:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.verifyingCredential:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.verifyingCredential:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]': {
|
||||
type: 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey: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-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]': {
|
||||
type: 'error.platform.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.vc-item-machine.verifyingCredential:invocation[0]': {
|
||||
type: 'error.platform.vc-item-machine.verifyingCredential:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]': {
|
||||
type: 'error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]': {
|
||||
type: 'error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]': {
|
||||
type: 'error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]': {
|
||||
type: 'error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]': {
|
||||
type: 'error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
data: unknown;
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
'xstate.stop': {type: 'xstate.stop'};
|
||||
"": { 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-machine.kebabPopUp.triggerAutoBackup:invocation[0]": { type: "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]": { type: "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]": { type: "done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]": { type: "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.verifyingCredential:invocation[0]": { type: "done.invoke.vc-item-machine.verifyingCredential:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey: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-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]": { type: "error.platform.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]"; data: unknown };
|
||||
"error.platform.vc-item-machine.verifyingCredential:invocation[0]": { type: "error.platform.vc-item-machine.verifyingCredential:invocation[0]"; data: unknown };
|
||||
"error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]"; data: unknown };
|
||||
"error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]"; data: unknown };
|
||||
"error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]"; data: unknown };
|
||||
"error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]"; data: unknown };
|
||||
"error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]"; data: unknown };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
"xstate.stop": { type: "xstate.stop" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
addWalletBindingId: 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]';
|
||||
checkDownloadExpiryLimit: 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
|
||||
checkStatus: 'done.invoke.checkStatus';
|
||||
downloadCredential: 'done.invoke.downloadCredential';
|
||||
generateKeyPair: 'done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]';
|
||||
isUserSignedAlready:
|
||||
| 'done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
|
||||
loadDownloadLimitConfig: 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
|
||||
requestBindingOTP:
|
||||
| 'done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]';
|
||||
updatePrivateKey: 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
verifyCredential: 'done.invoke.vc-item-machine.verifyingCredential:invocation[0]';
|
||||
"addWalletBindingId": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
|
||||
"checkDownloadExpiryLimit": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]";
|
||||
"checkStatus": "done.invoke.checkStatus";
|
||||
"downloadCredential": "done.invoke.downloadCredential";
|
||||
"generateKeyPair": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
|
||||
"isUserSignedAlready": "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]";
|
||||
"loadDownloadLimitConfig": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
|
||||
"requestBindingOTP": "done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]";
|
||||
"updatePrivateKey": "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"verifyCredential": "done.invoke.vc-item-machine.verifyingCredential:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions:
|
||||
| 'addVcToInProgressDownloads'
|
||||
| 'closeViewVcModal'
|
||||
| 'incrementDownloadCounter'
|
||||
| 'logDownloaded'
|
||||
| 'logRemovedVc'
|
||||
| 'logWalletBindingFailure'
|
||||
| 'logWalletBindingSuccess'
|
||||
| 'refreshAllVcs'
|
||||
| 'removeVcFromInProgressDownloads'
|
||||
| 'removeVcItem'
|
||||
| 'removeVcMetaDataFromStorage'
|
||||
| 'removeVcMetaDataFromVcMachineContext'
|
||||
| 'requestVcContext'
|
||||
| 'resetIsMachineInKebabPopupState'
|
||||
| 'resetPrivateKey'
|
||||
| 'sendActivationStartEvent'
|
||||
| 'sendActivationSuccessEvent'
|
||||
| 'sendBackupEvent'
|
||||
| 'sendDownloadLimitExpire'
|
||||
| 'sendTelemetryEvents'
|
||||
| 'sendUserCancelledActivationFailedEndEvent'
|
||||
| 'sendVcUpdated'
|
||||
| 'sendVerificationError'
|
||||
| 'sendWalletBindingErrorEvent'
|
||||
| 'sendWalletBindingSuccess'
|
||||
| 'setCommunicationDetails'
|
||||
| 'setContext'
|
||||
| 'setDownloadInterval'
|
||||
| 'setErrorAsVerificationError'
|
||||
| 'setErrorAsWalletBindingError'
|
||||
| 'setMaxDownloadCount'
|
||||
| 'setOTP'
|
||||
| 'setPinCard'
|
||||
| 'setPrivateKey'
|
||||
| 'setPublicKey'
|
||||
| 'setThumbprintForWalletBindingId'
|
||||
| 'setVcKey'
|
||||
| 'setVcMetadata'
|
||||
| 'setWalletBindingResponse'
|
||||
| 'storeContext'
|
||||
| 'storeVcInContext'
|
||||
| 'unSetBindingTransactionId'
|
||||
| 'unSetError'
|
||||
| 'unSetOTP';
|
||||
actions: "addVcToInProgressDownloads" | "closeViewVcModal" | "incrementDownloadCounter" | "logDownloaded" | "logRemovedVc" | "logWalletBindingFailure" | "logWalletBindingSuccess" | "refreshAllVcs" | "removeVcFromInProgressDownloads" | "removeVcItem" | "removeVcMetaDataFromStorage" | "removeVcMetaDataFromVcMachineContext" | "requestVcContext" | "resetIsMachineInKebabPopupState" | "resetPrivateKey" | "sendActivationStartEvent" | "sendActivationSuccessEvent" | "sendBackupEvent" | "sendDownloadLimitExpire" | "sendTelemetryEvents" | "sendUserCancelledActivationFailedEndEvent" | "sendVcUpdated" | "sendVerificationError" | "sendWalletBindingErrorEvent" | "sendWalletBindingSuccess" | "setCommunicationDetails" | "setContext" | "setDownloadInterval" | "setErrorAsVerificationError" | "setErrorAsWalletBindingError" | "setMaxDownloadCount" | "setOTP" | "setPinCard" | "setPrivateKey" | "setPublicKey" | "setThumbprintForWalletBindingId" | "setVcKey" | "setVcMetadata" | "setWalletBindingResponse" | "storeContext" | "storeVcInContext" | "unSetBindingTransactionId" | "unSetError" | "unSetOTP";
|
||||
delays: never;
|
||||
guards:
|
||||
| 'hasCredential'
|
||||
| 'isCustomSecureKeystore'
|
||||
| 'isDownloadAllowed'
|
||||
| 'isSignedIn';
|
||||
services:
|
||||
| 'addWalletBindingId'
|
||||
| 'checkDownloadExpiryLimit'
|
||||
| 'checkStatus'
|
||||
| 'downloadCredential'
|
||||
| 'generateKeyPair'
|
||||
| 'isUserSignedAlready'
|
||||
| 'loadDownloadLimitConfig'
|
||||
| 'requestBindingOTP'
|
||||
| 'updatePrivateKey'
|
||||
| 'verifyCredential';
|
||||
guards: "hasCredential" | "isCustomSecureKeystore" | "isDownloadAllowed" | "isSignedIn";
|
||||
services: "addWalletBindingId" | "checkDownloadExpiryLimit" | "checkStatus" | "downloadCredential" | "generateKeyPair" | "isUserSignedAlready" | "loadDownloadLimitConfig" | "requestBindingOTP" | "updatePrivateKey" | "verifyCredential";
|
||||
};
|
||||
eventsCausingActions: {
|
||||
addVcToInProgressDownloads: 'GET_VC_RESPONSE';
|
||||
closeViewVcModal: 'CLOSE_VC_MODAL' | 'STORE_RESPONSE';
|
||||
incrementDownloadCounter:
|
||||
| 'POLL'
|
||||
| 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
|
||||
logDownloaded: 'STORE_RESPONSE';
|
||||
logRemovedVc:
|
||||
| 'STORE_RESPONSE'
|
||||
| 'done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]';
|
||||
logWalletBindingFailure:
|
||||
| 'error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
logWalletBindingSuccess:
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
refreshAllVcs:
|
||||
| 'STORE_RESPONSE'
|
||||
| 'done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]';
|
||||
removeVcFromInProgressDownloads: 'STORE_RESPONSE';
|
||||
removeVcItem: 'CONFIRM';
|
||||
removeVcMetaDataFromStorage:
|
||||
| 'STORE_ERROR'
|
||||
| 'error.platform.vc-item-machine.verifyingCredential:invocation[0]';
|
||||
removeVcMetaDataFromVcMachineContext: 'DISMISS';
|
||||
requestVcContext: 'DISMISS' | 'REFRESH' | 'STORE_ERROR' | 'xstate.init';
|
||||
resetIsMachineInKebabPopupState:
|
||||
| ''
|
||||
| 'ADD_WALLET_BINDING_ID'
|
||||
| 'CANCEL'
|
||||
| 'CLOSE_VC_MODAL'
|
||||
| 'DISMISS'
|
||||
| 'REFRESH'
|
||||
| 'REMOVE'
|
||||
| 'SHOW_ACTIVITY'
|
||||
| 'done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]'
|
||||
| 'xstate.stop';
|
||||
resetPrivateKey:
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
sendActivationStartEvent: 'CONFIRM';
|
||||
sendActivationSuccessEvent:
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
sendBackupEvent:
|
||||
| 'done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
|
||||
sendDownloadLimitExpire:
|
||||
| 'FAILED'
|
||||
| 'error.platform.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
|
||||
sendTelemetryEvents: 'STORE_RESPONSE';
|
||||
sendUserCancelledActivationFailedEndEvent: 'DISMISS';
|
||||
sendVcUpdated: 'PIN_CARD';
|
||||
sendVerificationError: 'STORE_RESPONSE';
|
||||
sendWalletBindingErrorEvent:
|
||||
| 'error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
sendWalletBindingSuccess: 'SHOW_BINDING_STATUS';
|
||||
setCommunicationDetails:
|
||||
| 'done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]';
|
||||
setContext: 'CREDENTIAL_DOWNLOADED' | 'GET_VC_RESPONSE';
|
||||
setDownloadInterval: 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
|
||||
setErrorAsVerificationError: 'error.platform.vc-item-machine.verifyingCredential:invocation[0]';
|
||||
setErrorAsWalletBindingError:
|
||||
| 'error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]'
|
||||
| 'error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
setMaxDownloadCount: 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
|
||||
setOTP: 'INPUT_OTP';
|
||||
setPinCard: 'PIN_CARD';
|
||||
setPrivateKey: 'done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]';
|
||||
setPublicKey: 'done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]';
|
||||
setThumbprintForWalletBindingId:
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
setVcKey: 'REMOVE';
|
||||
setVcMetadata: 'UPDATE_VC_METADATA';
|
||||
setWalletBindingResponse: 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]';
|
||||
storeContext:
|
||||
| 'done.invoke.vc-item-machine.verifyingCredential:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
storeVcInContext:
|
||||
| 'STORE_RESPONSE'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
unSetBindingTransactionId: 'DISMISS';
|
||||
unSetError:
|
||||
| 'CANCEL'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]';
|
||||
unSetOTP:
|
||||
| 'DISMISS'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]';
|
||||
"addVcToInProgressDownloads": "GET_VC_RESPONSE";
|
||||
"closeViewVcModal": "CLOSE_VC_MODAL" | "STORE_RESPONSE";
|
||||
"incrementDownloadCounter": "POLL" | "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
|
||||
"logDownloaded": "STORE_RESPONSE";
|
||||
"logRemovedVc": "STORE_RESPONSE" | "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]";
|
||||
"logWalletBindingFailure": "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"logWalletBindingSuccess": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"refreshAllVcs": "STORE_RESPONSE" | "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]";
|
||||
"removeVcFromInProgressDownloads": "STORE_RESPONSE";
|
||||
"removeVcItem": "CONFIRM";
|
||||
"removeVcMetaDataFromStorage": "STORE_ERROR" | "error.platform.vc-item-machine.verifyingCredential:invocation[0]";
|
||||
"removeVcMetaDataFromVcMachineContext": "DISMISS";
|
||||
"requestVcContext": "DISMISS" | "REFRESH" | "STORE_ERROR" | "xstate.init";
|
||||
"resetIsMachineInKebabPopupState": "" | "ADD_WALLET_BINDING_ID" | "CANCEL" | "CLOSE_VC_MODAL" | "DISMISS" | "REFRESH" | "REMOVE" | "SHOW_ACTIVITY" | "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "xstate.stop";
|
||||
"resetPrivateKey": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"sendActivationStartEvent": "CONFIRM";
|
||||
"sendActivationSuccessEvent": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"sendBackupEvent": "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]";
|
||||
"sendDownloadLimitExpire": "FAILED" | "error.platform.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]";
|
||||
"sendTelemetryEvents": "STORE_RESPONSE";
|
||||
"sendUserCancelledActivationFailedEndEvent": "DISMISS";
|
||||
"sendVcUpdated": "PIN_CARD";
|
||||
"sendVerificationError": "STORE_RESPONSE";
|
||||
"sendWalletBindingErrorEvent": "error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"sendWalletBindingSuccess": "SHOW_BINDING_STATUS";
|
||||
"setCommunicationDetails": "done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]";
|
||||
"setContext": "CREDENTIAL_DOWNLOADED" | "GET_VC_RESPONSE";
|
||||
"setDownloadInterval": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
|
||||
"setErrorAsVerificationError": "error.platform.vc-item-machine.verifyingCredential:invocation[0]";
|
||||
"setErrorAsWalletBindingError": "error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"setMaxDownloadCount": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
|
||||
"setOTP": "INPUT_OTP";
|
||||
"setPinCard": "PIN_CARD";
|
||||
"setPrivateKey": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
|
||||
"setPublicKey": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
|
||||
"setThumbprintForWalletBindingId": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"setVcKey": "REMOVE";
|
||||
"setVcMetadata": "UPDATE_VC_METADATA";
|
||||
"setWalletBindingResponse": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
|
||||
"storeContext": "done.invoke.vc-item-machine.verifyingCredential:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"storeVcInContext": "STORE_RESPONSE" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"unSetBindingTransactionId": "DISMISS";
|
||||
"unSetError": "CANCEL" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
|
||||
"unSetOTP": "DISMISS" | "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
hasCredential: 'GET_VC_RESPONSE';
|
||||
isCustomSecureKeystore:
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]';
|
||||
isDownloadAllowed: 'POLL';
|
||||
isSignedIn:
|
||||
| 'done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]'
|
||||
| 'done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
|
||||
"hasCredential": "GET_VC_RESPONSE";
|
||||
"isCustomSecureKeystore": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
|
||||
"isDownloadAllowed": "POLL";
|
||||
"isSignedIn": "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
addWalletBindingId: 'done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]';
|
||||
checkDownloadExpiryLimit:
|
||||
| 'POLL'
|
||||
| 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
|
||||
checkStatus: 'done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
|
||||
downloadCredential: 'DOWNLOAD_READY';
|
||||
generateKeyPair: 'INPUT_OTP';
|
||||
isUserSignedAlready: 'STORE_RESPONSE';
|
||||
loadDownloadLimitConfig: 'GET_VC_RESPONSE' | 'STORE_ERROR';
|
||||
requestBindingOTP: 'CONFIRM' | 'RESEND_OTP';
|
||||
updatePrivateKey: 'done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]';
|
||||
verifyCredential: 'CREDENTIAL_DOWNLOADED';
|
||||
};
|
||||
matchesStates:
|
||||
| 'idle'
|
||||
| 'kebabPopUp'
|
||||
| 'kebabPopUp.idle'
|
||||
| 'kebabPopUp.pinCard'
|
||||
| 'kebabPopUp.removeWallet'
|
||||
| 'kebabPopUp.removingVc'
|
||||
| 'kebabPopUp.showActivities'
|
||||
| 'kebabPopUp.triggerAutoBackup'
|
||||
| 'loadVc'
|
||||
| 'loadVc.loadVcFromContext'
|
||||
| 'loadVc.loadVcFromServer'
|
||||
| 'loadVc.loadVcFromServer.checkingStatus'
|
||||
| 'loadVc.loadVcFromServer.downloadingCredential'
|
||||
| 'loadVc.loadVcFromServer.loadDownloadLimitConfig'
|
||||
| 'loadVc.loadVcFromServer.savingFailed'
|
||||
| 'loadVc.loadVcFromServer.savingFailed.idle'
|
||||
| 'loadVc.loadVcFromServer.savingFailed.viewingVc'
|
||||
| 'loadVc.loadVcFromServer.verifyingDownloadLimitExpiry'
|
||||
| 'verifyingCredential'
|
||||
| 'verifyingCredential.handleVCVerificationFailure'
|
||||
| 'verifyingCredential.idle'
|
||||
| 'verifyingCredential.triggerAutoBackupForVcDownload'
|
||||
| 'walletBinding'
|
||||
| 'walletBinding.acceptingBindingOTP'
|
||||
| 'walletBinding.acceptingBindingOTP.idle'
|
||||
| 'walletBinding.acceptingBindingOTP.resendOTP'
|
||||
| 'walletBinding.addKeyPair'
|
||||
| 'walletBinding.addingWalletBindingId'
|
||||
| 'walletBinding.requestingBindingOTP'
|
||||
| 'walletBinding.showBindingWarning'
|
||||
| 'walletBinding.showingWalletBindingError'
|
||||
| 'walletBinding.updatingContextVariables'
|
||||
| 'walletBinding.updatingPrivateKey'
|
||||
| {
|
||||
kebabPopUp?:
|
||||
| 'idle'
|
||||
| 'pinCard'
|
||||
| 'removeWallet'
|
||||
| 'removingVc'
|
||||
| 'showActivities'
|
||||
| 'triggerAutoBackup';
|
||||
loadVc?:
|
||||
| 'loadVcFromContext'
|
||||
| 'loadVcFromServer'
|
||||
| {
|
||||
loadVcFromServer?:
|
||||
| 'checkingStatus'
|
||||
| 'downloadingCredential'
|
||||
| 'loadDownloadLimitConfig'
|
||||
| 'savingFailed'
|
||||
| 'verifyingDownloadLimitExpiry'
|
||||
| {savingFailed?: 'idle' | 'viewingVc'};
|
||||
};
|
||||
verifyingCredential?:
|
||||
| 'handleVCVerificationFailure'
|
||||
| 'idle'
|
||||
| 'triggerAutoBackupForVcDownload';
|
||||
walletBinding?:
|
||||
| 'acceptingBindingOTP'
|
||||
| 'addKeyPair'
|
||||
| 'addingWalletBindingId'
|
||||
| 'requestingBindingOTP'
|
||||
| 'showBindingWarning'
|
||||
| 'showingWalletBindingError'
|
||||
| 'updatingContextVariables'
|
||||
| 'updatingPrivateKey'
|
||||
| {acceptingBindingOTP?: 'idle' | 'resendOTP'};
|
||||
"addWalletBindingId": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
|
||||
"checkDownloadExpiryLimit": "POLL" | "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
|
||||
"checkStatus": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]";
|
||||
"downloadCredential": "DOWNLOAD_READY";
|
||||
"generateKeyPair": "INPUT_OTP";
|
||||
"isUserSignedAlready": "STORE_RESPONSE";
|
||||
"loadDownloadLimitConfig": "GET_VC_RESPONSE" | "STORE_ERROR";
|
||||
"requestBindingOTP": "CONFIRM" | "RESEND_OTP";
|
||||
"updatePrivateKey": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
|
||||
"verifyCredential": "CREDENTIAL_DOWNLOADED";
|
||||
};
|
||||
matchesStates: "idle" | "kebabPopUp" | "kebabPopUp.idle" | "kebabPopUp.pinCard" | "kebabPopUp.removeWallet" | "kebabPopUp.removingVc" | "kebabPopUp.showActivities" | "kebabPopUp.triggerAutoBackup" | "loadVc" | "loadVc.loadVcFromContext" | "loadVc.loadVcFromServer" | "loadVc.loadVcFromServer.checkingStatus" | "loadVc.loadVcFromServer.downloadingCredential" | "loadVc.loadVcFromServer.loadDownloadLimitConfig" | "loadVc.loadVcFromServer.savingFailed" | "loadVc.loadVcFromServer.savingFailed.idle" | "loadVc.loadVcFromServer.savingFailed.viewingVc" | "loadVc.loadVcFromServer.verifyingDownloadLimitExpiry" | "verifyingCredential" | "verifyingCredential.handleVCVerificationFailure" | "verifyingCredential.idle" | "verifyingCredential.triggerAutoBackupForVcDownload" | "walletBinding" | "walletBinding.acceptingBindingOTP" | "walletBinding.acceptingBindingOTP.idle" | "walletBinding.acceptingBindingOTP.resendOTP" | "walletBinding.addKeyPair" | "walletBinding.addingWalletBindingId" | "walletBinding.requestingBindingOTP" | "walletBinding.showBindingWarning" | "walletBinding.showingWalletBindingError" | "walletBinding.updatingContextVariables" | "walletBinding.updatingPrivateKey" | { "kebabPopUp"?: "idle" | "pinCard" | "removeWallet" | "removingVc" | "showActivities" | "triggerAutoBackup";
|
||||
"loadVc"?: "loadVcFromContext" | "loadVcFromServer" | { "loadVcFromServer"?: "checkingStatus" | "downloadingCredential" | "loadDownloadLimitConfig" | "savingFailed" | "verifyingDownloadLimitExpiry" | { "savingFailed"?: "idle" | "viewingVc"; }; };
|
||||
"verifyingCredential"?: "handleVCVerificationFailure" | "idle" | "triggerAutoBackupForVcDownload";
|
||||
"walletBinding"?: "acceptingBindingOTP" | "addKeyPair" | "addingWalletBindingId" | "requestingBindingOTP" | "showBindingWarning" | "showingWalletBindingError" | "updatingContextVariables" | "updatingPrivateKey" | { "acceptingBindingOTP"?: "idle" | "resendOTP"; }; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -1,106 +1,58 @@
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]': {
|
||||
type: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
"done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]": { type: "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
isUserSignedAlready: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
"isUserSignedAlready": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions:
|
||||
| 'addVcToInProgressDownloads'
|
||||
| 'getVcItemResponse'
|
||||
| 'loadMyVcs'
|
||||
| 'loadReceivedVcs'
|
||||
| 'logTamperedVCsremoved'
|
||||
| 'prependToMyVcsMetadata'
|
||||
| 'removeDownloadFailedVcsFromStorage'
|
||||
| 'removeDownloadingFailedVcsFromMyVcs'
|
||||
| 'removeVcFromInProgressDownlods'
|
||||
| 'removeVcFromMyVcsMetadata'
|
||||
| 'resetDownloadFailedVcs'
|
||||
| 'resetInProgressVcsDownloaded'
|
||||
| 'resetTamperedVcs'
|
||||
| 'resetVerificationErrorMessage'
|
||||
| 'resetWalletBindingSuccess'
|
||||
| 'sendBackupEvent'
|
||||
| 'setDownloadedVc'
|
||||
| 'setDownloadingFailedVcs'
|
||||
| 'setMyVcs'
|
||||
| 'setReceivedVcs'
|
||||
| 'setUpdatedVcMetadatas'
|
||||
| 'setVerificationErrorMessage'
|
||||
| 'setWalletBindingSuccess'
|
||||
| 'updateMyVcsMetadata';
|
||||
actions: "addVcToInProgressDownloads" | "getVcItemResponse" | "loadMyVcs" | "loadReceivedVcs" | "logTamperedVCsremoved" | "prependToMyVcsMetadata" | "removeDownloadFailedVcsFromStorage" | "removeDownloadingFailedVcsFromMyVcs" | "removeVcFromInProgressDownlods" | "removeVcFromMyVcsMetadata" | "resetDownloadFailedVcs" | "resetInProgressVcsDownloaded" | "resetTamperedVcs" | "resetVerificationErrorMessage" | "resetWalletBindingSuccess" | "sendBackupEvent" | "setDownloadedVc" | "setDownloadingFailedVcs" | "setMyVcs" | "setReceivedVcs" | "setUpdatedVcMetadatas" | "setVerificationErrorMessage" | "setWalletBindingSuccess" | "updateMyVcsMetadata";
|
||||
delays: never;
|
||||
guards: 'isAnyVcTampered' | 'isSignedIn';
|
||||
services: 'isUserSignedAlready';
|
||||
guards: "isAnyVcTampered" | "isSignedIn";
|
||||
services: "isUserSignedAlready";
|
||||
};
|
||||
eventsCausingActions: {
|
||||
addVcToInProgressDownloads: 'ADD_VC_TO_IN_PROGRESS_DOWNLOADS';
|
||||
getVcItemResponse: 'GET_VC_ITEM';
|
||||
loadMyVcs:
|
||||
| 'REFRESH_MY_VCS'
|
||||
| 'REFRESH_RECEIVED_VCS'
|
||||
| 'STORE_RESPONSE'
|
||||
| 'VERIFY_VC_FAILED'
|
||||
| 'xstate.init';
|
||||
loadReceivedVcs: 'REFRESH_RECEIVED_VCS' | 'STORE_RESPONSE';
|
||||
logTamperedVCsremoved: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
prependToMyVcsMetadata: 'VC_ADDED';
|
||||
removeDownloadFailedVcsFromStorage: 'DELETE_VC';
|
||||
removeDownloadingFailedVcsFromMyVcs: 'STORE_RESPONSE';
|
||||
removeVcFromInProgressDownlods:
|
||||
| 'DOWNLOAD_LIMIT_EXPIRED'
|
||||
| 'REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS'
|
||||
| 'VERIFY_VC_FAILED';
|
||||
removeVcFromMyVcsMetadata: 'REMOVE_VC_FROM_CONTEXT';
|
||||
resetDownloadFailedVcs: 'STORE_RESPONSE';
|
||||
resetInProgressVcsDownloaded: 'RESET_IN_PROGRESS_VCS_DOWNLOADED';
|
||||
resetTamperedVcs: 'REMOVE_TAMPERED_VCS';
|
||||
resetVerificationErrorMessage: 'RESET_VERIFY_ERROR';
|
||||
resetWalletBindingSuccess: 'RESET_WALLET_BINDING_SUCCESS';
|
||||
sendBackupEvent: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
setDownloadedVc: 'VC_DOWNLOADED';
|
||||
setDownloadingFailedVcs: 'DOWNLOAD_LIMIT_EXPIRED';
|
||||
setMyVcs: 'STORE_RESPONSE';
|
||||
setReceivedVcs: 'STORE_RESPONSE';
|
||||
setUpdatedVcMetadatas: 'VC_METADATA_UPDATED';
|
||||
setVerificationErrorMessage: 'VERIFY_VC_FAILED';
|
||||
setWalletBindingSuccess: 'WALLET_BINDING_SUCCESS';
|
||||
updateMyVcsMetadata: 'VC_METADATA_UPDATED';
|
||||
"addVcToInProgressDownloads": "ADD_VC_TO_IN_PROGRESS_DOWNLOADS";
|
||||
"getVcItemResponse": "GET_VC_ITEM";
|
||||
"loadMyVcs": "DOWNLOAD_LIMIT_EXPIRED" | "REFRESH_MY_VCS" | "REFRESH_RECEIVED_VCS" | "STORE_RESPONSE" | "VERIFY_VC_FAILED" | "xstate.init";
|
||||
"loadReceivedVcs": "REFRESH_RECEIVED_VCS" | "STORE_RESPONSE";
|
||||
"logTamperedVCsremoved": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
"prependToMyVcsMetadata": "VC_ADDED";
|
||||
"removeDownloadFailedVcsFromStorage": "DELETE_VC";
|
||||
"removeDownloadingFailedVcsFromMyVcs": "STORE_RESPONSE";
|
||||
"removeVcFromInProgressDownlods": "DOWNLOAD_LIMIT_EXPIRED" | "REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS" | "VERIFY_VC_FAILED";
|
||||
"removeVcFromMyVcsMetadata": "REMOVE_VC_FROM_CONTEXT";
|
||||
"resetDownloadFailedVcs": "STORE_RESPONSE";
|
||||
"resetInProgressVcsDownloaded": "RESET_IN_PROGRESS_VCS_DOWNLOADED";
|
||||
"resetTamperedVcs": "REMOVE_TAMPERED_VCS";
|
||||
"resetVerificationErrorMessage": "RESET_VERIFY_ERROR";
|
||||
"resetWalletBindingSuccess": "RESET_WALLET_BINDING_SUCCESS";
|
||||
"sendBackupEvent": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
"setDownloadedVc": "VC_DOWNLOADED";
|
||||
"setDownloadingFailedVcs": "DOWNLOAD_LIMIT_EXPIRED";
|
||||
"setMyVcs": "STORE_RESPONSE";
|
||||
"setReceivedVcs": "STORE_RESPONSE";
|
||||
"setUpdatedVcMetadatas": "VC_METADATA_UPDATED";
|
||||
"setVerificationErrorMessage": "VERIFY_VC_FAILED";
|
||||
"setWalletBindingSuccess": "WALLET_BINDING_SUCCESS";
|
||||
"updateMyVcsMetadata": "VC_METADATA_UPDATED";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isAnyVcTampered: 'SHOW_TAMPERED_POPUP';
|
||||
isSignedIn: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
|
||||
"isAnyVcTampered": "SHOW_TAMPERED_POPUP";
|
||||
"isSignedIn": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
isUserSignedAlready: 'REMOVE_TAMPERED_VCS';
|
||||
};
|
||||
matchesStates:
|
||||
| 'deletingFailedVcs'
|
||||
| 'ready'
|
||||
| 'ready.myVcs'
|
||||
| 'ready.receivedVcs'
|
||||
| 'ready.showTamperedPopup'
|
||||
| 'ready.tamperedVCs'
|
||||
| 'ready.tamperedVCs.idle'
|
||||
| 'ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion'
|
||||
| {
|
||||
ready?:
|
||||
| 'myVcs'
|
||||
| 'receivedVcs'
|
||||
| 'showTamperedPopup'
|
||||
| 'tamperedVCs'
|
||||
| {tamperedVCs?: 'idle' | 'triggerAutoBackupForTamperedVcDeletion'};
|
||||
"isUserSignedAlready": "REMOVE_TAMPERED_VCS";
|
||||
};
|
||||
matchesStates: "deletingFailedVcs" | "ready" | "ready.myVcs" | "ready.receivedVcs" | "ready.showTamperedPopup" | "ready.tamperedVCs" | "ready.tamperedVCs.idle" | "ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion" | { "ready"?: "myVcs" | "receivedVcs" | "showTamperedPopup" | "tamperedVCs" | { "tamperedVCs"?: "idle" | "triggerAutoBackupForTamperedVcDeletion"; }; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
327
machines/bleShare/scan/scanActions.ts
Normal file
327
machines/bleShare/scan/scanActions.ts
Normal file
@@ -0,0 +1,327 @@
|
||||
import { Linking } from "react-native";
|
||||
import { getDeviceNameSync } from "react-native-device-info";
|
||||
import { assign, spawn, send, DoneInvokeEvent } from "xstate";
|
||||
import { VCShareFlowType } from "../../../shared/Utils";
|
||||
import { VCMetadata } from "../../../shared/VCMetadata";
|
||||
import { logState } from "../../../shared/commonUtil";
|
||||
import { SHOW_FACE_AUTH_CONSENT_SHARE_FLOW, isAndroid, DEFAULT_QR_HEADER, MY_VCS_STORE_KEY, MY_LOGIN_STORE_KEY } from "../../../shared/constants";
|
||||
import { getIdType } from "../../../shared/openId4VCI/Utils";
|
||||
import { TelemetryConstants } from "../../../shared/telemetry/TelemetryConstants";
|
||||
import { sendImpressionEvent, getImpressionEventData, sendEndEvent, getEndEventData, sendErrorEvent, getErrorEventData, sendStartEvent, getStartEventData } from "../../../shared/telemetry/TelemetryUtils";
|
||||
import { createQrLoginMachine } from "../../QrLogin/QrLoginMachine";
|
||||
import { VcMetaEvents } from "../../VerifiableCredential/VCMetaMachine/VCMetaEvents";
|
||||
import { ActivityLogEvents } from "../../activityLog";
|
||||
import { StoreEvents } from "../../store";
|
||||
import tuvali from '@mosip/tuvali';
|
||||
import BluetoothStateManager from 'react-native-bluetooth-state-manager';
|
||||
|
||||
const {wallet, EventTypes, VerificationStatus} = tuvali;
|
||||
export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
|
||||
return{
|
||||
setChildRef: assign({
|
||||
QrLoginRef: (context:any) => {
|
||||
const service = spawn(
|
||||
createQrLoginMachine(context.serviceRefs),
|
||||
QR_LOGIN_REF_ID,
|
||||
);
|
||||
service.subscribe(logState);
|
||||
return service;
|
||||
},
|
||||
}),
|
||||
|
||||
updateShowFaceAuthConsent: model.assign({
|
||||
showFaceAuthConsent: (_, event) => {
|
||||
return event.response || event.response === null;
|
||||
},
|
||||
}),
|
||||
|
||||
|
||||
setShowFaceAuthConsent: model.assign({
|
||||
showFaceAuthConsent: (_, event) => {
|
||||
return !event.isDoNotAskAgainChecked;
|
||||
},
|
||||
}),
|
||||
|
||||
getFaceAuthConsent: send(StoreEvents.GET(SHOW_FACE_AUTH_CONSENT_SHARE_FLOW), {
|
||||
to: (context:any) => context.serviceRefs.store,
|
||||
}),
|
||||
|
||||
storeShowFaceAuthConsent: send(
|
||||
(context, event) =>
|
||||
StoreEvents.SET(SHOW_FACE_AUTH_CONSENT_SHARE_FLOW, !event.isDoNotAskAgainChecked),
|
||||
{
|
||||
to: (context:any) => context.serviceRefs.store,
|
||||
},
|
||||
),
|
||||
|
||||
sendScanData: context =>
|
||||
context.QrLoginRef.send({
|
||||
type: 'GET',
|
||||
linkCode: context.linkCode,
|
||||
flowType: context.flowType,
|
||||
selectedVc: context.selectedVc,
|
||||
}),
|
||||
|
||||
openBluetoothSettings: () => {
|
||||
isAndroid()
|
||||
? BluetoothStateManager.openSettings().catch()
|
||||
: Linking.openURL('App-Prefs:Bluetooth');
|
||||
},
|
||||
|
||||
openAppPermission: () => Linking.openSettings(),
|
||||
|
||||
enableLocation: async () => {
|
||||
await Linking.sendIntent('android.settings.LOCATION_SOURCE_SETTINGS');
|
||||
},
|
||||
|
||||
setUri: model.assign({
|
||||
openId4VpUri: (_context, event) => event.params,
|
||||
}),
|
||||
|
||||
clearUri: assign({
|
||||
openId4VpUri: '',
|
||||
}),
|
||||
|
||||
setSenderInfo: assign({
|
||||
senderInfo: () => {
|
||||
return {name: 'Wallet', deviceName: 'Wallet', deviceId: ''};
|
||||
},
|
||||
}),
|
||||
|
||||
setReceiverInfo: assign({
|
||||
receiverInfo: () => {
|
||||
return {name: 'Verifier', deviceName: 'Verifier', deviceId: ''};
|
||||
},
|
||||
}),
|
||||
|
||||
setReadyForBluetoothStateCheck: model.assign({
|
||||
readyForBluetoothStateCheck: () => true,
|
||||
}),
|
||||
|
||||
setBleError: assign({
|
||||
bleError: (_context, event) => event.bleError,
|
||||
}),
|
||||
|
||||
setSelectedVc: assign({
|
||||
selectedVc: (_context, event) => event.vc,
|
||||
}),
|
||||
|
||||
resetSelectedVc: assign({
|
||||
selectedVc: {},
|
||||
}),
|
||||
|
||||
resetShowQuickShareSuccessBanner: assign({
|
||||
showQuickShareSuccessBanner: false,
|
||||
}),
|
||||
|
||||
setShowQuickShareSuccessBanner: assign({
|
||||
showQuickShareSuccessBanner: true,
|
||||
}),
|
||||
|
||||
setFlowType: assign({
|
||||
flowType: (_context, event) => event.flowType,
|
||||
}),
|
||||
|
||||
resetFlowType: assign({
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
}),
|
||||
|
||||
registerLoggers: assign({
|
||||
loggers: () => {
|
||||
if (__DEV__) {
|
||||
return [
|
||||
wallet.handleDataEvents(event => {
|
||||
console.log(
|
||||
getDeviceNameSync(),
|
||||
'<Sender.Event>',
|
||||
JSON.stringify(event).slice(0, 100),
|
||||
);
|
||||
}),
|
||||
];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
removeLoggers: assign({
|
||||
loggers: ({loggers}) => {
|
||||
loggers?.forEach(logger => logger.remove());
|
||||
return [];
|
||||
},
|
||||
}),
|
||||
|
||||
setShareLogTypeUnverified: model.assign({
|
||||
shareLogType: 'VC_SHARED',
|
||||
}),
|
||||
|
||||
setShareLogTypeVerified: model.assign({
|
||||
shareLogType: 'PRESENCE_VERIFIED_AND_VC_SHARED',
|
||||
}),
|
||||
|
||||
updateFaceCaptureBannerStatus: model.assign({
|
||||
showFaceCaptureSuccessBanner: true,
|
||||
}),
|
||||
|
||||
resetFaceCaptureBannerStatus: model.assign({
|
||||
showFaceCaptureSuccessBanner: false,
|
||||
}),
|
||||
|
||||
logShared: send(
|
||||
(context:any) => {
|
||||
const vcMetadata = context.selectedVc?.vcMetadata;
|
||||
return ActivityLogEvents.LOG_ACTIVITY({
|
||||
_vcKey: VCMetadata.fromVC(vcMetadata).getVcKey(),
|
||||
type: context.shareLogType
|
||||
? context.shareLogType
|
||||
: 'VC_SHARED_WITH_VERIFICATION_CONSENT',
|
||||
id: vcMetadata.id,
|
||||
idType: getIdType(vcMetadata.issuer),
|
||||
timestamp: Date.now(),
|
||||
deviceName:
|
||||
context.receiverInfo.name || context.receiverInfo.deviceName,
|
||||
vcLabel: vcMetadata.id,
|
||||
});
|
||||
},
|
||||
{to: context => context.serviceRefs.activityLog},
|
||||
),
|
||||
|
||||
logFailedVerification: send(
|
||||
context =>
|
||||
ActivityLogEvents.LOG_ACTIVITY({
|
||||
_vcKey: VCMetadata.fromVC(context.selectedVc).getVcKey(),
|
||||
type: 'PRESENCE_VERIFICATION_FAILED',
|
||||
timestamp: Date.now(),
|
||||
idType: getIdType(context.selectedVc.vcMetadata.issuer),
|
||||
id: context.selectedVc.vcMetadata.id,
|
||||
deviceName:
|
||||
context.receiverInfo.name || context.receiverInfo.deviceName,
|
||||
vcLabel: context.selectedVc.vcMetadata.id,
|
||||
}),
|
||||
{to: context => context.serviceRefs.activityLog},
|
||||
),
|
||||
|
||||
setLinkCode: assign({
|
||||
linkCode: (_, event) =>
|
||||
new URL(event.params).searchParams.get('linkCode'),
|
||||
}),
|
||||
setQuickShareData: assign({
|
||||
quickShareData: (_, event) =>
|
||||
JSON.parse(decodeData(event.params.split(DEFAULT_QR_HEADER)[1])),
|
||||
}),
|
||||
loadMetaDataToMemory: send(
|
||||
(context:any) => {
|
||||
let metadata = VCMetadata.fromVC(context.quickShareData?.meta);
|
||||
return StoreEvents.PREPEND(MY_VCS_STORE_KEY, metadata);
|
||||
},
|
||||
{to: context => context.serviceRefs.store},
|
||||
),
|
||||
loadVCDataToMemory: send(
|
||||
(context:any) => {
|
||||
let metadata = VCMetadata.fromVC(context.quickShareData?.meta);
|
||||
|
||||
let verifiableCredential = metadata.isFromOpenId4VCI()
|
||||
? {credential: context.quickShareData?.verifiableCredential}
|
||||
: context.quickShareData?.verifiableCredential;
|
||||
|
||||
return StoreEvents.SET(metadata.getVcKey(), {
|
||||
verifiableCredential: verifiableCredential,
|
||||
});
|
||||
},
|
||||
{to: context => context.serviceRefs.store},
|
||||
),
|
||||
refreshVCs: send(VcMetaEvents.REFRESH_MY_VCS, {
|
||||
to: context => context.serviceRefs.vcMeta,
|
||||
}),
|
||||
storeLoginItem: send(
|
||||
(_context, event) => {
|
||||
return StoreEvents.PREPEND(
|
||||
MY_LOGIN_STORE_KEY,
|
||||
(event as DoneInvokeEvent<string>).data,
|
||||
);
|
||||
},
|
||||
{to: (context:any) => context.serviceRefs.store},
|
||||
),
|
||||
|
||||
storingActivityLog: send(
|
||||
(_, event) =>
|
||||
ActivityLogEvents.LOG_ACTIVITY({
|
||||
_vcKey: '',
|
||||
id: event.response.selectedVc.vcMetadata.id,
|
||||
idType: getIdType(event.response.selectedVc.vcMetadata.issuer),
|
||||
type: 'QRLOGIN_SUCCESFULL',
|
||||
timestamp: Date.now(),
|
||||
deviceName: '',
|
||||
vcLabel: String(event.response.selectedVc.vcMetadata.id),
|
||||
}),
|
||||
{
|
||||
to: (context:any) => context.serviceRefs.activityLog,
|
||||
},
|
||||
),
|
||||
|
||||
sendVcShareSuccessEvent: () => {
|
||||
sendImpressionEvent(
|
||||
getImpressionEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.Screens.vcShareSuccessPage,
|
||||
),
|
||||
);
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.success,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendBLEConnectionErrorEvent: (_context, event) => {
|
||||
sendErrorEvent(
|
||||
getErrorEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
event.bleError.code,
|
||||
event.bleError.message,
|
||||
),
|
||||
);
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.failure,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendVcSharingStartEvent: () => {
|
||||
sendStartEvent(
|
||||
getStartEventData(TelemetryConstants.FlowType.senderVcShare),
|
||||
);
|
||||
sendImpressionEvent(
|
||||
getImpressionEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.Screens.scanScreen,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendVCShareFlowCancelEndEvent: () => {
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.cancel,
|
||||
{comment: 'User cancelled VC share'},
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendVCShareFlowTimeoutEndEvent: () => {
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.failure,
|
||||
{comment: 'VC sharing timeout'},
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
45
machines/bleShare/scan/scanGuards.ts
Normal file
45
machines/bleShare/scan/scanGuards.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { VCShareFlowType } from "../../../shared/Utils";
|
||||
import { androidVersion, isAndroid, isIOS } from "../../../shared/constants";
|
||||
|
||||
export const ScanGuards = () => {
|
||||
return {
|
||||
showFaceAuthConsentScreen: context => {
|
||||
return context.showFaceAuthConsent;
|
||||
},
|
||||
|
||||
// sample: 'OPENID4VP://connect:?name=OVPMOSIP&key=69dc92a2cc91f02258aa8094d6e2b62877f5b6498924fbaedaaa46af30abb364'
|
||||
isOpenIdQr: (_context, event) =>
|
||||
event.params.startsWith('OPENID4VP://'),
|
||||
// sample: 'INJIQUICKSHARE://NAKDFK:DB:JAHDIHAIDJXKABDAJDHUHW'
|
||||
isQuickShare: (_context, event) =>
|
||||
// event.params.startsWith(DEFAULT_QR_HEADER),
|
||||
// toggling the feature for now
|
||||
false,
|
||||
isQrLogin: (context, event) => {
|
||||
try {
|
||||
let linkCode = new URL(event.params);
|
||||
// sample: 'inji://landing-page-name?linkCode=sTjp0XVH3t3dGCU&linkExpireDateTime=2023-11-09T06:56:18.482Z'
|
||||
return linkCode.searchParams.get('linkCode') !== null;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
uptoAndroid11: () => isAndroid() && androidVersion < 31,
|
||||
|
||||
isIOS: () => isIOS(),
|
||||
|
||||
isMinimumStorageRequiredForAuditEntryReached: (_context, event) =>
|
||||
Boolean(event.data),
|
||||
|
||||
isFlowTypeMiniViewShareWithSelfie: context =>
|
||||
context.flowType === VCShareFlowType.MINI_VIEW_SHARE_WITH_SELFIE,
|
||||
|
||||
isFlowTypeMiniViewShare: context =>
|
||||
context.flowType === VCShareFlowType.MINI_VIEW_SHARE,
|
||||
|
||||
isFlowTypeSimpleShare: context =>
|
||||
context.flowType === VCShareFlowType.SIMPLE_SHARE,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,141 +1,23 @@
|
||||
/* eslint-disable sonarjs/no-duplicate-string */
|
||||
import tuvali from '@mosip/tuvali';
|
||||
import BluetoothStateManager from 'react-native-bluetooth-state-manager';
|
||||
import {
|
||||
ActorRefFrom,
|
||||
assign,
|
||||
DoneInvokeEvent,
|
||||
EventFrom,
|
||||
send,
|
||||
spawn,
|
||||
StateFrom,
|
||||
StateFrom
|
||||
} from 'xstate';
|
||||
import {createModel} from 'xstate/lib/model';
|
||||
import {EmitterSubscription, Linking} from 'react-native';
|
||||
import {DeviceInfo} from '../../../components/DeviceInfoList';
|
||||
import {getDeviceNameSync, isLocationEnabled} from 'react-native-device-info';
|
||||
import {VC} from '../../VerifiableCredential/VCMetaMachine/vc';
|
||||
import { AppServices } from '../../../shared/GlobalContext';
|
||||
import {ActivityLogEvents, ActivityLogType} from '../../activityLog';
|
||||
import {
|
||||
androidVersion,
|
||||
DEFAULT_QR_HEADER,
|
||||
FACE_AUTH_CONSENT,
|
||||
isAndroid,
|
||||
isIOS,
|
||||
MY_LOGIN_STORE_KEY,
|
||||
MY_VCS_STORE_KEY,
|
||||
} from '../../../shared/constants';
|
||||
import {subscribe} from '../../../shared/openIdBLE/walletEventHandler';
|
||||
import {
|
||||
check,
|
||||
checkMultiple,
|
||||
PERMISSIONS,
|
||||
PermissionStatus,
|
||||
requestMultiple,
|
||||
RESULTS,
|
||||
} from 'react-native-permissions';
|
||||
import {
|
||||
checkLocationPermissionStatus,
|
||||
requestLocationPermission,
|
||||
} from '../../../shared/location';
|
||||
import {CameraCapturedPicture} from 'expo-camera';
|
||||
import {createQrLoginMachine, qrLoginMachine} from '../../QrLoginMachine';
|
||||
import {StoreEvents} from '../../store';
|
||||
import {WalletDataEvent} from '@mosip/tuvali/lib/typescript/types/events';
|
||||
import {BLEError} from '../types';
|
||||
import Storage from '../../../shared/storage';
|
||||
import {VCMetadata} from '../../../shared/VCMetadata';
|
||||
import {
|
||||
getEndEventData,
|
||||
getErrorEventData,
|
||||
getImpressionEventData,
|
||||
getStartEventData,
|
||||
sendEndEvent,
|
||||
sendErrorEvent,
|
||||
sendImpressionEvent,
|
||||
sendStartEvent,
|
||||
} from '../../../shared/telemetry/TelemetryUtils';
|
||||
import { TelemetryConstants } from '../../../shared/telemetry/TelemetryConstants';
|
||||
import {logState} from '../../../shared/commonUtil';
|
||||
import {VCShareFlowType} from '../../../shared/Utils';
|
||||
import {getIdType} from '../../../shared/openId4VCI/Utils';
|
||||
import {VcMetaEvents} from '../../VerifiableCredential/VCMetaMachine/VCMetaMachine';
|
||||
import {
|
||||
getStartEventData,
|
||||
sendStartEvent
|
||||
} from '../../../shared/telemetry/TelemetryUtils';
|
||||
import { qrLoginMachine } from '../../QrLogin/QrLoginMachine';
|
||||
// @ts-ignore
|
||||
import {decodeData} from '@mosip/pixelpass';
|
||||
import { ScanActions } from './scanActions';
|
||||
import { ScanGuards } from './scanGuards';
|
||||
import { ScanModel } from './scanModel';
|
||||
import { ScanServices } from './scanServices';
|
||||
|
||||
const {wallet, EventTypes, VerificationStatus} = tuvali;
|
||||
|
||||
const model = createModel(
|
||||
{
|
||||
serviceRefs: {} as AppServices,
|
||||
senderInfo: {} as DeviceInfo,
|
||||
receiverInfo: {} as DeviceInfo,
|
||||
selectedVc: {} as VC,
|
||||
bleError: {} as BLEError,
|
||||
loggers: [] as EmitterSubscription[],
|
||||
vcName: '',
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
verificationImage: {} as CameraCapturedPicture,
|
||||
openId4VpUri: '',
|
||||
shareLogType: '' as ActivityLogType,
|
||||
QrLoginRef: {} as ActorRefFrom<typeof qrLoginMachine>,
|
||||
showQuickShareSuccessBanner: false,
|
||||
linkCode: '',
|
||||
quickShareData: {},
|
||||
showFaceAuthConsent: true as boolean,
|
||||
readyForBluetoothStateCheck: false,
|
||||
showFaceCaptureSuccessBanner: false,
|
||||
},
|
||||
{
|
||||
events: {
|
||||
SELECT_VC: (vc: VC, flowType: string) => ({vc, flowType}),
|
||||
SCAN: (params: string) => ({params}),
|
||||
ACCEPT_REQUEST: () => ({}),
|
||||
VERIFY_AND_ACCEPT_REQUEST: () => ({}),
|
||||
VC_ACCEPTED: () => ({}),
|
||||
VC_REJECTED: () => ({}),
|
||||
VC_SENT: () => ({}),
|
||||
CANCEL: () => ({}),
|
||||
CLOSE_BANNER: () => ({}),
|
||||
STAY_IN_PROGRESS: () => ({}),
|
||||
RETRY: () => ({}),
|
||||
DISMISS: () => ({}),
|
||||
DISMISS_QUICK_SHARE_BANNER: () => ({}),
|
||||
GOTO_HISTORY: () => ({}),
|
||||
CONNECTED: () => ({}),
|
||||
DISCONNECT: () => ({}),
|
||||
BLE_ERROR: (bleError: BLEError) => ({bleError}),
|
||||
CONNECTION_DESTROYED: () => ({}),
|
||||
SCREEN_BLUR: () => ({}),
|
||||
SCREEN_FOCUS: () => ({}),
|
||||
BLUETOOTH_PERMISSION_ENABLED: () => ({}),
|
||||
BLUETOOTH_PERMISSION_DENIED: () => ({}),
|
||||
BLUETOOTH_STATE_ENABLED: () => ({}),
|
||||
BLUETOOTH_STATE_DISABLED: () => ({}),
|
||||
NEARBY_ENABLED: () => ({}),
|
||||
NEARBY_DISABLED: () => ({}),
|
||||
GOTO_SETTINGS: () => ({}),
|
||||
START_PERMISSION_CHECK: () => ({}),
|
||||
LOCATION_ENABLED: () => ({}),
|
||||
LOCATION_DISABLED: () => ({}),
|
||||
LOCATION_REQUEST: () => ({}),
|
||||
CHECK_FLOW_TYPE: () => ({}),
|
||||
UPDATE_VC_NAME: (vcName: string) => ({vcName}),
|
||||
STORE_RESPONSE: (response: any) => ({response}),
|
||||
APP_ACTIVE: () => ({}),
|
||||
FACE_VALID: () => ({}),
|
||||
FACE_INVALID: () => ({}),
|
||||
RETRY_VERIFICATION: () => ({}),
|
||||
RESET: () => ({}),
|
||||
FACE_VERIFICATION_CONSENT: (isConsentGiven: boolean) => ({
|
||||
isConsentGiven,
|
||||
}),
|
||||
ALLOWED: () => ({}),
|
||||
DENIED: () => ({}),
|
||||
},
|
||||
},
|
||||
);
|
||||
const model=ScanModel;
|
||||
const QR_LOGIN_REF_ID = 'QrLogin';
|
||||
export const ScanEvents = model.events;
|
||||
|
||||
@@ -167,6 +49,7 @@ export const scanMachine =
|
||||
actions: ['sendBLEConnectionErrorEvent', 'setBleError'],
|
||||
},
|
||||
RESET: {
|
||||
actions:['removeLoggers', 'resetFlowType', 'resetSelectedVc'],
|
||||
target: '.checkStorage',
|
||||
},
|
||||
DISMISS: {
|
||||
@@ -562,7 +445,7 @@ export const scanMachine =
|
||||
},
|
||||
{
|
||||
cond: 'isFlowTypeMiniViewShareWithSelfie',
|
||||
target: '.verifyingIdentity',
|
||||
target:'.checkFaceAuthConsentForMiniView' ,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -701,6 +584,16 @@ export const scanMachine =
|
||||
entry: ['resetFlowType', 'resetSelectedVc'],
|
||||
always: '#scan.disconnected',
|
||||
},
|
||||
checkFaceAuthConsentForMiniView: {
|
||||
always:[
|
||||
{
|
||||
cond: 'showFaceAuthConsentScreen',
|
||||
target: 'faceVerificationConsent'
|
||||
},
|
||||
{
|
||||
target: 'verifyingIdentity'
|
||||
}
|
||||
],},
|
||||
faceVerificationConsent: {
|
||||
on: {
|
||||
FACE_VERIFICATION_CONSENT: {
|
||||
@@ -710,9 +603,15 @@ export const scanMachine =
|
||||
],
|
||||
target: 'verifyingIdentity',
|
||||
},
|
||||
DISMISS: {
|
||||
target: '#scan.reviewing.selectingVc',
|
||||
DISMISS:[
|
||||
{
|
||||
cond: 'isFlowTypeMiniViewShareWithSelfie',
|
||||
target: '#scan.checkFaceAuthConsent',
|
||||
},
|
||||
{
|
||||
target: '#scan.reviewing.selectingVc',
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
verifyingIdentity: {
|
||||
@@ -860,534 +759,19 @@ export const scanMachine =
|
||||
},
|
||||
},
|
||||
{
|
||||
actions: {
|
||||
setChildRef: assign({
|
||||
QrLoginRef: context => {
|
||||
const service = spawn(
|
||||
createQrLoginMachine(context.serviceRefs),
|
||||
QR_LOGIN_REF_ID,
|
||||
);
|
||||
service.subscribe(logState);
|
||||
return service;
|
||||
},
|
||||
}),
|
||||
actions: ScanActions(model,QR_LOGIN_REF_ID),
|
||||
|
||||
updateShowFaceAuthConsent: model.assign({
|
||||
showFaceAuthConsent: (_, event) => {
|
||||
return event.response || event.response === null;
|
||||
},
|
||||
}),
|
||||
|
||||
setShowFaceAuthConsent: model.assign({
|
||||
showFaceAuthConsent: (_, event) => {
|
||||
return !event.isConsentGiven;
|
||||
},
|
||||
}),
|
||||
|
||||
getFaceAuthConsent: send(StoreEvents.GET(FACE_AUTH_CONSENT), {
|
||||
to: context => context.serviceRefs.store,
|
||||
}),
|
||||
|
||||
storeShowFaceAuthConsent: send(
|
||||
(context, event) =>
|
||||
StoreEvents.SET(FACE_AUTH_CONSENT, !event.isConsentGiven),
|
||||
{
|
||||
to: context => context.serviceRefs.store,
|
||||
},
|
||||
),
|
||||
|
||||
sendScanData: context =>
|
||||
context.QrLoginRef.send({
|
||||
type: 'GET',
|
||||
linkCode: context.linkCode,
|
||||
flowType: context.flowType,
|
||||
selectedVc: context.selectedVc,
|
||||
faceAuthConsentGiven: context.showFaceAuthConsent,
|
||||
}),
|
||||
|
||||
openBluetoothSettings: () => {
|
||||
isAndroid()
|
||||
? BluetoothStateManager.openSettings().catch()
|
||||
: Linking.openURL('App-Prefs:Bluetooth');
|
||||
},
|
||||
|
||||
openAppPermission: () => Linking.openSettings(),
|
||||
|
||||
enableLocation: async () => {
|
||||
await Linking.sendIntent('android.settings.LOCATION_SOURCE_SETTINGS');
|
||||
},
|
||||
|
||||
setUri: model.assign({
|
||||
openId4VpUri: (_context, event) => event.params,
|
||||
}),
|
||||
|
||||
clearUri: assign({
|
||||
openId4VpUri: '',
|
||||
}),
|
||||
|
||||
setSenderInfo: assign({
|
||||
senderInfo: () => {
|
||||
return {name: 'Wallet', deviceName: 'Wallet', deviceId: ''};
|
||||
},
|
||||
}),
|
||||
|
||||
setReceiverInfo: assign({
|
||||
receiverInfo: () => {
|
||||
return {name: 'Verifier', deviceName: 'Verifier', deviceId: ''};
|
||||
},
|
||||
}),
|
||||
|
||||
setReadyForBluetoothStateCheck: model.assign({
|
||||
readyForBluetoothStateCheck: () => true,
|
||||
}),
|
||||
|
||||
setBleError: assign({
|
||||
bleError: (_context, event) => event.bleError,
|
||||
}),
|
||||
|
||||
setSelectedVc: assign({
|
||||
selectedVc: (_context, event) => event.vc,
|
||||
}),
|
||||
|
||||
resetSelectedVc: assign({
|
||||
selectedVc: {},
|
||||
}),
|
||||
|
||||
resetShowQuickShareSuccessBanner: assign({
|
||||
showQuickShareSuccessBanner: false,
|
||||
}),
|
||||
|
||||
setShowQuickShareSuccessBanner: assign({
|
||||
showQuickShareSuccessBanner: true,
|
||||
}),
|
||||
|
||||
setFlowType: assign({
|
||||
flowType: (_context, event) => event.flowType,
|
||||
}),
|
||||
|
||||
resetFlowType: assign({
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
}),
|
||||
|
||||
registerLoggers: assign({
|
||||
loggers: () => {
|
||||
if (__DEV__) {
|
||||
return [
|
||||
wallet.handleDataEvents(event => {
|
||||
console.log(
|
||||
getDeviceNameSync(),
|
||||
'<Sender.Event>',
|
||||
JSON.stringify(event).slice(0, 100),
|
||||
);
|
||||
}),
|
||||
];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
removeLoggers: assign({
|
||||
loggers: ({loggers}) => {
|
||||
loggers?.forEach(logger => logger.remove());
|
||||
return [];
|
||||
},
|
||||
}),
|
||||
|
||||
setShareLogTypeUnverified: model.assign({
|
||||
shareLogType: 'VC_SHARED',
|
||||
}),
|
||||
|
||||
setShareLogTypeVerified: model.assign({
|
||||
shareLogType: 'PRESENCE_VERIFIED_AND_VC_SHARED',
|
||||
}),
|
||||
|
||||
updateFaceCaptureBannerStatus: model.assign({
|
||||
showFaceCaptureSuccessBanner: true,
|
||||
}),
|
||||
|
||||
resetFaceCaptureBannerStatus: model.assign({
|
||||
showFaceCaptureSuccessBanner: false,
|
||||
}),
|
||||
|
||||
logShared: send(
|
||||
context => {
|
||||
const vcMetadata = context.selectedVc?.vcMetadata;
|
||||
return ActivityLogEvents.LOG_ACTIVITY({
|
||||
_vcKey: VCMetadata.fromVC(vcMetadata).getVcKey(),
|
||||
type: context.shareLogType
|
||||
? context.shareLogType
|
||||
: 'VC_SHARED_WITH_VERIFICATION_CONSENT',
|
||||
id: vcMetadata.id,
|
||||
idType: getIdType(vcMetadata.issuer),
|
||||
timestamp: Date.now(),
|
||||
deviceName:
|
||||
context.receiverInfo.name || context.receiverInfo.deviceName,
|
||||
vcLabel: vcMetadata.id,
|
||||
});
|
||||
},
|
||||
{to: context => context.serviceRefs.activityLog},
|
||||
),
|
||||
|
||||
logFailedVerification: send(
|
||||
context =>
|
||||
ActivityLogEvents.LOG_ACTIVITY({
|
||||
_vcKey: VCMetadata.fromVC(context.selectedVc).getVcKey(),
|
||||
type: 'PRESENCE_VERIFICATION_FAILED',
|
||||
timestamp: Date.now(),
|
||||
idType: getIdType(context.selectedVc.vcMetadata.issuer),
|
||||
id: context.selectedVc.vcMetadata.id,
|
||||
deviceName:
|
||||
context.receiverInfo.name || context.receiverInfo.deviceName,
|
||||
vcLabel: context.selectedVc.vcMetadata.id,
|
||||
}),
|
||||
{to: context => context.serviceRefs.activityLog},
|
||||
),
|
||||
|
||||
setLinkCode: assign({
|
||||
linkCode: (_, event) =>
|
||||
new URL(event.params).searchParams.get('linkCode'),
|
||||
}),
|
||||
setQuickShareData: assign({
|
||||
quickShareData: (_, event) =>
|
||||
JSON.parse(decodeData(event.params.split(DEFAULT_QR_HEADER)[1])),
|
||||
}),
|
||||
loadMetaDataToMemory: send(
|
||||
context => {
|
||||
let metadata = VCMetadata.fromVC(context.quickShareData?.meta);
|
||||
return StoreEvents.PREPEND(MY_VCS_STORE_KEY, metadata);
|
||||
},
|
||||
{to: context => context.serviceRefs.store},
|
||||
),
|
||||
loadVCDataToMemory: send(
|
||||
context => {
|
||||
let metadata = VCMetadata.fromVC(context.quickShareData?.meta);
|
||||
|
||||
let verifiableCredential = metadata.isFromOpenId4VCI()
|
||||
? {credential: context.quickShareData?.verifiableCredential}
|
||||
: context.quickShareData?.verifiableCredential;
|
||||
|
||||
return StoreEvents.SET(metadata.getVcKey(), {
|
||||
verifiableCredential: verifiableCredential,
|
||||
});
|
||||
},
|
||||
{to: context => context.serviceRefs.store},
|
||||
),
|
||||
refreshVCs: send(VcMetaEvents.REFRESH_MY_VCS, {
|
||||
to: context => context.serviceRefs.vcMeta,
|
||||
}),
|
||||
storeLoginItem: send(
|
||||
(_context, event) => {
|
||||
return StoreEvents.PREPEND(
|
||||
MY_LOGIN_STORE_KEY,
|
||||
(event as DoneInvokeEvent<string>).data,
|
||||
);
|
||||
},
|
||||
{to: context => context.serviceRefs.store},
|
||||
),
|
||||
|
||||
storingActivityLog: send(
|
||||
(_, event) =>
|
||||
ActivityLogEvents.LOG_ACTIVITY({
|
||||
_vcKey: '',
|
||||
id: event.response.selectedVc.vcMetadata.id,
|
||||
idType: getIdType(event.response.selectedVc.vcMetadata.issuer),
|
||||
type: 'QRLOGIN_SUCCESFULL',
|
||||
timestamp: Date.now(),
|
||||
deviceName: '',
|
||||
vcLabel: String(event.response.selectedVc.vcMetadata.id),
|
||||
}),
|
||||
{
|
||||
to: context => context.serviceRefs.activityLog,
|
||||
},
|
||||
),
|
||||
|
||||
sendVcShareSuccessEvent: () => {
|
||||
sendImpressionEvent(
|
||||
getImpressionEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.Screens.vcShareSuccessPage,
|
||||
),
|
||||
);
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.success,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendBLEConnectionErrorEvent: (_context, event) => {
|
||||
sendErrorEvent(
|
||||
getErrorEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
event.bleError.code,
|
||||
event.bleError.message,
|
||||
),
|
||||
);
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.failure,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendVcSharingStartEvent: () => {
|
||||
sendStartEvent(
|
||||
getStartEventData(TelemetryConstants.FlowType.senderVcShare),
|
||||
);
|
||||
sendImpressionEvent(
|
||||
getImpressionEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.Screens.scanScreen,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendVCShareFlowCancelEndEvent: () => {
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.cancel,
|
||||
{comment: 'User cancelled VC share'},
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
sendVCShareFlowTimeoutEndEvent: () => {
|
||||
sendEndEvent(
|
||||
getEndEventData(
|
||||
TelemetryConstants.FlowType.senderVcShare,
|
||||
TelemetryConstants.EndEventStatus.failure,
|
||||
{comment: 'VC sharing timeout'},
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
services: {
|
||||
checkBluetoothPermission: () => async callback => {
|
||||
// wait a bit for animation to finish when app becomes active
|
||||
await new Promise(resolve => setTimeout(resolve, 250));
|
||||
try {
|
||||
// Passing Granted for android since permission status is always granted even if its denied.
|
||||
let response: PermissionStatus = RESULTS.GRANTED;
|
||||
|
||||
if (isIOS()) {
|
||||
response = await check(PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL);
|
||||
}
|
||||
|
||||
if (response === RESULTS.GRANTED) {
|
||||
callback(model.events.BLUETOOTH_PERMISSION_ENABLED());
|
||||
} else {
|
||||
callback(model.events.BLUETOOTH_PERMISSION_DENIED());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
checkBluetoothState: () => callback => {
|
||||
const subscription = BluetoothStateManager.onStateChange(state => {
|
||||
if (state === 'PoweredOn') {
|
||||
callback(model.events.BLUETOOTH_STATE_ENABLED());
|
||||
} else {
|
||||
callback(model.events.BLUETOOTH_STATE_DISABLED());
|
||||
}
|
||||
}, true);
|
||||
return () => subscription.remove();
|
||||
},
|
||||
|
||||
requestBluetooth: () => callback => {
|
||||
BluetoothStateManager.requestToEnable()
|
||||
.then(() => callback(model.events.BLUETOOTH_STATE_ENABLED()))
|
||||
.catch(() => callback(model.events.BLUETOOTH_STATE_DISABLED()));
|
||||
},
|
||||
|
||||
requestToEnableLocationPermission: () => callback => {
|
||||
requestLocationPermission(
|
||||
() => callback(model.events.LOCATION_ENABLED()),
|
||||
() => callback(model.events.LOCATION_DISABLED()),
|
||||
);
|
||||
},
|
||||
|
||||
monitorConnection: () => callback => {
|
||||
const walletErrorCodePrefix = 'TVW';
|
||||
const subscription = wallet.handleDataEvents(event => {
|
||||
if (event.type === EventTypes.onDisconnected) {
|
||||
callback({type: 'DISCONNECT'});
|
||||
}
|
||||
if (
|
||||
event.type === EventTypes.onError &&
|
||||
event.code.includes(walletErrorCodePrefix)
|
||||
) {
|
||||
callback({
|
||||
type: 'BLE_ERROR',
|
||||
bleError: {message: event.message, code: event.code},
|
||||
});
|
||||
console.error('BLE Exception: ' + event.message);
|
||||
}
|
||||
});
|
||||
|
||||
return () => subscription.remove();
|
||||
},
|
||||
|
||||
checkNearByDevicesPermission: () => callback => {
|
||||
checkMultiple([
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
|
||||
])
|
||||
.then(response => {
|
||||
if (
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_ADVERTISE] ===
|
||||
RESULTS.GRANTED &&
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] ===
|
||||
RESULTS.GRANTED
|
||||
) {
|
||||
callback(model.events.NEARBY_ENABLED());
|
||||
} else {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
});
|
||||
},
|
||||
|
||||
requestNearByDevicesPermission: () => callback => {
|
||||
requestMultiple([
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
|
||||
])
|
||||
.then(response => {
|
||||
if (
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_SCAN] ===
|
||||
RESULTS.GRANTED &&
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] ===
|
||||
RESULTS.GRANTED
|
||||
) {
|
||||
callback(model.events.NEARBY_ENABLED());
|
||||
} else {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
});
|
||||
},
|
||||
|
||||
checkLocationPermission: () => callback => {
|
||||
checkLocationPermissionStatus(
|
||||
() => callback(model.events.LOCATION_ENABLED()),
|
||||
() => callback(model.events.LOCATION_DISABLED()),
|
||||
);
|
||||
},
|
||||
|
||||
checkLocationStatus: () => async callback => {
|
||||
const isEnabled: boolean = await isLocationEnabled();
|
||||
if (isEnabled) {
|
||||
callback(model.events.LOCATION_ENABLED());
|
||||
} else {
|
||||
callback(model.events.LOCATION_DISABLED());
|
||||
}
|
||||
},
|
||||
|
||||
startConnection: context => callback => {
|
||||
wallet.startConnection(context.openId4VpUri);
|
||||
const statusCallback = (event: WalletDataEvent) => {
|
||||
if (event.type === EventTypes.onSecureChannelEstablished) {
|
||||
callback({type: 'CONNECTED'});
|
||||
}
|
||||
};
|
||||
|
||||
const subscription = subscribe(statusCallback);
|
||||
return () => subscription?.remove();
|
||||
},
|
||||
|
||||
sendVc: context => callback => {
|
||||
const statusCallback = (event: WalletDataEvent) => {
|
||||
if (event.type === EventTypes.onDataSent) {
|
||||
callback({type: 'VC_SENT'});
|
||||
} else if (event.type === EventTypes.onVerificationStatusReceived) {
|
||||
callback({
|
||||
type:
|
||||
event.status === VerificationStatus.ACCEPTED
|
||||
? 'VC_ACCEPTED'
|
||||
: 'VC_REJECTED',
|
||||
});
|
||||
}
|
||||
};
|
||||
wallet.sendData(
|
||||
JSON.stringify({
|
||||
...context.selectedVc,
|
||||
}),
|
||||
);
|
||||
const subscription = subscribe(statusCallback);
|
||||
return () => subscription?.remove();
|
||||
},
|
||||
|
||||
disconnect: () => () => {
|
||||
try {
|
||||
wallet.disconnect();
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
},
|
||||
|
||||
checkStorageAvailability: () => async () => {
|
||||
return Promise.resolve(
|
||||
Storage.isMinimumLimitReached('minStorageRequiredForAuditEntry'),
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
guards: {
|
||||
showFaceAuthConsentScreen: context => {
|
||||
return context.showFaceAuthConsent;
|
||||
},
|
||||
|
||||
// sample: 'OPENID4VP://connect:?name=OVPMOSIP&key=69dc92a2cc91f02258aa8094d6e2b62877f5b6498924fbaedaaa46af30abb364'
|
||||
isOpenIdQr: (_context, event) =>
|
||||
event.params.startsWith('OPENID4VP://'),
|
||||
// sample: 'INJIQUICKSHARE://NAKDFK:DB:JAHDIHAIDJXKABDAJDHUHW'
|
||||
isQuickShare: (_context, event) =>
|
||||
// event.params.startsWith(DEFAULT_QR_HEADER),
|
||||
// toggling the feature for now
|
||||
false,
|
||||
isQrLogin: (context, event) => {
|
||||
try {
|
||||
let linkCode = new URL(event.params);
|
||||
// sample: 'inji://landing-page-name?linkCode=sTjp0XVH3t3dGCU&linkExpireDateTime=2023-11-09T06:56:18.482Z'
|
||||
return linkCode.searchParams.get('linkCode') !== null;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
uptoAndroid11: () => isAndroid() && androidVersion < 31,
|
||||
|
||||
isIOS: () => isIOS(),
|
||||
|
||||
isMinimumStorageRequiredForAuditEntryReached: (_context, event) =>
|
||||
Boolean(event.data),
|
||||
|
||||
isFlowTypeMiniViewShareWithSelfie: context =>
|
||||
context.flowType === VCShareFlowType.MINI_VIEW_SHARE_WITH_SELFIE,
|
||||
|
||||
isFlowTypeMiniViewShare: context =>
|
||||
context.flowType === VCShareFlowType.MINI_VIEW_SHARE,
|
||||
|
||||
isFlowTypeSimpleShare: context =>
|
||||
context.flowType === VCShareFlowType.SIMPLE_SHARE,
|
||||
},
|
||||
services: ScanServices(model),
|
||||
|
||||
guards: ScanGuards(),
|
||||
delays: {
|
||||
DESTROY_TIMEOUT: 500,
|
||||
CONNECTION_TIMEOUT: 5 * 1000,
|
||||
SHARING_TIMEOUT: 15 * 1000,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
);
|
||||
|
||||
type State = StateFrom<typeof scanMachine>;
|
||||
@@ -1399,12 +783,3 @@ export function createScanMachine(serviceRefs: AppServices) {
|
||||
});
|
||||
}
|
||||
|
||||
export function selectIsMinimumStorageRequiredForAuditEntryLimitReached(
|
||||
state: State,
|
||||
) {
|
||||
return state.matches('restrictSharingVc');
|
||||
}
|
||||
|
||||
export function selectIsFaceVerificationConsent(state: State) {
|
||||
return state.matches('reviewing.faceVerificationConsent');
|
||||
}
|
||||
|
||||
@@ -1,238 +1,121 @@
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'': {type: ''};
|
||||
'done.invoke.QrLogin': {
|
||||
type: 'done.invoke.QrLogin';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.scan.checkStorage:invocation[0]': {
|
||||
type: 'done.invoke.scan.checkStorage:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection': {
|
||||
type: 'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
"": { type: "" };
|
||||
"done.invoke.QrLogin": { type: "done.invoke.QrLogin"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.scan.checkStorage:invocation[0]": { type: "done.invoke.scan.checkStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection": { type: "xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection" };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
checkBluetoothPermission: 'done.invoke.scan.checkBluetoothPermission.checking:invocation[0]';
|
||||
checkBluetoothState:
|
||||
| 'done.invoke.scan.checkBluetoothState.checking:invocation[0]'
|
||||
| 'done.invoke.scan.recheckBluetoothState.checking:invocation[0]';
|
||||
checkLocationPermission: 'done.invoke.scan.checkingLocationState.checkingPermissionStatus:invocation[0]';
|
||||
checkLocationStatus: 'done.invoke.scan.checkingLocationState.checkLocationService:invocation[0]';
|
||||
checkNearByDevicesPermission: 'done.invoke.scan.checkNearbyDevicesPermission.checking:invocation[0]';
|
||||
checkStorageAvailability: 'done.invoke.scan.checkStorage:invocation[0]';
|
||||
disconnect:
|
||||
| 'done.invoke.scan.clearingConnection:invocation[0]'
|
||||
| 'done.invoke.scan.disconnectDevice:invocation[0]'
|
||||
| 'done.invoke.scan.reviewing.disconnect:invocation[0]';
|
||||
monitorConnection: 'done.invoke.scan:invocation[0]';
|
||||
requestBluetooth: 'done.invoke.scan.checkBluetoothState.requesting:invocation[0]';
|
||||
requestNearByDevicesPermission: 'done.invoke.scan.checkNearbyDevicesPermission.requesting:invocation[0]';
|
||||
requestToEnableLocationPermission: 'done.invoke.scan.checkingLocationState.requestToEnableLocation:invocation[0]';
|
||||
sendVc: 'done.invoke.scan.reviewing.sendingVc:invocation[0]';
|
||||
startConnection: 'done.invoke.scan.connecting:invocation[0]';
|
||||
"checkBluetoothPermission": "done.invoke.scan.checkBluetoothPermission.checking:invocation[0]";
|
||||
"checkBluetoothState": "done.invoke.scan.checkBluetoothState.checking:invocation[0]" | "done.invoke.scan.recheckBluetoothState.checking:invocation[0]";
|
||||
"checkLocationPermission": "done.invoke.scan.checkingLocationState.checkingPermissionStatus:invocation[0]";
|
||||
"checkLocationStatus": "done.invoke.scan.checkingLocationState.checkLocationService:invocation[0]";
|
||||
"checkNearByDevicesPermission": "done.invoke.scan.checkNearbyDevicesPermission.checking:invocation[0]";
|
||||
"checkStorageAvailability": "done.invoke.scan.checkStorage:invocation[0]";
|
||||
"disconnect": "done.invoke.scan.clearingConnection:invocation[0]" | "done.invoke.scan.disconnectDevice:invocation[0]" | "done.invoke.scan.reviewing.disconnect:invocation[0]";
|
||||
"monitorConnection": "done.invoke.scan:invocation[0]";
|
||||
"requestBluetooth": "done.invoke.scan.checkBluetoothState.requesting:invocation[0]";
|
||||
"requestNearByDevicesPermission": "done.invoke.scan.checkNearbyDevicesPermission.requesting:invocation[0]";
|
||||
"requestToEnableLocationPermission": "done.invoke.scan.checkingLocationState.requestToEnableLocation:invocation[0]";
|
||||
"sendVc": "done.invoke.scan.reviewing.sendingVc:invocation[0]";
|
||||
"startConnection": "done.invoke.scan.connecting:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
actions: "clearUri" | "enableLocation" | "getFaceAuthConsent" | "loadMetaDataToMemory" | "loadVCDataToMemory" | "logFailedVerification" | "logShared" | "openAppPermission" | "openBluetoothSettings" | "refreshVCs" | "registerLoggers" | "removeLoggers" | "resetFaceCaptureBannerStatus" | "resetFlowType" | "resetSelectedVc" | "resetShowQuickShareSuccessBanner" | "sendBLEConnectionErrorEvent" | "sendScanData" | "sendVCShareFlowCancelEndEvent" | "sendVCShareFlowTimeoutEndEvent" | "sendVcShareSuccessEvent" | "sendVcSharingStartEvent" | "setBleError" | "setChildRef" | "setFlowType" | "setLinkCode" | "setQuickShareData" | "setReadyForBluetoothStateCheck" | "setReceiverInfo" | "setSelectedVc" | "setSenderInfo" | "setShareLogTypeUnverified" | "setShareLogTypeVerified" | "setShowFaceAuthConsent" | "setShowQuickShareSuccessBanner" | "setUri" | "storeLoginItem" | "storeShowFaceAuthConsent" | "storingActivityLog" | "updateFaceCaptureBannerStatus" | "updateShowFaceAuthConsent";
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
guards: "isFlowTypeMiniViewShare" | "isFlowTypeMiniViewShareWithSelfie" | "isFlowTypeSimpleShare" | "isIOS" | "isMinimumStorageRequiredForAuditEntryReached" | "isOpenIdQr" | "isQrLogin" | "isQuickShare" | "showFaceAuthConsentScreen" | "uptoAndroid11";
|
||||
services: "checkBluetoothPermission" | "checkBluetoothState" | "checkLocationPermission" | "checkLocationStatus" | "checkNearByDevicesPermission" | "checkStorageAvailability" | "disconnect" | "monitorConnection" | "requestBluetooth" | "requestNearByDevicesPermission" | "requestToEnableLocationPermission" | "sendVc" | "startConnection";
|
||||
};
|
||||
eventsCausingActions: {
|
||||
clearUri: 'STORE_RESPONSE';
|
||||
getFaceAuthConsent:
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection';
|
||||
loadMetaDataToMemory: 'SCAN';
|
||||
loadVCDataToMemory: 'STORE_RESPONSE';
|
||||
logFailedVerification: 'FACE_INVALID';
|
||||
logShared: 'VC_ACCEPTED';
|
||||
openAppPermission: 'GOTO_SETTINGS' | 'LOCATION_REQUEST';
|
||||
openBluetoothSettings: 'GOTO_SETTINGS';
|
||||
refreshVCs: 'STORE_RESPONSE';
|
||||
registerLoggers: 'STORE_RESPONSE';
|
||||
removeLoggers:
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'STORE_RESPONSE'
|
||||
| 'xstate.init';
|
||||
resetFaceCaptureBannerStatus: 'ACCEPT_REQUEST' | 'CLOSE_BANNER';
|
||||
resetFlowType:
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'GOTO_HISTORY'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'xstate.init';
|
||||
resetSelectedVc:
|
||||
| 'DISCONNECT'
|
||||
| 'DISMISS'
|
||||
| 'DISMISS_QUICK_SHARE_BANNER'
|
||||
| 'GOTO_HISTORY'
|
||||
| 'SCREEN_BLUR'
|
||||
| 'xstate.init';
|
||||
resetShowQuickShareSuccessBanner: 'DISMISS' | 'DISMISS_QUICK_SHARE_BANNER';
|
||||
sendBLEConnectionErrorEvent: 'BLE_ERROR';
|
||||
sendScanData: 'SCAN';
|
||||
sendVCShareFlowCancelEndEvent: 'CANCEL';
|
||||
sendVCShareFlowTimeoutEndEvent: 'CANCEL' | 'RETRY';
|
||||
sendVcShareSuccessEvent: 'VC_ACCEPTED';
|
||||
sendVcSharingStartEvent: 'SCAN';
|
||||
setBleError: 'BLE_ERROR';
|
||||
setChildRef: 'STORE_RESPONSE';
|
||||
setFlowType: 'SELECT_VC';
|
||||
setLinkCode: 'SCAN';
|
||||
setQuickShareData: 'SCAN';
|
||||
setReadyForBluetoothStateCheck: 'BLUETOOTH_PERMISSION_ENABLED';
|
||||
setReceiverInfo: 'CONNECTED';
|
||||
setSelectedVc: 'SELECT_VC';
|
||||
setSenderInfo: 'CONNECTED';
|
||||
setShareLogTypeUnverified: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE';
|
||||
setShareLogTypeVerified: 'FACE_VALID';
|
||||
setShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
|
||||
setShowQuickShareSuccessBanner: 'STORE_RESPONSE';
|
||||
setUri: 'SCAN';
|
||||
storeLoginItem: 'done.invoke.QrLogin';
|
||||
storeShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
|
||||
storingActivityLog: 'STORE_RESPONSE';
|
||||
updateFaceCaptureBannerStatus: 'FACE_VALID';
|
||||
updateShowFaceAuthConsent: 'STORE_RESPONSE';
|
||||
"clearUri": "STORE_RESPONSE";
|
||||
"enableLocation": "ALLOWED" | "LOCATION_REQUEST";
|
||||
"getFaceAuthConsent": "DISCONNECT" | "DISMISS" | "xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection";
|
||||
"loadMetaDataToMemory": "SCAN";
|
||||
"loadVCDataToMemory": "STORE_RESPONSE";
|
||||
"logFailedVerification": "FACE_INVALID";
|
||||
"logShared": "VC_ACCEPTED";
|
||||
"openAppPermission": "GOTO_SETTINGS" | "LOCATION_REQUEST";
|
||||
"openBluetoothSettings": "GOTO_SETTINGS";
|
||||
"refreshVCs": "STORE_RESPONSE";
|
||||
"registerLoggers": "STORE_RESPONSE";
|
||||
"removeLoggers": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "RESET" | "SCREEN_BLUR" | "STORE_RESPONSE" | "xstate.init";
|
||||
"resetFaceCaptureBannerStatus": "ACCEPT_REQUEST" | "CLOSE_BANNER";
|
||||
"resetFlowType": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "GOTO_HISTORY" | "RESET" | "SCREEN_BLUR" | "xstate.init";
|
||||
"resetSelectedVc": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "GOTO_HISTORY" | "RESET" | "SCREEN_BLUR" | "xstate.init";
|
||||
"resetShowQuickShareSuccessBanner": "DISMISS" | "DISMISS_QUICK_SHARE_BANNER";
|
||||
"sendBLEConnectionErrorEvent": "BLE_ERROR";
|
||||
"sendScanData": "SCAN";
|
||||
"sendVCShareFlowCancelEndEvent": "CANCEL";
|
||||
"sendVCShareFlowTimeoutEndEvent": "CANCEL" | "RETRY";
|
||||
"sendVcShareSuccessEvent": "VC_ACCEPTED";
|
||||
"sendVcSharingStartEvent": "SCAN";
|
||||
"setBleError": "BLE_ERROR";
|
||||
"setChildRef": "STORE_RESPONSE";
|
||||
"setFlowType": "SELECT_VC";
|
||||
"setLinkCode": "SCAN";
|
||||
"setQuickShareData": "SCAN";
|
||||
"setReadyForBluetoothStateCheck": "BLUETOOTH_PERMISSION_ENABLED";
|
||||
"setReceiverInfo": "CONNECTED";
|
||||
"setSelectedVc": "SELECT_VC";
|
||||
"setSenderInfo": "CONNECTED";
|
||||
"setShareLogTypeUnverified": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE";
|
||||
"setShareLogTypeVerified": "FACE_VALID";
|
||||
"setShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
|
||||
"setShowQuickShareSuccessBanner": "STORE_RESPONSE";
|
||||
"setUri": "SCAN";
|
||||
"storeLoginItem": "done.invoke.QrLogin";
|
||||
"storeShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
|
||||
"storingActivityLog": "STORE_RESPONSE";
|
||||
"updateFaceCaptureBannerStatus": "FACE_VALID";
|
||||
"updateShowFaceAuthConsent": "STORE_RESPONSE";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
CONNECTION_TIMEOUT: 'SCAN';
|
||||
DESTROY_TIMEOUT: '' | 'DISMISS' | 'LOCATION_ENABLED' | 'RETRY';
|
||||
SHARING_TIMEOUT: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE' | 'FACE_VALID';
|
||||
"CONNECTION_TIMEOUT": "SCAN";
|
||||
"DESTROY_TIMEOUT": "" | "DISMISS" | "LOCATION_ENABLED" | "RETRY";
|
||||
"SHARING_TIMEOUT": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE" | "FACE_VALID";
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
isFlowTypeMiniViewShare: 'CHECK_FLOW_TYPE';
|
||||
isFlowTypeMiniViewShareWithSelfie: 'CHECK_FLOW_TYPE';
|
||||
isFlowTypeSimpleShare: 'CANCEL' | 'CHECK_FLOW_TYPE' | 'DISMISS';
|
||||
isIOS: 'BLUETOOTH_STATE_DISABLED' | 'START_PERMISSION_CHECK';
|
||||
isMinimumStorageRequiredForAuditEntryReached: 'done.invoke.scan.checkStorage:invocation[0]';
|
||||
isOpenIdQr: 'SCAN';
|
||||
isQrLogin: 'SCAN';
|
||||
isQuickShare: 'SCAN';
|
||||
showFaceAuthConsentScreen: 'VERIFY_AND_ACCEPT_REQUEST';
|
||||
uptoAndroid11: '' | 'START_PERMISSION_CHECK';
|
||||
"isFlowTypeMiniViewShare": "CHECK_FLOW_TYPE";
|
||||
"isFlowTypeMiniViewShareWithSelfie": "CHECK_FLOW_TYPE" | "DISMISS";
|
||||
"isFlowTypeSimpleShare": "CANCEL" | "CHECK_FLOW_TYPE" | "DISMISS";
|
||||
"isIOS": "BLUETOOTH_STATE_DISABLED" | "START_PERMISSION_CHECK";
|
||||
"isMinimumStorageRequiredForAuditEntryReached": "done.invoke.scan.checkStorage:invocation[0]";
|
||||
"isOpenIdQr": "SCAN";
|
||||
"isQrLogin": "SCAN";
|
||||
"isQuickShare": "SCAN";
|
||||
"showFaceAuthConsentScreen": "" | "VERIFY_AND_ACCEPT_REQUEST";
|
||||
"uptoAndroid11": "" | "START_PERMISSION_CHECK";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
QrLogin: 'SCAN';
|
||||
checkBluetoothPermission:
|
||||
| ''
|
||||
| 'BLUETOOTH_STATE_DISABLED'
|
||||
| 'NEARBY_ENABLED'
|
||||
| 'START_PERMISSION_CHECK';
|
||||
checkBluetoothState: '' | 'APP_ACTIVE';
|
||||
checkLocationPermission: 'APP_ACTIVE' | 'LOCATION_ENABLED';
|
||||
checkLocationStatus: '' | 'LOCATION_REQUEST';
|
||||
checkNearByDevicesPermission: 'APP_ACTIVE' | 'START_PERMISSION_CHECK';
|
||||
checkStorageAvailability: 'RESET' | 'SCREEN_FOCUS' | 'SELECT_VC';
|
||||
disconnect: '' | 'DISMISS' | 'LOCATION_ENABLED' | 'RETRY' | 'SCREEN_BLUR';
|
||||
monitorConnection: 'DISMISS' | 'SCREEN_BLUR' | 'xstate.init';
|
||||
requestBluetooth: 'BLUETOOTH_STATE_DISABLED';
|
||||
requestNearByDevicesPermission: 'NEARBY_DISABLED';
|
||||
requestToEnableLocationPermission: 'LOCATION_DISABLED';
|
||||
sendVc: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE' | 'FACE_VALID';
|
||||
startConnection: 'SCAN';
|
||||
};
|
||||
matchesStates:
|
||||
| 'bluetoothDenied'
|
||||
| 'bluetoothPermissionDenied'
|
||||
| 'checkBluetoothPermission'
|
||||
| 'checkBluetoothPermission.checking'
|
||||
| 'checkBluetoothPermission.enabled'
|
||||
| 'checkBluetoothState'
|
||||
| 'checkBluetoothState.checking'
|
||||
| 'checkBluetoothState.enabled'
|
||||
| 'checkBluetoothState.requesting'
|
||||
| 'checkFaceAuthConsent'
|
||||
| 'checkNearbyDevicesPermission'
|
||||
| 'checkNearbyDevicesPermission.checking'
|
||||
| 'checkNearbyDevicesPermission.enabled'
|
||||
| 'checkNearbyDevicesPermission.requesting'
|
||||
| 'checkStorage'
|
||||
| 'checkingLocationState'
|
||||
| 'checkingLocationState.checkLocationService'
|
||||
| 'checkingLocationState.checkingPermissionStatus'
|
||||
| 'checkingLocationState.denied'
|
||||
| 'checkingLocationState.disabled'
|
||||
| 'checkingLocationState.requestToEnableLocation'
|
||||
| 'clearingConnection'
|
||||
| 'connecting'
|
||||
| 'connecting.inProgress'
|
||||
| 'connecting.timeout'
|
||||
| 'decodeQuickShareData'
|
||||
| 'disconnectDevice'
|
||||
| 'disconnected'
|
||||
| 'findingConnection'
|
||||
| 'handlingBleError'
|
||||
| 'inactive'
|
||||
| 'invalid'
|
||||
| 'loadVCS'
|
||||
| 'loadVCS.idle'
|
||||
| 'loadVCS.navigatingToHome'
|
||||
| 'nearByDevicesPermissionDenied'
|
||||
| 'recheckBluetoothState'
|
||||
| 'recheckBluetoothState.checking'
|
||||
| 'recheckBluetoothState.enabled'
|
||||
| 'restrictSharingVc'
|
||||
| 'reviewing'
|
||||
| 'reviewing.accepted'
|
||||
| 'reviewing.cancelling'
|
||||
| 'reviewing.disconnect'
|
||||
| 'reviewing.faceVerificationConsent'
|
||||
| 'reviewing.idle'
|
||||
| 'reviewing.invalidIdentity'
|
||||
| 'reviewing.navigateToHistory'
|
||||
| 'reviewing.rejected'
|
||||
| 'reviewing.selectingVc'
|
||||
| 'reviewing.sendingVc'
|
||||
| 'reviewing.sendingVc.inProgress'
|
||||
| 'reviewing.sendingVc.sent'
|
||||
| 'reviewing.sendingVc.timeout'
|
||||
| 'reviewing.verifyingIdentity'
|
||||
| 'showQrLogin'
|
||||
| 'showQrLogin.idle'
|
||||
| 'showQrLogin.navigatingToHistory'
|
||||
| 'showQrLogin.storing'
|
||||
| 'startPermissionCheck'
|
||||
| {
|
||||
checkBluetoothPermission?: 'checking' | 'enabled';
|
||||
checkBluetoothState?: 'checking' | 'enabled' | 'requesting';
|
||||
checkNearbyDevicesPermission?: 'checking' | 'enabled' | 'requesting';
|
||||
checkingLocationState?:
|
||||
| 'checkLocationService'
|
||||
| 'checkingPermissionStatus'
|
||||
| 'denied'
|
||||
| 'disabled'
|
||||
| 'requestToEnableLocation';
|
||||
connecting?: 'inProgress' | 'timeout';
|
||||
loadVCS?: 'idle' | 'navigatingToHome';
|
||||
recheckBluetoothState?: 'checking' | 'enabled';
|
||||
reviewing?:
|
||||
| 'accepted'
|
||||
| 'cancelling'
|
||||
| 'disconnect'
|
||||
| 'faceVerificationConsent'
|
||||
| 'idle'
|
||||
| 'invalidIdentity'
|
||||
| 'navigateToHistory'
|
||||
| 'rejected'
|
||||
| 'selectingVc'
|
||||
| 'sendingVc'
|
||||
| 'verifyingIdentity'
|
||||
| {sendingVc?: 'inProgress' | 'sent' | 'timeout'};
|
||||
showQrLogin?: 'idle' | 'navigatingToHistory' | 'storing';
|
||||
"QrLogin": "SCAN";
|
||||
"checkBluetoothPermission": "" | "BLUETOOTH_STATE_DISABLED" | "NEARBY_ENABLED" | "START_PERMISSION_CHECK";
|
||||
"checkBluetoothState": "" | "APP_ACTIVE";
|
||||
"checkLocationPermission": "LOCATION_ENABLED";
|
||||
"checkLocationStatus": "" | "APP_ACTIVE" | "LOCATION_REQUEST";
|
||||
"checkNearByDevicesPermission": "APP_ACTIVE" | "START_PERMISSION_CHECK";
|
||||
"checkStorageAvailability": "RESET" | "SCREEN_FOCUS" | "SELECT_VC";
|
||||
"disconnect": "" | "DISMISS" | "LOCATION_ENABLED" | "RETRY" | "SCREEN_BLUR";
|
||||
"monitorConnection": "DISMISS" | "SCREEN_BLUR" | "xstate.init";
|
||||
"requestBluetooth": "BLUETOOTH_STATE_DISABLED";
|
||||
"requestNearByDevicesPermission": "NEARBY_DISABLED";
|
||||
"requestToEnableLocationPermission": "LOCATION_DISABLED";
|
||||
"sendVc": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE" | "FACE_VALID";
|
||||
"startConnection": "SCAN";
|
||||
};
|
||||
matchesStates: "bluetoothDenied" | "bluetoothPermissionDenied" | "checkBluetoothPermission" | "checkBluetoothPermission.checking" | "checkBluetoothPermission.enabled" | "checkBluetoothState" | "checkBluetoothState.checking" | "checkBluetoothState.enabled" | "checkBluetoothState.requesting" | "checkFaceAuthConsent" | "checkNearbyDevicesPermission" | "checkNearbyDevicesPermission.checking" | "checkNearbyDevicesPermission.enabled" | "checkNearbyDevicesPermission.requesting" | "checkStorage" | "checkingLocationState" | "checkingLocationState.LocationPermissionRationale" | "checkingLocationState.checkLocationService" | "checkingLocationState.checkingPermissionStatus" | "checkingLocationState.denied" | "checkingLocationState.disabled" | "checkingLocationState.requestToEnableLocation" | "clearingConnection" | "connecting" | "connecting.inProgress" | "connecting.timeout" | "decodeQuickShareData" | "disconnectDevice" | "disconnected" | "findingConnection" | "handlingBleError" | "inactive" | "invalid" | "loadVCS" | "loadVCS.idle" | "loadVCS.navigatingToHome" | "nearByDevicesPermissionDenied" | "recheckBluetoothState" | "recheckBluetoothState.checking" | "recheckBluetoothState.enabled" | "restrictSharingVc" | "reviewing" | "reviewing.accepted" | "reviewing.cancelling" | "reviewing.checkFaceAuthConsentForMiniView" | "reviewing.disconnect" | "reviewing.faceVerificationConsent" | "reviewing.idle" | "reviewing.invalidIdentity" | "reviewing.navigateToHistory" | "reviewing.rejected" | "reviewing.selectingVc" | "reviewing.sendingVc" | "reviewing.sendingVc.inProgress" | "reviewing.sendingVc.sent" | "reviewing.sendingVc.timeout" | "reviewing.verifyingIdentity" | "showQrLogin" | "showQrLogin.idle" | "showQrLogin.navigatingToHistory" | "showQrLogin.storing" | "startPermissionCheck" | { "checkBluetoothPermission"?: "checking" | "enabled";
|
||||
"checkBluetoothState"?: "checking" | "enabled" | "requesting";
|
||||
"checkNearbyDevicesPermission"?: "checking" | "enabled" | "requesting";
|
||||
"checkingLocationState"?: "LocationPermissionRationale" | "checkLocationService" | "checkingPermissionStatus" | "denied" | "disabled" | "requestToEnableLocation";
|
||||
"connecting"?: "inProgress" | "timeout";
|
||||
"loadVCS"?: "idle" | "navigatingToHome";
|
||||
"recheckBluetoothState"?: "checking" | "enabled";
|
||||
"reviewing"?: "accepted" | "cancelling" | "checkFaceAuthConsentForMiniView" | "disconnect" | "faceVerificationConsent" | "idle" | "invalidIdentity" | "navigateToHistory" | "rejected" | "selectingVc" | "sendingVc" | "verifyingIdentity" | { "sendingVc"?: "inProgress" | "sent" | "timeout"; };
|
||||
"showQrLogin"?: "idle" | "navigatingToHistory" | "storing"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
84
machines/bleShare/scan/scanModel.ts
Normal file
84
machines/bleShare/scan/scanModel.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { CameraCapturedPicture } from "expo-camera";
|
||||
import { EmitterSubscription } from "react-native";
|
||||
import { ActorRefFrom } from "xstate";
|
||||
import { createModel } from "xstate/lib/model";
|
||||
import { DeviceInfo } from "../../../components/DeviceInfoList";
|
||||
import { AppServices } from "../../../shared/GlobalContext";
|
||||
import { VCShareFlowType } from "../../../shared/Utils";
|
||||
import { qrLoginMachine } from "../../QrLogin/QrLoginMachine";
|
||||
import { VC } from "../../VerifiableCredential/VCMetaMachine/vc";
|
||||
import { ActivityLogType } from "../../activityLog";
|
||||
import { BLEError } from "../types";
|
||||
|
||||
const ScanEvents ={
|
||||
SELECT_VC: (vc: VC, flowType: string) => ({vc, flowType}),
|
||||
SCAN: (params: string) => ({params}),
|
||||
ACCEPT_REQUEST: () => ({}),
|
||||
VERIFY_AND_ACCEPT_REQUEST: () => ({}),
|
||||
VC_ACCEPTED: () => ({}),
|
||||
VC_REJECTED: () => ({}),
|
||||
VC_SENT: () => ({}),
|
||||
CANCEL: () => ({}),
|
||||
CLOSE_BANNER: () => ({}),
|
||||
STAY_IN_PROGRESS: () => ({}),
|
||||
RETRY: () => ({}),
|
||||
DISMISS: () => ({}),
|
||||
DISMISS_QUICK_SHARE_BANNER: () => ({}),
|
||||
GOTO_HISTORY: () => ({}),
|
||||
CONNECTED: () => ({}),
|
||||
DISCONNECT: () => ({}),
|
||||
BLE_ERROR: (bleError: BLEError) => ({bleError}),
|
||||
CONNECTION_DESTROYED: () => ({}),
|
||||
SCREEN_BLUR: () => ({}),
|
||||
SCREEN_FOCUS: () => ({}),
|
||||
BLUETOOTH_PERMISSION_ENABLED: () => ({}),
|
||||
BLUETOOTH_PERMISSION_DENIED: () => ({}),
|
||||
BLUETOOTH_STATE_ENABLED: () => ({}),
|
||||
BLUETOOTH_STATE_DISABLED: () => ({}),
|
||||
NEARBY_ENABLED: () => ({}),
|
||||
NEARBY_DISABLED: () => ({}),
|
||||
GOTO_SETTINGS: () => ({}),
|
||||
START_PERMISSION_CHECK: () => ({}),
|
||||
LOCATION_ENABLED: () => ({}),
|
||||
LOCATION_DISABLED: () => ({}),
|
||||
LOCATION_REQUEST: () => ({}),
|
||||
CHECK_FLOW_TYPE: () => ({}),
|
||||
UPDATE_VC_NAME: (vcName: string) => ({vcName}),
|
||||
STORE_RESPONSE: (response: any) => ({response}),
|
||||
APP_ACTIVE: () => ({}),
|
||||
FACE_VALID: () => ({}),
|
||||
FACE_INVALID: () => ({}),
|
||||
RETRY_VERIFICATION: () => ({}),
|
||||
RESET: () => ({}),
|
||||
FACE_VERIFICATION_CONSENT: (isDoNotAskAgainChecked: boolean) => ({
|
||||
isDoNotAskAgainChecked,
|
||||
}),
|
||||
ALLOWED: () => ({}),
|
||||
DENIED: () => ({}),
|
||||
}
|
||||
|
||||
export const ScanModel = createModel(
|
||||
{
|
||||
serviceRefs: {} as AppServices,
|
||||
senderInfo: {} as DeviceInfo,
|
||||
receiverInfo: {} as DeviceInfo,
|
||||
selectedVc: {} as VC,
|
||||
bleError: {} as BLEError,
|
||||
loggers: [] as EmitterSubscription[],
|
||||
vcName: '',
|
||||
flowType: VCShareFlowType.SIMPLE_SHARE,
|
||||
verificationImage: {} as CameraCapturedPicture,
|
||||
openId4VpUri: '',
|
||||
shareLogType: '' as ActivityLogType,
|
||||
QrLoginRef: {} as ActorRefFrom<typeof qrLoginMachine>,
|
||||
showQuickShareSuccessBanner: false,
|
||||
linkCode: '',
|
||||
quickShareData: {},
|
||||
showFaceAuthConsent: true as boolean,
|
||||
readyForBluetoothStateCheck: false,
|
||||
showFaceCaptureSuccessBanner: false,
|
||||
},
|
||||
{
|
||||
events: ScanEvents,
|
||||
},
|
||||
);
|
||||
@@ -117,3 +117,13 @@ export function selectIsQrLoginStoring(state: State) {
|
||||
export function selectIsDone(state: State) {
|
||||
return state.matches('reviewing.disconnect');
|
||||
}
|
||||
|
||||
export function selectIsMinimumStorageRequiredForAuditEntryLimitReached(
|
||||
state: State,
|
||||
) {
|
||||
return state.matches('restrictSharingVc');
|
||||
}
|
||||
|
||||
export function selectIsFaceVerificationConsent(state: State) {
|
||||
return state.matches('reviewing.faceVerificationConsent');
|
||||
}
|
||||
197
machines/bleShare/scan/scanServices.ts
Normal file
197
machines/bleShare/scan/scanServices.ts
Normal file
@@ -0,0 +1,197 @@
|
||||
import {WalletDataEvent} from '@mosip/tuvali/lib/typescript/types/events';
|
||||
import { isLocationEnabled } from "react-native-device-info";
|
||||
import Storage from '../../../shared/storage';
|
||||
import BluetoothStateManager from 'react-native-bluetooth-state-manager';
|
||||
import tuvali from '@mosip/tuvali';
|
||||
import {
|
||||
check,
|
||||
checkMultiple,
|
||||
PERMISSIONS,
|
||||
PermissionStatus,
|
||||
requestMultiple,
|
||||
RESULTS,
|
||||
} from 'react-native-permissions';
|
||||
import {subscribe} from '../../../shared/openIdBLE/walletEventHandler';
|
||||
import { requestLocationPermission, checkLocationPermissionStatus } from "../../../shared/location";
|
||||
import { isIOS } from "../../../shared/constants";
|
||||
|
||||
const {wallet, EventTypes, VerificationStatus} = tuvali;
|
||||
|
||||
export const ScanServices=(model:any)=>{
|
||||
return { checkBluetoothPermission: () => async callback => {
|
||||
// wait a bit for animation to finish when app becomes active
|
||||
await new Promise(resolve => setTimeout(resolve, 250));
|
||||
try {
|
||||
// Passing Granted for android since permission status is always granted even if its denied.
|
||||
let response: PermissionStatus = RESULTS.GRANTED;
|
||||
|
||||
if (isIOS()) {
|
||||
response = await check(PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL);
|
||||
}
|
||||
|
||||
if (response === RESULTS.GRANTED) {
|
||||
callback(model.events.BLUETOOTH_PERMISSION_ENABLED());
|
||||
} else {
|
||||
callback(model.events.BLUETOOTH_PERMISSION_DENIED());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
checkBluetoothState: () => callback => {
|
||||
const subscription = BluetoothStateManager.onStateChange(state => {
|
||||
if (state === 'PoweredOn') {
|
||||
callback(model.events.BLUETOOTH_STATE_ENABLED());
|
||||
} else {
|
||||
callback(model.events.BLUETOOTH_STATE_DISABLED());
|
||||
}
|
||||
}, true);
|
||||
return () => subscription.remove();
|
||||
},
|
||||
|
||||
requestBluetooth: () => callback => {
|
||||
BluetoothStateManager.requestToEnable()
|
||||
.then(() => callback(model.events.BLUETOOTH_STATE_ENABLED()))
|
||||
.catch(() => callback(model.events.BLUETOOTH_STATE_DISABLED()));
|
||||
},
|
||||
|
||||
requestToEnableLocationPermission: () => callback => {
|
||||
requestLocationPermission(
|
||||
() => callback(model.events.LOCATION_ENABLED()),
|
||||
() => callback(model.events.LOCATION_DISABLED()),
|
||||
);
|
||||
},
|
||||
|
||||
monitorConnection: () => callback => {
|
||||
const walletErrorCodePrefix = 'TVW';
|
||||
const subscription = wallet.handleDataEvents(event => {
|
||||
if (event.type === EventTypes.onDisconnected) {
|
||||
callback({type: 'DISCONNECT'});
|
||||
}
|
||||
if (
|
||||
event.type === EventTypes.onError &&
|
||||
event.code.includes(walletErrorCodePrefix)
|
||||
) {
|
||||
callback({
|
||||
type: 'BLE_ERROR',
|
||||
bleError: {message: event.message, code: event.code},
|
||||
});
|
||||
console.error('BLE Exception: ' + event.message);
|
||||
}
|
||||
});
|
||||
|
||||
return () => subscription.remove();
|
||||
},
|
||||
|
||||
checkNearByDevicesPermission: () => callback => {
|
||||
checkMultiple([
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
|
||||
])
|
||||
.then(response => {
|
||||
if (
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_ADVERTISE] ===
|
||||
RESULTS.GRANTED &&
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] ===
|
||||
RESULTS.GRANTED
|
||||
) {
|
||||
callback(model.events.NEARBY_ENABLED());
|
||||
} else {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
});
|
||||
},
|
||||
|
||||
requestNearByDevicesPermission: () => callback => {
|
||||
requestMultiple([
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
|
||||
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
|
||||
])
|
||||
.then(response => {
|
||||
if (
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_SCAN] ===
|
||||
RESULTS.GRANTED &&
|
||||
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] ===
|
||||
RESULTS.GRANTED
|
||||
) {
|
||||
callback(model.events.NEARBY_ENABLED());
|
||||
} else {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
callback(model.events.NEARBY_DISABLED());
|
||||
});
|
||||
},
|
||||
|
||||
checkLocationPermission: () => callback => {
|
||||
checkLocationPermissionStatus(
|
||||
() => callback(model.events.LOCATION_ENABLED()),
|
||||
() => callback(model.events.LOCATION_DISABLED()),
|
||||
);
|
||||
},
|
||||
|
||||
checkLocationStatus: () => async callback => {
|
||||
const isEnabled: boolean = await isLocationEnabled();
|
||||
if (isEnabled) {
|
||||
callback(model.events.LOCATION_ENABLED());
|
||||
} else {
|
||||
callback(model.events.LOCATION_DISABLED());
|
||||
}
|
||||
},
|
||||
|
||||
startConnection: (context:any) => callback => {
|
||||
wallet.startConnection(context.openId4VpUri);
|
||||
const statusCallback = (event: WalletDataEvent) => {
|
||||
if (event.type === EventTypes.onSecureChannelEstablished) {
|
||||
callback({type: 'CONNECTED'});
|
||||
}
|
||||
};
|
||||
|
||||
const subscription = subscribe(statusCallback);
|
||||
return () => subscription?.remove();
|
||||
},
|
||||
|
||||
sendVc: context => callback => {
|
||||
const statusCallback = (event: WalletDataEvent) => {
|
||||
if (event.type === EventTypes.onDataSent) {
|
||||
callback({type: 'VC_SENT'});
|
||||
} else if (event.type === EventTypes.onVerificationStatusReceived) {
|
||||
callback({
|
||||
type:
|
||||
event.status === VerificationStatus.ACCEPTED
|
||||
? 'VC_ACCEPTED'
|
||||
: 'VC_REJECTED',
|
||||
});
|
||||
}
|
||||
};
|
||||
wallet.sendData(
|
||||
JSON.stringify({
|
||||
...context.selectedVc,
|
||||
}),
|
||||
);
|
||||
const subscription = subscribe(statusCallback);
|
||||
return () => subscription?.remove();
|
||||
},
|
||||
|
||||
disconnect: () => () => {
|
||||
try {
|
||||
console.log("inside wallet disconnect");
|
||||
wallet.disconnect();
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
},
|
||||
|
||||
checkStorageAvailability: () => async () => {
|
||||
return Promise.resolve(
|
||||
Storage.isMinimumLimitReached('minStorageRequiredForAuditEntry'),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
MY_VCS_STORE_KEY,
|
||||
RECEIVED_VCS_STORE_KEY,
|
||||
SETTINGS_STORE_KEY,
|
||||
FACE_AUTH_CONSENT,
|
||||
SHOW_FACE_AUTH_CONSENT_SHARE_FLOW,
|
||||
ENOENT,
|
||||
} from '../shared/constants';
|
||||
import SecureKeystore from '@mosip/secure-keystore';
|
||||
@@ -563,7 +563,7 @@ export async function setItem(
|
||||
appId,
|
||||
};
|
||||
encryptedData = JSON.stringify(settings);
|
||||
} else if (key === FACE_AUTH_CONSENT) {
|
||||
} else if (key === SHOW_FACE_AUTH_CONSENT_SHARE_FLOW) {
|
||||
encryptedData = JSON.stringify(value);
|
||||
} else {
|
||||
encryptedData = await encryptJson(encryptionKey, JSON.stringify(value));
|
||||
@@ -632,7 +632,7 @@ export async function getItem(
|
||||
parsedData.encryptedData = JSON.parse(decryptedData);
|
||||
}
|
||||
return parsedData;
|
||||
} else if (key === FACE_AUTH_CONSENT) {
|
||||
} else if (key === SHOW_FACE_AUTH_CONSENT_SHARE_FLOW) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
decryptedData = await decryptJson(encryptionKey, data);
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
|
||||
// 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'};
|
||||
"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';
|
||||
"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: never;
|
||||
@@ -31,47 +24,25 @@ export interface Typegen0 {
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
forwardStoreRequest:
|
||||
| 'APPEND'
|
||||
| 'CLEAR'
|
||||
| 'EXPORT'
|
||||
| 'GET'
|
||||
| 'GET_VCS_DATA'
|
||||
| 'PREPEND'
|
||||
| 'REMOVE'
|
||||
| 'REMOVE_ITEMS'
|
||||
| 'REMOVE_VC_METADATA'
|
||||
| 'RESTORE_BACKUP'
|
||||
| 'SET'
|
||||
| 'UPDATE';
|
||||
notifyParent:
|
||||
| 'KEY_RECEIVED'
|
||||
| 'READY'
|
||||
| 'done.invoke.store.resettingStorage:invocation[0]';
|
||||
setEncryptionKey: 'KEY_RECEIVED';
|
||||
"forwardStoreRequest": "APPEND" | "CLEAR" | "EXPORT" | "GET" | "GET_VCS_DATA" | "PREPEND" | "REMOVE" | "REMOVE_ITEMS" | "REMOVE_VC_METADATA" | "RESTORE_BACKUP" | "SET" | "UPDATE";
|
||||
"notifyParent": "KEY_RECEIVED" | "READY" | "done.invoke.store.resettingStorage:invocation[0]";
|
||||
"setEncryptionKey": "KEY_RECEIVED";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isCustomSecureKeystore: 'KEY_RECEIVED';
|
||||
"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]';
|
||||
"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';
|
||||
matchesStates: "checkEncryptionKey" | "checkStorageInitialisation" | "failedReadingKey" | "generatingEncryptionKey" | "gettingEncryptionKey" | "ready" | "resettingStorage";
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]': {
|
||||
type: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'xstate.after(100)#HomeScreen.tabs.init': {
|
||||
type: 'xstate.after(100)#HomeScreen.tabs.init';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
"done.invoke.HomeScreen.tabs.checkStorage:invocation[0]": { type: "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.after(100)#HomeScreen.tabs.init": { type: "xstate.after(100)#HomeScreen.tabs.init" };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
checkStorageAvailability: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
|
||||
"checkStorageAvailability": "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
@@ -23,43 +18,23 @@ export interface Typegen0 {
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
resetSelectedVc: 'DISMISS_MODAL' | 'xstate.init';
|
||||
sendAddEvent: 'DOWNLOAD_ID';
|
||||
setSelectedVc: 'VIEW_VC';
|
||||
spawnTabActors: 'xstate.init';
|
||||
"resetSelectedVc": "DISMISS_MODAL" | "xstate.init";
|
||||
"sendAddEvent": "DOWNLOAD_ID";
|
||||
"setSelectedVc": "VIEW_VC";
|
||||
"spawnTabActors": "xstate.init";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isMinimumStorageLimitReached: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
|
||||
"isMinimumStorageLimitReached": "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
checkStorageAvailability: 'GOTO_ISSUERS';
|
||||
issuersMachine: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
|
||||
};
|
||||
matchesStates:
|
||||
| 'modals'
|
||||
| 'modals.none'
|
||||
| 'modals.viewingVc'
|
||||
| 'tabs'
|
||||
| 'tabs.checkStorage'
|
||||
| 'tabs.gotoIssuers'
|
||||
| 'tabs.history'
|
||||
| 'tabs.idle'
|
||||
| 'tabs.init'
|
||||
| 'tabs.myVcs'
|
||||
| 'tabs.receivedVcs'
|
||||
| 'tabs.storageLimitReached'
|
||||
| {
|
||||
modals?: 'none' | 'viewingVc';
|
||||
tabs?:
|
||||
| 'checkStorage'
|
||||
| 'gotoIssuers'
|
||||
| 'history'
|
||||
| 'idle'
|
||||
| 'init'
|
||||
| 'myVcs'
|
||||
| 'receivedVcs'
|
||||
| 'storageLimitReached';
|
||||
"checkStorageAvailability": "GOTO_ISSUERS";
|
||||
"issuersMachine": "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]";
|
||||
};
|
||||
matchesStates: "modals" | "modals.none" | "modals.viewingVc" | "tabs" | "tabs.checkStorage" | "tabs.gotoIssuers" | "tabs.history" | "tabs.idle" | "tabs.init" | "tabs.myVcs" | "tabs.receivedVcs" | "tabs.storageLimitReached" | { "modals"?: "none" | "viewingVc";
|
||||
"tabs"?: "checkStorage" | "gotoIssuers" | "history" | "idle" | "init" | "myVcs" | "receivedVcs" | "storageLimitReached"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import {Button, Centered, Column, Text} from '../../components/ui';
|
||||
import {Theme} from '../../components/ui/styleUtils';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {useQrLogin} from './QrLoginController';
|
||||
import {QrLoginRef} from '../../machines/QrLoginMachine';
|
||||
import {QrLoginRef} from '../../machines/QrLogin/QrLoginMachine';
|
||||
import {Icon} from 'react-native-elements';
|
||||
import {Modal} from '../../components/ui/Modal';
|
||||
import {VcItemContainer} from '../../components/VC/VcItemContainer';
|
||||
|
||||
@@ -6,7 +6,7 @@ import {useQrLogin} from './QrLoginController';
|
||||
import {Image, View} from 'react-native';
|
||||
import {Icon, ListItem, Switch} from 'react-native-elements';
|
||||
import {Modal} from '../../components/ui/Modal';
|
||||
import {QrLoginRef} from '../../machines/QrLoginMachine';
|
||||
import {QrLoginRef} from '../../machines/QrLogin/QrLoginMachine';
|
||||
import {ScrollView} from 'react-native';
|
||||
import {getClientNameForCurrentLanguage} from '../../i18n';
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {MessageOverlay} from '../../components/MessageOverlay';
|
||||
import {MyBindedVcs} from './MyBindedVcs';
|
||||
import {QrLoginSuccess} from './QrLoginSuccessMessage';
|
||||
import {QrConsent} from './QrConsent';
|
||||
import {QrLoginRef} from '../../machines/QrLoginMachine';
|
||||
import {QrLoginRef} from '../../machines/QrLogin/QrLoginMachine';
|
||||
import {Icon} from 'react-native-elements';
|
||||
import {View} from 'react-native';
|
||||
import {FaceVerificationAlertOverlay} from '../Scan/FaceVerificationAlertOverlay';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {useSelector} from '@xstate/react';
|
||||
import {useContext, useState} from 'react';
|
||||
import {ActorRefFrom} from 'xstate';
|
||||
import { QrLoginEvents } from '../../machines/QrLogin/QrLoginMachine';
|
||||
import {
|
||||
QrLoginEvents,
|
||||
selectClientName,
|
||||
selectErrorMessage,
|
||||
selectEssentialClaims,
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
selectVoluntaryClaims,
|
||||
selectCredential,
|
||||
selectVerifiableCredentialData,
|
||||
} from '../../machines/QrLoginMachine';
|
||||
} from '../../machines/QrLogin/QrLoginSelectors';
|
||||
import {selectBindedVcsMetadata} from '../../machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors';
|
||||
import {GlobalContext} from '../../shared/GlobalContext';
|
||||
import {QrLoginProps} from './QrLogin';
|
||||
@@ -85,8 +85,8 @@ export function useQrLogin({service}: QrLoginProps) {
|
||||
const vcData = vcRef.getSnapshot().context;
|
||||
service.send(QrLoginEvents.SELECT_VC(vcData));
|
||||
},
|
||||
FACE_VERIFICATION_CONSENT: (isConsentGiven: boolean) =>
|
||||
service.send(QrLoginEvents.FACE_VERIFICATION_CONSENT(isConsentGiven)),
|
||||
FACE_VERIFICATION_CONSENT: (isDoNotAskAgainChecked: boolean) =>
|
||||
service.send(QrLoginEvents.FACE_VERIFICATION_CONSENT(isDoNotAskAgainChecked)),
|
||||
DISMISS: () => service.send(QrLoginEvents.DISMISS()),
|
||||
SCANNING_DONE: (qrCode: string) =>
|
||||
service.send(QrLoginEvents.SCANNING_DONE(qrCode)),
|
||||
|
||||
@@ -6,7 +6,7 @@ import {Modal} from '../../components/ui/Modal';
|
||||
import {Centered, Button, Text, Column} from '../../components/ui';
|
||||
import {Theme} from '../../components/ui/styleUtils';
|
||||
import {useQrLogin} from './QrLoginController';
|
||||
import {QrLoginRef} from '../../machines/QrLoginMachine';
|
||||
import {QrLoginRef} from '../../machines/QrLogin/QrLoginMachine';
|
||||
import {getClientNameForCurrentLanguage} from '../../i18n';
|
||||
|
||||
export const QrLoginSuccess: React.FC<QrLoginSuccessProps> = props => {
|
||||
|
||||
@@ -90,7 +90,7 @@ export const FaceVerificationAlertOverlay: React.FC<
|
||||
|
||||
interface FaceVerificationAlertProps {
|
||||
isVisible: boolean;
|
||||
onConfirm: (isConsentGiven: boolean) => void;
|
||||
onConfirm: (isDoNotAskAgainChecked: boolean) => void;
|
||||
close: () => void;
|
||||
isQrLogin?: boolean;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
selectIsFaceIdentityVerified,
|
||||
selectCredential,
|
||||
selectVerifiableCredentialData,
|
||||
} from '../../machines/bleShare/scan/selectors';
|
||||
} from '../../machines/bleShare/scan/scanSelectors';
|
||||
import {
|
||||
selectBleError,
|
||||
selectIsAccepted,
|
||||
|
||||
@@ -16,10 +16,13 @@ import {BannerNotificationContainer} from '../../components/BannerNotificationCo
|
||||
import {SharingStatusModal} from './SharingStatusModal';
|
||||
import {SvgImage} from '../../components/ui/svg';
|
||||
import {LocationPermissionRational} from './LocationPermissionRational';
|
||||
import { FaceVerificationAlertOverlay } from './FaceVerificationAlertOverlay';
|
||||
import { useSendVcScreen } from './SendVcScreenController';
|
||||
|
||||
export const ScanScreen: React.FC = () => {
|
||||
const {t} = useTranslation('ScanScreen');
|
||||
const controller = useScanScreen();
|
||||
const scanScreenController = useScanScreen();
|
||||
const sendVcScreenController = useSendVcScreen();
|
||||
const [isBluetoothOn, setIsBluetoothOn] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -36,13 +39,13 @@ export const ScanScreen: React.FC = () => {
|
||||
|
||||
// TODO(kludge): skip running this hook on every render
|
||||
useEffect(() => {
|
||||
if (controller.isStartPermissionCheck && !controller.isEmpty)
|
||||
controller.START_PERMISSION_CHECK();
|
||||
if (scanScreenController.isStartPermissionCheck && !scanScreenController.isEmpty)
|
||||
scanScreenController.START_PERMISSION_CHECK();
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (controller.isQuickShareDone) controller.GOTO_HOME();
|
||||
}, [controller.isQuickShareDone]);
|
||||
if (scanScreenController.isQuickShareDone) scanScreenController.GOTO_HOME();
|
||||
}, [scanScreenController.isQuickShareDone]);
|
||||
|
||||
const openSettings = () => {
|
||||
Linking.openSettings();
|
||||
@@ -123,14 +126,14 @@ export const ScanScreen: React.FC = () => {
|
||||
testID="enableLocationServicesMessage"
|
||||
align="center"
|
||||
color={Theme.Colors.errorMessage}>
|
||||
{controller.locationError.message}
|
||||
{scanScreenController.locationError.message}
|
||||
</Text>
|
||||
</Centered>
|
||||
|
||||
<Button
|
||||
testID="enableLocationServicesButton"
|
||||
title={controller.locationError.button}
|
||||
onPress={controller.LOCATION_REQUEST}
|
||||
title={scanScreenController.locationError.button}
|
||||
onPress={scanScreenController.LOCATION_REQUEST}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
@@ -139,58 +142,58 @@ export const ScanScreen: React.FC = () => {
|
||||
function qrScannerComponent() {
|
||||
return (
|
||||
<Column crossAlign="center" margin="0 0 0 -6">
|
||||
<QrScanner onQrFound={controller.SCAN} title={t('scanningGuide')} />
|
||||
<QrScanner onQrFound={scanScreenController.SCAN} title={t('scanningGuide')} />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
function loadQRScanner() {
|
||||
if (controller.isEmpty) {
|
||||
if (scanScreenController.isEmpty) {
|
||||
return noShareableVcText();
|
||||
}
|
||||
if (controller.selectIsInvalid) {
|
||||
if (scanScreenController.selectIsInvalid) {
|
||||
return displayInvalidQRpopup();
|
||||
}
|
||||
if (controller.isNearByDevicesPermissionDenied) {
|
||||
if (scanScreenController.isNearByDevicesPermissionDenied) {
|
||||
return allowNearbyDevicesPermissionComponent();
|
||||
}
|
||||
if (
|
||||
(controller.isBluetoothDenied || !isBluetoothOn) &&
|
||||
controller.isReadyForBluetoothStateCheck
|
||||
(scanScreenController.isBluetoothDenied || !isBluetoothOn) &&
|
||||
scanScreenController.isReadyForBluetoothStateCheck
|
||||
) {
|
||||
return bluetoothIsOffText();
|
||||
}
|
||||
if (controller.isLocalPermissionRational) {
|
||||
if (scanScreenController.isLocalPermissionRational) {
|
||||
return (
|
||||
<LocationPermissionRational
|
||||
onConfirm={controller.ALLOWED}
|
||||
onCancel={controller.DENIED}
|
||||
onConfirm={scanScreenController.ALLOWED}
|
||||
onCancel={scanScreenController.DENIED}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (controller.isLocationDisabled || controller.isLocationDenied) {
|
||||
if (scanScreenController.isLocationDisabled || scanScreenController.isLocationDenied) {
|
||||
return allowLocationComponent();
|
||||
}
|
||||
|
||||
if (controller.isBluetoothPermissionDenied) {
|
||||
if (scanScreenController.isBluetoothPermissionDenied) {
|
||||
return allowBluetoothPermissionComponent();
|
||||
}
|
||||
if (controller.isScanning) {
|
||||
if (scanScreenController.isScanning) {
|
||||
return qrScannerComponent();
|
||||
}
|
||||
}
|
||||
|
||||
function displayStorageLimitReachedError(): React.ReactNode {
|
||||
return (
|
||||
!controller.isEmpty && (
|
||||
!scanScreenController.isEmpty && (
|
||||
<ErrorMessageOverlay
|
||||
testID="storageLimitReachedError"
|
||||
isVisible={
|
||||
controller.isMinimumStorageRequiredForAuditEntryLimitReached
|
||||
scanScreenController.isMinimumStorageRequiredForAuditEntryLimitReached
|
||||
}
|
||||
translationPath={'ScanScreen'}
|
||||
error="errors.storageLimitReached"
|
||||
onDismiss={controller.GOTO_HOME}
|
||||
onDismiss={scanScreenController.GOTO_HOME}
|
||||
/>
|
||||
)
|
||||
);
|
||||
@@ -198,17 +201,17 @@ export const ScanScreen: React.FC = () => {
|
||||
|
||||
function displayInvalidQRpopup(): React.ReactNode {
|
||||
return (
|
||||
!controller.isEmpty && (
|
||||
!scanScreenController.isEmpty && (
|
||||
<SharingStatusModal
|
||||
isVisible={controller.selectIsInvalid}
|
||||
isVisible={scanScreenController.selectIsInvalid}
|
||||
testId={'invalidQrPopup'}
|
||||
image={SvgImage.ErrorLogo()}
|
||||
title={t(`status.bleError.TVW_CON_001.title`)}
|
||||
message={t(`status.bleError.TVW_CON_001.message`)}
|
||||
gradientButtonTitle={t('status.bleError.retry')}
|
||||
clearButtonTitle={t('status.bleError.home')}
|
||||
onGradientButton={controller.DISMISS}
|
||||
onClearButton={controller.GOTO_HOME}
|
||||
onGradientButton={scanScreenController.DISMISS}
|
||||
onClearButton={scanScreenController.GOTO_HOME}
|
||||
/>
|
||||
)
|
||||
);
|
||||
@@ -217,19 +220,24 @@ export const ScanScreen: React.FC = () => {
|
||||
return (
|
||||
<Column fill backgroundColor={Theme.Colors.whiteBackgroundColor}>
|
||||
<BannerNotificationContainer />
|
||||
<FaceVerificationAlertOverlay
|
||||
isVisible={sendVcScreenController.isFaceVerificationConsent}
|
||||
onConfirm={sendVcScreenController.FACE_VERIFICATION_CONSENT}
|
||||
close={sendVcScreenController.DISMISS}
|
||||
/>
|
||||
<Centered
|
||||
padding="24 0"
|
||||
align="space-evenly"
|
||||
backgroundColor={Theme.Colors.whiteBackgroundColor}>
|
||||
{loadQRScanner()}
|
||||
{controller.isQrLogin && (
|
||||
{scanScreenController.isQrLogin && (
|
||||
<QrLogin
|
||||
isVisible={controller.isQrLogin}
|
||||
service={controller.isQrRef}
|
||||
isVisible={scanScreenController.isQrLogin}
|
||||
service={scanScreenController.isQrRef}
|
||||
/>
|
||||
)}
|
||||
<MessageOverlay
|
||||
isVisible={controller.isQrLoginstoring}
|
||||
isVisible={scanScreenController.isQrLoginstoring}
|
||||
title={t('loading')}
|
||||
progress
|
||||
/>
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
selectQrLoginRef,
|
||||
selectIsQuickShareDone,
|
||||
selectShowQuickShareSuccessBanner,
|
||||
} from '../../machines/bleShare/scan/selectors';
|
||||
} from '../../machines/bleShare/scan/scanSelectors';
|
||||
import {
|
||||
selectIsBluetoothDenied,
|
||||
selectIsNearByDevicesPermissionDenied,
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
} from '../../machines/bleShare/commonSelectors';
|
||||
import {
|
||||
ScanEvents,
|
||||
selectIsMinimumStorageRequiredForAuditEntryLimitReached,
|
||||
} from '../../machines/bleShare/scan/scanMachine';
|
||||
import { selectIsMinimumStorageRequiredForAuditEntryLimitReached } from '../../machines/bleShare/scan/scanSelectors';
|
||||
import {BOTTOM_TAB_ROUTES} from '../../routes/routesConstants';
|
||||
import {MainBottomTabParamList} from '../../routes/routeTypes';
|
||||
import {useNavigation, NavigationProp} from '@react-navigation/native';
|
||||
|
||||
@@ -9,7 +9,6 @@ import {useInterpret} from '@xstate/react';
|
||||
import {GlobalContext} from '../../shared/GlobalContext';
|
||||
import {useFocusEffect} from '@react-navigation/native';
|
||||
import {VcItemContainer} from '../../components/VC/VcItemContainer';
|
||||
import {VCMetadata} from '../../shared/VCMetadata';
|
||||
import {createVCItemMachine} from '../../machines/VerifiableCredential/VCItemMachine/VCItemMachine';
|
||||
import {
|
||||
getImpressionEventData,
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
selectReceiverInfo,
|
||||
selectVcName,
|
||||
selectVerifiableCredentialData,
|
||||
} from '../../machines/bleShare/scan/selectors';
|
||||
} from '../../machines/bleShare/scan/scanSelectors';
|
||||
import {
|
||||
selectIsCancelling,
|
||||
selectIsInvalidIdentity,
|
||||
@@ -17,8 +17,8 @@ import {
|
||||
} from '../../machines/bleShare/commonSelectors';
|
||||
import {
|
||||
ScanEvents,
|
||||
selectIsFaceVerificationConsent,
|
||||
} from '../../machines/bleShare/scan/scanMachine';
|
||||
import { selectIsFaceVerificationConsent } from '../../machines/bleShare/scan/scanSelectors';
|
||||
import {VCShareFlowType} from '../../shared/Utils';
|
||||
import {NavigationProp, useNavigation} from '@react-navigation/native';
|
||||
import {RootRouteProps} from '../../routes';
|
||||
@@ -63,8 +63,8 @@ export function useSendVcScreen() {
|
||||
),
|
||||
CANCEL: () => scanService.send(ScanEvents.CANCEL()),
|
||||
ACCEPT_REQUEST: () => scanService.send(ScanEvents.ACCEPT_REQUEST()),
|
||||
FACE_VERIFICATION_CONSENT: (isConsentGiven: boolean) =>
|
||||
scanService.send(ScanEvents.FACE_VERIFICATION_CONSENT(isConsentGiven)),
|
||||
FACE_VERIFICATION_CONSENT: (isDoNotAskAgainChecked: boolean) =>
|
||||
scanService.send(ScanEvents.FACE_VERIFICATION_CONSENT(isDoNotAskAgainChecked)),
|
||||
VERIFY_AND_ACCEPT_REQUEST: () =>
|
||||
scanService.send(ScanEvents.VERIFY_AND_ACCEPT_REQUEST()),
|
||||
DISMISS: () => scanService.send(ScanEvents.DISMISS()),
|
||||
|
||||
@@ -41,7 +41,9 @@ export const SETTINGS_STORE_KEY = 'settings';
|
||||
|
||||
export const APP_ID_LENGTH = 12;
|
||||
|
||||
export const FACE_AUTH_CONSENT = 'faceAuthConsent';
|
||||
export const SHOW_FACE_AUTH_CONSENT_SHARE_FLOW = 'showFaceAuthConsentShareFlow';
|
||||
|
||||
export const SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW='showFaceAuthConsentQrLoginFlow'
|
||||
|
||||
//Banner Status
|
||||
export const BANNER_TYPE_SUCCESS = 'success';
|
||||
|
||||
Reference in New Issue
Block a user