mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-06 20:23:52 -05:00
* [INJIMOB-3647] refactor: modify data type of isRevoked to EvaluationStatus Type representing any possible value of EvaluationStatus. - "TRUE" → Condition was evaluated and is positively true - "FALSE" → Condition was evaluated and is definitively false - "UNDETERMINED" → Condition could not be evaluated due to an error Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: modify data type of isRevoked to EvaluationStatus Type representing any possible value of EvaluationStatus. - "TRUE" → Condition was evaluated and is positively true - "FALSE" → Condition was evaluated and is definitively false - "UNDETERMINED" → Condition could not be evaluated due to an error Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: change statuslistVC type to record from string Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> # Conflicts: # shared/vcjs/verifyCredential.ts * [INJIMOB-3647] refactor: update status revoke check to check for null status Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: VCMetadat constructor isRevoked param Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: rename EvaluationStatus to RevocationStatus Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> * [INJIMOB-3647] refactor: modify revocation status logs Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com> --------- Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
181 lines
5.4 KiB
TypeScript
181 lines
5.4 KiB
TypeScript
import 'react-native-get-random-values';
|
|
import React, {useContext, useEffect, useState} from 'react';
|
|
import {AppLayout} from './screens/AppLayout';
|
|
import {useFont} from './shared/hooks/useFont';
|
|
import {GlobalContextProvider} from './components/GlobalContextProvider';
|
|
import {GlobalContext} from './shared/GlobalContext';
|
|
import {useSelector} from '@xstate/react';
|
|
import {useTranslation} from 'react-i18next';
|
|
import {
|
|
APP_EVENTS,
|
|
selectIsDecryptError,
|
|
selectIsKeyInvalidateError,
|
|
selectIsDeepLinkDetected,
|
|
selectIsReadError,
|
|
selectIsReady,
|
|
} from './machines/app';
|
|
import {DualMessageOverlay} from './components/DualMessageOverlay';
|
|
import {useApp} from './screens/AppController';
|
|
import {Alert, AppState} from 'react-native';
|
|
import {
|
|
configureTelemetry,
|
|
getErrorEventData,
|
|
sendErrorEvent,
|
|
} from './shared/telemetry/TelemetryUtils';
|
|
import {TelemetryConstants} from './shared/telemetry/TelemetryConstants';
|
|
import {MessageOverlay} from './components/MessageOverlay';
|
|
import {NativeModules} from 'react-native';
|
|
import {isHardwareKeystoreExists} from './shared/cryptoutil/cryptoUtil';
|
|
import i18n from './i18n';
|
|
import {CopilotProvider} from 'react-native-copilot';
|
|
import {CopilotTooltip} from './components/CopilotTooltip';
|
|
import {Theme} from './components/ui/styleUtils';
|
|
import {selectAppSetupComplete} from './machines/auth';
|
|
|
|
const {RNSecureKeystoreModule} = NativeModules;
|
|
// kludge: this is a bad practice but has been done temporarily to surface
|
|
// an occurrence of a bug with minimal residual code changes, this should
|
|
// be removed once the bug cause is determined & fixed, ref: INJI-222
|
|
const DecryptErrorAlert = (controller, t) => {
|
|
const heading = t('errors.decryptionFailed');
|
|
const desc = t('errors.decryptionFailed');
|
|
const ignoreBtnTxt = t('ignore');
|
|
Alert.alert(heading, desc, [
|
|
{
|
|
text: ignoreBtnTxt,
|
|
onPress: () => controller.ignoreDecrypt(),
|
|
style: 'cancel',
|
|
},
|
|
]);
|
|
};
|
|
|
|
const AppLayoutWrapper: React.FC = () => {
|
|
const {appService} = useContext(GlobalContext);
|
|
const isDecryptError = useSelector(appService, selectIsDecryptError);
|
|
const isDeepLinkFlow = useSelector(appService, selectIsDeepLinkDetected);
|
|
const controller = useApp();
|
|
const {t} = useTranslation('WelcomeScreen');
|
|
|
|
const authService = appService.children.get('auth');
|
|
const isAppSetupComplete = useSelector(authService, selectAppSetupComplete);
|
|
|
|
const [isDeepLinkOverlayVisible, setDeepLinkOverlayVisible] =
|
|
useState(isDeepLinkFlow);
|
|
|
|
useEffect(() => {
|
|
if (AppState.currentState === 'active') {
|
|
appService.send(APP_EVENTS.ACTIVE());
|
|
} else {
|
|
appService.send(APP_EVENTS.INACTIVE());
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
setDeepLinkOverlayVisible(isDeepLinkFlow);
|
|
}, [isDeepLinkFlow]);
|
|
|
|
if (isDecryptError) {
|
|
DecryptErrorAlert(controller, t);
|
|
}
|
|
configureTelemetry();
|
|
return (
|
|
<>
|
|
<AppLayout />
|
|
|
|
<MessageOverlay
|
|
isVisible={isDeepLinkOverlayVisible && !isAppSetupComplete}
|
|
title={t('errors.appSetupIncomplete.title')}
|
|
message={t('errors.appSetupIncomplete.message')}
|
|
onButtonPress={() => {
|
|
setDeepLinkOverlayVisible(false);
|
|
}}
|
|
buttonText={t('common:ok')}
|
|
minHeight={'auto'}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const AppLoadingWrapper: React.FC = () => {
|
|
const {appService} = useContext(GlobalContext);
|
|
const isReadError = useSelector(appService, selectIsReadError);
|
|
const isKeyInvalidateError = useSelector(
|
|
appService,
|
|
selectIsKeyInvalidateError,
|
|
);
|
|
const controller = useApp();
|
|
const {t} = useTranslation('WelcomeScreen');
|
|
useEffect(() => {
|
|
if (isKeyInvalidateError) {
|
|
configureTelemetry();
|
|
sendErrorEvent(
|
|
getErrorEventData(
|
|
TelemetryConstants.FlowType.appLogin,
|
|
TelemetryConstants.ErrorId.appWasReset,
|
|
TelemetryConstants.ErrorMessage.appWasReset,
|
|
),
|
|
);
|
|
}
|
|
}, [isKeyInvalidateError]);
|
|
return (
|
|
<>
|
|
<MessageOverlay
|
|
isVisible={isKeyInvalidateError}
|
|
title={t('errors.invalidateKeyError.title')}
|
|
message={t('errors.invalidateKeyError.message')}
|
|
onButtonPress={controller.RESET}
|
|
buttonText={t('common:ok')}
|
|
minHeight={'auto'}
|
|
/>
|
|
|
|
{isReadError ? (
|
|
<DualMessageOverlay
|
|
isVisible={isReadError}
|
|
title={t('failedToReadKeys')}
|
|
message={t('retryRead')}
|
|
onTryAgain={controller.TRY_AGAIN}
|
|
onIgnore={controller.IGNORE}
|
|
/>
|
|
) : null}
|
|
</>
|
|
);
|
|
};
|
|
|
|
const AppInitialization: React.FC = () => {
|
|
const {appService} = useContext(GlobalContext);
|
|
const hasFontsLoaded = useFont();
|
|
const isReady = useSelector(appService, selectIsReady);
|
|
const {t} = useTranslation('common');
|
|
|
|
useEffect(() => {
|
|
if (isHardwareKeystoreExists) {
|
|
RNSecureKeystoreModule.updatePopup(
|
|
t('biometricPopup.title'),
|
|
t('biometricPopup.description'),
|
|
);
|
|
}
|
|
}, [i18n.language]);
|
|
|
|
return isReady && hasFontsLoaded ? (
|
|
<AppLayoutWrapper />
|
|
) : (
|
|
<AppLoadingWrapper />
|
|
);
|
|
};
|
|
|
|
export default function App() {
|
|
return (
|
|
<GlobalContextProvider>
|
|
<CopilotProvider
|
|
stopOnOutsideClick
|
|
androidStatusBarVisible
|
|
tooltipComponent={CopilotTooltip}
|
|
tooltipStyle={Theme.Styles.copilotStyle}
|
|
stepNumberComponent={() => null}
|
|
animated>
|
|
<AppInitialization />
|
|
</CopilotProvider>
|
|
</GlobalContextProvider>
|
|
);
|
|
}
|