Files
inji-wallet/screens/AuthScreenController.ts
PuBHARGAVI 853cda3625 feat(Inji-402): track login & onboarding flow events in telemetry (#918)
* feat(INJI-402): track different flows of login and onboarding features in telemetry

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* feat(INJI-402): add missing events in the login flow

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* feat(INJI-402): track hardware keystore not supported error in telemetry

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* fix(INJI-402): send biometric event only when biometrics are enrolled in device

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* feat(INJI-402): send error event for every 5 passcode mismatch attempts

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* feat(INJI-402): add telemetry events to track passcode screen flow when biometrics change

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* feat(INJI-402): add subtype to impression and interact event

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* fix(INJI-402): remove additionalParamters in error event

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* feat(INJI-402): remove extra impression events and fix the biometrics reenabling flow

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* refactor(INJI-402): change getData method name to getStartEventData in telemetry utils

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* feat(INJI-402): don't show biometric failed alert message when user cancels the flow

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* refactor(INJI-402): change telemetry events name

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* fix(INJI-402): add missing functions in telemetry utils

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* refactor(INJI-402): add impression event in passcode screen and change Main to Home in event

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

---------

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>
2023-10-13 18:51:05 +05:30

143 lines
4.4 KiB
TypeScript

import {useMachine, useSelector} from '@xstate/react';
import {useContext, useEffect, useState} from 'react';
import * as LocalAuthentication from 'expo-local-authentication';
import {AuthEvents, selectSettingUp, selectAuthorized} from '../machines/auth';
import {RootRouteProps} from '../routes';
import {GlobalContext} from '../shared/GlobalContext';
import {
biometricsMachine,
selectError,
selectIsEnabled,
selectIsSuccess,
selectIsUnvailable,
selectUnenrolledNotice,
selectErrorResponse,
} from '../machines/biometrics';
import {SettingsEvents} from '../machines/settings';
import {useTranslation} from 'react-i18next';
import {
sendStartEvent,
sendImpressionEvent,
sendInteractEvent,
getStartEventData,
getInteractEventData,
getImpressionEventData,
getEndEventData,
sendEndEvent,
} from '../shared/telemetry/TelemetryUtils';
export function useAuthScreen(props: RootRouteProps) {
const {appService} = useContext(GlobalContext);
const authService = appService.children.get('auth');
const settingsService = appService.children.get('settings');
const isSettingUp = useSelector(authService, selectSettingUp);
const isAuthorized = useSelector(authService, selectAuthorized);
const [alertMsg, setHasAlertMsg] = useState('');
const [isBiometricsAvailable, setIsBiometricsAvailable] = useState(false);
const [biometricState, biometricSend, bioService] =
useMachine(biometricsMachine);
const isEnabledBio = useSelector(bioService, selectIsEnabled);
const isUnavailableBio = useSelector(bioService, selectIsUnvailable);
const isSuccessBio = useSelector(bioService, selectIsSuccess);
const errorMsgBio = useSelector(bioService, selectError);
const unEnrolledNoticeBio = useSelector(bioService, selectUnenrolledNotice);
const errorResponse = useSelector(bioService, selectErrorResponse);
const usePasscode = () => {
props.navigation.navigate('Passcode', {setup: isSettingUp});
};
const {t} = useTranslation('AuthScreen');
const fetchIsAvailable = async () => {
const result = await LocalAuthentication.hasHardwareAsync();
setIsBiometricsAvailable(result);
};
fetchIsAvailable();
useEffect(() => {
if (isAuthorized) {
sendEndEvent(getEndEventData('App Onboarding', 'SUCCESS'));
props.navigation.reset({
index: 0,
routes: [{name: 'Main'}],
});
sendImpressionEvent(getImpressionEventData('App Onboarding', 'Home'));
return;
}
// if biometic state is success then lets send auth service BIOMETRICS
if (isSuccessBio) {
authService.send(AuthEvents.SETUP_BIOMETRICS('true'));
settingsService.send(SettingsEvents.TOGGLE_BIOMETRIC_UNLOCK(true));
// setup passcode aswell
usePasscode();
// handle biometric failure unknown error
} else if (errorMsgBio) {
sendEndEvent(
getEndEventData('App Onboarding', 'FAILURE', {
errorId: errorResponse.res.error,
errorMessage: errorResponse.res.warning,
stackTrace: errorResponse.stacktrace,
}),
);
// show alert message whenever biometric state gets failure
if (errorResponse.res.error !== 'user_cancel') {
setHasAlertMsg(t(errorMsgBio));
}
// handle any unenrolled notice
} else if (unEnrolledNoticeBio) {
setHasAlertMsg(t(unEnrolledNoticeBio));
// we dont need to see this page to user once biometric is unavailable on its device
} else if (isUnavailableBio) {
sendStartEvent(getStartEventData('App Onboarding'));
usePasscode();
}
}, [isSuccessBio, isUnavailableBio, errorMsgBio, unEnrolledNoticeBio]);
const useBiometrics = async () => {
const isBiometricsEnrolled = await LocalAuthentication.isEnrolledAsync();
if (isBiometricsEnrolled) {
sendStartEvent(getStartEventData('App Onboarding'));
sendInteractEvent(
getInteractEventData(
'App Onboarding',
'TOUCH',
'Use Biometrics Button',
),
);
if (biometricState.matches({failure: 'unenrolled'})) {
biometricSend({type: 'RETRY_AUTHENTICATE'});
return;
}
biometricSend({type: 'AUTHENTICATE'});
} else {
setHasAlertMsg(t('errors.unenrolled'));
}
};
const hideAlert = () => {
setHasAlertMsg('');
};
return {
isBiometricsAvailable,
isSettingUp,
alertMsg,
isEnabledBio,
hideAlert,
useBiometrics,
usePasscode,
};
}