Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Inji-436): add telemetry events for app triggered warnings #986

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6cbc8ee
refactor(INJI-435): add enum for flow type,end event status & interac…
PuBHARGAVI Oct 16, 2023
99b11f4
fix(INJI-435): change flow type value to camel case in getEventType f…
PuBHARGAVI Oct 17, 2023
f1ee71f
feat(INJI-435): add start,interact & impression events in vc activati…
PuBHARGAVI Oct 18, 2023
72b7e43
feat(INJI-435): add end,error events in vc activation flow
PuBHARGAVI Oct 18, 2023
6e78a8b
feat(INJI-435): increase the pressable area of kebab icon
PuBHARGAVI Oct 19, 2023
e071a19
feat: generate impression event only after going into otp modal & tra…
PuBHARGAVI Oct 19, 2023
cac4546
fix(INJI-435): resolve merge conflicts
PuBHARGAVI Oct 19, 2023
ed551f5
refactor(INJI-435): move sendImpression event from addVc modal to otp…
PuBHARGAVI Oct 19, 2023
62505c8
fix(INJI-435): add missing impression event in issuer machine
PuBHARGAVI Oct 19, 2023
733e2ad
refactor(INJI-435): return bindingAuthFailedError from state machines…
PuBHARGAVI Oct 20, 2023
86e7025
fix(INJI-435): add padding and fix the activation status overflow in …
PuBHARGAVI Oct 20, 2023
d1d275f
refactor(INJI-435): change the telemetry sdk path in package.json
PuBHARGAVI Oct 20, 2023
c9f4987
fix(INJI-435): resolve merge conflicts
PuBHARGAVI Oct 20, 2023
4147c0b
Merge remote-tracking branch 'upstream/develop' into inji-435-add-tel…
PuBHARGAVI Oct 25, 2023
3c049bc
refactor(INJI-435): extract esignetMosipVcItem and existingMosipVcIte…
PuBHARGAVI Oct 25, 2023
8b633ec
refactor(INJI-435): remove duplicate assignments of selectors
PuBHARGAVI Oct 25, 2023
844c227
feat(INJI-436): add telemetry events to track the app generated warnings
PuBHARGAVI Nov 2, 2023
4a33039
Merge remote-tracking branch 'upstream/develop' into inji-436-add-tel…
PuBHARGAVI Nov 3, 2023
18b853b
fix(INJI-436): remove duplicate telemetry constant import in QR login…
PuBHARGAVI Nov 3, 2023
8839563
refactor(INJI-436): remove unused app id import in app.tsx
PuBHARGAVI Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import {
import {DualMessageOverlay} from './components/DualMessageOverlay';
import {useApp} from './screens/AppController';
import {Alert} from 'react-native';
import {configureTelemetry} from './shared/telemetry/TelemetryUtils';
import {
TelemetryConstants,
configureTelemetry,
getErrorEventData,
sendErrorEvent,
} from './shared/telemetry/TelemetryUtils';
import {MessageOverlay} from './components/MessageOverlay';
import SecureKeystore from 'react-native-secure-keystore';
import {isHardwareKeystoreExists} from './shared/cryptoutil/cryptoUtil';
Expand Down Expand Up @@ -59,6 +64,18 @@ const AppLoadingWrapper: React.FC = () => {
);
const controller = useApp();
const {t} = useTranslation('WelcomeScreen');
useEffect(() => {
if (isKeyInvalidateError) {
configureTelemetry();
sendErrorEvent(
getErrorEventData(
TelemetryConstants.FlowType.appLogin,
TelemetryConstants.ErrorId.appWasReset,
TelemetryConstants.ErrorMessage.appWasReset,
),
);
}
}, [isKeyInvalidateError]);
return (
<>
<AppLoading />
Expand Down
139 changes: 84 additions & 55 deletions machines/QrLoginMachine.typegen.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,85 @@
// This file was automatically generated. Edits will be overwritten

// 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": "DISMISS";
"loadMyVcs": "done.invoke.QrLogin.linkTransaction:invocation[0]";
"loadThumbprint": "FACE_VALID";
"resetLinkTransactionId": "GET";
"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";
"setThumbprint": "STORE_RESPONSE";
"setlinkTransactionResponse": "done.invoke.QrLogin.linkTransaction:invocation[0]";
};
eventsCausingDelays: {

};
eventsCausingGuards: {
"isConsentAlreadyCaptured": "done.invoke.QrLogin.sendingAuthenticate:invocation[0]";
};
eventsCausingServices: {
"linkTransaction": "GET";
"sendAuthenticate": "STORE_RESPONSE";
"sendConsent": "CONFIRM";
};
matchesStates: "ShowError" | "done" | "faceAuth" | "invalidIdentity" | "linkTransaction" | "loadMyVcs" | "loadingThumbprint" | "requestConsent" | "sendingAuthenticate" | "sendingConsent" | "showvcList" | "success" | "waitingForData";
tags: never;
}

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: 'DISMISS';
loadMyVcs: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
loadThumbprint: 'FACE_VALID';
resetLinkTransactionId: 'GET';
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';
setThumbprint: 'STORE_RESPONSE';
setlinkTransactionResponse: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isConsentAlreadyCaptured: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
};
eventsCausingServices: {
linkTransaction: 'GET';
sendAuthenticate: 'STORE_RESPONSE';
sendConsent: 'CONFIRM';
};
matchesStates:
| 'ShowError'
| 'done'
| 'faceAuth'
| 'invalidIdentity'
| 'linkTransaction'
| 'loadMyVcs'
| 'loadingThumbprint'
| 'requestConsent'
| 'sendingAuthenticate'
| 'sendingConsent'
| 'showvcList'
| 'success'
| 'waitingForData';
tags: never;
}
105 changes: 61 additions & 44 deletions machines/revoke.typegen.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,62 @@
// This file was automatically generated. Edits will be overwritten

// This file was automatically generated. Edits will be overwritten

export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]": { type: "done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]": { type: "error.platform.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]"; data: unknown };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"requestOtp": "done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]";
"requestRevoke": "done.invoke.RevokeVids.requestingRevoke:invocation[0]";
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
"clearOtp": "DISMISS" | "ERROR" | "REVOKE_VCS" | "done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]" | "xstate.init";
"logRevoked": "STORE_RESPONSE";
"revokeVID": "SUCCESS";
"setIdBackendError": "error.platform.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]";
"setOtp": "INPUT_OTP";
"setOtpError": "ERROR";
"setTransactionId": "DISMISS" | "REVOKE_VCS" | "xstate.init";
"setVIDs": "REVOKE_VCS";
};
eventsCausingDelays: {

};
eventsCausingGuards: {

};
eventsCausingServices: {
"requestOtp": never;
"requestRevoke": "INPUT_OTP";
};
matchesStates: "acceptingOtpInput" | "acceptingVIDs" | "acceptingVIDs.idle" | "acceptingVIDs.requestingOtp" | "idle" | "invalid" | "invalid.backend" | "invalid.otp" | "loggingRevoke" | "requestingRevoke" | "revokingVc" | { "acceptingVIDs"?: "idle" | "requestingOtp";
"invalid"?: "backend" | "otp"; };
tags: never;
}

export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]': {
type: 'done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]': {
type: 'error.platform.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
requestOtp: 'done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]';
requestRevoke: 'done.invoke.RevokeVids.requestingRevoke:invocation[0]';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
clearOtp:
| 'DISMISS'
| 'ERROR'
| 'REVOKE_VCS'
| 'done.invoke.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]'
| 'xstate.init';
logRevoked: 'STORE_RESPONSE';
revokeVID: 'SUCCESS';
setIdBackendError: 'error.platform.RevokeVids.acceptingVIDs.requestingOtp:invocation[0]';
setOtp: 'INPUT_OTP';
setOtpError: 'ERROR';
setTransactionId: 'DISMISS' | 'REVOKE_VCS' | 'xstate.init';
setVIDs: 'REVOKE_VCS';
};
eventsCausingDelays: {};
eventsCausingGuards: {};
eventsCausingServices: {
requestOtp: never;
requestRevoke: 'INPUT_OTP';
};
matchesStates:
| 'acceptingOtpInput'
| 'acceptingVIDs'
| 'acceptingVIDs.idle'
| 'acceptingVIDs.requestingOtp'
| 'idle'
| 'invalid'
| 'invalid.backend'
| 'invalid.otp'
| 'loggingRevoke'
| 'requestingRevoke'
| 'revokingVc'
| {acceptingVIDs?: 'idle' | 'requestingOtp'; invalid?: 'backend' | 'otp'};
tags: never;
}
14 changes: 11 additions & 3 deletions machines/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,13 @@ export const settingsMachine = model.createMachine(
}),

updateDefaults: model.assign({
appId: () => {
const appId = generateAppId();
appId: (_, event) => {
const appId =
event.response != null &&
event.response.encryptedData == null &&
event.response.appId != null
? event.response.appId
: generateAppId();
__AppId.setValue(appId);
return appId;
},
Expand Down Expand Up @@ -246,7 +251,10 @@ export const settingsMachine = model.createMachine(
},

guards: {
hasData: (_, event) => event.response != null,
hasData: (_, event) =>
event.response != null &&
event.response.encryptedData != null &&
event.response.appId != null,
hasPartialData: (_, event) =>
event.response != null && event.response.appId == null,
},
Expand Down
10 changes: 1 addition & 9 deletions machines/settings.typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,12 @@ export interface Typegen0 {
resetInjiProps: 'done.invoke.settings.resetInjiProps:invocation[0]';
};
missingImplementations: {
actions: 'injiTourGuide';
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
injiTourGuide:
| 'ACCEPT_HARDWARE_SUPPORT_NOT_EXISTS'
| 'BACK'
| 'CANCEL'
| 'STORE_RESPONSE'
| 'done.invoke.settings.resetInjiProps:invocation[0]'
| 'error.platform.settings.resetInjiProps:invocation[0]';
requestStoredContext: 'xstate.init';
resetCredentialRegistry: 'CANCEL' | 'UPDATE_MIMOTO_HOST';
setContext: 'STORE_RESPONSE';
Expand Down Expand Up @@ -64,7 +57,6 @@ export interface Typegen0 {
matchesStates:
| 'idle'
| 'init'
| 'injiTourGuide'
| 'resetInjiProps'
| 'showInjiTourGuide'
| 'storingDefaults';
Expand Down
30 changes: 26 additions & 4 deletions machines/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import {createModel} from 'xstate/lib/model';
import {generateSecureRandom} from 'react-native-securerandom';
import {log} from 'xstate/lib/actions';
import {MY_VCS_STORE_KEY} from '../shared/constants';
import {MY_VCS_STORE_KEY, SETTINGS_STORE_KEY} from '../shared/constants';
import SecureKeystore from 'react-native-secure-keystore';
import {
AUTH_TIMEOUT,
Expand Down Expand Up @@ -485,8 +485,18 @@ export async function setItem(
encryptionKey: string,
) {
try {
const data = JSON.stringify(value);
const encryptedData = await encryptJson(encryptionKey, data);
let encryptedData;
if (key === SETTINGS_STORE_KEY) {
const appId = value.appId;
delete value.appId;
const settings = {
encryptedData: await encryptJson(encryptionKey, JSON.stringify(value)),
appId,
};
encryptedData = JSON.stringify(settings);
} else {
encryptedData = await encryptJson(encryptionKey, JSON.stringify(value));
}
await Storage.setItem(key, encryptedData, encryptionKey);
} catch (e) {
console.error('error setItem:', e);
Expand All @@ -502,7 +512,19 @@ export async function getItem(
try {
const data = await Storage.getItem(key, encryptionKey);
if (data != null) {
const decryptedData = await decryptJson(encryptionKey, data);
let decryptedData;
if (key === SETTINGS_STORE_KEY) {
let parsedData = JSON.parse(data);
if (parsedData.encryptedData) {
decryptedData = await decryptJson(
encryptionKey,
parsedData.encryptedData,
);
parsedData.encryptedData = JSON.parse(decryptedData);
}
return parsedData;
}
decryptedData = await decryptJson(encryptionKey, data);
return JSON.parse(decryptedData);
}
if (data === null && VCMetadata.isVCKey(key)) {
Expand Down
Loading