diff --git a/App.tsx b/App.tsx index d4aeaba87b..adc105eef2 100644 --- a/App.tsx +++ b/App.tsx @@ -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'; @@ -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 ( <> diff --git a/locales/ara.json b/locales/ara.json index ecb09b78d5..ff428a2a78 100644 --- a/locales/ara.json +++ b/locales/ara.json @@ -205,12 +205,6 @@ }, "AddVcModal": { "requestingCredential": "جارٍ طلب بيانات الاعتماد...", - "confirmationDialog": { - "title": "هل تريد إلغاء التنزيل؟", - "message": "بمجرد الإلغاء، لن يتم تنزيل بطاقتك وستحتاج إلى إعادة بدء التنزيل.", - "wait": "لا، سأنتظر", - "cancel": "نعم، إلغاء" - }, "errors": { "input": { "empty": "فارغًا", @@ -275,7 +269,13 @@ "title": "التحقق من OTP", "otpSentMessage": "لقد أرسلنا الرمز المكون من 6 أرقام إلى رقم هاتفك المحمول المسجل!", "resendTheCode": "يمكنك إعادة إرسال الرمز بتنسيق ", - "resendCode": "أعد إرسال الرمز" + "resendCode": "أعد إرسال الرمز", + "confirmationDialog": { + "title": "هل تريد إلغاء التنزيل؟", + "message": "بمجرد الإلغاء، لن يتم تنزيل بطاقتك وستحتاج إلى إعادة بدء التنزيل.", + "wait": "لا، سأنتظر", + "cancel": "نعم، إلغاء" + } }, "MyVcsTab": { "bringYourDigitalID": "أحضر هويتك الرقمية", diff --git a/locales/en.json b/locales/en.json index 244b41fc3f..afa5f55005 100644 --- a/locales/en.json +++ b/locales/en.json @@ -206,12 +206,6 @@ }, "AddVcModal": { "requestingCredential": "Requesting credential...", - "confirmationDialog": { - "title": "Do you want to cancel downloading?", - "message": "Once cancelled, your card will not be downloaded and you need to reinitiate the download.", - "wait": "No, I’ll wait", - "cancel": "Yes, Cancel" - }, "errors": { "input": { "empty": "The input cannot be empty", @@ -276,7 +270,13 @@ "title": "OTP Verification", "otpSentMessage": "We've sent the 6 digit code to your registered mobile number!", "resendTheCode": "You can resend the code in ", - "resendCode": "Resend Code" + "resendCode": "Resend Code", + "confirmationDialog": { + "title": "Do you want to cancel downloading?", + "message": "Once cancelled, your card will not be downloaded and you need to reinitiate the download.", + "wait": "No, I’ll wait", + "cancel": "Yes, Cancel" + } }, "MyVcsTab": { "bringYourDigitalID": "Bring your digital identity", diff --git a/locales/fil.json b/locales/fil.json index ee623b7102..f2c351bf67 100644 --- a/locales/fil.json +++ b/locales/fil.json @@ -204,12 +204,6 @@ }, "AddVcModal": { "requestingCredential": "Humihiling ng kredensyal...", - "confirmationDialog": { - "title": "Gusto mo bang kanselahin ang pag-download?", - "message": "Kapag nakansela, hindi na mada-download ang iyong card at kailangan mong simulan muli ang pag-download.", - "wait": "Hindi, maghihintay ako", - "cancel": "Oo, Kanselahin" - }, "errors": { "input": { "empty": "Hindi maaaring walang laman ang input", @@ -274,7 +268,13 @@ "title": "Pag-verify ng OTP", "otpSentMessage": "Ipinadala namin ang 6 na digit na code sa iyong rehistradong mobile number!", "resendTheCode": "Maaari mong ipadala muli ang code sa ", - "resendCode": "Ipadala muli ang Code" + "resendCode": "Ipadala muli ang Code", + "confirmationDialog": { + "title": "Gusto mo bang kanselahin ang pag-download?", + "message": "Kapag nakansela, hindi na mada-download ang iyong card at kailangan mong simulan muli ang pag-download.", + "wait": "Hindi, maghihintay ako", + "cancel": "Oo, Kanselahin" + } }, "MyVcsTab": { "bringYourDigitalID": "Dalhin ang Iyong Digital ID", diff --git a/locales/hin.json b/locales/hin.json index 3232e48675..4679524673 100644 --- a/locales/hin.json +++ b/locales/hin.json @@ -202,12 +202,6 @@ }, "AddVcModal": { "requestingCredential": "क्रेडेंशियल का अनुरोध कर रहा है...", - "confirmationDialog": { - "title": "क्या आप डाउनलोडिंग रद्द करना चाहते हैं?", - "message": "एक बार रद्द होने पर, आपका कार्ड डाउनलोड नहीं किया जाएगा और आपको डाउनलोड फिर से शुरू करना होगा।", - "wait": "नहीं, मैं इंतजार करूंगा", - "cancel": "हाँ, रद्द करें" - }, "errors": { "input": { "empty": "इनपुट खाली नहीं हो सकता", @@ -272,7 +266,13 @@ "title": "ओटीपी सत्यापन", "otpSentMessage": "हमने आपके पंजीकृत मोबाइल नंबर पर 6 अंकों का कोड भेज दिया है!", "resendTheCode": "आप कोड को फिर से भेज सकते हैं ", - "resendCode": "पुन: कोड भेजे" + "resendCode": "पुन: कोड भेजे", + "confirmationDialog": { + "title": "क्या आप डाउनलोडिंग रद्द करना चाहते हैं?", + "message": "एक बार रद्द होने पर, आपका कार्ड डाउनलोड नहीं किया जाएगा और आपको डाउनलोड फिर से शुरू करना होगा।", + "wait": "नहीं, मैं इंतजार करूंगा", + "cancel": "हाँ, रद्द करें" + } }, "MyVcsTab": { "downloadCard": "डाउनलोड कार्ड", diff --git a/locales/spa.json b/locales/spa.json index 577758855b..da59717fa5 100644 --- a/locales/spa.json +++ b/locales/spa.json @@ -117,12 +117,6 @@ }, "AddVcModal": { "requestingCredential": "Solicitando credencial...", - "confirmationDialog": { - "title": "Quieres cancelar la descarga?", - "message": "OUna vez cancelada, su tarjeta no se descargará y deberá reiniciar la descarga.", - "wait": "No, esperaré", - "cancel": "Sí, cancelar" - }, "errors": { "input": { "empty": "El campo no puede estar vacío", @@ -179,7 +173,13 @@ }, "OtpVerificationModal": { "enterOtp": "Ingresa el código de verificación de 6 dígitos que te hemos enviado", - "header": "Verificación de OTP" + "header": "Verificación de OTP", + "confirmationDialog": { + "title": "Quieres cancelar la descarga?", + "message": "OUna vez cancelada, su tarjeta no se descargará y deberá reiniciar la descarga.", + "wait": "No, esperaré", + "cancel": "Sí, cancelar" + } }, "MyVcsTab": { "addVcButton": "Agregar Tarjeta", diff --git a/locales/tam.json b/locales/tam.json index d033f08ea8..06333ea85b 100644 --- a/locales/tam.json +++ b/locales/tam.json @@ -201,12 +201,6 @@ }, "AddVcModal": { "requestingCredential": "நற்சான்றிதழைக் கோருகிறது...", - "confirmationDialog": { - "title": "பதிவிறக்குவதை ரத்துசெய்ய விரும்புகிறீர்களா?", - "message": "ரத்துசெய்யப்பட்டதும், உங்கள் கார்டு பதிவிறக்கம் செய்யப்படாது மேலும் நீங்கள் பதிவிறக்கத்தை மீண்டும் தொடங்க வேண்டும்.", - "wait": "இல்லை, நான் காத்திருப்பேன்", - "cancel": "ஆம், ரத்துசெய்" - }, "errors": { "input": { "empty": "உள்ளீடு காலியாக இருக்க முடியாது", @@ -271,7 +265,13 @@ "title": "OTP சரிபார்ப்பு", "otpSentMessage": "உங்கள் பதிவு செய்யப்பட்ட மொபைல் எண்ணுக்கு 6 இலக்கக் குறியீட்டை அனுப்பியுள்ளோம்!", "resendTheCode": "நீங்கள் குறியீட்டை மீண்டும் அனுப்பலாம் ", - "resendCode": "குறியீட்டை மீண்டும் அனுப்பு" + "resendCode": "குறியீட்டை மீண்டும் அனுப்பு", + "confirmationDialog": { + "title": "பதிவிறக்குவதை ரத்துசெய்ய விரும்புகிறீர்களா?", + "message": "ரத்துசெய்யப்பட்டதும், உங்கள் கார்டு பதிவிறக்கம் செய்யப்படாது மேலும் நீங்கள் பதிவிறக்கத்தை மீண்டும் தொடங்க வேண்டும்.", + "wait": "இல்லை, நான் காத்திருப்பேன்", + "cancel": "ஆம், ரத்துசெய்" + } }, "MyVcsTab": { "bringYourDigitalID": "உங்கள் டிஜிட்டல் ஐடியைக் கொண்டு வாருங்கள்", diff --git a/machines/settings.ts b/machines/settings.ts index 5c1559e08d..2a9feee326 100644 --- a/machines/settings.ts +++ b/machines/settings.ts @@ -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; }, @@ -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, }, diff --git a/machines/settings.typegen.ts b/machines/settings.typegen.ts index 31ee28ed65..6534f02f14 100644 --- a/machines/settings.typegen.ts +++ b/machines/settings.typegen.ts @@ -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'; @@ -64,7 +57,6 @@ export interface Typegen0 { matchesStates: | 'idle' | 'init' - | 'injiTourGuide' | 'resetInjiProps' | 'showInjiTourGuide' | 'storingDefaults'; diff --git a/machines/store.ts b/machines/store.ts index 6d29f5328b..921fbde33f 100644 --- a/machines/store.ts +++ b/machines/store.ts @@ -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, @@ -486,8 +486,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); @@ -503,7 +513,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)) { diff --git a/screens/Home/MyVcs/AddVcModal.tsx b/screens/Home/MyVcs/AddVcModal.tsx index 1b3eb1f999..adcdfab493 100644 --- a/screens/Home/MyVcs/AddVcModal.tsx +++ b/screens/Home/MyVcs/AddVcModal.tsx @@ -6,7 +6,6 @@ import {IdInputModal} from './IdInputModal'; import {useTranslation} from 'react-i18next'; import {GET_INDIVIDUAL_ID} from '../../../shared/constants'; import {TelemetryConstants} from '../../../shared/telemetry/TelemetryUtils'; -import {Button, Column} from '../../../components/ui'; export const AddVcModal: React.FC = props => { const {t} = useTranslation('AddVcModal'); @@ -16,10 +15,7 @@ export const AddVcModal: React.FC = props => { if (controller.isRequestingCredential) { GET_INDIVIDUAL_ID({id: '', idType: 'UIN'}); } - return ( - (!controller.isAcceptingOtpInput && !controller.isRequestingCredential) || - !controller.isDownloadCancelled - ); + return controller.isAcceptingUinInput; }; const dismissIdInputModal = () => { @@ -38,6 +34,7 @@ export const AddVcModal: React.FC = props => { {(controller.isAcceptingOtpInput || controller.isDownloadCancelled) && ( = props => { title={t('requestingCredential')} progress /> - - - -