mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 21:48:04 -05:00
* [INJIMOB-3440] fix: qr login not showing binded VCs Post success of wallet binding, VCItem machine was sending an event to update the VC data stored in VCMetada machine context, which was causing the issue of not able to recognize binded VCs. Other changes: - refactor: rm unused variable Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3440] refactor: rename variable aligning intent Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> --------- Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
537 lines
15 KiB
TypeScript
537 lines
15 KiB
TypeScript
import {assign, send} from 'xstate';
|
|
import {CommunicationDetails, UUID} from '../../../shared/Utils';
|
|
import {StoreEvents} from '../../store';
|
|
import {VCMetadata} from '../../../shared/VCMetadata';
|
|
import {MIMOTO_BASE_URL, MY_VCS_STORE_KEY} from '../../../shared/constants';
|
|
import i18n from '../../../i18n';
|
|
import {getHomeMachineService} from '../../../screens/Home/HomeScreenController';
|
|
import {DownloadProps} from '../../../shared/api';
|
|
import {isHardwareKeystoreExists} from '../../../shared/cryptoutil/cryptoUtil';
|
|
import {getBindingCertificateConstant} from '../../../shared/keystore/SecureKeystore';
|
|
import {getVcVerificationDetails} from '../../../shared/openId4VCI/Utils';
|
|
import {TelemetryConstants} from '../../../shared/telemetry/TelemetryConstants';
|
|
import {
|
|
sendStartEvent,
|
|
getStartEventData,
|
|
sendInteractEvent,
|
|
getInteractEventData,
|
|
sendEndEvent,
|
|
getEndEventData,
|
|
sendErrorEvent,
|
|
getErrorEventData,
|
|
} from '../../../shared/telemetry/TelemetryUtils';
|
|
|
|
import {ActivityLogEvents} from '../../activityLog';
|
|
import {BackupEvents} from '../../backupAndRestore/backup/backupMachine';
|
|
import {VcMetaEvents} from '../VCMetaMachine/VCMetaMachine';
|
|
import {WalletBindingResponse} from '../VCMetaMachine/vc';
|
|
import {BannerStatusType} from '../../../components/BannerNotification';
|
|
import {VCActivityLog} from '../../../components/ActivityLogEvent';
|
|
|
|
export const VCItemActions = model => {
|
|
return {
|
|
setIsVerified: assign({
|
|
vcMetadata: (context: any) =>
|
|
new VCMetadata({
|
|
...context.vcMetadata,
|
|
isVerified: true,
|
|
}),
|
|
}),
|
|
resetIsVerified: assign({
|
|
vcMetadata: (context: any) =>
|
|
new VCMetadata({
|
|
...context.vcMetadata,
|
|
isVerified: false,
|
|
}),
|
|
}),
|
|
|
|
setVerificationStatus: assign({
|
|
verificationStatus: (context: any, event) => {
|
|
const statusType =
|
|
event.response.statusType === BannerStatusType.IN_PROGRESS
|
|
? BannerStatusType.IN_PROGRESS
|
|
: event.response.vcMetadata.isVerified
|
|
? BannerStatusType.SUCCESS
|
|
: BannerStatusType.ERROR;
|
|
|
|
return getVcVerificationDetails(
|
|
statusType,
|
|
context.vcMetadata,
|
|
context.verifiableCredential,
|
|
context.wellknownResponse,
|
|
);
|
|
},
|
|
}),
|
|
|
|
resetVerificationStatus: assign({
|
|
verificationStatus: (context: any) => {
|
|
return context.verificationStatus?.statusType ===
|
|
BannerStatusType.IN_PROGRESS
|
|
? context.verificationStatus
|
|
: null;
|
|
},
|
|
showVerificationStatusBanner: () => false,
|
|
}),
|
|
|
|
showVerificationBannerStatus: assign({
|
|
showVerificationStatusBanner: () => true,
|
|
}),
|
|
|
|
sendVerificationStatusToVcMeta: send(
|
|
(context: any) => ({
|
|
type: 'SET_VERIFICATION_STATUS',
|
|
verificationStatus: context.verificationStatus,
|
|
}),
|
|
{to: context => context.serviceRefs.vcMeta},
|
|
),
|
|
|
|
removeVerificationStatusFromVcMeta: send(
|
|
(context: any) => ({
|
|
type: 'RESET_VERIFICATION_STATUS',
|
|
verificationStatus: context.verificationStatus,
|
|
}),
|
|
{to: context => context.serviceRefs.vcMeta},
|
|
),
|
|
|
|
setCommunicationDetails: model.assign({
|
|
communicationDetails: (_context, event) => {
|
|
const communicationDetails: CommunicationDetails = {
|
|
phoneNumber: event.data.response.maskedMobile,
|
|
emailId: event.data.response.maskedEmail,
|
|
};
|
|
return communicationDetails;
|
|
},
|
|
}),
|
|
requestVcContext: send(
|
|
(context: any) => ({
|
|
type: 'GET_VC_ITEM',
|
|
vcMetadata: context.vcMetadata,
|
|
}),
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
|
|
sendDownloadingFailedToVcMeta: send(
|
|
(_: any) => ({
|
|
type: 'VC_DOWNLOADING_FAILED',
|
|
}),
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
|
|
setContext: model.assign((context, event) => {
|
|
const vcMetadata = VCMetadata.fromVC(context.vcMetadata);
|
|
if (!vcMetadata.id) {
|
|
const credId = UUID.generate();
|
|
vcMetadata.id = `${credId}_${vcMetadata.issuer}`;
|
|
}
|
|
return {
|
|
...context,
|
|
...event.response,
|
|
vcMetadata: vcMetadata,
|
|
};
|
|
}),
|
|
storeContext: send(
|
|
(context: any) => {
|
|
const {
|
|
serviceRefs,
|
|
isMachineInKebabPopupState,
|
|
verificationStatus,
|
|
showVerificationStatusBanner,
|
|
...data
|
|
} = context;
|
|
data.credentialRegistry = MIMOTO_BASE_URL;
|
|
return StoreEvents.SET(
|
|
VCMetadata.fromVC(context.vcMetadata).getVcKey(),
|
|
data,
|
|
);
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.store,
|
|
},
|
|
),
|
|
|
|
setVcMetadata: assign({
|
|
vcMetadata: (_, event) => event.vcMetadata,
|
|
}),
|
|
|
|
updateWellknownResponse: assign({
|
|
wellknownResponse: (_, event) => event.data,
|
|
}),
|
|
|
|
storeVcInContext: send(
|
|
//todo : separate handling done for openid4vci , handle commonly from vc machine
|
|
(context: any) => {
|
|
const {serviceRefs, wellknownResponse, ...data} = context;
|
|
return {
|
|
type: 'VC_DOWNLOADED',
|
|
vc: data,
|
|
vcMetadata: context.vcMetadata,
|
|
};
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
|
|
updateVcMetadata: send(
|
|
(context: any) => VcMetaEvents.VC_METADATA_UPDATED(context.vcMetadata),
|
|
{
|
|
to: (context: any) => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
|
|
removeVcMetaDataFromStorage: send(
|
|
(context: any) => {
|
|
return StoreEvents.REMOVE_VC_METADATA(
|
|
MY_VCS_STORE_KEY,
|
|
context.vcMetadata.getVcKey(),
|
|
);
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.store,
|
|
},
|
|
),
|
|
removeVcMetaDataFromVcMachineContext: send(
|
|
(context: any) => {
|
|
return {
|
|
type: 'REMOVE_VC_FROM_CONTEXT',
|
|
vcMetadata: context.vcMetadata,
|
|
};
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
sendDownloadLimitExpire: send(
|
|
(context: any, event) => {
|
|
return {
|
|
type: 'DOWNLOAD_LIMIT_EXPIRED',
|
|
vcMetadata: context.vcMetadata,
|
|
};
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
|
|
sendVerificationError: send(
|
|
(context: any, _event) => {
|
|
return {
|
|
type: 'VERIFY_VC_FAILED',
|
|
errorMessage: context.error,
|
|
vcMetadata: context.vcMetadata,
|
|
};
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
refreshAllVcs: send(
|
|
() => ({
|
|
type: 'REFRESH_MY_VCS',
|
|
}),
|
|
{
|
|
to: (context: any) => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
|
|
setPinCard: assign({
|
|
vcMetadata: (context: any) =>
|
|
new VCMetadata({
|
|
...context.vcMetadata,
|
|
isPinned: !context.vcMetadata.isPinned,
|
|
}),
|
|
}),
|
|
|
|
resetIsMachineInKebabPopupState: assign({
|
|
isMachineInKebabPopupState: () => false,
|
|
}),
|
|
|
|
sendBackupEvent: send(BackupEvents.DATA_BACKUP(true), {
|
|
to: (context: any) => context.serviceRefs.backup,
|
|
}),
|
|
|
|
setErrorAsWalletBindingError: assign({
|
|
error: () =>
|
|
i18n.t('errors.genericError', {
|
|
ns: 'common',
|
|
}),
|
|
}),
|
|
setErrorAsVerificationError: assign({
|
|
//todo handle error message from different actions
|
|
error: (_context, event) => (event.data as Error).message,
|
|
}),
|
|
unSetError: assign({
|
|
error: () => '',
|
|
}),
|
|
unSetBindingTransactionId: assign({bindingTransactionId: () => ''}),
|
|
sendWalletBindingSuccess: send(
|
|
context => {
|
|
const {
|
|
serviceRefs,
|
|
isMachineInKebabPopupState,
|
|
verificationStatus,
|
|
showVerificationStatusBanner,
|
|
...data
|
|
} = context;
|
|
return {
|
|
type: 'WALLET_BINDING_SUCCESS',
|
|
vcKey: context.vcMetadata.getVcKey(),
|
|
vc: data,
|
|
};
|
|
},
|
|
{
|
|
to: (context: any) => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
setWalletBindingResponse: assign({
|
|
walletBindingResponse: (_context, event) =>
|
|
event.data as WalletBindingResponse,
|
|
}),
|
|
incrementDownloadCounter: model.assign({
|
|
downloadCounter: ({downloadCounter}) => downloadCounter + 1,
|
|
}),
|
|
|
|
setMaxDownloadCount: model.assign({
|
|
maxDownloadCount: (_context, event) =>
|
|
Number((event.data as DownloadProps).maxDownloadLimit),
|
|
}),
|
|
|
|
setDownloadInterval: model.assign({
|
|
downloadInterval: (_context, event) =>
|
|
Number((event.data as DownloadProps).downloadInterval),
|
|
}),
|
|
sendActivationStartEvent: context => {
|
|
sendStartEvent(
|
|
getStartEventData(
|
|
context.isMachineInKebabPopupState
|
|
? TelemetryConstants.FlowType.vcActivationFromKebab
|
|
: TelemetryConstants.FlowType.vcActivation,
|
|
),
|
|
);
|
|
sendInteractEvent(
|
|
getInteractEventData(
|
|
context.isMachineInKebabPopupState
|
|
? TelemetryConstants.FlowType.vcActivationFromKebab
|
|
: TelemetryConstants.FlowType.vcActivation,
|
|
TelemetryConstants.InteractEventSubtype.click,
|
|
'Activate Button',
|
|
),
|
|
);
|
|
},
|
|
|
|
sendUserCancelledActivationFailedEndEvent: context => {
|
|
const [errorId, errorMessage] = [
|
|
TelemetryConstants.ErrorId.userCancel,
|
|
TelemetryConstants.ErrorMessage.activationCancelled,
|
|
];
|
|
sendEndEvent(
|
|
getEndEventData(
|
|
context.isMachineInKebabPopupState
|
|
? TelemetryConstants.FlowType.vcActivationFromKebab
|
|
: TelemetryConstants.FlowType.vcActivation,
|
|
TelemetryConstants.EndEventStatus.failure,
|
|
{
|
|
errorId: errorId,
|
|
errorMessage: errorMessage,
|
|
},
|
|
),
|
|
);
|
|
},
|
|
|
|
sendWalletBindingErrorEvent: (context, event) => {
|
|
if (context.error) {
|
|
const error = JSON.parse(JSON.stringify(event.data)).name
|
|
? JSON.parse(JSON.stringify(event.data)).name + '-' + context.error
|
|
: context.error;
|
|
sendErrorEvent(
|
|
getErrorEventData(
|
|
TelemetryConstants.FlowType.vcActivation,
|
|
TelemetryConstants.ErrorId.activationFailed,
|
|
error,
|
|
),
|
|
);
|
|
}
|
|
sendEndEvent(
|
|
getEndEventData(
|
|
TelemetryConstants.FlowType.vcActivation,
|
|
TelemetryConstants.EndEventStatus.failure,
|
|
),
|
|
);
|
|
},
|
|
|
|
sendActivationSuccessEvent: context =>
|
|
sendEndEvent(
|
|
getEndEventData(
|
|
context.isMachineInKebabPopupState
|
|
? TelemetryConstants.FlowType.vcActivationFromKebab
|
|
: TelemetryConstants.FlowType.vcActivation,
|
|
TelemetryConstants.EndEventStatus.success,
|
|
{'Activation key': context.vcMetadata?.downloadKeyType},
|
|
),
|
|
),
|
|
|
|
setPublicKey: assign({
|
|
publicKey: (_context, event) => {
|
|
if (!isHardwareKeystoreExists) {
|
|
return event.data.publicKey as string;
|
|
}
|
|
return event.data.publicKey as string;
|
|
},
|
|
}),
|
|
|
|
setPrivateKey: assign({
|
|
privateKey: (_context, event) => event.data.privateKey as string,
|
|
}),
|
|
resetPrivateKey: assign({
|
|
privateKey: () => '',
|
|
}),
|
|
setThumbprintForWalletBindingId: send(
|
|
(context: any) => {
|
|
const {walletBindingResponse} = context;
|
|
const walletBindingIdKey = getBindingCertificateConstant(
|
|
walletBindingResponse.walletBindingId,
|
|
);
|
|
return StoreEvents.SET(
|
|
walletBindingIdKey,
|
|
walletBindingResponse.thumbprint,
|
|
);
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.store,
|
|
},
|
|
),
|
|
setOTP: model.assign({
|
|
OTP: (_, event) => {
|
|
return event.OTP;
|
|
},
|
|
}),
|
|
|
|
unSetOTP: model.assign({OTP: () => ''}),
|
|
removeVcItem: send(
|
|
(context: any) => {
|
|
return StoreEvents.REMOVE(
|
|
MY_VCS_STORE_KEY,
|
|
VCMetadata.fromVC(context.vcMetadata).getVcKey(),
|
|
);
|
|
},
|
|
{to: context => context.serviceRefs.store},
|
|
),
|
|
|
|
setVcKey: model.assign({
|
|
vcMetadata: (_, event) => event.vcMetadata,
|
|
}),
|
|
removeVcFromInProgressDownloads: send(
|
|
(context: any) => {
|
|
return {
|
|
type: 'REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS',
|
|
vcMetadata: context.vcMetadata,
|
|
};
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
|
|
addVcToInProgressDownloads: send(
|
|
(context: any) => {
|
|
return {
|
|
type: 'ADD_VC_TO_IN_PROGRESS_DOWNLOADS',
|
|
requestId: context.vcMetadata.requestId,
|
|
};
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.vcMeta,
|
|
},
|
|
),
|
|
sendTelemetryEvents: () => {
|
|
sendEndEvent({
|
|
type: TelemetryConstants.FlowType.vcDownload,
|
|
status: TelemetryConstants.EndEventStatus.success,
|
|
});
|
|
},
|
|
closeViewVcModal: send('DISMISS_MODAL', {
|
|
to: () => getHomeMachineService(),
|
|
}),
|
|
logDownloaded: send(
|
|
(context: any) => {
|
|
return ActivityLogEvents.LOG_ACTIVITY(
|
|
VCActivityLog.getLogFromObject({
|
|
_vcKey: context.vcMetadata.getVcKey(),
|
|
type: 'VC_DOWNLOADED',
|
|
issuer: context.vcMetadata.issuer!!,
|
|
credentialConfigurationId:
|
|
context.verifiableCredential.credentialConfigurationId,
|
|
timestamp: Date.now(),
|
|
deviceName: '',
|
|
}),
|
|
);
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.activityLog,
|
|
},
|
|
),
|
|
logRemovedVc: send(
|
|
(context: any, _) => {
|
|
const vcMetadata = VCMetadata.fromVC(context.vcMetadata);
|
|
return ActivityLogEvents.LOG_ACTIVITY(
|
|
VCActivityLog.getLogFromObject({
|
|
credentialConfigurationId:
|
|
context.verifiableCredential.credentialConfigurationId,
|
|
issuer: vcMetadata.issuer!!,
|
|
_vcKey: vcMetadata.getVcKey(),
|
|
type: 'VC_REMOVED',
|
|
timestamp: Date.now(),
|
|
deviceName: '',
|
|
}),
|
|
);
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.activityLog,
|
|
},
|
|
),
|
|
logWalletBindingSuccess: send(
|
|
(context: any) => {
|
|
const vcMetadata = VCMetadata.fromVC(context.vcMetadata);
|
|
return ActivityLogEvents.LOG_ACTIVITY(
|
|
VCActivityLog.getLogFromObject({
|
|
_vcKey: vcMetadata.getVcKey(),
|
|
type: 'WALLET_BINDING_SUCCESSFULL',
|
|
credentialConfigurationId:
|
|
context.verifiableCredential.credentialConfigurationId,
|
|
issuer: vcMetadata.issuer!!,
|
|
timestamp: Date.now(),
|
|
deviceName: '',
|
|
}),
|
|
);
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.activityLog,
|
|
},
|
|
),
|
|
|
|
logWalletBindingFailure: send(
|
|
(context: any) => {
|
|
const vcMetadata = VCMetadata.fromVC(context.vcMetadata);
|
|
return ActivityLogEvents.LOG_ACTIVITY(
|
|
VCActivityLog.getLogFromObject({
|
|
_vcKey: vcMetadata.getVcKey(),
|
|
type: 'WALLET_BINDING_FAILURE',
|
|
credentialConfigurationId:
|
|
context.verifiableCredential.credentialConfigurationId,
|
|
issuer: vcMetadata.issuer!!,
|
|
timestamp: Date.now(),
|
|
deviceName: '',
|
|
}),
|
|
);
|
|
},
|
|
{
|
|
to: context => context.serviceRefs.activityLog,
|
|
},
|
|
),
|
|
};
|
|
};
|