mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 13:38:01 -05:00
[INJIMOB-3581] add revocation and reverification logic (#2117)
* [INJIMOB-3581] add revocation and reverification logic Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-3581] refactor readable array conversion to a shared utility 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:
@@ -79,6 +79,8 @@ export const HomeScreen: React.FC<HomeRouteProps> = props => {
|
||||
isVisible={controller.activeTab === 0}
|
||||
service={controller.tabRefs.myVcs}
|
||||
vcItemActor={controller.selectedVc}
|
||||
isViewingVc={controller.isViewingVc}
|
||||
|
||||
/>
|
||||
<ReceivedVcsTab
|
||||
isVisible={controller.activeTab === 1}
|
||||
@@ -117,6 +119,7 @@ export const HomeScreen: React.FC<HomeRouteProps> = props => {
|
||||
};
|
||||
|
||||
export interface HomeScreenTabProps {
|
||||
isViewingVc: any;
|
||||
isVisible: boolean;
|
||||
service: TabRef;
|
||||
vcItemActor: ActorRefFrom<typeof VCItemMachine>;
|
||||
|
||||
@@ -37,4 +37,43 @@
|
||||
"tabs"?: "checkStorage" | "gotoIssuers" | "history" | "idle" | "init" | "myVcs" | "receivedVcs" | "storageLimitReached"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
// 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" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"checkStorageAvailability": "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"resetSelectedVc": "DISMISS_MODAL" | "xstate.init";
|
||||
"sendAddEvent": "DOWNLOAD_ID";
|
||||
"setSelectedVc": "VIEW_VC";
|
||||
"spawnTabActors": "xstate.init";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"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"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,13 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
|
||||
Array<Record<string, VCMetadata>>
|
||||
>([]);
|
||||
const [showPinVc, setShowPinVc] = useState(true);
|
||||
const [highlightCardLayout, setHighlightCardLayout] = useState<null | {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
type: 'success' | 'failure';
|
||||
}>(null);
|
||||
|
||||
const getId = () => {
|
||||
controller.DISMISS();
|
||||
@@ -68,6 +75,13 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.isViewingVc) {
|
||||
controller.RESET_HIGHLIGHT?.();
|
||||
setHighlightCardLayout(null);
|
||||
}
|
||||
}, [props.isViewingVc]);
|
||||
|
||||
useEffect(() => {
|
||||
filterVcs(search);
|
||||
}, [controller.vcData]);
|
||||
@@ -276,23 +290,40 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
|
||||
)}
|
||||
</Row>
|
||||
{showPinVc &&
|
||||
vcMetadataOrderedByPinStatus.map((vcMetadata, index) => {
|
||||
return (
|
||||
<VcItemContainer
|
||||
key={vcMetadata.getVcKey()}
|
||||
vcMetadata={vcMetadata}
|
||||
margin="0 2 8 2"
|
||||
onPress={controller.VIEW_VC}
|
||||
isDownloading={controller.inProgressVcDownloads?.has(
|
||||
vcMetadata.getVcKey(),
|
||||
)}
|
||||
isPinned={vcMetadata.isPinned}
|
||||
isInitialLaunch={controller.isInitialDownloading}
|
||||
isTopCard={index === 0}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
vcMetadataOrderedByPinStatus.map((vcMetadata, index) => {
|
||||
const vcKey = vcMetadata.getVcKey();
|
||||
|
||||
const isSuccessHighlighted =
|
||||
controller.reverificationSuccess.status &&
|
||||
controller.reverificationSuccess.vcKey === vcKey;
|
||||
|
||||
const isFailureHighlighted =
|
||||
controller.reverificationfailure.status &&
|
||||
controller.reverificationfailure.vcKey === vcKey;
|
||||
const highlightType = isSuccessHighlighted
|
||||
? 'success'
|
||||
: isFailureHighlighted
|
||||
? 'failure'
|
||||
: null;
|
||||
|
||||
return (
|
||||
<VcItemContainer
|
||||
key={vcKey}
|
||||
vcMetadata={vcMetadata}
|
||||
margin="0 2 8 2"
|
||||
onPress={controller.VIEW_VC}
|
||||
isDownloading={controller.inProgressVcDownloads?.has(vcKey)}
|
||||
isPinned={vcMetadata.isPinned}
|
||||
isInitialLaunch={controller.isInitialDownloading}
|
||||
isTopCard={index === 0}
|
||||
onMeasured={rect => {
|
||||
if (highlightType && !highlightCardLayout) {
|
||||
setHighlightCardLayout({ ...rect, type: highlightType });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{filteredSearchData.length > 0 && !showPinVc
|
||||
? filteredSearchData.map(vcMetadataObj => {
|
||||
const [vcKey, vcMetadata] =
|
||||
@@ -470,6 +501,14 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
|
||||
primaryButtonTestID="tryAgain"
|
||||
/>
|
||||
)}
|
||||
<MessageOverlay
|
||||
overlayMode='highlight'
|
||||
isVisible={!!highlightCardLayout && !props.isViewingVc}
|
||||
cardLayout={highlightCardLayout ?? undefined}
|
||||
onBackdropPress={() => {
|
||||
controller.RESET_HIGHLIGHT()
|
||||
setHighlightCardLayout(null)}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
selectDownloadingFailedVcs,
|
||||
selectInProgressVcDownloads,
|
||||
selectIsRefreshingMyVcs,
|
||||
selectIsReverificationFailure,
|
||||
selectIsReverificationSuccess,
|
||||
selectIsTampered,
|
||||
selectMyVcs,
|
||||
selectMyVcsMetadata,
|
||||
@@ -44,7 +46,6 @@ export function useMyVcsTab(props: HomeScreenTabProps) {
|
||||
const vcMetaService = appService.children.get('vcMeta')!!;
|
||||
const settingsService = appService.children.get('settings')!!;
|
||||
const authService = appService.children.get('auth');
|
||||
|
||||
return {
|
||||
service,
|
||||
AddVcModalService: useSelector(service, selectAddVcModal),
|
||||
@@ -72,7 +73,17 @@ export function useMyVcsTab(props: HomeScreenTabProps) {
|
||||
vcMetaService,
|
||||
selectVerificationErrorMessage,
|
||||
),
|
||||
|
||||
reverificationSuccess: useSelector(vcMetaService,selectIsReverificationSuccess),
|
||||
reverificationfailure: useSelector(vcMetaService,selectIsReverificationFailure),
|
||||
RESET_REVERIFICATION_FAILURE: () => {
|
||||
vcMetaService.send(VcMetaEvents.RESET_REVERIFY_VC_FAILED());
|
||||
},
|
||||
RESET_REVERIFICATION_SUCCESS: () => {
|
||||
vcMetaService.send(VcMetaEvents.RESET_REVERIFY_VC_SUCCESS());
|
||||
},
|
||||
RESET_HIGHLIGHT:()=>{
|
||||
vcMetaService.send(VcMetaEvents.RESET_HIGHLIGHT());
|
||||
},
|
||||
SET_STORE_VC_ITEM_STATUS: () =>
|
||||
service.send(MyVcsTabEvents.SET_STORE_VC_ITEM_STATUS()),
|
||||
|
||||
|
||||
@@ -1,73 +1,89 @@
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
'done.invoke.AddVcModal': {
|
||||
type: 'done.invoke.AddVcModal';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.GetVcModal': {
|
||||
type: 'done.invoke.GetVcModal';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]': {
|
||||
type: 'done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]';
|
||||
data: unknown;
|
||||
__tip: 'See the XState TS docs to learn how to strongly type this.';
|
||||
};
|
||||
'xstate.init': {type: 'xstate.init'};
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
checkNetworkStatus: 'done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]';
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
resetStoringVcItemStatus: 'RESET_STORE_VC_ITEM_STATUS';
|
||||
sendVcAdded: 'STORE_RESPONSE';
|
||||
setStoringVcItemStatus: 'SET_STORE_VC_ITEM_STATUS' | 'STORE_RESPONSE';
|
||||
storeVcItem: 'done.invoke.AddVcModal';
|
||||
viewVcFromParent: 'VIEW_VC';
|
||||
};
|
||||
eventsCausingDelays: {};
|
||||
eventsCausingGuards: {
|
||||
isNetworkOn: 'done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]';
|
||||
};
|
||||
eventsCausingServices: {
|
||||
AddVcModal:
|
||||
| 'done.invoke.GetVcModal'
|
||||
| 'done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]';
|
||||
GetVcModal: 'GET_VC';
|
||||
checkNetworkStatus: 'ADD_VC' | 'TRY_AGAIN';
|
||||
};
|
||||
matchesStates:
|
||||
| 'addVc'
|
||||
| 'addVc.checkNetwork'
|
||||
| 'addVc.networkOff'
|
||||
| 'addingVc'
|
||||
| 'addingVc.savingFailed'
|
||||
| 'addingVc.savingFailed.idle'
|
||||
| 'addingVc.storing'
|
||||
| 'addingVc.waitingForvcKey'
|
||||
| 'gettingVc'
|
||||
| 'gettingVc.waitingForvcKey'
|
||||
| 'idle'
|
||||
| 'viewingVc'
|
||||
| {
|
||||
addVc?: 'checkNetwork' | 'networkOff';
|
||||
addingVc?:
|
||||
| 'savingFailed'
|
||||
| 'storing'
|
||||
| 'waitingForvcKey'
|
||||
| {savingFailed?: 'idle'};
|
||||
gettingVc?: 'waitingForvcKey';
|
||||
};
|
||||
tags: never;
|
||||
}
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke.AddVcModal": { type: "done.invoke.AddVcModal"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.GetVcModal": { type: "done.invoke.GetVcModal"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]": { type: "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"checkNetworkStatus": "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"resetStoringVcItemStatus": "RESET_STORE_VC_ITEM_STATUS";
|
||||
"sendDownloadingFailedToVcMeta": "STORE_ERROR";
|
||||
"sendVcAdded": "STORE_RESPONSE";
|
||||
"setStoringVcItemStatus": "SET_STORE_VC_ITEM_STATUS" | "STORE_RESPONSE";
|
||||
"storeVcItem": "done.invoke.AddVcModal";
|
||||
"viewVcFromParent": "VIEW_VC";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"isNetworkOn": "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"AddVcModal": "done.invoke.GetVcModal" | "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
|
||||
"GetVcModal": "GET_VC";
|
||||
"checkNetworkStatus": "ADD_VC" | "TRY_AGAIN";
|
||||
};
|
||||
matchesStates: "addVc" | "addVc.checkNetwork" | "addVc.networkOff" | "addingVc" | "addingVc.savingFailed" | "addingVc.savingFailed.idle" | "addingVc.storing" | "addingVc.waitingForvcKey" | "gettingVc" | "gettingVc.waitingForvcKey" | "idle" | "viewingVc" | { "addVc"?: "checkNetwork" | "networkOff";
|
||||
"addingVc"?: "savingFailed" | "storing" | "waitingForvcKey" | { "savingFailed"?: "idle"; };
|
||||
"gettingVc"?: "waitingForvcKey"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke.AddVcModal": { type: "done.invoke.AddVcModal"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.GetVcModal": { type: "done.invoke.GetVcModal"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]": { type: "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"checkNetworkStatus": "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: never;
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"resetStoringVcItemStatus": "RESET_STORE_VC_ITEM_STATUS";
|
||||
"sendDownloadingFailedToVcMeta": "STORE_ERROR";
|
||||
"sendVcAdded": "STORE_RESPONSE";
|
||||
"setStoringVcItemStatus": "SET_STORE_VC_ITEM_STATUS" | "STORE_RESPONSE";
|
||||
"storeVcItem": "done.invoke.AddVcModal";
|
||||
"viewVcFromParent": "VIEW_VC";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
"isNetworkOn": "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"AddVcModal": "done.invoke.GetVcModal" | "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
|
||||
"GetVcModal": "GET_VC";
|
||||
"checkNetworkStatus": "ADD_VC" | "TRY_AGAIN";
|
||||
};
|
||||
matchesStates: "addVc" | "addVc.checkNetwork" | "addVc.networkOff" | "addingVc" | "addingVc.savingFailed" | "addingVc.savingFailed.idle" | "addingVc.storing" | "addingVc.waitingForvcKey" | "gettingVc" | "gettingVc.waitingForvcKey" | "idle" | "viewingVc" | { "addVc"?: "checkNetwork" | "networkOff";
|
||||
"addingVc"?: "savingFailed" | "storing" | "waitingForvcKey" | { "savingFailed"?: "idle"; };
|
||||
"gettingVc"?: "waitingForvcKey"; };
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
|
||||
const controller = useViewVcModal(props);
|
||||
const profileImage = controller.verifiableCredentialData.face;
|
||||
const verificationStatus = controller.verificationStatus;
|
||||
const verificationStatusMessage = controller.verificationStatus?.isRevoked ? "revoked" : controller.verificationStatus?.isExpired ? "expired" : controller.verificationStatus?.statusType;
|
||||
const [verifiableCredential, setVerifiableCredential] = useState(null);
|
||||
const [svgTemplate, setSvgTemplate] = useState<string[] | null>(null);
|
||||
const [svgRendererError, setSvgRendererError] = useState<string[] | null>(
|
||||
@@ -68,7 +69,7 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
|
||||
!controller.verifiableCredentialData.vcMetadata.isVerified &&
|
||||
!controller.isVerificationInProgress
|
||||
) {
|
||||
props.vcItemActor.send({type: 'VERIFY'});
|
||||
props.vcItemActor.send({ type: 'VERIFY' });
|
||||
}
|
||||
}, [controller.verifiableCredentialData.vcMetadata.isVerified]);
|
||||
|
||||
@@ -179,8 +180,8 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
|
||||
{controller.showVerificationStatusBanner && (
|
||||
<BannerNotification
|
||||
type={verificationStatus?.statusType as BannerStatus}
|
||||
message={t(`VcVerificationBanner:${verificationStatus?.statusType}`, {
|
||||
vcDetails: `${verificationStatus.vcType} ${verificationStatus?.vcNumber}`,
|
||||
message={t(`VcVerificationBanner:${verificationStatusMessage}`, {
|
||||
vcDetails: `${verificationStatus?.vcType} ${verificationStatus?.vcNumber ?? ""}`,
|
||||
})}
|
||||
onClosePress={controller.RESET_VERIFICATION_STATUS}
|
||||
key={'reVerificationInProgress'}
|
||||
@@ -238,7 +239,7 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
|
||||
/>
|
||||
|
||||
<MessageOverlay
|
||||
isVisible={controller.isWalletBindingInProgress}
|
||||
isVisible={controller.isWalletBindingInProgress || controller.isReverifyingVc}
|
||||
title={t('inProgress')}
|
||||
progress
|
||||
/>
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
selectShowVerificationStatusBanner,
|
||||
selectIsVerificationCompleted,
|
||||
selectCredential,
|
||||
isReverifyingVc,
|
||||
} from '../../machines/VerifiableCredential/VCItemMachine/VCItemSelectors';
|
||||
import {selectPasscode} from '../../machines/auth';
|
||||
import {biometricsMachine, selectIsSuccess} from '../../machines/biometrics';
|
||||
@@ -113,6 +114,7 @@ export function useViewVcModal({vcItemActor, isVisible}: ViewVcModalProps) {
|
||||
isBindingError: useSelector(vcItemActor, selectShowWalletBindingError),
|
||||
isBindingSuccess: useSelector(vcItemActor, selectWalletBindingSuccess),
|
||||
isBindingWarning: useSelector(vcItemActor, selectBindingWarning),
|
||||
isReverifyingVc: useSelector(vcItemActor, isReverifyingVc),
|
||||
isCommunicationDetails: useSelector(
|
||||
vcItemActor,
|
||||
selectIsCommunicationDetails,
|
||||
|
||||
Reference in New Issue
Block a user